LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
OptionalSequence.h
Go to the documentation of this file.
1 #ifndef fhiclcpp_types_OptionalSequence_h
2 #define fhiclcpp_types_OptionalSequence_h
3 
4 #include "fhiclcpp/type_traits.h"
5 #include "fhiclcpp/types/Atom.h"
14 
15 #include <array>
16 #include <string>
17 #include <type_traits>
18 
19 namespace fhicl {
20 
21  class ParameterSet;
22 
23  //==================================================================
24  // e.g. OptionalSequence<int,4> ====> std::array<int,4>
25  //
26  template <typename T, std::size_t N = -1ull>
27  class OptionalSequence final : public detail::SequenceBase,
28  private detail::RegisterIfTableMember {
29  public:
34 
35  using ftype = std::array<std::shared_ptr<tt::fhicl_type<T>>, N>;
36  using value_type = std::array<tt::return_type<T>, N>;
37 
38  explicit OptionalSequence(Name&& name);
39  explicit OptionalSequence(Name&& name, Comment&& comment);
40  explicit OptionalSequence(Name&& name,
41  Comment&& comment,
42  std::function<bool()> maybeUse);
43 
44  bool
46  {
47  if (!has_value_)
48  return false;
49 
50  value_type result = {{tt::return_type<T>()}};
51  cet::transform_all(
52  value_, result.begin(), [](auto const& elem) { return (*elem)(); });
53 
54  std::swap(result, t);
55  return true;
56  }
57 
58  bool
59  hasValue() const
60  {
61  return has_value_;
62  }
63 
64  private:
66  bool has_value_{false};
67 
68  std::size_t
69  get_size() const override
70  {
71  return value_.size();
72  }
73 
74  void
75  do_prepare_elements_for_validation(std::size_t const n) override
76  {
78  }
79 
80  void
83  {
84  cet::for_all(value_, [&pw](auto& e) { pw.walk_over(*e); });
85  }
86 
87  void
89  pw) const override
90  {
91  cet::for_all(value_, [&pw](auto const& e) { pw.walk_over(*e); });
92  }
93 
95  bool const trimParents) override;
96  };
97 
98  //==================================================================
99  // e.g. OptionalSequence<int> ====> std::vector<int>
100  //
101  template <typename T>
102  class OptionalSequence<T, -1ull> final
103  : public detail::SequenceBase,
105  public:
110 
111  using ftype = std::vector<std::shared_ptr<tt::fhicl_type<T>>>;
112  using value_type = std::vector<tt::return_type<T>>;
113 
114  explicit OptionalSequence(Name&& name);
115  explicit OptionalSequence(Name&& name, Comment&& comment);
116  explicit OptionalSequence(Name&& name,
117  Comment&& comment,
118  std::function<bool()> maybeUse);
119 
120  bool
122  {
123 
124  if (!has_value_)
125  return false;
126 
127  value_type result;
128  cet::transform_all(value_, std::back_inserter(result), [](auto const& e) {
129  return (*e)();
130  });
131 
132  std::swap(result, t);
133  return true;
134  }
135 
136  private:
138  bool has_value_{false};
139 
140  void
141  do_prepare_elements_for_validation(std::size_t const n) override
142  {
143  if (n < value_.size()) {
144  value_.resize(n);
145  } else if (n > value_.size()) {
146 
147  std::string key_fragment{key()};
148  // When emplacing a new element, do not include in the key
149  // argument the current name-stack stem--it will
150  // automatically be prepended.
151  auto const& nsr = NameStackRegistry::instance();
152  if (!nsr.empty()) {
153  std::string const& current_stem = nsr.current();
154  std::size_t const pos =
155  key_fragment.find(current_stem) != std::string::npos ?
156  current_stem.size() + 1ul : // + 1ul to account for the '.'
157  0ul;
158  key_fragment.replace(0ul, pos, "");
159  }
160 
161  for (auto i = value_.size(); i != n; ++i) {
162  value_.emplace_back(
163  new tt::fhicl_type<T>{Name::sequence_element(key_fragment, i)});
164  }
165  }
166  }
167 
168  std::size_t
169  get_size() const override
170  {
171  return value_.size();
172  }
173 
174  void
177  {
178  cet::for_all(value_, [&pw](auto& e) { pw.walk_over(*e); });
179  }
180 
181  void
183  pw) const override
184  {
185  cet::for_all(value_, [&pw](auto const& e) { pw.walk_over(*e); });
186  }
187 
188  void do_set_value(fhicl::ParameterSet const&,
189  bool const trimParents) override;
190  };
191 }
192 
194 
195 #endif /* fhiclcpp_types_OptionalSequence_h */
196 
197 // Local variables:
198 // mode: c++
199 // End:
void do_prepare_elements_for_validation(std::size_t const n) override
static NameStackRegistry & instance()
std::array< tt::return_type< Table< T >< art::RootInputFileSequence::Config::SecondaryFile > >,-1ull > value_type
#define NO_DELEGATED_PARAMETERS
void check_nargs_for_bounded_sequences(std::string const &key, std::size_t expected, std::size_t provided)
void do_walk_elements(detail::ParameterWalker< tt::const_flavor::require_non_const > &pw) override
#define NO_OPTIONAL_TYPES
std::array< std::shared_ptr< tt::fhicl_type< Table< T >< art::RootInputFileSequence::Config::SecondaryFile > >>,-1ull > ftype
void walk_over(tt::maybe_const_t< ParameterBase, C > &)
typename fhicl_type_impl< T >::type fhicl_type
Definition: type_traits.h:305
void do_set_value(fhicl::ParameterSet const &, bool const trimParents) override
parameter set interface
bool operator()(value_type &t) const
void do_prepare_elements_for_validation(std::size_t const n) override
void do_walk_elements(detail::ParameterWalker< tt::const_flavor::require_const > &pw) const override
#define NO_NESTED_TABLE_FRAGMENTS
void do_walk_elements(detail::ParameterWalker< tt::const_flavor::require_non_const > &pw) override
bool operator()(value_type &t) const
static Name sequence_element(std::size_t const i)
Definition: Name.h:17
std::size_t get_size() const override
void do_walk_elements(detail::ParameterWalker< tt::const_flavor::require_const > &pw) const override
std::string name() const
Definition: ParameterBase.h:49
Char_t n[5]
std::vector< tt::return_type< T >> value_type
typename return_type_impl< ARGS... >::value_type return_type
Definition: type_traits.h:342
std::vector< std::shared_ptr< tt::fhicl_type< T >>> ftype
Float_t e
Definition: plot.C:34
std::string key() const
Definition: ParameterBase.h:44
std::string comment() const
Definition: ParameterBase.h:54
std::size_t get_size() const override
OptionalSequence(Name &&name)