LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
TupleAs.h
Go to the documentation of this file.
1 #ifndef fhiclcpp_types_TupleAs_h
2 #define fhiclcpp_types_TupleAs_h
3 
4 #include "fhiclcpp/type_traits.h"
7 #include "fhiclcpp/types/Tuple.h"
11 
12 #include <memory>
13 #include <string>
14 #include <utility>
15 
16 namespace fhicl {
17 
18  //==================================================================
19  // e.g. TupleAs<T,int,double,bool> ====> T(int,double,bool)
20  //
21  template <typename T, typename... ARGS>
22  class TupleAs;
23 
24  template <typename T, typename... ARGS>
25  class TupleAs<T(ARGS...)> {
26  public:
27  using default_type = T;
28  using via_type = typename OptionalTuple<ARGS...>::value_type;
29  using value_type = T;
30  using ftype = typename OptionalTuple<ARGS...>::ftype;
31 
32  explicit TupleAs(Name&& name);
33  explicit TupleAs(Name&& name, Comment&& comment);
34  explicit TupleAs(Name&& name,
35  Comment&& comment,
36  std::function<bool()> maybeUse);
37 
38  // c'tors supporting default values
39  explicit TupleAs(Name&& name, T const& t);
40  explicit TupleAs(Name&& name, Comment&& comment, T const& t);
41  explicit TupleAs(Name&& name,
42  Comment&& comment,
43  std::function<bool()> maybeUse,
44  T const& t);
45 
46  template <std::size_t... I>
47  T
48  fill(via_type const& via, std::index_sequence<I...>) const
49  {
50  return T{std::get<I>(via)...};
51  }
52 
53  T
54  operator()() const
55  {
56  via_type via;
57  return tupleObj_(via) ? fill(via, std::index_sequence_for<ARGS...>{}) :
58  tupleObj_.has_default() ?
59  *t_ :
60  throw fhicl::exception(
61  cant_find); // fix this exception category!
62  }
63 
64  //=================================================================
65  // expert only
66 
68  {
69  return tupleObj_;
70  } // Allows implicit conversion from
71  // TupleAs to ParameterBase (necessary
72  // for ParameterWalker)
73  private:
75  std::shared_ptr<T>
76  t_{}; // shared instead of unique to allowed Sequence<TupleAs<>> objects.
77 
78  Comment conversion_comment(Comment&& comment) const;
79  Comment conversion_comment(Comment&& comment, T const& t) const;
80  };
81 
82  //==================================================================
83  // IMPLEMENTATION
84 
85  template <typename T, typename... ARGS>
86  TupleAs<T(ARGS...)>::TupleAs(Name&& name)
87  : TupleAs{std::move(name), Comment("")}
88  {}
89 
90  template <typename T, typename... ARGS>
91  TupleAs<T(ARGS...)>::TupleAs(Name&& name, Comment&& comment)
92  : tupleObj_{std::move(name), conversion_comment(std::move(comment))}
93  {
94  tupleObj_.set_par_style(par_style::REQUIRED);
95  }
96 
97  template <typename T, typename... ARGS>
98  TupleAs<T(ARGS...)>::TupleAs(Name&& name,
99  Comment&& comment,
100  std::function<bool()> maybeUse)
101  : tupleObj_{std::move(name),
102  conversion_comment(std::move(comment)),
103  maybeUse}
104  {
105  tupleObj_.set_par_style(par_style::REQUIRED_CONDITIONAL);
106  }
107 
108  // c'tors supporting default values
109  template <typename T, typename... ARGS>
110  TupleAs<T(ARGS...)>::TupleAs(Name&& name, T const& t)
111  : TupleAs{std::move(name), Comment(""), t}
112  {}
113 
114  template <typename T, typename... ARGS>
115  TupleAs<T(ARGS...)>::TupleAs(Name&& name, Comment&& comment, T const& t)
116  : tupleObj_{std::move(name), conversion_comment(std::move(comment), t)}
117  , t_{std::make_shared<T>(t)}
118  {
119  tupleObj_.set_par_style(par_style::DEFAULT);
120  }
121 
122  template <typename T, typename... ARGS>
123  TupleAs<T(ARGS...)>::TupleAs(Name&& name,
124  Comment&& comment,
125  std::function<bool()> maybeUse,
126  T const& t)
127  : tupleObj_{std::move(name),
128  conversion_comment(std::move(comment), t),
129  maybeUse}
130  , t_{std::make_shared<T>(t)}
131  {
132  tupleObj_.set_par_style(par_style::DEFAULT_CONDITIONAL);
133  }
134 
135  template <typename T, typename... ARGS>
136  Comment
137  TupleAs<T(ARGS...)>::conversion_comment(Comment&& comment) const
138  {
139  std::string const preface =
140  "N.B. The following sequence is converted to type:";
141  std::string const name =
142  " '" + cet::demangle_symbol(typeid(T).name()) + "'";
143  std::string const user_comment =
144  comment.value.empty() ? "" : "\n\n" + comment.value;
145 
146  std::ostringstream oss;
147  oss << preface << '\n' << name << user_comment;
148  return Comment{oss.str().c_str()};
149  }
150 
151  //=================================================================
152  // metaprogramming necessary for determining if provided type 'T'
153  // has an 'std::ostream& operator<<(std::ostream&, T const&)' defined
154 
155  namespace has_insertion_operator_impl {
156  typedef char no;
157  typedef char yes[2];
158 
159  struct any_t {
160  template <typename T>
161  any_t(T const&);
162  };
163 
164  no operator<<(std::ostream const&, any_t const&);
165 
166  yes& test(std::ostream&);
167  no test(no);
168 
169  template <typename T>
171  static std::ostream& s;
172  static T const& t;
173  static bool const value = sizeof(test(s << t)) == sizeof(yes);
174  };
175  }
176 
177  template <typename T>
180  };
181 
182  struct NoInsert {
183  template <typename T>
184  std::string
185  operator()(T const&)
186  {
187  return " A default value is present, but it cannot be\n"
188  " printed out since no 'operator<<' overload has\n"
189  " been provided for the above type.";
190  }
191  };
192 
193  struct YesInsert {
194  template <typename T>
195  std::string
196  operator()(T const& t)
197  {
198  std::ostringstream os;
199  os << " with a default value of:\n"
200  << " " << t;
201  return os.str();
202  }
203  };
204 
205  //===============================================================================
206 
207  template <typename T, typename... ARGS>
208  Comment
209  TupleAs<T(ARGS...)>::conversion_comment(Comment&& comment, T const& t) const
210  {
211  std::string const preface{
212  "N.B. The following sequence is converted to type:"};
213  std::string const name{" '" +
214  cet::demangle_symbol(typeid(T).name()) + "'"};
215 
217  stringified_default;
218 
219  std::string const user_comment{
220  comment.value.empty() ? "" : "\n\n" + comment.value};
221 
222  std::ostringstream oss;
223  oss << preface << '\n'
224  << name << '\n'
225  << stringified_default(t) << user_comment;
226  return Comment{oss.str().c_str()};
227  }
228 }
229 
230 #endif /* fhiclcpp_types_TupleAs_h */
231 
232 // Local variables:
233 // mode: c++
234 // End:
T fill(via_type const &via, std::index_sequence< I... >) const
Definition: TupleAs.h:48
typename OptionalTuple< ARGS... >::ftype ftype
Definition: TupleAs.h:30
std::string operator()(T const &)
Definition: TupleAs.h:185
parameter set interface
typename OptionalTuple< ARGS... >::value_type via_type
Definition: TupleAs.h:28
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
std::string value(boost::any const &)
std::string operator()(T const &t)
Definition: TupleAs.h:196
std::ostream & operator<<(std::ostream &, ParameterSetID const &)
OptionalTuple< ARGS... > tupleObj_
Definition: TupleAs.h:74
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33