Tuple.h
Go to the documentation of this file.
1 #ifndef fhiclcpp_types_Tuple_h
2 #define fhiclcpp_types_Tuple_h
3 
5 #include "fhiclcpp/type_traits.h"
6 #include "fhiclcpp/types/Atom.h"
12 
13 #include <memory>
14 #include <string>
15 #include <utility>
16 
17 namespace fhicl {
18 
19  namespace tuple_detail {
20 
21  // Auxiliary struct for accepting either
22  //
23  // (1) {1, false, "Henry"}
24  // (2) std::tuple<int,bool,string>{2, true, "Hannah"}
25  //
26  // default values for Sequence<T,N>
27 
28  template <typename... DEFAULTS>
29  class ValueHolder {
30  public:
31  ValueHolder(DEFAULTS... defaults)
32  : holder_{std::forward_as_tuple(defaults...)}
33  {}
34 
35  ValueHolder(std::tuple<DEFAULTS...> const& tup) : holder_{tup} {}
36 
37  template <std::size_t I>
38  auto const&
39  get() const
40  {
41  return std::get<I>(holder_);
42  }
43 
44  private:
45  std::tuple<DEFAULTS...> holder_;
46  };
47  }
48 
49  class ParameterSet;
50 
51  //==================================================================
52  // e.g. Tuple<int,double,bool> ====> std::tuple<int,double,bool>
53  //
54 
55  template <typename... TYPES>
56  class Tuple final : public detail::SequenceBase,
58  public:
59  using default_type = tuple_detail::ValueHolder<
61  using value_type = std::tuple<tt::return_type<TYPES>...>;
62  using ftype = std::tuple<std::shared_ptr<tt::fhicl_type<TYPES>>...>;
63 
64  explicit Tuple(Name&& name);
65  explicit Tuple(Name&& name, Comment&& comment);
66  explicit Tuple(Name&& name,
67  Comment&& comment,
68  std::function<bool()> maybeUse);
69 
70  // c'tors supporting defaults;
71  explicit Tuple(Name&& name, default_type const& defaults);
72  explicit Tuple(Name&& name,
73  Comment&& comment,
74  default_type const& defaults);
75  explicit Tuple(Name&& name,
76  Comment&& comment,
77  std::function<bool()> maybeUse,
78  default_type const& defaults);
79 
80  auto operator()() const;
81 
82  template <std::size_t I>
83  auto
84  get() const
85  {
86  return (*std::get<I>(value_))();
87  }
88 
89  private:
90  //=================================================================
91  // aliases
92  using TUPLE = std::tuple<tt::fhicl_type<TYPES>...>;
93  using UTUPLE = std::tuple<TYPES...>;
94 
96 
97  std::size_t
98  get_size() const override
99  {
100  return std::tuple_size<ftype>();
101  }
102 
103  void
104  do_set_value(fhicl::ParameterSet const&, bool /*trimParents*/) override
105  {}
106 
107  //===================================================================
108  // iterate over tuple elements
109  using PW_non_const =
112 
113  void
115  {}
116 
117  template <typename E, typename... T>
118  void
119  visit_element(PW_non_const& pw, E& elem, T&... others)
120  {
121  static_assert(!tt::is_table_fragment<E>::value,
126  pw.walk_over(*elem);
127  visit_element(pw, others...);
128  }
129 
130  template <std::size_t... I>
131  void
132  iterate_over_tuple(PW_non_const& pw, std::index_sequence<I...>)
133  {
134  visit_element(pw, std::get<I>(value_)...);
135  }
136 
137  void
138  do_prepare_elements_for_validation(std::size_t const n) override
139  {
141  }
142 
143  void
145  {
146  iterate_over_tuple(pw, std::index_sequence_for<TYPES...>{});
147  }
148 
149  void
151  {}
152 
153  template <typename E, typename... T>
154  void
155  visit_element(PW_const& pw, E const& elem, T const&... others) const
156  {
157  static_assert(!tt::is_table_fragment<E>::value,
162  pw.walk_over(*elem);
163  visit_element(pw, others...);
164  }
165 
166  template <std::size_t... I>
167  void
168  iterate_over_tuple(PW_const& pw, std::index_sequence<I...>) const
169  {
170  visit_element(pw, std::get<I>(value_)...);
171  }
172 
173  void
174  do_walk_elements(PW_const& pw) const override
175  {
176  iterate_over_tuple(pw, std::index_sequence_for<TYPES...>{});
177  }
178 
179  //===============================================================
180  // finalizing tuple elements
181  void finalize_tuple_elements(std::size_t) {}
182 
183  template <typename E, typename... T>
184  void
185  finalize_tuple_elements(std::size_t i, E& elem, T&... others)
186  {
187  using elem_ftype = typename E::element_type;
194  elem = std::make_shared<elem_ftype>(Name::sequence_element(i));
195  finalize_tuple_elements(++i, others...);
196  }
197 
198  template <std::size_t... I>
199  void
200  finalize_elements(std::index_sequence<I...>)
201  {
202  finalize_tuple_elements(0, std::get<I>(value_)...);
203  }
204 
205  //===================================================================
206  // filling tuple elements from default
207  template <size_t I>
208  std::enable_if_t<(I >= std::tuple_size<TUPLE>::value)>
210  {}
211 
212  template <size_t I>
215  {
216  using elem_utype = std::tuple_element_t<I, UTUPLE>;
222  auto& elem = std::get<I>(value_);
223  elem = std::make_shared<tt::fhicl_type<elem_utype>>(
224  Name::sequence_element(I), defaults.template get<I>());
225  fill_tuple_element<I + 1>(defaults);
226  }
227 
228  void
229  fill_tuple_elements(default_type const& default_values)
230  {
231  fill_tuple_element<0>(default_values);
232  }
233 
234  //===================================================================
235  // filling return type
236  template <size_t I, typename value_type>
237  std::enable_if_t<(I >= std::tuple_size<TUPLE>::value)>
239  {}
240 
241  template <size_t I, typename value_type>
244  {
245  std::get<I>(result) = (*std::get<I>(value_))();
246  fill_return_element<I + 1>(result);
247  }
248 
249  void
250  assemble_rtype(value_type& result) const
251  {
252  fill_return_element<0>(result);
253  }
254 
255  //===================================================================
256  // preparing elements for validation
257  template <size_t I>
258  std::enable_if_t<(I >= std::tuple_size<TUPLE>::value)>
260  {}
261 
262  template <size_t I>
265  {
266  std::get<I>(value_)->set_par_style(par_style::REQUIRED);
267  prepare_element_for_validation<I + 1>();
268  }
269 
270  }; // class Tuple
271 
272  //================= IMPLEMENTATION =========================
273  //
274  template <typename... TYPES>
276  {}
277 
278  template <typename... TYPES>
280  : SequenceBase{std::move(name),
281  std::move(comment),
285  , RegisterIfTableMember{this}
286  {
287  finalize_elements(std::index_sequence_for<TYPES...>{});
289  }
290 
291  template <typename... TYPES>
293  Comment&& comment,
294  std::function<bool()> maybeUse)
295  : SequenceBase{std::move(name),
296  std::move(comment),
299  maybeUse}
300  , RegisterIfTableMember{this}
301  {
302  finalize_elements(std::index_sequence_for<TYPES...>{});
304  }
305 
306  // c'tors supporting defaults
307 
308  template <typename... TYPES>
310  : Tuple{std::move(name), Comment(""), defaults}
311  {}
312 
313  template <typename... TYPES>
315  Comment&& comment,
316  default_type const& defaults)
317  : SequenceBase{std::move(name),
318  std::move(comment),
322  , RegisterIfTableMember{this}
323  {
324  fill_tuple_elements(defaults);
326  }
327 
328  template <typename... TYPES>
330  Comment&& comment,
331  std::function<bool()> maybeUse,
332  default_type const& defaults)
333  : SequenceBase{std::move(name),
334  std::move(comment),
337  maybeUse}
338  , RegisterIfTableMember{this}
339  {
340  fill_tuple_elements(defaults);
342  }
343 
344  template <typename... TYPES>
345  auto
347  {
349  assemble_rtype(result);
350  return result;
351  }
352 }
353 
354 #endif /* fhiclcpp_types_Tuple_h */
355 
356 // Local variables:
357 // mode: c++
358 // End:
ValueHolder(DEFAULTS...defaults)
Definition: Tuple.h:31
void do_walk_elements(PW_const &pw) const override
Definition: Tuple.h:174
const XML_Char * name
Definition: expat.h:151
void do_set_value(fhicl::ParameterSet const &, bool) override
Definition: Tuple.h:104
ValueHolder(std::tuple< DEFAULTS... > const &tup)
Definition: Tuple.h:35
#define NO_DELEGATED_PARAMETERS
std::enable_if_t<(I< std::tuple_size< TUPLE >::value)> fill_return_element(value_type &result) const
Definition: Tuple.h:243
void check_nargs_for_bounded_sequences(std::string const &key, std::size_t expected, std::size_t provided)
void fill_tuple_elements(default_type const &default_values)
Definition: Tuple.h:229
#define NO_OPTIONAL_TYPES
std::size_t get_size() const override
Definition: Tuple.h:98
std::enable_if_t<(I >=std::tuple_size< TUPLE >::value)> fill_tuple_element(default_type const &)
Definition: Tuple.h:209
ftype value_
Definition: Tuple.h:95
std::function< bool()> AlwaysUse()
double value_
SequenceBase(Name &&name, Comment &&comment, par_style const vt, par_type const type, std::function< bool()> maybeUse)
Definition: SequenceBase.h:20
void finalize_elements(std::index_sequence< I... >)
Definition: Tuple.h:200
void iterate_over_tuple(PW_non_const &pw, std::index_sequence< I... >)
Definition: Tuple.h:132
void do_prepare_elements_for_validation(std::size_t const n) override
Definition: Tuple.h:138
std::enable_if_t<(I >=std::tuple_size< TUPLE >::value)> prepare_element_for_validation()
Definition: Tuple.h:259
void walk_over(tt::maybe_const_t< ParameterBase, C > &)
std::enable_if_t<(I< std::tuple_size< TUPLE >::value)> fill_tuple_element(default_type const &defaults)
Definition: Tuple.h:214
const XML_Char int const XML_Char * value
Definition: expat.h:331
typename fhicl_type_impl< T >::type fhicl_type
Definition: type_traits.h:273
Float_t E
Definition: plot.C:20
#define NO_STD_CONTAINERS
void iterate_over_tuple(PW_const &pw, std::index_sequence< I... >) const
Definition: Tuple.h:168
void finalize_tuple_elements(std::size_t i, E &elem, T &...others)
Definition: Tuple.h:185
std::tuple< TYPES... > UTUPLE
Definition: Tuple.h:93
#define NO_NESTED_TABLE_FRAGMENTS
void visit_element(PW_non_const &pw, E &elem, T &...others)
Definition: Tuple.h:119
auto operator()() const
Definition: Tuple.h:346
static Name sequence_element(std::size_t const i)
Definition: Name.h:17
void finalize_tuple_elements(std::size_t)
Definition: Tuple.h:181
void assemble_rtype(value_type &result) const
Definition: Tuple.h:250
std::tuple< tt::return_type< TYPES >... > value_type
Definition: Tuple.h:61
std::enable_if_t<(I< std::tuple_size< TUPLE >::value)> prepare_element_for_validation()
Definition: Tuple.h:264
void do_walk_elements(PW_non_const &pw) override
Definition: Tuple.h:144
double T
Definition: Xdiff_gwt.C:5
#define NO_DEFAULTS_FOR_TABLE
std::tuple< DEFAULTS... > holder_
Definition: Tuple.h:45
std::tuple< std::shared_ptr< tt::fhicl_type< TYPES >>... > ftype
Definition: Tuple.h:62
std::enable_if_t<(I >=std::tuple_size< TUPLE >::value)> fill_return_element(value_type &) const
Definition: Tuple.h:238
Tuple(Name &&name)
Definition: Tuple.h:275
void visit_element(PW_non_const &)
Definition: Tuple.h:114
std::string comment() const
Definition: ParameterBase.h:54
std::tuple< tt::fhicl_type< TYPES >... > TUPLE
Definition: Tuple.h:92
void visit_element(PW_const &) const
Definition: Tuple.h:150
void visit_element(PW_const &pw, E const &elem, T const &...others) const
Definition: Tuple.h:155