First file to eliminate need for boost_pp. 2 more to go

This commit is contained in:
Jason Turner
2011-09-12 23:08:27 -06:00
parent cc927fc6bc
commit d5e1650167

View File

@@ -4,13 +4,6 @@
// and Jason Turner (jason@emptycrate.com) // and Jason Turner (jason@emptycrate.com)
// http://www.chaiscript.com // http://www.chaiscript.com
#include <boost/preprocessor.hpp>
#define gettypeinfo(z,n,text) ti.push_back(chaiscript::detail::Get_Type_Info<Param ## n>::get());
#define casthelper(z,n,text) BOOST_PP_COMMA_IF(n) chaiscript::boxed_cast< Param ## n >(params[n])
#define trycast(z,n,text) chaiscript::boxed_cast<Param ## n>(params[n]);
#ifndef BOOST_PP_IS_ITERATING
#ifndef CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_ #ifndef CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_
#define CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_ #define CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_
@@ -46,19 +39,6 @@ namespace chaiscript
}; };
} }
}
#define BOOST_PP_ITERATION_LIMITS ( 0, 10 )
#define BOOST_PP_FILENAME_1 <chaiscript/dispatchkit/proxy_functions_detail.hpp>
#include BOOST_PP_ITERATE()
# endif
#else
# define n BOOST_PP_ITERATION()
namespace chaiscript
{
namespace dispatch namespace dispatch
{ {
namespace detail namespace detail
@@ -67,62 +47,105 @@ namespace chaiscript
* Used by Proxy_Function_Impl to return a list of all param types * Used by Proxy_Function_Impl to return a list of all param types
* it contains. * it contains.
*/ */
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) > template<typename Ret, typename ... Params>
std::vector<Type_Info> build_param_type_list(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param))) std::vector<Type_Info> build_param_type_list(Ret (*)(Params...))
{ {
std::vector<Type_Info> ti; return std::vector<Type_Info> { chaiscript::detail::Get_Type_Info<Ret>::get(),
ti.push_back(chaiscript::detail::Get_Type_Info<Ret>::get()); chaiscript::detail::Get_Type_Info<Params>::get()... };
BOOST_PP_REPEAT(n, gettypeinfo, ~)
return ti;
} }
// Forward declaration
template<typename ... Rest>
struct Try_Cast;
// implementation
template<typename Param, typename ... Rest>
struct Try_Cast<Param, Rest...>
{
static void do_try(const std::vector<Boxed_Value> &params, int generation)
{
boxed_cast<Param>(params[generation]);
Try_Cast<Rest...>::do_try(params, generation+1);
}
};
// 0th case
template<>
struct Try_Cast<>
{
static void do_try(const std::vector<Boxed_Value> &, int)
{
}
};
/**
* Used by Proxy_Function_Impl to determine if it is equivalent to another
* Proxy_Function_Impl object. This function is primarly used to prevent
* registration of two functions with the exact same signatures
*/
template<typename Ret, typename ... Params>
bool compare_types_cast(Ret (*)(Params...),
const std::vector<Boxed_Value> &params)
{
try {
Try_Cast<Params...>::do_try(params, 0);
} catch (const exception::bad_boxed_cast &) {
return false;
}
return true;
}
template<typename Ret, int count, typename ... Params>
struct Call_Func
{
template<typename ... InnerParams>
static Ret do_call(const std::function<Ret (Params...)> &f,
const std::vector<Boxed_Value> &params, InnerParams ... innerparams)
{
return Call_Func<Ret, count - 1, Params...>::do_call(f, params, innerparams..., params[sizeof...(Params) - count]);
}
};
template<typename Ret, typename ... Params>
struct Call_Func<Ret, 0, Params...>
{
template<typename ... InnerParams>
static Ret do_call(const std::function<Ret (Params...)> &f,
const std::vector<Boxed_Value> &, InnerParams ... innerparams)
{
return f(boxed_cast<Params>(innerparams)...);
}
};
/** /**
* Used by Proxy_Function_Impl to perform typesafe execution of a function. * Used by Proxy_Function_Impl to perform typesafe execution of a function.
* The function attempts to unbox each paramter to the expected type. * The function attempts to unbox each paramter to the expected type.
* if any unboxing fails the execution of the function fails and * if any unboxing fails the execution of the function fails and
* the bad_boxed_cast is passed up to the caller. * the bad_boxed_cast is passed up to the caller.
*/ */
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)> template<typename Ret, typename ... Params>
Ret call_func(const std::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))> &f, Ret call_func(const std::function<Ret (Params...)> &f,
const std::vector<Boxed_Value> &params) const std::vector<Boxed_Value> &params)
{ {
if (params.size() != n) if (params.size() == sizeof...(Params))
{ {
throw exception::arity_error(static_cast<int>(params.size()), n); return Call_Func<Ret, sizeof...(Params), Params...>::do_call(f, params);
} else { }
return f(BOOST_PP_REPEAT(n, casthelper, ~));
throw exception::arity_error(static_cast<int>(params.size()), sizeof...(Params));
}
} }
} }
/**
* Used by Proxy_Function_Impl to determine if it is equivalent to another
* Proxy_Function_Impl object. This function is primarly used to prevent
* registration of two functions with the exact same signatures
*/
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
bool compare_types_cast(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param)),
const std::vector<Boxed_Value> & BOOST_PP_IF(n, params, ))
{
try {
BOOST_PP_REPEAT(n, trycast, ~);
} catch (const exception::bad_boxed_cast &) {
return false;
} }
return true;
}
}
}
}
#undef n
#endif
#ifndef BOOST_PP_IS_ITERATING
namespace chaiscript namespace chaiscript
{ {