FireBreath  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Pages
MethodConverter.h
1 /**********************************************************\
2 Original Author: Georg Fritzsche
3 Generated on: 2010-02-03
4 License: Dual license model; choose one of two:
5  New BSD License
6  http://www.opensource.org/licenses/bsd-license.php
7  - or -
8  GNU Lesser General Public License, version 2.1
9  http://www.gnu.org/licenses/lgpl-2.1.html
10 
11 Copyright 2009 Georg Fritzsche, Firebreath development team
12 \**********************************************************/
13 
14 
15 #pragma once
16 #ifndef METHOD_CONVERTER_H
17 #define METHOD_CONVERTER_H
18 
19 #if defined(_MSC_VER)
20 # pragma once
21 #endif
22 
23 #include <boost/preprocessor/repetition.hpp>
24 #include <boost/preprocessor/cat.hpp>
25 #include <boost/preprocessor/arithmetic/sub.hpp>
26 #include <boost/preprocessor/arithmetic/add.hpp>
27 #include <boost/preprocessor/comparison/equal.hpp>
28 #include <boost/preprocessor/comparison/greater.hpp>
29 #include <boost/function.hpp>
30 #include <boost/bind.hpp>
31 #include "ConverterUtils.h"
32 
33 #define _FB_MW_TPL(z, n, data) typename T##n
34 #define _FB_MW_Tn(z, n, data) T##n
35 #define _FB_MW_TLAST(n) BOOST_PP_CAT(T, BOOST_PP_SUB(n,1))
36 
37 #define _FB_MW_CNLARG(n) convertArgumentSoft<typename plain_type<T##n>::type>(in, BOOST_PP_ADD(n,1))
38 #define _FB_MW_CLARG(n) convertLastArgument<TLast>(in, BOOST_PP_ADD(n,1))
39 #define _FB_MW_CARGS(z, n, t) BOOST_PP_IF(BOOST_PP_EQUAL(n, BOOST_PP_SUB(t,1)), _FB_MW_CLARG(n), _FB_MW_CNLARG(n))
40 #define _FB_MW_TLASTDEF(n) typedef typename plain_type<_FB_MW_TLAST(n)>::type TLast;
41 
42 #define _FB_METHOD_WRAPPER(z, n, data) \
43  template<typename C, typename R \
44  BOOST_PP_COMMA_IF(BOOST_PP_GREATER(n,0)) \
45  BOOST_PP_ENUM(n, _FB_MW_TPL, 0), typename F> \
46  struct method_wrapper##n \
47  { \
48  typedef FB::variant result_type; \
49  F f; \
50  method_wrapper##n(F f) : f(f) {} \
51  FB::variant operator()(C* instance, const FB::VariantList& in) \
52  { \
53  BOOST_PP_IF(BOOST_PP_GREATER(n,0), _FB_MW_TLASTDEF(n), BOOST_PP_EMPTY()) \
54  return (instance->*f)( \
55  BOOST_PP_ENUM(n, _FB_MW_CARGS, n) \
56  ); \
57  } \
58  }; \
59  template<typename C \
60  BOOST_PP_COMMA_IF(BOOST_PP_GREATER(n,0)) \
61  BOOST_PP_ENUM(n, _FB_MW_TPL, 0), typename F> \
62  struct method_wrapper##n<C, void \
63  BOOST_PP_COMMA_IF(BOOST_PP_GREATER(n,0)) \
64  BOOST_PP_ENUM(n, _FB_MW_Tn, 0), F> \
65  { \
66  typedef FB::variant result_type; \
67  F f; \
68  method_wrapper##n(F f) : f(f) {} \
69  FB::variant operator()(C* instance, const FB::VariantList& in) \
70  { \
71  BOOST_PP_IF(BOOST_PP_GREATER(n,0), _FB_MW_TLASTDEF(n), BOOST_PP_EMPTY()) \
72  (instance->*f)( \
73  BOOST_PP_ENUM(n, _FB_MW_CARGS, n) \
74  ); \
75  return FB::variant(); \
76  } \
77  };
78 
79 #define _FB_MAKE_METHOD(z, n, data) \
80  template<class C, class R \
81  BOOST_PP_COMMA_IF(BOOST_PP_GREATER(n,0)) \
82  BOOST_PP_ENUM(n, _FB_MW_TPL, 0)> \
83  inline FB::CallMethodFunctor \
84  make_method(C* instance, R (C::*function)( \
85  BOOST_PP_ENUM(n, _FB_MW_Tn, 0))) \
86  { \
87  return boost::bind( \
88  FB::detail::methods::method_wrapper##n<C, R \
89  BOOST_PP_COMMA_IF(BOOST_PP_GREATER(n,0)) \
90  BOOST_PP_ENUM(n, _FB_MW_Tn, 0) \
91  , R (C::*)(BOOST_PP_ENUM(n, _FB_MW_Tn, 0))>(function), \
92  instance, _1); \
93  } \
94  template<class C, class R \
95  BOOST_PP_COMMA_IF(BOOST_PP_GREATER(n,0)) \
96  BOOST_PP_ENUM(n, _FB_MW_TPL, 0)> \
97  inline FB::CallMethodFunctor \
98  make_method(C* instance, R (C::*function)( \
99  BOOST_PP_ENUM(n, _FB_MW_Tn, 0)) const) \
100  { \
101  return boost::bind(FB::detail::methods::method_wrapper##n<C, R \
102  BOOST_PP_COMMA_IF(BOOST_PP_GREATER(n,0)) \
103  BOOST_PP_ENUM(n, _FB_MW_Tn, 0) \
104  , R (C::*)(BOOST_PP_ENUM(n, _FB_MW_Tn, 0)) const>(function), \
105  instance, _1); \
106  }
107 
108 namespace FB
109 {
110  namespace detail { namespace methods
111  {
112  using FB::detail::plain_type;
113  using FB::convertArgumentSoft;
114 
115  BOOST_PP_REPEAT(50, _FB_METHOD_WRAPPER, BOOST_PP_EMPTY())
116 
117  } } // namespace detail::methods
118 
119  BOOST_PP_REPEAT(50, _FB_MAKE_METHOD, BOOST_PP_EMPTY())
120 
121 } // namespace FB
122 
123 #undef _FB_METHOD_WRAPPER
124 #undef _FB_MAKE_METHOD
125 #undef _FB_MW_TPL
126 #undef _FB_MW_Tn
127 #undef _FB_MW_TLAST
128 
129 #undef _FB_MW_CNLARG
130 #undef _FB_MW_CLARG
131 #undef _FB_MW_CARGS
132 #undef _FB_MW_TLASTDEF
133 
134 #endif //METHOD_CONVERTER_H