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
12namespace wibble {
13
14template< typename E >
15using is_enum_class = std::integral_constant< bool,
16 std::is_enum< E >::value && !std::is_convertible< E, int >::value >;
17
18template< 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 ) { }
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!
73template< typename Self, typename = typename
74 std::enable_if< is_enum_class< Self >::value >::type >
75constexpr StrongEnumFlags< Self > operator|( Self a, Self b ) noexcept {
77 return Ret( a ) | Ret( b );
78}
79
80template< typename Self, typename = typename
81 std::enable_if< is_enum_class< Self >::value >::type >
82constexpr StrongEnumFlags< Self > operator&( Self a, Self b ) noexcept {
84 return Ret( a ) & Ret( b );
85}
86
87}
88
89#endif // WIBBLE_STRONGENUMFLAG_H
Definition amorph.h:17
std::integral_constant< bool, std::is_enum< E >::value &&!std::is_convertible< E, int >::value > is_enum_class
Definition strongenumflags.h:16
constexpr StrongEnumFlags< Self > operator&(Self a, Self b) noexcept
Definition strongenumflags.h:82
constexpr StrongEnumFlags< Self > operator|(Self a, Self b) noexcept
Definition strongenumflags.h:75
Definition amorph.h:30
Definition strongenumflags.h:19
This & operator|=(This o) noexcept
Definition strongenumflags.h:34
constexpr StrongEnumFlags() noexcept
Definition strongenumflags.h:24
friend constexpr bool operator!=(This a, This b) noexcept
Definition strongenumflags.h:56
This & operator&=(This o) noexcept
Definition strongenumflags.h:39
constexpr StrongEnumFlags(Self flag) noexcept
Definition strongenumflags.h:25
typename std::underlying_type< Self >::type UnderlyingType
Definition strongenumflags.h:22
constexpr StrongEnumFlags(UnderlyingType st) noexcept
Definition strongenumflags.h:28
friend constexpr This operator&(This a, This b) noexcept
Definition strongenumflags.h:48
StrongEnumFlags< Self > This
Definition strongenumflags.h:21
friend constexpr bool operator==(This a, This b) noexcept
Definition strongenumflags.h:52
friend constexpr This operator|(This a, This b) noexcept
Definition strongenumflags.h:44
constexpr bool has(Self x) const noexcept
Definition strongenumflags.h:60