summaryrefslogtreecommitdiff
path: root/include/ncurses/utils
diff options
context:
space:
mode:
authorDaniil Rozanov <dev@rozanov.info>2025-03-15 18:03:23 +0400
committerDaniil Rozanov <dev@rozanov.info>2025-03-15 18:03:23 +0400
commit4a9ce6e2555dfaf9155fa279f25667350377f688 (patch)
tree11bc0ea3a7b1c0be2c47419b7058d46d16e5f9f4 /include/ncurses/utils
feat: chtype wrap
Diffstat (limited to 'include/ncurses/utils')
-rw-r--r--include/ncurses/utils/flags.hpp156
-rw-r--r--include/ncurses/utils/macros.hpp50
-rw-r--r--include/ncurses/utils/modifiers.hpp31
-rw-r--r--include/ncurses/utils/multiflags.hpp202
-rw-r--r--include/ncurses/utils/preamble.hpp8
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_