alpaqa 1.0.0a16
Nonconvex constrained optimization
Loading...
Searching...
No Matches
json.tpp
Go to the documentation of this file.
5
6#include <nlohmann/json.hpp>
7#include <stdexcept>
8
9namespace alpaqa::params {
10
12
13namespace detail {
14std::string join_sorted_keys(const auto &members) {
15 auto keys = std::views::keys(members);
16 std::vector<std::string> sorted_keys{keys.begin(), keys.end()};
18 return util::join(sorted_keys, {.sep = ", ", .empty = "∅"});
19}
20} // namespace detail
21
22template <class T>
23 requires requires { attribute_table<T, json>::table; }
24void set_param(T &t, const json &j) {
25 if (!j.is_object())
26 throw invalid_json_param("Invalid value " + to_string(j) +
27 " for type '" + demangled_typename(typeid(T)) +
28 "' (expected object, but got " +
29 j.type_name() + ')');
30 // Dictionary of members
31 const auto &members = attribute_table<T, json>::table;
32 // Loop over all items in the JSON object
33 for (auto &&el : j.items()) {
34 const auto &key = el.key();
35 auto it = members.find(key);
36 // If member was not found
37 if (it == members.end()) {
38 // Perhaps it's an alias to another member?
39 if constexpr (requires { attribute_alias_table<T, json>::table; }) {
41 auto alias_it = aliases.find(key);
42 // If it's not an alias either, raise an error
43 if (alias_it == aliases.end()) {
45 "Invalid key '" + key + "' for type '" +
46 demangled_typename(typeid(T)) +
47 "',\n possible keys are: " +
48 detail::join_sorted_keys(members) + " (aliases: " +
50 }
51 // Resolve the alias and make sure that the target exists
52 it = members.find(alias_it->second);
53 if (it == members.end())
54 throw std::logic_error(
55 "Alias '" + std::string(alias_it->first) +
56 "' refers to nonexistent option '" +
57 std::string(alias_it->second) + "' in '" +
58 demangled_typename(typeid(T)) + "'");
59 }
60 // If there are no aliases, then it's always an error
61 else {
62 throw invalid_json_param("Invalid key '" + key +
63 "' for type '" +
64 demangled_typename(typeid(T)) +
65 "',\n possible keys are: " +
67 }
68 }
69 // Member was found, invoke its setter (and possibly recurse)
70 try {
71 it->second.set(t, el.value());
72 } catch (invalid_json_param &e) {
73 // Keep a backtrace of the JSON keys for error reporting
74 e.backtrace.push_back(key);
75 throw;
76 }
77 }
78}
79
80template <class T>
81 requires requires { enum_table<T, json>::table; }
82void set_param(T &t, const json &j) {
83 if (!j.is_string())
84 throw invalid_json_param("Invalid value " + to_string(j) +
85 " for enum '" + demangled_typename(typeid(T)) +
86 "' (expected string, but got " +
87 j.type_name() + ')');
88 // Dictionary of members
89 const auto &m = enum_table<T, json>::table;
90 std::string value = j;
91 auto it = m.find(value);
92 if (it == m.end()) {
94 "Invalid value '" + value + "' for enum '" +
95 demangled_typename(typeid(T)) +
96 "',\n possible values are: " + detail::join_sorted_keys(m));
97 }
98 t = it->second.value;
99}
100
101template <class T>
102 requires requires { enum_table<T, json>::table; }
103void get_param(const T &t, json &j) {
104 j = enum_name(t);
105}
106
107template <class T>
108 requires requires { attribute_table<T, json>::table; }
109void get_param(const T &t, json &s) {
110 s = json::object();
111 const auto &m = attribute_table<T, json>::table;
112 for (auto &&[k, v] : m)
113 v.get(t, s[k]);
114}
115
116} // namespace alpaqa::params
std::string demangled_typename(const std::type_info &t)
Get the pretty name of the given type as a string.
std::string join_sorted_keys(const auto &members)
Definition json.tpp:14
void get_param(const T &t, json &j)
Get the first argument as a JSON object j.
Definition json.tpp:103
void set_param(T &t, const json &j)
Update/overwrite the first argument based on the JSON object j.
Definition json.tpp:24
Specialize this type to define the alternative attribute name to attribute setters dictionaries for a...
Definition structs.hpp:44
Specialize this type to define the attribute name to attribute setters dictionaries for a struct type...
Definition structs.hpp:19
Specialize this type to define the enumerator name to value dictionaries for an enum type T.
Definition structs.hpp:72
std::string join(std::ranges::input_range auto strings, join_opt opt={})
Join the list of strings into a single string, using the separator given by opt.
void sort_case_insensitive(auto &range)
Sort the given range of strings in-place in a case-insensitive manner.
EigenConfigd DefaultConfig
Definition config.hpp:26
constexpr const auto inf
Definition config.hpp:98
constexpr const char * enum_name(LBFGSStepSize s)
Definition lbfgs.hpp:229
Double-precision double configuration.
Definition config.hpp:160
Custom parameter parsing exception.
Definition json.hpp:39
std::vector< std::string > backtrace
Definition json.hpp:41