diff --git a/README.md b/README.md index 11fde4c..00904e8 100644 --- a/README.md +++ b/README.md @@ -201,29 +201,36 @@ int main() { ## API -- [Enum traits](#Enum-traits) -- [Generic functions](#Generic-functions) +- `enum.hpp` + - [Enum traits](#Enum-traits) + - [Enum generic functions](#Enum-generic-functions) +- `enum_bitflags.hpp` + - [Enum bitflags](#Enum-bitflags) + - [Enum operators](#Enum-operators) + - [Enum bitflags operators](#Enum-bitflags-operators) + - [Enum bitflags functions](#Enum-bitflags-functions) ### Enum traits ```cpp -// declare unscoped enumeration +// declares unscoped enumeration ENUM_HPP_DECL( /*enum_name*/, /*underlying_type*/, /*fields*/) -// declare scoped enumeration +// declares scoped enumeration ENUM_HPP_CLASS_DECL( /*enum_name*/, /*underlying_type*/, /*fields*/) -// declare only traits for external enumerations +// declares only traits for external enumerations ENUM_HPP_TRAITS_DECL( /*enum_name*/, /*fields*/) +// declared enumeration traits struct /*enum_name*/_traits { using enum_type = /*enum_name*/; using underlying_type = /*underlying_type*/; @@ -257,7 +264,7 @@ struct /*enum_name*/_traits { }; ``` -### Generic functions +### Enum generic functions ```cpp // should be in enum namespace @@ -321,6 +328,202 @@ namespace enum_hpp } ``` +### Enum bitflags + +```cpp +namespace enum_hpp::bitflags +{ + template < typename Enum > + class bitflags final { + public: + using enum_type = Enum; + using underlying_type = std::underlying_type_t; + + bitflags() = default; + bitflags(const bitflags&) = default; + bitflags& operator=(const bitflags&) = default; + + constexpr bitflags(enum_type flags); + constexpr explicit bitflags(underlying_type flags); + + constexpr void swap(bitflags& other) noexcept; + constexpr explicit operator bool() const noexcept; + + constexpr underlying_type as_raw() const noexcept; + constexpr enum_type as_enum() const noexcept; + + constexpr bool has(bitflags flags) const noexcept; + constexpr bitflags& set(bitflags flags) noexcept; + constexpr bitflags& toggle(bitflags flags) noexcept; + constexpr bitflags& clear(bitflags flags) noexcept; + }; + + template < typename Enum > + constexpr void swap(bitflags& l, bitflags& r) noexcept; +} + +namespace std +{ + template < typename Enum > + struct hash> { + size_t operator()(enum_hpp::bitflags::bitflags bf) const noexcept; + }; +} +``` + +### Enum operators + +```cpp +// declares enumeration operators +ENUM_HPP_OPERATORS_DECL(/*enum_name*/) + +// declared enumeration operators +constexpr bitflags operator ~ (/*enum_name*/ l) noexcept; +constexpr bitflags operator | (/*enum_name*/ l, /*enum_name*/ r) noexcept; +constexpr bitflags operator & (/*enum_name*/ l, /*enum_name*/ r) noexcept; +constexpr bitflags operator ^ (/*enum_name*/ l, /*enum_name*/ r) noexcept; +``` + +### Enum bitflags operators + +```cpp +namespace enum_hpp::bitflags +{ + template < typename Enum > + constexpr bool operator < (Enum l, bitflags r) noexcept; + + template < typename Enum > + constexpr bool operator < (bitflags l, Enum r) noexcept; + + template < typename Enum > + constexpr bool operator < (std::underlying_type_t l, bitflags r) noexcept; + + template < typename Enum > + constexpr bool operator < (bitflags l, std::underlying_type_t r) noexcept; + + template < typename Enum > + constexpr bool operator < (bitflags l, bitflags r) noexcept; + + // and also for other comparison operators (<, >, <=, >=, ==, !=) +} + +namespace enum_hpp::bitflags +{ + template < typename Enum > + constexpr bitflags operator ~ (bitflags l) noexcept; + + template < typename Enum > + constexpr bitflags operator | (Enum l, bitflags r) noexcept; + + template < typename Enum > + constexpr bitflags operator | (bitflags l, Enum r) noexcept; + + template < typename Enum > + constexpr bitflags operator | (bitflags l, bitflags r) noexcept; + + template < typename Enum > + constexpr bitflags& operator |= (bitflags& l, Enum r) noexcept; + + template < typename Enum > + constexpr bitflags& operator |= (bitflags& l, bitflags r) noexcept; + + // and also for other bitwise logic operators (|, |=, &, &=, ^, ^=) +} +``` + +### Enum bitflags functions + +```cpp +namespace enum_hpp::bitflags +{ + // any + + template < enum Enum > + constexpr bool any(Enum flags) noexcept; + + template < typename Enum > + constexpr bool any(bitflags flags) noexcept; + + // none + + template < enum Enum > + constexpr bool none(Enum flags) noexcept; + + template < typename Enum > + constexpr bool none(bitflags flags) noexcept; + + // all_of + + template < enum Enum > + constexpr bool all_of(Enum flags, Enum mask) noexcept; + + template < typename Enum > + constexpr bool all_of(Enum flags, bitflags mask) noexcept; + + template < typename Enum > + constexpr bool all_of(bitflags flags, Enum mask) noexcept; + + template < typename Enum > + constexpr bool all_of(bitflags flags, bitflags mask) noexcept; + + // any_of + + template < enum Enum > + constexpr bool any_of(Enum flags, Enum mask) noexcept; + + template < typename Enum > + constexpr bool any_of(Enum flags, bitflags mask) noexcept; + + template < typename Enum > + constexpr bool any_of(bitflags flags, Enum mask) noexcept; + + template < typename Enum > + constexpr bool any_of(bitflags flags, bitflags mask) noexcept; + + // none_of + + template < enum Enum > + constexpr bool none_of(Enum flags, Enum mask) noexcept; + + template < typename Enum > + constexpr bool none_of(Enum flags, bitflags mask) noexcept; + + template < typename Enum > + constexpr bool none_of(bitflags flags, Enum mask) noexcept; + + template < typename Enum > + constexpr bool none_of(bitflags flags, bitflags mask) noexcept; + + // any_except + + template < enum Enum > + constexpr bool any_except(Enum flags, Enum mask) noexcept; + + template < typename Enum > + constexpr bool any_except(Enum flags, bitflags mask) noexcept; + + template < typename Enum > + constexpr bool any_except(bitflags flags, Enum mask) noexcept; + + template < typename Enum > + constexpr bool any_except(bitflags flags, bitflags mask) noexcept; + + // none_except + + template < enum Enum > + constexpr bool none_except(Enum flags, Enum mask) noexcept; + + template < typename Enum > + constexpr bool none_except(Enum flags, bitflags mask) noexcept; + + template < typename Enum > + constexpr bool none_except(bitflags flags, Enum mask) noexcept; + + template < typename Enum > + constexpr bool none_except(bitflags flags, bitflags mask) noexcept; +} +``` + ## Alternatives [Better Enums](https://github.com/aantron/better-enums) diff --git a/headers/enum.hpp/enum_bitflags.hpp b/headers/enum.hpp/enum_bitflags.hpp index 4d69b17..a8884b9 100644 --- a/headers/enum.hpp/enum_bitflags.hpp +++ b/headers/enum.hpp/enum_bitflags.hpp @@ -13,7 +13,7 @@ namespace enum_hpp::bitflags { template < typename Enum > - class bitflags { + class bitflags final { static_assert(std::is_enum_v); public: using enum_type = Enum; @@ -23,17 +23,17 @@ namespace enum_hpp::bitflags bitflags(const bitflags&) = default; bitflags& operator=(const bitflags&) = default; - constexpr void swap(bitflags& other) noexcept { - using std::swap; - swap(flags_, other.flags_); - } - constexpr bitflags(enum_type flags) : flags_(static_cast(flags)) {} constexpr explicit bitflags(underlying_type flags) : flags_(flags) {} + constexpr void swap(bitflags& other) noexcept { + using std::swap; + swap(flags_, other.flags_); + } + constexpr explicit operator bool() const noexcept { return !!flags_; } @@ -311,10 +311,10 @@ namespace enum_hpp::bitflags } // -// ENUM_HPP_REGISTER_BITFLAGS_OPERATORS +// ENUM_HPP_OPERATORS_DECL // -#define ENUM_HPP_REGISTER_BITFLAGS_OPERATORS(Enum)\ +#define ENUM_HPP_OPERATORS_DECL(Enum)\ constexpr ::enum_hpp::bitflags::bitflags operator~ [[maybe_unused]] (Enum l) noexcept {\ return ~::enum_hpp::bitflags::bitflags(l);\ }\ diff --git a/untests/enum_bitflags_tests.cpp b/untests/enum_bitflags_tests.cpp index 0316a9f..6e539b6 100644 --- a/untests/enum_bitflags_tests.cpp +++ b/untests/enum_bitflags_tests.cpp @@ -22,7 +22,7 @@ namespace all = read_write | execute }; - ENUM_HPP_REGISTER_BITFLAGS_OPERATORS(access) + ENUM_HPP_OPERATORS_DECL(access) } TEST_CASE("enum_bitflags") {