Molassembler  3.0.0
Molecule graph and conformer library
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Invoke.h
Go to the documentation of this file.
1 
11 #ifndef INCLUDE_MOLASSEMBLER_TEMPLE_INVOKE_H
12 #define INCLUDE_MOLASSEMBLER_TEMPLE_INVOKE_H
13 
14 #include <boost/tuple/tuple.hpp>
15 
16 #include <tuple>
17 #include <functional>
18 
19 namespace Scine {
20 namespace Molassembler {
21 
23 namespace Temple {
24 namespace Detail {
25 
26 template<typename TupleType, typename Function, size_t ... Inds>
27 auto boostTupleInvokeHelper(
28  Function&& function,
29  const TupleType& tuple,
30  std::index_sequence<Inds...> /* indices */
31 ) {
32  return function(
33  boost::get<Inds>(tuple)...
34  );
35 }
36 
37 } // namespace Detail
38 
40 template<
41  typename HT,
42  typename TT,
43  typename Function
44 > auto invoke(
45  Function&& function,
46  const boost::tuples::cons<HT, TT>& tuple
47 ) {
48  return Detail::boostTupleInvokeHelper(
49  function,
50  tuple,
51  std::make_index_sequence<
52  //std::tuple_size<TupleType>::value
53  boost::tuples::length<
54  boost::tuples::cons<HT, TT>
55  >::value
56  >()
57  );
58 }
59 
60 namespace Detail {
61 
62 template<class> struct sfinae_true : std::true_type {};
63 
68 template<typename Function, typename TupleType, size_t ... Inds>
69 auto invokeHelper(
70  Function&& function,
71  const TupleType& tuple,
72  std::index_sequence<Inds...> /* indices */
73 ) {
74  return std::invoke(function, std::get<Inds>(tuple)...);
75 }
76 
81 struct InvokeTester {
82  template<typename Function, typename TupleType, std::size_t ... Inds>
83  constexpr auto operator() (
84  Function&& function,
85  const TupleType& tuple,
86  std::index_sequence<Inds...> /* inds */
87  ) -> decltype(
88  function(
89  std::declval<
90  std::tuple_element_t<Inds, TupleType>
91  >()...
92  )
93  );
94 };
95 
104 template<typename Function, typename TupleType>
105 static auto isTupleCallableTest(int) -> sfinae_true<
106  decltype(
107  std::declval<InvokeTester>()(
108  std::declval<Function>(),
109  std::declval<TupleType>(),
110  std::make_index_sequence<std::tuple_size<TupleType>::value>()
111  )
112  )
113 >;
114 
115 template<typename Function, typename TupleType, typename... Args>
116 static auto isTupleCallableTest(long) -> std::false_type;
117 
124 template<typename Function, typename TupleType, typename... Args>
125 struct isTupleCallable : decltype(isTupleCallableTest<Function, TupleType, Args...>(0)) {};
126 
127 } // namespace Detail
128 
137 template<
138  typename Fn,
139  typename TupleType,
140  std::enable_if_t<Detail::isTupleCallable<Fn, TupleType>::value, int> = 0
141 > auto invoke(
142  Fn&& function,
143  const TupleType& tuple
144 ) {
145  return Detail::invokeHelper(
146  std::forward<Fn>(function),
147  tuple,
148  std::make_index_sequence<
149  std::tuple_size<TupleType>::value
150  >()
151  );
152 }
153 
154 template<
155  typename Fn,
156  typename... Args,
157  std::enable_if_t<
158  sizeof...(Args) != 1 || !Detail::isTupleCallable<Fn, Args...>::value,
159  int
160  > = 0
161 >
162 auto invoke(Fn&& function, Args&& ... args) {
163  return std::invoke(function, std::forward<Args>(args)...);
164 }
165 
166 namespace Detail {
167 
168 template<typename Functor>
169 struct Invoker {
170  Functor function;
171 
172  Invoker(Functor&& passFunction) : function(passFunction) {}
173 
174  template<typename TupleType>
175  constexpr auto operator() (const TupleType& tuple) const noexcept(noexcept(invoke(function, tuple))) {
176  return invoke(function, tuple);
177  }
178 };
179 
180 } // namespace Detail
181 
182 template<typename Functor>
183 auto make_tuple_callable(Functor&& functor) {
184  return Detail::Invoker<Functor>(std::forward<Functor>(functor));
185 }
186 
187 } // namespace Temple
188 } // namespace Molassembler
189 } // namespace Scine
190 
191 #endif
auto invoke(Function &&function, const boost::tuples::cons< HT, TT > &tuple)
Invokes a function with all values in a given boost tuple.
Definition: Invoke.h:44