Table.h
Go to the documentation of this file.
1 #ifndef fhiclcpp_types_Table_h
2 #define fhiclcpp_types_Table_h
3 
5 #include "fhiclcpp/type_traits.h"
9 #include "fhiclcpp/types/Name.h"
16 
17 #include <memory>
18 #include <ostream>
19 #include <set>
20 #include <string>
21 
22 namespace fhicl {
23 
24  //========================================================
25  template <typename T, typename KeysToIgnore = void>
26  class Table final : public detail::TableBase,
27  private detail::RegisterIfTableMember {
28  public:
29  static_assert(!tt::is_sequence_type_v<T>, NO_STD_CONTAINERS);
30  static_assert(!tt::is_fhicl_type_v<T>, NO_NESTED_FHICL_TYPES_IN_TABLE);
31  static_assert(!tt::is_table_fragment_v<T>, NO_NESTED_TABLE_FRAGMENTS);
32  static_assert(!tt::is_delegated_parameter_v<T>, NO_DELEGATED_PARAMETERS);
33 
34  //=====================================================
35  // User-friendly
36  // ... c'tors
37  template <typename... TCARGS>
38  explicit Table(Name&& name, TCARGS&&... tcargs);
39  template <typename... TCARGS>
40  explicit Table(Name&& name, Comment&& comment, TCARGS&&... tcargs);
41  template <typename... TCARGS>
42  explicit Table(Name&& name,
43  Comment&& comment,
44  MaybeUseFunction maybeUse,
45  TCARGS&&... tcargs);
46 
47  // Choose this c'tor if user specifies the second 'KeysToIgnore' template
48  // argument.
49  template <typename K = KeysToIgnore,
51  Table(ParameterSet const& pset);
52 
53  // If user does not specify the second 'KeysToIgnore' template argument,
54  // then choose this c'tor.
55  template <typename K = KeysToIgnore,
57  Table(ParameterSet const& pset,
58  std::set<std::string> const& keysToIgnore = {});
59 
60  // ... Accessors
61  auto const&
62  operator()() const
63  {
64  return *value_;
65  }
66 
67  ParameterSet const&
68  get_PSet() const
69  {
70  return pset_;
71  }
72 
73  void validate(ParameterSet const& pset,
74  std::set<std::string> const& keysToIgnore = {});
75 
77  std::ostream& os,
78  std::string const& tab = std::string(3, ' ')) const;
79 
80  //=====================================================
81  // Expert-only
82  using default_type = T;
83  using value_type = T;
84 
85  private:
86  using members_t = std::vector<cet::exempt_ptr<ParameterBase>>;
87 
88  std::shared_ptr<T> value_{std::make_shared<T>()};
91 
92  struct Impl {};
93  Table(ParameterSet const&, std::set<std::string> const&, Impl);
95 
96  members_t const&
97  get_members() const override
98  {
99  return members_;
100  }
101  void do_set_value(fhicl::ParameterSet const& pset) override;
102  };
103 
104  template <typename T>
105  inline std::ostream&
106  operator<<(std::ostream& os, Table<T> const& t)
107  {
108  std::ostringstream config;
109  t.print_allowed_configuration(config);
110  return os << config.str();
111  }
112 }
113 
114 // Implementation
115 
123 
124 namespace fhicl {
125 
126  template <typename T, typename KeysToIgnore>
127  template <typename... TCARGS>
128  Table<T, KeysToIgnore>::Table(Name&& name, TCARGS&&... tcargs)
129  : Table{std::move(name), Comment(""), std::forward<TCARGS>(tcargs)...}
130  {}
131 
132  template <typename T, typename KeysToIgnore>
133  template <typename... TCARGS>
135  Comment&& comment,
136  TCARGS&&... tcargs)
141  , RegisterIfTableMember{this}
142  , value_{std::make_shared<T>(std::forward<TCARGS>(tcargs)...)}
143  {
146  }
147 
148  template <typename T, typename KeysToIgnore>
149  template <typename... TCARGS>
151  Comment&& comment,
152  MaybeUseFunction maybeUse,
153  TCARGS&&... tcargs)
157  maybeUse}
158  , RegisterIfTableMember{this}
159  , value_{std::make_shared<T>(std::forward<TCARGS>(tcargs)...)}
160  {
163  }
164 
165  template <typename T, typename KeysToIgnore>
166  template <typename, typename>
168  : Table{pset, KeysToIgnore{}(), Impl{}}
169  {}
170 
171  template <typename T, typename KeysToIgnore>
172  template <typename, typename>
174  std::set<std::string> const& keysToIgnore)
175  : Table{pset, keysToIgnore, Impl{}}
176  {}
177 
178  template <typename T, typename KeysToIgnore>
180  std::set<std::string> const& keysToIgnore,
181  Impl)
182  : TableBase{Name("<top_level>"),
183  Comment(""),
186  , RegisterIfTableMember{this}
187  {
190  validate(pset, keysToIgnore);
191  }
192 
193  template <typename T, typename KeysToIgnore>
194  void
196  std::set<std::string> const& keysToIgnore)
197  {
198  pset_ = pset;
199  detail::ValidateThenSet vs{pset_, keysToIgnore};
200  cet::for_all(members(), [&vs](auto m) { vs.walk_over(*m); });
201 
202  try {
203  vs.check_keys();
204  }
205  catch (fhicl::detail::validationException const&) {
207  throw;
208  }
209  }
210 
211  template <typename T, typename KeysToIgnore>
212  void
214  std::ostream& os,
215  std::string const& tab) const
216  {
217  os << '\n' << tab << detail::optional_parameter_message() << '\n';
218  detail::PrintAllowedConfiguration pc{os, false, tab};
219  pc.walk_over(*this);
220  }
221 
222  template <typename T, typename KeysToIgnore>
223  void
225  {
226  // Kind of tricky: we do not have the name of the current
227  // parameter set. A placeholder is often used (e.g. "<top_level>").
228  // Fortunately, since the pset is passed in, we can just assign to
229  // it for a top-level ParameterSet. However, for nested parameter
230  // sets, we need to trim off the placeholder, and then the key we
231  // send pset.get<fhicl::ParameterSet>(key) is the key relative to
232  // the top-level pset.
233  std::string const& rkey = key();
235  pset_ = (nkey == rkey) ? pset : pset.get<fhicl::ParameterSet>(nkey);
236  }
237 
238  template <typename T, typename KeysToIgnore>
239  void
241  {
242  bool const implicitly_default =
243  std::all_of(members_.begin(), members_.end(), [](auto p) {
244  return p->has_default() || p->is_optional();
245  });
246  if (implicitly_default)
248  }
249 }
250 
251 #endif /* fhiclcpp_types_Table_h */
252 
253 // Local variables:
254 // mode: c++
255 // End:
void print_allowed_configuration(std::ostream &os, std::string const &tab=std::string(3, ' ')) const
Definition: Table.h:213
std::string const & name() const
Definition: ParameterBase.h:43
trkf::TrackStatePropagator::trkmkr::KalmanFilterFitTrackMaker::Config default_type
Definition: Table.h:82
#define NO_DELEGATED_PARAMETERS
std::string string
Definition: nybbler.cc:12
trkf::TrackStatePropagator::trkmkr::KalmanFilterFitTrackMaker::Config value_type
Definition: Table.h:83
ParameterSet const & get_PSet() const
Definition: Table.h:68
ChannelGroupService::Name Name
ParameterSet pset_
Definition: Table.h:89
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)
Table(Name &&name, TCARGS &&...tcargs)
Definition: Table.h:128
static Config * config
Definition: config.cpp:1054
members_t members_
Definition: Table.h:90
std::vector< cet::exempt_ptr< ParameterBase > > const & members() const
Definition: TableBase.h:19
def move(depos, offset)
Definition: depos.py:107
T get(std::string const &key) const
Definition: ParameterSet.h:271
#define NO_STD_CONTAINERS
p
Definition: test.py:223
void validate(ParameterSet const &pset, std::set< std::string > const &keysToIgnore={})
Definition: Table.h:195
#define NO_NESTED_TABLE_FRAGMENTS
std::string const & key() const
Definition: ParameterBase.h:38
auto const & operator()() const
Definition: Table.h:62
#define Comment
members_t const & get_members() const override
Definition: Table.h:97
void do_set_value(fhicl::ParameterSet const &pset) override
Definition: Table.h:224
auto for_all(FwdCont &, Func)
std::shared_ptr< T > value_
Definition: Table.h:88
void maybe_implicitly_default()
Definition: Table.h:240
std::string const & comment() const
Definition: ParameterBase.h:48
TableBase(Name const &name, Comment const &comment, par_style const vt, std::function< bool()> maybeUse)
Definition: TableBase.h:11
static std::vector< base_ptr > release_members()
void set_par_style(par_style const vt)