-
-
Save fschoenberger/54c5342f220af510e1f78308a8994a45 to your computer and use it in GitHub Desktop.
Flags class for C++
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
module; | |
#include <compare> | |
#include <type_traits> | |
export module util:flags; | |
export namespace util { | |
template <typename BitType> | |
requires std::is_enum_v<BitType> | |
class Flags { | |
public: | |
using MaskType = std::underlying_type_t<BitType>; | |
// constructors | |
constexpr Flags() noexcept | |
: mask_(0) | |
{ | |
} | |
explicit(false) constexpr Flags(BitType bit) noexcept | |
: mask_(static_cast<MaskType>(bit)) | |
{ | |
} | |
constexpr Flags(Flags<BitType> const& rhs) noexcept = default; | |
constexpr explicit Flags(MaskType flags) noexcept | |
: mask_(flags) | |
{ | |
} | |
// relational operators | |
constexpr auto operator<=>(Flags<BitType> const&) const = default; | |
// logical operator | |
constexpr bool operator!() const noexcept { return !mask_; } | |
// bitwise operators | |
constexpr Flags<BitType> operator&(Flags<BitType> const& rhs) const noexcept { return Flags<BitType>(mask_ & rhs.mask_); } | |
constexpr Flags<BitType> operator|(Flags<BitType> const& rhs) const noexcept { return Flags<BitType>(mask_ | rhs.mask_); } | |
constexpr Flags<BitType> operator^(Flags<BitType> const& rhs) const noexcept { return Flags<BitType>(mask_ ^ rhs.mask_); } | |
constexpr Flags<BitType> operator~() const noexcept { return Flags<BitType>(mask_ ^ static_cast<MaskType>(-1)); } | |
// assignment operators | |
constexpr Flags<BitType>& operator=(Flags<BitType> const& rhs) noexcept = default; | |
constexpr Flags<BitType>& operator|=(Flags<BitType> const& rhs) noexcept | |
{ | |
mask_ |= rhs.mask_; | |
return *this; | |
} | |
constexpr Flags<BitType>& operator&=(Flags<BitType> const& rhs) noexcept | |
{ | |
mask_ &= rhs.mask_; | |
return *this; | |
} | |
constexpr Flags<BitType>& operator^=(Flags<BitType> const& rhs) noexcept | |
{ | |
mask_ ^= rhs.mask_; | |
return *this; | |
} | |
// cast operators | |
explicit constexpr operator bool() const noexcept { return !!mask_; } | |
explicit constexpr operator MaskType() const noexcept { return mask_; } | |
private: | |
MaskType mask_; | |
}; | |
// bitwise operators | |
template <typename BitType> | |
requires std::is_enum_v<BitType> | |
constexpr Flags<BitType> operator&(BitType bit, Flags<BitType> const& flags) noexcept | |
{ | |
return flags.operator&(bit); | |
} | |
template <typename BitType> | |
requires std::is_enum_v<BitType> | |
constexpr Flags<BitType> operator|(BitType bit, Flags<BitType> const& flags) noexcept | |
{ | |
return flags.operator|(bit); | |
} | |
template <typename BitType> | |
requires std::is_enum_v<BitType> | |
constexpr Flags<BitType> operator^(BitType bit, Flags<BitType> const& flags) noexcept | |
{ | |
return flags.operator^(bit); | |
} | |
// bitwise operators on BitType | |
template <typename BitType> | |
requires std::is_enum_v<BitType> | |
inline constexpr Flags<BitType> operator&(BitType lhs, BitType rhs) noexcept | |
{ | |
return Flags<BitType>(lhs) & rhs; | |
} | |
template <typename BitType> | |
requires std::is_enum_v<BitType> | |
inline constexpr Flags<BitType> operator|(BitType lhs, BitType rhs) noexcept | |
{ | |
return Flags<BitType>(lhs) | rhs; | |
} | |
template <typename BitType> | |
requires std::is_enum_v<BitType> | |
inline constexpr Flags<BitType> operator^(BitType lhs, BitType rhs) noexcept | |
{ | |
return Flags<BitType>(lhs) ^ rhs; | |
} | |
template <typename BitType> | |
requires std::is_enum_v<BitType> | |
inline constexpr Flags<BitType> operator~(BitType bit) noexcept | |
{ | |
return ~(Flags<BitType>(bit)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment