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