Chris@16
|
1 /*=============================================================================
|
Chris@16
|
2 Copyright (c) 2005-2006 Joao Abecasis
|
Chris@16
|
3 Copyright (c) 2006-2007 Tobias Schwinger
|
Chris@16
|
4
|
Chris@16
|
5 Use modification and distribution are subject to the Boost Software
|
Chris@16
|
6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 http://www.boost.org/LICENSE_1_0.txt).
|
Chris@16
|
8 ==============================================================================*/
|
Chris@16
|
9
|
Chris@16
|
10 #if !defined(BOOST_FUSION_FUNCTIONAL_INVOCATION_INVOKE_PROCEDURE_HPP_INCLUDED)
|
Chris@16
|
11 #if !defined(BOOST_PP_IS_ITERATING)
|
Chris@16
|
12
|
Chris@16
|
13 #include <boost/preprocessor/cat.hpp>
|
Chris@16
|
14 #include <boost/preprocessor/iteration/iterate.hpp>
|
Chris@16
|
15 #include <boost/preprocessor/arithmetic/dec.hpp>
|
Chris@16
|
16 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
Chris@16
|
17 #include <boost/preprocessor/repetition/enum.hpp>
|
Chris@16
|
18 #include <boost/preprocessor/repetition/enum_shifted.hpp>
|
Chris@16
|
19 #include <boost/preprocessor/repetition/enum_params.hpp>
|
Chris@16
|
20 #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
|
Chris@16
|
21
|
Chris@16
|
22 #include <boost/type_traits/remove_reference.hpp>
|
Chris@16
|
23
|
Chris@16
|
24 #include <boost/mpl/front.hpp>
|
Chris@16
|
25
|
Chris@16
|
26 #include <boost/function_types/is_callable_builtin.hpp>
|
Chris@16
|
27 #include <boost/function_types/is_member_function_pointer.hpp>
|
Chris@16
|
28 #include <boost/function_types/parameter_types.hpp>
|
Chris@16
|
29
|
Chris@16
|
30 #include <boost/fusion/support/category_of.hpp>
|
Chris@16
|
31 #include <boost/fusion/sequence/intrinsic/at.hpp>
|
Chris@16
|
32 #include <boost/fusion/sequence/intrinsic/size.hpp>
|
Chris@16
|
33 #include <boost/fusion/sequence/intrinsic/begin.hpp>
|
Chris@16
|
34 #include <boost/fusion/iterator/next.hpp>
|
Chris@16
|
35 #include <boost/fusion/iterator/deref.hpp>
|
Chris@16
|
36 #include <boost/fusion/functional/invocation/limits.hpp>
|
Chris@16
|
37 #include <boost/fusion/functional/invocation/detail/that_ptr.hpp>
|
Chris@16
|
38
|
Chris@16
|
39 namespace boost { namespace fusion
|
Chris@16
|
40 {
|
Chris@16
|
41 namespace result_of
|
Chris@16
|
42 {
|
Chris@16
|
43 template <typename Function, class Sequence> struct invoke_procedure
|
Chris@16
|
44 {
|
Chris@16
|
45 typedef void type;
|
Chris@16
|
46 };
|
Chris@16
|
47 }
|
Chris@16
|
48
|
Chris@16
|
49 template <typename Function, class Sequence>
|
Chris@16
|
50 inline void invoke_procedure(Function, Sequence &);
|
Chris@16
|
51
|
Chris@16
|
52 template <typename Function, class Sequence>
|
Chris@16
|
53 inline void invoke_procedure(Function, Sequence const &);
|
Chris@16
|
54
|
Chris@16
|
55 //----- ---- --- -- - - - -
|
Chris@16
|
56
|
Chris@16
|
57 namespace detail
|
Chris@16
|
58 {
|
Chris@16
|
59 namespace ft = function_types;
|
Chris@16
|
60
|
Chris@16
|
61 template<
|
Chris@16
|
62 typename Function, class Sequence,
|
Chris@16
|
63 int N = result_of::size<Sequence>::value,
|
Chris@16
|
64 bool MFP = ft::is_member_function_pointer<Function>::value,
|
Chris@16
|
65 bool RandomAccess = traits::is_random_access<Sequence>::value
|
Chris@16
|
66 >
|
Chris@16
|
67 struct invoke_procedure_impl;
|
Chris@16
|
68
|
Chris@16
|
69 #define BOOST_PP_FILENAME_1 \
|
Chris@16
|
70 <boost/fusion/functional/invocation/invoke_procedure.hpp>
|
Chris@16
|
71 #define BOOST_PP_ITERATION_LIMITS \
|
Chris@16
|
72 (0, BOOST_FUSION_INVOKE_PROCEDURE_MAX_ARITY)
|
Chris@16
|
73 #include BOOST_PP_ITERATE()
|
Chris@16
|
74
|
Chris@16
|
75 }
|
Chris@16
|
76
|
Chris@16
|
77 template <typename Function, class Sequence>
|
Chris@16
|
78 inline void invoke_procedure(Function f, Sequence & s)
|
Chris@16
|
79 {
|
Chris@16
|
80 detail::invoke_procedure_impl<
|
Chris@16
|
81 typename boost::remove_reference<Function>::type,Sequence
|
Chris@16
|
82 >::call(f,s);
|
Chris@16
|
83 }
|
Chris@16
|
84
|
Chris@16
|
85 template <typename Function, class Sequence>
|
Chris@16
|
86 inline void invoke_procedure(Function f, Sequence const & s)
|
Chris@16
|
87 {
|
Chris@16
|
88 detail::invoke_procedure_impl<
|
Chris@16
|
89 typename boost::remove_reference<Function>::type,Sequence const
|
Chris@16
|
90 >::call(f,s);
|
Chris@16
|
91 }
|
Chris@16
|
92
|
Chris@16
|
93 }}
|
Chris@16
|
94
|
Chris@16
|
95 #define BOOST_FUSION_FUNCTIONAL_INVOCATION_INVOKE_PROCEDURE_HPP_INCLUDED
|
Chris@16
|
96 #else // defined(BOOST_PP_IS_ITERATING)
|
Chris@16
|
97 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
98 //
|
Chris@16
|
99 // Preprocessor vertical repetition code
|
Chris@16
|
100 //
|
Chris@16
|
101 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
102 #define N BOOST_PP_ITERATION()
|
Chris@16
|
103
|
Chris@16
|
104 #define M(z,j,data) fusion::at_c<j>(s)
|
Chris@16
|
105
|
Chris@16
|
106 template <typename Function, class Sequence>
|
Chris@16
|
107 struct invoke_procedure_impl<Function,Sequence,N,false,true>
|
Chris@16
|
108 {
|
Chris@16
|
109
|
Chris@16
|
110 #if N > 0
|
Chris@16
|
111
|
Chris@16
|
112 static inline void call(Function & f, Sequence & s)
|
Chris@16
|
113 {
|
Chris@16
|
114 f(BOOST_PP_ENUM(N,M,~));
|
Chris@16
|
115 }
|
Chris@16
|
116
|
Chris@16
|
117 #else
|
Chris@16
|
118
|
Chris@16
|
119 static inline void call(Function & f, Sequence & /*s*/)
|
Chris@16
|
120 {
|
Chris@16
|
121 f();
|
Chris@16
|
122 }
|
Chris@16
|
123
|
Chris@16
|
124 #endif
|
Chris@16
|
125
|
Chris@16
|
126 };
|
Chris@16
|
127
|
Chris@16
|
128 #if N > 0
|
Chris@16
|
129 template <typename Function, class Sequence>
|
Chris@16
|
130 struct invoke_procedure_impl<Function,Sequence,N,true,true>
|
Chris@16
|
131 {
|
Chris@16
|
132 static inline void call(Function & f, Sequence & s)
|
Chris@16
|
133 {
|
Chris@16
|
134 (that_ptr<typename mpl::front<
|
Chris@16
|
135 ft::parameter_types<Function> >::type
|
Chris@16
|
136 >::get(fusion::at_c<0>(s))->*f)(BOOST_PP_ENUM_SHIFTED(N,M,~));
|
Chris@16
|
137 }
|
Chris@16
|
138 };
|
Chris@16
|
139 #endif
|
Chris@16
|
140
|
Chris@16
|
141 #undef M
|
Chris@16
|
142
|
Chris@16
|
143 #define M(z,j,data) \
|
Chris@16
|
144 typedef typename result_of::next< BOOST_PP_CAT(I,BOOST_PP_DEC(j)) \
|
Chris@16
|
145 >::type I ## j ; \
|
Chris@16
|
146 I##j i##j = fusion::next(BOOST_PP_CAT(i,BOOST_PP_DEC(j)));
|
Chris@16
|
147
|
Chris@16
|
148 template <typename Function, class Sequence>
|
Chris@16
|
149 struct invoke_procedure_impl<Function,Sequence,N,false,false>
|
Chris@16
|
150 {
|
Chris@16
|
151
|
Chris@16
|
152 #if N > 0
|
Chris@16
|
153
|
Chris@16
|
154 static inline void call(Function & f, Sequence & s)
|
Chris@16
|
155 {
|
Chris@16
|
156 typedef typename result_of::begin<Sequence>::type I0;
|
Chris@16
|
157 I0 i0 = fusion::begin(s);
|
Chris@16
|
158 BOOST_PP_REPEAT_FROM_TO(1,N,M,~)
|
Chris@16
|
159 f( BOOST_PP_ENUM_PARAMS(N,*i) );
|
Chris@16
|
160 }
|
Chris@16
|
161
|
Chris@16
|
162 #else
|
Chris@16
|
163 static inline void call(Function & f, Sequence & /*s*/)
|
Chris@16
|
164 {
|
Chris@16
|
165 f();
|
Chris@16
|
166 }
|
Chris@16
|
167
|
Chris@16
|
168 #endif
|
Chris@16
|
169
|
Chris@16
|
170 };
|
Chris@16
|
171
|
Chris@16
|
172 #if N > 0
|
Chris@16
|
173 template <typename Function, class Sequence>
|
Chris@16
|
174 struct invoke_procedure_impl<Function,Sequence,N,true,false>
|
Chris@16
|
175 {
|
Chris@16
|
176 static inline void call(Function & f, Sequence & s)
|
Chris@16
|
177 {
|
Chris@16
|
178 typedef typename result_of::begin<Sequence>::type I0;
|
Chris@16
|
179 I0 i0 = fusion::begin(s);
|
Chris@16
|
180 BOOST_PP_REPEAT_FROM_TO(1,N,M,~)
|
Chris@16
|
181
|
Chris@16
|
182 (that_ptr<typename mpl::front<
|
Chris@16
|
183 ft::parameter_types<Function> >::type
|
Chris@16
|
184 >::get(*i0)->*f)(BOOST_PP_ENUM_SHIFTED_PARAMS(N,*i));
|
Chris@16
|
185 }
|
Chris@16
|
186 };
|
Chris@16
|
187 #endif
|
Chris@16
|
188
|
Chris@16
|
189 #undef M
|
Chris@16
|
190
|
Chris@16
|
191 #undef N
|
Chris@16
|
192 #endif // defined(BOOST_PP_IS_ITERATING)
|
Chris@16
|
193 #endif
|
Chris@16
|
194
|