Types - Helper for enum-based flags

This commit is contained in:
Emmanuel BENOîT 2017-11-07 13:38:41 +01:00
parent 3adfdadd11
commit 82fc8406b3
2 changed files with 186 additions and 0 deletions

View file

@ -9,6 +9,47 @@
namespace ebcl { namespace ebcl {
/*= FLAGS HELPER =============================================================*/
// This class is meant to be used along with an enum that represents flags.
// The values from the enum are considered to be bit numbers.
template<
typename Enum ,
typename Storage = uint32_t
> class T_Flags
{
private:
Storage flags_;
public:
constexpr T_Flags( ) noexcept;
constexpr T_Flags( T_Flags const& other ) noexcept;
constexpr T_Flags( const Enum flag ) noexcept;
constexpr T_Flags( std::initializer_list< Enum > flags ) noexcept;
explicit constexpr T_Flags( const Storage flags ) noexcept;
constexpr T_Flags operator |=( T_Flags other ) noexcept;
constexpr T_Flags operator &=( T_Flags other ) noexcept;
constexpr T_Flags operator ^=( T_Flags other ) noexcept;
constexpr T_Flags operator ~( ) const noexcept;
constexpr T_Flags operator &( T_Flags other ) const noexcept;
constexpr T_Flags operator |( T_Flags other ) const noexcept;
constexpr T_Flags operator ^( T_Flags other ) const noexcept;
constexpr operator bool( ) const noexcept;
constexpr bool operator!( ) const noexcept;
explicit constexpr operator Storage( ) const noexcept;
constexpr bool operator ==( const T_Flags other ) const noexcept;
constexpr bool operator !=( const T_Flags other ) const noexcept;
constexpr bool isSet( const T_Flags value ) const noexcept;
constexpr bool isClear( const T_Flags value ) const noexcept;
};
/*= VARIANT TYPE =============================================================*/ /*= VARIANT TYPE =============================================================*/
// Forward declaration of the main variant type // Forward declaration of the main variant type

View file

@ -8,6 +8,151 @@
namespace ebcl { namespace ebcl {
/*= FLAGS HELPER =============================================================*/
template< typename E , typename S >
inline constexpr T_Flags< E , S >::T_Flags( ) noexcept
: flags_( 0 )
{ }
template< typename E , typename S >
inline constexpr T_Flags< E , S >::T_Flags(
T_Flags< E , S > const& other ) noexcept
: flags_( other.flags_ )
{ }
template< typename E , typename S >
inline constexpr T_Flags< E , S >::T_Flags(
const E flag ) noexcept
: flags_( 1 << int( flag ) )
{ }
template< typename E , typename S >
inline constexpr T_Flags< E , S >::T_Flags(
std::initializer_list< E > flags ) noexcept
: flags_( 0 )
{
for ( auto f : flags ) {
flags_ |= ( 1 << int( f ) );
}
}
/*----------------------------------------------------------------------------*/
template< typename E , typename S >
inline constexpr T_Flags< E , S >::T_Flags(
const S flags ) noexcept
: flags_( flags )
{ }
/*----------------------------------------------------------------------------*/
template< typename E , typename S >
inline constexpr T_Flags< E , S > T_Flags< E , S >::operator |=(
const T_Flags< E , S > other ) noexcept
{
flags_ |= other.flags_;
return *this;
}
template< typename E , typename S >
inline constexpr T_Flags< E , S > T_Flags< E , S >::operator &=(
const T_Flags< E , S > other ) noexcept
{
flags_ &= other.flags_;
return *this;
}
template< typename E , typename S >
inline constexpr T_Flags< E , S > T_Flags< E , S >::operator ^=(
const T_Flags< E , S > other ) noexcept
{
flags_ ^= other.flags_;
return *this;
}
/*----------------------------------------------------------------------------*/
template< typename E , typename S >
inline constexpr T_Flags<E , S > T_Flags< E , S >::operator ~( ) const noexcept
{
return T_Flags( ~flags_ );
}
template< typename E , typename S >
inline constexpr T_Flags< E , S > T_Flags< E , S >::operator &(
const T_Flags< E , S > other ) const noexcept
{
return T_Flags( flags_ & other.flags_ );
}
template< typename E , typename S >
inline constexpr T_Flags< E , S > T_Flags< E , S >::operator |(
const T_Flags< E , S > other ) const noexcept
{
return T_Flags( flags_ | other.flags_ );
}
template< typename E , typename S >
inline constexpr T_Flags< E , S > T_Flags< E , S >::operator ^(
const T_Flags< E , S > other ) const noexcept
{
return T_Flags( flags_ ^ other.flags_ );
}
/*----------------------------------------------------------------------------*/
template< typename E , typename S >
inline constexpr T_Flags< E , S >::operator bool( ) const noexcept
{
return flags_ != 0;
}
template< typename E , typename S >
inline constexpr bool T_Flags< E , S >::operator!( ) const noexcept
{
return flags_ == 0;
}
template< typename E , typename S >
inline constexpr T_Flags< E , S >::operator S( ) const noexcept
{
return flags_;
}
/*----------------------------------------------------------------------------*/
template< typename E , typename S >
inline constexpr bool T_Flags< E , S >::operator ==(
const T_Flags< E , S > other ) const noexcept
{
return flags_ == other.flags_;
}
template< typename E , typename S >
inline constexpr bool T_Flags< E , S >::operator !=(
const T_Flags< E , S > other ) const noexcept
{
return flags_ != other.flags_;
}
/*----------------------------------------------------------------------------*/
template< typename E , typename S >
inline constexpr bool T_Flags< E , S >::isSet(
const T_Flags< E , S > value ) const noexcept
{
return ( *this & value ) == value;
}
template< typename E , typename S >
inline constexpr bool T_Flags< E , S >::isClear(
const T_Flags< E , S > value ) const noexcept
{
return !( *this & value );
}
/*= VARIANT TYPE =============================================================*/ /*= VARIANT TYPE =============================================================*/
template< typename T > template< typename T >