Avara3D 0.2.0
C++ API reference
Bitmask.h
1//
2// Bitmask.h
3// avara3d
4//
5// Created by Morgan Davis on 1/6/26.
6// Copyright © 2026 Morgan K Davis. All rights reserved.
7//
8
9#ifndef AVARA3D_UTIL_BITMASK_H
10#define AVARA3D_UTIL_BITMASK_H
11
12#include <type_traits>
13
14namespace a3d::util::bitmask {
15
16 // [Internal Types]
17
18 // unsigned underlying type used for bitwise ops.
19 template<typename E>
20 using U = std::make_unsigned_t<std::underlying_type_t<E>>;
21
22 // [Internal Functions]
23
24 // converts enum to its underlying integer type (unsigned for bitwise ops).
25 template<typename E>
26 constexpr U<E> to_uint(E e) noexcept {
27 static_assert(std::is_enum_v<E>, "a3d::util::bitmask::to_uint() requires an enum type");
28 return static_cast<U<E>>(static_cast<std::underlying_type_t<E>>(e));
29 }
30
31 // true if ANY bits in 'bits' are set in 'value'
32 template<typename E>
33 constexpr bool any(E value, E bits) noexcept {
34 return (to_uint(value) & to_uint(bits)) != 0;
35 }
36
37 // true if ALL bits in 'bits' are set in 'value'
38 template<typename E>
39 constexpr bool all(E value, E bits) noexcept {
40 const auto v = to_uint(value);
41 const auto b = to_uint(bits);
42 return (v & b) == b;
43 }
44
45 // [Public Functions]
46
48 template<typename E>
49 constexpr bool contains(E value, E bits) noexcept {
50 return any(value, bits);
51 }
52
54 template<typename E>
55 constexpr bool contains_all(E value, E bits) noexcept {
56 return all(value, bits);
57 }
58
60 template<typename E>
61 constexpr E add(E value, E bits) noexcept {
62 return static_cast<E>(to_uint(value) | to_uint(bits));
63 }
64
66 template<typename E>
67 constexpr E remove(E value, E bits) noexcept {
68 return static_cast<E>(to_uint(value) & ~to_uint(bits));
69 }
70
72 template<typename E>
73 constexpr void add_inplace(E& value, E bits) noexcept {
74 value = add(value, bits);
75 }
76
78 template<typename E>
79 constexpr void remove_inplace(E& value, E bits) noexcept {
80 value = remove(value, bits);
81 }
82
83 // [Internal Bitmask Operator Support]
84
85 template<typename E>
86 struct enable_ops : std::false_type {};
87
88 template<typename E>
89 constexpr bool enable_ops_v = enable_ops<E>::value;
90
91 template<typename E>
92 concept MaskEnum = std::is_enum_v<E> && enable_ops_v<E>;
93
94}
95
96namespace a3d {
97
98 // [Public Non-Member Functions]
99
101 template<util::bitmask::MaskEnum E>
102 constexpr E operator|(E a, E b) noexcept {
103 return static_cast<E>(util::bitmask::to_uint(a) | util::bitmask::to_uint(b));
104 }
105
107 template<util::bitmask::MaskEnum E>
108 constexpr E operator&(E a, E b) noexcept {
109 return static_cast<E>(util::bitmask::to_uint(a) & util::bitmask::to_uint(b));
110 }
111
113 template<util::bitmask::MaskEnum E>
114 constexpr E operator^(E a, E b) noexcept {
115 return static_cast<E>(util::bitmask::to_uint(a) ^ util::bitmask::to_uint(b));
116 }
117
119 template<util::bitmask::MaskEnum E>
120 constexpr E operator~(E a) noexcept {
121 return static_cast<E>(~util::bitmask::to_uint(a));
122 }
123
125 template<util::bitmask::MaskEnum E>
126 constexpr E& operator|=(E& a, E b) noexcept {
127 return a = (a | b);
128 }
129
131 template<util::bitmask::MaskEnum E>
132 constexpr E& operator&=(E& a, E b) noexcept {
133 return a = (a & b);
134 }
135
137 template<util::bitmask::MaskEnum E>
138 constexpr E& operator^=(E& a, E b) noexcept {
139 return a = (a ^ b);
140 }
141
142}
143
144#endif // AVARA3D_UTIL_BITMASK_H