Skip to content

Commit

Permalink
Tuple implement by myself at C++03 for function overloads. #43
Browse files Browse the repository at this point in the history
this tuple is internal use only.
  • Loading branch information
satoren committed Aug 5, 2016
1 parent 09ade2c commit 35f8e9d
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 21 deletions.
3 changes: 3 additions & 0 deletions include/kaguya/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
106 changes: 106 additions & 0 deletions include/kaguya/function_tuple_def.hpp
Original file line number Diff line number Diff line change
@@ -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 <string>

#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<KAGUYA_PP_STRUCT_TEMPLATE_DEF_REPEAT(KAGUYA_PP_INC(KAGUYA_FUNCTION_MAX_OVERLOADS))>
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<KAGUYA_PP_TEMPLATE_DEF_REPEAT(N)>\
struct tuple<KAGUYA_PP_TEMPLATE_ARG_REPEAT(N)> {\
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);

template<typename Tuple>struct tuple_size;

#define KAGUYA_TUPLE_SIZE_DEF(N) \
template< KAGUYA_PP_TEMPLATE_DEF_REPEAT(N)>\
struct tuple_size<tuple<KAGUYA_PP_TEMPLATE_ARG_REPEAT(N)> >\
{\
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<std::size_t remain, class result, bool flag = remain <= 0>
struct tuple_element
{
};
#define KAGUYA_TUPLE_ELEMENT_DEF(N) \
template<std::size_t remain, class arg KAGUYA_PP_TEMPLATE_DEF_REPEAT_CONCAT(N) >\
struct tuple_element<remain, tuple<arg KAGUYA_PP_TEMPLATE_ARG_REPEAT_CONCAT(N)>, true>\
{\
typedef arg type;\
};\
template<std::size_t remain, class arg KAGUYA_PP_TEMPLATE_DEF_REPEAT_CONCAT(N) >\
struct tuple_element<remain, tuple<arg KAGUYA_PP_TEMPLATE_ARG_REPEAT_CONCAT(N)>, false>\
: tuple_element<remain - 1, tuple<KAGUYA_PP_TEMPLATE_ARG_REPEAT(N)> >\
{\
};\

KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_TUPLE_ELEMENT_DEF);

#undef KAGUYA_TUPLE_SIZE_DEF

template<size_t S, typename T>struct tuple_get_helper;
#define KAGUYA_TUPLE_GET_DEF(N) \
template<typename T>struct tuple_get_helper<N,T>\
{\
static typename tuple_element<N-1, T>::type& get(T& t)\
{\
return t.KAGUYA_PP_CAT(elem, N); \
}\
static const typename tuple_element<N-1, T>::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<size_t S, typename T>
typename tuple_element<S, T>::type& get(T& t)
{
return tuple_get_helper<S + 1, T>::get(t);
}
template<size_t S, typename T>
const typename tuple_element<S, T>::type& get(const T& t)
{
return tuple_get_helper<S + 1, T>::cget(t);
}
#endif
}

}
40 changes: 20 additions & 20 deletions include/kaguya/native_function.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -566,13 +566,13 @@ namespace kaguya

template<typename TupleType, std::size_t ...S> int invoke_tuple_impl(lua_State* state, TupleType&& tuple, nativefunction::index_tuple<S...>)
{
return best_match_invoke(state, std::get<S>(tuple)...);
return best_match_invoke(state, fntuple::get<S>(tuple)...);
}
template<typename TupleType> int invoke_tuple(lua_State* state, TupleType&& tuple)
{
typedef typename std::decay<TupleType>::type ttype;

typedef typename nativefunction::index_range<0, std::tuple_size<ttype>::value>::type indexrange;
typedef typename nativefunction::index_range<0, fntuple::tuple_size<ttype>::value>::type indexrange;

return invoke_tuple_impl(state, tuple, indexrange());
}
Expand All @@ -593,12 +593,12 @@ namespace kaguya
}
template<typename TupleType, std::size_t ...S> void push_arg_typename_tuple_impl(lua_State *state, TupleType&& tuple, nativefunction::index_tuple<S...>)
{
return push_arg_typename(state,std::get<S>(tuple)...);
return push_arg_typename(state, fntuple::get<S>(tuple)...);
}
template<typename TupleType>void push_arg_typename_tuple(lua_State *state, TupleType&& tuple)
{
typedef typename std::decay<TupleType>::type ttype;
typedef typename nativefunction::index_range<0, std::tuple_size<ttype>::value>::type indexrange;
typedef typename nativefunction::index_range<0, fntuple::tuple_size<ttype>::value>::type indexrange;

return push_arg_typename_tuple_impl(state,tuple, indexrange());
}
Expand All @@ -610,32 +610,32 @@ 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<N - 1>(tuple));\
int score = nativefunction::compute_function_matching_score(state, fntuple::get<N - 1>(tuple));\
if (currentbestscore < score) {\
currentbestscore = score;\
currentbestindex = N;\
}\
}
#define KAGUYA_FUNCTION_INVOKE(N) if (currentbestindex == N) {\
return nativefunction::call(state, standard::get<N - 1>(tuple));\
return nativefunction::call(state, fntuple::get<N - 1>(tuple));\
}\


