wibble  1.1
strongenumflags.h
Go to the documentation of this file.
1 // -*- C++ -*- (c) 2013 Vladimír Štill <xstill@fi.muni.cz>
2 
3 #if __cplusplus < 201103L
4 #error "strongenumflag is only supported with c++11 or newer"
5 #endif
6 
7 #include <type_traits>
8 
9 #ifndef WIBBLE_STRONGENUMFLAG_H
10 #define WIBBLE_STRONGENUMFLAG_H
11 
12 namespace wibble {
13 
14 template< typename E >
15 using is_enum_class = std::integral_constant< bool,
16  std::is_enum< E >::value && !std::is_convertible< E, int >::value >;
17 
18 template< typename Self >
20  static_assert( is_enum_class< Self >::value, "Not an enum class." );
22  using UnderlyingType = typename std::underlying_type< Self >::type;
23 
24  constexpr StrongEnumFlags() noexcept : store( 0 ) { }
25  constexpr StrongEnumFlags( Self flag ) noexcept :
26  store( static_cast< UnderlyingType >( flag ) )
27  { }
28  explicit constexpr StrongEnumFlags( UnderlyingType st ) noexcept : store( st ) { }
29 
30  constexpr explicit operator UnderlyingType() const noexcept {
31  return store;
32  }
33 
34  This &operator|=( This o ) noexcept {
35  store |= o.store;
36  return *this;
37  }
38 
39  This &operator&=( This o ) noexcept {
40  store &= o.store;
41  return *this;
42  }
43 
44  friend constexpr This operator|( This a, This b ) noexcept {
45  return This( a.store | b.store );
46  }
47 
48  friend constexpr This operator&( This a, This b ) noexcept {
49  return This( a.store & b.store );
50  }
51 
52  friend constexpr bool operator==( This a, This b ) noexcept {
53  return a.store == b.store;
54  }
55 
56  friend constexpr bool operator!=( This a, This b ) noexcept {
57  return a.store != b.store;
58  }
59 
60  constexpr bool has( Self x ) const noexcept {
61  return (*this) & x;
62  }
63 
64  constexpr operator bool() const noexcept {
65  return store;
66  }
67 
68  private:
69  UnderlyingType store;
70 };
71 
72 // don't catch integral types and classical enum!
73 template< typename Self, typename = typename
74  std::enable_if< is_enum_class< Self >::value >::type >
75 constexpr StrongEnumFlags< Self > operator|( Self a, Self b ) noexcept {
76  using Ret = StrongEnumFlags< Self >;
77  return Ret( a ) | Ret( b );
78 }
79 
80 template< typename Self, typename = typename
81  std::enable_if< is_enum_class< Self >::value >::type >
82 constexpr StrongEnumFlags< Self > operator&( Self a, Self b ) noexcept {
83  using Ret = StrongEnumFlags< Self >;
84  return Ret( a ) & Ret( b );
85 }
86 
87 }
88 
89 #endif // WIBBLE_STRONGENUMFLAG_H
friend constexpr This operator &(This a, This b) noexcept
Definition: strongenumflags.h:48
This & operator &=(This o) noexcept
Definition: strongenumflags.h:39
friend constexpr This operator|(This a, This b) noexcept
Definition: strongenumflags.h:44
std::integral_constant< bool, std::is_enum< E >::value &&!std::is_convertible< E, int >::value > is_enum_class
Definition: strongenumflags.h:16
constexpr bool has(Self x) const noexcept
Definition: strongenumflags.h:60
Definition: strongenumflags.h:19
This & operator|=(This o) noexcept
Definition: strongenumflags.h:34
friend constexpr bool operator!=(This a, This b) noexcept
Definition: strongenumflags.h:56
StrongEnumFlags< Self > This
Definition: strongenumflags.h:21
constexpr StrongEnumFlags(UnderlyingType st) noexcept
Definition: strongenumflags.h:28
constexpr StrongEnumFlags(Self flag) noexcept
Definition: strongenumflags.h:25
Definition: amorph.h:17
friend constexpr bool operator==(This a, This b) noexcept
Definition: strongenumflags.h:52
typename std::underlying_type< ProtectMode >::type UnderlyingType
Definition: strongenumflags.h:22
constexpr StrongEnumFlags() noexcept
Definition: strongenumflags.h:24