OptionalTable.h
Go to the documentation of this file.
1 #ifndef fhiclcpp_types_OptionalTable_h
2 #define fhiclcpp_types_OptionalTable_h
3 
5 #include "fhiclcpp/type_traits.h"
8 #include "fhiclcpp/types/Name.h"
15 
16 #include <memory>
17 #include <set>
18 #include <string>
19 
20 namespace fhicl {
21 
22  //========================================================
23  template <typename T>
24  class OptionalTable final : public detail::TableBase,
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_TABLE);
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 OptionalTable(Name&& name);
36  explicit OptionalTable(Name&& name, Comment&& comment);
37  explicit OptionalTable(Name&& name,
38  Comment&& comment,
39  std::function<bool()> maybeUse);
40  OptionalTable(ParameterSet const& pset,
41  std::set<std::string> const& keysToIgnore);
42 
43  // ... Accessors
44  std::optional<T>
45  operator()() const
46  {
47  return value_ ? std::make_optional(*value_) : std::nullopt;
48  }
49 
50  // Obsolete
51  bool
52  operator()(T& value) const
53  {
54  if (has_value_) {
55  value = *value_;
56  return true;
57  }
58  return false;
59  }
60 
61  bool
62  hasValue() const
63  {
64  return has_value_;
65  }
66 
67  ParameterSet const&
68  get_PSet() const
69  {
70  return pset_;
71  }
72 
74  std::ostream& os,
75  std::string const& tab = std::string(3, ' ')) const;
76 
77  //=====================================================
78  // Expert-only
79  using value_type = T;
80 
81  OptionalTable();
82 
83  void validate(ParameterSet const& pset,
84  std::set<std::string> const& keysToIgnore = {});
85 
86  private:
87  using members_t = std::vector<cet::exempt_ptr<ParameterBase>>;
88 
89  std::shared_ptr<T> value_{std::make_shared<T>()};
90  bool has_value_{false};
93 
94  members_t const&
95  get_members() const override
96  {
97  return members_;
98  }
99  void do_set_value(fhicl::ParameterSet const& pset) override;
100  };
101 
102  template <typename T>
103  inline std::ostream&
104  operator<<(std::ostream& os, OptionalTable<T> const& t)
105  {
106  std::ostringstream config;
107  t.print_allowed_configuration(config);
108  return os << config.str();
109  }
110 }
111 
118 
119 namespace fhicl {
120 
121  template <typename T>
124  {}
125 
126  template <typename T>
132  , RegisterIfTableMember{this}
133  {
135  }
136 
137  template <typename T>
139  Comment&& comment,
140  std::function<bool()> maybeUse)
144  maybeUse}
145  , RegisterIfTableMember{this}
146  {
148  }
149 
150  template <typename T>
152  std::set<std::string> const& keysToIgnore)
153  : TableBase{Name("<top_level>"),
154  Comment(""),
157  , RegisterIfTableMember{this}
158  {
160  validate(pset, keysToIgnore);
161  }
162 
163  template <typename T>
164  void
166  std::set<std::string> const& keysToIgnore)
167  {
168  pset_ = pset;
169  detail::ValidateThenSet vs{pset_, keysToIgnore};
170  cet::for_all(members(), [&vs](auto m) { vs(m.get()); });
171  vs.check_keys();
172  }
173 
174  template <typename T>
175  void
177  std::string const& tab) const
178  {
179  os << '\n' << tab << detail::optional_parameter_message() << '\n';
181  pc.walk_over(*this);
182  }
183 
184  template <typename T>
185  void
187  {
188  // Kind of tricky: we do not have the name of the current
189  // parameter set. A placeholder is often used
190  // (e.g. "<top_level>"). Fortunately, since the pset is passed
191  // in, we can just assign to it for a top-level ParameterSet.
192  // However, for nested parameter sets, we need to trim off the
193  // placeholder, and then the key we send
194  // pset.get<fhicl::ParameterSet>(key) is the key relative to the
195  // top-level pset.
196  std::string const& rkey = key();
198  if (nkey == rkey) {
199  pset_ = pset;
200  has_value_ = true;
201  } else {
203  }
204  }
205 }
206 
207 #endif /* fhiclcpp_types_OptionalTable_h */
208 
209 // Local variables:
210 // mode: c++
211 // End:
std::string const & name() const
Definition: ParameterBase.h:43
void validate(ParameterSet const &pset, std::set< std::string > const &keysToIgnore={})
void do_set_value(fhicl::ParameterSet const &pset) override
#define NO_DELEGATED_PARAMETERS
std::string string
Definition: nybbler.cc:12
std::shared_ptr< T > value_
Definition: OptionalTable.h:89
std::optional< T > operator()() const
Definition: OptionalTable.h:45
ChannelGroupService::Name Name
std::function< bool()> AlwaysUse()
#define NO_NESTED_FHICL_TYPES_IN_TABLE
std::string optional_parameter_message(bool const with_comment=true)
std::string strip_first_containing_name(std::string const &key)
members_t const & get_members() const override
Definition: OptionalTable.h:95
static Config * config
Definition: config.cpp:1054
std::vector< cet::exempt_ptr< ParameterBase > > const & members() const
Definition: TableBase.h:19
def move(depos, offset)
Definition: depos.py:107
#define NO_STD_CONTAINERS
std::vector< cet::exempt_ptr< ParameterBase >> members_t
Definition: OptionalTable.h:87
void print_allowed_configuration(std::ostream &os, std::string const &tab=std::string(3, ' ')) const
#define NO_NESTED_TABLE_FRAGMENTS
std::string const & key() const
Definition: ParameterBase.h:38
bool operator()(T &value) const
Definition: OptionalTable.h:52
#define Comment
ParameterSet pset_
Definition: OptionalTable.h:91
std::optional< T > get_if_present(std::string const &key) const
Definition: ParameterSet.h:224
auto for_all(FwdCont &, Func)
std::string const & comment() const
Definition: ParameterBase.h:48
bool hasValue() const
Definition: OptionalTable.h:62
TableBase(Name const &name, Comment const &comment, par_style const vt, std::function< bool()> maybeUse)
Definition: TableBase.h:11
ParameterSet const & get_PSet() const
Definition: OptionalTable.h:68
static std::vector< base_ptr > release_members()
void function(int client, int *resource, int parblock, int *test, int p)