#ifndef INCLUDE_UTILS_MULTIFLAGS_HPP_ #define INCLUDE_UTILS_MULTIFLAGS_HPP_ #include #include "ncurses/utils/macros.hpp" #include namespace NCURSES_CPP_NAMESPACE { template struct is_applyable : public std::false_type {}; template using is_combosable_types = typename std::enable_if::value && is_applyable::value, bool>::type; template = true> class multiflags { public: using value_type = typename std::underlying_type::type; using second_value_type = typename SecondBitType::value_type; // constructors NCURSES_CPP_CONSTEXPR multiflags() NCURSES_CPP_NOEXCEPT : value_(0) {} NCURSES_CPP_CONSTEXPR multiflags(BitType bit) NCURSES_CPP_NOEXCEPT : value_(static_cast(bit)) {} NCURSES_CPP_CONSTEXPR multiflags(SecondBitType bit) NCURSES_CPP_NOEXCEPT : value_(static_cast(bit)) {} NCURSES_CPP_CONSTEXPR multiflags(flags flag) NCURSES_CPP_NOEXCEPT : value_(static_cast(flag)) {} NCURSES_CPP_CONSTEXPR multiflags(multiflags const &rhs) NCURSES_CPP_NOEXCEPT = default; NCURSES_CPP_CONSTEXPR explicit multiflags(value_type multiflags) : value_(multiflags) {} // relational operators #define NCURSES_CPP_RELATIONAL(op) \ NCURSES_CPP_CONSTEXPR bool operator op( \ multiflags const &rhs) \ const NCURSES_CPP_NOEXCEPT { \ return value_ op rhs.value_; \ } NCURSES_CPP_RELATIONAL(==) NCURSES_CPP_RELATIONAL(!=) // logical operator NCURSES_CPP_CONSTEXPR bool operator!() const NCURSES_CPP_NOEXCEPT { return !value_; } // bitwise operators #define NCURSES_CPP_BITWISE(op) \ NCURSES_CPP_CONSTEXPR multiflags operator op( \ multiflags const &rhs) \ const NCURSES_CPP_NOEXCEPT { \ return multiflags(value_ op rhs.value_); \ } NCURSES_CPP_BITWISE(&) NCURSES_CPP_BITWISE(|) NCURSES_CPP_BITWISE(^) /*NCURSES_CPP_CONSTEXPR multiflags operator~() const {*/ /* return multiflags(m_mask ^ * is_bitmask::allmultiflags.m_mask);*/ /*}*/ // assignment operators #define NCURSES_CPP_ASSIGNMENT(op) \ NCURSES_CPP_CONSTEXPR_14 multiflags &operator op##=( \ multiflags const &rhs) NCURSES_CPP_NOEXCEPT { \ value_ op## = rhs.value_; \ return *this; \ } NCURSES_CPP_CONSTEXPR_14 multiflags & operator=(multiflags const &rhs) NCURSES_CPP_NOEXCEPT = default; NCURSES_CPP_ASSIGNMENT(&) NCURSES_CPP_ASSIGNMENT(|) NCURSES_CPP_ASSIGNMENT(^) // cast operators explicit NCURSES_CPP_CONSTEXPR operator bool() const NCURSES_CPP_NOEXCEPT { return !!value_; } explicit NCURSES_CPP_CONSTEXPR operator value_type() const NCURSES_CPP_NOEXCEPT { return value_; } #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 value_type value_; }; // TODO:const BitType& - link may be not as good as copy #define NPP_DEF_GLOB_OP(type_arg, op, pos) \ template = true> \ NCURSES_CPP_CONSTEXPR_INLINE type_arg operator op( \ const pos &bit, multiflags const &flag) \ NCURSES_CPP_NOEXCEPT { \ return flag.operator op(bit); \ } #define NPP_DEF_GLOB_OP_FLAGS(op) \ template = true> \ NCURSES_CPP_CONSTEXPR_INLINE multiflags operator op( \ const flags &flag, \ multiflags const &mflags) NCURSES_CPP_NOEXCEPT { \ return mflags.operator op( \ static_cast::mask_type>(flag)); \ } #define NPP_DEF_GLOB_BITTYPE(op) \ template = true> \ NCURSES_CPP_CONSTEXPR_INLINE multiflags operator op( \ BitType lhs, SecondBitType rhs) NCURSES_CPP_NOEXCEPT { \ return multiflags( \ static_cast::value_type>( \ lhs) \ op static_cast::second_value_type>(rhs)); \ } \ template = true> \ NCURSES_CPP_CONSTEXPR_INLINE multiflags operator op( \ SecondBitType lhs, BitType rhs) NCURSES_CPP_NOEXCEPT { \ return rhs op lhs; \ } \ template = true> \ NCURSES_CPP_CONSTEXPR_INLINE multiflags operator op( \ flags lhs, SecondBitType rhs) NCURSES_CPP_NOEXCEPT { \ return multiflags( \ static_cast::mask_type>(lhs) op static_cast< \ typename multiflags::second_value_type>( \ rhs)); \ } \ template = true> \ NCURSES_CPP_CONSTEXPR_INLINE multiflags operator op( \ SecondBitType lhs, flags rhs) NCURSES_CPP_NOEXCEPT { \ return rhs op lhs; \ } #define NPP_DEF_GLOB_OP_BOOL_FIRST(op) NPP_DEF_GLOB_OP(bool, op, BitType) #define NPP_DEF_GLOB_OP_BOOL_SECOND(op) NPP_DEF_GLOB_OP(bool, op, SecondBitType) #if !defined(NCURSES_CPP_HAS_SPACESHIP_OPERATOR) // relational operators only needed for pre C++20 NPP_DEF_GLOB_OP_BOOL_FIRST(==) NPP_DEF_GLOB_OP_BOOL_FIRST(!=) NPP_DEF_GLOB_OP_BOOL_SECOND(==) NPP_DEF_GLOB_OP_BOOL_SECOND(!=) #endif NPP_DEF_GLOB_OP_FLAGS(&) NPP_DEF_GLOB_OP_FLAGS(|) NPP_DEF_GLOB_OP_FLAGS(^) // 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_FLAGS #undef NPP_DEF_GLOB_BITTYPE #undef NPP_DEF_GLOB_OP_BOOL_FIRST #undef NPP_DEF_GLOB_OP_BOOL_SECOND } // namespace NCURSES_CPP_NAMESPACE #endif // INCLUDE_UTILS_MULTIFLAGS_HPP_