Molassembler  1.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 function(
75  std::get<Inds>(tuple)...
76  );
77 }
78 
83 struct InvokeTester {
84  template<typename Function, typename TupleType, std::size_t ... Inds>
85  constexpr auto operator() (
86  Function&& function,
87  const TupleType& tuple,
88  std::index_sequence<Inds...> /* inds */
89  ) -> decltype(
90  function(
91  std::declval<
92  std::tuple_element_t<Inds, TupleType>
93  >()...
94  )
95  );
96 };
97 
106 template<typename Function, typename TupleType>
107 static auto isTupleCallableTest(int) -> sfinae_true<
108  decltype(
109  std::declval<InvokeTester>()(
110  std::declval<Function>(),
111  std::declval<TupleType>(),
112  std::make_index_sequence<std::tuple_size<TupleType>::value>()
113  )
114  )
115 >;
116 
117 template<typename Function, typename TupleType, typename... Args>
118 static auto isTupleCallableTest(long) -> std::false_type;
119 
126 template<typename Function, typename TupleType, typename... Args>
127 struct isTupleCallable : decltype(isTupleCallableTest<Function, TupleType, Args...>(0)) {};
128 
129 } // namespace Detail
130 
139 template<
140  typename Function,
141  typename TupleType,
142  std::enable_if_t<
143  Detail::isTupleCallable<Function, TupleType>::value,
144  int
145  > = 0
146 > auto invoke(
147  Function&& function,
148  const TupleType& tuple
149 ) {
150  return Detail::invokeHelper(
151  std::forward<Function>(function),
152  tuple,
153  std::make_index_sequence<
154  std::tuple_size<TupleType>::value
155  >()
156  );
157 }
158 
167 template<
168  typename Fn,
169  typename... Args,
170  std::enable_if_t<
171  !(sizeof...(Args) == 1 && Detail::isTupleCallable<Fn, Args...>::value)
172  && std::is_member_pointer<std::decay_t<Fn>>{},
173  int
174  > = 0
175 > constexpr decltype(auto) invoke(Fn&& f, Args&&... args)
176 noexcept(noexcept(std::mem_fn(f)(std::forward<Args>(args)...)))
177 {
178  return std::mem_fn(f)(std::forward<Args>(args)...);
179 }
180 
189 template<
190  typename Fn,
191  typename... Args,
192  std::enable_if_t<
193  !(sizeof...(Args) == 1 && Detail::isTupleCallable<Fn, Args...>::value)
194  && !std::is_member_pointer<std::decay_t<Fn>>{},
195  int
196  > = 0
197 > constexpr decltype(auto) invoke(Fn&& f, Args&&... args)
198  noexcept(noexcept(std::forward<Fn>(f)(std::forward<Args>(args)...)))
199 {
200  return std::forward<Fn>(f)(std::forward<Args>(args)...);
201 }
202 
203 namespace Detail {
204 
205 template<typename Functor>
206 struct Invoker {
207  Functor function;
208 
209  Invoker(Functor&& passFunction) : function(passFunction) {}
210 
211  template<typename TupleType>
212  constexpr auto operator() (const TupleType& tuple) const noexcept(noexcept(invoke(function, tuple))) {
213  return invoke(function, tuple);
214  }
215 };
216 
217 } // namespace Detail
218 
219 template<typename Functor>
220 auto make_tuple_callable(Functor&& functor) {
221  return Detail::Invoker<Functor>(std::forward<Functor>(functor));
222 }
223 
224 } // namespace Temple
225 } // namespace Molassembler
226 } // namespace Scine
227 
228 #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