LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
OptionalTuple.h
Go to the documentation of this file.
1 #ifndef fhiclcpp_types_OptionalTuple_h
2 #define fhiclcpp_types_OptionalTuple_h
3 
5 #include "fhiclcpp/type_traits.h"
6 #include "fhiclcpp/types/Atom.h"
14 
15 #include <optional>
16 #include <string>
17 #include <utility>
18 
19 namespace fhicl {
20 
21  class ParameterSet;
22 
23  //==================================================================
24  // e.g. OptionalTuple<int,double,bool> ====> std::tuple<int,double,bool>
25  //
26 
27  template <typename... T>
28  class OptionalTuple final : public detail::SequenceBase,
29  private detail::RegisterIfTableMember {
30  public:
31  using ftype = std::tuple<std::shared_ptr<tt::fhicl_type<T>>...>;
32  using value_type = std::tuple<tt::return_type<T>...>;
33 
34  static_assert(
35  !std::disjunction_v<tt::is_table_fragment<tt::return_type<T>>...>,
37  static_assert(
38  !std::disjunction_v<tt::is_optional_parameter<tt::return_type<T>>...>,
40  static_assert(
41  !std::disjunction_v<tt::is_delegated_parameter<tt::return_type<T>>...>,
43 
44  explicit OptionalTuple(Name&& name);
45  explicit OptionalTuple(Name&& name, Comment&& comment);
46  explicit OptionalTuple(Name&& name,
47  Comment&& comment,
48  std::function<bool()> maybeUse);
49 
50  auto operator()() const -> std::optional<value_type>;
51  auto operator()(value_type&) const -> bool;
52 
53  bool
54  hasValue() const
55  {
56  return has_value_;
57  }
58 
59  private:
61  bool has_value_{false};
62 
63  std::size_t
64  get_size() const noexcept override
65  {
66  return std::tuple_size<ftype>();
67  }
68 
69  //===================================================================
70  // iterate over tuple elements
71  using PW_non_const =
74 
75  template <std::size_t... I>
76  void
77  iterate_over_tuple(PW_non_const& pw, std::index_sequence<I...>)
78  {
79  (pw.walk_over(*std::get<I>(value_)), ...);
80  }
81 
82  void
83  do_prepare_elements_for_validation(std::size_t const n) override
84  {
86  }
87 
88  void
89  do_walk_elements(PW_non_const& pw) override
90  {
91  iterate_over_tuple(pw, std::index_sequence_for<T...>{});
92  }
93 
94  template <std::size_t... I>
95  void
96  iterate_over_tuple(PW_const& pw, std::index_sequence<I...>) const
97  {
98  (pw.walk_over(*std::get<I>(value_)), ...);
99  }
100 
101  void
102  do_walk_elements(PW_const& pw) const override
103  {
104  iterate_over_tuple(pw, std::index_sequence_for<T...>{});
105  }
106 
107  //===================================================================
108  // finalizing tuple elements
109  template <std::size_t I>
110  void
112  {
113  using elem_ftype = typename std::tuple_element_t<I, ftype>::element_type;
114  std::get<I>(value_) =
115  std::make_shared<elem_ftype>(Name::sequence_element(I));
116  }
117 
118  template <std::size_t... I>
119  void
120  finalize_elements(std::index_sequence<I...>)
121  {
122  (finalize_element<I>(), ...);
123  }
124 
125  //===================================================================
126  // filling return type
127  template <std::size_t... I>
128  value_type
129  get_rtype_result(std::index_sequence<I...>) const
130  {
131  return value_type{(*std::get<I>(value_))()...};
132  }
133 
134  void
136  {
137  // We do not explicitly set the sequence values here as the
138  // individual elements are set one at a time. However, this
139  // function is reached in the ValidateThenSet algorithm if the
140  // optional parameter is present. Otherwise, this override is
141  // skipped.
142  has_value_ = true;
143  }
144 
145  }; // class OptionalTuple
146 
147  //================= IMPLEMENTATION =========================
148  //
149  template <typename... T>
151  : OptionalTuple{std::move(name), Comment("")}
152  {}
153 
154  template <typename... T>
156  : SequenceBase{std::move(name),
157  std::move(comment),
161  , RegisterIfTableMember{this}
162  {
163  finalize_elements(std::index_sequence_for<T...>{});
165  }
166 
167  template <typename... T>
169  Comment&& comment,
170  std::function<bool()> maybeUse)
171  : SequenceBase{std::move(name),
172  std::move(comment),
175  maybeUse}
176  , RegisterIfTableMember{this}
177  {
178  finalize_elements(std::index_sequence_for<T...>{});
180  }
181 
182  template <typename... T>
183  auto
185  {
186  if (!has_value_)
187  return std::nullopt;
188  return std::make_optional(
189  get_rtype_result(std::index_sequence_for<T...>()));
190  }
191 
192  template <typename... T>
193  auto
195  {
196  auto result = operator()();
197  if (result) {
198  r = *result;
199  }
200  return result.has_value();
201  }
202 }
203 
204 #endif /* fhiclcpp_types_OptionalTuple_h */
205 
206 // Local variables:
207 // mode: c++
208 // End:
TRandom r
Definition: spectrum.C:23
void iterate_over_tuple(PW_non_const &pw, std::index_sequence< I... >)
Definition: OptionalTuple.h:77
OptionalTuple(Name &&name)
bool hasValue() const
Definition: OptionalTuple.h:54
void do_set_value(fhicl::ParameterSet const &) override
#define NO_DELEGATED_PARAMETERS
value_type get_rtype_result(std::index_sequence< I... >) const
void check_nargs_for_bounded_sequences(std::string const &key, std::size_t expected, std::size_t provided)
STL namespace.
#define NO_OPTIONAL_TYPES
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 do_walk_elements(PW_non_const &pw) override
Definition: OptionalTuple.h:89
void do_prepare_elements_for_validation(std::size_t const n) override
Definition: OptionalTuple.h:83
void walk_over(tt::maybe_const_t< ParameterBase, C > &)
parameter set interface
std::string const & name() const
std::string const & key() const
Definition: ParameterBase.cc:6
void finalize_elements(std::index_sequence< I... >)
std::tuple< std::shared_ptr< tt::fhicl_type< T >>... > ftype
Definition: OptionalTuple.h:31
#define NO_NESTED_TABLE_FRAGMENTS
std::size_t get_size() const noexcept override
Definition: OptionalTuple.h:64
std::tuple< tt::return_type< T >... > value_type
Definition: OptionalTuple.h:32
static Name sequence_element(std::size_t const i)
Definition: Name.h:16
void iterate_over_tuple(PW_const &pw, std::index_sequence< I... >) const
Definition: OptionalTuple.h:96
auto operator()() const -> std::optional< value_type >
Char_t n[5]
typename return_type_impl< ARGS... >::value_type return_type
Definition: type_traits.h:357
std::string const & comment() const
void do_walk_elements(PW_const &pw) const override