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 <string>
16 #include <utility>
17 
18 namespace fhicl {
19 
20  class ParameterSet;
21 
22  //==================================================================
23  // e.g. OptionalTuple<int,double,bool> ====> std::tuple<int,double,bool>
24  //
25 
26  template <typename... T>
27  class OptionalTuple final : public detail::SequenceBase,
28  private detail::RegisterIfTableMember {
29  public:
30  using ftype = std::tuple<std::shared_ptr<tt::fhicl_type<T>>...>;
31  using value_type = std::tuple<tt::return_type<T>...>;
32 
33  static_assert(
34  !std::disjunction_v<tt::is_table_fragment<tt::return_type<T>>...>,
36  static_assert(
37  !std::disjunction_v<tt::is_optional_parameter<tt::return_type<T>>...>,
39  static_assert(
40  !std::disjunction_v<tt::is_delegated_parameter<tt::return_type<T>>...>,
42 
43  explicit OptionalTuple(Name&& name);
44  explicit OptionalTuple(Name&& name, Comment&& comment);
45  explicit OptionalTuple(Name&& name,
46  Comment&& comment,
47  std::function<bool()> maybeUse);
48 
49  bool operator()(value_type&) const;
50 
51  bool
52  hasValue() const
53  {
54  return has_value_;
55  }
56 
57  private:
59  bool has_value_{false};
60 
61  std::size_t
62  get_size() const noexcept override
63  {
64  return std::tuple_size<ftype>();
65  }
66 
67  //===================================================================
68  // iterate over tuple elements
69  using PW_non_const =
72 
73  template <std::size_t... I>
74  void
75  iterate_over_tuple(PW_non_const& pw, std::index_sequence<I...>)
76  {
77  (pw.walk_over(*std::get<I>(value_)), ...);
78  }
79 
80  void
81  do_prepare_elements_for_validation(std::size_t const n) override
82  {
84  }
85 
86  void
87  do_walk_elements(PW_non_const& pw) override
88  {
89  iterate_over_tuple(pw, std::index_sequence_for<T...>{});
90  }
91 
92  template <std::size_t... I>
93  void
94  iterate_over_tuple(PW_const& pw, std::index_sequence<I...>) const
95  {
96  (pw.walk_over(*std::get<I>(value_)), ...);
97  }
98 
99  void
100  do_walk_elements(PW_const& pw) const override
101  {
102  iterate_over_tuple(pw, std::index_sequence_for<T...>{});
103  }
104 
105  //===================================================================
106  // finalizing tuple elements
107  template <std::size_t I>
108  void
110  {
111  using elem_ftype = typename std::tuple_element_t<I, ftype>::element_type;
112  std::get<I>(value_) =
113  std::make_shared<elem_ftype>(Name::sequence_element(I));
114  }
115 
116  template <std::size_t... I>
117  void
118  finalize_elements(std::index_sequence<I...>)
119  {
120  (finalize_element<I>(), ...);
121  }
122 
123  //===================================================================
124  // filling return type
125  template <std::size_t... I>
126  value_type
127  get_rtype_result(std::index_sequence<I...>) const
128  {
129  return value_type{(*std::get<I>(value_))()...};
130  }
131 
132  void
134  bool const /*trimParents*/) override
135  {
136  // We do not explicitly set the sequence values here as the
137  // individual elements are set one at a time. However, this
138  // function is reached in the ValidateThenSet algorithm if the
139  // optional parameter is present. Otherwise, this override is
140  // skipped.
141  has_value_ = true;
142  }
143 
144  }; // class OptionalTuple
145 
146  //================= IMPLEMENTATION =========================
147  //
148  template <typename... T>
150  : OptionalTuple{std::move(name), Comment("")}
151  {}
152 
153  template <typename... T>
155  : SequenceBase{std::move(name),
156  std::move(comment),
160  , RegisterIfTableMember{this}
161  {
162  finalize_elements(std::index_sequence_for<T...>{});
164  }
165 
166  template <typename... T>
168  Comment&& comment,
169  std::function<bool()> maybeUse)
170  : SequenceBase{std::move(name),
171  std::move(comment),
174  maybeUse}
175  , RegisterIfTableMember{this}
176  {
177  finalize_elements(std::index_sequence_for<T...>{});
179  }
180 
181  template <typename... T>
182  bool
184  {
185  if (!has_value_)
186  return false;
187  auto result = get_rtype_result(std::index_sequence_for<T...>());
188  std::swap(result, r);
189  return true;
190  }
191 }
192 
193 #endif /* fhiclcpp_types_OptionalTuple_h */
194 
195 // Local variables:
196 // mode: c++
197 // End:
const XML_Char * name
Definition: expat.h:151
void iterate_over_tuple(PW_non_const &pw, std::index_sequence< I... >)
Definition: OptionalTuple.h:75
OptionalTuple(Name &&name)
bool hasValue() const
Definition: OptionalTuple.h:52
#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)
#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:20
void do_walk_elements(PW_non_const &pw) override
Definition: OptionalTuple.h:87
void do_prepare_elements_for_validation(std::size_t const n) override
Definition: OptionalTuple.h:81
void walk_over(tt::maybe_const_t< ParameterBase, C > &)
std::void_t< T > n
void finalize_elements(std::index_sequence< I... >)
std::tuple< std::shared_ptr< tt::fhicl_type< T >>... > ftype
Definition: OptionalTuple.h:30
#define NO_NESTED_TABLE_FRAGMENTS
std::size_t get_size() const noexcept override
Definition: OptionalTuple.h:62
std::tuple< tt::return_type< T >... > value_type
Definition: OptionalTuple.h:31
std::string const & key() const
Definition: ParameterBase.h:44
static Name sequence_element(std::size_t const i)
Definition: Name.h:17
void iterate_over_tuple(PW_const &pw, std::index_sequence< I... >) const
Definition: OptionalTuple.h:94
bool operator()(value_type &) const
void do_set_value(fhicl::ParameterSet const &, bool const ) override
std::string const & comment() const
Definition: ParameterBase.h:54
TRandom3 r(0)
typename return_type_impl< ARGS... >::value_type return_type
Definition: type_traits.h:330
double T
Definition: Xdiff_gwt.C:5
void do_walk_elements(PW_const &pw) const override