LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
OptionalAtom.h
Go to the documentation of this file.
1 #ifndef fhiclcpp_types_OptionalAtom_h
2 #define fhiclcpp_types_OptionalAtom_h
3 
5 #include "fhiclcpp/type_traits.h"
8 #include "fhiclcpp/types/Name.h"
15 
16 #include <optional>
17 #include <sstream>
18 #include <string>
19 
20 namespace fhicl {
21 
22  //========================================================
23  template <typename T>
24  class OptionalAtom final : public detail::AtomBase,
25  private detail::RegisterIfTableMember {
26  public:
27  static_assert(!tt::is_sequence_type_v<T>, NO_STD_CONTAINERS);
28  static_assert(!tt::is_fhicl_type_v<T>, NO_NESTED_FHICL_TYPES_IN_ATOM);
29  static_assert(!tt::is_table_fragment_v<T>, NO_NESTED_TABLE_FRAGMENTS);
30  static_assert(!tt::is_delegated_parameter_v<T>, NO_DELEGATED_PARAMETERS);
31 
32  //=====================================================
33  // User-friendly
34  // ... c'tors
35  explicit OptionalAtom(Name&& name);
36  explicit OptionalAtom(Name&& name, Comment&& comment);
37  explicit OptionalAtom(Name&& name,
38  Comment&& comment,
39  std::function<bool()> maybeUse);
40 
41  // ... Accessors
42  std::optional<T>
43  operator()() const
44  {
45  return value_;
46  }
47 
48  // Obsolete
49  bool
50  operator()(T& value) const
51  {
52  if (hasValue()) {
53  value = *value_;
54  return true;
55  }
56  return false;
57  }
58 
59  bool
60  hasValue() const
61  {
62  return value_.has_value();
63  }
64 
65  // Expert-only
66  using value_type = T;
67 
68  OptionalAtom();
69 
70  private:
71  std::optional<T> value_{};
72 
73  std::string get_stringified_value() const override;
74  void do_set_value(fhicl::ParameterSet const&) override;
75  };
76 }
77 
80 
81 namespace fhicl {
82 
83  template <typename T>
85  : OptionalAtom{std::move(name), Comment("")}
86  {}
87 
88  template <typename T>
90  : AtomBase{std::move(name),
91  std::move(comment),
94  , RegisterIfTableMember{this}
95  {
97  }
98 
99  template <typename T>
101  Comment&& comment,
102  std::function<bool()> maybeUse)
103  : AtomBase{std::move(name),
104  std::move(comment),
106  maybeUse}
107  , RegisterIfTableMember{this}
108  {
110  }
111 
112  template <typename T>
113  std::string
115  {
116  std::stringstream oss;
117  if (value_) {
118  using namespace detail::yes_defaults;
119  oss << maybe_quotes<T>(*value_);
120  } else {
121  using namespace detail::no_defaults;
122  oss << expected_types<T>();
123  }
124  return oss.str();
125  }
126 
127  template <typename T>
128  void
130  {
131  auto const trimmed_key = detail::strip_first_containing_name(key());
132  if (auto value = pset.get_if_present<T>(trimmed_key)) {
133  value_ = *value;
134  }
135  }
136 }
137 
138 #endif /* fhiclcpp_types_OptionalAtom_h */
139 
140 // Local variables:
141 // mode: c++
142 // End:
AtomBase(Name const &name, Comment const &comment, par_style const vt, std::function< bool()> maybeUse)
Definition: AtomBase.h:10
#define NO_DELEGATED_PARAMETERS
std::function< bool()> AlwaysUse()
std::string get_stringified_value() const override
Definition: OptionalAtom.h:114
std::string strip_first_containing_name(std::string const &key)
parameter set interface
#define NO_STD_CONTAINERS
std::string const & name() const
bool operator()(T &value) const
Definition: OptionalAtom.h:50
std::string const & key() const
Definition: ParameterBase.cc:6
#define NO_NESTED_TABLE_FRAGMENTS
std::optional< T > operator()() const
Definition: OptionalAtom.h:43
double value
Definition: spectrum.C:18
std::optional< T > get_if_present(std::string const &key) const
Definition: ParameterSet.h:267
bool hasValue() const
Definition: OptionalAtom.h:60
std::optional< T > value_
Definition: OptionalAtom.h:71
std::string const & comment() const
void do_set_value(fhicl::ParameterSet const &) override
Definition: OptionalAtom.h:129
#define NO_NESTED_FHICL_TYPES_IN_ATOM