Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

file 126 lines (112 sloc) 3.923 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
//~ Copyright (c) 2005-2007 Redshift Software, Inc.
//~ Distributed under the Boost Software License, Version 1.0.
//~ (See accompanying file LICENSE_1_0.txt or copy at
//~ http://www.boost.org/LICENSE_1_0.txt)

#ifndef com_redshift_software_libraries_base_c_function_hpp
#define com_redshift_software_libraries_base_c_function_hpp

#include <boost/function.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/control/expr_if.hpp>
#include <boost/type_traits.hpp>
#include <boost/type_traits/function_traits.hpp>


namespace redshift { namespace base {
#ifndef RSI_BASE_MAKE_C_FUNCTION_MAX_ARITY
#define RSI_BASE_MAKE_C_FUNCTION_MAX_ARITY 9
#endif

namespace detail
{
template <typename InterfaceGUID, typename FunctionType>
struct c_function_traits
{
typedef typename boost::remove_pointer<FunctionType>::type
function_type;
typedef boost::function<function_type>
function_shunt;
typedef boost::function_traits<function_type>
function_traits;
static const int
arity = function_traits::arity;
typedef typename function_traits::result_type
result_type;
};

template <int Arity> struct c_function { };
#define RSI_LIB_BASE_C_FUNCTION(z,ARITY,d) \
template <> struct c_function<ARITY> \
{ \
template <typename InterfaceGUID, typename FunctionType> \
struct instance \
{ \
typedef instance<InterfaceGUID,FunctionType> \
self_type; \
typedef c_function_traits<InterfaceGUID,FunctionType> \
traits_type; \
typedef typename traits_type::function_traits F; \
static \
typename traits_type::function_shunt & shunt() \
{ \
static typename traits_type::function_shunt shunt_; \
return shunt_; \
} \
static \
typename traits_type::result_type \
function ( BOOST_PP_ENUM(ARITY,RSI_LIB_BASE_C_FUNCTION_ARGN,_) ) \
{ \
return (self_type::shunt()) ( \
BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(ARITY),a) \
); \
} \
}; \
};
#define RSI_LIB_BASE_C_FUNCTION_ARGN(x,n,d) \
BOOST_PP_CAT(BOOST_PP_CAT(typename F::arg,BOOST_PP_INC(n)),_type) \
BOOST_PP_CAT(a,BOOST_PP_INC(n))
BOOST_PP_REPEAT(RSI_BASE_MAKE_C_FUNCTION_MAX_ARITY,RSI_LIB_BASE_C_FUNCTION,_)
#undef RSI_LIB_BASE_C_FUNCTION
#undef RSI_LIB_BASE_C_FUNCTION_ARGN
}

/**
Returns a pointer to a C function that will call the given function
object when called. Given the possibility that one could create multiple
C functions to a single target function object type make_c_function
takes as the first template argument a type identifier to distinguish
between them. The second template argument specifies the type of
the C function created. Example:
class A
{
void some_call(int);
};
A a;
void (* cf)(int)
= make_c_function<struct call_0, void(*)(int)>(
boost::bind(A::some_call,&a,boost::_1)
);
*/
template <
typename InterfaceGUID,
typename FunctionType,
typename CallType
>
typename
detail::c_function_traits<InterfaceGUID,FunctionType>::function_type *
make_c_function(CallType call)
{
typedef detail::c_function_traits<InterfaceGUID,FunctionType> cf;
typedef
typename detail::c_function<cf::arity>
::template instance<InterfaceGUID,FunctionType>
cfi;

cfi::shunt() = call;
return &cfi::function;
}

} }

#ifdef com_redshift_software_libraries_base_p
com_redshift_software_libraries_base_p {
using ::redshift::base::make_c_function;
} p_com_redshift_software_libraries_base
#endif

#endif
Something went wrong with that request. Please try again.