2#ifndef LIBSBX_UTILITY_ENUM_HPP_
3#define LIBSBX_UTILITY_ENUM_HPP_
11#include <libsbx/utility/string_literal.hpp>
13namespace sbx::utility {
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);
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);
27template<
auto... Values>
28requires (std::is_enum_v<
decltype(Values)> && ...)
31 inline static constexpr auto values = std::array{Values...};
33 inline static constexpr auto contains(
const typename decltype(values)::value_type value)
noexcept ->
bool {
34 for (
auto entry : values) {
43 inline static constexpr auto size()
noexcept -> std::size_t {
47 inline static constexpr auto is_empty()
noexcept -> std::size_t {
56 template<
typename Type>
57 requires (std::is_enum_v<Type>)
58 inline static constexpr auto contains(
const Type value)
noexcept ->
bool {
62 inline static constexpr auto size()
noexcept -> std::size_t {
66 inline static constexpr auto is_empty()
noexcept -> std::size_t {
72template<
typename Enum>
73requires (std::is_enum_v<Enum>)
76template<
typename Enum>
77requires (std::is_enum_v<Enum>)
80template<std::
size_t Shift>
81struct bit : std::integral_constant<std::size_t, (std::size_t{1} << Shift)> { };
83template<std::size_t Shift>
84inline constexpr auto bit_v = bit<Shift>::value;
86template<typename Enum, typename Underlying = std::underlying_type_t<Enum>>
87requires (std::is_enum_v<Enum>)
92 using value_type = Enum;
93 using underlying_type = Underlying;
95 constexpr bit_field() noexcept
96 : _value{underlying_type{0}} { }
98 constexpr bit_field(const value_type value) noexcept
99 : _value{to_underlying(value)} { }
101 explicit constexpr bit_field(const underlying_type value) noexcept
104 constexpr auto set(const value_type value) noexcept -> bit_field& {
105 return *this |= value;
108 constexpr auto operator|=(const value_type value) noexcept ->
bit_field& {
109 _value |=
static_cast<underlying_type
>(value);
114 constexpr auto clear(
const value_type value)
noexcept ->
void {
115 _value &= ~static_cast<underlying_type>(value);
118 constexpr auto override(
const value_type value)
noexcept ->
void {
122 constexpr auto has(
const value_type value)
const noexcept ->
bool {
123 return _value &
static_cast<underlying_type
>(value);
126 constexpr auto has_any() const noexcept ->
bool {
127 return _value != underlying_type{0};
130 constexpr auto has_none() const noexcept ->
bool {
131 return _value == underlying_type{0};
134 constexpr auto operator*() const noexcept -> value_type {
135 return from_underlying<value_type>(_value);
138 constexpr auto value() const -> value_type {
139 return static_cast<value_type
>(_value);
142 constexpr auto underlying() const -> underlying_type {
148 underlying_type _value;
152template<
typename Enum>
153requires (std::is_enum_v<Enum>)
156 std::string_view name;
159template<
typename Enum>
160requires (std::is_enum_v<Enum>)
164template<
typename Type>
165concept mapped_enum =
requires() {
166 std::is_enum_v<Type>;
170template<mapped_enum Enum>
171constexpr auto to_string(
const Enum value) -> std::string_view {
174 if (entry == std::ranges::end(enum_mapping<Enum>::values)) {
181template<mapped_enum Enum>
182constexpr auto from_string(
const std::string_view name) -> std::optional<Enum> {
183 auto entry = std::ranges::find_if(enum_mapping<Enum>::values, [&name](
const auto& entry){
return entry.name == name; });
185 if (entry == std::ranges::end(enum_mapping<Enum>::values)) {
194template<
typename Type>
195requires (sbx::utility::is_bit_field_v<Type>)
196constexpr auto operator|(Type lhs, Type rhs) -> Type {
197 return sbx::utility::from_underlying<Type>(sbx::utility::to_underlying(lhs) | sbx::utility::to_underlying(rhs));
200template<
typename Type>
201requires (sbx::utility::is_bit_field_v<Type>)
202constexpr auto operator|=(Type& lhs, Type rhs) -> Type& {
208template<
typename Type>
209requires (sbx::utility::is_bit_field_v<Type>)
210constexpr auto operator&(Type lhs, Type rhs) -> Type {
211 return sbx::utility::from_underlying<Type>(sbx::utility::to_underlying(lhs) & sbx::utility::to_underlying(rhs));
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