From 35f8e9dc874dcb04da4466851524362d6097a2dd Mon Sep 17 00:00:00 2001 From: satoren Date: Sat, 6 Aug 2016 02:17:16 +0900 Subject: [PATCH] Tuple implement by myself at C++03 for function overloads. #43 this tuple is internal use only. --- include/kaguya/config.hpp | 3 + include/kaguya/function_tuple_def.hpp | 106 +++++++++++++++++++++++ include/kaguya/native_function.hpp | 40 ++++----- include/kaguya/native_function_cxx03.hpp | 2 + include/kaguya/utility.hpp | 1 - include/kaguya/utility_cxx03.hpp | 1 + 6 files changed, 132 insertions(+), 21 deletions(-) create mode 100644 include/kaguya/function_tuple_def.hpp diff --git a/include/kaguya/config.hpp b/include/kaguya/config.hpp index f3034eff..b07c10af 100644 --- a/include/kaguya/config.hpp +++ b/include/kaguya/config.hpp @@ -64,12 +64,15 @@ extern "C" { #endif #ifndef KAGUYA_FUNCTION_MAX_ARGS +///! max argumeent number for binding function. this define used C++03 only. #define KAGUYA_FUNCTION_MAX_ARGS 9 #endif #ifndef KAGUYA_FUNCTION_MAX_TUPLE_SIZE +///! this define used C++03 only. #define KAGUYA_FUNCTION_MAX_TUPLE_SIZE 9 #endif #ifndef KAGUYA_FUNCTION_MAX_OVERLOADS +///! this define used C++03 only. #define KAGUYA_FUNCTION_MAX_OVERLOADS KAGUYA_FUNCTION_MAX_TUPLE_SIZE #endif diff --git a/include/kaguya/function_tuple_def.hpp b/include/kaguya/function_tuple_def.hpp new file mode 100644 index 00000000..6e6c96e3 --- /dev/null +++ b/include/kaguya/function_tuple_def.hpp @@ -0,0 +1,106 @@ +// Copyright satoren +// 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) +#pragma once + +#include + +#include "kaguya/config.hpp" +#include "kaguya/utility.hpp" + +namespace kaguya +{ + namespace fntuple + { + +#if KAGUYA_USE_CPP11 + using std::tuple; + using std::get; + using std::tuple_element; + using std::tuple_size; +#else + using util::null_type; + //boost::tuple is max +#define KAGUYA_PP_STRUCT_TDEF_REP(N) KAGUYA_PP_CAT(typename A,N) = null_type +#define KAGUYA_PP_STRUCT_TEMPLATE_DEF_REPEAT(N) KAGUYA_PP_REPEAT_ARG(N,KAGUYA_PP_STRUCT_TDEF_REP) + + template + struct tuple { + }; + +#define KAGUYA_FUNCTION_TUPLE_ELEMENT(N) KAGUYA_PP_CAT(A,N) KAGUYA_PP_CAT(elem,N); +#define KAGUYA_FUNCTION_TUPLE_ELEMENT_INIT(N) KAGUYA_PP_CAT(elem,N)(KAGUYA_PP_CAT(a,N)) +#define KAGUYA_FUNCTION_TUPLE_IMPL_DEF(N) \ + template\ + struct tuple {\ + KAGUYA_PP_REPEAT(N,KAGUYA_FUNCTION_TUPLE_ELEMENT)\ + tuple(KAGUYA_PP_ARG_DEF_REPEAT(N)):KAGUYA_PP_REPEAT_ARG(N,KAGUYA_FUNCTION_TUPLE_ELEMENT_INIT){}\ + }; + + + KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_FUNCTION_TUPLE_IMPL_DEF); + + templatestruct tuple_size; + +#define KAGUYA_TUPLE_SIZE_DEF(N) \ + template< KAGUYA_PP_TEMPLATE_DEF_REPEAT(N)>\ + struct tuple_size >\ + {\ + static const size_t value = N;\ + };\ + + KAGUYA_TUPLE_SIZE_DEF(0); + KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_TUPLE_SIZE_DEF); +#undef KAGUYA_TUPLE_SIZE_DEF + + + template + struct tuple_element + { + }; +#define KAGUYA_TUPLE_ELEMENT_DEF(N) \ + template\ + struct tuple_element, true>\ + {\ + typedef arg type;\ + };\ + template\ + struct tuple_element, false>\ + : tuple_element >\ + {\ + };\ + + KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_TUPLE_ELEMENT_DEF); + +#undef KAGUYA_TUPLE_SIZE_DEF + + templatestruct tuple_get_helper; +#define KAGUYA_TUPLE_GET_DEF(N) \ + templatestruct tuple_get_helper\ + {\ + static typename tuple_element::type& get(T& t)\ + {\ + return t.KAGUYA_PP_CAT(elem, N); \ + }\ + static const typename tuple_element::type& cget(const T& t)\ + {\ + return t.KAGUYA_PP_CAT(elem, N); \ + }\ + }; + KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_TUPLE_GET_DEF); + + template + typename tuple_element::type& get(T& t) + { + return tuple_get_helper::get(t); + } + template + const typename tuple_element::type& get(const T& t) + { + return tuple_get_helper::cget(t); + } +#endif + } + +} diff --git a/include/kaguya/native_function.hpp b/include/kaguya/native_function.hpp index 16dce158..943cb4e7 100644 --- a/include/kaguya/native_function.hpp +++ b/include/kaguya/native_function.hpp @@ -16,13 +16,13 @@ #if KAGUYA_USE_CPP11 #include "kaguya/native_function_cxx11.hpp" #else -#include "kaguya/preprocess.hpp" #include "kaguya/native_function_cxx03.hpp" #endif +#include "kaguya/function_tuple_def.hpp" + namespace kaguya { - struct FunctionImpl { virtual int invoke(lua_State *state) = 0; @@ -566,13 +566,13 @@ namespace kaguya template int invoke_tuple_impl(lua_State* state, TupleType&& tuple, nativefunction::index_tuple) { - return best_match_invoke(state, std::get(tuple)...); + return best_match_invoke(state, fntuple::get(tuple)...); } template int invoke_tuple(lua_State* state, TupleType&& tuple) { typedef typename std::decay::type ttype; - typedef typename nativefunction::index_range<0, std::tuple_size::value>::type indexrange; + typedef typename nativefunction::index_range<0, fntuple::tuple_size::value>::type indexrange; return invoke_tuple_impl(state, tuple, indexrange()); } @@ -593,12 +593,12 @@ namespace kaguya } template void push_arg_typename_tuple_impl(lua_State *state, TupleType&& tuple, nativefunction::index_tuple) { - return push_arg_typename(state,std::get(tuple)...); + return push_arg_typename(state, fntuple::get(tuple)...); } templatevoid push_arg_typename_tuple(lua_State *state, TupleType&& tuple) { typedef typename std::decay::type ttype; - typedef typename nativefunction::index_range<0, std::tuple_size::value>::type indexrange; + typedef typename nativefunction::index_range<0, fntuple::tuple_size::value>::type indexrange; return push_arg_typename_tuple_impl(state,tuple, indexrange()); } @@ -610,24 +610,24 @@ namespace kaguya namespace detail { #define KAGUYA_FUNCTION_SCOREING(N) if (currentbestscore < nativefunction::MAX_OVERLOAD_SCORE) {\ - int score = nativefunction::compute_function_matching_score(state, standard::get(tuple));\ + int score = nativefunction::compute_function_matching_score(state, fntuple::get(tuple));\ if (currentbestscore < score) {\ currentbestscore = score;\ currentbestindex = N;\ }\ } #define KAGUYA_FUNCTION_INVOKE(N) if (currentbestindex == N) {\ - return nativefunction::call(state, standard::get(tuple));\ + return nativefunction::call(state, fntuple::get(tuple));\ }\ -#define KAGUYA_ARG_PUSH_TYPENAMES(N)lua_pushliteral(state, "\t\t"); lua_pushstring(state, nativefunction::argTypesName(standard::get(tuple)).c_str());lua_pushliteral(state, "\n"); +#define KAGUYA_ARG_PUSH_TYPENAMES(N)lua_pushliteral(state, "\t\t"); lua_pushstring(state, nativefunction::argTypesName(fntuple::get(tuple)).c_str());lua_pushliteral(state, "\n"); #define KAGUYA_TEMPLATE_PARAMETER(N) template #define KAGUYA_TUPLE_INVOKE_DEF(N) \ KAGUYA_TEMPLATE_PARAMETER(N)\ - int invoke_tuple(lua_State* state, standard::tuple& tuple)\ + int invoke_tuple(lua_State* state, fntuple::tuple& tuple)\ {\ - if(N==1){return nativefunction::call(state, standard::get<0>(tuple));}\ + if(N==1){return nativefunction::call(state, fntuple::get<0>(tuple));}\ int32_t currentbestscore = 0;\ int32_t currentbestindex = -1;\ KAGUYA_PP_REPEAT(N, KAGUYA_FUNCTION_SCOREING);\ @@ -635,7 +635,7 @@ namespace kaguya throw LuaTypeMismatch(); \ }\ KAGUYA_TEMPLATE_PARAMETER(N)\ - void push_arg_typename_tuple(lua_State *state,standard::tuple& tuple)\ + void push_arg_typename_tuple(lua_State *state,fntuple::tuple& tuple)\ {\ KAGUYA_PP_REPEAT(N, KAGUYA_ARG_PUSH_TYPENAMES);\ }\ @@ -666,24 +666,24 @@ namespace kaguya template - inline FunctionInvokerType > function(T f) + inline FunctionInvokerType > function(T f) { KAGUYA_STATIC_ASSERT(nativefunction::is_callable::type>::value, "argument need callable"); - return FunctionInvokerType >(standard::tuple(f)); + return FunctionInvokerType >(fntuple::tuple(f)); } template - inline FunctionInvokerType > > function(T f) + inline FunctionInvokerType > > function(T f) { - return FunctionInvokerType > >(standard::tuple >(standard::function(f))); + return FunctionInvokerType > >(fntuple::tuple >(standard::function(f))); } #if KAGUYA_USE_CPP11 template - FunctionInvokerType > overload(Functions... fns) + FunctionInvokerType > overload(Functions... fns) { - return FunctionInvokerType >(standard::tuple(fns...)); + return FunctionInvokerType >(fntuple::tuple(fns...)); } #else #define KAGUYA_DEF_TEMPLATE(N) KAGUYA_PP_CAT(typename F,N) @@ -691,9 +691,9 @@ namespace kaguya #define KAGUYA_TUPLE_ARG_DEF(N) KAGUYA_PP_CAT(f,N) #define KAGUYA_ARG_DEF(N) KAGUYA_PP_CAT(F,N) KAGUYA_PP_CAT(f,N) #define KAGUYA_FOVERLOAD_DEF(N) template\ - FunctionInvokerType > overload(KAGUYA_PP_REPEAT_ARG(N,KAGUYA_ARG_DEF))\ + FunctionInvokerType > overload(KAGUYA_PP_REPEAT_ARG(N,KAGUYA_ARG_DEF))\ {\ - typedef typename standard::tuple ttype;\ + typedef typename fntuple::tuple ttype;\ return FunctionInvokerType(ttype(KAGUYA_PP_REPEAT_ARG(N,KAGUYA_TUPLE_ARG_DEF)));\ } KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_FOVERLOAD_DEF) diff --git a/include/kaguya/native_function_cxx03.hpp b/include/kaguya/native_function_cxx03.hpp index 8f463f7b..486575f6 100644 --- a/include/kaguya/native_function_cxx03.hpp +++ b/include/kaguya/native_function_cxx03.hpp @@ -10,6 +10,8 @@ #include "kaguya/utility.hpp" #include "kaguya/object.hpp" +#include "kaguya/preprocess.hpp" + namespace kaguya { namespace nativefunction diff --git a/include/kaguya/utility.hpp b/include/kaguya/utility.hpp index 6d7e03ae..db3ff56f 100644 --- a/include/kaguya/utility.hpp +++ b/include/kaguya/utility.hpp @@ -12,7 +12,6 @@ #if KAGUYA_USE_CPP11 #include "kaguya/utility_cxx11.hpp" #else -#include "kaguya/preprocess.hpp" #include "kaguya/utility_cxx03.hpp" #endif diff --git a/include/kaguya/utility_cxx03.hpp b/include/kaguya/utility_cxx03.hpp index 04f01b1d..ecf591d8 100644 --- a/include/kaguya/utility_cxx03.hpp +++ b/include/kaguya/utility_cxx03.hpp @@ -7,6 +7,7 @@ #include #include "kaguya/config.hpp" +#include "kaguya/preprocess.hpp" namespace kaguya {