LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
TableAs.h
Go to the documentation of this file.
1 #ifndef fhiclcpp_types_TableAs_h
2 #define fhiclcpp_types_TableAs_h
3 
4 // ====================================================================
5 // The 'TableAs' class template allows the conversion of a
6 // fhicl::Table<Config> type to a user-defined type. For a given type:
7 //
8 // fhicl::TableAs<MyType, a::MyTypeConfig>
9 //
10 // where the 'a::MyTypeConfig' type is a template argument to
11 // 'fhicl::Table<a::MyTypeConfig>', a conversion to 'MyType'
12 // automatically occurs if the user provides a conversion function in
13 // the same namespace as 'MyTypeConfig'. Specifically:
14 //
15 // namespace a {
16 // struct MyTypeConfig {
17 // fhicl::Atom<int> myParam{fhicl::Name("myParam")};
18 // ...
19 // };
20 //
21 // MyType convert(MyTypeConfig const& config)
22 // {
23 // return MyType{config.myParam(), ...};
24 // }
25 // }
26 //
27 // Assuming these criteria are met, a 'MyType' object will be returned
28 // upon calling the operator() function of the fhicl::TableAs object.
29 // ====================================================================
30 
31 #include "fhiclcpp/type_traits.h"
37 
38 #include <memory>
39 #include <string>
40 #include <utility>
41 
42 namespace fhicl {
43 
44  //==================================================================
45  // e.g. TableAs<T, Config> ====> T as created by convert(Config)
46  //
47  template <typename T, typename Config>
48  class TableAs {
49  public:
50  using default_type = T;
52  using value_type = T;
53 
54  explicit TableAs(Name&& name);
55  explicit TableAs(Name&& name, Comment&& comment);
56  explicit TableAs(Name&& name,
57  Comment&& comment,
58  std::function<bool()> maybeUse);
59 
60  // c'tors supporting default values
61  explicit TableAs(Name&& name, T const& t);
62  explicit TableAs(Name&& name, Comment&& comment, T const& t);
63  explicit TableAs(Name&& name,
64  Comment&& comment,
65  std::function<bool()> maybeUse,
66  T const& t);
67 
68  T
69  operator()() const
70  {
71  via_type via;
72  return tableObj_(via) ? convert(via) :
74  *t_ :
75  throw fhicl::exception(
76  cant_find); // fix this exception category!
77  }
78 
79  // Allow implicit conversion from TableAs to ParameterBase to
80  // access metadata of underlying fhicl-cpp type.
81  operator detail::ParameterBase const&() const noexcept { return tableObj_; }
82 
83  //=================================================================
84  // expert only
85 
86  // The non-const conversion operator from is necessary for the
87  // ParameterWalker to iterate through a sequence of TableAs
88  // objects.
89  operator detail::ParameterBase&() noexcept { return tableObj_; }
90 
91  private:
93  std::shared_ptr<T>
94  t_{}; // shared instead of unique to allowed Sequence<TableAs<>> objects.
95 
96  Comment conversion_comment(Comment&& comment) const;
97  Comment conversion_comment(Comment&& comment, T const& t) const;
98  };
99 
100  //==================================================================
101  // IMPLEMENTATION
102 
103  template <typename T, typename Config>
105  : TableAs{std::move(name), Comment("")}
106  {}
107 
108  template <typename T, typename Config>
110  : tableObj_{std::move(name), conversion_comment(std::move(comment))}
111  {
113  }
114 
115  template <typename T, typename Config>
117  Comment&& comment,
118  std::function<bool()> maybeUse)
119  : tableObj_{std::move(name),
120  conversion_comment(std::move(comment)),
121  maybeUse}
122  {
124  }
125 
126  // c'tors supporting default values
127  template <typename T, typename Config>
128  TableAs<T, Config>::TableAs(Name&& name, T const& t)
129  : TableAs{std::move(name), Comment(""), t}
130  {}
131 
132  template <typename T, typename Config>
133  TableAs<T, Config>::TableAs(Name&& name, Comment&& comment, T const& t)
134  : tableObj_{std::move(name), conversion_comment(std::move(comment), t)}
135  , t_{std::make_shared<T>(t)}
136  {
138  }
139 
140  template <typename T, typename Config>
142  Comment&& comment,
143  std::function<bool()> maybeUse,
144  T const& t)
145  : tableObj_{std::move(name),
146  conversion_comment(std::move(comment), t),
147  maybeUse}
148  , t_{std::make_shared<T>(t)}
149  {
151  }
152 
153  //===============================================================================
154 
155  template <typename T, typename Config>
156  Comment
158  {
159  std::string const preface =
160  "N.B. The following table is converted to type:";
161  std::string const name =
162  " '" + cet::demangle_symbol(typeid(T).name()) + "'";
163  std::string const user_comment =
164  comment.value.empty() ? "" : "\n\n" + comment.value;
165 
166  std::ostringstream oss;
167  oss << preface << '\n' << name << user_comment;
168  return Comment{oss.str().c_str()};
169  }
170 
171  template <typename T, typename Config>
172  Comment
173  TableAs<T, Config>::conversion_comment(Comment&& comment, T const& t) const
174  {
175  std::string const preface{"N.B. The following table is converted to type:"};
176  std::string const name{" '" +
177  cet::demangle_symbol(typeid(T).name()) + "'"};
178 
179  std::string const user_comment{
180  comment.value.empty() ? "" : "\n\n" + comment.value};
181 
182  std::ostringstream oss;
183  oss << preface << '\n'
184  << name << '\n'
185  << detail::maybe_insert(t) << user_comment;
186  return Comment{oss.str().c_str()};
187  }
188 }
189 
190 #endif /* fhiclcpp_types_TableAs_h */
191 
192 // Local variables:
193 // mode: c++
194 // End:
std::string maybe_insert(T const &t)
Definition: maybe_insert.h:23
OptionalTable< Config > tableObj_
Definition: TableAs.h:92
Comment conversion_comment(Comment &&comment) const
Definition: TableAs.h:157
TableAs(Name &&name)
Definition: TableAs.h:104
typename OptionalTable< Config >::value_type via_type
Definition: TableAs.h:51
T operator()() const
Definition: TableAs.h:69
parameter set interface
std::shared_ptr< T > t_
Definition: TableAs.h:94
std::string value
Definition: Comment.h:37
void set_par_style(par_style const vt)
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33