Files
libconfig/build-config/reflect-cpp/include/rfl/thirdparty/enchantum/common.hpp
Emily Boudreaux ec13264050 feat(reflect-cpp): Switched from glaze -> reflect cpp
A bug was discovered in glaze which prevented valid toml output. We have
switched to toml++ and reflect-cpp. The interface has remained the same
so this should not break any code
2025-12-06 10:55:46 -05:00

97 lines
2.5 KiB
C++

#pragma once
#include <concepts>
#include <limits>
#include <type_traits>
#ifndef ENCHANTUM_ASSERT
#include <cassert>
// clang-format off
#define ENCHANTUM_ASSERT(cond, msg, ...) assert(cond && msg)
// clang-format on
#endif
#ifndef ENCHANTUM_THROW
// additional info such as local variables are here
#define ENCHANTUM_THROW(exception, ...) throw exception
#endif
#ifndef ENCHANTUM_MAX_RANGE
#define ENCHANTUM_MAX_RANGE 256
#endif
#ifndef ENCHANTUM_MIN_RANGE
#define ENCHANTUM_MIN_RANGE (-ENCHANTUM_MAX_RANGE)
#endif
namespace enchantum {
template<typename T>
concept Enum = std::is_enum_v<T>;
template<typename T>
concept SignedEnum = Enum<T> && std::signed_integral<std::underlying_type_t<T>>;
template<typename T>
concept UnsignedEnum = Enum<T> && !SignedEnum<T>;
template<typename T>
concept ScopedEnum = Enum<T> && (!std::is_convertible_v<T, std::underlying_type_t<T>>);
template<typename T>
concept UnscopedEnum = Enum<T> && !ScopedEnum<T>;
template<typename E, typename Underlying>
concept EnumOfUnderlying = Enum<E> && std::same_as<std::underlying_type_t<E>, Underlying>;
template<Enum E>
inline constexpr bool is_bitflag = requires(E e) {
requires std::same_as<decltype(e & e), bool> || std::same_as<decltype(e & e), E>;
{ ~e } -> std::same_as<E>;
{ e | e } -> std::same_as<E>;
{ e &= e } -> std::same_as<E&>;
{ e |= e } -> std::same_as<E&>;
};
template<typename T>
concept BitFlagEnum = Enum<T> && is_bitflag<T>;
template<typename T>
concept EnumFixedUnderlying = Enum<T> && requires { T{0}; };
template<typename T>
struct enum_traits;
template<SignedEnum E>
struct enum_traits<E> {
private:
using U = std::underlying_type_t<E>;
using L = std::numeric_limits<U>;
public:
static constexpr std::size_t prefix_length = 0;
static constexpr auto min = (L::min)() > ENCHANTUM_MIN_RANGE ? (L::min)() : ENCHANTUM_MIN_RANGE;
static constexpr auto max = (L::max)() < ENCHANTUM_MAX_RANGE ? (L::max)() : ENCHANTUM_MAX_RANGE;
};
template<UnsignedEnum E>
struct enum_traits<E> {
private:
using T = std::underlying_type_t<E>;
using L = std::numeric_limits<T>;
public:
static constexpr std::size_t prefix_length = 0;
static constexpr auto min = []() {
if constexpr (std::is_same_v<T, bool>)
return false;
else
return (ENCHANTUM_MIN_RANGE) < 0 ? 0 : (ENCHANTUM_MIN_RANGE);
}();
static constexpr auto max = []() {
if constexpr (std::is_same_v<T, bool>)
return true;
else
return (L::max)() < (ENCHANTUM_MAX_RANGE) ? (L::max)() : (ENCHANTUM_MAX_RANGE);
}();
};
} // namespace enchantum