wxMaxima
EnumWrapper.h
1 // -*- mode: c++; c-file-style: "linux"; c-basic-offset: 2; indent-tabs-mode:
2 // nil -*-
3 //
4 // Copyright (C) 2020 Kuba Ober <kuba@mareimbrium.org>
5 //
6 // Everyone is permitted to copy and distribute verbatim copies
7 // of this licence document, but changing it is not allowed.
8 //
9 // WXWINDOWS LIBRARY LICENCE
10 // TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
11 //
12 // This library is free software; you can redistribute it and/or modify it
13 // under the terms of the GNU Library General Public Licence as published by
14 // the Free Software Foundation; either version 2 of the Licence, or (at your
15 // option) any later version.
16 //
17 // This library is distributed in the hope that it will be useful, but WITHOUT
18 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
20 // Licence for more details.
21 //
22 // You should have received a copy of the GNU Library General Public Licence
23 // along with this software, usually in a file named COPYING.LIB. If not,
24 // write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
25 // Floor, Boston, MA 02110-1301 USA.
26 //
27 // EXCEPTION NOTICE
28 //
29 // 1. As a special exception, the copyright holders of this library give
30 // permission for additional uses of the text contained in this release of the
31 // library as licenced under the wxWindows Library Licence, applying either
32 // version 3.1 of the Licence, or (at your option) any later version of the
33 // Licence as published by the copyright holders of version 3.1 of the Licence
34 // document.
35 //
36 // 2. The exception is that you may use, copy, link, modify and distribute
37 // under your own terms, binary object code versions of works based on the
38 // Library.
39 //
40 // 3. If you copy code from files distributed under the terms of the GNU
41 // General Public Licence or the GNU Library General Public Licence into a
42 // copy of this library, as this licence permits, the exception does not apply
43 // to the code that you add in this way. To avoid misleading anyone as to the
44 // status of such modified files, you must delete this exception notice from
45 // such code and/or adjust the licensing conditions notice accordingly.
46 //
47 // 4. If you write modifications of your own for this library, it is your
48 // choice whether to permit this exception to apply to your modifications. If
49 // you do not wish that, you must delete the exception notice from such code
50 // and/or adjust the licensing conditions notice accordingly.
51 //
52 // SPDX-License-Identifier: wxWindows
53 
54 #ifndef WXMAXIMA_ENUMWRAPPER_H
55 #define WXMAXIMA_ENUMWRAPPER_H
56 
57 #include <cstddef>
58 #include <functional>
59 #include <type_traits>
60 
71 template <typename Enum, typename Storage, Enum defaultValue = Enum{},
72  typename std::enable_if<std::is_enum<Enum>::value &&
73  std::is_integral<Storage>::value,
74  bool>::type = true>
75 class EnumWrapper {
76  Storage value = Storage(defaultValue);
77 
78  // We can at least make sure that the default value fits
79  static_assert(
80  Enum(Storage(defaultValue)) == defaultValue,
81  "The default value doesn't survive a roundtrip through this wrapper.");
82  // There's no point in using this type if it doesn't save space.
83  static_assert(
84  sizeof(Storage) < sizeof(Enum),
85  "EnumWrapper should be used only to save space."
86  "When removing it, don't forget to take care of default value!");
87 
88 public:
89  constexpr EnumWrapper() = default;
90  constexpr EnumWrapper(Storage) = delete;
91  // cppcheck-suppress noExplicitConstructor
92  constexpr EnumWrapper(Enum value) noexcept : value(value) {}
93  constexpr operator Enum() const noexcept { return Enum(value); }
94  constexpr operator Storage() const = delete;
95  constexpr size_t hash() const { return std::hash<Storage>()(value); }
96 
97  constexpr bool operator==(EnumWrapper o) const { return value == o.value; }
98  constexpr bool operator==(Enum o) const { return value == o; }
99  constexpr bool operator!=(EnumWrapper o) const { return value != o.value; }
100  constexpr bool operator!=(Enum o) const { return value != o; }
101 };
102 
103 template <typename E, typename S, E defVal>
104 constexpr bool operator==(E a, EnumWrapper<E,S,defVal> b) { return b == a; }
105 
106 template <typename E, typename S, E defVal>
107 constexpr bool operator!=(E a, EnumWrapper<E,S,defVal> b) { return b != a; }
108 
109 namespace std {
110 
111 template <typename Enum, typename Storage, Enum defaultValue>
112 struct hash<EnumWrapper<Enum, Storage, defaultValue>> {
113  constexpr auto
114  operator()(EnumWrapper<Enum, Storage, defaultValue> value) const {
115  return value.hash();
116  }
117 };
118 
119 }
120 
121 #endif
EnumWrapper
Definition: EnumWrapper.h:75