strongenumflags.h
Go to the documentation of this file.
// -*- C++ -*- (c) 2013 Vladimír Štill <xstill@fi.muni.cz>
#if __cplusplus < 201103L
#error "strongenumflag is only supported with c++11 or newer"
#endif
#include <type_traits>
#ifndef WIBBLE_STRONGENUMFLAG_H
#define WIBBLE_STRONGENUMFLAG_H
namespace wibble {
template< typename E >
using is_enum_class = std::integral_constant< bool,
std::is_enum< E >::value && !std::is_convertible< E, int >::value >;
template< typename Self >
struct StrongEnumFlags {
static_assert( is_enum_class< Self >::value, "Not an enum class." );
using This = StrongEnumFlags< Self >;
using UnderlyingType = typename std::underlying_type< Self >::type;
constexpr StrongEnumFlags() noexcept : store( 0 ) { }
constexpr StrongEnumFlags( Self flag ) noexcept :
store( static_cast< UnderlyingType >( flag ) )
{ }
explicit constexpr StrongEnumFlags( UnderlyingType st ) noexcept : store( st ) { }
constexpr explicit operator UnderlyingType() const noexcept {
return store;
}
This &operator|=( This o ) noexcept {
store |= o.store;
return *this;
}
This &operator&=( This o ) noexcept {
store &= o.store;
return *this;
}
friend constexpr This operator|( This a, This b ) noexcept {
return This( a.store | b.store );
}
friend constexpr This operator&( This a, This b ) noexcept {
return This( a.store & b.store );
}
friend constexpr bool operator==( This a, This b ) noexcept {
return a.store == b.store;
}
friend constexpr bool operator!=( This a, This b ) noexcept {
return a.store != b.store;
}
constexpr bool has( Self x ) const noexcept {
return (*this) & x;
}
constexpr operator bool() const noexcept {
return store;
}
private:
UnderlyingType store;
};
// don't catch integral types and classical enum!
template< typename Self, typename = typename
std::enable_if< is_enum_class< Self >::value >::type >
constexpr StrongEnumFlags< Self > operator|( Self a, Self b ) noexcept {
using Ret = StrongEnumFlags< Self >;
return Ret( a ) | Ret( b );
}
template< typename Self, typename = typename
std::enable_if< is_enum_class< Self >::value >::type >
constexpr StrongEnumFlags< Self > operator&( Self a, Self b ) noexcept {
using Ret = StrongEnumFlags< Self >;
return Ret( a ) & Ret( b );
}
}
#endif // WIBBLE_STRONGENUMFLAG_H
wibble::StrongEnumFlags::operator &
friend constexpr This operator &(This a, This b) noexcept
Definition: strongenumflags.h:48
wibble::StrongEnumFlags::operator &=
This & operator &=(This o) noexcept
Definition: strongenumflags.h:39
wibble::StrongEnumFlags::operator|
friend constexpr This operator|(This a, This b) noexcept
Definition: strongenumflags.h:44
wibble::is_enum_class
std::integral_constant< bool, std::is_enum< E >::value &&!std::is_convertible< E, int >::value > is_enum_class
Definition: strongenumflags.h:16
wibble::StrongEnumFlags::has
constexpr bool has(Self x) const noexcept
Definition: strongenumflags.h:60
wibble::StrongEnumFlags
Definition: strongenumflags.h:19
wibble::StrongEnumFlags::operator|=
This & operator|=(This o) noexcept
Definition: strongenumflags.h:34
wibble::StrongEnumFlags::operator!=
friend constexpr bool operator!=(This a, This b) noexcept
Definition: strongenumflags.h:56
wibble::StrongEnumFlags::This
StrongEnumFlags< Self > This
Definition: strongenumflags.h:21
wibble::StrongEnumFlags::StrongEnumFlags
constexpr StrongEnumFlags(UnderlyingType st) noexcept
Definition: strongenumflags.h:28
wibble::StrongEnumFlags::StrongEnumFlags
constexpr StrongEnumFlags(Self flag) noexcept
Definition: strongenumflags.h:25
wibble
Definition: amorph.h:17
wibble::StrongEnumFlags::operator==
friend constexpr bool operator==(This a, This b) noexcept
Definition: strongenumflags.h:52
wibble::StrongEnumFlags< ProtectMode >::UnderlyingType
typename std::underlying_type< ProtectMode >::type UnderlyingType
Definition: strongenumflags.h:22
wibble::StrongEnumFlags::StrongEnumFlags
constexpr StrongEnumFlags() noexcept
Definition: strongenumflags.h:24