sandbox
Loading...
Searching...
No Matches
enum.hpp
1// SPDX-License-Identifier: MIT
2#ifndef LIBSBX_UTILITY_ENUM_HPP_
3#define LIBSBX_UTILITY_ENUM_HPP_
4
5#include <type_traits>
6#include <array>
7#include <ranges>
8#include <optional>
9#include <string_view>
10
11#include <libsbx/utility/string_literal.hpp>
12
13namespace sbx::utility {
14
15template<typename Enum>
16requires (std::is_enum_v<Enum>)
17constexpr auto to_underlying(const Enum value) -> std::underlying_type_t<Enum> {
18 return static_cast<std::underlying_type_t<Enum>>(value);
19}
20
21template<typename Enum>
22requires (std::is_enum_v<Enum>)
23constexpr auto from_underlying(const std::underlying_type_t<Enum> value) -> Enum {
24 return static_cast<Enum>(value);
25}
26
27template<typename Enum>
28requires (std::is_enum_v<Enum>)
29struct is_bit_field : std::false_type { };
30
31template<typename Enum>
32requires (std::is_enum_v<Enum>)
33inline constexpr auto is_bit_field_v = is_bit_field<Enum>::value;
34
35template<std::size_t Shift>
36struct bit : std::integral_constant<std::size_t, (std::size_t{1} << Shift)> { };
37
38template<std::size_t Shift>
39inline constexpr auto bit_v = bit<Shift>::value;
40
41template<typename Enum, typename Underlying = std::underlying_type_t<Enum>>
42requires (std::is_enum_v<Enum>)
43class bit_field {
44
45public:
46
47 using value_type = Enum;
48 using underlying_type = Underlying;
49
50 constexpr bit_field() noexcept
51 : _value{underlying_type{0}} { }
52
53 constexpr bit_field(const value_type value) noexcept
54 : _value{to_underlying(value)} { }
55
56 explicit constexpr bit_field(const underlying_type value) noexcept
57 : _value{value} { }
58
59 constexpr auto set(const value_type value) noexcept -> bit_field& {
60 return *this |= value;
61 }
62
63 constexpr auto operator|=(const value_type value) noexcept -> bit_field& {
64 _value |= static_cast<underlying_type>(value);
65
66 return *this;
67 }
68
69 constexpr auto clear(const value_type value) noexcept -> void {
70 _value &= ~static_cast<underlying_type>(value);
71 }
72
73 constexpr auto override(const value_type value) noexcept -> void {
74 _value = static_cast<underlying_type>(value);
75 }
76
77 constexpr auto has(const value_type value) const noexcept -> bool {
78 return _value & static_cast<underlying_type>(value);
79 }
80
81 constexpr auto has_any() const noexcept -> bool {
82 return _value != underlying_type{0};
83 }
84
85 constexpr auto has_none() const noexcept -> bool {
86 return _value == underlying_type{0};
87 }
88
89 constexpr auto operator*() const noexcept -> value_type {
90 return from_underlying<value_type>(_value);
91 }
92
93 constexpr auto value() const -> value_type {
94 return static_cast<value_type>(_value);
95 }
96
97 constexpr auto underlying() const -> underlying_type {
98 return _value;
99 }
100
101private:
102
103 underlying_type _value;
104
105}; // class bit_field
106
107} // namespace sbx::utility
108
109template<typename Type>
110requires (sbx::utility::is_bit_field_v<Type>)
111constexpr auto operator|(Type lhs, Type rhs) -> Type {
112 return sbx::utility::from_underlying<Type>(sbx::utility::to_underlying(lhs) | sbx::utility::to_underlying(rhs));
113}
114
115template<typename Type>
116requires (sbx::utility::is_bit_field_v<Type>)
117constexpr auto operator|=(Type& lhs, Type rhs) -> Type& {
118 lhs = lhs | rhs;
119
120 return lhs;
121}
122
123template<typename Type>
124requires (sbx::utility::is_bit_field_v<Type>)
125constexpr auto operator&(Type lhs, Type rhs) -> Type {
126 return sbx::utility::from_underlying<Type>(sbx::utility::to_underlying(lhs) & sbx::utility::to_underlying(rhs));
127}
128
129template<typename Type>
130requires (sbx::utility::is_bit_field_v<Type>)
131constexpr auto operator^(Type lhs, Type rhs) -> Type {
132 return sbx::utility::from_underlying<Type>(sbx::utility::to_underlying(lhs) ^ sbx::utility::to_underlying(rhs));
133}
134
135template<typename Type>
136requires (sbx::utility::is_bit_field_v<Type>)
137constexpr auto operator~(Type lhs) -> Type {
138 return sbx::utility::from_underlying<Type>(~sbx::utility::to_underlying(lhs));
139}
140
141#endif // LIBSBX_UTILITY_ENUM_HPP_
constexpr auto operator*(basic_degree< Type > lhs, const Other rhs) noexcept -> basic_degree< Type >
Multiplies a degree value by a scalar factor.
Definition: angle.ipp:105
Definition: enum.hpp:43
Definition: enum.hpp:36
Definition: enum.hpp:29