libqi-api  2.4.3.28
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
anyfunctionfactory.hxx
Go to the documentation of this file.
1 #pragma once
2 /*
3 ** Copyright (C) 2013 Aldebaran Robotics
4 ** See COPYING for the license
5 */
6 
7 #ifndef _QITYPE_DETAILS_ANYFUNCTIONFACTORY_HXX_
8 #define _QITYPE_DETAILS_ANYFUNCTIONFACTORY_HXX_
9 
10 #include <boost/mpl/for_each.hpp>
11 #include <boost/mpl/transform_view.hpp>
12 #include <boost/mpl/find_if.hpp>
13 #include <boost/mpl/vector.hpp>
14 #include <boost/mpl/pop_front.hpp>
15 #include <boost/mpl/at.hpp>
16 #include <boost/mpl/placeholders.hpp>
17 #include <boost/mpl/max_element.hpp>
18 #include <boost/mpl/transform.hpp>
19 #include <boost/type_traits/remove_reference.hpp>
20 #include <boost/type_traits/add_pointer.hpp>
21 #include <boost/type_traits/remove_const.hpp>
22 #include <boost/type_traits/remove_pointer.hpp>
23 #include <boost/type_traits/is_member_function_pointer.hpp>
24 #include <boost/function_types/function_type.hpp>
25 #include <boost/function_types/function_arity.hpp>
26 #include <boost/function_types/function_pointer.hpp>
27 #include <boost/function_types/member_function_pointer.hpp>
28 #include <boost/function_types/result_type.hpp>
29 #include <boost/function_types/parameter_types.hpp>
30 #include <boost/bind.hpp>
31 #include <boost/any.hpp>
32 #include <boost/thread/mutex.hpp>
33 #include <qi/atomic.hpp>
34 #include <qi/anyvalue.hpp>
35 
36 namespace qi
37 {
38  namespace detail
39  {
40  /* General idea: code generated to make a function call taking a
41  * void*, long, or long& is the same.
42  * So we reduce the function types for which we effectively implement
43  * call, and bounce the equivalent functions to it.
44  */
45 
46  /* ASSERTS
47  * We make some asumptions for this code to work. Failure on any of
48  * those asumptions will *not* be detected and will cause undefined behavior.
49  * - typesystem Storage for pointer types is by-value, and by-pointer for everything else
50  * - compiler-generated code is the same when calling a function:
51  * - with argument T and EqType<T>::type
52  * - with return type T and EqType<T>::rType
53  * - with all pointer types and all reference types for argument/return type
54  */
55 
56  class Class{}; // dummy class placeholder
57 
58  /* For each type, get equivalent type, and if it is a reference
59  * Equivalent type is a type for which when types are substituted in a
60  * function call, compiler-generated code is the same.
61  * *WARNING* some magic occurs for return type, so have a separate rule
62  * which matches less stuffs for it.
63  */
64  template <typename T, bool isWordSize>
65  struct EqTypeBase
66  {
67  typedef T type;
68  typedef T rType;
69  typedef typename boost::is_reference<T>::type isReference;
70  static const int dbgTag = 0;
71  };
72 
73  template<typename T>
74  struct EqTypeBase<T, true>
75  {
76  typedef typename boost::mpl::if_<typename boost::is_fundamental<T>::type, void*, T>::type type;
77  typedef typename boost::mpl::if_<typename boost::is_fundamental<T>::type, void*, T>::type rType;
78  typedef typename boost::is_reference<T>::type isReference;
79  static const int dbgTag = 1;
80  };
81 
82  template <typename T>
83  struct EqType: public EqTypeBase<T, sizeof(T) == sizeof(void*)>
84  {
85  };
86 
87  template <> struct EqType<void>
88  {
89  typedef void type;
90  typedef void* rType;
91  typedef boost::false_type isReference;
92  };
93 
94  template<> struct EqType<double>
95  {
96  typedef double type;
97  typedef double rType;
98  typedef boost::false_type isReference;
99  };
100 
101  template<> struct EqType<float>
102  {
103  typedef float type;
104  typedef float rType;
105  typedef boost::false_type isReference;
106  };
107 
108  template<> struct EqType<bool>
109  {
110  typedef bool type;
111  typedef bool rType;
112  typedef boost::false_type isReference;
113  };
114 
115  template <typename T> struct EqType<T&>
116  {
117  typedef void* type;
118  typedef void* rType;
119  typedef boost::true_type isReference;
120  static const int dbgTag = 2;
121  };
122 
123  template <typename T> struct EqType<T const &>
124  {
125  typedef void* type;
126  typedef void* rType;
127  typedef boost::true_type isReference;
128  static const int dbgTag = 3;
129  };
130 
131  // HACK: mark pointer as references, because typesystem transmit them
132  // by-value
133  template <typename T>
134  struct EqType<T *>
135  {
136  typedef void* type;
137  typedef void* rType;
138  typedef boost::true_type isReference;
139  static const int dbgTag = 4;
140  };
141 
142  // helper to compute a reference mask iterating through a mpl sequence
143  template<typename S, typename I, int p>
144  struct RefMasqBuilderHelper
145  {
146  typedef typename boost::mpl::deref<I>::type type;
147  static const unsigned int isRef = EqType<type>::isReference::value;
148  static const unsigned long vSelf = isRef << p;
149  static const unsigned long val = vSelf + RefMasqBuilderHelper<S,
150  typename boost::mpl::next<I>::type, p+1>::val;
151  };
152 
153  template<typename S, int p>
154  struct RefMasqBuilderHelper<S, typename boost::mpl::end<S>::type, p>
155  {
156  static const unsigned long val = 0;
157  };
158 
159  /* Equivalent function info for function type F
160  *
161  */
162  template<typename F> struct EqFunctionBare
163  {
164  typedef typename boost::function_types::components<F>::type Components;
165 
166  typedef typename boost::function_types::parameter_types<F>::type Arguments;
167  typedef typename boost::function_types::result_type<F>::type Result;
168 
169  // need to handle result type separately
170  typedef typename boost::mpl::transform<Arguments,
172  typedef typename EqType<Result>::rType EqResult;
173  typedef typename boost::mpl::push_front<EqArguments, EqResult>::type EqComponents;
174 
175  // Bit b is set if argument index b+1 (0=return type) is a reference.
176  static const unsigned long refMask = RefMasqBuilderHelper<Components,
177  typename boost::mpl::begin<Components>::type, 0>::val;
178  typedef typename boost::function_types::function_type<EqComponents>::type type;
179  };
180 
181  template<typename F> struct EqMemberFunction
182  {
183  typedef typename boost::function_types::components<F>::type Components;
184  // we need to handle object type and return type separately
185  // arguments with object
186  typedef typename boost::function_types::parameter_types<F>::type MethodArguments;
187  // arguments without object
188  typedef typename boost::mpl::pop_front<MethodArguments>::type Arguments;
189  // return type
190  typedef typename boost::function_types::result_type<F>::type Result;
191  typedef typename boost::mpl::transform<Arguments,
193  typedef typename EqType<Result>::rType EqResult;
194  // push equivalent object type
195  typedef typename boost::mpl::push_front<EqArguments, detail::Class&>::type EqComponentsInt;
196  typedef typename boost::mpl::push_front<EqComponentsInt, EqResult>::type EqComponents;
197  typedef typename boost::function_types::member_function_pointer<EqComponents>::type type;
198  static const unsigned long refMask = RefMasqBuilderHelper<Components,
199  typename boost::mpl::begin<Components>::type, 0>::val;
200  };
201 
202  template<typename F>
203  struct EqFunction:
204  public boost::mpl::if_<typename boost::is_member_function_pointer<F>::type,
205  EqMemberFunction<F>,
206  EqFunctionBare<F> >::type
207  {};
208  /* args[i] is a pointer to an element of expected type DROPPING ref
209  * we will make the call by dereferencing all args, so we must add
210  * one layer of pointer to effective refs
211  *
212  */
213  inline void transformRef(void** args, void** out, unsigned int sz, unsigned long refMask)
214  {
215  for (unsigned i=0; i<sz; ++i)
216  {
217  if (refMask & (1 << (i+1))) // bit 0 is for return type
218  out[i] = &args[i];
219  else
220  out[i] = args[i];
221  }
222  }
223 
235  {
236  public:
237  AnyReferenceCopy &operator()() { return *this; }
238  };
239 
240  template<typename T> void operator,(AnyReferenceCopy& g, const T& any)
241  {
242  *(AnyReference*)&g = AnyReference::from(any).clone();
243  }
244 
245  // makeCall function family
246  // accepts a bare function, boost function, member function
247  // we handled byval/byref in refMask/transformRef, so bypass
248  // entirely ptrFromStorage.
249 
250 #define callArg(z, n, _) \
251  BOOST_PP_COMMA_IF(n) * (typename boost::remove_reference<P##n>::type*)args[n]
252 #define makeCall(n, argstypedecl, argstype, argsdecl, argsues, comma) \
253  template <typename R comma argstypedecl> \
254  void* makeCall(R (*f)(argstype), void** args) \
255  { \
256  detail::AnyReferenceCopy val; \
257  val(), f(BOOST_PP_REPEAT(n, callArg, _)); \
258  return val.rawValue(); \
259  }
261 #undef makeCall
262 
263 #ifdef _WIN32
264 #define STATIC_IF_SAFE
265 #else
266 #define STATIC_IF_SAFE static
267 #endif
268 
269 // hacks are disabled for boost::function (refMask forced to 0)
270 // so use ptrFromStorage.
271 #define declType(z, n, _) \
272  STATIC_IF_SAFE TypeInterface* type_##n = \
273  typeOf<typename boost::remove_reference<P##n>::type>();
274 #define callArgBF(z, n, _) \
275  BOOST_PP_COMMA_IF(n) * (typename boost::remove_reference<P##n>::type*) \
276  type_##n->ptrFromStorage(&args[n])
277 
278 #define makeCall(n, argstypedecl, argstype, argsdecl, argsues, comma) \
279  template <typename R comma argstypedecl> \
280  void* makeCall(boost::function<R(argstype)> f, void** args) \
281  { \
282  BOOST_PP_REPEAT(n, declType, _) detail::AnyReferenceCopy val; \
283  val(), f(BOOST_PP_REPEAT(n, callArgBF, _)); \
284  return val.rawValue(); \
285  }
287 #undef makeCall
288 
289 #define makeCall(n, argstypedecl, argstype, argsdecl, argsues, comma) \
290  template <typename R comma argstypedecl> \
291  void* makeCall(R (Class::*f)(argstype), void* instance, void** args) \
292  { \
293  detail::AnyReferenceCopy val; \
294  Class* cptr = *(Class**)instance; \
295  val(), ((*cptr).*f)(BOOST_PP_REPEAT(n, callArg, _)); \
296  return val.rawValue(); \
297  }
299 #undef makeCall
300 
301 #define makeCall_(n, argstypedecl, argstype, argsdecl, argsues, comma) \
302  template <typename R comma argstypedecl> \
303  void* makeCall(R (Class::*f)(argstype), void** args) \
304  { \
305  return makeCall(f, args[0], args + 1); \
306  }
307 
309 #undef callArg
310 #undef makeCall_
311 
312 #ifdef QITYPE_TRACK_FUNCTIONTYPE_INSTANCES
313  // debug-tool to monitor function type usage
314  void QI_API functionTypeTrack(const std::string& functionName);
315  void QI_API functionTypeDump();
316 #endif
317  }
318 
319  struct InfosKeyMask: public std::vector<TypeInterface*>
320  {
321  public:
322  InfosKeyMask(const std::vector<TypeInterface*>& b, unsigned long mask)
323  : std::vector<TypeInterface*>(b), _mask(mask) {}
324  bool operator < (const InfosKeyMask& b) const
325  {
326  if (size() != b.size())
327  return size() < b.size();
328  for (unsigned i=0; i<size(); ++i)
329  {
330  if ( (*this)[i]->info() != b[i]->info())
331  return (*this)[i]->info() < b[i]->info();
332  }
333  return _mask < b._mask;
334  }
335  unsigned long _mask;
336  };
337 
338  /* T is the *reducted* function type
339  * S is the storage type of the function
340  * So each instance must know the refMask, and the real return type
341  *
342  * categories of S in use:
343  * boost::function: no reduction performed
344  * bare function pointer
345  * member function pointer: T is the linearized signature
346  */
347  template<typename T, typename S>
349  {
350  public:
351  typedef typename boost::function_types::result_type<T>::type ReturnType;
353  : refMask(refMask)
354  {
355 #ifdef QITYPE_TRACK_FUNCTIONTYPE_INSTANCES
356  detail::functionTypeTrack(typeid(S).name());
357 #endif
358  }
359  virtual void* call(void* storage, void** args, unsigned int argc)
360  {
361 #if QI_HAS_VARIABLE_LENGTH_ARRAY
362  void* out[argc];
363 #else
364  void* outStatic[8];
365  void** out;
366  if (argc <= 8)
367  out = outStatic;
368  else
369  out = new void*[argc];
370 #endif
371  detail::transformRef(args, out, argc, refMask);
372  void* v = detail::makeCall(*(S*)ptrFromStorage(&storage), (void**)out);
373  // v is storage for type ReturnType we claimed we were
374  // adapt return value if needed
375  if (boost::is_pointer<ReturnType>::value
377  {
378  // if refMask&1, real return type is some Foo& and v is Foo*
379  // else, return type is Foo with sizeof(Foo) == sizeof(void*) and v is a Foo
380  void* vstorage = _resultType->initializeStorage(
381  (refMask&1)? v: &v);
382  vstorage = _resultType->clone(vstorage);
383  //qiLogWarning("ft") << "Ret deref " << (unsigned long)v <<' ' << vstorage
384  // << ' ' << *(unsigned long*)vstorage;
385  v = vstorage;
386  }
387 #if ! QI_HAS_VARIABLE_LENGTH_ARRAY
388  if (argc > 8)
389  delete[] out;
390 #endif
391  return v;
392  }
393  unsigned long refMask;
394  static FunctionTypeInterfaceEq<T, S>* make(unsigned long refMask, std::vector<TypeInterface*> argsType,
395  TypeInterface* returnType)
396  { // we need to hash/compare on all the arguments
397  std::vector<TypeInterface*> key(argsType);
398  key.push_back(returnType);
399  typedef std::map<InfosKeyMask, FunctionTypeInterfaceEq<T, S>* > FTMap;
400  static FTMap* ftMap = 0;
401  static boost::mutex* mutex = 0;
402  QI_THREADSAFE_NEW(ftMap, mutex);
403  boost::mutex::scoped_lock lock(*mutex);
404  FunctionTypeInterfaceEq<T, S>* & fptr = (*ftMap)[InfosKeyMask(key, refMask)];
405  if (!fptr)
406  {
408  fptr->_resultType = returnType;
409  fptr->_argumentsType = argsType;
410  }
411  return fptr;
412  }
414  };
415 
416  namespace detail
417  {
418 
419  // Trick used to avoid instanciating a T
420  template<typename T> struct Ident
421  {
422  };
423 
425  {
426  template<typename T> void operator()(Ident<T>)
427  {
428  qiLogCategory("qitype.functiontypefactory");
429  if (boost::is_reference<T>::value && !boost::is_const<
430  typename boost::remove_reference<T>::type>::value)
431  qiLogWarning() << "Function argument is a non-const reference: " << typeid(T).name();
432  }
433  };
434  template<typename T> struct remove_constptr
435  {
436  typedef T type;
437  };
438  template<typename T> struct remove_constptr<const T*>
439  {
440  typedef T* type;
441  };
442  // Fill a vector<TypeInterface*> from a T*
444  {
445  inline fill_arguments(std::vector<TypeInterface*>* target)
446  : target(target) {}
447 
448  template<typename T> void operator()(T*) const
449  {
450  TypeInterface* result = typeOf<
451  typename remove_constptr<
452  typename boost::remove_const<
453  typename boost::remove_reference<T>::type
454  >::type>::type>();
455  target->push_back(result);
456  }
457  std::vector<TypeInterface*>* target;
458  };
459 
460  // build a function pointer or member function pointer type
461  template<typename F, bool Member> struct FunctionPointerSynthetizer
462  {
463  typedef typename boost::function_types::member_function_pointer<F>::type type;
464  };
465  template<typename F> struct FunctionPointerSynthetizer<F, false>
466  {
467  typedef typename boost::function_types::function_pointer<F>::type type;
468  };
469  // Accept a function pointer or member function pointer
470  template<typename F>
472  {
473  typedef typename boost::function_types::parameter_types<F>::type ArgsType;
474  typedef typename boost::function_types::result_type<F>::type ResType;
475  TypeInterface* resultType = typeOf<ResType>();
476  std::vector<TypeInterface*> argumentsType;
477  // Generate and store a TypeInterface* for each argument
478  boost::mpl::for_each<
479  boost::mpl::transform_view<ArgsType,
480  boost::add_pointer<
481  boost::remove_const<
482  boost::remove_reference<boost::mpl::_1> > > > >(detail::fill_arguments(&argumentsType));
483  typedef typename EqFunction<F>::type MapedF;
484  // regenerate eq function pointer type
485  typedef typename boost::function_types::components<MapedF>::type EqComponents;
486  // would have used mpl::if_ but it has laziness issues it seems
487  typedef typename FunctionPointerSynthetizer<EqComponents,
488  boost::is_member_function_pointer<F>::value>::type EqFunPtr;
489  unsigned long mask = EqFunction<F>::refMask;
490  FunctionTypeInterface* ftype = FunctionTypeInterfaceEq<MapedF, EqFunPtr>::make(mask, argumentsType, resultType);
491 
492  qiLogDebug("qitype.makeAnyFunction") << "bare mask " << (unsigned long)EqFunction<F>::refMask;
493  return AnyFunction(ftype, ftype->clone(ftype->initializeStorage(&func)));
494  }
495 
496  template<typename C, typename R>
498  R (C::*fun)(const AnyArguments&)
499  )
500  {
501  // Pack arguments, call, wrap return value in AnyValue
502  AnyArguments nargs;
503  nargs.args().resize(vargs.size()-1);
504  for (unsigned i=0; i<vargs.size()-1; ++i)
505  nargs.args()[i] = vargs[i+1];
506  C* inst = (C*)vargs.front().rawValue();
507  if (!inst)
508  qiLogWarning("qitype.AnyArgumentsBouncer") << "Null instance";
510  output(), (*inst.*fun)(nargs); // output clones
511  AnyValue* v = new AnyValue(output, false, true); // steal output
512  return AnyReference::fromPtr(v);
513  }
514 
515  template<typename R>
517  boost::function<R (const AnyArguments&)> f
518  )
519  {
520  AnyArguments nargs;
521  if(!vargs.empty())
522  {
523  nargs.args().resize(vargs.size());
524  for (unsigned i=0; i<vargs.size(); ++i)
525  nargs.args()[i] = vargs[i];
526  }
528  output(), f(nargs);
529  AnyValue* v = new AnyValue(output, false, true); // steal output
530  return AnyReference::fromPtr(v);
531  }
532 
533  template<typename C, typename R>
535  {
536  AnyFunction res = AnyFunction::fromDynamicFunction(boost::bind(&bouncer<C, R>, _1, fun));
537  // The signature storage in GO will drop first argument, and bug if none is present
538  const_cast<std::vector<TypeInterface*> &>(res.functionType()->argumentsType()).push_back(typeOf<AnyValue>());
539  return res;
540  }
541 
542  template<typename R>
544  {
545  boost::function<R (const AnyArguments&)> fu = fun;
546  AnyFunction res = AnyFunction::fromDynamicFunction(boost::bind(&bouncerBF<R>, _1, fun));
547  // The signature storage in GO will drop first argument, and bug if none is present
548  const_cast<std::vector<TypeInterface*> &>(res.functionType()->argumentsType()).push_back(typeOf<AnyValue>());
549  return res;
550  }
551 
552  template<typename R> AnyFunction makeAnyFunctionBare(boost::function<R (const AnyArguments&)> fun)
553  {
554  AnyFunction res = AnyFunction::fromDynamicFunction(boost::bind(&bouncerBF<R>, _1, fun));
555  // The signature storage in GO will drop first argument, and bug if none is present
556  const_cast<std::vector<TypeInterface*> &>(res.functionType()->argumentsType()).push_back(typeOf<AnyValue>());
557  return res;
558  }
559 
560  template<typename F> AnyFunction makeAnyFunctionBare(boost::function<F> func)
561  {
562  /* Do not try to reduce anything on a boost::function.
563  * It will bounce to an internal template backend anyway
564  */
565  typedef typename boost::function_types::parameter_types<F>::type ArgsType;
566  typedef typename boost::function_types::result_type<F>::type ResType;
567  TypeInterface* resultType = typeOf<ResType>();
568  std::vector<TypeInterface*> argumentsType;
569  boost::mpl::for_each<
570  boost::mpl::transform_view<ArgsType,
571  boost::add_pointer<
572  boost::remove_const<
573  boost::remove_reference<boost::mpl::_1> > > > >(detail::fill_arguments(&argumentsType));
574  FunctionTypeInterface* ftype = FunctionTypeInterfaceEq<F, boost::function<F> >::make(0, argumentsType, resultType);
575  return AnyFunction(ftype, new boost::function<F>(func));
576  }
577 
578  // Use helper structures for which template partial specialisation is possible
579  template<typename T> struct AnyFunctionMaker
580  {
581  static AnyFunction make(T func)
582  {
583  return makeAnyFunctionBare(func);
584  }
585  };
586  template<typename T> struct AnyFunctionMaker<T*>
587  {
588  static AnyFunction make(T* func)
589  {
590  return makeAnyFunctionBare(func);
591  }
592  };
593  template<typename R, typename F, typename B>
594  struct AnyFunctionMaker<boost::_bi::bind_t<R, F, B> >
595  {
596  static AnyFunction make(boost::_bi::bind_t<R, F, B> v)
597  {
598  typedef typename boost::function<typename boost_bind_function_type<
599  boost::_bi::bind_t<R, F, B> >::type> CompatType;
600  CompatType f = v;
601  return AnyFunction::from(f);
602  }
603  };
604  template<typename T> struct AnyFunctionMaker<boost::function<T> >
605  {
606  static AnyFunction make(boost::function<T> func)
607  {
608  assert(sizeof(boost::function<T>) == sizeof(boost::function<void ()>));
609  AnyFunction res = detail::makeAnyFunctionBare(func);
610  return res;
611  }
612  };
613  template<typename T> struct AnyFunctionMaker<const T&>
614  : public AnyFunctionMaker<T> {};
615  template<> struct AnyFunctionMaker<AnyFunction>
616  {
617  static AnyFunction make(AnyFunction func)
618  {
619  return func;
620  }
621  };
622  }
623 
624  template<typename T>
626  {
627  return detail::AnyFunctionMaker<T>::make(f);
628  }
629 
630  namespace detail
631  {
632  template<typename T> struct Pointer
633  {
634  static T* pointer(T& t)
635  {
636  return &t;
637  }
638  };
639  template<typename T> struct Pointer<T*>
640  {
641  static T* pointer(T* & t)
642  {
643  return t;
644  }
645  };
646  }
647 
648  template<typename F, typename C>
649  AnyFunction AnyFunction::from(F func, C instance)
650  {
651  /* Taking a AnyFunction of F will likely imply a typeOf<C> which is
652  * unnecessary. So use a fake class in signature.
653  */
654  typedef typename boost::function_types::result_type<F>::type Result;
655  typedef typename boost::function_types::parameter_types<F, boost::mpl::identity<boost::mpl::_1> >::type Args;
656  typedef typename boost::mpl::pop_front<Args>::type ArgsNoClass;
657  typedef typename boost::mpl::push_front<ArgsNoClass, detail::Class&>::type ArgsFakeClass;
658  typedef typename boost::mpl::push_front<ArgsFakeClass, Result>::type ComponentsFaked;
659  typedef typename boost::function_types::member_function_pointer<ComponentsFaked>::type MethodTypeFaked;
660  MethodTypeFaked newFunk = *(MethodTypeFaked*)(void*)&func;
661  AnyFunction res = AnyFunction::from(newFunk);
662 
663  // Dynamic-cast instance to expected pointer type.
664  typedef typename boost::mpl::at_c<Args, 0>::type FirstArg;
665  // Get expected
666  FirstArg* ptr = dynamic_cast<FirstArg*>(detail::Pointer<C>::pointer(instance));
667  if (!ptr && instance)
668  throw std::runtime_error("makeAnyFunction: failed to dynamic_cast bound value to expected type");
669  res.prependArgument((void*)(const void*)ptr);
670  return res;
671  }
672 
673 }
674 #endif // _QITYPE_DETAILS_ANYFUNCTIONFACTORY_HXX_
void transformRef(void **args, void **out, unsigned int sz, unsigned long refMask)
static const unsigned long refMask
virtual void * ptrFromStorage(void **)=0
virtual void * call(void *storage, void **args, unsigned int argc)
#define makeCall_(n, argstypedecl, argstype, argsdecl, argsues, comma)
AnyValueVector & args()
#define QI_API
Definition: api.hpp:34
static AnyFunction from(F func)
bool operator<(const InfosKeyMask &b) const
FunctionTypeInterfaceEq(unsigned long refMask)
#define qiLogCategory(Cat)
Definition: log.hpp:46
boost::function< RF > bind(const AF &fun,...)
boost::function_types::function_pointer< F >::type type
AnyFunction makeAnyFunctionBare(F func)
#define qiLogDebug(...)
Definition: log.hpp:69
boost::mpl::push_front< EqArguments, detail::Class & >::type EqComponentsInt
virtual TypeKind kind()
Definition: type.hxx:96
boost::mpl::pop_front< MethodArguments >::type Arguments
FunctionTypeInterface * functionType() const
Definition: anyfunction.hxx:79
#define QI_THREADSAFE_NEW(...)
Safe static initialization of variables.
Definition: atomic.hpp:252
boost::mpl::transform< Arguments, EqType< boost::mpl::_1 > >::type EqArguments
boost::function_types::function_type< EqComponents >::type type
_QI_BOUNCE_TYPE_METHODS(DefaultTypeImplMethods< S >)
#define qiLogWarning(...)
Log in warning mode.
Definition: log.hpp:102
boost::is_reference< T >::type isReference
fill_arguments(std::vector< TypeInterface * > *target)
boost::function_types::member_function_pointer< EqComponents >::type type
#define makeCall(n, argstypedecl, argstype, argsdecl, argsues, comma)
const std::vector< TypeInterface * > & argumentsType()
Definition: anyfunction.hxx:25
AnyReference bouncer(const AnyReferenceVector &vargs, R(C::*fun)(const AnyArguments &))
A function with AnyArguments as its sole argument will behave as if AnyFunction::fromDynamicFunction ...
boost::function_types::parameter_types< F >::type MethodArguments
boost::is_reference< T >::type isReference
std::vector< AnyReference > AnyReferenceVector
boost::function_types::result_type< T >::type ReturnType
boost::function_types::components< F >::type Components
boost::mpl::transform< Arguments, EqType< boost::mpl::_1 > >::type EqArguments
boost::mpl::if_< typename boost::is_fundamental< T >::type, void *, T >::type type
boost::mpl::if_< typename boost::is_fundamental< T >::type, void *, T >::type rType
const AnyFunction & prependArgument(void *value) const
Prepend extra argument value to argument list.
TypeInterface * _resultType
Definition: anyfunction.hpp:83
boost::function_types::parameter_types< F >::type Arguments
static AnyFunction fromDynamicFunction(DynamicFunction f)
static const unsigned long refMask
boost::function_types::components< F >::type Components
boost::mpl::push_front< EqComponentsInt, EqResult >::type EqComponents
boost::function_types::member_function_pointer< F >::type type
TypeInterface * typeOf()
Definition: type.hxx:91
AnyReference clone() const
void operator,(AnyReferenceCopy &g, const T &any)
AnyReference bouncerBF(const AnyReferenceVector &vargs, boost::function< R(const AnyArguments &)> f)
static FunctionTypeInterfaceEq< T, S > * make(unsigned long refMask, std::vector< TypeInterface * > argsType, TypeInterface *returnType)
static AnyReference from(const T &ref)
static AnyReference fromPtr(const T *ptr)
virtual void * clone(void *)=0
Allocate a storage and copy the value given as an argument.
EqType< Result >::rType EqResult
std::vector< TypeInterface * > _argumentsType
Definition: anyfunction.hpp:85
InfosKeyMask(const std::vector< TypeInterface * > &b, unsigned long mask)
boost::mpl::push_front< EqArguments, EqResult >::type EqComponents
boost::function_types::result_type< F >::type Result
static T * pointer(T &t)
EqType< Result >::rType EqResult
boost::function_types::result_type< F >::type Result
#define QI_GEN(f)
Definition: preproc.hpp:476
std::vector< TypeInterface * > * target
virtual void * initializeStorage(void *ptr=0)=0