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<
typename Enum>
28requires (std::is_enum_v<Enum>)
31template<
typename Enum>
32requires (std::is_enum_v<Enum>)
35template<std::
size_t Shift>
36struct bit : std::integral_constant<std::size_t, (std::size_t{1} << Shift)> { };
38template<std::size_t Shift>
39inline constexpr auto bit_v = bit<Shift>::value;
41template<typename Enum, typename Underlying = std::underlying_type_t<Enum>>
42requires (std::is_enum_v<Enum>)
47 using value_type = Enum;
48 using underlying_type = Underlying;
50 constexpr bit_field() noexcept
51 : _value{underlying_type{0}} { }
53 constexpr bit_field(const value_type value) noexcept
54 : _value{to_underlying(value)} { }
56 explicit constexpr bit_field(const underlying_type value) noexcept
59 constexpr auto set(const value_type value) noexcept -> bit_field& {
60 return *this |= value;
63 constexpr auto operator|=(const value_type value) noexcept ->
bit_field& {
64 _value |=
static_cast<underlying_type
>(value);
69 constexpr auto clear(
const value_type value)
noexcept ->
void {
70 _value &= ~static_cast<underlying_type>(value);
73 constexpr auto override(
const value_type value)
noexcept ->
void {
74 _value =
static_cast<underlying_type
>(value);
77 constexpr auto has(
const value_type value)
const noexcept ->
bool {
78 return _value &
static_cast<underlying_type
>(value);
81 constexpr auto has_any() const noexcept ->
bool {
82 return _value != underlying_type{0};
85 constexpr auto has_none() const noexcept ->
bool {
86 return _value == underlying_type{0};
89 constexpr auto operator*() const noexcept -> value_type {
90 return from_underlying<value_type>(_value);
93 constexpr auto value() const -> value_type {
94 return static_cast<value_type
>(_value);
97 constexpr auto underlying() const -> underlying_type {
103 underlying_type _value;
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));
115template<
typename Type>
116requires (sbx::utility::is_bit_field_v<Type>)
117constexpr auto operator|=(Type& lhs, Type rhs) -> Type& {
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));
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));
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));
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