LArSoft  v09_90_00
Liquid Argon Software toolkit - https://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"
12 
13 #include <memory>
14 #include <string>
15 #include <tuple>
16 #include <utility>
17 
18 namespace fhicl {
19 
20  //==================================================================
21  // e.g. TupleAs<T,int,double,bool> ====> T(int,double,bool)
22  //
23  template <typename T, typename... ARGS>
24  class TupleAs;
25 
26  template <typename T, typename... ARGS>
27  class TupleAs<T(ARGS...)> {
28  public:
29  using default_type = T;
30  using via_type = typename OptionalTuple<ARGS...>::value_type;
31  using value_type = T;
32  using ftype = typename OptionalTuple<ARGS...>::ftype;
33 
34  explicit TupleAs(Name&& name);
35  explicit TupleAs(Name&& name, Comment&& comment);
36  explicit TupleAs(Name&& name,
37  Comment&& comment,
38  std::function<bool()> maybeUse);
39 
40  // c'tors supporting default values
41  explicit TupleAs(Name&& name, T const& t);
42  explicit TupleAs(Name&& name, Comment&& comment, T const& t);
43  explicit TupleAs(Name&& name,
44  Comment&& comment,
45  std::function<bool()> maybeUse,
46  T const& t);
47 
48  T
49  operator()() const
50  {
51  via_type via;
52  return tupleObj_(via) ? std::make_from_tuple<T>(via) :
53  tupleObj_.has_default() ?
54  *t_ :
55  throw fhicl::exception(
56  cant_find); // fix this exception category!
57  }
58 
59  //=================================================================
60  // expert only
61 
63  {
64  return tupleObj_;
65  } // Allows implicit conversion from
66  // TupleAs to ParameterBase (necessary
67  // for ParameterWalker)
68  private:
70  std::shared_ptr<T>
71  t_{}; // shared instead of unique to allowed Sequence<TupleAs<>> objects.
72 
73  Comment conversion_comment(Comment&& comment) const;
74  Comment conversion_comment(Comment&& comment, T const& t) const;
75  };
76 
77  //==================================================================
78  // IMPLEMENTATION
79 
80  template <typename T, typename... ARGS>
81  TupleAs<T(ARGS...)>::TupleAs(Name&& name)
82  : TupleAs{std::move(name), Comment("")}
83  {}
84 
85  template <typename T, typename... ARGS>
86  TupleAs<T(ARGS...)>::TupleAs(Name&& name, Comment&& comment)
87  : tupleObj_{std::move(name), conversion_comment(std::move(comment))}
88  {
89  tupleObj_.set_par_style(par_style::REQUIRED);
90  }
91 
92  template <typename T, typename... ARGS>
93  TupleAs<T(ARGS...)>::TupleAs(Name&& name,
94  Comment&& comment,
95  std::function<bool()> maybeUse)
96  : tupleObj_{std::move(name),
97  conversion_comment(std::move(comment)),
98  maybeUse}
99  {
100  tupleObj_.set_par_style(par_style::REQUIRED_CONDITIONAL);
101  }
102 
103  // c'tors supporting default values
104  template <typename T, typename... ARGS>
105  TupleAs<T(ARGS...)>::TupleAs(Name&& name, T const& t)
106  : TupleAs{std::move(name), Comment(""), t}
107  {}
108 
109  template <typename T, typename... ARGS>
110  TupleAs<T(ARGS...)>::TupleAs(Name&& name, Comment&& comment, T const& t)
111  : tupleObj_{std::move(name), conversion_comment(std::move(comment), t)}
112  , t_{std::make_shared<T>(t)}
113  {
114  tupleObj_.set_par_style(par_style::DEFAULT);
115  }
116 
117  template <typename T, typename... ARGS>
118  TupleAs<T(ARGS...)>::TupleAs(Name&& name,
119  Comment&& comment,
120  std::function<bool()> maybeUse,
121  T const& t)
122  : tupleObj_{std::move(name),
123  conversion_comment(std::move(comment), t),
124  maybeUse}
125  , t_{std::make_shared<T>(t)}
126  {
127  tupleObj_.set_par_style(par_style::DEFAULT_CONDITIONAL);
128  }
129 
130  //===============================================================================
131 
132  template <typename T, typename... ARGS>
133  Comment
134  TupleAs<T(ARGS...)>::conversion_comment(Comment&& comment) const
135  {
136  std::string const preface =
137  "N.B. The following sequence is converted to type:";
138  std::string const name =
139  " '" + cet::demangle_symbol(typeid(T).name()) + "'";
140  std::string const user_comment =
141  comment.value.empty() ? "" : "\n\n" + comment.value;
142 
143  std::ostringstream oss;
144  oss << preface << '\n' << name << user_comment;
145  return Comment{oss.str().c_str()};
146  }
147 
148  template <typename T, typename... ARGS>
149  Comment
150  TupleAs<T(ARGS...)>::conversion_comment(Comment&& comment, T const& t) const
151  {
152  std::string const preface{
153  "N.B. The following sequence is converted to type:"};
154  std::string const name{" '" +
155  cet::demangle_symbol(typeid(T).name()) + "'"};
156 
157  std::string const user_comment{
158  comment.value.empty() ? "" : "\n\n" + comment.value};
159 
160  std::ostringstream oss;
161  oss << preface << '\n'
162  << name << '\n'
163  << detail::maybe_insert(t) << user_comment;
164  return Comment{oss.str().c_str()};
165  }
166 }
167 
168 #endif /* fhiclcpp_types_TupleAs_h */
169 
170 // Local variables:
171 // mode: c++
172 // End:
std::string maybe_insert(T const &t)
Definition: maybe_insert.h:23
typename OptionalTuple< ARGS... >::ftype ftype
Definition: TupleAs.h:32
parameter set interface
typename OptionalTuple< ARGS... >::value_type via_type
Definition: TupleAs.h:30
OptionalTuple< ARGS... > tupleObj_
Definition: TupleAs.h:69
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33