Sequence.h
Go to the documentation of this file.
1 #ifndef fhiclcpp_types_Sequence_h
2 #define fhiclcpp_types_Sequence_h
3 
5 #include "fhiclcpp/type_traits.h"
6 #include "fhiclcpp/types/Atom.h"
14 
15 #include <array>
16 #include <initializer_list>
17 #include <memory>
18 #include <string>
19 #include <type_traits>
20 
21 namespace fhicl {
22 
23  namespace sequence_detail {
24 
25  // Auxiliary struct for accepting either
26  //
27  // (1) {1, 3, 5} or
28  // (2) std::array<int,3>{2, 4, 6}
29  //
30  // default values for Sequence<T,N>
31 
32  template <typename T>
33  class ValueHolder {
34  public:
35  ValueHolder(std::initializer_list<T> list) : holder_{list} {}
36 
37  template <std::size_t N>
38  ValueHolder(std::array<T, N> const& array)
39  : holder_(array.cbegin(), array.cend())
40  {}
41 
42  auto
43  begin() const noexcept
44  {
45  return holder_.cbegin();
46  }
47  auto
48  end() const noexcept
49  {
50  return holder_.cend();
51  }
52  auto
53  cbegin() const noexcept
54  {
55  return holder_.cbegin();
56  }
57  auto
58  cend() const noexcept
59  {
60  return holder_.cend();
61  }
62 
63  private:
64  std::vector<T> const holder_;
65  };
66  }
67 
68  class ParameterSet;
69 
70  //==================================================================
71  // e.g. Sequence<int,4> ====> std::array<int,4>
72  //
73  template <typename T, std::size_t N = -1ull>
74  class Sequence final : public detail::SequenceBase,
76  public:
77  static_assert(!tt::is_table_fragment_v<T>, NO_NESTED_TABLE_FRAGMENTS);
78  static_assert(!tt::is_optional_parameter_v<T>, NO_OPTIONAL_TYPES);
79  static_assert(!tt::is_delegated_parameter_v<T>, NO_DELEGATED_PARAMETERS);
80 
81  using default_type =
83  using ftype = std::array<std::shared_ptr<tt::fhicl_type<T>>, N>;
84  using value_type = std::array<tt::return_type<T>, N>;
85 
86  explicit Sequence(Name&& name);
87  explicit Sequence(Name&& name, Comment&& comment);
88  explicit Sequence(Name&& name,
89  Comment&& comment,
90  std::function<bool()> maybeUse);
91 
92  // c'tors that support defaults
93  explicit Sequence(Name&& name, default_type const& defaults);
94  explicit Sequence(Name&& name,
95  Comment&& comment,
96  default_type const& defaults);
97  explicit Sequence(Name&& name,
98  Comment&& comment,
99  std::function<bool()> maybeUse,
100  default_type const& defaults);
101 
102  auto
103  operator()() const
104  {
107  value_, result.begin(), [](auto const& elem) { return (*elem)(); });
108  return result;
109  }
110 
111  auto
112  operator()(std::size_t const i) const
113  {
114  return (*value_.at(i))();
115  }
116 
117  private:
119 
120  std::size_t
121  get_size() const noexcept override
122  {
123  return value_.size();
124  }
125 
126  void
127  do_prepare_elements_for_validation(std::size_t const n) override
128  {
130  }
131 
132  void
135  {
136  cet::for_all(value_, [&pw](auto& e) { pw.walk_over(*e); });
137  }
138 
139  void
141  pw) const override
142  {
143  cet::for_all(value_, [&pw](auto const& e) { pw.walk_over(*e); });
144  }
145 
146  void
147  do_set_value(fhicl::ParameterSet const&, bool /*trimParents*/) override
148  {}
149  };
150 
151  //==================================================================
152  // e.g. Sequence<int> ====> std::vector<int>
153  //
154  template <typename T>
155  class Sequence<T, -1ull> final : public detail::SequenceBase,
157  public:
158  static_assert(!tt::is_table_fragment_v<T>, NO_NESTED_TABLE_FRAGMENTS);
159  static_assert(!tt::is_optional_parameter_v<T>, NO_OPTIONAL_TYPES);
160  static_assert(!tt::is_delegated_parameter_v<T>, NO_DELEGATED_PARAMETERS);
161 
162  using default_type = std::vector<typename tt::fhicl_type<T>::default_type>;
163  using ftype = std::vector<std::shared_ptr<tt::fhicl_type<T>>>;
164  using value_type = std::vector<tt::return_type<T>>;
165 
166  explicit Sequence(Name&& name);
167  explicit Sequence(Name&& name, Comment&& comment);
168  explicit Sequence(Name&& name,
169  Comment&& comment,
170  std::function<bool()> maybeUse);
171 
172  // c'tors supporting default values
173  explicit Sequence(Name&& name, default_type const& defaults);
174  explicit Sequence(Name&& name,
175  Comment&& comment,
176  default_type const& defaults);
177  explicit Sequence(Name&& name,
178  Comment&& comment,
179  std::function<bool()> maybeUse,
180  default_type const& defaults);
181 
182  auto
183  operator()() const
184  {
186  cet::transform_all(value_, std::back_inserter(result), [](auto const& e) {
187  return (*e)();
188  });
189  return result;
190  }
191 
192  auto
193  operator()(std::size_t const i) const
194  {
195  return (*value_.at(i))();
196  }
197 
198  private:
200 
201  void
202  do_prepare_elements_for_validation(std::size_t const n) override
203  {
204  // For an unbounded sequence, we need to resize it so that any
205  // nested parameters of the elements can be checked.
206  if (n < value_.size()) {
207  value_.resize(n);
208  } else if (n > value_.size()) {
209  std::string key_fragment{key()};
210  // When emplacing a new element, do not include in the key
211  // argument the current name-stack stem--it will automatically
212  // be prepended.
213  auto const& nsr = NameStackRegistry::instance();
214  if (!nsr.empty()) {
215  std::string const& current_stem = nsr.current();
216  std::size_t const pos =
217  key_fragment.find(current_stem) != std::string::npos ?
218  current_stem.size() + 1ul : // + 1ul to account for the '.'
219  0ul;
220  key_fragment.replace(0ul, pos, "");
221  }
222 
223  for (auto i = value_.size(); i != n; ++i) {
224  value_.push_back(std::make_shared<tt::fhicl_type<T>>(Name::sequence_element(key_fragment, i)));
225  }
226  }
227  }
228 
229  std::size_t
230  get_size() const noexcept override
231  {
232  return value_.size();
233  }
234 
235  void
238  {
239  cet::for_all(value_, [&pw](auto& e) { pw.walk_over(*e); });
240  }
241 
242  void
244  pw) const override
245  {
246  cet::for_all(value_, [&pw](auto const& e) { pw.walk_over(*e); });
247  }
248 
249  void
250  do_set_value(fhicl::ParameterSet const&, bool /*trimParents*/) override
251  {}
252  };
253 }
254 
256 #include "cetlib_except/demangle.h"
258 #include "fhiclcpp/type_traits.h"
262 
263 #include <iostream>
264 #include <string>
265 
266 namespace fhicl {
267 
268  //==================================================================
269  // e.g. Sequence<int,4> ====> std::array<int,4>
270  //
271 
272  template <typename T, std::size_t N>
274  {}
275 
276  template <typename T, std::size_t N>
278  : SequenceBase{std::move(name),
279  std::move(comment),
283  , RegisterIfTableMember{this}
284  , value_{{nullptr}}
285  {
286  for (std::size_t i{}; i != N; ++i) {
287  value_.at(i) =
288  std::make_shared<tt::fhicl_type<T>>(Name::sequence_element(i));
289  }
291  }
292 
293  template <typename T, std::size_t N>
295  Comment&& comment,
296  std::function<bool()> maybeUse)
297  : SequenceBase{std::move(name),
298  std::move(comment),
301  maybeUse}
302  , RegisterIfTableMember{this}
303  , value_{{nullptr}}
304  {
305  for (std::size_t i{}; i != N; ++i) {
306  value_.at(i) =
307  std::make_shared<tt::fhicl_type<T>>(Name::sequence_element(i));
308  }
310  }
311 
312  // c'tors that support defaults
313  template <typename T, std::size_t N>
315  : Sequence{std::move(name), Comment{""}, defaults}
316  {}
317 
318  template <typename T, std::size_t N>
320  Comment&& comment,
321  default_type const& defaults)
322  : SequenceBase{std::move(name),
323  std::move(comment),
327  , RegisterIfTableMember{this}
328  , value_{{nullptr}}
329  {
330  std::size_t i{};
331  for (auto const& arg : defaults) {
332  value_.at(i) =
333  std::make_shared<tt::fhicl_type<T>>(Name::sequence_element(i), arg);
334  ++i;
335  }
337  }
338 
339  template <typename T, std::size_t N>
341  Comment&& comment,
342  std::function<bool()> maybeUse,
343  default_type const& defaults)
344  : SequenceBase{std::move(name),
345  std::move(comment),
348  maybeUse}
349  , RegisterIfTableMember{this}
350  , value_{{nullptr}}
351  {
352  std::size_t i{};
353  for (auto const& arg : defaults) {
354  value_.at(i) =
355  std::make_shared<tt::fhicl_type<T>>(Name::sequence_element(i), arg);
356  ++i;
357  }
359  }
360 
361  //==================================================================
362  // e.g. Sequence<int> ====> std::vector<int>
363  //
364  template <typename T>
366  : Sequence{std::move(name), Comment{""}}
367  {}
368 
369  template <typename T>
371  : SequenceBase{std::move(name),
372  std::move(comment),
376  , RegisterIfTableMember{this}
377  , value_{{std::make_shared<tt::fhicl_type<T>>(Name::sequence_element(0ul))}}
378  {
380  }
381 
382  template <typename T>
384  Comment&& comment,
385  std::function<bool()> maybeUse)
386  : SequenceBase{std::move(name),
387  std::move(comment),
390  maybeUse}
391  , RegisterIfTableMember{this}
392  , value_{{std::make_shared<tt::fhicl_type<T>>(Name::sequence_element(0ul))}}
393  {
395  }
396 
397  // c'tors that support defaults
398  template <typename T>
400  : Sequence{std::move(name), Comment{""}, defaults}
401  {}
402 
403  template <typename T>
405  Comment&& comment,
406  default_type const& defaults)
407  : SequenceBase{std::move(name),
408  std::move(comment),
412  , RegisterIfTableMember{this}
413  {
414  static_assert(!tt::is_table_v<T>, NO_DEFAULTS_FOR_TABLE);
415  std::size_t i{};
416  for (auto const& t : defaults) {
417  value_.push_back(std::make_shared<tt::fhicl_type<T>>(Name::sequence_element(i), t));
418  ++i;
419  }
421  }
422 
423  template <typename T>
425  Comment&& comment,
426  std::function<bool()> maybeUse,
427  default_type const& defaults)
428  : SequenceBase{std::move(name),
429  std::move(comment),
432  maybeUse}
433  , RegisterIfTableMember{this}
434  {
435  static_assert(!tt::is_table_v<T>, NO_DEFAULTS_FOR_TABLE);
436  std::size_t i{};
437  for (auto const& t : defaults) {
438  value_.emplace_back(std::make_shared<tt::fhicl_type<T>>(Name::sequence_element(i), t));
439  ++i;
440  }
442  }
443 }
444 
445 #endif /* fhiclcpp_types_Sequence_h */
446 
447 // Local variables:
448 // mode: c++
449 // End:
const XML_Char * name
Definition: expat.h:151
std::array< tt::return_type< string >,-1ull > value_type
Definition: Sequence.h:84
void do_set_value(fhicl::ParameterSet const &, bool) override
Definition: Sequence.h:250
std::vector< T > const holder_
Definition: Sequence.h:64
static NameStackRegistry & instance()
void do_walk_elements(detail::ParameterWalker< tt::const_flavor::require_const > &pw) const override
Definition: Sequence.h:243
void do_prepare_elements_for_validation(std::size_t const n) override
Definition: Sequence.h:127
#define NO_DELEGATED_PARAMETERS
void do_set_value(fhicl::ParameterSet const &, bool) override
Definition: Sequence.h:147
void check_nargs_for_bounded_sequences(std::string const &key, std::size_t expected, std::size_t provided)
auto operator()(std::size_t const i) const
Definition: Sequence.h:193
auto operator()(std::size_t const i) const
Definition: Sequence.h:112
auto operator()() const
Definition: Sequence.h:183
#define NO_OPTIONAL_TYPES
ValueHolder(std::array< T, N > const &array)
Definition: Sequence.h:38
std::function< bool()> AlwaysUse()
SequenceBase(Name &&name, Comment &&comment, par_style const vt, par_type const type, std::function< bool()> maybeUse)
Definition: SequenceBase.h:20
void do_walk_elements(detail::ParameterWalker< tt::const_flavor::require_non_const > &pw) override
Definition: Sequence.h:236
void do_prepare_elements_for_validation(std::size_t const n) override
Definition: Sequence.h:202
void walk_over(tt::maybe_const_t< ParameterBase, C > &)
auto operator()() const
Definition: Sequence.h:103
auto end() const noexcept
Definition: Sequence.h:48
typename fhicl_type_impl< T >::type fhicl_type
Definition: type_traits.h:293
auto begin() const noexcept
Definition: Sequence.h:43
std::vector< typename tt::fhicl_type< T >::default_type > default_type
Definition: Sequence.h:162
std::vector< std::shared_ptr< tt::fhicl_type< T >>> ftype
Definition: Sequence.h:163
std::void_t< T > n
void do_walk_elements(detail::ParameterWalker< tt::const_flavor::require_const > &pw) const override
Definition: Sequence.h:140
auto cend() const noexcept
Definition: Sequence.h:58
Sequence(Name &&name)
Definition: Sequence.h:273
void do_walk_elements(detail::ParameterWalker< tt::const_flavor::require_non_const > &pw) override
Definition: Sequence.h:133
auto transform_all(Container &, OutputIt, UnaryOp)
#define NO_NESTED_TABLE_FRAGMENTS
std::vector< tt::return_type< T >> value_type
Definition: Sequence.h:164
std::array< std::shared_ptr< tt::fhicl_type< string >>,-1ull > ftype
Definition: Sequence.h:83
static Name sequence_element(std::size_t const i)
Definition: Name.h:17
std::size_t get_size() const noexcept override
Definition: Sequence.h:230
ValueHolder(std::initializer_list< T > list)
Definition: Sequence.h:35
auto for_all(FwdCont &, Func)
std::string const & comment() const
Definition: ParameterBase.h:54
typename return_type_impl< ARGS... >::value_type return_type
Definition: type_traits.h:330
double T
Definition: Xdiff_gwt.C:5
auto cbegin() const noexcept
Definition: Sequence.h:53
#define NO_DEFAULTS_FOR_TABLE
Float_t e
Definition: plot.C:35
std::size_t get_size() const noexcept override
Definition: Sequence.h:121
enum BeamMode string