DNDSR 0.2.1
Distributed Numeric Data Structure for CFV
Loading...
Searching...
No Matches
ConfigEnum.hpp
Go to the documentation of this file.
1#pragma once
2/// @file ConfigEnum.hpp
3/// @brief Extended enum-to-JSON serialization macro that also exposes allowed
4/// string values for JSON Schema generation.
5///
6/// @details
7/// ## Problem
8///
9/// The standard `NLOHMANN_JSON_SERIALIZE_ENUM` macro generates `to_json`/`from_json`
10/// overloads for an enum, but provides no way to programmatically query the set of
11/// allowed string values at runtime. The config schema generator needs this list
12/// to produce `"enum": ["Roe", "HLLC", ...]` entries.
13///
14/// ## Solution
15///
16/// `DNDS_DEFINE_ENUM_JSON` wraps `NLOHMANN_JSON_SERIALIZE_ENUM` and additionally
17/// generates a free function `_dnds_enum_allowed_values_<EnumType>()` that returns
18/// `std::vector<std::string>` of the valid string representations.
19///
20/// The companion macro `DNDS_ENUM_ALLOWED_VALUES(EnumType)` calls this function.
21///
22/// ## Usage
23///
24/// @code
25/// // In Gas.hpp (at namespace scope, after enum definition):
26/// enum RiemannSolverType { UnknownRS, Roe, HLLC, HLLEP };
27///
28/// DNDS_DEFINE_ENUM_JSON(RiemannSolverType,
29/// {UnknownRS, nullptr},
30/// {Roe, "Roe"},
31/// {HLLC, "HLLC"},
32/// {HLLEP, "HLLEP"})
33///
34/// // Then in a config struct's DNDS_DECLARE_CONFIG body:
35/// DNDS_FIELD(rsType, "Riemann solver type",
36/// DNDS::Config::enum_values(DNDS_ENUM_ALLOWED_VALUES(RiemannSolverType)));
37/// // The schema will include "enum": ["Roe", "HLLC", "HLLEP"]
38/// @endcode
39///
40/// ## Backward Compatibility
41///
42/// Existing enums using `NLOHMANN_JSON_SERIALIZE_ENUM` continue to work for
43/// serialization. To also get schema enum values, replace with
44/// `DNDS_DEFINE_ENUM_JSON`. Until that replacement, pass allowed values
45/// explicitly via `DNDS::Config::enum_values({"Roe","HLLC",...})` in the
46/// `DNDS_FIELD` call.
47///
48/// ## Convention for the nullptr sentinel
49///
50/// Following the existing DNDSR convention, the first entry in the mapping
51/// should map the "unknown/invalid" enum value to `nullptr`. This entry is
52/// skipped when building the allowed-values list for the schema (users should
53/// never write `null` in a config file).
54
56#include <vector>
57#include <string>
58
59// ============================================================================
60// Internal: Extract string values from the enum mapping pairs.
61// ============================================================================
62// The NLOHMANN_JSON_SERIALIZE_ENUM macro takes pairs like {EnumVal, "string"}
63// or {EnumVal, nullptr}. We need to extract just the non-null strings.
64//
65// We use a helper struct that can be constructed from either a string literal
66// or nullptr, letting us filter nulls at runtime.
67
68namespace DNDS
69{
70 namespace detail
71 {
72 /// @brief A pair of (enum-value, optional string) used to extract allowed values.
73 ///
74 /// Constructed implicitly from the `{EnumVal, "string"}` initializer pairs.
75 /// When the string is nullptr (the unknown/sentinel value), `str` is empty
76 /// and `isNull` is true.
77 template <typename EnumType>
79 {
80 EnumType value;
81 std::string str;
82 bool isNull;
83
84 EnumStringPair(EnumType v, const char *s)
85 : value(v), str(s ? s : ""), isNull(s == nullptr) {}
86 EnumStringPair(EnumType v, std::nullptr_t) // NOLINT(bugprone-macro-parentheses)
87 : value(v), isNull(true)
88 {
89 }
90 };
91
92 /// @brief Extract non-null string values from a list of enum-string pairs.
93 template <typename EnumType>
94 std::vector<std::string> extractEnumStrings(
95 std::initializer_list<EnumStringPair<EnumType>> pairs)
96 {
97 std::vector<std::string> result;
98 result.reserve(pairs.size());
99 for (const auto &p : pairs)
100 {
101 if (!p.isNull)
102 result.push_back(p.str);
103 }
104 return result;
105 }
106 } // namespace detail
107} // namespace DNDS
108
109// ============================================================================
110// DNDS_DEFINE_ENUM_JSON(EnumType, ...)
111// ============================================================================
112/// @brief Define JSON serialization for an enum AND expose its allowed string values.
113///
114/// Drop-in replacement for `NLOHMANN_JSON_SERIALIZE_ENUM` that additionally
115/// generates a function returning the allowed string values for schema emission.
116///
117/// The variadic arguments are `{EnumValue, "string"}` pairs, identical to those
118/// accepted by `NLOHMANN_JSON_SERIALIZE_ENUM`. Pairs with `nullptr` as the
119/// string (sentinel/unknown values) are excluded from the allowed-values list.
120///
121/// @param EnumType_ The enum type.
122/// @param ... Comma-separated `{EnumValue, "string_or_nullptr"}` pairs.
123///
124/// Generates:
125/// 1. `NLOHMANN_JSON_SERIALIZE_ENUM(EnumType_, ...)` — standard serialization.
126/// 2. `inline std::vector<std::string> _dnds_enum_values_<mangled>()` — allowed values.
127/// Accessed via `DNDS_ENUM_ALLOWED_VALUES(EnumType_)`.
128#define DNDS_DEFINE_ENUM_JSON(EnumType_, ...) \
129 /* (1) Standard nlohmann enum serialization */ \
130 NLOHMANN_JSON_SERIALIZE_ENUM(EnumType_, __VA_ARGS__) \
131 /* (2) Allowed-values function for schema generation */ \
132 inline std::vector<std::string> _dnds_enum_allowed_values_fn(EnumType_ *) \
133 { \
134 return ::DNDS::detail::extractEnumStrings<EnumType_>(__VA_ARGS__); \
135 }
136
137// ============================================================================
138// DNDS_ENUM_ALLOWED_VALUES(EnumType)
139// ============================================================================
140/// @brief Get the list of allowed string values for an enum type.
141///
142/// Returns `std::vector<std::string>`. Only works for enums defined with
143/// `DNDS_DEFINE_ENUM_JSON`. Uses ADL on a dummy pointer argument to find
144/// the correct overload of `_dnds_enum_allowed_values_fn`.
145///
146/// @param EnumType_ The enum type (unquoted).
147#define DNDS_ENUM_ALLOWED_VALUES(EnumType_) \
148 _dnds_enum_allowed_values_fn(static_cast<EnumType_ *>(nullptr))
JSON-to-Eigen conversion utilities and nlohmann_json helper macros.
std::vector< std::string > extractEnumStrings(std::initializer_list< EnumStringPair< EnumType > > pairs)
Extract non-null string values from a list of enum-string pairs.
the host side operators are provided as implemented
A pair of (enum-value, optional string) used to extract allowed values.
EnumStringPair(EnumType v, const char *s)
EnumStringPair(EnumType v, std::nullptr_t)
Eigen::Matrix< real, 5, 1 > v
auto result
const tPoint const tPoint const tPoint & p