mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Put detail classes not part of the interface into deeper namespaces to clear up the to level.
This commit is contained in:
parent
16c6f62fe3
commit
3d7a93ae1c
|
@ -26,6 +26,7 @@
|
|||
#include <iostream>
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
namespace debug {
|
||||
inline std::string dump_types(lua_State* L) {
|
||||
std::string visual;
|
||||
|
@ -46,6 +47,7 @@ inline void print_stack(lua_State* L) {
|
|||
inline void print_section(const std::string& message, lua_State* L) {
|
||||
std::cout << "-- " << message << " -- [ " << dump_types(L) << " ]" << std::endl;
|
||||
}
|
||||
} // detail
|
||||
} // debug
|
||||
} // sol
|
||||
|
||||
|
|
|
@ -34,6 +34,14 @@
|
|||
#include <memory>
|
||||
|
||||
namespace sol {
|
||||
template <typename Sig, typename... Args>
|
||||
struct function_packer : std::tuple<Args...> { using std::tuple<Args...>::tuple; };
|
||||
|
||||
template <typename Sig, typename... Args>
|
||||
function_packer<Sig, Args...> function_pack( Args&&... args ) {
|
||||
return function_packer<Sig, Args...>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
class function : public reference {
|
||||
private:
|
||||
void luacall( std::ptrdiff_t argcount, std::ptrdiff_t resultcount ) const {
|
||||
|
@ -218,7 +226,7 @@ struct pusher<function_sig<Sigs...>> {
|
|||
|
||||
template<typename R, typename... Args, typename Fx, typename = std::result_of_t<Fx(Args...)>>
|
||||
static void set_memfx(types<R(Args...)> t, lua_State* L, Fx&& fx) {
|
||||
typedef std::decay_t<Unwrapped<Unqualified<Fx>>> raw_fx_t;
|
||||
typedef std::decay_t<meta::Unwrapped<meta::Unqualified<Fx>>> raw_fx_t;
|
||||
typedef R(* fx_ptr_t)(Args...);
|
||||
typedef std::is_convertible<raw_fx_t, fx_ptr_t> is_convertible;
|
||||
set_isconvertible_fx(is_convertible(), t, L, std::forward<Fx>(fx));
|
||||
|
@ -226,7 +234,7 @@ struct pusher<function_sig<Sigs...>> {
|
|||
|
||||
template<typename Fx>
|
||||
static void set_memfx(types<>, lua_State* L, Fx&& fx) {
|
||||
typedef Unwrapped<Unqualified<Fx>> fx_t;
|
||||
typedef meta::Unwrapped<meta::Unqualified<Fx>> fx_t;
|
||||
set(L, &fx_t::operator(), std::forward<Fx>(fx));
|
||||
}
|
||||
|
||||
|
@ -242,13 +250,13 @@ struct pusher<function_sig<Sigs...>> {
|
|||
|
||||
template<typename... Args, typename R, typename C, typename T>
|
||||
static void set(lua_State* L, R (C::*memfxptr)(Args...), T&& obj) {
|
||||
typedef Bool<is_specialization_of<Unqualified<T>, std::reference_wrapper>::value || std::is_pointer<T>::value> is_reference;
|
||||
typedef meta::Bool<meta::is_specialization_of<meta::Unqualified<T>, std::reference_wrapper>::value || std::is_pointer<T>::value> is_reference;
|
||||
set_reference_fx(is_reference(), L, memfxptr, std::forward<T>(obj));
|
||||
}
|
||||
|
||||
template<typename Sig, typename C, typename T>
|
||||
static void set(lua_State* L, Sig C::* memfxptr, T&& obj) {
|
||||
typedef Bool<is_specialization_of<Unqualified<T>, std::reference_wrapper>::value || std::is_pointer<T>::value> is_reference;
|
||||
typedef meta::Bool<meta::is_specialization_of<meta::Unqualified<T>, std::reference_wrapper>::value || std::is_pointer<T>::value> is_reference;
|
||||
set_reference_fx(is_reference(), L, memfxptr, std::forward<T>(obj));
|
||||
}
|
||||
|
||||
|
@ -260,14 +268,14 @@ struct pusher<function_sig<Sigs...>> {
|
|||
template<typename Fx, typename R, typename... Args>
|
||||
static void set_isconvertible_fx(std::true_type, types<R(Args...)>, lua_State* L, Fx&& fx) {
|
||||
typedef R(* fx_ptr_t)(Args...);
|
||||
fx_ptr_t fxptr = unwrap(std::forward<Fx>(fx));
|
||||
fx_ptr_t fxptr = detail::unwrap(std::forward<Fx>(fx));
|
||||
set(L, fxptr);
|
||||
}
|
||||
|
||||
template<typename Fx, typename R, typename... Args>
|
||||
static void set_isconvertible_fx(std::false_type, types<R(Args...)>, lua_State* L, Fx&& fx) {
|
||||
typedef Unwrapped<std::decay_t<Fx>> fx_t;
|
||||
std::unique_ptr<base_function> sptr(new functor_function<fx_t>(std::forward<Fx>(fx)));
|
||||
typedef meta::Unwrapped<std::decay_t<Fx>> fx_t;
|
||||
std::unique_ptr<base_function> sptr = std::make_unique<function_detail::functor_function<fx_t>>(std::forward<Fx>(fx));
|
||||
set_fx<Fx>(L, std::move(sptr));
|
||||
}
|
||||
|
||||
|
@ -279,7 +287,7 @@ struct pusher<function_sig<Sigs...>> {
|
|||
template<typename Fx, typename T>
|
||||
static void set_reference_fx(std::false_type, lua_State* L, Fx&& fx, T&& obj) {
|
||||
typedef std::remove_pointer_t<std::decay_t<Fx>> clean_fx;
|
||||
std::unique_ptr<base_function> sptr(new member_function<clean_fx, Unqualified<T>>(std::forward<T>(obj), std::forward<Fx>(fx)));
|
||||
std::unique_ptr<function_detail::base_function> sptr = std::make_unique<function_detail::member_function<clean_fx, meta::Unqualified<T>>>(std::forward<T>(obj), std::forward<Fx>(fx));
|
||||
return set_fx<Fx>(L, std::move(sptr));
|
||||
}
|
||||
|
||||
|
@ -291,11 +299,11 @@ struct pusher<function_sig<Sigs...>> {
|
|||
// We don't need to store the size, because the other side is templated
|
||||
// with the same member function pointer type
|
||||
typedef std::decay_t<Fx> dFx;
|
||||
typedef Unqualified<Fx> uFx;
|
||||
typedef meta::Unqualified<Fx> uFx;
|
||||
dFx memfxptr(std::forward<Fx>(fx));
|
||||
auto userptr = ptr(obj);
|
||||
auto userptr = detail::ptr(obj);
|
||||
void* userobjdata = static_cast<void*>(userptr);
|
||||
lua_CFunction freefunc = &static_member_function<std::decay_t<decltype(*userptr)>, uFx>::call;
|
||||
lua_CFunction freefunc = &function_detail::static_member_function<std::decay_t<decltype(*userptr)>, uFx>::call;
|
||||
|
||||
int upvalues = stack::stack_detail::push_as_upvalues(L, memfxptr);
|
||||
upvalues += stack::push(L, userobjdata);
|
||||
|
@ -306,24 +314,24 @@ struct pusher<function_sig<Sigs...>> {
|
|||
template<typename Fx>
|
||||
static void set_fx(std::false_type, lua_State* L, Fx&& fx) {
|
||||
std::decay_t<Fx> target(std::forward<Fx>(fx));
|
||||
lua_CFunction freefunc = &static_function<Fx>::call;
|
||||
lua_CFunction freefunc = &function_detail::static_function<Fx>::call;
|
||||
|
||||
int upvalues = stack::stack_detail::push_as_upvalues(L, target);
|
||||
stack::push(L, freefunc, upvalues);
|
||||
}
|
||||
|
||||
template<typename Fx>
|
||||
static void set_fx(lua_State* L, std::unique_ptr<base_function> luafunc) {
|
||||
static void set_fx(lua_State* L, std::unique_ptr<function_detail::base_function> luafunc) {
|
||||
const static auto& metakey = u8"sol.ƒ.♲.🗑.(/¯◡ ‿ ◡)/¯ ~ ┻━┻ (ノ◕ヮ◕)ノ*:・゚✧";
|
||||
const static char* metatablename = &metakey[0];
|
||||
base_function* target = luafunc.release();
|
||||
function_detail::base_function* target = luafunc.release();
|
||||
void* userdata = reinterpret_cast<void*>(target);
|
||||
lua_CFunction freefunc = detail::call;
|
||||
lua_CFunction freefunc = function_detail::call;
|
||||
|
||||
int metapushed = luaL_newmetatable(L, metatablename);
|
||||
if(metapushed == 1) {
|
||||
lua_pushstring(L, "__gc");
|
||||
stack::push(L, detail::gc);
|
||||
stack::push(L, function_detail::gc);
|
||||
lua_settable(L, -3);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
@ -341,7 +349,7 @@ struct pusher<function_sig<Sigs...>> {
|
|||
};
|
||||
|
||||
template<typename T, typename... Args>
|
||||
struct pusher<sol::detail::function_packer<T, Args...>> {
|
||||
struct pusher<function_packer<T, Args...>> {
|
||||
template <std::size_t... I, typename FP>
|
||||
static int push_func(std::index_sequence<I...>, lua_State* L, FP&& fp) {
|
||||
return stack::push<T>(L, std::get<I>(fp)...);
|
||||
|
@ -364,7 +372,7 @@ template<typename... Functions>
|
|||
struct pusher<overload_set<Functions...>> {
|
||||
template<std::size_t... I, typename Set>
|
||||
static int push(std::index_sequence<I...>, lua_State* L, Set&& set) {
|
||||
pusher<function_sig<>>{}.set_fx<Set>(L, std::make_unique<overloaded_function<Functions...>>(std::get<I>(set)...));
|
||||
pusher<function_sig<>>{}.set_fx<Set>(L, std::make_unique<function_detail::overloaded_function<Functions...>>(std::get<I>(set)...));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -376,21 +384,21 @@ struct pusher<overload_set<Functions...>> {
|
|||
|
||||
template<typename Signature>
|
||||
struct getter<std::function<Signature>> {
|
||||
typedef function_traits<Signature> fx_t;
|
||||
typedef meta::function_traits<Signature> fx_t;
|
||||
typedef typename fx_t::args_type args_types;
|
||||
typedef tuple_types<typename fx_t::return_type> return_types;
|
||||
typedef meta::tuple_types<typename fx_t::return_type> return_types;
|
||||
|
||||
template<typename... Args, typename... Ret>
|
||||
static std::function<Signature> get_std_func(types<Args...>, types<Ret...>, lua_State* L, int index = -1) {
|
||||
static std::function<Signature> get_std_func(types<Ret...>, types<Args...>, lua_State* L, int index = -1) {
|
||||
sol::function f(L, index);
|
||||
auto fx = [f, L, index](Args&&... args) -> return_type_t<Ret...> {
|
||||
auto fx = [f, L, index](Args&&... args) -> meta::return_type_t<Ret...> {
|
||||
return f.call<Ret...>(std::forward<Args>(args)...);
|
||||
};
|
||||
return std::move(fx);
|
||||
}
|
||||
|
||||
template<typename... FxArgs>
|
||||
static std::function<Signature> get_std_func(types<FxArgs...>, types<void>, lua_State* L, int index = -1) {
|
||||
static std::function<Signature> get_std_func(types<void>, types<FxArgs...>, lua_State* L, int index = -1) {
|
||||
sol::function f(L, index);
|
||||
auto fx = [f, L, index](FxArgs&&... args) -> void {
|
||||
f(std::forward<FxArgs>(args)...);
|
||||
|
@ -399,12 +407,12 @@ struct getter<std::function<Signature>> {
|
|||
}
|
||||
|
||||
template<typename... FxArgs>
|
||||
static std::function<Signature> get_std_func(types<FxArgs...> t, types<>, lua_State* L, int index = -1) {
|
||||
return get_std_func(std::move(t), types<void>(), L, index);
|
||||
static std::function<Signature> get_std_func(types<>, types<FxArgs...> t, lua_State* L, int index = -1) {
|
||||
return get_std_func(types<void>(), t, L, index);
|
||||
}
|
||||
|
||||
static std::function<Signature> get(lua_State* L, int index) {
|
||||
return get_std_func(args_types(), return_types(), L, index);
|
||||
return get_std_func(return_types(), args_types(), L, index);
|
||||
}
|
||||
};
|
||||
} // stack
|
||||
|
|
|
@ -42,13 +42,14 @@ struct constructor_match {
|
|||
constructor_match(T* obj) : obj(obj) {}
|
||||
|
||||
template <bool b, typename Fx, std::size_t I, typename... R, typename... Args>
|
||||
int operator()(Bool<b>, types<Fx>, Index<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start) const {
|
||||
int operator()(meta::Bool<b>, types<Fx>, Index<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start) const {
|
||||
default_construct func{};
|
||||
return stack::typed_call<b ? false : stack::stack_detail::default_check_arguments>(r, a, func, L, start, obj);
|
||||
}
|
||||
};
|
||||
} // detail
|
||||
|
||||
namespace function_detail {
|
||||
template <typename T, typename... TypeLists, typename Match>
|
||||
inline int construct(Match&& matchfx, lua_State* L, int fxarity, int start) {
|
||||
// use same overload resolution matching as all other parts of the framework
|
||||
|
@ -109,7 +110,7 @@ struct usertype_constructor_function : base_function {
|
|||
usertype_constructor_function(Functions... fxs) : overloads(fxs...) {}
|
||||
|
||||
template <bool b, typename Fx, std::size_t I, typename... R, typename... Args>
|
||||
int call(Bool<b>, types<Fx>, Index<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start) {
|
||||
int call(meta::Bool<b>, types<Fx>, Index<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start) {
|
||||
static const auto& meta = usertype_traits<T>::metatable;
|
||||
T** pointerpointer = reinterpret_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
|
||||
T*& referencepointer = *pointerpointer;
|
||||
|
@ -119,7 +120,7 @@ struct usertype_constructor_function : base_function {
|
|||
userdataref.pop();
|
||||
|
||||
auto& func = std::get<I>(overloads);
|
||||
stack::typed_call<b ? false : stack::stack_detail::default_check_arguments>(r, a, func, L, start, detail::implicit_wrapper<T>(obj));
|
||||
stack::typed_call<b ? false : stack::stack_detail::default_check_arguments>(r, a, func, L, start, function_detail::implicit_wrapper<T>(obj));
|
||||
|
||||
userdataref.push();
|
||||
luaL_getmetatable(L, &meta[0]);
|
||||
|
@ -139,9 +140,10 @@ struct usertype_constructor_function : base_function {
|
|||
call_syntax syntax = stack::get_call_syntax(L, meta);
|
||||
int argcount = lua_gettop(L) - static_cast<int>(syntax);
|
||||
auto mfx = [&](auto&&... args) { return this->call(std::forward<decltype(args)>(args)...); };
|
||||
return construct<T, pop_front_type_t<function_args_t<Functions>>...>(mfx, L, argcount, 1 + static_cast<int>(syntax));
|
||||
return construct<T, meta::pop_front_type_t<meta::function_args_t<Functions>>...>(mfx, L, argcount, 1 + static_cast<int>(syntax));
|
||||
}
|
||||
};
|
||||
} // function_detail
|
||||
} // sol
|
||||
|
||||
#endif // SOL_FUNCTION_TYPES_ALLOCATOR_HPP
|
||||
|
|
|
@ -26,8 +26,7 @@
|
|||
#include <memory>
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
struct ref_call_t {} const ref_call = ref_call_t{};
|
||||
namespace function_detail {
|
||||
template <typename T>
|
||||
struct implicit_wrapper {
|
||||
T& item;
|
||||
|
@ -41,14 +40,6 @@ struct implicit_wrapper {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename Sig, typename... Args>
|
||||
struct function_packer : std::tuple<Args...> { using std::tuple<Args...>::tuple; };
|
||||
|
||||
template <typename Sig, typename... Args>
|
||||
function_packer<Sig, Args...> function_pack( Args&&... args ) {
|
||||
return function_packer<Sig, Args...>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
inline bool check_types(types<>, std::index_sequence<>, lua_State*, int) {
|
||||
return true;
|
||||
}
|
||||
|
@ -63,7 +54,7 @@ inline bool check_types(types<Arg, Args...>, std::index_sequence<I, In...>, lua_
|
|||
|
||||
template<typename T, typename Func, typename = void>
|
||||
struct functor {
|
||||
typedef callable_traits<Func> traits_type;
|
||||
typedef meta::callable_traits<Func> traits_type;
|
||||
typedef typename traits_type::args_type args_type;
|
||||
typedef typename traits_type::return_type return_type;
|
||||
static const std::size_t arity = traits_type::arity;
|
||||
|
@ -98,7 +89,7 @@ struct functor {
|
|||
|
||||
template<typename T, typename Func>
|
||||
struct functor<T, Func, std::enable_if_t<std::is_member_object_pointer<Func>::value>> {
|
||||
typedef callable_traits<Func> traits_type;
|
||||
typedef meta::callable_traits<Func> traits_type;
|
||||
typedef typename traits_type::args_type args_type;
|
||||
typedef typename traits_type::return_type return_type;
|
||||
static const std::size_t arity = traits_type::arity;
|
||||
|
@ -131,13 +122,13 @@ struct functor<T, Func, std::enable_if_t<std::is_member_object_pointer<Func>::va
|
|||
|
||||
template<typename T, typename Func>
|
||||
struct functor<T, Func, std::enable_if_t<std::is_function<Func>::value || std::is_class<Func>::value>> {
|
||||
typedef callable_traits<Func> traits_type;
|
||||
typedef pop_front_type_t<typename traits_type::args_type> args_type;
|
||||
typedef meta::callable_traits<Func> traits_type;
|
||||
typedef meta::pop_front_type_t<typename traits_type::args_type> args_type;
|
||||
typedef typename traits_type::return_type return_type;
|
||||
static const std::size_t arity = traits_type::arity;
|
||||
typedef std::tuple_element_t<0, typename traits_type::args_tuple_type> Arg0;
|
||||
typedef std::conditional_t<std::is_pointer<Func>::value || std::is_class<Func>::value, Func, std::add_pointer_t<Func>> function_type;
|
||||
static_assert(std::is_base_of<Unqualified<std::remove_pointer_t<Arg0>>, T>::value, "Any non-member-function must have a first argument which is covariant with the desired userdata type.");
|
||||
static_assert(std::is_base_of<meta::Unqualified<std::remove_pointer_t<Arg0>>, T>::value, "Any non-member-function must have a first argument which is covariant with the desired userdata type.");
|
||||
T* item;
|
||||
function_type invocation;
|
||||
|
||||
|
@ -176,7 +167,6 @@ public:
|
|||
return this->call(types<return_type>(), std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
} // detail
|
||||
|
||||
struct base_function {
|
||||
virtual int operator()(lua_State*) {
|
||||
|
@ -186,7 +176,6 @@ struct base_function {
|
|||
virtual ~base_function() {}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
static int base_call(lua_State* L, void* inheritancedata) {
|
||||
if (inheritancedata == nullptr) {
|
||||
throw error("call from Lua to C++ function has null data");
|
||||
|
@ -245,10 +234,10 @@ inline int usertype_call(lua_State* L) {
|
|||
|
||||
template<std::size_t I>
|
||||
inline int usertype_gc(lua_State* L) {
|
||||
func_gc<I>(Bool<(I < 1)>(), L);
|
||||
func_gc<I>(meta::Bool<(I < 1)>(), L);
|
||||
return 0;
|
||||
}
|
||||
} // detail
|
||||
} // function_detail
|
||||
} // sol
|
||||
|
||||
#endif // SOL_FUNCTION_TYPES_CORE_HPP
|
||||
|
|
|
@ -25,11 +25,12 @@
|
|||
#include "function_types_core.hpp"
|
||||
|
||||
namespace sol {
|
||||
namespace function_detail {
|
||||
template<typename Function>
|
||||
struct functor_function : public base_function {
|
||||
typedef decltype(&Function::operator()) function_type;
|
||||
typedef function_return_t<function_type> return_type;
|
||||
typedef function_args_t<function_type> args_type;
|
||||
typedef meta::function_return_t<function_type> return_type;
|
||||
typedef meta::function_args_t<function_type> args_type;
|
||||
Function fx;
|
||||
|
||||
template<typename... Args>
|
||||
|
@ -59,8 +60,8 @@ struct functor_function : public base_function {
|
|||
template<typename Function, typename T>
|
||||
struct member_function : public base_function {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
typedef function_return_t<function_type> return_type;
|
||||
typedef function_args_t<function_type> args_types;
|
||||
typedef meta::function_return_t<function_type> return_type;
|
||||
typedef meta::function_args_t<function_type> args_types;
|
||||
struct functor {
|
||||
T member;
|
||||
function_type invocation;
|
||||
|
@ -70,7 +71,7 @@ struct member_function : public base_function {
|
|||
|
||||
template<typename... Args>
|
||||
return_type operator()(Args&&... args) {
|
||||
auto& mem = unwrap(deref(member));
|
||||
auto& mem = detail::unwrap(detail::deref(member));
|
||||
return (mem.*invocation)(std::forward<Args>(args)...);
|
||||
}
|
||||
} fx;
|
||||
|
@ -79,9 +80,10 @@ struct member_function : public base_function {
|
|||
member_function(Tm&& m, Args&&... args): fx(std::forward<Tm>(m), std::forward<Args>(args)...) {}
|
||||
|
||||
virtual int operator()(lua_State* L) override {
|
||||
return stack::typed_call(tuple_types<return_type>(), args_types(), fx, L);
|
||||
return stack::typed_call(meta::tuple_types<return_type>(), args_types(), fx, L);
|
||||
}
|
||||
};
|
||||
} // function_detail
|
||||
} // sol
|
||||
|
||||
#endif // SOL_FUNCTION_TYPES_MEMBER_HPP
|
||||
|
|
|
@ -27,9 +27,10 @@
|
|||
#include "function_types_usertype.hpp"
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
namespace function_detail {
|
||||
namespace internals {
|
||||
template <typename T>
|
||||
struct overload_traits : function_traits<T> {};
|
||||
struct overload_traits : meta::function_traits<T> {};
|
||||
|
||||
template <typename T, typename Func, typename X>
|
||||
struct overload_traits<functor<T, Func, X>> {
|
||||
|
@ -45,27 +46,27 @@ inline int overload_match_arity(types<>, std::index_sequence<>, std::index_seque
|
|||
|
||||
template <typename Fx, typename... Fxs, std::size_t I, std::size_t... In, std::size_t... M, typename Match, typename... Args>
|
||||
inline int overload_match_arity(types<Fx, Fxs...>, std::index_sequence<I, In...>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||
typedef overload_traits<Unqualified<Fx>> traits;
|
||||
typedef tuple_types<typename traits::return_type> return_types;
|
||||
typedef overload_traits<meta::Unqualified<Fx>> traits;
|
||||
typedef meta::tuple_types<typename traits::return_type> return_types;
|
||||
typedef typename traits::args_type args_type;
|
||||
typedef typename args_type::indices args_indices;
|
||||
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
||||
if (find_in_pack_v<Index<traits::arity>, Index<M>...>::value) {
|
||||
if (meta::find_in_pack_v<Index<traits::arity>, Index<M>...>::value) {
|
||||
return overload_match_arity(types<Fxs...>(), std::index_sequence<In...>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
if (traits::arity != fxarity) {
|
||||
return overload_match_arity(types<Fxs...>(), std::index_sequence<In...>(), std::index_sequence<traits::arity, M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
if (sizeof...(Fxs) != 0 && !detail::check_types(args_type(), args_indices(), L, start)) {
|
||||
if (sizeof...(Fxs) != 0 && function_detail::check_types(args_type(), args_indices(), L, start)) {
|
||||
return overload_match_arity(types<Fxs...>(), std::index_sequence<In...>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
return matchfx(Bool<sizeof...(Fxs) != 0>(), types<Fx>(), Index<I>(), return_types(), args_type(), L, fxarity, start, std::forward<Args>(args)...);
|
||||
return matchfx(meta::Bool<sizeof...(Fxs) != 0>(), types<Fx>(), Index<I>(), return_types(), args_type(), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
} // detail
|
||||
} // internals
|
||||
|
||||
template <typename... Functions, typename Match, typename... Args>
|
||||
inline int overload_match_arity(Match&& matchfx, lua_State* L, int fxarity, int start = 1, Args&&... args) {
|
||||
return detail::overload_match_arity(types<Functions...>(), std::index_sequence_for<Functions...>(), std::index_sequence<>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||
return internals::overload_match_arity(types<Functions...>(), std::index_sequence_for<Functions...>(), std::index_sequence<>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Functions, typename Match, typename... Args>
|
||||
|
@ -93,7 +94,7 @@ struct overloaded_function : base_function {
|
|||
}
|
||||
|
||||
template <bool b, typename Fx, std::size_t I, typename... R, typename... Args>
|
||||
int call(Bool<b>, types<Fx>, Index<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start) {
|
||||
int call(meta::Bool<b>, types<Fx>, Index<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start) {
|
||||
auto& func = std::get<I>(overloads);
|
||||
return stack::typed_call<b ? false : stack::stack_detail::default_check_arguments>(r, a, func, L, start);
|
||||
}
|
||||
|
@ -106,7 +107,7 @@ struct overloaded_function : base_function {
|
|||
|
||||
template <typename T, typename... Functions>
|
||||
struct usertype_overloaded_function : base_function {
|
||||
typedef std::tuple<detail::functor<T, std::remove_pointer_t<std::decay_t<Functions>>>...> overload_list;
|
||||
typedef std::tuple<functor<T, std::remove_pointer_t<std::decay_t<Functions>>>...> overload_list;
|
||||
typedef std::index_sequence_for<Functions...> indices;
|
||||
overload_list overloads;
|
||||
|
||||
|
@ -118,18 +119,19 @@ struct usertype_overloaded_function : base_function {
|
|||
usertype_overloaded_function(Functions... fxs) : overloads(fxs...) {}
|
||||
|
||||
template <bool b,typename Fx, std::size_t I, typename... R, typename... Args>
|
||||
int call(Bool<b>, types<Fx>, Index<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start) {
|
||||
int call(meta::Bool<b>, types<Fx>, Index<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start) {
|
||||
auto& func = std::get<I>(overloads);
|
||||
func.item = ptr(stack::get<T>(L, 1));
|
||||
func.item = detail::ptr(stack::get<T>(L, 1));
|
||||
return stack::typed_call<b ? false : stack::stack_detail::default_check_arguments>(r, a, func, L, start);
|
||||
}
|
||||
|
||||
virtual int operator()(lua_State* L) override {
|
||||
auto mfx = [&](auto&&... args){ return this->call(std::forward<decltype(args)>(args)...); };
|
||||
return overload_match<detail::functor<T, std::remove_pointer_t<std::decay_t<Functions>>>...>(mfx, L, 2);
|
||||
return overload_match<functor<T, std::remove_pointer_t<std::decay_t<Functions>>>...>(mfx, L, 2);
|
||||
}
|
||||
|
||||
};
|
||||
} // function_detail
|
||||
} // sol
|
||||
|
||||
#endif // SOL_FUNCTION_TYPES_OVERLOAD_HPP
|
||||
|
|
|
@ -25,15 +25,16 @@
|
|||
#include "stack.hpp"
|
||||
|
||||
namespace sol {
|
||||
namespace function_detail {
|
||||
template<typename Function>
|
||||
struct static_function {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
typedef function_traits<function_type> traits_type;
|
||||
typedef meta::function_traits<function_type> traits_type;
|
||||
|
||||
static int call(lua_State* L) {
|
||||
auto udata = stack::stack_detail::get_as_upvalues<function_type*>(L);
|
||||
function_type* fx = udata.first;
|
||||
int r = stack::typed_call(tuple_types<typename traits_type::return_type>(), typename traits_type::args_type(), fx, L);
|
||||
int r = stack::typed_call(meta::tuple_types<typename traits_type::return_type>(), typename traits_type::args_type(), fx, L);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -45,7 +46,7 @@ struct static_function {
|
|||
template<typename T, typename Function>
|
||||
struct static_member_function {
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
typedef function_traits<function_type> traits_type;
|
||||
typedef meta::function_traits<function_type> traits_type;
|
||||
|
||||
static int call(lua_State* L) {
|
||||
auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L, 1);
|
||||
|
@ -53,13 +54,14 @@ struct static_member_function {
|
|||
function_type& memfx = memberdata.first;
|
||||
T& item = *objdata.first;
|
||||
auto fx = [&item, &memfx](auto&&... args) -> typename traits_type::return_type { return (item.*memfx)(std::forward<decltype(args)>(args)...); };
|
||||
return stack::typed_call(tuple_types<typename traits_type::return_type>(), typename traits_type::args_type(), fx, L);
|
||||
return stack::typed_call(meta::tuple_types<typename traits_type::return_type>(), typename traits_type::args_type(), fx, L);
|
||||
}
|
||||
|
||||
int operator()(lua_State* L) {
|
||||
return call(L);
|
||||
}
|
||||
};
|
||||
} // function_detail
|
||||
} // sol
|
||||
|
||||
#endif // SOL_FUNCTION_TYPES_STATIC_HPP
|
||||
|
|
|
@ -27,11 +27,12 @@
|
|||
#include <map>
|
||||
|
||||
namespace sol {
|
||||
namespace function_detail {
|
||||
template<typename Function, typename Tp>
|
||||
struct usertype_function_core : public base_function {
|
||||
typedef std::remove_pointer_t<Tp> T;
|
||||
typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
|
||||
typedef detail::functor<T, function_type> fx_t;
|
||||
typedef functor<T, function_type> fx_t;
|
||||
typedef typename fx_t::traits_type traits_type;
|
||||
typedef typename fx_t::args_type args_type;
|
||||
typedef typename fx_t::return_type return_type;
|
||||
|
@ -41,9 +42,9 @@ struct usertype_function_core : public base_function {
|
|||
template<typename... Args>
|
||||
usertype_function_core(Args&&... args): fx(std::forward<Args>(args)...) {}
|
||||
|
||||
template<typename Return, typename Raw = Unqualified<Return>>
|
||||
template<typename Return, typename Raw = meta::Unqualified<Return>>
|
||||
std::enable_if_t<std::is_same<T, Raw>::value, int> push(lua_State* L, Return&& r) {
|
||||
if(ptr(unwrap(r)) == fx.item) {
|
||||
if(detail::ptr(detail::unwrap(r)) == fx.item) {
|
||||
// push nothing
|
||||
// note that pushing nothing with the ':'
|
||||
// syntax means we leave the instance of what
|
||||
|
@ -57,7 +58,7 @@ struct usertype_function_core : public base_function {
|
|||
return stack::push(L, std::forward<Return>(r));
|
||||
}
|
||||
|
||||
template<typename Return, typename Raw = Unqualified<Return>>
|
||||
template<typename Return, typename Raw = meta::Unqualified<Return>>
|
||||
std::enable_if_t<!std::is_same<T, Raw>::value, int> push(lua_State* L, Return&& r) {
|
||||
return stack::push(L, std::forward<Return>(r));
|
||||
}
|
||||
|
@ -92,11 +93,11 @@ struct usertype_function : public usertype_function_core<Function, Tp> {
|
|||
usertype_function(Args&&... args): base_t(std::forward<Args>(args)...) {}
|
||||
|
||||
int prelude(lua_State* L) {
|
||||
this->fx.item = ptr(stack::get<T>(L, 1));
|
||||
this->fx.item = detail::ptr(stack::get<T>(L, 1));
|
||||
if(this->fx.item == nullptr) {
|
||||
throw error("userdata for function call is null: are you using the wrong syntax? (use item:function/variable(...) syntax)");
|
||||
}
|
||||
return static_cast<base_t&>(*this)(tuple_types<return_type>(), args_type(), Index<2>(), L);
|
||||
return static_cast<base_t&>(*this)(meta::tuple_types<return_type>(), args_type(), Index<2>(), L);
|
||||
}
|
||||
|
||||
virtual int operator()(lua_State* L) override {
|
||||
|
@ -123,9 +124,9 @@ struct usertype_variable_function : public usertype_function_core<Function, Tp>
|
|||
}
|
||||
switch(argcount) {
|
||||
case 2:
|
||||
return static_cast<base_t&>(*this)(tuple_types<return_type>(), types<>(), Index<2>(), L);
|
||||
return static_cast<base_t&>(*this)(meta::tuple_types<return_type>(), types<>(), Index<2>(), L);
|
||||
case 3:
|
||||
return static_cast<base_t&>(*this)(tuple_types<void>(), args_type(), Index<3>(), L);
|
||||
return static_cast<base_t&>(*this)(meta::tuple_types<void>(), args_type(), Index<3>(), L);
|
||||
default:
|
||||
throw error("cannot get/set userdata member variable with inappropriate number of arguments");
|
||||
}
|
||||
|
@ -151,7 +152,7 @@ struct usertype_indexing_function : base_function {
|
|||
std::pair<bool, base_function*>& target = functionpair->second;
|
||||
if (target.first) {
|
||||
stack::push<upvalue>(L, target.second);
|
||||
stack::push(L, c_closure(detail::usertype_call<0>, 1));
|
||||
stack::push(L, c_closure(usertype_call<0>, 1));
|
||||
return 1;
|
||||
}
|
||||
return (*target.second)(L);
|
||||
|
@ -164,6 +165,7 @@ struct usertype_indexing_function : base_function {
|
|||
return prelude(L);
|
||||
}
|
||||
};
|
||||
} // function_detail
|
||||
} // sol
|
||||
|
||||
#endif // SOL_FUNCTION_TYPES_USERTYPE_HPP
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace sol {
|
|||
template<typename Table, typename Key>
|
||||
struct proxy : public proxy_base<proxy<Table, Key>> {
|
||||
private:
|
||||
typedef If<is_specialization_of<Key, std::tuple>, Key, std::tuple<If<std::is_array<Unqualified<Key>>, Key&, Unqualified<Key>>>> key_type;
|
||||
typedef meta::If<meta::is_specialization_of<Key, std::tuple>, Key, std::tuple<meta::If<std::is_array<meta::Unqualified<Key>>, Key&, meta::Unqualified<Key>>>> key_type;
|
||||
Table tbl;
|
||||
key_type key;
|
||||
|
||||
|
@ -52,7 +52,7 @@ public:
|
|||
|
||||
template<typename T>
|
||||
proxy& set(T&& item) {
|
||||
tuple_set( std::make_index_sequence<std::tuple_size<Unqualified<key_type>>::value>(), std::forward<T>(item) );
|
||||
tuple_set( std::make_index_sequence<std::tuple_size<meta::Unqualified<key_type>>::value>(), std::forward<T>(item) );
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -62,24 +62,24 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
template<typename U, EnableIf<Function<Unqualified<U>>> = 0>
|
||||
template<typename U, meta::EnableIf<meta::Function<meta::Unqualified<U>>> = 0>
|
||||
proxy& operator=(U&& other) {
|
||||
return set_function(std::forward<U>(other));
|
||||
}
|
||||
|
||||
template<typename U, DisableIf<Function<Unqualified<U>>> = 0>
|
||||
template<typename U, meta::DisableIf<meta::Function<meta::Unqualified<U>>> = 0>
|
||||
proxy& operator=(U&& other) {
|
||||
return set(std::forward<U>(other));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
decltype(auto) get() const {
|
||||
return tuple_get<T>( std::make_index_sequence<std::tuple_size<Unqualified<key_type>>::value>() );
|
||||
return tuple_get<T>( std::make_index_sequence<std::tuple_size<meta::Unqualified<key_type>>::value>() );
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
decltype(auto) operator[](K&& k) const {
|
||||
auto keys = tuplefy(key, std::forward<K>(k));
|
||||
auto keys = meta::tuplefy(key, std::forward<K>(k));
|
||||
return proxy<Table, decltype(keys)>(tbl, std::move(keys));
|
||||
}
|
||||
|
||||
|
|
|
@ -34,13 +34,13 @@ struct proxy_base {
|
|||
return super.template get<std::string>();
|
||||
}
|
||||
|
||||
template<typename T, EnableIf<Not<is_string_constructible<T>>, is_proxy_primitive<Unqualified<T>>> = 0>
|
||||
template<typename T, meta::EnableIf<meta::Not<meta::is_string_constructible<T>>, is_proxy_primitive<meta::Unqualified<T>>> = 0>
|
||||
operator T ( ) const {
|
||||
const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
|
||||
return super.template get<T>( );
|
||||
}
|
||||
|
||||
template<typename T, EnableIf<Not<is_string_constructible<T>>, Not<is_proxy_primitive<Unqualified<T>>>> = 0>
|
||||
template<typename T, meta::EnableIf<meta::Not<meta::is_string_constructible<T>>, meta::Not<is_proxy_primitive<meta::Unqualified<T>>>> = 0>
|
||||
operator T& ( ) const {
|
||||
const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
|
||||
return super.template get<T&>( );
|
||||
|
|
17
sol/raii.hpp
17
sol/raii.hpp
|
@ -26,26 +26,15 @@
|
|||
#include "traits.hpp"
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
struct default_construct {
|
||||
template<typename T, typename... Args>
|
||||
void operator()(T&& obj, Args&&... args) const {
|
||||
std::allocator<Unqualified<T>> alloc{};
|
||||
std::allocator<meta::Unqualified<T>> alloc{};
|
||||
alloc.construct(obj, std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct placement_construct {
|
||||
T obj;
|
||||
|
||||
template <typename... Args>
|
||||
placement_construct( Args&&... args ) : obj(std::forward<Args>(args)...) {}
|
||||
|
||||
template<typename... Args>
|
||||
void operator()(Args&&... args) const {
|
||||
default_construct{}(obj, std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
} // detail
|
||||
|
||||
template<typename... Args>
|
||||
using constructors = sol::types<Args...>;
|
||||
|
|
|
@ -27,14 +27,14 @@
|
|||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
template<typename R, typename... Args, typename F, typename = std::result_of_t<Unqualified<F>(Args...)>>
|
||||
inline auto resolve_i(types<R(Args...)>, F&&) -> R(Unqualified<F>::*)(Args...) {
|
||||
template<typename R, typename... Args, typename F, typename = std::result_of_t<meta::Unqualified<F>(Args...)>>
|
||||
inline auto resolve_i(types<R(Args...)>, F&&) -> R(meta::Unqualified<F>::*)(Args...) {
|
||||
using Sig = R(Args...);
|
||||
typedef Unqualified<F> Fu;
|
||||
typedef meta::Unqualified<F> Fu;
|
||||
return static_cast<Sig Fu::*>(&Fu::operator());
|
||||
}
|
||||
|
||||
template<typename F, typename U = Unqualified<F>>
|
||||
template<typename F, typename U = meta::Unqualified<F>>
|
||||
inline auto resolve_f(std::true_type, F&& f)
|
||||
-> decltype(resolve_i(types<function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f))) {
|
||||
return resolve_i(types<function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f));
|
||||
|
@ -46,7 +46,7 @@ inline void resolve_f(std::false_type, F&&) {
|
|||
"Cannot use no-template-parameter call with an overloaded functor: specify the signature");
|
||||
}
|
||||
|
||||
template<typename F, typename U = Unqualified<F>>
|
||||
template<typename F, typename U = meta::Unqualified<F>>
|
||||
inline auto resolve_i(types<>, F&& f) -> decltype(resolve_f(has_deducible_signature<U> {}, std::forward<F>(f))) {
|
||||
return resolve_f(has_deducible_signature<U> {}, std::forward<F>(f));
|
||||
}
|
||||
|
|
|
@ -50,13 +50,13 @@ struct checker;
|
|||
|
||||
template<typename T, typename... Args>
|
||||
inline int push(lua_State* L, T&& t, Args&&... args) {
|
||||
return pusher<Unqualified<T>>{}.push(L, std::forward<T>(t), std::forward<Args>(args)...);
|
||||
return pusher<meta::Unqualified<T>>{}.push(L, std::forward<T>(t), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// overload allows to use a pusher of a specific type, but pass in any kind of args
|
||||
template<typename T, typename Arg, typename... Args>
|
||||
inline int push(lua_State* L, Arg&& arg, Args&&... args) {
|
||||
return pusher<Unqualified<T>>{}.push(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
|
||||
return pusher<meta::Unqualified<T>>{}.push(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
inline int push_args(lua_State*) {
|
||||
|
@ -73,17 +73,17 @@ inline int push_args(lua_State* L, T&& t, Args&&... args) {
|
|||
|
||||
template<typename T>
|
||||
inline decltype(auto) get(lua_State* L, int index = -1) {
|
||||
return getter<Unqualified<T>>{}.get(L, index);
|
||||
return getter<meta::Unqualified<T>>{}.get(L, index);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline decltype(auto) pop(lua_State* L) {
|
||||
return popper<Unqualified<T>>{}.pop(L);
|
||||
return popper<meta::Unqualified<T>>{}.pop(L);
|
||||
}
|
||||
|
||||
template <typename T, typename Handler>
|
||||
bool check(lua_State* L, int index, Handler&& handler) {
|
||||
typedef Unqualified<T> Tu;
|
||||
typedef meta::Unqualified<T> Tu;
|
||||
checker<Tu> c;
|
||||
// VC++ has a bad warning here: shut it up
|
||||
(void)c;
|
||||
|
@ -98,22 +98,22 @@ bool check(lua_State* L, int index) {
|
|||
|
||||
template <bool global = false, typename Key>
|
||||
void get_field(lua_State* L, Key&& key) {
|
||||
field_getter<Unqualified<Key>, global>{}.get(L, std::forward<Key>(key));
|
||||
field_getter<meta::Unqualified<Key>, global>{}.get(L, std::forward<Key>(key));
|
||||
}
|
||||
|
||||
template <bool global = false, typename Key>
|
||||
void get_field(lua_State* L, Key&& key, int tableindex) {
|
||||
field_getter<Unqualified<Key>, global>{}.get(L, std::forward<Key>(key), tableindex);
|
||||
field_getter<meta::Unqualified<Key>, global>{}.get(L, std::forward<Key>(key), tableindex);
|
||||
}
|
||||
|
||||
template <bool global = false, typename Key, typename Value>
|
||||
void set_field(lua_State* L, Key&& key, Value&& value) {
|
||||
field_setter<Unqualified<Key>, global>{}.set(L, std::forward<Key>(key), std::forward<Value>(value));
|
||||
field_setter<meta::Unqualified<Key>, global>{}.set(L, std::forward<Key>(key), std::forward<Value>(value));
|
||||
}
|
||||
|
||||
template <bool global = false, typename Key, typename Value>
|
||||
void set_field(lua_State* L, Key&& key, Value&& value, int tableindex) {
|
||||
field_setter<Unqualified<Key>, global>{}.set(L, std::forward<Key>(key), std::forward<Value>(value), tableindex);
|
||||
field_setter<meta::Unqualified<Key>, global>{}.set(L, std::forward<Key>(key), std::forward<Value>(value), tableindex);
|
||||
}
|
||||
|
||||
namespace stack_detail {
|
||||
|
@ -190,14 +190,14 @@ inline int push_userdata_pointer(lua_State* L, Key&& metatablekey) {
|
|||
return push_confirmed_userdata<T>(L, std::forward<Key>(metatablekey));
|
||||
}
|
||||
|
||||
template <typename T, typename Key, typename Arg, EnableIf<std::is_same<T, Unqualified<Arg>>> = 0>
|
||||
template <typename T, typename Key, typename Arg, meta::EnableIf<std::is_same<T, meta::Unqualified<Arg>>> = 0>
|
||||
inline int push_userdata_pointer(lua_State* L, Key&& metatablekey, Arg&& arg) {
|
||||
if (arg == nullptr)
|
||||
return push(L, nil);
|
||||
return push_confirmed_userdata<T>(L, std::forward<Key>(metatablekey), std::forward<Arg>(arg));
|
||||
}
|
||||
|
||||
template <typename T, typename Key, typename Arg, DisableIf<std::is_same<T, Unqualified<Arg>>> = 0>
|
||||
template <typename T, typename Key, typename Arg, meta::DisableIf<std::is_same<T, meta::Unqualified<Arg>>> = 0>
|
||||
inline int push_userdata_pointer(lua_State* L, Key&& metatablekey, Arg&& arg) {
|
||||
return push_confirmed_userdata<T>(L, std::forward<Key>(metatablekey), std::forward<Arg>(arg));
|
||||
}
|
||||
|
@ -207,12 +207,12 @@ inline int push_userdata_pointer(lua_State* L, Key&& metatablekey, Arg0&& arg0,
|
|||
return push_confirmed_userdata<T>(L, std::forward<Key>(metatablekey), std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename T, typename Key, typename... Args, DisableIf<std::is_pointer<T>> = 0>
|
||||
template<typename T, typename Key, typename... Args, meta::DisableIf<std::is_pointer<T>> = 0>
|
||||
inline int push_userdata(lua_State* L, Key&& metatablekey, Args&&... args) {
|
||||
return push_confirmed_userdata<T>(L, std::forward<Key>(metatablekey), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename T, typename Key, typename... Args, EnableIf<std::is_pointer<T>> = 0>
|
||||
template<typename T, typename Key, typename... Args, meta::EnableIf<std::is_pointer<T>> = 0>
|
||||
inline int push_userdata(lua_State* L, Key&& metatablekey, Args&&... args) {
|
||||
return push_userdata_pointer<T>(L, std::forward<Key>(metatablekey), std::forward<Args>(args)...);
|
||||
}
|
||||
|
@ -291,14 +291,14 @@ struct getter<T, std::enable_if_t<std::is_floating_point<T>::value>> {
|
|||
};
|
||||
|
||||
template<typename T>
|
||||
struct getter<T, std::enable_if_t<And<std::is_integral<T>, std::is_signed<T>>::value>> {
|
||||
struct getter<T, std::enable_if_t<meta::And<std::is_integral<T>, std::is_signed<T>>::value>> {
|
||||
static T get(lua_State* L, int index = -1) {
|
||||
return static_cast<T>(lua_tointeger(L, index));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct getter<T, std::enable_if_t<And<std::is_integral<T>, std::is_unsigned<T>>::value>> {
|
||||
struct getter<T, std::enable_if_t<meta::And<std::is_integral<T>, std::is_unsigned<T>>::value>> {
|
||||
static T get(lua_State* L, int index = -1) {
|
||||
return static_cast<T>(lua_tointeger(L, index));
|
||||
}
|
||||
|
@ -471,7 +471,7 @@ struct pusher<T, std::enable_if_t<std::is_floating_point<T>::value>> {
|
|||
};
|
||||
|
||||
template<typename T>
|
||||
struct pusher<T, std::enable_if_t<And<std::is_integral<T>, std::is_signed<T>>::value>> {
|
||||
struct pusher<T, std::enable_if_t<meta::And<std::is_integral<T>, std::is_signed<T>>::value>> {
|
||||
static int push(lua_State* L, const T& value) {
|
||||
lua_pushinteger(L, static_cast<lua_Integer>(value));
|
||||
return 1;
|
||||
|
@ -479,7 +479,7 @@ struct pusher<T, std::enable_if_t<And<std::is_integral<T>, std::is_signed<T>>::v
|
|||
};
|
||||
|
||||
template<typename T>
|
||||
struct pusher<T, std::enable_if_t<And<std::is_integral<T>, std::is_unsigned<T>>::value>> {
|
||||
struct pusher<T, std::enable_if_t<meta::And<std::is_integral<T>, std::is_unsigned<T>>::value>> {
|
||||
static int push(lua_State* L, const T& value) {
|
||||
typedef std::make_signed_t<T> signed_int;
|
||||
return stack::push(L, static_cast<signed_int>(value));
|
||||
|
@ -487,7 +487,7 @@ struct pusher<T, std::enable_if_t<And<std::is_integral<T>, std::is_unsigned<T>>:
|
|||
};
|
||||
|
||||
template<typename T>
|
||||
struct pusher<T, std::enable_if_t<And<has_begin_end<T>, Not<has_key_value_pair<T>>>::value>> {
|
||||
struct pusher<T, std::enable_if_t<meta::And<meta::has_begin_end<T>, meta::Not<meta::has_key_value_pair<T>>>::value>> {
|
||||
static int push(lua_State* L, const T& cont) {
|
||||
lua_createtable(L, static_cast<int>(cont.size()), 0);
|
||||
unsigned index = 1;
|
||||
|
@ -495,7 +495,7 @@ struct pusher<T, std::enable_if_t<And<has_begin_end<T>, Not<has_key_value_pair<T
|
|||
// push the index
|
||||
pusher<unsigned>{}.push(L, index++);
|
||||
// push the value
|
||||
pusher<Unqualified<decltype(i)>>{}.push(L, i);
|
||||
pusher<meta::Unqualified<decltype(i)>>{}.push(L, i);
|
||||
// set the table
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
|
@ -504,12 +504,12 @@ struct pusher<T, std::enable_if_t<And<has_begin_end<T>, Not<has_key_value_pair<T
|
|||
};
|
||||
|
||||
template<typename T>
|
||||
struct pusher<T, std::enable_if_t<And<has_begin_end<T>, has_key_value_pair<T>>::value>> {
|
||||
struct pusher<T, std::enable_if_t<meta::And<meta::has_begin_end<T>, meta::has_key_value_pair<T>>::value>> {
|
||||
static int push(lua_State* L, const T& cont) {
|
||||
lua_createtable(L, static_cast<int>(cont.size()), 0);
|
||||
for(auto&& pair : cont) {
|
||||
pusher<Unqualified<decltype(pair.first)>>{}.push(L, pair.first);
|
||||
pusher<Unqualified<decltype(pair.second)>>{}.push(L, pair.second);
|
||||
pusher<meta::Unqualified<decltype(pair.first)>>{}.push(L, pair.first);
|
||||
pusher<meta::Unqualified<decltype(pair.second)>>{}.push(L, pair.second);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
return 1;
|
||||
|
@ -669,7 +669,7 @@ struct field_getter<std::tuple<Args...>, b, C> {
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
struct field_getter<T, true, std::enable_if_t<is_c_str<T>::value>> {
|
||||
struct field_getter<T, true, std::enable_if_t<meta::is_c_str<T>::value>> {
|
||||
template <typename Key>
|
||||
void get(lua_State* L, Key&& key, int = -1) {
|
||||
lua_getglobal(L, &key[0]);
|
||||
|
@ -677,7 +677,7 @@ struct field_getter<T, true, std::enable_if_t<is_c_str<T>::value>> {
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
struct field_getter<T, false, std::enable_if_t<is_c_str<T>::value>> {
|
||||
struct field_getter<T, false, std::enable_if_t<meta::is_c_str<T>::value>> {
|
||||
template <typename Key>
|
||||
void get(lua_State* L, Key&& key, int tableindex = -1) {
|
||||
lua_getfield(L, tableindex, &key[0]);
|
||||
|
@ -705,7 +705,7 @@ struct field_setter {
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
struct field_setter<T, true, std::enable_if_t<is_c_str<T>::value>> {
|
||||
struct field_setter<T, true, std::enable_if_t<meta::is_c_str<T>::value>> {
|
||||
template <typename Key, typename Value>
|
||||
void set(lua_State* L, Key&& key, Value&& value, int = -2) {
|
||||
push(L, std::forward<Value>(value));
|
||||
|
@ -714,7 +714,7 @@ struct field_setter<T, true, std::enable_if_t<is_c_str<T>::value>> {
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
struct field_setter<T, false, std::enable_if_t<is_c_str<T>::value>> {
|
||||
struct field_setter<T, false, std::enable_if_t<meta::is_c_str<T>::value>> {
|
||||
template <typename Key, typename Value>
|
||||
void set(lua_State* L, Key&& key, Value&& value, int tableindex = -2) {
|
||||
push(L, std::forward<Value>(value));
|
||||
|
@ -860,9 +860,9 @@ inline int typed_call(types<void> tr, types<Args...> ta, Fx&& fx, lua_State* L,
|
|||
return 0;
|
||||
}
|
||||
|
||||
template<bool check_args = stack_detail::default_check_arguments, typename Ret0, typename... Ret, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<Not<std::is_void<Ret0>>::value>>
|
||||
template<bool check_args = stack_detail::default_check_arguments, typename Ret0, typename... Ret, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<meta::Not<std::is_void<Ret0>>::value>>
|
||||
inline int typed_call(types<Ret0, Ret...>, types<Args...> ta, Fx&& fx, lua_State* L, int start = 1, FxArgs&&... fxargs) {
|
||||
decltype(auto) r = call<check_args>(types<return_type_t<Ret0, Ret...>>(), ta, L, start, fx, std::forward<FxArgs>(fxargs)...);
|
||||
decltype(auto) r = call<check_args>(types<meta::return_type_t<Ret0, Ret...>>(), ta, L, start, fx, std::forward<FxArgs>(fxargs)...);
|
||||
int nargs = static_cast<int>(sizeof...(Args));
|
||||
lua_pop(L, nargs);
|
||||
return push(L, std::forward<decltype(r)>(r));
|
||||
|
|
|
@ -68,7 +68,7 @@ public:
|
|||
|
||||
template<typename... Args>
|
||||
void open_libraries(Args&&... args) {
|
||||
static_assert(are_same<lib, Args...>::value, "all types must be libraries");
|
||||
static_assert(meta::are_same<lib, Args...>::value, "all types must be libraries");
|
||||
if(sizeof...(args) == 0) {
|
||||
luaL_openlibs(L);
|
||||
return;
|
||||
|
|
|
@ -38,7 +38,7 @@ class table_core : public reference {
|
|||
friend class state_view;
|
||||
|
||||
template <typename... Args>
|
||||
using is_global = And<Bool<top_level>, is_c_str<Args>...>;
|
||||
using is_global = meta::And<meta::Bool<top_level>, meta::is_c_str<Args>...>;
|
||||
|
||||
template<typename... Ret, std::size_t... I, typename Keys>
|
||||
auto tuple_get( types<Ret...>, std::index_sequence<I...>, Keys&& keys ) const
|
||||
|
@ -201,21 +201,21 @@ private:
|
|||
set_resolved_function<R( Args... )>( std::forward<Key>( key ), std::forward<Fx>( fx ) );
|
||||
}
|
||||
|
||||
template<typename Fx, typename Key, EnableIf<is_specialization_of<Unqualified<Fx>, overload_set>> = 0>
|
||||
template<typename Fx, typename Key, meta::EnableIf<meta::is_specialization_of<meta::Unqualified<Fx>, overload_set>> = 0>
|
||||
void set_fx( types<>, Key&& key, Fx&& fx ) {
|
||||
set(std::forward<Key>(key), std::forward<Fx>(fx));
|
||||
}
|
||||
|
||||
template<typename Fx, typename Key, DisableIf<is_specialization_of<Unqualified<Fx>, overload_set>> = 0>
|
||||
template<typename Fx, typename Key, meta::DisableIf<meta::is_specialization_of<meta::Unqualified<Fx>, overload_set>> = 0>
|
||||
void set_fx( types<>, Key&& key, Fx&& fx ) {
|
||||
typedef Unwrapped<Unqualified<Fx>> fx_t;
|
||||
typedef meta::Unwrapped<meta::Unqualified<Fx>> fx_t;
|
||||
typedef decltype( &fx_t::operator() ) Sig;
|
||||
set_fx( types<function_signature_t<Sig>>( ), std::forward<Key>( key ), std::forward<Fx>( fx ) );
|
||||
set_fx( types<meta::function_signature_t<Sig>>( ), std::forward<Key>( key ), std::forward<Fx>( fx ) );
|
||||
}
|
||||
|
||||
template<typename... Sig, typename... Args, typename Key>
|
||||
void set_resolved_function( Key&& key, Args&&... args ) {
|
||||
set(std::forward<Key>(key), detail::function_pack<function_sig<Sig...>>(std::forward<Args>(args)...));
|
||||
set(std::forward<Key>(key), function_pack<function_sig<Sig...>>(std::forward<Args>(args)...));
|
||||
}
|
||||
};
|
||||
} // sol
|
||||
|
|
|
@ -28,6 +28,10 @@
|
|||
#include <functional>
|
||||
|
||||
namespace sol {
|
||||
template<std::size_t I>
|
||||
using Index = std::integral_constant<std::size_t, I>;
|
||||
|
||||
namespace meta {
|
||||
template<typename T>
|
||||
struct identity { typedef T type; };
|
||||
|
||||
|
@ -69,7 +73,7 @@ using remove_member_pointer_t = remove_member_pointer<T>;
|
|||
template<typename T, template<typename...> class Templ>
|
||||
struct is_specialization_of : std::false_type { };
|
||||
template<typename... T, template<typename...> class Templ>
|
||||
struct is_specialization_of<Templ<T...>, Templ> : std::true_type { };
|
||||
struct meta::is_specialization_of<Templ<T...>, Templ> : std::true_type { };
|
||||
|
||||
template<class T, class...>
|
||||
struct are_same : std::true_type { };
|
||||
|
@ -83,9 +87,6 @@ using Type = typename T::type;
|
|||
template<bool B>
|
||||
using Bool = std::integral_constant<bool, B>;
|
||||
|
||||
template<std::size_t I>
|
||||
using Index = std::integral_constant<std::size_t, I>;
|
||||
|
||||
template<typename T>
|
||||
using Not = Bool<!T::value>;
|
||||
|
||||
|
@ -338,6 +339,24 @@ using is_string_constructible = Or<std::is_same<Unqualified<T>, const char*>, st
|
|||
template <typename T>
|
||||
using is_c_str = Or<std::is_same<std::decay_t<Unqualified<T>>, char*>, std::is_same<Unqualified<T>, std::string>>;
|
||||
|
||||
namespace detail {
|
||||
template <typename T, meta::DisableIf<meta::is_specialization_of<meta::Unqualified<T>, std::tuple>> = 0>
|
||||
decltype(auto) force_tuple(T&& x) {
|
||||
return std::forward_as_tuple(x);
|
||||
}
|
||||
|
||||
template <typename T, meta::EnableIf<meta::is_specialization_of<meta::Unqualified<T>, std::tuple>> = 0>
|
||||
decltype(auto) force_tuple(T&& x) {
|
||||
return std::forward<T>(x);
|
||||
}
|
||||
} // detail
|
||||
|
||||
template <typename... X>
|
||||
decltype(auto) tuplefy(X&&... x ) {
|
||||
return std::tuple_cat(detail::force_tuple(x)...);
|
||||
}
|
||||
} // meta
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
auto unwrap(T&& item) -> decltype(std::forward<T>(item)) {
|
||||
return std::forward<T>(item);
|
||||
|
@ -349,7 +368,7 @@ T& unwrap(std::reference_wrapper<T> arg) {
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
T& deref(T& item) {
|
||||
decltype(auto) deref(T&& item) {
|
||||
return item;
|
||||
}
|
||||
|
||||
|
@ -392,23 +411,7 @@ template<typename T>
|
|||
inline T* ptr(T* val) {
|
||||
return val;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template <typename T, DisableIf<is_specialization_of<Unqualified<T>, std::tuple>> = 0>
|
||||
decltype(auto) force_tuple(T&& x) {
|
||||
return std::forward_as_tuple(x);
|
||||
}
|
||||
|
||||
template <typename T, EnableIf<is_specialization_of<Unqualified<T>, std::tuple>> = 0>
|
||||
decltype(auto) force_tuple(T&& x) {
|
||||
return std::forward<T>(x);
|
||||
}
|
||||
} // detail
|
||||
|
||||
template <typename... X>
|
||||
decltype(auto) tuplefy(X&&... x ) {
|
||||
return std::tuple_cat(detail::force_tuple(x)...);
|
||||
}
|
||||
} // sol
|
||||
|
||||
#endif // SOL_TRAITS_HPP
|
||||
|
|
|
@ -26,18 +26,19 @@
|
|||
#include <cstddef>
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
using swallow = std::initializer_list<int>;
|
||||
} // detail
|
||||
|
||||
template<typename... Args>
|
||||
struct types { typedef std::index_sequence_for<Args...> indices; static constexpr std::size_t size() { return sizeof...(Args); } };
|
||||
|
||||
namespace meta {
|
||||
namespace detail {
|
||||
template<typename... Args>
|
||||
struct tuple_types_ { typedef types<Args...> type; };
|
||||
|
||||
template<typename... Args>
|
||||
struct tuple_types_<std::tuple<Args...>> { typedef types<Args...> type; };
|
||||
|
||||
using swallow = std::initializer_list<int>;
|
||||
|
||||
} // detail
|
||||
|
||||
template<typename... Args>
|
||||
|
@ -51,9 +52,7 @@ using pop_front_type_t = typename pop_front_type<Arg>::type;
|
|||
|
||||
template<typename Arg, typename... Args>
|
||||
struct pop_front_type<types<Arg, Args...>> { typedef types<Args...> type; };
|
||||
|
||||
|
||||
|
||||
} // meta
|
||||
} // sol
|
||||
|
||||
#endif // SOL_TUPLE_HPP
|
||||
|
|
|
@ -186,7 +186,7 @@ template <typename T>
|
|||
struct lua_type_of<T, std::enable_if_t<std::is_enum<T>::value>> : std::integral_constant<type, type::number> {};
|
||||
|
||||
template <typename T>
|
||||
struct is_lua_primitive : std::integral_constant<bool, type::userdata != lua_type_of<Unqualified<T>>::value> { };
|
||||
struct is_lua_primitive : std::integral_constant<bool, type::userdata != lua_type_of<meta::Unqualified<T>>::value> { };
|
||||
|
||||
template <typename T>
|
||||
struct is_proxy_primitive : is_lua_primitive<T> { };
|
||||
|
@ -199,7 +199,7 @@ struct is_proxy_primitive<std::tuple<Args...>> : std::true_type { };
|
|||
|
||||
template<typename T>
|
||||
inline type type_of() {
|
||||
return lua_type_of<Unqualified<T>>::value;
|
||||
return lua_type_of<meta::Unqualified<T>>::value;
|
||||
}
|
||||
|
||||
inline type type_of(lua_State* L, int index) {
|
||||
|
|
|
@ -102,7 +102,7 @@ template <typename... Args>
|
|||
struct is_constructor<constructor_wrapper<Args...>> : std::true_type {};
|
||||
|
||||
template <typename... Args>
|
||||
using has_constructor = Or<is_constructor<Unqualified<Args>>...>;
|
||||
using has_constructor = meta::Or<is_constructor<meta::Unqualified<Args>>...>;
|
||||
|
||||
template <typename T>
|
||||
struct is_destructor : std::false_type {};
|
||||
|
@ -111,7 +111,7 @@ template <typename Fx>
|
|||
struct is_destructor<destructor_wrapper<Fx>> : std::true_type {};
|
||||
|
||||
template <typename... Args>
|
||||
using has_destructor = Or<is_destructor<Unqualified<Args>>...>;
|
||||
using has_destructor = meta::Or<is_destructor<meta::Unqualified<Args>>...>;
|
||||
|
||||
template<typename T, bool refmeta, typename Funcs, typename FuncTable, typename MetaFuncTable>
|
||||
inline void push_metatable(lua_State* L, bool needsindexfunction, Funcs&& funcs, FuncTable&& functable, MetaFuncTable&& metafunctable) {
|
||||
|
@ -168,13 +168,13 @@ inline void set_global_deleter(lua_State* L, lua_CFunction cleanup, Functions&&
|
|||
template<typename T>
|
||||
class usertype {
|
||||
private:
|
||||
typedef std::map<std::string, std::pair<bool, base_function*>> function_map_t;
|
||||
typedef std::map<std::string, std::pair<bool, function_detail::base_function*>> function_map_t;
|
||||
std::vector<std::string> functionnames;
|
||||
std::vector<std::unique_ptr<base_function>> functions;
|
||||
std::vector<std::unique_ptr<function_detail::base_function>> functions;
|
||||
std::vector<luaL_Reg> functiontable;
|
||||
std::vector<luaL_Reg> metafunctiontable;
|
||||
base_function* indexfunc;
|
||||
base_function* newindexfunc;
|
||||
function_detail::base_function* indexfunc;
|
||||
function_detail::base_function* newindexfunc;
|
||||
function_map_t indexwrapper, newindexwrapper;
|
||||
lua_CFunction constructfunc;
|
||||
const char* destructfuncname;
|
||||
|
@ -183,51 +183,51 @@ private:
|
|||
bool needsindexfunction;
|
||||
|
||||
template<typename... Functions>
|
||||
std::unique_ptr<base_function> make_function(const std::string&, overload_set<Functions...> func) {
|
||||
return std::make_unique<usertype_overloaded_function<T, Functions...>>(std::move(func));
|
||||
std::unique_ptr<function_detail::base_function> make_function(const std::string&, overload_set<Functions...> func) {
|
||||
return std::make_unique<function_detail::usertype_overloaded_function<T, Functions...>>(std::move(func));
|
||||
}
|
||||
|
||||
template<typename... Functions>
|
||||
std::unique_ptr<base_function> make_function(const std::string&, constructor_wrapper<Functions...> func) {
|
||||
return std::make_unique<usertype_constructor_function<T, Functions...>>(std::move(func));
|
||||
std::unique_ptr<function_detail::base_function> make_function(const std::string&, constructor_wrapper<Functions...> func) {
|
||||
return std::make_unique<function_detail::usertype_constructor_function<T, Functions...>>(std::move(func));
|
||||
}
|
||||
|
||||
template<typename Arg, typename... Args, typename Ret>
|
||||
std::unique_ptr<base_function> make_function(const std::string&, Ret(*func)(Arg, Args...)) {
|
||||
typedef Unqualified<std::remove_pointer_t<Arg>> Argu;
|
||||
std::unique_ptr<function_detail::base_function> make_function(const std::string&, Ret(*func)(Arg, Args...)) {
|
||||
typedef meta::Unqualified<std::remove_pointer_t<Arg>> Argu;
|
||||
static_assert(std::is_base_of<Argu, T>::value, "Any non-member-function must have a first argument which is covariant with the desired userdata type.");
|
||||
typedef std::decay_t<decltype(func)> function_type;
|
||||
return std::make_unique<usertype_function<function_type, T>>(func);
|
||||
return std::make_unique<function_detail::usertype_function<function_type, T>>(func);
|
||||
}
|
||||
|
||||
template<typename Base, typename Ret>
|
||||
std::unique_ptr<base_function> make_variable_function(std::true_type, const std::string&, Ret Base::* func) {
|
||||
std::unique_ptr<function_detail::base_function> make_variable_function(std::true_type, const std::string&, Ret Base::* func) {
|
||||
static_assert(std::is_base_of<Base, T>::value, "Any registered function must be part of the class");
|
||||
typedef std::decay_t<decltype(func)> function_type;
|
||||
return std::make_unique<usertype_variable_function<function_type, T>>(func);
|
||||
return std::make_unique<function_detail::usertype_variable_function<function_type, T>>(func);
|
||||
}
|
||||
|
||||
template<typename Base, typename Ret>
|
||||
std::unique_ptr<base_function> make_variable_function(std::false_type, const std::string&, Ret Base::* func) {
|
||||
std::unique_ptr<function_detail::base_function> make_variable_function(std::false_type, const std::string&, Ret Base::* func) {
|
||||
static_assert(std::is_base_of<Base, T>::value, "Any registered function must be part of the class");
|
||||
typedef std::decay_t<decltype(func)> function_type;
|
||||
return std::make_unique<usertype_function<function_type, T>>(func);
|
||||
return std::make_unique<function_detail::usertype_function<function_type, T>>(func);
|
||||
}
|
||||
|
||||
template<typename Base, typename Ret>
|
||||
std::unique_ptr<base_function> make_function(const std::string& name, Ret Base::* func) {
|
||||
std::unique_ptr<function_detail::base_function> make_function(const std::string& name, Ret Base::* func) {
|
||||
typedef std::decay_t<decltype(func)> function_type;
|
||||
return make_variable_function(std::is_member_object_pointer<function_type>(), name, func);
|
||||
}
|
||||
|
||||
template<typename Fx>
|
||||
std::unique_ptr<base_function> make_function(const std::string&, Fx&& func) {
|
||||
typedef Unqualified<Fx> Fxu;
|
||||
typedef std::tuple_element_t<0, typename function_traits<Fxu>::args_tuple_type> Arg0;
|
||||
typedef Unqualified<std::remove_pointer_t<Arg0>> Argu;
|
||||
std::unique_ptr<function_detail::base_function> make_function(const std::string&, Fx&& func) {
|
||||
typedef meta::Unqualified<Fx> Fxu;
|
||||
typedef std::tuple_element_t<0, typename meta::function_traits<Fxu>::args_tuple_type> Arg0;
|
||||
typedef meta::Unqualified<std::remove_pointer_t<Arg0>> Argu;
|
||||
static_assert(std::is_base_of<Argu, T>::value, "Any non-member-function must have a first argument which is covariant with the desired usertype.");
|
||||
typedef std::decay_t<Fxu> function_type;
|
||||
return std::make_unique<usertype_function<function_type, T>>(func);
|
||||
return std::make_unique<function_detail::usertype_function<function_type, T>>(func);
|
||||
}
|
||||
|
||||
template<std::size_t N, typename... Args>
|
||||
|
@ -236,7 +236,7 @@ private:
|
|||
std::string& name = functionnames.back();
|
||||
// Insert bubble to keep with compile-time argument count (simpler and cheaper to do)
|
||||
functions.push_back(nullptr);
|
||||
constructfunc = construct<T, Args...>;
|
||||
constructfunc = function_detail::construct<T, Args...>;
|
||||
metafunctiontable.push_back({ functionnames.back().c_str(), constructfunc });
|
||||
}
|
||||
|
||||
|
@ -251,7 +251,7 @@ private:
|
|||
|
||||
functionnames.push_back(std::move(funcname));
|
||||
std::string& name = functionnames.back();
|
||||
destructfunc = destruct<T>;
|
||||
destructfunc = function_detail::destruct<T>;
|
||||
destructfuncname = name.c_str();
|
||||
// Insert bubble to stay with the compile-time count
|
||||
functions.push_back(nullptr);
|
||||
|
@ -270,25 +270,25 @@ private:
|
|||
std::string& name = functionnames.back();
|
||||
auto baseptr = make_function(name, std::move(dx.fx));
|
||||
functions.emplace_back(std::move(baseptr));
|
||||
destructfunc = detail::usertype_call<N>;
|
||||
destructfunc = function_detail::usertype_call<N>;
|
||||
destructfuncname = name.c_str();
|
||||
}
|
||||
|
||||
template<std::size_t N, typename Fx>
|
||||
void build_function(std::string funcname, Fx&& func) {
|
||||
typedef std::is_member_object_pointer<Unqualified<Fx>> is_variable;
|
||||
typedef std::is_member_object_pointer<meta::Unqualified<Fx>> is_variable;
|
||||
functionnames.push_back(std::move(funcname));
|
||||
std::string& name = functionnames.back();
|
||||
auto baseptr = make_function(name, std::forward<Fx>(func));
|
||||
functions.emplace_back(std::move(baseptr));
|
||||
auto metamethodfind = std::find(meta_function_names.begin(), meta_function_names.end(), name);
|
||||
if (metamethodfind != meta_function_names.end()) {
|
||||
metafunctiontable.push_back({ name.c_str(), detail::usertype_call<N> });
|
||||
metafunctiontable.push_back({ name.c_str(), function_detail::usertype_call<N> });
|
||||
meta_function metafunction = static_cast<meta_function>(metamethodfind - meta_function_names.begin());
|
||||
switch (metafunction) {
|
||||
case meta_function::garbage_collect:
|
||||
destructfuncname = name.c_str();
|
||||
destructfunc = detail::usertype_call<N>;
|
||||
destructfunc = function_detail::usertype_call<N>;
|
||||
return;
|
||||
case meta_function::index:
|
||||
indexfunc = functions.back().get();
|
||||
|
@ -298,7 +298,7 @@ private:
|
|||
newindexfunc = functions.back().get();
|
||||
break;
|
||||
case meta_function::construct:
|
||||
constructfunc = detail::usertype_call<N>;
|
||||
constructfunc = function_detail::usertype_call<N>;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -312,7 +312,7 @@ private:
|
|||
return;
|
||||
}
|
||||
indexwrapper.insert({ name, { true, functions.back().get() } });
|
||||
functiontable.push_back({ name.c_str(), detail::usertype_call<N> });
|
||||
functiontable.push_back({ name.c_str(), function_detail::usertype_call<N> });
|
||||
}
|
||||
|
||||
template<std::size_t N, typename Fx, typename... Args>
|
||||
|
@ -332,13 +332,13 @@ private:
|
|||
void build_function_tables() {
|
||||
int variableend = 0;
|
||||
if (!indexwrapper.empty()) {
|
||||
functions.push_back(std::make_unique<usertype_indexing_function>("__index", indexfunc, std::move(indexwrapper)));
|
||||
metafunctiontable.push_back({ "__index", detail::usertype_call<N> });
|
||||
functions.push_back(std::make_unique<function_detail::usertype_indexing_function>("__index", indexfunc, std::move(indexwrapper)));
|
||||
metafunctiontable.push_back({ "__index", function_detail::usertype_call<N> });
|
||||
++variableend;
|
||||
}
|
||||
if (!newindexwrapper.empty()) {
|
||||
functions.push_back(std::make_unique<usertype_indexing_function>("__newindex", newindexfunc, std::move(newindexwrapper)));
|
||||
metafunctiontable.push_back({ "__newindex", indexwrapper.empty() ? detail::usertype_call<N> : detail::usertype_call<N + 1> });
|
||||
functions.push_back(std::make_unique<function_detail::usertype_indexing_function>("__newindex", newindexfunc, std::move(newindexwrapper)));
|
||||
metafunctiontable.push_back({ "__newindex", indexwrapper.empty() ? function_detail::usertype_call<N> : function_detail::usertype_call<N + 1> });
|
||||
++variableend;
|
||||
}
|
||||
if (destructfunc != nullptr) {
|
||||
|
@ -346,13 +346,13 @@ private:
|
|||
}
|
||||
switch (variableend) {
|
||||
case 2:
|
||||
functiongcfunc = detail::usertype_gc<N + 2>;
|
||||
functiongcfunc = function_detail::usertype_gc<N + 2>;
|
||||
break;
|
||||
case 1:
|
||||
functiongcfunc = detail::usertype_gc<N + 1>;
|
||||
functiongcfunc = function_detail::usertype_gc<N + 1>;
|
||||
break;
|
||||
case 0:
|
||||
functiongcfunc = detail::usertype_gc<N + 0>;
|
||||
functiongcfunc = function_detail::usertype_gc<N + 0>;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -372,12 +372,12 @@ private:
|
|||
usertype(usertype_detail::add_destructor_tag, Args&&... args) : usertype(usertype_detail::verified, "__gc", default_destructor, std::forward<Args>(args)...) {}
|
||||
|
||||
template<typename... Args>
|
||||
usertype(usertype_detail::check_destructor_tag, Args&&... args) : usertype(If<And<std::is_destructible<T>, Not<usertype_detail::has_destructor<Args...>>>, usertype_detail::add_destructor_tag, usertype_detail::verified_tag>(), std::forward<Args>(args)...) {}
|
||||
usertype(usertype_detail::check_destructor_tag, Args&&... args) : usertype(meta::If<meta::And<std::is_destructible<T>, meta::Not<usertype_detail::has_destructor<Args...>>>, usertype_detail::add_destructor_tag, usertype_detail::verified_tag>(), std::forward<Args>(args)...) {}
|
||||
|
||||
public:
|
||||
|
||||
template<typename... Args>
|
||||
usertype(Args&&... args) : usertype(If<And<std::is_default_constructible<T>, Not<usertype_detail::has_constructor<Args...>>>, decltype(default_constructor), usertype_detail::check_destructor_tag>(), std::forward<Args>(args)...) {}
|
||||
usertype(Args&&... args) : usertype(meta::If<meta::And<std::is_default_constructible<T>, meta::Not<usertype_detail::has_constructor<Args...>>>, decltype(default_constructor), usertype_detail::check_destructor_tag>(), std::forward<Args>(args)...) {}
|
||||
|
||||
template<typename... Args, typename... CArgs>
|
||||
usertype(constructors<CArgs...> constructorlist, Args&&... args) : usertype(usertype_detail::verified, "new", constructorlist, "__gc", default_destructor, std::forward<Args>(args)...) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user