alpaqa 1.0.0a8
Nonconvex constrained optimization
Loading...
Searching...
No Matches
params.tpp
Go to the documentation of this file.
2
5
6#include <charconv>
7#include <chrono>
8#include <concepts>
9#include <map>
10#include <numeric>
11#include <stdexcept>
12#include <string_view>
13#include <system_error>
14#include <tuple>
15#include <type_traits>
16
17namespace alpaqa::params {
18
20
21/// Throw a meaningful error when `s.key` is not empty, to indicate that
22/// the given type @p T is not of struct type and cannot be indexed into.
23template <class T>
25 if (!s.key.empty())
26 throw invalid_param("Type '" + demangled_typename(typeid(T)) +
27 "' cannot be indexed in '" +
28 std::string(s.full_key) + "'");
29}
30
31/// Throw a meaningful error to indicate that parameters of type @p T are not
32/// supported or implemented.
33template <class T>
34void unsupported_type(T &, [[maybe_unused]] ParamString s) {
35 throw invalid_param("Unknown parameter type '" +
36 demangled_typename(typeid(T)) + "' in '" +
37 std::string(s.full_key) + "'");
38}
39
40template <>
41void set_param(bool &b, ParamString s);
42
43template <>
44void set_param(std::string_view &v, ParamString s);
45
46template <>
47void set_param(std::string &v, ParamString s);
48
49template <class T>
50 requires((std::floating_point<T> || std::integral<T>) && !std::is_enum_v<T>)
51void set_param(T &f, ParamString s);
52
53template <>
54void set_param(vec<config_t> &v, ParamString s);
55
56template <>
57void set_param(vec_from_file<config_t> &v, ParamString s);
58
59template <class Rep, class Period>
60void set_param(std::chrono::duration<Rep, Period> &t, ParamString s);
61
62/// Return a function that applies @ref set_param to the given attribute of a
63/// value of type @p T.
64template <class T, class A>
65auto param_setter(A T::*attr) {
66 return [attr](T &t, ParamString s) { return set_param(t.*attr, s); };
67}
68
69/// Function wrapper to set attributes of a struct, type-erasing the type of the
70/// attribute.
71template <class T>
73 template <class A>
74 param_setter_fun_t(A T::*attr) : set(param_setter(attr)) {}
75 std::function<void(T &, ParamString)> set;
76 void operator()(T &t, ParamString s) const { return set(t, s); }
77};
78
79/// Dictionary that maps struct attribute names to type-erased functions that
80/// set those attributes.
81template <class T>
83 std::map<std::string_view, param_setter_fun_t<T>>;
84
85/// Specialize this type to define the attribute name to attribute setters
86/// dictionaries for a struct type @p T.
87template <class T>
89
90/// Return a string enumerating the possible attribute names for the struct type
91/// @p T.
92template <class T>
94 const auto &tbl = dict_to_struct_table<T>::table;
95 if (tbl.empty())
96 return std::string{};
97 auto penult = std::prev(tbl.end());
98 auto quote_concat = [](std::string &&a, auto b) {
99 return a + "'" + std::string(b.first) + "', ";
100 };
101 return std::accumulate(tbl.begin(), penult, std::string{}, quote_concat) +
102 "'" + std::string(penult->first) + "'";
103}
104
105/// Use @p s to index into the struct type @p T and overwrite the attribute
106/// given by @p s.key.
107template <class T>
108 requires requires { dict_to_struct_table<T>::table; }
109void set_param(T &t, ParamString s) {
110 const auto &m = dict_to_struct_table<T>::table;
111 auto [key, remainder] = split_key(s.key);
112 auto it = m.find(key);
113 if (it == m.end())
114 throw invalid_param("Invalid key '" + std::string(key) +
115 "' for type '" + demangled_typename(typeid(T)) +
116 "' in '" + std::string(s.full_key) +
117 "',\n possible keys are: " + possible_keys<T>());
118 s.key = remainder;
119 it->second.set(t, s);
120}
121
122/// Helper macro to easily specialize @ref alpaqa::params::dict_to_struct_table.
123#define PARAMS_TABLE(type_, ...) \
124 template <> \
125 struct dict_to_struct_table<type_> { \
126 using type = type_; \
127 inline static const dict_to_struct_table_t<type> table{__VA_ARGS__}; \
128 }
129
130/// Helper macro to easily initialize a
131/// @ref alpaqa::params::dict_to_struct_table_t.
132#define PARAMS_MEMBER(name) \
133 { \
134#name, &type::name \
135 }
136
137} // namespace alpaqa::params
std::string demangled_typename(const std::type_info &t)
Get the pretty name of the given type as a string.
void set_param(bool &b, ParamString s)
Definition: params.cpp:26
auto param_setter(A T::*attr)
Return a function that applies set_param to the given attribute of a value of type T.
Definition: params.tpp:65
void unsupported_type(T &, ParamString s)
Throw a meaningful error to indicate that parameters of type T are not supported or implemented.
Definition: params.tpp:34
std::string_view key
The subkey to resolve next.
Definition: params.hpp:20
void assert_key_empty(ParamString s)
Throw a meaningful error when s.key is not empty, to indicate that the given type T is not of struct ...
Definition: params.tpp:24
std::string_view full_key
Full key string, used for diagnostics.
Definition: params.hpp:18
auto split_key(std::string_view full, char tok='.')
Split the string full on the first occurrence of tok.
Definition: params.hpp:32
std::map< std::string_view, param_setter_fun_t< T > > dict_to_struct_table_t
Dictionary that maps struct attribute names to type-erased functions that set those attributes.
Definition: params.tpp:83
auto possible_keys()
Return a string enumerating the possible attribute names for the struct type T.
Definition: params.tpp:93
Represents a parameter value encoded as a string in the format abc.def.key=value.
Definition: params.hpp:16
Specialize this type to define the attribute name to attribute setters dictionaries for a struct type...
Definition: params.tpp:88
typename Conf::vec vec
Definition: config.hpp:52
Custom parameter parsing exception.
Definition: params.hpp:26
Function wrapper to set attributes of a struct, type-erasing the type of the attribute.
Definition: params.tpp:72
std::function< void(T &, ParamString)> set
Definition: params.tpp:75
void operator()(T &t, ParamString s) const
Definition: params.tpp:76