Pothos  0.4.1-gb758ed46
The Pothos dataflow programming software suite
CallableImpl.hpp
Go to the documentation of this file.
1 
11 #pragma once
12 #include <Pothos/Config.hpp>
16 #include <functional> //std::function
17 #include <type_traits> //std::type_info, std::is_void
18 #include <utility> //std::forward
19 
20 namespace Pothos {
21 namespace Detail {
22 
23 struct POTHOS_API CallableContainer
24 {
25  CallableContainer(void);
26  virtual ~CallableContainer(void);
27  virtual size_t getNumArgs(void) const = 0;
28  virtual const std::type_info &type(const int argNo) = 0;
29  virtual Object call(const Object *args) = 0;
30 };
31 
32 } //namespace Detail
33 
34 template <typename ValueType>
35 Callable &Callable::bind(ValueType &&val, const size_t argNo)
36 {
37  return this->bind(Object(std::forward<ValueType>(val)), argNo);
38 }
39 
40 namespace Detail {
41 
42 /***********************************************************************
43  * Function specialization for return type with variable args
44  **********************************************************************/
45 template <typename ReturnType, typename... ArgsType>
46 class CallableFunctionContainer : public Detail::CallableContainer
47 {
48 public:
49  template <typename FcnType>
50  CallableFunctionContainer(const FcnType &fcn):
51  _fcn(fcn)
52  {
53  return;
54  }
55 
56  size_t getNumArgs(void) const
57  {
58  return sizeof...(ArgsType);
59  }
60 
61  const std::type_info &type(const int argNo)
62  {
63  return typeR<ArgsType..., ReturnType>(argNo);
64  }
65 
66  Object call(const Object *args)
67  {
68  return call(args, typename Gens<sizeof...(ArgsType)>::Type());
69  }
70 
71 private:
72 
74  template <typename T>
75  const std::type_info &typeR(const int argNo)
76  {
77  if (argNo == 0) return typeid(T);
78  return typeid(ReturnType);
79  }
80 
82  template <typename T0, typename T1, typename... Ts>
83  const std::type_info &typeR(const int argNo)
84  {
85  if (argNo == 0) return typeid(T0);
86  return typeR<T1, Ts...>(argNo-1);
87  }
88 
93  template<int...> struct Seq {};
94  template<int N, int... S> struct Gens : Gens<N-1, N-1, S...> {};
95  template<int... S> struct Gens<0, S...>{ typedef Seq<S...> Type; };
97 
99  template<int ...S>
100  Object call(const Object *args, Seq<S...>)
101  {
102  checkArgs(args); //fixes warning for 0 args case
103  return CallHelper<
104  decltype(_fcn), std::is_void<ReturnType>::value
105  >::call(_fcn, args[S].extract<ArgsType>()...);
106  }
107 
109  void checkArgs(const Object *){}
110 
112  template <typename FcnType, bool Condition> struct CallHelper;
113  template <typename FcnType> struct CallHelper<FcnType, false>
114  {
115  static Object call(const FcnType &fcn, const ArgsType&... args)
116  {
117  return Object::make(fcn(args...));
118  }
119  };
120  template <typename FcnType> struct CallHelper<FcnType, true>
121  {
122  static Object call(const FcnType &fcn, const ArgsType&... args)
123  {
124  fcn(args...); return Object();
125  }
126  };
127 
128  std::function<ReturnType(ArgsType...)> _fcn;
129 };
130 
131 template <typename ClassType, typename... ArgsType>
132 ClassType CallableFactoryWrapper(const ArgsType&... args)
133 {
134  return ClassType(args...);
135 }
136 
137 template <typename ClassType, typename... ArgsType>
138 ClassType *CallableFactoryNewWrapper(const ArgsType&... args)
139 {
140  return new ClassType(args...);
141 }
142 
143 template <typename ClassType, typename... ArgsType>
144 std::shared_ptr<ClassType> CallableFactorySharedWrapper(const ArgsType&... args)
145 {
146  return std::shared_ptr<ClassType>(new ClassType(args...));
147 }
148 
149 } //namespace Detail
150 
151 /***********************************************************************
152  * Templated factory/constructor calls with variable args
153  **********************************************************************/
154 template <typename ReturnType, typename ClassType, typename... ArgsType>
155 Callable::Callable(ReturnType(ClassType::*fcn)(ArgsType...)):
156  _impl(new Detail::CallableFunctionContainer<ReturnType, ClassType &, ArgsType...>(std::mem_fn(fcn)))
157 {
158  return;
159 }
160 
161 template <typename ReturnType, typename ClassType, typename... ArgsType>
162 Callable::Callable(ReturnType(ClassType::*fcn)(ArgsType...) const):
163  _impl(new Detail::CallableFunctionContainer<ReturnType, const ClassType &, ArgsType...>(std::mem_fn(fcn)))
164 {
165  return;
166 }
167 
168 template <typename ReturnType, typename... ArgsType>
169 Callable::Callable(ReturnType(*fcn)(ArgsType...)):
170  _impl(new Detail::CallableFunctionContainer<ReturnType, ArgsType...>(fcn))
171 {
172  return;
173 }
174 
175 template <typename ReturnType, typename ClassType, typename... ArgsType>
176 Callable Callable::make(ReturnType(ClassType::*fcn)(ArgsType...))
177 {
178  return Callable(fcn);
179 }
180 
181 template <typename ReturnType, typename ClassType, typename... ArgsType>
182 Callable Callable::make(ReturnType(ClassType::*fcn)(ArgsType...) const)
183 {
184  return Callable(fcn);
185 }
186 
187 template <typename ReturnType, typename... ArgsType>
188 Callable Callable::make(ReturnType(*fcn)(ArgsType...))
189 {
190  return Callable(fcn);
191 }
192 
193 template <typename ClassType, typename... ArgsType>
195 {
196  return Callable(&Detail::CallableFactoryWrapper<ClassType, ArgsType...>);
197 }
198 
199 template <typename ClassType, typename... ArgsType>
201 {
202  return Callable(&Detail::CallableFactoryNewWrapper<ClassType, ArgsType...>);
203 }
204 
205 template <typename ClassType, typename... ArgsType>
207 {
208  return Callable(&Detail::CallableFactorySharedWrapper<ClassType, ArgsType...>);
209 }
210 
211 } //namespace Pothos
static Callable make(ReturnType(ClassType::*fcn)(ArgsType...))
Definition: CallableImpl.hpp:176
#define POTHOS_API
Definition: Config.hpp:41
Callable & bind(ValueType &&val, const size_t argNo)
Definition: CallableImpl.hpp:35
static Object make(ValueType &&value)
Definition: ObjectImpl.hpp:206
Definition: Callable.hpp:30
Definition: Testing.hpp:134
static Callable factoryShared(void)
Definition: CallableImpl.hpp:206
Definition: Object.hpp:55
static Callable factoryNew(void)
Definition: CallableImpl.hpp:200
static Callable factory(void)
Definition: CallableImpl.hpp:194