28 #ifndef INCLUDED_GenericCaller_h_GUID_C49A7DEE_89E6_478D_627A_CFFB9ED39EAC
29 #define INCLUDED_GenericCaller_h_GUID_C49A7DEE_89E6_478D_627A_CFFB9ED39EAC
35 #include <boost/preprocessor/cat.hpp>
36 #include <boost/preprocessor/if.hpp>
37 #include <boost/preprocessor/enum.hpp>
38 #include <boost/preprocessor/enum_params.hpp>
39 #include <boost/preprocessor/repeat.hpp>
40 #include <boost/preprocessor/facilities/empty.hpp>
42 #include <boost/function_types/function_arity.hpp>
43 #include <boost/function_types/result_type.hpp>
44 #include <boost/function_types/parameter_types.hpp>
45 #include <boost/type_traits/is_void.hpp>
46 #include <boost/type_traits/is_same.hpp>
47 #include <boost/type_traits/is_pointer.hpp>
48 #include <boost/type_traits/is_function.hpp>
49 #include <boost/type_traits/remove_cv.hpp>
50 #include <boost/type_traits/remove_reference.hpp>
51 #include <boost/type_traits/remove_pointer.hpp>
53 #include <boost/mpl/at.hpp>
54 #include <boost/mpl/int.hpp>
55 #include <boost/mpl/next_prior.hpp>
57 #include <boost/static_assert.hpp>
62 #ifndef OSVR_UTIL_CALLER_MAX_ARITY
63 #define OSVR_UTIL_CALLER_MAX_ARITY 3
68 #ifndef OSVR_DOXYGEN_EXTERNAL
69 namespace functor_trampolines {
70 #endif // ifndef OSVR_DOXYGEN_EXTERNAL
86 BOOST_CONSTEXPR_OR_CONST this_last_t
this_last = {};
92 #ifndef OSVR_DOXYGEN_EXTERNAL
97 template <
typename F,
int C>
struct param_at {
99 typedef typename boost::function_types::parameter_types<F>::type
104 typename boost::mpl::at<ParamTypes,
105 boost::mpl::int_<C> >::type type;
117 template <
typename ThisLocation,
int Arity,
int Return>
121 #define OSVR_PARAM_STEM p
125 #define OSVR_MAKE_PARAMLIST(Z, N, unused) \
126 typename param_at<FPtr, N>::type BOOST_PP_CAT(OSVR_PARAM_STEM, N)
131 #define OSVR_RETURNTYPE(R) \
132 BOOST_PP_IF(R, typename boost::function_types::result_type<FPtr>::type, \
138 #define OSVR_RETURNSTATEMENT(R) BOOST_PP_IF(R, return, BOOST_PP_EMPTY())
145 #define OSVR_MAKE_CALLERS(Z, ARITY, RETURNS) \
146 template <> struct Caller<this_last_t, ARITY, RETURNS> { \
147 template <typename FPtr, typename F> struct Specialized { \
148 static OSVR_RETURNTYPE(RETURNS) \
149 call(BOOST_PP_ENUM(ARITY, OSVR_MAKE_PARAMLIST, ~) \
150 BOOST_PP_COMMA_IF(ARITY) void *functor) { \
151 F *o = static_cast<F *>(functor); \
152 OSVR_RETURNSTATEMENT(RETURNS) (*o)( \
153 BOOST_PP_ENUM_PARAMS(ARITY, OSVR_PARAM_STEM)); \
157 template <> struct Caller<this_first_t, ARITY, RETURNS> { \
158 template <typename FPtr, typename F> \
159 static OSVR_RETURNTYPE(RETURNS) \
160 call(void *functor BOOST_PP_COMMA_IF(ARITY) \
161 BOOST_PP_ENUM(ARITY, OSVR_MAKE_PARAMLIST, ~)) { \
162 F *o = static_cast<F *>(functor); \
163 OSVR_RETURNSTATEMENT(RETURNS) (*o)( \
164 BOOST_PP_ENUM_PARAMS(ARITY, OSVR_PARAM_STEM)); \
168 BOOST_PP_REPEAT(OSVR_UTIL_CALLER_MAX_ARITY, OSVR_MAKE_CALLERS, 0)
170 BOOST_PP_REPEAT(OSVR_UTIL_CALLER_MAX_ARITY, OSVR_MAKE_CALLERS, 1)
172 #undef OSVR_MAKE_CALLERS
173 #undef OSVR_RETURNSTATEMENT
174 #undef OSVR_RETURNTYPE
175 #undef OSVR_MAKE_PARAMLIST
176 #undef OSVR_PARAM_STEM
177 template <
typename FunctionPtr,
typename FunctionObjectType,
181 typename ThisLocation>
182 struct ComputeGenericCaller {
184 typedef typename boost::remove_cv<
185 typename boost::remove_reference<ThisLocation>::type>::type
186 UnqualifiedThisLocation;
188 BOOST_STATIC_ASSERT_MSG(
189 (boost::is_same<UnqualifiedThisLocation,
190 this_first_t>::value ||
191 boost::is_same<UnqualifiedThisLocation,
192 this_last_t>::value),
193 "ThisLocation must be either this_last_t or this_first_t");
194 BOOST_STATIC_ASSERT_MSG(
195 !(boost::is_pointer<FunctionObjectType>::value),
196 "FunctionObjectType must be the type of your function "
198 BOOST_STATIC_ASSERT_MSG(
199 boost::is_function<
typename boost::remove_pointer<
200 FunctionPtr>::type>::value &&
201 boost::is_pointer<FunctionPtr>::value,
202 "FunctionPtr must be a function pointer type");
203 #endif // OSVR_DOXYGEN
207 typedef typename boost::mpl::prior<
208 boost::function_types::function_arity<FunctionPtr> >::type
213 boost::is_void<
typename boost::function_types::result_type<
215 boost::mpl::int_<0>, boost::mpl::int_<1> >::type Returns;
218 typedef detail::Caller<UnqualifiedThisLocation, Arity::value,
219 Returns::value> GeneralResult;
222 typedef typename GeneralResult::template Specialized<
223 FunctionPtr, FunctionObjectType> type;
226 #endif // ifndef OSVR_DOXYGEN_EXTERNAL
239 template <
typename FunctionPtr,
typename FunctionObjectType,
240 typename ThisLocation>
242 : detail::ComputeGenericCaller<FunctionPtr, FunctionObjectType,
243 ThisLocation>::type {};
257 template <
typename FunctionPtr,
typename FunctionObjectType,
258 typename ThisLocation>
262 return &CallerType::call;
272 template <
typename FunctionPtr,
typename FunctionObjectType,
273 typename ThisLocation>
276 return getCaller<FunctionPtr, FunctionObjectType, ThisLocation>();
292 template <
typename FunctionPtr,
typename FunctionObjectType,
293 typename ThisLocation>
294 inline FunctionPtr
getCaller( FunctionObjectType
const *, ThisLocation
const &) {
297 return getCaller<FunctionPtr, FunctionObjectType, ThisLocation>();
299 #ifndef OSVR_DOXYGEN_EXTERNAL
304 using functor_trampolines::GenericCaller;
306 using functor_trampolines::this_first_t;
308 using functor_trampolines::this_last_t;
310 #endif // ifndef OSVR_DOXYGEN_EXTERNAL
315 #endif // INCLUDED_GenericCaller_h_GUID_C49A7DEE_89E6_478D_627A_CFFB9ED39EAC
BOOST_CONSTEXPR_OR_CONST this_last_t this_last
Pass as an argument to a getCaller() overload to indicate the last parameter of the function contains...
The main namespace for all C++ elements of the framework, internal and external.
Tag type indicating the last parameter of the function contains the "this" pointer.
Tag type indicating the first parameter of the function contains the "this" pointer.
FunctionPtr getCaller()
Get a generic functor caller: a pointer to a function that will call an object of your specific funct...
t_< detail::if_impl< Args...>> if_
FunctionPtr getCaller(FunctionObjectType const *, ThisLocation const &)
Get a generic functor caller. Pass a pointer to a function object and specify the location of "this" ...
Struct containing a single static function member named "call" that serves as a converter from a func...
BOOST_CONSTEXPR_OR_CONST this_first_t this_first
Pass as an argument to a getCaller() overload to indicate the first parameter of the function contain...