diff options
author | Daniil Rozanov <dev@rozanov.info> | 2025-03-15 18:03:23 +0400 |
---|---|---|
committer | Daniil Rozanov <dev@rozanov.info> | 2025-03-15 18:03:23 +0400 |
commit | 4a9ce6e2555dfaf9155fa279f25667350377f688 (patch) | |
tree | 11bc0ea3a7b1c0be2c47419b7058d46d16e5f9f4 /include/ncurses/utils |
feat: chtype wrap
Diffstat (limited to 'include/ncurses/utils')
-rw-r--r-- | include/ncurses/utils/flags.hpp | 156 | ||||
-rw-r--r-- | include/ncurses/utils/macros.hpp | 50 | ||||
-rw-r--r-- | include/ncurses/utils/modifiers.hpp | 31 | ||||
-rw-r--r-- | include/ncurses/utils/multiflags.hpp | 202 | ||||
-rw-r--r-- | include/ncurses/utils/preamble.hpp | 8 |
5 files changed, 447 insertions, 0 deletions
diff --git a/include/ncurses/utils/flags.hpp b/include/ncurses/utils/flags.hpp new file mode 100644 index 0000000..69b7aa9 --- /dev/null +++ b/include/ncurses/utils/flags.hpp @@ -0,0 +1,156 @@ +#ifndef INCLUDE_NCURSES_FLAGS_HPP_ +#define INCLUDE_NCURSES_FLAGS_HPP_ + +#include <type_traits> + +#include <ncurses/utils/preamble.hpp> + +namespace NCURSES_CPP_NAMESPACE { + +template <typename FlagBitsType> struct is_bitmask : public std::false_type {}; + +template <typename BitType, typename std::enable_if<is_bitmask<BitType>::value, + bool>::type = true> +class flags { +public: + using mask_type = typename std::underlying_type<BitType>::type; + + // constructors + NCURSES_CPP_CONSTEXPR flags() NCURSES_CPP_NOEXCEPT : mask_(0) {} + + NCURSES_CPP_CONSTEXPR flags(BitType bit) NCURSES_CPP_NOEXCEPT + : mask_(static_cast<mask_type>(bit)) {} + + NCURSES_CPP_CONSTEXPR + flags(flags<BitType> const &rhs) NCURSES_CPP_NOEXCEPT = default; + + NCURSES_CPP_CONSTEXPR explicit flags(mask_type flags) : mask_(flags) {} + + // relational operators + +#define NCURSES_CPP_RELATIONAL(op) \ + NCURSES_CPP_CONSTEXPR bool operator op(flags<BitType> const &rhs) \ + const NCURSES_CPP_NOEXCEPT { \ + return mask_ op rhs.mask_; \ + } + +#define NCURSES_CPP_BITWISE(op) \ + NCURSES_CPP_CONSTEXPR flags<BitType> operator op(flags<BitType> const &rhs) \ + const NCURSES_CPP_NOEXCEPT { \ + return flags<BitType>(mask_ op rhs.mask_); \ + } + +#define NCURSES_CPP_ASSIGNMENT(op) \ + NCURSES_CPP_CONSTEXPR_14 flags<BitType> &operator op##=( \ + flags<BitType> 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<BitType> operator~() const {*/ + /* return flags<BitType>(m_mask ^ is_bitmask<BitType>::allflags.m_mask);*/ + /*}*/ + + // assignment operators + NCURSES_CPP_CONSTEXPR_14 flags<BitType> & + operator=(flags<BitType> 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 !!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 <typename BitType, \ + typename std::enable_if<is_bitmask<BitType>::value, bool>::type = \ + true> \ + NCURSES_CPP_CONSTEXPR_INLINE type_arg operator op( \ + const BitType &bit, flags<BitType> const &flags) NCURSES_CPP_NOEXCEPT { \ + return flags.operator op(bit); \ + } + +#define NPP_DEF_GLOB_BITTYPE(op) \ + template <typename BitType, \ + typename std::enable_if<is_bitmask<BitType>::value, bool>::type = \ + true> \ + NCURSES_CPP_CONSTEXPR_INLINE flags<BitType> operator op( \ + BitType lhs, BitType rhs) NCURSES_CPP_NOEXCEPT { \ + return flags<BitType>(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<BitType>, 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 <typename BitType, + typename std::enable_if<is_bitmask<BitType>::value>::type> +NCURSES_CPP_CONSTEXPR_INLINE flags<BitType> +operator~(BitType bit) NCURSES_CPP_NOEXCEPT { + return ~(flags<BitType>(bit)); +} + +} // namespace NCURSES_CPP_NAMESPACE + +#endif // INCLUDE_NCURSES_FLAGS_HPP_ diff --git a/include/ncurses/utils/macros.hpp b/include/ncurses/utils/macros.hpp new file mode 100644 index 0000000..d26423b --- /dev/null +++ b/include/ncurses/utils/macros.hpp @@ -0,0 +1,50 @@ +#ifndef INCLUDE_NCURSES_MARCOS_HPP_ +#define INCLUDE_NCURSES_MARCOS_HPP_ + +#if !defined(NCURSES_CPP_NAMESPACE) +#define NCURSES_CPP_NAMESPACE ncurses +#endif + +#if defined(__cpp_constexpr) +#define NCURSES_CPP_CONSTEXPR constexpr +#if 201304 <= __cpp_constexpr +#define NCURSES_CPP_CONSTEXPR_14 constexpr +#else +#define NCURSES_CPP_CONSTEXPR_14 +#endif +#if (201907 <= __cpp_constexpr) && \ + (!defined(__GNUC__) || (110400 < GCC_VERSION)) +#define NCURSES_CPP_CONSTEXPR_20 constexpr +#else +#define NCURSES_CPP_CONSTEXPR_20 +#endif +#define NCURSES_CPP_CONST_OR_CONSTEXPR constexpr +#else +#define NCURSES_CPP_CONSTEXPR +#define NCURSES_CPP_CONSTEXPR_14 +#define NCURSES_CPP_CONST_OR_CONSTEXPR const +#endif + +#if !defined(NCURSES_CPP_CONSTEXPR_INLINE) +#if 201606L <= __cpp_inline_variables +#define NCURSES_CPP_CONSTEXPR_INLINE NCURSES_CPP_CONSTEXPR inline +#else +#define NCURSES_CPP_CONSTEXPR_INLINE NCURSES_CPP_CONSTEXPR +#endif +#endif + +#if !defined(NCURSES_CPP_NOEXCEPT) +#if defined(_MSC_VER) && (_MSC_VER <= 1800) +#define NCURSES_CPP_NOEXCEPT +#else +#define NCURSES_CPP_NOEXCEPT noexcept +#define NCURSES_CPP_HAS_NOEXCEPT 1 +#if defined(NCURSES_CPP_NO_EXCEPTIONS) +#define NCURSES_CPP_NOEXCEPT_WHEN_NO_EXCEPTIONS noexcept +#else +#define NCURSES_CPP_NOEXCEPT_WHEN_NO_EXCEPTIONS +#endif +#endif +#endif + +#endif // INCLUDE_NCURSES_MARCOS_HPP_ diff --git a/include/ncurses/utils/modifiers.hpp b/include/ncurses/utils/modifiers.hpp new file mode 100644 index 0000000..79e4139 --- /dev/null +++ b/include/ncurses/utils/modifiers.hpp @@ -0,0 +1,31 @@ +#ifndef INCLUDE_UTILS_MODIFIERS_HPP_ +#define INCLUDE_UTILS_MODIFIERS_HPP_ + +#include <type_traits> + +#include <ncurses/utils/flags.hpp> + +namespace NCURSES_CPP_NAMESPACE { + +template <typename Derived, typename ApplicantType> class composable { +public: + using flags_type = multiflags<ApplicantType>; + using flags_mask_type = multiflags<ApplicantType>; + + NCURSES_CPP_CONSTEXPR_14 composable & + operator&(const ApplicantType applicant) { + static_cast<Derived *>(this)->value_(); + } + + NCURSES_CPP_CONSTEXPR_14 composable &operator&(const flags_type &flags) { + value_ &= static_cast<flags_mask_type>(flags); + return *this; + } + +private: + value_type value_; +}; + +} // namespace NCURSES_CPP_NAMESPACE + +#endif // INCLUDE_UTILS_MODIFIERS_HPP_ diff --git a/include/ncurses/utils/multiflags.hpp b/include/ncurses/utils/multiflags.hpp new file mode 100644 index 0000000..e6af6a6 --- /dev/null +++ b/include/ncurses/utils/multiflags.hpp @@ -0,0 +1,202 @@ +#ifndef INCLUDE_UTILS_MULTIFLAGS_HPP_ +#define INCLUDE_UTILS_MULTIFLAGS_HPP_ + +#include <type_traits> + +#include "ncurses/utils/macros.hpp" +#include <ncurses/utils/flags.hpp> + +namespace NCURSES_CPP_NAMESPACE { + +template <typename FlagBitType, typename PrimaryType> +struct is_applyable : public std::false_type {}; + +template <typename BitType, typename SecondBitType> +using is_combosable_types = + typename std::enable_if<is_bitmask<BitType>::value && + is_applyable<SecondBitType, BitType>::value, + bool>::type; + +template <typename BitType, typename SecondBitType, + is_combosable_types<BitType, SecondBitType> = true> +class multiflags { +public: + using value_type = typename std::underlying_type<BitType>::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<value_type>(bit)) {} + + NCURSES_CPP_CONSTEXPR multiflags(SecondBitType bit) NCURSES_CPP_NOEXCEPT + : value_(static_cast<value_type>(bit)) {} + + NCURSES_CPP_CONSTEXPR multiflags(flags<BitType> flag) NCURSES_CPP_NOEXCEPT + : value_(static_cast<value_type>(flag)) {} + + NCURSES_CPP_CONSTEXPR + multiflags(multiflags<BitType, SecondBitType> 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<BitType, SecondBitType> 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<BitType, SecondBitType> operator op( \ + multiflags<BitType, SecondBitType> const &rhs) \ + const NCURSES_CPP_NOEXCEPT { \ + return multiflags<BitType, SecondBitType>(value_ op rhs.value_); \ + } + + NCURSES_CPP_BITWISE(&) + NCURSES_CPP_BITWISE(|) + NCURSES_CPP_BITWISE(^) + + /*NCURSES_CPP_CONSTEXPR multiflags<BitType> operator~() const {*/ + /* return multiflags<BitType>(m_mask ^ + * is_bitmask<BitType>::allmultiflags.m_mask);*/ + /*}*/ + + // assignment operators + +#define NCURSES_CPP_ASSIGNMENT(op) \ + NCURSES_CPP_CONSTEXPR_14 multiflags<BitType, SecondBitType> &operator op##=( \ + multiflags<BitType, SecondBitType> const &rhs) NCURSES_CPP_NOEXCEPT { \ + value_ op## = rhs.value_; \ + return *this; \ + } + + NCURSES_CPP_CONSTEXPR_14 multiflags<BitType, SecondBitType> & + operator=(multiflags<BitType, SecondBitType> 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 <typename BitType, typename SecondBitType, \ + is_combosable_types<BitType, SecondBitType> = true> \ + NCURSES_CPP_CONSTEXPR_INLINE type_arg operator op( \ + const pos &bit, multiflags<BitType, SecondBitType> const &flag) \ + NCURSES_CPP_NOEXCEPT { \ + return flag.operator op(bit); \ + } + +#define NPP_DEF_GLOB_OP_FLAGS(op) \ + template <typename BitType, typename SecondBitType, \ + is_combosable_types<BitType, SecondBitType> = true> \ + NCURSES_CPP_CONSTEXPR_INLINE multiflags<BitType, SecondBitType> operator op( \ + const flags<BitType> &flag, \ + multiflags<BitType, SecondBitType> const &mflags) NCURSES_CPP_NOEXCEPT { \ + return mflags.operator op( \ + static_cast<typename flags<BitType>::mask_type>(flag)); \ + } + +#define NPP_DEF_GLOB_BITTYPE(op) \ + template <typename BitType, typename SecondBitType, \ + is_combosable_types<BitType, SecondBitType> = true> \ + NCURSES_CPP_CONSTEXPR_INLINE multiflags<BitType, SecondBitType> operator op( \ + BitType lhs, SecondBitType rhs) NCURSES_CPP_NOEXCEPT { \ + return multiflags<BitType, SecondBitType>( \ + static_cast<typename multiflags<BitType, SecondBitType>::value_type>( \ + lhs) \ + op static_cast<typename multiflags< \ + BitType, SecondBitType>::second_value_type>(rhs)); \ + } \ + template <typename BitType, typename SecondBitType, \ + is_combosable_types<BitType, SecondBitType> = true> \ + NCURSES_CPP_CONSTEXPR_INLINE multiflags<BitType, SecondBitType> operator op( \ + SecondBitType lhs, BitType rhs) NCURSES_CPP_NOEXCEPT { \ + return rhs op lhs; \ + } \ + template <typename BitType, typename SecondBitType, \ + is_combosable_types<BitType, SecondBitType> = true> \ + NCURSES_CPP_CONSTEXPR_INLINE multiflags<BitType, SecondBitType> operator op( \ + flags<BitType> lhs, SecondBitType rhs) NCURSES_CPP_NOEXCEPT { \ + return multiflags<BitType, SecondBitType>( \ + static_cast<typename flags<BitType>::mask_type>(lhs) op static_cast< \ + typename multiflags<BitType, SecondBitType>::second_value_type>( \ + rhs)); \ + } \ + template <typename BitType, typename SecondBitType, \ + is_combosable_types<BitType, SecondBitType> = true> \ + NCURSES_CPP_CONSTEXPR_INLINE multiflags<BitType, SecondBitType> operator op( \ + SecondBitType lhs, flags<BitType> 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_ diff --git a/include/ncurses/utils/preamble.hpp b/include/ncurses/utils/preamble.hpp new file mode 100644 index 0000000..4571a75 --- /dev/null +++ b/include/ncurses/utils/preamble.hpp @@ -0,0 +1,8 @@ +#ifndef INCLUDE_UTILS_PREAMBLE_HPP_ +#define INCLUDE_UTILS_PREAMBLE_HPP_ + +#include <ncurses.h> + +#include <ncurses/utils/macros.hpp> + +#endif // INCLUDE_UTILS_PREAMBLE_HPP_ |