Pothos  0.7.0-gf7fbae99
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 <Pothos/Util/Templates.hpp> //integer_sequence
17 #include <functional> //std::function
18 #include <type_traits> //std::type_info, std::is_void
19 #include <utility> //std::forward
20 
21 namespace Pothos {
22 namespace Detail {
23 
24 struct POTHOS_API CallableContainer
25 {
26  CallableContainer(void);
27  virtual ~CallableContainer(void);
28  virtual size_t getNumArgs(void) const = 0;
29  virtual const std::type_info &type(const int argNo) = 0;
30  virtual Object call(const Object *args) = 0;
31 };
32 
33 } //namespace Detail
34 
35 template <typename ValueType>
36 Callable &Callable::bind(ValueType &&val, const size_t argNo)
37 {
38  return this->bind(Object(std::forward<ValueType>(val)), argNo);
39 }
40 
41 namespace Detail {
42 
43 /***********************************************************************
44  * Function specialization for return type with variable args
45  **********************************************************************/
46 template <typename ReturnType, typename FcnRType, typename... ArgsType>
47 class CallableFunctionContainer : public Detail::CallableContainer
48 {
49 public:
50  template <typename FcnType>
51  CallableFunctionContainer(const FcnType &fcn):
52  _fcn(fcn)
53  {
54  return;
55  }
56 
57  size_t getNumArgs(void) const
58  {
59  return sizeof...(ArgsType);
60  }
61 
62  const std::type_info &type(const int argNo)
63  {
64  return typeR<ArgsType..., ReturnType>(argNo);
65  }
66 
67  Object call(const Object *args)
68  {
70  }
71 
72 private:
73 
75  template <typename T>
76  const std::type_info &typeR(const int argNo)
77  {
78  if (argNo == 0) return typeid(T);
79  return typeid(ReturnType);
80  }
81 
83  template <typename T0, typename T1, typename... Ts>
84  const std::type_info &typeR(const int argNo)
85  {
86  if (argNo == 0) return typeid(T0);
87  return typeR<T1, Ts...>(argNo-1);
88  }
89 
91  template<std::size_t ...S>
93  {
94  checkArgs(args); //fixes warning for 0 args case
95  return CallHelper<
96  decltype(_fcn),
97  std::is_void<ReturnType>::value,
98  std::is_same<ReturnType, FcnRType>::value,
99  std::is_reference<ReturnType>::value and
100  not std::is_const<typename std::remove_reference<ReturnType>::type>::value
101  >::call(_fcn, args[S].extract<ArgsType>()...);
102  }
103 
105  void checkArgs(const Object *){}
106 
108  template <typename FcnType, bool isVoid, bool isSameR, bool isReference> struct CallHelper;
109  template <typename FcnType> struct CallHelper<FcnType, false, true, false>
110  {
111  static Object call(const FcnType &fcn, const ArgsType&... args)
112  {
113  return Object::make(fcn(args...));
114  }
115  };
116  template <typename FcnType> struct CallHelper<FcnType, false, false, false>
117  {
118  static Object call(const FcnType &fcn, const ArgsType&... args)
119  {
120  return fcn(args...);
121  }
122  };
123  template <typename FcnType> struct CallHelper<FcnType, false, true, true>
124  {
125  static Object call(const FcnType &fcn, const ArgsType&... args)
126  {
127  return Object::make(std::ref(fcn(args...)));
128  }
129  };
130  template <typename FcnType> struct CallHelper<FcnType, true, true, false>
131  {
132  static Object call(const FcnType &fcn, const ArgsType&... args)
133  {
134  fcn(args...); return Object();
135  }
136  };
137 
138  std::function<FcnRType(ArgsType...)> _fcn;
139 };
140 
141 template <typename ClassType, typename... ArgsType>
142 Object CallableFactoryNewWrapper(ArgsType&&... args)
143 {
144  return Object(new ClassType(std::forward<ArgsType>(args)...));
145 }
146 
147 } //namespace Detail
148 
149 /***********************************************************************
150  * Templated factory/constructor calls with variable args
151  **********************************************************************/
152 template <typename ReturnType, typename ClassType, typename... ArgsType>
153 Callable::Callable(ReturnType(ClassType::*fcn)(ArgsType...)):
154  _impl(new Detail::CallableFunctionContainer<ReturnType, ReturnType, ClassType &, ArgsType...>(std::mem_fn(fcn)))
155 {
156  return;
157 }
158 
159 template <typename ReturnType, typename ClassType, typename... ArgsType>
160 Callable::Callable(ReturnType(ClassType::*fcn)(ArgsType...) const):
161  _impl(new Detail::CallableFunctionContainer<ReturnType, ReturnType, const ClassType &, ArgsType...>(std::mem_fn(fcn)))
162 {
163  return;
164 }
165 
166 template <typename ReturnType, typename... ArgsType>
167 Callable::Callable(ReturnType(*fcn)(ArgsType...)):
168  _impl(new Detail::CallableFunctionContainer<ReturnType, ReturnType, ArgsType...>(fcn))
169 {
170  return;
171 }
172 
173 template <typename ReturnType, typename ClassType, typename... ArgsType>
174 Callable Callable::make(ReturnType(ClassType::*fcn)(ArgsType...))
175 {
176  return Callable(fcn);
177 }
178 
179 template <typename ReturnType, typename ClassType, typename... ArgsType>
180 Callable Callable::make(ReturnType(ClassType::*fcn)(ArgsType...) const)
181 {
182  return Callable(fcn);
183 }
184 
185 template <typename ReturnType, typename... ArgsType>
186 Callable Callable::make(ReturnType(*fcn)(ArgsType...))
187 {
188  return Callable(fcn);
189 }
190 
191 template <typename ClassType, typename... ArgsType>
193 {
194  return Callable(new Detail::CallableFunctionContainer<ClassType, Object, ArgsType...>(
195  &Object::emplace<ClassType, ArgsType...>));
196 }
197 
198 template <typename ClassType, typename... ArgsType>
200 {
201  return Callable(new Detail::CallableFunctionContainer<ClassType *, Object, ArgsType...>(
202  &Detail::CallableFactoryNewWrapper<ClassType, ArgsType...>));
203 }
204 
205 template <typename ClassType, typename... ArgsType>
207 {
208  using SharedType = std::shared_ptr<ClassType>;
209  return Callable(new Detail::CallableFunctionContainer<SharedType, SharedType, ArgsType...>(
210  &std::make_shared<ClassType, ArgsType...>));
211 }
212 
213 inline Callable::Callable(Detail::CallableContainer *impl):
214  _impl(impl)
215 {
216  return;
217 }
218 
219 } //namespace Pothos
static Callable make(ReturnType(ClassType::*fcn)(ArgsType...))
Definition: CallableImpl.hpp:174
#define POTHOS_API
Definition: Config.hpp:41
Callable & bind(ValueType &&val, const size_t argNo)
Definition: CallableImpl.hpp:36
static Object make(ValueType &&value)
Definition: ObjectImpl.hpp:110
make_index_sequence< sizeof...(T)> index_sequence_for
Definition: Templates.hpp:116
Definition: Callable.hpp:30
Definition: Templates.hpp:67
Definition: ArchiveEntry.hpp:20
static Callable factoryShared(void)
Definition: CallableImpl.hpp:206
Definition: Object.hpp:47
static Callable factoryNew(void)
Definition: CallableImpl.hpp:199
static Callable factory(void)
Definition: CallableImpl.hpp:192