Created
June 6, 2018 08:41
-
-
Save eugeneko/03defe82d3536ef9cef7121895678950 to your computer and use it in GitHub Desktop.
Flag set template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// @file ls/common/FlagSet.h | |
/// @brief Flag set wrapper | |
#pragma once | |
#include "ls/common/import.h" | |
namespace ls | |
{ | |
/// @addtogroup LsCommon | |
/// @{ | |
/// @brief Flag Set | |
/// @tparam E Enum type | |
template <class E, class = enable_if_t<is_enum<E>::value>> | |
class FlagSet | |
{ | |
public: | |
/// @brief Enum type | |
using Enum = E; | |
/// @brief Integer type | |
using Integer = typename underlying_type<Enum>::type; | |
public: | |
/// @brief Ctor by integer | |
explicit FlagSet(const Integer& value) | |
: m_value(value) | |
{ | |
} | |
/// @brief Empty ctor | |
FlagSet() = default; | |
/// @brief Copy ctor | |
FlagSet(const FlagSet& another) = default; | |
/// @brief Ctor by enum | |
FlagSet(const Enum value) | |
: m_value((Integer) value) | |
{ | |
} | |
/// @brief Assign | |
FlagSet& operator = (const FlagSet& another) = default; | |
/// @brief AND Enum | |
FlagSet& operator &= (const Enum value) | |
{ | |
m_value &= (Integer) value; | |
return *this; | |
} | |
/// @brief AND FlagSet | |
FlagSet& operator &= (const FlagSet value) | |
{ | |
m_value &= value.m_value; | |
return *this; | |
} | |
/// @brief OR Enum | |
FlagSet& operator |= (const Enum value) | |
{ | |
m_value |= (Integer) value; | |
return *this; | |
} | |
/// @brief OR FlagSet | |
FlagSet& operator |= (const FlagSet value) | |
{ | |
m_value |= value.m_value; | |
return *this; | |
} | |
/// @brief XOR Enum | |
FlagSet& operator ^= (const Enum value) | |
{ | |
m_value ^= (Integer) value; | |
return *this; | |
} | |
/// @brief XOR FlagSet | |
FlagSet& operator ^= (const FlagSet value) | |
{ | |
m_value ^= value.m_value; | |
return *this; | |
} | |
/// @brief RESET Enum | |
FlagSet& operator -= (const Enum value) | |
{ | |
m_value &= ~(Integer) value; | |
return *this; | |
} | |
/// @brief RESET FlagSet | |
FlagSet& operator -= (const FlagSet value) | |
{ | |
m_value &= ~value.m_value; | |
return *this; | |
} | |
/// @brief AND Enum | |
FlagSet operator & (const Enum value) const | |
{ | |
return FlagSet(m_value & (Integer) value); | |
} | |
/// @brief AND FlagSet | |
FlagSet operator & (const FlagSet value) const | |
{ | |
return FlagSet(m_value & value.m_value); | |
} | |
/// @brief OR Enum | |
FlagSet operator | (const Enum value) const | |
{ | |
return FlagSet(m_value | (Integer) value); | |
} | |
/// @brief OR FlagSet | |
FlagSet operator | (const FlagSet value) const | |
{ | |
return FlagSet(m_value | value.m_value); | |
} | |
/// @brief XOR Enum | |
FlagSet operator ^ (const Enum value) const | |
{ | |
return FlagSet(m_value ^ (Integer) value); | |
} | |
/// @brief XOR FlagSet | |
FlagSet operator ^ (const FlagSet value) const | |
{ | |
return FlagSet(m_value ^ value.m_value); | |
} | |
/// @brief RESET Enum | |
FlagSet operator - (const Enum value) const | |
{ | |
return FlagSet(m_value & ~(Integer) value); | |
} | |
/// @brief RESET FlagSet | |
FlagSet operator - (const FlagSet value) const | |
{ | |
return FlagSet(m_value & ~value.m_value); | |
} | |
/// @brief Bitwise NOT | |
FlagSet operator ~ () const | |
{ | |
return FlagSet(~m_value); | |
} | |
/// @brief General NOT | |
bool operator ! () const | |
{ | |
return !m_value; | |
} | |
/// @brief Cast to integer | |
operator Integer() const | |
{ | |
return m_value; | |
} | |
/// @brief Test | |
inline bool is(const Enum value) const | |
{ | |
Integer flags = (Integer) value; | |
return (m_value & flags) == flags && (flags != 0 || m_value == flags); | |
} | |
protected: | |
/// @brief Value | |
Integer m_value = 0; | |
}; | |
/// @brief Operator OR for enums | |
template <class Enum, class = enable_if_t<IsEnumClass<Enum>::value>> | |
FlagSet<Enum> operator |(const Enum lhs, const Enum rhs) | |
{ | |
return FlagSet<Enum>(lhs) | rhs; | |
} | |
/// @brief Operator AND for enums | |
template <class Enum, class = enable_if_t<IsEnumClass<Enum>::value>> | |
FlagSet<Enum> operator & (const Enum lhs, const Enum rhs) | |
{ | |
return FlagSet<Enum>(lhs) & rhs; | |
} | |
/// @brief Operator XOR for enums | |
template <class Enum, class = enable_if_t<IsEnumClass<Enum>::value>> | |
FlagSet<Enum> operator ^ (const Enum lhs, const Enum rhs) | |
{ | |
return FlagSet<Enum>(lhs) ^ rhs; | |
} | |
/// @brief Operator RESET for enums | |
template <class Enum, class = enable_if_t<IsEnumClass<Enum>::value>> | |
FlagSet<Enum> operator - (const Enum lhs, const Enum rhs) | |
{ | |
return FlagSet<Enum>(lhs) - rhs; | |
} | |
/// @} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment