DNDSR 0.1.0.dev1+gcd065ad
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
55#include "JsonUtil.hpp"
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 /// @brief Extract non-null string values from a list of enum-string pairs.
91 template <typename EnumType>
92 std::vector<std::string> extractEnumStrings(
93 std::initializer_list<EnumStringPair<EnumType>> pairs)
94 {
95 std::vector<std::string> result;
96 result.reserve(pairs.size());
97 for (const auto &p : pairs)
98 {
99 if (!p.isNull)
100 result.push_back(p.str);
101 }
102 return result;
103 }
104 } // namespace detail
105} // namespace DNDS
106
107// ============================================================================
108// DNDS_DEFINE_ENUM_JSON(EnumType, ...)
109// ============================================================================
110/// @brief Define JSON serialization for an enum AND expose its allowed string values.
111///
112/// Drop-in replacement for `NLOHMANN_JSON_SERIALIZE_ENUM` that additionally
113/// generates a function returning the allowed string values for schema emission.
114///
115/// The variadic arguments are `{EnumValue, "string"}` pairs, identical to those
116/// accepted by `NLOHMANN_JSON_SERIALIZE_ENUM`. Pairs with `nullptr` as the
117/// string (sentinel/unknown values) are excluded from the allowed-values list.
118///
119/// @param EnumType_ The enum type.
120/// @param ... Comma-separated `{EnumValue, "string_or_nullptr"}` pairs.
121///
122/// Generates:
123/// 1. `NLOHMANN_JSON_SERIALIZE_ENUM(EnumType_, ...)` — standard serialization.
124/// 2. `inline std::vector<std::string> _dnds_enum_values_<mangled>()` — allowed values.
125/// Accessed via `DNDS_ENUM_ALLOWED_VALUES(EnumType_)`.
126#define DNDS_DEFINE_ENUM_JSON(EnumType_, ...) \
127 /* (1) Standard nlohmann enum serialization */ \
128 NLOHMANN_JSON_SERIALIZE_ENUM(EnumType_, __VA_ARGS__) \
129 /* (2) Allowed-values function for schema generation */ \
130 inline std::vector<std::string> _dnds_enum_allowed_values_fn(EnumType_ *) \
131 { \
132 return ::DNDS::detail::extractEnumStrings<EnumType_>(__VA_ARGS__); \
133 }
134
135// ============================================================================
136// DNDS_ENUM_ALLOWED_VALUES(EnumType)
137// ============================================================================
138/// @brief Get the list of allowed string values for an enum type.
139///
140/// Returns `std::vector<std::string>`. Only works for enums defined with
141/// `DNDS_DEFINE_ENUM_JSON`. Uses ADL on a dummy pointer argument to find
142/// the correct overload of `_dnds_enum_allowed_values_fn`.
143///
144/// @param EnumType_ The enum type (unquoted).
145#define DNDS_ENUM_ALLOWED_VALUES(EnumType_) \
146 _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