This library just like other libraries uses compiler-specific hacks based on __FUNCSIG__ / __PRETTY_FUNCTION__.
If you face any issues while using the library don't hesistate to open up an issue.
This library cannot reflect automaticly on forward declared enums you will get a static_assert error.
The reason is to avoid ODR issues, where you reflect on a forward declared enum in one translation unit then reflect the full definition in another unit you will face ODR issues.
But however this disallows automatic detection of empty enums.
enum class Empty {};if you have an empty enum with no members and you wish to build a generic library using enchantum algorithms then you can use the ENCHANTUM_DECLARE_EMPTY macro to declare the enum as empty.
Enum values must be in the range [ENCHANTUM_MIN_RANGE,ENCHANTUM_MAX_RANGE]
By default, ENCHANTUM_MIN_RANGE = -256, ENCHANTUM_MAX_RANGE = 256.
If you need a different range for all enum types by default, redefine the macro ENCHANTUM_MAX_RANGE and if you don't explicitly define ENCHANTUM_MIN_RANGE it will be -ENCHANTUM_MAX_RANGE. Increasing this value can lead to longer compilation times but unlike other libraries it is not massivly increasing see benchmarks.
Enum values outside of this range won't be reflected by enchantum.
Enums that satisfy the BitFlagEnum concept ignore the [min, max] range, and reflect:
- The 0 value
- All powers-of-two up to the max bit set
They won't reflect combinations of flags.
Note: Defining the macro values project wide is recommended to avoid ODR issues
#define ENCHANTUM_MIN_RANGE 0 // if not defined it will be -512
#define ENCHANTUM_MAX_RANGE 512
#include <enchantum/enchantum.hpp>If you need a different range for a specific enum type, add the specialization enum_traits for the enum type.
#include <enchantum/enchantum.hpp>
enum class wizards { longbeard = 300, midbeard = 400, redbearded = 600 };
template <>
struct enchantum::enum_traits<wizards> { // defined in enchantum/common.hpp you only need that header
static constexpr auto min = static_cast<int>(wizards::longbeard);
static constexpr auto max = static_cast<int>(wizards::redbearded);
};If you see a message that goes like this
note: constexpr evaluation hit maximum step limit; possible infinite loop?
or
maximum constexpr step count exceeded.
Change the limit for the number of constexpr steps allowed: (hyperlink to docs)
MSVC: /constexpr:depthN, /constexpr:stepsN
Clang: -fconstexpr-depth=N, -fconstexpr-steps=N
GCC: -fconstexpr-depth=N, -fconstexpr-loop-limit=N, -fconstexpr-ops-limit=N
Clang is super weird with these enums
template<typename T>
struct ReallyClang_QuestionMark {
enum Type {
A,B,C
};
};
enchantum::entries<ReallyClang_QuestionMark<int>::Type>; // some long compiler errorApparantly Clang optimizes unused enum names in templates? I don't know really but a workaround is this (you must atleast mention the name of an enumarator once)
template<typename T>
struct GoodClang {
enum Type_ {
A,B,C
};
using Type = decltype(Type_::A);
};
enchantum::entries<GoodClang<int>::Type>; // happy clangunnamed enums are not supported except on msvc
enum {
SomeConstant = 10;
};
using Type = decltype(SomeConstant);
enchantum::entries<Type>; // won't work and won't be officially supportedthis works
typedef enum {
SomeConstant = 10;
} Type;just give it a name.
Unscoped enums seem to work however.
template<typename T>
struct Nest {
enum class A {a,b,c};
};
enchantum::entries<Nest<int>::A>; // failsThere is no workaround.
enum class A {
a,b,c
};
using B = A;
enchantum::entries<B>; // failsThere is no workaround.