dfx 0.1.0
Linux-based dynamic dataflow executor
Loading...
Searching...
No Matches
EnumString.hpp File Reference

Macro-based enum <-> string utilities for dfx. More...

Include dependency graph for EnumString.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Namespaces

namespace  dfx::Enum
 Enum string conversion and enumeration utilities.

Macros

#define ENUM_TO_STRING_IMPL(E, ...)
 Define dfx::Enum::toStringView(E) and dfx::Enum::toString(E) for enum type E.
#define ENUM_FROM_STRING_IMPL(E)
 Define dfx::Enum::fromStringView<E> and dfx::Enum::fromString<E> specializations for enum E.
#define ENUM_ALL_VALUES_MAP_IMPL(E, ...)
 Define allValuesMap<E>() and allValuesMapView<E>() specializations for enum E.
#define ENUM_ALL_VALUES_IMPL(E, ...)
 Define allValues<E>() and allValuesStringView<E>() specializations for enum E.
#define ENUM_STD_FMT_FORMATTER(E)
 Define std::formatter<E> formatting the enum as its label via dfx::Enum::toStringView.
#define DEFINE_ENUM_STRING(Enum, ...)
 Define the full enum string API for Enum (definitions + maps + value lists).
#define DECLARE_ENUM_STRING_FUNCTIONS(E)
 Declare the enum string API (and std::formatter) for enum type E.

Functions

template<typename E>
std::string_view dfx::Enum::toStringView (E e) noexcept
 Convert an enum value into a string view.
template<typename E>
std::string dfx::Enum::toString (E e) noexcept
 Convert an enum value into a string.
template<typename E>
std::optional< E > dfx::Enum::fromStringView (std::string_view) noexcept=delete
 Convert a string view to an enum value.
template<typename E>
std::optional< E > dfx::Enum::fromString (std::string const &) noexcept=delete
 Convert a string to an enum value.
template<typename E>
std::unordered_map< std::string, E > const & dfx::Enum::allValuesMap () noexcept=delete
 Map from label (owned string) to enum value for type E.
template<typename E>
std::unordered_map< std::string_view, E > const & dfx::Enum::allValuesMapView () noexcept=delete
 Map from label (string_view) to enum value for type E.
template<typename E>
std::vector< E > const & dfx::Enum::allValues () noexcept=delete
 Return all enum values registered for E, in the order provided to the macro. Deleted by default; provided via macro specialization.
template<typename E>
std::vector< std::string_view > const & dfx::Enum::allValuesStringView () noexcept=delete
 Return all labels registered for E, in the order provided to the macro. Deleted by default; provided via macro specialization.

Detailed Description

Macro-based enum <-> string utilities for dfx.

This header provides a small "enum reflection" facility (without language reflection) by generating:

How it’s meant to be used

1) Define an enum:

enum class Color { Red, Green, Blue };

2) In a header, declare the API for that enum:

#define DECLARE_ENUM_STRING_FUNCTIONS(E)
Declare the enum string API (and std::formatter) for enum type E.
Definition EnumString.hpp:327

3) In exactly one .cpp (or one TU), provide the definitions:

Color::Red, "red",
Color::Green, "green",
Color::Blue, "blue");
#define DEFINE_ENUM_STRING(Enum,...)
Define the full enum string API for Enum (definitions + maps + value lists).
Definition EnumString.hpp:307

Then you can do:

auto s = dfx::Enum::toStringView(Color::Green); // "green"
auto e1 = dfx::Enum::fromStringView<Color>("red"); // Color::Red
auto e2 = dfx::Enum::fromStringView<Color>("oops"); // std::nullopt
auto vs = dfx::Enum::allValues<Color>(); // { Red, Green, Blue }
auto ss = dfx::Enum::allValuesStringView<Color>(); // { "red","green","blue" }
std::string f = std::format("{}", Color::Blue); // "blue" (via std::formatter)
std::vector< std::string_view > const & allValuesStringView() noexcept=delete
Return all labels registered for E, in the order provided to the macro. Deleted by default; provided ...
std::vector< E > const & allValues() noexcept=delete
Return all enum values registered for E, in the order provided to the macro. Deleted by default; prov...
std::string_view toStringView(E e) noexcept
Convert an enum value into a string view.
std::optional< E > fromStringView(std::string_view) noexcept=delete
Convert a string view to an enum value.

