37#ifndef DEADDEV_BITMASK_HPP
38#define DEADDEV_BITMASK_HPP
44#ifndef DEADDEV_CONSTEVAL
45#if __cplusplus >= 202002L
46#define DEADDEV_CONSTEVAL consteval
48#define DEADDEV_CONSTEVAL constexpr
52#ifndef DEADDEV_NODISCARD
53#if defined(__has_cpp_attribute) && __has_cpp_attribute(nodiscard)
54#define DEADDEV_NODISCARD [[nodiscard]]
56#define DEADDEV_NODISCARD
70#ifdef __cpp_lib_is_scoped_enum
76template <
typename T>
constexpr bool is_scoped_enum_v = ::std::is_scoped_enum_v<T>;
77#elif defined(__has_builtin) && __has_builtin(__is_scoped_enum)
93 ::std::is_enum<T>::value &&
94 !::std::is_convertible<T, typename ::std::underlying_type<T>::type>::value;
117DEADDEV_CONSTEVAL
auto combine_flags(::std::underlying_type_t<T> &result, T value)
119 result |=
static_cast<::std::underlying_type_t<T>
>(value);
122#if __cplusplus < 201703L
132 return static_cast<T
>(val);
143template <
typename T,
typename... Args>
145 return static_cast<T
>(
static_cast<typename ::std::underlying_type<T>::type
>(arg) |
146 static_cast<typename ::std::underlying_type<T>::type
>(
150template <
typename T,
typename... Args>
151DEADDEV_CONSTEVAL
auto calculate_all_flags_cpp_17(Args... args) -> T {
152 ::std::underlying_type_t<T> result{0};
154 return static_cast<T
>(result);
166template <
typename T,
typename... Args>
168#if __cplusplus < 201703L
171 return calculate_all_flags_cpp_17<T>(args...);
181 return static_cast<T
>((1ull << ((
sizeof(T) * CHAR_BIT) - 1)) - 1);
214 : decltype(adl_bitmask_operations_check(::std::declval<T &>())){};
223 typename = typename ::std::enable_if<::std::is_enum<T>::value>::type>
225#ifdef DEADDEV_ENABLE_BITMASKS_FOR_SCOPED_ENUMS
237 typename = typename ::std::enable_if<::std::is_enum<T>::value>::type>
251 typename = typename ::std::enable_if<::deaddev::details::is_bitmask_v<T>>::type>
285 DEADDEV_NODISCARD
explicit constexpr operator enum_type() const noexcept {
293 DEADDEV_NODISCARD
explicit constexpr operator mask_type() const noexcept {
307 return mask_ == mask;
311 return mask_ != mask;
315 return mask_ <= mask;
319 return mask_ >= mask;
331 return mask_ == other.mask_;
335 return mask_ != other.mask_;
339 return mask_ <= other.mask_;
343 return mask_ >= other.mask_;
347 return mask_ < other.mask_;
351 return mask_ > other.mask_;
361 return bitmask(mask_ ^ other.mask_);
366 return bitmask(mask_ | other.mask_);
371 return bitmask(mask_ & other.mask_);
376 mask_ ^= other.mask_;
382 mask_ |= other.mask_;
388 mask_ &= other.mask_;
446 return (mask_ & other.mask_) == other.mask_;
490template <
typename T,
typename = ::std::enable_if<::deaddev::details::is_bitmask_v<T>>>
492 return right == left;
494template <
typename T,
typename = ::std::enable_if<::deaddev::details::is_bitmask_v<T>>>
496 return right != left;
498template <
typename T,
typename = ::std::enable_if<::deaddev::details::is_bitmask_v<T>>>
500 return right <= left;
502template <
typename T,
typename = ::std::enable_if<::deaddev::details::is_bitmask_v<T>>>
504 return right >= left;
506template <
typename T,
typename = ::std::enable_if<::deaddev::details::is_bitmask_v<T>>>
510template <
typename T,
typename = ::std::enable_if<::deaddev::details::is_bitmask_v<T>>>
514template <
typename T,
typename = ::std::enable_if<::deaddev::details::is_bitmask_v<T>>>
515DEADDEV_NODISCARD
constexpr bool operator==(
typename std::underlying_type<T>::type left,
517 return right == left;
519template <
typename T,
typename = ::std::enable_if<::deaddev::details::is_bitmask_v<T>>>
520DEADDEV_NODISCARD
constexpr bool operator!=(
typename std::underlying_type<T>::type left,
522 return right != left;
524template <
typename T,
typename = ::std::enable_if<::deaddev::details::is_bitmask_v<T>>>
525DEADDEV_NODISCARD
constexpr bool operator>=(
typename std::underlying_type<T>::type left,
527 return right <= left;
529template <
typename T,
typename = ::std::enable_if<::deaddev::details::is_bitmask_v<T>>>
530DEADDEV_NODISCARD
constexpr bool operator<=(
typename std::underlying_type<T>::type left,
532 return right >= left;
534template <
typename T,
typename = ::std::enable_if<::deaddev::details::is_bitmask_v<T>>>
535DEADDEV_NODISCARD
constexpr bool operator<(
typename std::underlying_type<T>::type left,
539template <
typename T,
typename = ::std::enable_if<::deaddev::details::is_bitmask_v<T>>>
540DEADDEV_NODISCARD
constexpr bool operator>(
typename std::underlying_type<T>::type left,
545template <
typename T,
typename = ::std::enable_if<::deaddev::details::is_bitmask_v<T>>>
550template <
typename T,
typename = ::std::enable_if<::deaddev::details::is_bitmask_v<T>>>
555template <
typename T,
typename = ::std::enable_if<::deaddev::details::is_bitmask_v<T>>>
560template <
typename T,
typename = ::std::enable_if<::deaddev::details::is_bitmask_v<T>>>
565template <
typename T,
typename = ::std::enable_if<::deaddev::details::is_bitmask_v<T>>>
570template <
typename T,
typename = ::std::enable_if<::deaddev::details::is_bitmask_v<T>>>
575template <
typename T,
typename = ::std::enable_if<::deaddev::details::is_bitmask_v<T>>>
587#define DEADDEV_ENABLE_BITMASK(T, ...) \
588 auto adl_bitmask_operations_check(T &) -> ::deaddev::details::bitmask_traits< \
589 T, ::deaddev::details::calculate_all_flags<T>(__VA_ARGS__)>;
599#define DEADDEV_ENABLE_BITMASK_EXTERNAL(T, ...) \
601 struct ::deaddev::details::bitmask_operations_check_traits<T> \
602 : ::deaddev::details::bitmask_traits< \
603 T, ::deaddev::details::calculate_all_flags<T>(__VA_ARGS__)> {};
Bitmask class type.
Definition bitmask.hpp:252
DEADDEV_NODISCARD constexpr bool operator!=(mask_type mask) const noexcept
comparison operator
Definition bitmask.hpp:310
constexpr bitmask & remove(enum_type flag) noexcept
Combine bit mask with an enum value.
Definition bitmask.hpp:471
constexpr bitmask(mask_type value) noexcept
mask from integral type assignment operator
Definition bitmask.hpp:278
::std::underlying_type_t< T > mask_type
underlying type of enum
Definition bitmask.hpp:256
constexpr bitmask & remove(bitmask other) noexcept
Combine bit mask with an enum value.
Definition bitmask.hpp:479
DEADDEV_NODISCARD constexpr bitmask operator&(bitmask other) const noexcept
comparison operator
Definition bitmask.hpp:370
DEADDEV_NODISCARD constexpr bool operator<(mask_type mask) const noexcept
comparison operator
Definition bitmask.hpp:322
constexpr bitmask & set(bitmask other) noexcept
Combine bit mask with an enum value.
Definition bitmask.hpp:463
DEADDEV_NODISCARD constexpr bool operator<=(bitmask other) const noexcept
comparison operator
Definition bitmask.hpp:338
constexpr bitmask & operator&=(enum_type other) noexcept
comparison operator
Definition bitmask.hpp:420
DEADDEV_NODISCARD constexpr bitmask operator^(bitmask other) const noexcept
comparison operator
Definition bitmask.hpp:360
DEADDEV_NODISCARD constexpr bool operator!=(bitmask other) const noexcept
comparison operator
Definition bitmask.hpp:334
DEADDEV_NODISCARD constexpr bitmask operator|(bitmask other) const noexcept
comparison operator
Definition bitmask.hpp:365
DEADDEV_NODISCARD constexpr bitmask operator&(enum_type other) const noexcept
comparison operator
Definition bitmask.hpp:403
DEADDEV_NODISCARD constexpr bool operator>=(mask_type mask) const noexcept
comparison operator
Definition bitmask.hpp:318
constexpr bitmask & operator^=(bitmask other) noexcept
comparison operator
Definition bitmask.hpp:375
DEADDEV_NODISCARD constexpr bool operator>(mask_type mask) const noexcept
comparison operator
Definition bitmask.hpp:326
constexpr bitmask & operator|=(enum_type other) noexcept
comparison operator
Definition bitmask.hpp:414
DEADDEV_NODISCARD constexpr bool operator>(bitmask other) const noexcept
comparison operator
Definition bitmask.hpp:350
DEADDEV_NODISCARD constexpr bitmask operator|(enum_type other) const noexcept
comparison operator
Definition bitmask.hpp:398
DEADDEV_NODISCARD constexpr bool operator<=(mask_type mask) const noexcept
comparison operator
Definition bitmask.hpp:314
DEADDEV_NODISCARD constexpr bool is_set(enum_type flag) const noexcept
Checks if an enum value is in the mask.
Definition bitmask.hpp:433
constexpr bitmask & operator^=(enum_type other) noexcept
comparison operator
Definition bitmask.hpp:408
DEADDEV_NODISCARD static DEADDEV_CONSTEVAL bitmask all_flags() noexcept
returns bitmask with all flags set
Definition bitmask.hpp:301
constexpr bitmask & set(enum_type flag) noexcept
Combine bit mask with an enum value.
Definition bitmask.hpp:455
DEADDEV_NODISCARD constexpr bool operator==(mask_type mask) const noexcept
comparison operator
Definition bitmask.hpp:306
DEADDEV_NODISCARD constexpr bool operator>=(bitmask other) const noexcept
comparison operator
Definition bitmask.hpp:342
constexpr bitmask & operator&=(bitmask other) noexcept
comparison operator
Definition bitmask.hpp:387
DEADDEV_NODISCARD constexpr bool is_set(bitmask other) const noexcept
Checks if all flags from other bit mask is set in this bit mask.
Definition bitmask.hpp:445
DEADDEV_NODISCARD constexpr bool operator<(bitmask other) const noexcept
comparison operator
Definition bitmask.hpp:346
DEADDEV_NODISCARD constexpr bitmask operator~() const noexcept
comparison operator
Definition bitmask.hpp:355
DEADDEV_NODISCARD constexpr bool operator==(bitmask other) const noexcept
comparison operator
Definition bitmask.hpp:330
constexpr bitmask & operator|=(bitmask other) noexcept
comparison operator
Definition bitmask.hpp:381
T enum_type
original enum
Definition bitmask.hpp:258
DEADDEV_NODISCARD constexpr bitmask operator^(enum_type other) const noexcept
comparison operator
Definition bitmask.hpp:393
constexpr bitmask() noexcept=default
default constructor
constexpr T bitmask_all_flags_v
All flags combined.
Definition bitmask.hpp:238
DEADDEV_CONSTEVAL auto combine_flags(::std::underlying_type_t< T > &result, T value) -> void
Flag combination routine.
Definition bitmask.hpp:117
constexpr bool is_bitmask_v
Is T a bitmask type.
Definition bitmask.hpp:224
auto adl_bitmask_operations_check(...) -> ::deaddev::details::empty_bitmask_traits
noop
DEADDEV_CONSTEVAL auto calculate_all_flags() -> T
returns all flags
Definition bitmask.hpp:180
constexpr bool is_scoped_enum_v
c++14 compatible std::is_scoped_enum
Definition bitmask.hpp:92
DEADDEV_CONSTEVAL auto calculate_all_flags_cpp_before_17(T val) -> T
sentinel recursion overload for all flags calculation
Definition bitmask.hpp:131
it's me :)
Definition bitmask.hpp:63
trait implementation
Definition bitmask.hpp:214
used for deaddev::details::is_bitmask_v<T> and deaddev::details::bitmask_all_flags_v<T>
Definition bitmask.hpp:191
static constexpr bool enable
for sfinae checks
Definition bitmask.hpp:193
static constexpr T all_flags
for better negation
Definition bitmask.hpp:195
default value
Definition bitmask.hpp:101
static constexpr size_t all_flags
Definition bitmask.hpp:106
static constexpr bool enable
for sfinae type checks
Definition bitmask.hpp:103