ParameterSet.h
Go to the documentation of this file.
1 #ifndef fhiclcpp_ParameterSet_h
2 #define fhiclcpp_ParameterSet_h
3 
4 // ======================================================================
5 //
6 // ParameterSet
7 //
8 // ======================================================================
9 
10 #include "cetlib_except/demangle.h"
12 #include "fhiclcpp/coding.h"
17 #include "fhiclcpp/exception.h"
18 #include "fhiclcpp/fwd.h"
19 
20 #include <any>
21 #include <functional>
22 #include <map>
23 #include <optional>
24 #include <sstream>
25 #include <string>
26 #include <typeinfo>
27 #include <unordered_map>
28 #include <vector>
29 
30 // ----------------------------------------------------------------------
31 
32 namespace cetlib {
33  class filepath_maker;
34 }
35 
37 public:
40  using annot_t = std::unordered_map<std::string, std::string>;
41 
42  // compiler generates default c'tor, d'tor, copy c'tor, copy assignment
43 
44  static ParameterSet make(intermediate_table const& tbl);
45  static ParameterSet make(extended_value const& xval);
46  static ParameterSet make(std::string const& str);
47  static ParameterSet make(std::string const& filename,
49 
50  // observers:
51  bool is_empty() const;
52  ParameterSetID id() const;
53 
54  std::string to_string() const;
55  std::string to_compact_string() const;
56 
57  std::string to_indented_string() const;
58  std::string to_indented_string(unsigned initial_indent_level) const;
59  std::string to_indented_string(unsigned initial_indent_level,
60  bool annotate) const;
61  std::string to_indented_string(unsigned initial_indent_level,
62  detail::print_mode pm) const;
63 
64  std::vector<std::string> get_names() const;
65  std::vector<std::string> get_pset_names() const;
66  std::vector<std::string> get_all_keys() const;
67 
68  // retrievers (nested key OK):
69  bool has_key(std::string const& key) const;
70  bool is_key_to_table(std::string const& key) const;
71  bool is_key_to_sequence(std::string const& key) const;
72  bool is_key_to_atom(std::string const& key) const;
73 
74  template <class T>
75  std::optional<T> get_if_present(std::string const& key) const;
76  template <class T, class Via>
77  std::optional<T> get_if_present(std::string const& key,
78  T convert(Via const&)) const;
79 
80  // Obsolete interface
81  template <class T>
82  bool get_if_present(std::string const& key, T& value) const;
83  template <class T, class Via>
84  bool get_if_present(std::string const& key,
85  T& value,
86  T convert(Via const&)) const;
87 
88  template <class T>
89  T get(std::string const& key) const;
90  template <class T, class Via>
91  T get(std::string const& key, T convert(Via const&)) const;
92  template <class T>
93  T get(std::string const& key, T const& default_value) const;
94  template <class T, class Via>
95  T get(std::string const& key,
96  T const& default_value,
97  T convert(Via const&)) const;
98 
99  std::string get_src_info(std::string const& key) const;
100 
101  // Facility to traverse the ParameterSet tree
102  void walk(ParameterSetWalker& psw) const;
103 
104  // inserters (key must be local: no nesting):
105  void put(std::string const& key); // Implicit nil value.
106  template <class T> // Fail on preexisting key.
107  void put(std::string const& key, T const& value);
108  void put_or_replace(std::string const& key); // Implicit nil value.
109  template <class T> // Succeed.
110  void put_or_replace(std::string const& key, T const& value);
111  template <class T> // Fail if preexisting key of incompatible type.
112  void put_or_replace_compatible(std::string const& key, T const& value);
113 
114  // deleters:
115  bool erase(std::string const& key);
116 
117  // comparators:
118  bool operator==(ParameterSet const& other) const;
119  bool operator!=(ParameterSet const& other) const;
120 
121 private:
122  using map_t = std::map<std::string, std::any>;
124 
128 
129  // Private inserters.
130  void insert_(std::string const& key, std::any const& value);
131  void insert_or_replace_(std::string const& key, std::any const& value);
132  void insert_or_replace_compatible_(std::string const& key,
133  std::any const& value);
134 
135  std::string to_string_(bool compact = false) const;
136  std::string stringify_(std::any const& a, bool compact = false) const;
137 
138  bool key_is_type_(std::string const& key,
139  std::function<bool(std::any const&)> func) const;
140 
141  // Local retrieval only.
142  template <class T>
143  std::optional<T> get_one_(std::string const& key) const;
144  bool find_one_(std::string const& key) const;
145  std::optional<ParameterSet> descend_(
146  std::vector<std::string> const& names) const;
147 
148 }; // ParameterSet
149 
150 // ======================================================================
151 
152 inline std::string
154 {
155  return to_string_();
156 }
157 
158 inline std::string
160 {
161  return to_string_(true);
162 }
163 
164 inline bool
166 {
167  return key_is_type_(key, &detail::is_table);
168 }
169 
170 inline bool
172 {
173  return key_is_type_(key, &detail::is_sequence);
174 }
175 
176 inline bool
178 {
179  return key_is_type_(key, [](std::any const& a) {
180  return !(detail::is_sequence(a) || detail::is_table(a));
181  });
182 }
183 
184 template <class T>
185 void
186 fhicl::ParameterSet::put(std::string const& key, T const& value)
187 {
188  auto insert = [this, &value](auto const& key) {
189  using detail::encode;
190  this->insert_(key, std::any(encode(value)));
191  };
192  detail::try_insert(insert, key);
193 }
194 
195 template <class T>
196 void
198 {
199  auto insert_or_replace = [this, &value](auto const& key) {
200  using detail::encode;
201  this->insert_or_replace_(key, std::any(encode(value)));
202  srcMapping_.erase(key);
203  };
204  detail::try_insert(insert_or_replace, key);
205 }
206 
207 template <class T>
208 void
210  T const& value)
211 {
212  auto insert_or_replace_compatible = [this, &value](auto const& key) {
213  using detail::encode;
214  this->insert_or_replace_compatible_(key, std::any(encode(value)));
215  srcMapping_.erase(key);
216  };
217  detail::try_insert(insert_or_replace_compatible, key);
218 }
219 
220 // ----------------------------------------------------------------------
221 
222 template <class T>
223 std::optional<T>
225 {
226  auto keys = detail::get_names(key);
227  if (auto ps = descend_(keys.tables())) {
228  return ps->get_one_<T>(keys.last());
229  }
230  return std::nullopt;
231 }
232 
233 template <class T, class Via>
234 std::optional<T>
236  T convert(Via const&)) const
237 {
238  auto go_between = get_if_present<Via>(key);
239  if (not go_between) {
240  return std::nullopt;
241  }
242  return std::make_optional(convert(*go_between));
243 } // get_if_present<>()
244 
245 template <class T>
246 bool
248 {
249  if (auto present_parameter = get_if_present<T>(key)) {
250  value = *present_parameter;
251  return true;
252  }
253  return false;
254 }
255 
256 template <class T, class Via>
257 bool
259  T& result,
260  T convert(Via const&)) const
261 {
262  if (auto present_parameter = get_if_present<T>(key, convert)) {
263  result = *present_parameter;
264  return true;
265  }
266  return false;
267 } // get_if_present<>()
268 
269 template <class T>
270 T
272 {
273  auto result = get_if_present<T>(key);
274  return result ? *result : throw fhicl::exception(cant_find, key);
275 }
276 
277 template <class T, class Via>
278 T
279 fhicl::ParameterSet::get(std::string const& key, T convert(Via const&)) const
280 {
281  auto result = get_if_present<T>(key, convert);
282  return result ? *result : throw fhicl::exception(cant_find, key);
283 }
284 
285 template <class T>
286 T
287 fhicl::ParameterSet::get(std::string const& key, T const& default_value) const
288 {
289  auto result = get_if_present<T>(key);
290  return result ? *result : default_value;
291 }
292 
293 template <class T, class Via>
294 T
296  T const& default_value,
297  T convert(Via const&)) const
298 {
299  auto result = get_if_present<T>(key, convert);
300  return result ? *result : default_value;
301 }
302 
303 // ----------------------------------------------------------------------
304 
305 inline bool
307 {
308  return id() == other.id();
309 }
310 
311 inline bool
313 {
314  return !operator==(other);
315 }
316 
317 // ----------------------------------------------------------------------
318 
319 template <class T>
320 std::optional<T>
322 {
323  T value;
324  try {
325  auto skey = detail::get_sequence_indices(key);
326 
327  map_iter_t it = mapping_.find(skey.name());
328  if (it == mapping_.end()) {
329  return std::nullopt;
330  }
331 
332  auto a = it->second;
333  if (!detail::find_an_any(
334  skey.indices().cbegin(), skey.indices().cend(), a)) {
336  }
337 
338  using detail::decode;
339  decode(a, value);
340  return std::make_optional(value);
341  }
342  catch (fhicl::exception const& e) {
343  std::ostringstream errmsg;
344  errmsg << "\nUnsuccessful attempt to convert FHiCL parameter '" << key
345  << "' to type '" << cet::demangle_symbol(typeid(value).name())
346  << "'.\n\n"
347  << "[Specific error:]";
348  throw fhicl::exception(type_mismatch, errmsg.str(), e);
349  }
350  catch (std::exception const& e) {
351  std::ostringstream errmsg;
352  errmsg << "\nUnsuccessful attempt to convert FHiCL parameter '" << key
353  << "' to type '" << cet::demangle_symbol(typeid(value).name())
354  << "'.\n\n"
355  << "[Specific error:]\n"
356  << e.what() << "\n\n";
357  throw fhicl::exception(type_mismatch, errmsg.str());
358  }
359 }
360 
361 // ----------------------------------------------------------------------
362 
363 namespace fhicl {
364  template <>
365  void ParameterSet::put(std::string const& key,
366  fhicl::extended_value const& value);
367 }
368 
369 // ======================================================================
370 
371 #endif /* fhiclcpp_ParameterSet_h */
372 
373 // Local Variables:
374 // mode: c++
375 // End:
static QCString name
Definition: declinfo.cpp:673
bool operator!=(ParameterSet const &other) const
Definition: ParameterSet.h:312
static QCString result
ps_atom_t encode(std::string const &)
Definition: coding.cc:87
std::string string
Definition: nybbler.cc:12
Keys get_names(std::string const &key)
std::unordered_map< std::string, std::string > annot_t
Definition: ParameterSet.h:40
intermediate_table::const_iterator const_iterator
bool find_an_any(cit_size_t it, cit_size_t const cend, std::any &a)
string filename
Definition: train.py:213
map_t::const_iterator map_iter_t
Definition: ParameterSet.h:123
bool operator!=(ModuleKeyAndType const &a, ModuleKeyAndType const &b) noexcept
std::vector< std::any > ps_sequence_t
Definition: coding.h:45
bool is_key_to_sequence(std::string const &key) const
Definition: ParameterSet.h:171
void try_insert(L l, std::string const &key)
Definition: try_blocks.h:11
bool is_key_to_table(std::string const &key) const
Definition: ParameterSet.h:165
const double e
std::map< std::string, std::any > map_t
Definition: ParameterSet.h:122
def key(type, name=None)
Definition: graph.py:13
const double a
def convert(inputfile, outputfile="wire-cell-garfield-fine-response.json.bz2", average=False, shaped=False)
Definition: garfield.py:262
T get(std::string const &key) const
Definition: ParameterSet.h:271
bool operator==(ParameterSet const &other) const
Definition: ParameterSet.h:306
void put_or_replace_compatible(std::string const &key, T const &value)
Definition: ParameterSet.h:209
def walk(top, topdown=True)
fhicl::detail::ps_atom_t ps_atom_t
Definition: ParameterSet.h:38
std::string to_compact_string() const
Definition: ParameterSet.h:159
static constexpr double ps
Definition: Units.h:99
SequenceKey get_sequence_indices(std::string const &key)
fhicl::detail::ps_sequence_t ps_sequence_t
Definition: ParameterSet.h:39
ParameterSetID id() const
unique_ptr< InputSource > make(ParameterSet const &conf, InputSourceDescription &desc)
std::string ps_atom_t
Definition: coding.h:44
std::optional< T > get_if_present(std::string const &key) const
Definition: ParameterSet.h:224
std::optional< T > get_one_(std::string const &key) const
Definition: ParameterSet.h:321
def func()
Definition: docstring.py:7
bool is_key_to_atom(std::string const &key) const
Definition: ParameterSet.h:177
bool is_table(std::any const &val)
Definition: coding.h:55
void decode(std::any const &a, Hep2Vector &result)
Definition: CLHEP_ps.h:12
ParameterSetID id_
Definition: ParameterSet.h:127
static std::vector< std::string > const names
Definition: FragmentType.hh:8
def maker(G, ac, typename)
Definition: apa.py:280
void put_or_replace(std::string const &key)
void function(int client, int *resource, int parblock, int *test, int p)
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
void put(std::string const &key)
static QCString str
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
bool is_sequence(std::any const &val)
Definition: coding.h:49
std::string to_string() const
Definition: ParameterSet.h:153
bool operator==(ModuleKeyAndType const &a, ModuleKeyAndType const &b) noexcept