Important constraints / caveats

  • DEFINE_ENUM_STRING emits non-inline function definitions and static objects; it must appear in exactly one translation unit per enum, or you will hit ODR / multiple-definition errors.
  • toStringView() uses a switch without a default. If you pass a value not listed in the macro, execution reaches UNREACHABLE_IMPL() (undefined behavior / terminate, depending on your impl).
  • fromStringView() uses a hash map lookup. Strings must match the labels exactly.
  • allValuesMapView() stores keys as std::string_view. It assumes your labels are backed by storage that lives forever (string literals are fine).
  • Because this code relies on preprocessor wizardry, a maximum of 32 values can be used for a single enum.

Macro Definition Documentation

◆ DECLARE_ENUM_STRING_FUNCTIONS

#define DECLARE_ENUM_STRING_FUNCTIONS ( E)
Value:
namespace dfx::Enum \
{ \
[[nodiscard]] std::string_view toStringView(E e) noexcept; \
[[nodiscard]] std::string toString(E e) noexcept; \
template<> [[nodiscard]] std::optional<E> fromStringView(std::string_view str) noexcept; \
template<> [[nodiscard]] std::optional<E> fromString(std::string const & str) noexcept; \
template<> [[nodiscard]] std::unordered_map<std::string_view, E> const & allValuesMapView() noexcept; \
template<> [[nodiscard]] std::unordered_map<std::string, E> const & allValuesMap() noexcept; \
template<> [[nodiscard]] std::vector<E> const & allValues() noexcept; \
template<> [[nodiscard]] std::vector<std::string_view> const & allValuesStringView<E>() noexcept; \
} \
#define ENUM_STD_FMT_FORMATTER(E)
Define std::formatter<E> formatting the enum as its label via dfx::Enum::toStringView.
Definition EnumString.hpp:284
Enum string conversion and enumeration utilities.
Definition EnumString.hpp:120
STL namespace.

Declare the enum string API (and std::formatter) for enum type E.

Put this in a header next to the enum definition. Then put DEFINE_ENUM_STRING(E, ...) in one .cpp to provide the definitions.

Declares:

◆ DEFINE_ENUM_STRING

#define DEFINE_ENUM_STRING ( Enum,
... )
Value:
ENUM_TO_STRING_IMPL(Enum, __VA_ARGS__) \
ENUM_FROM_STRING_IMPL(Enum) \
ENUM_ALL_VALUES_MAP_IMPL(Enum, SWAP_POSITION(__VA_ARGS__)) \
ENUM_ALL_VALUES_IMPL(Enum, __VA_ARGS__)
#define ENUM_TO_STRING_IMPL(E,...)
Define dfx::Enum::toStringView(E) and dfx::Enum::toString(E) for enum type E.
Definition EnumString.hpp:103

Define the full enum string API for Enum (definitions + maps + value lists).

Expands to:

Parameters
EnumThe enum type.
...Alternating (enumValue, label) pairs.
Warning
Must be used in exactly one translation unit per enum.

◆ ENUM_ALL_VALUES_IMPL

#define ENUM_ALL_VALUES_IMPL ( E,
... )
Value:
namespace dfx::Enum \
{ \
template<> \
[[nodiscard]] std::vector<E> const & allValues() noexcept \
{ \
static std::vector<E> const vec = { \
ENUM_STRING_ONE_OUT_OF_TWO_1(__VA_ARGS__) \
}; \
return vec; \
} \
template<> \
[[nodiscard]] std::vector<std::string_view> const & allValuesStringView<E>() noexcept \
{ \
static std::vector<std::string_view> const vec = { \
ENUM_STRING_ONE_OUT_OF_TWO_2(__VA_ARGS__) \
}; \
return vec; \
} \
}

