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 // the 'MyType' object will be returned.
30 // ====================================================================
31 
32 #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  //=================================================================
80  // expert only
81 
83  {
84  return tableObj_;
85  } // Allows implicit conversion from
86  // TableAs to ParameterBase (necessary
87  // for ParameterWalker)
88  private:
90  std::shared_ptr<T>
91  t_{}; // shared instead of unique to allowed Sequence<TableAs<>> objects.
92 
94  Comment conversion_comment(Comment&& comment, T const& t) const;
95  };
96 
97  //==================================================================
98  // IMPLEMENTATION
99 
100  template <typename T, typename Config>
102  : TableAs{std::move(name), Comment("")}
103  {}
104 
105  template <typename T, typename Config>
108  {
110  }
111 
112  template <typename T, typename Config>
114  Comment&& comment,
115  std::function<bool()> maybeUse)
118  maybeUse}
119  {
121  }
122 
123  // c'tors supporting default values
124  template <typename T, typename Config>
126  : TableAs{std::move(name), Comment(""), t}
127  {}
128 
129  template <typename T, typename Config>
132  , t_{std::make_shared<T>(t)}
133  {
135  }
136 
137  template <typename T, typename Config>
139  Comment&& comment,
140  std::function<bool()> maybeUse,
141  T const& t)
144  maybeUse}
145  , t_{std::make_shared<T>(t)}
146  {
148  }
149 
150  template <typename T, typename Config>
151  Comment
153  {
154  std::string const preface =
155  "N.B. The following table is converted to type:";
156  std::string const name =
157  " '" + cet::demangle_symbol(typeid(T).name()) + "'";
158  std::string const user_comment =
159  comment.value.empty() ? "" : "\n\n" + comment.value;
160 
161  std::ostringstream oss;
162  oss << preface << '\n' << name << user_comment;
163  return Comment{oss.str().c_str()};
164  }
165 
166  //=================================================================
167  // metaprogramming necessary for determining if provided type 'T'
168  // has an 'std::ostream& operator<<(std::ostream&, T const&)' defined
169 
170  namespace has_insertion_operator_impl {
171  typedef char no;
172  typedef char yes[2];
173 
174  struct any_t {
175  template <typename T>
176  any_t(T const&);
177  };
178 
179  no operator<<(std::ostream const&, any_t const&);
180 
181  yes& test(std::ostream&);
182  no test(no);
183 
184  template <typename T>
186  static std::ostream& s;
187  static T const& t;
188  static bool const value = sizeof(test(s << t)) == sizeof(yes);
189  };
190  }
191 
192  template <typename T>
195 
196  struct NoInsert {
197  template <typename T>
199  operator()(T const&)
200  {
201  return " A default value is present, but it cannot be\n"
202  " printed out since no 'operator<<' overload has\n"
203  " been provided for the above type.";
204  }
205  };
206 
207  struct YesInsert {
208  template <typename T>
210  operator()(T const& t)
211  {
212  std::ostringstream os;
213  os << " with a default value of:\n"
214  << " " << t;
215  return os.str();
216  }
217  };
218 
219  //===============================================================================
220 
221  template <typename T, typename Config>
222  Comment
224  {
225  std::string const preface{"N.B. The following table is converted to type:"};
226  std::string const name{" '" +
227  cet::demangle_symbol(typeid(T).name()) + "'"};
228 
230  stringified_default;
231 
232  std::string const user_comment{
233  comment.value.empty() ? "" : "\n\n" + comment.value};
234 
235  std::ostringstream oss;
236  oss << preface << '\n'
237  << name << '\n'
238  << stringified_default(t) << user_comment;
239  return Comment{oss.str().c_str()};
240  }
241 }
242 
243 #endif /* fhiclcpp_types_TableAs_h */
244 
245 // Local variables:
246 // mode: c++
247 // End:
static QCString name
Definition: declinfo.cpp:673
OptionalTable< Config > tableObj_
Definition: TableAs.h:89
Comment conversion_comment(Comment &&comment) const
Definition: TableAs.h:152
TableAs(Name &&name)
Definition: TableAs.h:101
std::string operator()(T const &)
Definition: TableAs.h:199
std::string string
Definition: nybbler.cc:12
typename OptionalTable< Config >::value_type via_type
Definition: TableAs.h:51
int comment
T operator()() const
Definition: TableAs.h:69
def move(depos, offset)
Definition: depos.py:107
def convert(inputfile, outputfile="wire-cell-garfield-fine-response.json.bz2", average=False, shaped=False)
Definition: garfield.py:262
#define Comment
std::string operator()(T const &t)
Definition: TableAs.h:210
std::ostream & operator<<(std::ostream &, ParameterSetID const &)
void function(int client, int *resource, int parblock, int *test, int p)
std::shared_ptr< T > t_
Definition: TableAs.h:91
void set_par_style(par_style const vt)
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33