#define KAGUYA_ARG_PUSH_TYPENAMES(N)lua_pushliteral(state, "\t\t"); lua_pushstring(state, nativefunction::argTypesName(standard::get<N-1>(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<N-1>(tuple)).c_str());lua_pushliteral(state, "\n");
#define KAGUYA_TEMPLATE_PARAMETER(N) template<KAGUYA_PP_TEMPLATE_DEF_REPEAT(N)>
#define KAGUYA_TUPLE_INVOKE_DEF(N) \
KAGUYA_TEMPLATE_PARAMETER(N)\
int invoke_tuple(lua_State* state, standard::tuple<KAGUYA_PP_TEMPLATE_ARG_REPEAT(N)>& tuple)\
int invoke_tuple(lua_State* state, fntuple::tuple<KAGUYA_PP_TEMPLATE_ARG_REPEAT(N)>& 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);\
KAGUYA_PP_REPEAT(N, KAGUYA_FUNCTION_INVOKE);\
throw LuaTypeMismatch(); \
}\
KAGUYA_TEMPLATE_PARAMETER(N)\
void push_arg_typename_tuple(lua_State *state,standard::tuple<KAGUYA_PP_TEMPLATE_ARG_REPEAT(N)>& tuple)\
void push_arg_typename_tuple(lua_State *state,fntuple::tuple<KAGUYA_PP_TEMPLATE_ARG_REPEAT(N)>& tuple)\
{\
KAGUYA_PP_REPEAT(N, KAGUYA_ARG_PUSH_TYPENAMES);\
}\
Expand Down Expand Up @@ -666,34 +666,34 @@ namespace kaguya


template<typename T>
inline FunctionInvokerType<standard::tuple<T> > function(T f)
inline FunctionInvokerType<fntuple::tuple<T> > function(T f)
{
KAGUYA_STATIC_ASSERT(nativefunction::is_callable<typename traits::decay<T>::type>::value, "argument need callable");
return FunctionInvokerType<standard::tuple<T> >(standard::tuple<T>(f));
return FunctionInvokerType<fntuple::tuple<T> >(fntuple::tuple<T>(f));
}

template<typename FTYPE, typename T>
inline FunctionInvokerType<standard::tuple<standard::function<FTYPE> > > function(T f)
inline FunctionInvokerType<fntuple::tuple<standard::function<FTYPE> > > function(T f)
{
return FunctionInvokerType<standard::tuple<standard::function<FTYPE> > >(standard::tuple<standard::function<FTYPE> >(standard::function<FTYPE>(f)));
return FunctionInvokerType<fntuple::tuple<standard::function<FTYPE> > >(fntuple::tuple<standard::function<FTYPE> >(standard::function<FTYPE>(f)));
}
#if KAGUYA_USE_CPP11


template<typename... Functions>
FunctionInvokerType<standard::tuple<Functions...> > overload(Functions... fns)
FunctionInvokerType<fntuple::tuple<Functions...> > overload(Functions... fns)
{
return FunctionInvokerType<standard::tuple<Functions...> >(standard::tuple<Functions...>(fns...));
return FunctionInvokerType<fntuple::tuple<Functions...> >(fntuple::tuple<Functions...>(fns...));
}
#else
#define KAGUYA_DEF_TEMPLATE(N) KAGUYA_PP_CAT(typename F,N)
#define KAGUYA_TEMPLATE_ARG_DEF(N) KAGUYA_PP_CAT(F,N)
#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<KAGUYA_PP_REPEAT_ARG(N,KAGUYA_DEF_TEMPLATE)>\
FunctionInvokerType<standard::tuple<KAGUYA_PP_REPEAT_ARG(N,KAGUYA_TEMPLATE_ARG_DEF)> > overload(KAGUYA_PP_REPEAT_ARG(N,KAGUYA_ARG_DEF))\
FunctionInvokerType<fntuple::tuple<KAGUYA_PP_REPEAT_ARG(N,KAGUYA_TEMPLATE_ARG_DEF)> > overload(KAGUYA_PP_REPEAT_ARG(N,KAGUYA_ARG_DEF))\
{\
typedef typename standard::tuple<KAGUYA_PP_REPEAT_ARG(N,KAGUYA_TEMPLATE_ARG_DEF)> ttype;\
typedef typename fntuple::tuple<KAGUYA_PP_REPEAT_ARG(N,KAGUYA_TEMPLATE_ARG_DEF)> ttype;\
return FunctionInvokerType<ttype>(ttype(KAGUYA_PP_REPEAT_ARG(N,KAGUYA_TUPLE_ARG_DEF)));\
}
KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_FOVERLOAD_DEF)
Expand Down
2 changes: 2 additions & 0 deletions include/kaguya/native_function_cxx03.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "kaguya/utility.hpp"
#include "kaguya/object.hpp"

#include "kaguya/preprocess.hpp"

namespace kaguya
{
namespace nativefunction
Expand Down
1 change: 0 additions & 1 deletion include/kaguya/utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#if KAGUYA_USE_CPP11
#include "kaguya/utility_cxx11.hpp"
#else
#include "kaguya/preprocess.hpp"
#include "kaguya/utility_cxx03.hpp"
#endif

Expand Down
1 change: 1 addition & 0 deletions include/kaguya/utility_cxx03.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <string>

#include "kaguya/config.hpp"
#include "kaguya/preprocess.hpp"

namespace kaguya
{
Expand Down

0 comments on commit 35f8e9d

Please sign in to comment.