#pragma once #include #include #include #ifndef ENCHANTUM_ASSERT #include // 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 concept Enum = std::is_enum_v; template concept SignedEnum = Enum && std::signed_integral>; template concept UnsignedEnum = Enum && !SignedEnum; template concept ScopedEnum = Enum && (!std::is_convertible_v>); template concept UnscopedEnum = Enum && !ScopedEnum; template concept EnumOfUnderlying = Enum && std::same_as, Underlying>; template inline constexpr bool is_bitflag = requires(E e) { requires std::same_as || std::same_as; { ~e } -> std::same_as; { e | e } -> std::same_as; { e &= e } -> std::same_as; { e |= e } -> std::same_as; }; template concept BitFlagEnum = Enum && is_bitflag; template concept EnumFixedUnderlying = Enum && requires { T{0}; }; template struct enum_traits; template struct enum_traits { private: using U = std::underlying_type_t; using L = std::numeric_limits; 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 struct enum_traits { private: using T = std::underlying_type_t; using L = std::numeric_limits; public: static constexpr std::size_t prefix_length = 0; static constexpr auto min = []() { if constexpr (std::is_same_v) return false; else return (ENCHANTUM_MIN_RANGE) < 0 ? 0 : (ENCHANTUM_MIN_RANGE); }(); static constexpr auto max = []() { if constexpr (std::is_same_v) return true; else return (L::max)() < (ENCHANTUM_MAX_RANGE) ? (L::max)() : (ENCHANTUM_MAX_RANGE); }(); }; } // namespace enchantum