LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
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...> const 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... T>
56  class Tuple final : public detail::SequenceBase,
58  public:
59  using default_type =
61  using value_type = std::tuple<tt::return_type<T>...>;
62  using ftype = std::tuple<std::shared_ptr<tt::fhicl_type<T>>...>;
63 
64  static_assert(
65  !std::disjunction_v<tt::is_table_fragment<tt::return_type<T>>...>,
67  static_assert(
68  !std::disjunction_v<tt::is_optional_parameter<tt::return_type<T>>...>,
70  static_assert(
71  !std::disjunction_v<tt::is_delegated_parameter<tt::return_type<T>>...>,
73 
74  explicit Tuple(Name&& name);
75  explicit Tuple(Name&& name, Comment&& comment);
76  explicit Tuple(Name&& name,
77  Comment&& comment,
78  std::function<bool()> maybeUse);
79 
80  // c'tors supporting defaults;
81  explicit Tuple(Name&& name, default_type const& defaults);
82  explicit Tuple(Name&& name,
83  Comment&& comment,
84  default_type const& defaults);
85  explicit Tuple(Name&& name,
86  Comment&& comment,
87  std::function<bool()> maybeUse,
88  default_type const& defaults);
89 
90  auto operator()() const;
91 
92  template <std::size_t I>
93  auto
94  get() const
95  {
96  return (*std::get<I>(value_))();
97  }
98 
99  private:
101 
102  std::size_t
103  get_size() const noexcept override
104  {
105  return std::tuple_size<ftype>();
106  }
107 
108  void
109  do_set_value(ParameterSet const&) override
110  {}
111 
112  //===================================================================
113  // iterate over tuple elements
114  using PW_non_const =
117 
118  template <std::size_t... I>
119  void
120  iterate_over_tuple(PW_non_const& pw, std::index_sequence<I...>)
121  {
122  (pw.walk_over(*std::get<I>(value_)), ...);
123  }
124 
125  void
126  do_prepare_elements_for_validation(std::size_t const n) override
127  {
128  detail::check_nargs_for_bounded_sequences(key(), get_size(), n);
129  }
130 
131  void
133  {
134  iterate_over_tuple(pw, std::index_sequence_for<T...>{});
135  }
136 
137  template <std::size_t... I>
138  void
139  iterate_over_tuple(PW_const& pw, std::index_sequence<I...>) const
140  {
141  (pw.walk_over(*std::get<I>(value_)), ...);
142  }
143 
144  void
145  do_walk_elements(PW_const& pw) const override
146  {
147  iterate_over_tuple(pw, std::index_sequence_for<T...>{});
148  }
149 
150  //===============================================================
151  // finalizing tuple elements
152  template <std::size_t I>
153  void
155  {
156  using elem_ftype = typename std::tuple_element_t<I, ftype>::element_type;
157  std::get<I>(value_) =
158  std::make_shared<elem_ftype>(Name::sequence_element(I));
159  }
160 
161  template <std::size_t... I>
162  void
163  finalize_elements(std::index_sequence<I...>)
164  {
165  (finalize_element<I>(), ...);
166  }
167 
168  //===================================================================
169  // filling tuple elements from default
170  template <size_t I>
171  void
173  {
174  using elem_ftype = typename std::tuple_element_t<I, ftype>::element_type;
175  std::get<I>(value_) = std::make_shared<elem_ftype>(
176  Name::sequence_element(I), defaults.template get<I>());
177  }
178 
179  template <std::size_t... I>
180  void
181  fill_tuple_elements(default_type const& default_values,
182  std::index_sequence<I...>)
183  {
184  (fill_tuple_element<I>(default_values), ...);
185  }
186 
187  //===================================================================
188  // filling return type
189  template <std::size_t... I>
190  value_type
191  get_rtype_result(std::index_sequence<I...>) const
192  {
193  return value_type{(*std::get<I>(value_))()...};
194  }
195 
196  }; // class Tuple
197 
198  //================= IMPLEMENTATION =========================
199  //
200  template <typename... T>
201  Tuple<T...>::Tuple(Name&& name) : Tuple{std::move(name), Comment("")}
202  {}
203 
204  template <typename... T>
206  : SequenceBase{std::move(name),
207  std::move(comment),
211  , RegisterIfTableMember{this}
212  {
213  finalize_elements(std::index_sequence_for<T...>{});
215  }
216 
217  template <typename... T>
219  Comment&& comment,
220  std::function<bool()> maybeUse)
221  : SequenceBase{std::move(name),
222  std::move(comment),
225  maybeUse}
226  , RegisterIfTableMember{this}
227  {
228  finalize_elements(std::index_sequence_for<T...>{});
230  }
231 
232  // c'tors supporting defaults
233 
234  template <typename... T>
236  : Tuple{std::move(name), Comment(""), defaults}
237  {}
238 
239  template <typename... T>
241  Comment&& comment,
242  default_type const& defaults)
243  : SequenceBase{std::move(name),
244  std::move(comment),
248  , RegisterIfTableMember{this}
249  {
250  fill_tuple_elements(defaults, std::index_sequence_for<T...>());
252  }
253 
254  template <typename... T>
256  Comment&& comment,
257  std::function<bool()> maybeUse,
258  default_type const& defaults)
259  : SequenceBase{std::move(name),
260  std::move(comment),
263  maybeUse}
264  , RegisterIfTableMember{this}
265  {
266  fill_tuple_elements(defaults, std::index_sequence_for<T...>());
268  }
269 
270  template <typename... T>
271  auto
273  {
274  return get_rtype_result(std::index_sequence_for<T...>());
275  }
276 }
277 
278 #endif /* fhiclcpp_types_Tuple_h */
279 
280 // Local variables:
281 // mode: c++
282 // End:
value_type get_rtype_result(std::index_sequence< I... >) const
Definition: Tuple.h:191
void do_walk_elements(PW_non_const &pw) override
Definition: Tuple.h:132
#define NO_DELEGATED_PARAMETERS
std::tuple< tt::return_type< T >... > value_type
Definition: Tuple.h:61
void check_nargs_for_bounded_sequences(std::string const &key, std::size_t expected, std::size_t provided)
void do_walk_elements(PW_const &pw) const override
Definition: Tuple.h:145
#define NO_OPTIONAL_TYPES
void * Tuple
Definition: DBFolder.h:13
std::function< bool()> AlwaysUse()
SequenceBase(Name &&name, Comment &&comment, par_style const vt, par_type const type, std::function< bool()> maybeUse)
Definition: SequenceBase.h:19
void walk_over(tt::maybe_const_t< ParameterBase, C > &)
ValueHolder(std::tuple< Defaults... > const &tup)
Definition: Tuple.h:35
std::tuple< std::shared_ptr< tt::fhicl_type< T >>... > ftype
Definition: Tuple.h:62
auto operator()() const
Definition: Tuple.h:272
parameter set interface
std::tuple< Defaults... > const holder_
Definition: Tuple.h:45
std::string const & name() const
void iterate_over_tuple(PW_const &pw, std::index_sequence< I... >) const
Definition: Tuple.h:139
void fill_tuple_elements(default_type const &default_values, std::index_sequence< I... >)
Definition: Tuple.h:181
void finalize_elements(std::index_sequence< I... >)
Definition: Tuple.h:163
#define NO_NESTED_TABLE_FRAGMENTS
static Name sequence_element(std::size_t const i)
Definition: Name.h:16
ValueHolder(Defaults...defaults)
Definition: Tuple.h:31
void do_prepare_elements_for_validation(std::size_t const n) override
Definition: Tuple.h:126
void do_set_value(ParameterSet const &) override
Definition: Tuple.h:109
void finalize_element()
Definition: Tuple.h:154
void iterate_over_tuple(PW_non_const &pw, std::index_sequence< I... >)
Definition: Tuple.h:120
std::size_t get_size() const noexcept override
Definition: Tuple.h:103
Char_t n[5]
typename return_type_impl< ARGS... >::value_type return_type
Definition: type_traits.h:357
std::string const & comment() const
void fill_tuple_element(default_type const &defaults)
Definition: Tuple.h:172
ftype value_
Definition: Tuple.h:100
Tuple(Name &&name)
Definition: Tuple.h:201