Pothos  0.3.0-ga8f2d4e2
The Pothos dataflow programming software suite
 All Classes Namespaces Files Functions Variables Typedefs Friends Macros
CallableImpl.tmpl.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::make(std::forward<ValueType>(val)), argNo);
38 }
39 
40 namespace Detail {
41 #for $NARGS in range($MAX_ARGS+1)
42 /***********************************************************************
43  * Function specialization for return type with $(NARGS) args
44  **********************************************************************/
45 template <typename ReturnType, $expand('typename A%d', $NARGS)>
46 struct CallableFunctionContainer$(NARGS) : Detail::CallableContainer
47 {
48  template <typename FcnType>
49  CallableFunctionContainer$(NARGS)(const FcnType &fcn):
50  _fcn(std::bind(fcn, $expand('std::placeholders::_$(%d+1)', $NARGS)))
51  {
52  return;
53  }
54 
55  size_t getNumArgs(void) const
56  {
57  return $NARGS;
58  }
59 
60  const std::type_info &type(const int $optarg('argNo', $NARGS))
61  {
62  #for $i in range($NARGS):
63  if (argNo == $i) return typeid(A$i);
64  #end for
65  return typeid(ReturnType);
66  }
67 
68  Object call(const Object * $optarg('args', $NARGS))
69  {
70  #for $i in range($NARGS):
71  auto &a$i = args[$i].extract<A$i>();
72  #end for
73  return CallHelper<
74  decltype(_fcn), std::is_void<ReturnType>::value
75  >::call(_fcn, $expand('a%d', $NARGS));
76  }
77 
79  template <typename FcnType, bool Condition> struct CallHelper;
80  template <typename FcnType> struct CallHelper<FcnType, false>
81  {
82  static Object call(const FcnType &fcn, $expand('const A%d &a%d', $NARGS))
83  {
84  return Object::make(fcn($expand('a%d', $NARGS)));
85  }
86  };
87  template <typename FcnType> struct CallHelper<FcnType, true>
88  {
89  static Object call(const FcnType &fcn, $expand('const A%d &a%d', $NARGS))
90  {
91  fcn($expand('a%d', $NARGS)); return Object();
92  }
93  };
94 
95  std::function<ReturnType($expand('A%d', $NARGS))> _fcn;
96 };
97 
98 template <typename ClassType, $expand('typename A%d', $NARGS)>
99 ClassType CallableFactoryWrapper($expand('const A%d &a%d', $NARGS))
100 {
101  return ClassType($expand('a%d', $NARGS));
102 }
103 
104 template <typename ClassType, $expand('typename A%d', $NARGS)>
105 ClassType *CallableFactoryNewWrapper($expand('const A%d &a%d', $NARGS))
106 {
107  return new ClassType($expand('a%d', $NARGS));
108 }
109 
110 template <typename ClassType, $expand('typename A%d', $NARGS)>
111 std::shared_ptr<ClassType> CallableFactorySharedWrapper($expand('const A%d &a%d', $NARGS))
112 {
113  return std::shared_ptr<ClassType>(new ClassType($expand('a%d', $NARGS)));
114 }
115 #end for
116 
117 } //namespace Detail
118 
119 #for $NARGS in range($MAX_ARGS)
120 /***********************************************************************
121  * Templated factory/constructor calls with $(NARGS) args
122  **********************************************************************/
123 template <typename ReturnType, typename ClassType, $expand('typename A%d', $NARGS)>
124 Callable::Callable(ReturnType(ClassType::*fcn)($expand('A%d', $NARGS))):
125  _impl(new Detail::CallableFunctionContainer$(NARGS+1)<ReturnType, ClassType &, $expand('A%d', $NARGS)>(fcn))
126 {
127  return;
128 }
129 
130 template <typename ReturnType, typename ClassType, $expand('typename A%d', $NARGS)>
131 Callable::Callable(ReturnType(ClassType::*fcn)($expand('A%d', $NARGS)) const):
132  _impl(new Detail::CallableFunctionContainer$(NARGS+1)<ReturnType, const ClassType &, $expand('A%d', $NARGS)>(fcn))
133 {
134  return;
135 }
136 
137 template <typename ReturnType, $expand('typename A%d', $NARGS)>
138 Callable::Callable(ReturnType(*fcn)($expand('A%d', $NARGS))):
139  _impl(new Detail::CallableFunctionContainer$(NARGS)<ReturnType, $expand('A%d', $NARGS)>(fcn))
140 {
141  return;
142 }
143 
144 template <$expand('typename A%d', $NARGS), typename ReturnType, typename ClassType>
145 Callable Callable::make(ReturnType(ClassType::*fcn)($expand('A%d', $NARGS)))
146 {
147  return Callable(fcn);
148 }
149 
150 template <$expand('typename A%d', $NARGS), typename ReturnType, typename ClassType>
151 Callable Callable::make(ReturnType(ClassType::*fcn)($expand('A%d', $NARGS)) const)
152 {
153  return Callable(fcn);
154 }
155 
156 template <$expand('typename A%d', $NARGS), typename ReturnType>
157 Callable Callable::make(ReturnType(*fcn)($expand('A%d', $NARGS)))
158 {
159  return Callable(fcn);
160 }
161 
162 template <typename ClassType, $expand('typename A%d', $NARGS)>
164 {
165  return Callable(&Detail::CallableFactoryWrapper<ClassType, $expand('A%d', $NARGS)>);
166 }
167 
168 template <typename ClassType, $expand('typename A%d', $NARGS)>
170 {
171  return Callable(&Detail::CallableFactoryNewWrapper<ClassType, $expand('A%d', $NARGS)>);
172 }
173 
174 template <typename ClassType, $expand('typename A%d', $NARGS)>
176 {
177  return Callable(&Detail::CallableFactorySharedWrapper<ClassType, $expand('A%d', $NARGS)>);
178 }
179 
180 #end for
181 } //namespace Pothos
#define POTHOS_API
Definition: Config.hpp:41
Callable & bind(ValueType &&val, const size_t argNo)
Definition: CallableImpl.tmpl.hpp:35
static Callable make(ReturnType(ClassType::*fcn)($expand('A%d', $NARGS)))
Definition: CallableImpl.tmpl.hpp:145
static Object make(ValueType &&value)
Definition: ObjectImpl.hpp:206
Definition: Callable.tmpl.hpp:30
static Callable factoryShared(void)
Definition: CallableImpl.tmpl.hpp:175
const ValueType & extract(void) const
Definition: ObjectImpl.hpp:221
static Callable factoryNew(void)
Definition: CallableImpl.tmpl.hpp:169
static Callable factory(void)
Definition: CallableImpl.tmpl.hpp:163