v0.3.0 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.
19template<typename E>
20using 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).
25template<typename E>
26constexpr 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'
32template<typename E>
33constexpr 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'
38template<typename E>
39constexpr 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
48template<typename E>
49constexpr bool contains(E value, E bits) noexcept {
50 return any(value, bits);
51}
52
54template<typename E>
55constexpr bool contains_all(E value, E bits) noexcept {
56 return all(value, bits);
57}
58
60template<typename E>
61constexpr E add(E value, E bits) noexcept {
62 return static_cast<E>(to_uint(value) | to_uint(bits));
63}
64
66template<typename E>
67constexpr E remove(E value, E bits) noexcept {
68 return static_cast<E>(to_uint(value) & ~to_uint(bits));
69}
70
72template<typename E>
73constexpr void add_inplace(E& value, E bits) noexcept {
74 value = add(value, bits);
75}
76
78template<typename E>
79constexpr void remove_inplace(E& value, E bits) noexcept {
80 value = remove(value, bits);
81}
82
83// [Internal Bitmask Operator Support]
84
85template<typename E>
86struct enable_ops : std::false_type {};
87
88template<typename E>
89constexpr bool enable_ops_v = enable_ops<E>::value;
90
91template<typename E>
92concept MaskEnum = std::is_enum_v<E> && enable_ops_v<E>;
93
94} // namespace a3d::util::bitmask
95
96namespace a3d {
97
98// [Public Non-Member Functions]
99
101template<util::bitmask::MaskEnum E>
102constexpr E operator|(E a, E b) noexcept {
103 return static_cast<E>(util::bitmask::to_uint(a) | util::bitmask::to_uint(b));
104}
105
107template<util::bitmask::MaskEnum E>
108constexpr E operator&(E a, E b) noexcept {
109 return static_cast<E>(util::bitmask::to_uint(a) & util::bitmask::to_uint(b));
110}
111
113template<util::bitmask::MaskEnum E>
114constexpr E operator^(E a, E b) noexcept {
115 return static_cast<E>(util::bitmask::to_uint(a) ^ util::bitmask::to_uint(b));
116}
117
119template<util::bitmask::MaskEnum E>
120constexpr E operator~(E a) noexcept {
121 return static_cast<E>(~util::bitmask::to_uint(a));
122}
123
125template<util::bitmask::MaskEnum E>
126constexpr E& operator|=(E& a, E b) noexcept {
127 return a = (a | b);
128}
129
131template<util::bitmask::MaskEnum E>
132constexpr E& operator&=(E& a, E b) noexcept {
133 return a = (a & b);
134}
135
137template<util::bitmask::MaskEnum E>
138constexpr E& operator^=(E& a, E b) noexcept {
139 return a = (a ^ b);
140}
141
142} // namespace a3d
143
144#endif // AVARA3D_UTIL_BITMASK_H