alpaqa 1.0.0a15
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
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 auto keys = std::views::keys(members);
63 std::vector<std::string> sorted_keys{keys.begin(), keys.end()};
65 throw invalid_json_param("Invalid key '" + key +
66 "' for type '" +
67 demangled_typename(typeid(T)) +
68 "',\n possible keys are: " +
70 }
71 }
72 // Member was found, invoke its setter (and possibly recurse)
73 try {
74 it->second.set(t, el.value());
75 } catch (invalid_json_param &e) {
76 // Keep a backtrace of the JSON keys for error reporting
77 e.backtrace.push_back(key);
78 throw;
79 }
80 }
81}
82
83template <class T>
84 requires requires { attribute_table<T, json>::table; }
85void get_param(const T &t, json &s) {
86 s = json::object();
87 const auto &m = attribute_table<T, json>::table;
88 for (auto &&[k, v] : m)
89 v.get(t, s[k]);
90}
91
92} // 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 &s)
Get the first argument as a JSON object j.
Definition json.tpp:85
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:42
Specialize this type to define the attribute name to attribute setters dictionaries for a struct type...
Definition structs.hpp:19
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:25
constexpr const auto inf
Definition config.hpp:85
Double-precision double configuration.
Definition config.hpp:135
Custom parameter parsing exception.
Definition json.hpp:33
std::vector< std::string > backtrace
Definition json.hpp:35