Skip to content

Instantly share code, notes, and snippets.

@eugeneko
Created June 6, 2018 08:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eugeneko/03defe82d3536ef9cef7121895678950 to your computer and use it in GitHub Desktop.
Save eugeneko/03defe82d3536ef9cef7121895678950 to your computer and use it in GitHub Desktop.
Flag set template
/// @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