#ifndef INCLUDE_NCURSES_FLAGS_HPP_ #define INCLUDE_NCURSES_FLAGS_HPP_ #include #include namespace NCURSES_CPP_NAMESPACE { template struct is_bitmask : public std::false_type {}; template ::value, bool>::type = true> class flags { public: using mask_type = typename std::underlying_type::type; // constructors NCURSES_CPP_CONSTEXPR flags() NCURSES_CPP_NOEXCEPT : mask_(0) {} NCURSES_CPP_CONSTEXPR flags(BitType bit) NCURSES_CPP_NOEXCEPT : mask_(static_cast(bit)) {} NCURSES_CPP_CONSTEXPR flags(flags const &rhs) NCURSES_CPP_NOEXCEPT : mask_(rhs.mask_) {} NCURSES_CPP_CONSTEXPR explicit flags(mask_type flags) : mask_(flags) {} // relational operators #define NCURSES_CPP_RELATIONAL(op) \ NCURSES_CPP_CONSTEXPR bool operator op(flags const &rhs) \ const NCURSES_CPP_NOEXCEPT { \ return mask_ op rhs.mask_; \ } #define NCURSES_CPP_BITWISE(op) \ NCURSES_CPP_CONSTEXPR flags operator op(flags const &rhs) \ const NCURSES_CPP_NOEXCEPT { \ return flags(mask_ op rhs.mask_); \ } #define NCURSES_CPP_ASSIGNMENT(op) \ NCURSES_CPP_CONSTEXPR_14 flags &operator op##=( \ flags const &rhs) NCURSES_CPP_NOEXCEPT { \ mask_ op## = rhs.mask_; \ return *this; \ } NCURSES_CPP_RELATIONAL(<) NCURSES_CPP_RELATIONAL(<=) NCURSES_CPP_RELATIONAL(>) NCURSES_CPP_RELATIONAL(>=) NCURSES_CPP_RELATIONAL(==) NCURSES_CPP_RELATIONAL(!=) // logical operator NCURSES_CPP_CONSTEXPR bool operator!() const NCURSES_CPP_NOEXCEPT { return !mask_; } // bitwise operators NCURSES_CPP_BITWISE(&) NCURSES_CPP_BITWISE(|) NCURSES_CPP_BITWISE(^) /*NCURSES_CPP_CONSTEXPR flags operator~() const {*/ /* return flags(m_mask ^ is_bitmask::allflags.m_mask);*/ /*}*/ // assignment operators NCURSES_CPP_CONSTEXPR_14 flags & operator=(flags const &rhs) NCURSES_CPP_NOEXCEPT { mask_ = rhs.mask_; return *this; } NCURSES_CPP_ASSIGNMENT(&) NCURSES_CPP_ASSIGNMENT(|) NCURSES_CPP_ASSIGNMENT(^) // cast operators explicit NCURSES_CPP_CONSTEXPR operator bool() const NCURSES_CPP_NOEXCEPT { return !!mask_; } explicit NCURSES_CPP_CONSTEXPR operator mask_type() const NCURSES_CPP_NOEXCEPT { return mask_; } #undef NCURSES_CPP_RELATIONAL #undef NCURSES_CPP_BITWISE #undef NCURSES_CPP_ASSIGNMENT #if defined(NCURSES_CPP_FLAGS_MASK_TYPE_AS_PUBLIC) public: #else private: #endif mask_type mask_; }; // TODO:const BitType& - link may be not as good as copy #define NPP_DEF_GLOB_OP(type_arg, op) \ template ::value, bool>::type = \ true> \ NCURSES_CPP_CONSTEXPR_INLINE type_arg operator op( \ const BitType &bit, flags const &flags) NCURSES_CPP_NOEXCEPT { \ return flags.operator op(bit); \ } #define NPP_DEF_GLOB_BITTYPE(op) \ template ::value, bool>::type = \ true> \ NCURSES_CPP_CONSTEXPR_INLINE flags operator op( \ BitType lhs, BitType rhs) NCURSES_CPP_NOEXCEPT { \ return flags(lhs) op rhs; \ } #define NPP_DEF_GLOB_OP_BOOL(op) NPP_DEF_GLOB_OP(bool, op) #define NPP_DEF_GLOB_OP_FLAG(op) NPP_DEF_GLOB_OP(flags, op) #if !defined(NCURSES_CPP_HAS_SPACESHIP_OPERATOR) // relational operators only needed for pre C++20 NPP_DEF_GLOB_OP_BOOL(<) NPP_DEF_GLOB_OP_BOOL(<=) NPP_DEF_GLOB_OP_BOOL(>) NPP_DEF_GLOB_OP_BOOL(>=) NPP_DEF_GLOB_OP_BOOL(==) NPP_DEF_GLOB_OP_BOOL(!=) #endif NPP_DEF_GLOB_OP_FLAG(&) NPP_DEF_GLOB_OP_FLAG(|) NPP_DEF_GLOB_OP_FLAG(^) // bitwise operators on BitType NPP_DEF_GLOB_BITTYPE(&) NPP_DEF_GLOB_BITTYPE(|) NPP_DEF_GLOB_BITTYPE(^) #undef NPP_DEF_GLOB_OP #undef NPP_DEF_GLOB_OP_BOOL #undef NPP_DEF_GLOB_OP_FLAG #undef NPP_DEF_GLOB_BITTYPE template ::value>::type> NCURSES_CPP_CONSTEXPR_INLINE flags operator~(BitType bit) NCURSES_CPP_NOEXCEPT { return ~(flags(bit)); } } // namespace NCURSES_CPP_NAMESPACE #endif // INCLUDE_NCURSES_FLAGS_HPP_