intermediate_table.h
Go to the documentation of this file.
1 #ifndef fhiclcpp_intermediate_table_h
2 #define fhiclcpp_intermediate_table_h
3 
4 ////////////////////////////////////////////////////////////////////////
5 // intermediate table: generic representation of parameters.
6 //
7 // This class should only be used in the following two circumstances:
8 //
9 // 1. Configuration post-processing, prior to ParameterSet creation
10 // (use the "simple interface" where possible).
11 //
12 // 2. Internally by FHiCL.
13 //
14 // In all other circumstances, ParameterSet is almost certainly more
15 // appropriate.
16 //
17 // 2012/08/29 CG.
18 ////////////////////////////////////////////////////////////////////////
19 
20 ////////////////////////////////////////////////////////////////////////
21 // Supplemental expert notes on intermediate_table vs ParameterSet.
22 //
23 // 1. Intermediate tables contain only extended values; ParameterSets
24 // contain only std::any.
25 //
26 // 2. The std::any in a ParameterSet may not be the same type as the
27 // std::any in the corresponding extended_value in the intermediate
28 // table whence it came.
29 //
30 // 3. An extended_value::sequence_t is std::vector<extended_value>; a
31 // ParameterSet::ps_sequence_t is std::vector<std::any>.
32 //
33 // 4. An extended_value::table_t is std::map<std::string,
34 // extended_value>; the equivalent concept in ParameterSet is
35 // ParameterSet (stored as std::any).
36 //
37 // 5. An extended_value::complex_t is std::pair<std::string,
38 // std::string>; the equivalent concept in ParameterSet is
39 // std::string (stored as std::any).
40 //
41 // 6. Numbers, boolean values and strings are to be stored in
42 // intermediate_tables at all times in their canonical string form
43 // (using detail::encode()); complex numbers are stored in
44 // intermediate tables as a pair of strings representing the
45 // canonical string forms of the real and imaginary parts. In
46 // ParameterSets they are stored as a single std::string,
47 // "(real,imag)".
48 //
49 ////////////////////////////////////////////////////////////////////////
50 
51 #include "fhiclcpp/coding.h"
52 #include "fhiclcpp/exception.h"
54 #include "fhiclcpp/fwd.h"
55 #include "fhiclcpp/type_traits.h"
56 
57 #include <any>
58 #include <complex>
59 #include <string>
60 #include <type_traits>
61 #include <vector>
62 
63 // ----------------------------------------------------------------------
64 
66 public:
67  ////////////////////
68  // Simple interface:
69  bool empty() const;
70 
71  bool exists(std::string const& key) const;
72 
73  void erase(std::string const& key, bool in_prolog = false);
74 
75  template <typename T>
76  T get(std::string const& name);
77 
78  bool put(std::string const& name,
79  std::string const& value, // String.
80  bool in_prolog = false);
81  bool put(std::string const& name,
82  char const* value, // String.
83  bool in_prolog = false);
84  bool put(std::string const& name,
85  bool value, // Boolean.
86  bool in_prolog = false);
87  template <typename T>
88  bool put(std::string const& name,
89  std::complex<T> const& value, // Complex.
90  bool in_prolog = false);
91  template <typename T>
92  bool put(std::string const& name,
93  std::vector<T> const& value, // Sequence.
94  bool in_prolog = false);
95  template <typename T>
97  T value, // Number
98  bool in_prolog = false);
99 
100  bool putEmptySequence(std::string const& name,
101  bool in_prolog = false); // Empty Sequence.
102  bool putEmptyTable(std::string const& name,
103  bool in_prolog = false); // Empty Table.
104  bool putNil(std::string const& name,
105  bool in_prolog = false); // Nil.
106 
107  ////////////////////
108  // Expert interface.
109  // Typedefs.
116 
117  const_iterator begin() const;
118  const_iterator end() const;
119 
120  // Flexible insert interface.
121  bool insert(std::string const& key,
122  bool in_prolog,
123  value_tag tag,
124  std::any const& value);
125  bool insert(std::string const& key, extended_value const& value);
126  bool insert(std::string const& key, extended_value&& value);
127 
128  /// \throw if item does not exist.
129  extended_value const& find(std::string const& key) const;
130 
131  /// \return nullptr if not able to be updated.
132  extended_value* locate(std::string const& key);
133 
134  /// \throw if not able to be updated.
135  extended_value& update(std::string const& key);
136 
137 private:
138  // Do all the work required to find somewhere to put the new
139  // value. Called by insert().
141  extended_value const& value);
142 
143  // Return an item with a bool indicating whether it may be updated.
144  std::pair<extended_value*, bool> locate_(std::string const& key,
145  bool in_prolog = false);
146 
147  static std::vector<std::string> split(std::string const& key);
148 
150 
151 }; // intermediate_table
152 
153 namespace fhicl::detail {
154 
155  // Template declaration (no general definition).
156  template <typename T, typename Enable = void>
158 
159  // Partial specialization for value types.
160  template <typename T>
162  typename tt::disable_if<std::is_reference_v<T> ||
163  std::is_pointer_v<T>>::type> {
164  public:
165  T
167  {
168  T result;
169  detail::decode(table.find(key).value, result);
170  return result;
171  }
172  };
173 
174  // Partial specialization for std::complex<U>.
175  template <typename U>
177  std::complex<U>,
178  typename tt::disable_if<std::is_reference_v<std::complex<U>> ||
179  std::is_pointer_v<std::complex<U>>>::type> {
180  public:
181  std::complex<U>
183  {
185  U r, i;
186  detail::decode(c.first, r);
187  detail::decode(c.second, i);
188  return std::complex<U>(r, i);
189  }
190  };
191 
192  // Full specialization for sequence_t
193  template <>
195  public:
198  {
199  return std::any_cast<intermediate_table::sequence_t>(
200  table.find(key).value);
201  }
202  };
203 
204  // Full specialization for sequence_t&: will throw if not writable
205  template <>
207  public:
208  intermediate_table::sequence_t&
210  {
211  auto item = table.locate(key);
212  if (item != nullptr) {
213  return std::any_cast<intermediate_table::sequence_t&>(item->value);
214  }
216  << "Requested non-updatable parameter \"" << key << "\" for update.\n";
217  }
218  };
219 
220  // Full specialization for sequence_t const&
221  template <>
223  public:
224  intermediate_table::sequence_t const&
226  {
227  return std::any_cast<intermediate_table::sequence_t const&>(
228  table.find(key).value);
229  }
230  };
231 
232  // Full specialization for table_t
233  template <>
235  public:
238  {
239  return std::any_cast<intermediate_table::table_t>(table.find(key).value);
240  }
241  };
242 
243  // Full specialization for table_t&: will throw if not writable
244  template <>
246  public:
247  intermediate_table::table_t&
249  {
250  auto item = table.locate(key);
251  if (item != nullptr) {
252  return std::any_cast<intermediate_table::table_t&>(item->value);
253  }
255  << "Requested non-updatable parameter " << key << " for update.\n";
256  }
257  };
258 
259  // Full specialization for table_t const&
260  template <>
262  public:
263  intermediate_table::table_t const&
265  {
266  return std::any_cast<intermediate_table::table_t const&>(
267  table.find(key).value);
268  }
269  };
270 }
271 
272 template <typename T>
273 inline T
275 {
276  static detail::it_value_get<T> getter;
277  return getter(*this, key);
278 }
279 
280 inline bool
282  std::string const& value, // String.
283  bool in_prolog)
284 {
285  return insert(key, in_prolog, STRING, detail::encode(value));
286 }
287 
288 inline bool
290  char const* value, // String.
291  bool const in_prolog)
292 {
293  return insert(key, in_prolog, STRING, detail::encode(value));
294 }
295 
296 inline bool
298  bool const value, // Boolean.
299  bool const in_prolog)
300 {
301  return insert(key, in_prolog, BOOL, detail::encode(value));
302 }
303 
304 template <typename T>
305 bool
307  std::complex<T> const& value, // Complex.
308  bool const in_prolog)
309 {
310  return insert(
311  key,
312  in_prolog,
313  COMPLEX,
314  complex_t(detail::encode(value.real()), detail::encode(value.imag())));
315 }
316 
317 template <typename T>
318 inline bool
320  std::vector<T> const& value, // Sequence.
321  bool const in_prolog)
322 {
323  bool result = putEmptySequence(key, in_prolog);
324  if (!result) {
325  return result;
326  }
327  size_t count(0);
328  for (auto const& item : value) {
329  result =
330  result && put(key + "[" + std::to_string(count++) + "]", item, in_prolog);
331  }
332  return result;
333 }
334 
335 template <typename T>
338  T const value, // Number
339  bool const in_prolog)
340 {
341  return insert(key, in_prolog, NUMBER, detail::encode(value));
342 }
343 
345  std::string const& key,
346  bool const in_prolog) // Sequence.
347 {
348  return insert(key, in_prolog, SEQUENCE, sequence_t{});
349 }
350 
352  std::string const& key,
353  bool const in_prolog) // Table.
354 {
355  return insert(key, in_prolog, TABLE, table_t{});
356 }
357 
359  bool const in_prolog) // Nil.
360 {
361  return insert(key, in_prolog, NIL, detail::encode(nullptr));
362 }
363 
364 inline fhicl::extended_value*
366 {
367  extended_value* result = nullptr;
368  auto located = locate_(key);
369  if (located.second) {
370  result = located.first;
371  }
372  return result;
373 }
374 
375 inline fhicl::extended_value&
377 {
378  auto located = locate_(key);
379  if (!located.second) {
381  << "Requested non-modifiable item \"" << key << "\" for update.\n";
382  }
383  return *located.first;
384 }
385 
386 #endif /* fhiclcpp_intermediate_table_h */
387 
388 // Local Variables:
389 // mode: c++
390 // End:
static QCString name
Definition: declinfo.cpp:673
extended_value * locate(std::string const &key)
static QCString result
const_iterator end() const
ps_atom_t encode(std::string const &)
Definition: coding.cc:87
std::string string
Definition: nybbler.cc:12
intermediate_table::sequence_t & operator()(intermediate_table &table, std::string const &key)
bool insert(std::string const &key, bool in_prolog, value_tag tag, std::any const &value)
bool putEmptySequence(std::string const &name, bool in_prolog=false)
iter< iterator_tag, const std::pair< const Key, T >> const_iterator
Definition: stdmap_shims.h:128
STL namespace.
intermediate_table::sequence_t const & operator()(intermediate_table &table, std::string const &key)
std::pair< std::string, std::string > complex_t
void decode(std::any const &, std::string &)
Definition: type_traits.h:61
extended_value::complex_t complex_t
def key(type, name=None)
Definition: graph.py:13
const_iterator begin() const
intermediate_table::table_t operator()(intermediate_table &table, std::string const &key)
intermediate_table::table_t const & operator()(intermediate_table &table, std::string const &key)
bool putNil(std::string const &name, bool in_prolog=false)
intermediate_table::sequence_t operator()(intermediate_table &table, std::string const &key)
extended_value::sequence_t sequence_t
std::vector< extended_value > sequence_t
shims::map< std::string, extended_value > table_t
bool put(std::string const &name, std::string const &value, bool in_prolog=false)
bool exists(std::string const &key) const
fhicl::extended_value::sequence_t sequence_t
bool putEmptyTable(std::string const &name, bool in_prolog=false)
std::enable_if<!b, T > disable_if
Definition: type_traits.h:66
extended_value * pre_insert_(std::string const &key, extended_value const &value)
void erase(std::string const &key, bool in_prolog=false)
extended_value const & find(std::string const &key) const
extended_value & update(std::string const &key)
static std::vector< std::string > split(std::string const &key)
iter< iterator_tag, std::pair< const Key, T >> iterator
Definition: stdmap_shims.h:127
std::enable_if<!b, T > disable_if
T get(std::string const &name)
std::pair< extended_value *, bool > locate_(std::string const &key, bool in_prolog=false)
extended_value::atom_t atom_t
intermediate_table::table_t & operator()(intermediate_table &table, std::string const &key)
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33