Define allValues<E>() and allValuesStringView<E>() specializations for enum E.

Parameters
EThe enum type.
...Alternating (enumValue, label) pairs.
Warning
Must be used in exactly one translation unit (non-inline definitions).

◆ ENUM_ALL_VALUES_MAP_IMPL

#define ENUM_ALL_VALUES_MAP_IMPL ( E,
... )
Value:
namespace dfx::Enum \
{ \
template<> \
[[nodiscard]] std::unordered_map<std::string, E> const & allValuesMap() noexcept \
{ \
static std::unordered_map<std::string, E> const map = { \
ENUM_FROM_STRING_GENERATE_MAPPING(__VA_ARGS__) \
}; \
return map; \
} \
template<> \
[[nodiscard]] std::unordered_map<std::string_view, E> const & allValuesMapView() noexcept \
{ \
static std::unordered_map<std::string_view, E> const map = { \
ENUM_FROM_STRING_GENERATE_MAPPING(__VA_ARGS__) \
}; \
return map; \
} \
}
std::unordered_map< std::string_view, E > const & allValuesMapView() noexcept=delete
Map from label (string_view) to enum value for type E.

Define allValuesMap<E>() and allValuesMapView<E>() specializations for enum E.

The variadic arguments are expected as alternating (label, enumValue) pairs (note the order), which is why DEFINE_ENUM_STRING feeds it with SWAP_POSITION(__VA_ARGS__).

Warning
Must be used in exactly one translation unit (non-inline definitions).

◆ ENUM_FROM_STRING_IMPL

#define ENUM_FROM_STRING_IMPL ( E)
Value:
namespace dfx::Enum \
{ \
template<> \
[[nodiscard]] std::optional<E> fromStringView(std::string_view str) noexcept \
{ \
auto const & map = allValuesMapView<E>(); \
auto const itr = map.find(str); \
if (itr == map.end()) \
return std::nullopt; \
return itr->second; \
} \
template<> \
[[nodiscard]] std::optional<E> fromString(std::string const & str) noexcept \
{ return fromStringView<E>(str); } \
}

Define dfx::Enum::fromStringView<E> and dfx::Enum::fromString<E> specializations for enum E.

Implementation performs a lookup in allValuesMapView<E>().

Warning
Requires that allValuesMapView<E>() is also specialized/defined (see ENUM_ALL_VALUES_MAP_IMPL or DEFINE_ENUM_STRING).
Must be used in exactly one translation unit (non-inline definitions).

◆ ENUM_STD_FMT_FORMATTER

#define ENUM_STD_FMT_FORMATTER ( E)
Value:
template<> \
struct std::formatter<E> : public formatter<std::string_view> \
{ \
auto format(E const & e, format_context & ctx) const \
{ return formatter<std::string_view>::format(dfx::Enum::toStringView(e), ctx); } \
}

Define std::formatter<E> formatting the enum as its label via dfx::Enum::toStringView.

This allows:

std::format("{}", myEnumValue);
Warning
Provide this only if toStringView(E) is declared/defined (via the macros above).

◆ ENUM_TO_STRING_IMPL

#define ENUM_TO_STRING_IMPL ( E,
... )
Value:
namespace dfx::Enum \
{ \
[[nodiscard]] std::string_view toStringView(E e) noexcept \
{ \
switch (e) \
{ \
ENUM_TO_STRING_GENERATE_MAPPING(__VA_ARGS__) \
} \
UNREACHABLE_IMPL(); \
} \
[[nodiscard]] std::string toString(E e) noexcept \
{ return std::string(toStringView(e)); } \
}
std::string toString(E e) noexcept
Convert an enum value into a string.

Define dfx::Enum::toStringView(E) and dfx::Enum::toString(E) for enum type E.

Emits:

Parameters
EThe enum type (e.g. Color).
...Alternating (enumValue, label) pairs, e.g. Color::Red, "red", Color::Blue, "blue".
Warning
Must be used in exactly one translation unit (non-inline definitions).
Passing an unmapped enum value reaches UNREACHABLE_IMPL().