Skip to content

Latest commit

 

History

History
155 lines (106 loc) · 4.53 KB

File metadata and controls

155 lines (106 loc) · 4.53 KB

Limitations

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.

Forward Declared Enums

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 Range

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);
};

Other Compiler Issues

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

Unscoped enums in templates may not work correctly on Сlang.

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 error

Apparantly 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 clang

Unnamed Enums

unnamed 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 supported

this works

typedef enum {
    SomeConstant = 10;
} Type;

just give it a name.

Scoped Enums in templated classes are not supported on NVC++

Unscoped enums seem to work however.

template<typename T>
struct Nest {
    enum class A {a,b,c};
};

enchantum::entries<Nest<int>::A>; // fails

There is no workaround.

Aliased enums are not supported on NVC++

enum class A {
    a,b,c
};
using B = A;
enchantum::entries<B>; // fails

There is no workaround.