From 2b69a03c466a37c8fd5fe290ec64f1cff9cf14da Mon Sep 17 00:00:00 2001 From: ThePhD Date: Thu, 7 Jul 2016 20:11:18 -0400 Subject: [PATCH] Renew single inside of repository --- single/sol/sol.hpp | 819 +++++++++++++++++++++++++++------------------ 1 file changed, 488 insertions(+), 331 deletions(-) diff --git a/single/sol/sol.hpp b/single/sol/sol.hpp index 481fc8ba..99cd2394 100644 --- a/single/sol/sol.hpp +++ b/single/sol/sol.hpp @@ -20,8 +20,8 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // This file was generated with a script. -// Generated 2016-06-29 18:04:02.541304 UTC -// This header was generated with sol v2.8.9 (revision 833be87) +// Generated 2016-07-08 00:10:28.267637 UTC +// This header was generated with sol v2.9.0 (revision f7108d5) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -2937,9 +2937,9 @@ namespace sol { template struct function_sig {}; - struct up_value_index { + struct upvalue_index { int index; - up_value_index(int idx) : index(lua_upvalueindex(idx)) {} + upvalue_index(int idx) : index(lua_upvalueindex(idx)) {} operator int() const { return index; } }; @@ -2982,9 +2982,10 @@ namespace sol { struct user { U value; - user(U x) : value(std::forward(x)) {} + user(U x) : value(std::move(x)) {} operator U* () { return std::addressof(value); } operator U& () { return value; } + operator const U& () const { return value; } }; template @@ -3380,12 +3381,16 @@ namespace sol { || meta::is_specialization_of>::value > { }; + template + struct is_lua_primitive : std::true_type {}; template struct is_lua_primitive> : std::true_type { }; template - struct is_lua_primitive> : std::true_type {}; + struct is_lua_primitive> : std::true_type { }; template - struct is_lua_primitive : std::true_type {}; + struct is_lua_primitive> : is_lua_primitive { }; + template + struct is_lua_primitive> : std::true_type {}; template <> struct is_lua_primitive : std::true_type {}; template <> @@ -3800,6 +3805,10 @@ namespace sol { typedef T& type; }; template + struct strip> { + typedef T& type; + }; + template struct strip> { typedef T type; }; @@ -3915,7 +3924,7 @@ namespace sol { template inline int alloc_destroy(lua_State* L) { - void* rawdata = lua_touserdata(L, up_value_index(1)); + void* rawdata = lua_touserdata(L, upvalue_index(1)); T* data = static_cast(rawdata); std::allocator alloc; alloc.destroy(data); @@ -4677,7 +4686,7 @@ namespace sol { template decltype(auto) overload(Args&&... args) { - return overload_set(std::forward(args)...); + return overload_set...>(std::forward(args)...); } } @@ -5160,6 +5169,11 @@ namespace sol { inline std::unique_ptr make_unique_deleter(Args&&... args) { return std::unique_ptr(new T(std::forward(args)...)); } + + template + struct constructors_for { + List l; + }; } // detail template @@ -5464,8 +5478,9 @@ namespace sol { static int push_with(lua_State* L, Args&&... args) { // A dumb pusher void* rawdata = lua_newuserdata(L, sizeof(T)); + T* data = static_cast(rawdata); std::allocator alloc; - alloc.construct(static_cast(rawdata), std::forward(args)...); + alloc.construct(data, std::forward(args)...); if (with_meta) { lua_CFunction cdel = stack_detail::alloc_destroy; // Make sure we have a plain GC set for this data @@ -5478,6 +5493,11 @@ namespace sol { return 1; } + template + static int push(lua_State* L, Args&&... args) { + return push_with(L, std::forward(args)...); + } + static int push(lua_State* L, const user& u) { return push_with(L, u.value); } @@ -6054,7 +6074,7 @@ namespace sol { typedef std::array data_t; data_t voiddata{ {} }; for (std::size_t i = 0, d = 0; d < sizeof(T); ++i, d += sizeof(void*)) { - voiddata[i] = get(L, up_value_index(index++)); + voiddata[i] = get(L, upvalue_index(index++)); } return std::pair(*reinterpret_cast(static_cast(voiddata.data())), index); } @@ -6522,83 +6542,10 @@ namespace sol { return name; } - struct base_function { - virtual int operator()(lua_State* L) { - return luaL_error(L, "sol: failure to call specialized wrapped C++ function from Lua"); - } - - virtual ~base_function() {} - }; - - static int base_call(lua_State* L, void* inheritancedata) { - if (inheritancedata == nullptr) { - return luaL_error(L, "sol: call from Lua to C++ function has null data"); - } - - base_function* pfx = static_cast(inheritancedata); - base_function& fx = *pfx; - return detail::trampoline(L, fx); - } - - static int base_gc(lua_State* L, void* udata) { - if (udata == nullptr) { - return luaL_error(L, "sol: call from lua to C++ gc function with null data"); - } - - base_function* ptr = static_cast(udata); - std::default_delete dx{}; - dx(ptr); - return 0; - } - - template - static void func_gc(std::true_type, lua_State*) { - - } - - template - static void func_gc(std::false_type, lua_State* L) { - for (std::size_t i = 0; i < limit; ++i) { - void* value = stack::get(L, up_value_index(static_cast(i + 1))); - if (value == nullptr) - continue; - base_function* obj = static_cast(value); - std::allocator alloc{}; - alloc.destroy(obj); - alloc.deallocate(obj, 1); - } - } - + template inline int call(lua_State* L) { - void* ludata = stack::get(L, up_value_index(1)); - void** pinheritancedata = static_cast(ludata); - return base_call(L, *pinheritancedata); - } - - inline int gc(lua_State* L) { - void* udata = stack::get(L, 1); - void** pudata = static_cast(udata); - return base_gc(L, *pudata); - } - - template - inline int usertype_call(lua_State* L) { - // Zero-based template parameter, but upvalues start at 1 - return base_call(L, stack::get(L, up_value_index(static_cast(I + 1)))); - } - - template - inline int usertype_gc(lua_State* L) { - func_gc(meta::boolean<(I < 1)>(), L); - return 0; - } - - inline void free_function_cleanup(lua_State* L) { - const static char* metatablename = &cleanup_key()[0]; - int metapushed = luaL_newmetatable(L, metatablename); - if (metapushed == 1) { - stack::set_field(L, "__gc", function_detail::gc); - } + Fx& fx = stack::get>(L, upvalue_index(1)); + return fx(L); } } // function_detail } // sol @@ -6609,6 +6556,24 @@ namespace sol { // beginning of sol\call.hpp +// beginning of sol\protect.hpp + +namespace sol { + + template + struct protect_t { + T value; + }; + + template + auto protect(T&& value) { + return protect_t>{ std::forward(value) }; + } + +} // sol + +// end of sol\protect.hpp + // beginning of sol\property.hpp namespace sol { @@ -6737,7 +6702,7 @@ namespace sol { return overload_match_arity(types(), std::index_sequence(), std::index_sequence(), std::forward(matchfx), L, fxarity, start, std::forward(args)...); } if (traits::free_arity != fxarity) { - return overload_match_arity(types(), std::index_sequence(), std::index_sequence(), std::forward(matchfx), L, fxarity, start, std::forward(args)...); + return overload_match_arity(types(), std::index_sequence(), std::index_sequence(), std::forward(matchfx), L, fxarity, start, std::forward(args)...); } if (!stack::stack_detail::check_types().check(args_list(), args_indices(), L, start, no_panic)) { return overload_match_arity(types(), std::index_sequence(), std::index_sequence(), std::forward(matchfx), L, fxarity, start, std::forward(args)...); @@ -6758,7 +6723,7 @@ namespace sol { } template - inline int construct(Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) { + inline int construct_match(Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) { // use same overload resolution matching as all other parts of the framework return overload_match_arity::call)...>(std::forward(matchfx), L, fxarity, start, std::forward(args)...); } @@ -6777,7 +6742,7 @@ namespace sol { reference userdataref(L, -1); userdataref.pop(); - construct(constructor_match(obj), L, argcount, 1 + static_cast(syntax)); + construct_match(constructor_match(obj), L, argcount, 1 + static_cast(syntax)); userdataref.push(); luaL_getmetatable(L, &meta[0]); @@ -6790,14 +6755,14 @@ namespace sol { return 1; } - template + template struct agnostic_lua_call_wrapper { static int var_call(std::true_type, lua_State* L, F& f) { typedef wrapper> wrap; typedef typename wrap::returns_list returns_list; typedef typename wrap::free_args_list args_list; typedef typename wrap::caller caller; - return stack::call_into_lua(returns_list(), args_list(), L, is_index ? 2 : 3, caller(), f); + return stack::call_into_lua(returns_list(), args_list(), L, is_index ? 2 : 3, caller(), f); } static int var_call(std::false_type, lua_State* L, F& f) { @@ -6805,7 +6770,7 @@ namespace sol { typedef typename wrap::free_args_list args_list; typedef typename wrap::returns_list returns_list; typedef typename wrap::caller caller; - return stack::call_into_lua(returns_list(), args_list(), L, 1, caller(), f); + return stack::call_into_lua<0, checked>(returns_list(), args_list(), L, 1, caller(), f); } static int call(lua_State* L, F& f) { @@ -6813,78 +6778,80 @@ namespace sol { } }; - template - struct agnostic_lua_call_wrapper { + template + struct agnostic_lua_call_wrapper { static int call(lua_State* L, lua_r_CFunction f) { return f(L); } }; - template - struct agnostic_lua_call_wrapper { + template + struct agnostic_lua_call_wrapper { static int call(lua_State* L, lua_CFunction f) { return f(L); } }; - template - struct agnostic_lua_call_wrapper { + template + struct agnostic_lua_call_wrapper { static int call(lua_State* L, const no_prop&) { return luaL_error(L, is_index ? "sol: cannot read from a writeonly property" : "sol: cannot write to a readonly property"); } }; - template - struct agnostic_lua_call_wrapper { + template + struct agnostic_lua_call_wrapper { static int call(lua_State* L, const no_construction&) { return luaL_error(L, "sol: cannot call this constructor (tagged as non-constructible)"); } }; - template - struct agnostic_lua_call_wrapper, is_index, is_variable, C> { + template + struct agnostic_lua_call_wrapper, is_index, is_variable, checked, C> { static int call(lua_State*, const bases&) { // Uh. How did you even call this, lul return 0; } }; - template - struct lua_call_wrapper : agnostic_lua_call_wrapper {}; + template + struct lua_call_wrapper : agnostic_lua_call_wrapper {}; - template - struct lua_call_wrapper::value>> { + template + struct lua_call_wrapper::value>> { static int call(lua_State* L, F& f) { typedef wrapper> wrap; typedef typename wrap::returns_list returns_list; typedef typename wrap::args_list args_list; typedef typename wrap::caller caller; typedef typename wrap::object_type object_type; + typedef std::conditional_t::value, object_type, T> Ta; #ifdef SOL_SAFE_USERTYPE - object_type* o = static_cast(stack::get(L, 1)); + object_type* o = static_cast(stack::get(L, 1)); if (o == nullptr) { return luaL_error(L, "sol: received null for 'self' argument (use ':' for accessing member functions, make sure member variables are preceeded by the actual object with '.' syntax)"); } - return stack::call_into_lua(returns_list(), args_list(), L, is_variable ? 3 : 2, caller(), f, *o); + return stack::call_into_lua(returns_list(), args_list(), L, is_variable ? 3 : 2, caller(), f, *o); #else - object_type& o = static_cast(stack::get(L, 1)); - return stack::call_into_lua(returns_list(), args_list(), L, is_variable ? 3 : 2, caller(), f, o); + object_type& o = static_cast(stack::get(L, 1)); + return stack::call_into_lua(returns_list(), args_list(), L, is_variable ? 3 : 2, caller(), f, o); #endif // Safety } }; - template - struct lua_call_wrapper::value>> { + template + struct lua_call_wrapper::value>> { typedef sol::lua_bind_traits traits_type; static int call_assign(std::true_type, lua_State* L, F& f) { typedef wrapper> wrap; typedef typename wrap::args_list args_list; typedef typename wrap::object_type object_type; + typedef std::conditional_t::value, object_type, T> Ta; typedef typename wrap::caller caller; #ifdef SOL_SAFE_USERTYPE - object_type* o = static_cast(stack::get(L, 1)); + object_type* o = static_cast(stack::get(L, 1)); if (o == nullptr) { if (is_variable) { return luaL_error(L, "sol: received nil for 'self' argument (bad '.' access?)"); @@ -6893,7 +6860,7 @@ namespace sol { } return stack::call_into_lua(types(), args_list(), L, is_variable ? 3 : 2, caller(), f, *o); #else - object_type& o = static_cast(stack::get(L, 1)); + object_type& o = static_cast(stack::get(L, 1)); return stack::call_into_lua(types(), args_list(), L, is_variable ? 3 : 2, caller(), f, o); #endif // Safety } @@ -6916,8 +6883,8 @@ namespace sol { } }; - template - struct lua_call_wrapper::value>> { + template + struct lua_call_wrapper::value>> { typedef sol::lua_bind_traits traits_type; static int call(lua_State* L, F& f) { @@ -6933,16 +6900,16 @@ namespace sol { } return luaL_error(L, "sol: 'self' argument is nil (pass 'self' as first argument)"); } - return stack::call_into_lua(returns_list(), types<>(), L, is_variable ? 3 : 2, caller(), f, *o); + return stack::call_into_lua(returns_list(), types<>(), L, is_variable ? 3 : 2, caller(), f, *o); #else object_type& o = static_cast(stack::get(L, 1)); - return stack::call_into_lua(returns_list(), types<>(), L, is_variable ? 3 : 2, caller(), f, o); + return stack::call_into_lua(returns_list(), types<>(), L, is_variable ? 3 : 2, caller(), f, o); #endif // Safety } }; - template - struct lua_call_wrapper, is_index, is_variable, C> { + template + struct lua_call_wrapper, is_index, is_variable, checked, C> { typedef sol::constructor_list F; static int call(lua_State* L, F&) { @@ -6957,7 +6924,7 @@ namespace sol { T* obj = reinterpret_cast(pointerpointer + 1); referencepointer = obj; - construct(constructor_match(obj), L, argcount, 1 + static_cast(syntax)); + construct_match(constructor_match(obj), L, argcount, 1 + static_cast(syntax)); userdataref.push(); luaL_getmetatable(L, &metakey[0]); @@ -6971,8 +6938,8 @@ namespace sol { } }; - template - struct lua_call_wrapper, is_index, is_variable, C> { + template + struct lua_call_wrapper, is_index, is_variable, checked, C> { typedef sol::constructor_wrapper F; struct onmatch { @@ -6986,7 +6953,7 @@ namespace sol { referencepointer = obj; auto& func = std::get(f.set); - stack::call_into_lua<1, false>(r, a, L, start, func, detail::implicit_wrapper(obj)); + stack::call_into_lua<1, checked>(r, a, L, start, func, detail::implicit_wrapper(obj)); userdataref.push(); luaL_getmetatable(L, &metakey[0]); @@ -7006,13 +6973,13 @@ namespace sol { call_syntax syntax = stack::get_call_syntax(L, usertype_traits::metatable); int syntaxval = static_cast(syntax); int argcount = lua_gettop(L) - syntaxval; - return construct>...>(onmatch(), L, argcount, 1 + syntaxval, f); + return construct_match>...>(onmatch(), L, argcount, 1 + syntaxval, f); } }; - template - struct lua_call_wrapper, is_index, is_variable, std::enable_if_t::value>> { + template + struct lua_call_wrapper, is_index, is_variable, checked, std::enable_if_t::value>> { typedef sol::destructor_wrapper F; static int call(lua_State* L, const F&) { @@ -7020,8 +6987,8 @@ namespace sol { } }; - template - struct lua_call_wrapper, is_index, is_variable, std::enable_if_t::value>> { + template + struct lua_call_wrapper, is_index, is_variable, checked, std::enable_if_t::value>> { typedef sol::destructor_wrapper F; static int call(lua_State* L, const F& f) { @@ -7031,15 +6998,15 @@ namespace sol { } }; - template - struct lua_call_wrapper, is_index, is_variable, C> { + template + struct lua_call_wrapper, is_index, is_variable, checked, C> { typedef overload_set F; struct on_match { template int operator()(types, index_value, types, types, lua_State* L, int, int, F& fx) { auto& f = std::get(fx.set); - return lua_call_wrapper{}.call(L, f); + return lua_call_wrapper{}.call(L, f); } }; @@ -7048,11 +7015,26 @@ namespace sol { } }; + template + struct lua_call_wrapper, is_index, is_variable, checked, C> { + typedef protect_t F; + + static int call(lua_State* L, F& fx) { + return lua_call_wrapper{}.call(L, fx.value); + } + }; + template - int call_wrapped(lua_State* L, Fx&& fx) { + inline int call_wrapped(lua_State* L, Fx&& fx) { return lua_call_wrapper, is_index, is_variable>{}.call(L, std::forward(fx)); } + template + inline int call_user(lua_State* L) { + auto& fx = stack::get>(L, upvalue_index(1)); + return call_wrapped(L, fx); + } + template struct is_var_bind : std::false_type {}; @@ -7198,7 +7180,7 @@ namespace sol { // end of sol\function_types_templated.hpp -// beginning of sol\function_types_basic.hpp +// beginning of sol\function_types_stateless.hpp namespace sol { namespace function_detail { @@ -7323,12 +7305,7 @@ namespace sol { // idx 1...n: verbatim data of member variable pointer auto memberdata = stack::stack_detail::get_as_upvalues(L, 1); function_type& memfx = memberdata.first; - auto fx = [&L, &memfx](auto&&... args) -> typename traits_type::return_type { - auto& item = stack::get(L, 1); - return (item.*memfx)(std::forward(args)...); - }; - int n = stack::call_into_lua<1>(meta::tuple_types(), typename traits_type::args_list(), L, 2, fx); - return n; + return call_detail::call_wrapped(L, memfx); } static int call(lua_State* L) { @@ -7375,146 +7352,130 @@ namespace sol { } // function_detail } // sol -// end of sol\function_types_basic.hpp +// end of sol\function_types_stateless.hpp -// beginning of sol\function_types_member.hpp +// beginning of sol\function_types_stateful.hpp namespace sol { -namespace function_detail { -template -struct free_function : public base_function { - typedef meta::unwrapped_t> Function; - typedef meta::function_return_t return_type; - typedef meta::function_args_t args_lists; - Function fx; + namespace function_detail { + template + struct functor_function { + typedef meta::unwrapped_t> Function; + typedef decltype(&Function::operator()) function_type; + typedef meta::function_return_t return_type; + typedef meta::function_args_t args_lists; + Function fx; - template - free_function(Args&&... args): fx(std::forward(args)...) {} + template + functor_function(Function f, Args&&... args) : fx(std::move(f), std::forward(args)...) {} - int call(lua_State* L) { - return stack::call_into_lua(meta::tuple_types(), args_lists(), L, 1, fx); - } + int call(lua_State* L) { + return stack::call_into_lua(meta::tuple_types(), args_lists(), L, 1, fx); + } - virtual int operator()(lua_State* L) override { - auto f = [&](lua_State* L) -> int { return this->call(L);}; - return detail::trampoline(L, f); - } -}; + int operator()(lua_State* L) { + auto f = [&](lua_State* L) -> int { return this->call(L); }; + return detail::trampoline(L, f); + } + }; -template -struct functor_function : public base_function { - typedef meta::unwrapped_t> Function; - typedef decltype(&Function::operator()) function_type; - typedef meta::function_return_t return_type; - typedef meta::function_args_t args_lists; - Function fx; + template + struct member_function { + typedef std::remove_pointer_t> function_type; + typedef meta::function_return_t return_type; + typedef meta::function_args_t args_lists; + struct functor { + function_type invocation; + T member; - template - functor_function(Args&&... args): fx(std::forward(args)...) {} + template + functor(function_type f, Args&&... args) : invocation(std::move(f)), member(std::forward(args)...) {} - int call(lua_State* L) { - return stack::call_into_lua(meta::tuple_types(), args_lists(), L, 1, fx); - } + template + return_type operator()(Args&&... args) { + auto& mem = detail::unwrap(detail::deref(member)); + return (mem.*invocation)(std::forward(args)...); + } + } fx; - virtual int operator()(lua_State* L) override { - auto f = [&](lua_State* L) -> int { return this->call(L);}; - return detail::trampoline(L, f); - } -}; + template + member_function(function_type f, Args&&... args) : fx(std::move(f), std::forward(args)...) {} -template -struct member_function : public base_function { - typedef std::remove_pointer_t> function_type; - typedef meta::function_return_t return_type; - typedef meta::function_args_t args_lists; - struct functor { - function_type invocation; - T member; - - template - functor(F&& f, Args&&... args): invocation(std::forward(f)), member(std::forward(args)...) {} + int call(lua_State* L) { + return stack::call_into_lua(meta::tuple_types(), args_lists(), L, 1, fx); + } - template - return_type operator()(Args&&... args) { - auto& mem = detail::unwrap(detail::deref(member)); - return (mem.*invocation)(std::forward(args)...); - } - } fx; + int operator()(lua_State* L) { + auto f = [&](lua_State* L) -> int { return this->call(L); }; + return detail::trampoline(L, f); + } - template - member_function(F&& f, Args&&... args) : fx(std::forward(f), std::forward(args)...) {} + ~member_function() { - int call(lua_State* L) { - return stack::call_into_lua(meta::tuple_types(), args_lists(), L, 1, fx); - } + } + }; - virtual int operator()(lua_State* L) override { - auto f = [&](lua_State* L) -> int { return this->call(L);}; - return detail::trampoline(L, f); - } -}; + template + struct member_variable { + typedef std::remove_pointer_t> function_type; + typedef typename meta::bind_traits::return_type return_type; + typedef typename meta::bind_traits::args_list args_lists; + function_type var; + T member; + typedef std::add_lvalue_reference_t>> M; -template -struct member_variable : public base_function { - typedef std::remove_pointer_t> function_type; - typedef typename meta::bind_traits::return_type return_type; - typedef typename meta::bind_traits::args_list args_lists; - function_type var; - T member; - typedef std::add_lvalue_reference_t>> M; + template + member_variable(function_type v, Args&&... args) : var(std::move(v)), member(std::forward(args)...) {} - template - member_variable(V&& v, Args&&... args): var(std::forward(v)), member(std::forward(args)...) {} + int set_assignable(std::false_type, lua_State* L, M) { + lua_pop(L, 1); + return luaL_error(L, "sol: cannot write to this type: copy assignment/constructor not available"); + } - int set_assignable(std::false_type, lua_State* L, M) { - lua_pop(L, 1); - return luaL_error(L, "sol: cannot write to this type: copy assignment/constructor not available"); - } + int set_assignable(std::true_type, lua_State* L, M mem) { + (mem.*var) = stack::get(L, 1); + lua_pop(L, 1); + return 0; + } - int set_assignable(std::true_type, lua_State* L, M mem) { - (mem.*var) = stack::get(L, 1); - lua_pop(L, 1); - return 0; - } + int set_variable(std::true_type, lua_State* L, M mem) { + return set_assignable(std::is_assignable, return_type>(), L, mem); + } - int set_variable(std::true_type, lua_State* L, M mem) { - return set_assignable(std::is_assignable, return_type>(), L, mem); - } + int set_variable(std::false_type, lua_State* L, M) { + lua_pop(L, 1); + return luaL_error(L, "sol: cannot write to a const variable"); + } - int set_variable(std::false_type, lua_State* L, M) { - lua_pop(L, 1); - return luaL_error(L, "sol: cannot write to a const variable"); - } + int call(lua_State* L) { + M mem = detail::unwrap(detail::deref(member)); + switch (lua_gettop(L)) { + case 0: + stack::push(L, (mem.*var)); + return 1; + case 1: + return set_variable(meta::neg>(), L, mem); + default: + return luaL_error(L, "sol: incorrect number of arguments to member variable function"); + } + } - int call(lua_State* L) { - M mem = detail::unwrap(detail::deref(member)); - switch (lua_gettop(L)) { - case 0: - stack::push(L, (mem.*var)); - return 1; - case 1: - return set_variable(meta::neg>(), L, mem); - default: - return luaL_error(L, "sol: incorrect number of arguments to member variable function"); - } - } - - virtual int operator()(lua_State* L) override { - auto f = [&](lua_State* L) -> int { return this->call(L);}; - return detail::trampoline(L, f); - } -}; -} // function_detail + int operator()(lua_State* L) { + auto f = [&](lua_State* L) -> int { return this->call(L); }; + return detail::trampoline(L, f); + } + }; + } // function_detail } // sol -// end of sol\function_types_member.hpp +// end of sol\function_types_stateful.hpp // beginning of sol\function_types_overloaded.hpp namespace sol { namespace function_detail { template - struct overloaded_function : base_function { + struct overloaded_function { typedef std::tuple overload_list; typedef std::make_index_sequence indices; overload_list overloads; @@ -7528,12 +7489,12 @@ namespace sol { } template - int call(types, index_value, types r, types a, lua_State* L, int, int start) { + int call(types, index_value, types, types, lua_State* L, int, int) { auto& func = std::get(overloads); - return stack::call_into_lua<0, false>(r, a, L, start, func); + return call_detail::call_wrapped(L, func); } - virtual int operator()(lua_State* L) override { + int operator()(lua_State* L) { auto mfx = [&](auto&&... args) { return this->call(std::forward(args)...); }; return call_detail::overload_match(mfx, L, 1); } @@ -7629,13 +7590,51 @@ namespace sol { } namespace stack { + template + struct pusher, std::enable_if_t::value && !std::is_void::value>> { + static int push(lua_State* L, property_wrapper pw) { + return stack::push(L, sol::overload(std::move(pw.read), std::move(pw.write))); + } + }; + + template + struct pusher> { + static int push(lua_State* L, property_wrapper pw) { + return stack::push(L, std::move(pw.read)); + } + }; + + template + struct pusher> { + static int push(lua_State* L, property_wrapper pw) { + return stack::push(L, std::move(pw.write)); + } + }; + + template + struct pusher>> { + static int push(lua_State* L, detail::constructors_for>) { + lua_CFunction cf = call_detail::construct; + return stack::push(L, cf); + } + }; + + template + struct pusher>> { + static int push(lua_State* L, constructor_wrapper c) { + lua_CFunction cf = call_detail::call_user; + int closures = stack::push(L, make_user(std::move(c))); + return stack::push(L, c_closure(cf, closures)); + } + }; + template struct pusher> { template static void select_convertible(std::false_type, types, lua_State* L, Fx&& fx, Args&&... args) { typedef std::remove_pointer_t> clean_fx; - std::unique_ptr sptr = std::make_unique>(std::forward(fx), std::forward(args)...); - set_fx(L, std::move(sptr)); + typedef function_detail::functor_function F; + set_fx(L, std::forward(fx), std::forward(args)...); } template @@ -7647,7 +7646,7 @@ namespace sol { template static void select_convertible(types t, lua_State* L, Fx&& fx, Args&&... args) { - typedef std::decay_t>> raw_fx_t; + typedef std::decay_t> raw_fx_t; typedef R(*fx_ptr_t)(A...); typedef std::is_convertible is_convertible; select_convertible(is_convertible(), t, L, std::forward(fx), std::forward(args)...); @@ -7655,15 +7654,15 @@ namespace sol { template static void select_convertible(types<>, lua_State* L, Fx&& fx, Args&&... args) { - typedef meta::function_signature_t>> Sig; + typedef meta::function_signature_t> Sig; select_convertible(types(), L, std::forward(fx), std::forward(args)...); } template static void select_reference_member_variable(std::false_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) { typedef std::remove_pointer_t> clean_fx; - std::unique_ptr sptr = std::make_unique, clean_fx>>(std::forward(fx), std::forward(obj), std::forward(args)...); - set_fx(L, std::move(sptr)); + typedef function_detail::member_variable, clean_fx> F; + set_fx(L, std::forward(fx), std::forward(obj), std::forward(args)...); } template @@ -7699,9 +7698,9 @@ namespace sol { template static void select_reference_member_function(std::false_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) { - typedef std::remove_pointer_t> clean_fx; - std::unique_ptr sptr = std::make_unique>, clean_fx>>(std::forward(fx), std::forward(obj), std::forward(args)...); - set_fx(L, std::move(sptr)); + typedef std::decay_t clean_fx; + typedef function_detail::member_function, clean_fx> F; + set_fx(L, std::forward(fx), std::forward(obj), std::forward(args)...); } template @@ -7758,14 +7757,11 @@ namespace sol { select_function(std::is_function>(), L, std::forward(fx), std::forward(args)...); } - static void set_fx(lua_State* L, std::unique_ptr luafunc) { - function_detail::base_function* target = luafunc.release(); - void* targetdata = static_cast(target); - lua_CFunction freefunc = function_detail::call; + template + static void set_fx(lua_State* L, Args&&... args) { + lua_CFunction freefunc = function_detail::call>; - stack::push(L, userdata_value(targetdata)); - function_detail::free_function_cleanup(L); - lua_setmetatable(L, -2); + stack::push>(L, std::forward(args)...); stack::push(L, c_closure(freefunc, 1)); } @@ -7816,12 +7812,14 @@ namespace sol { template struct pusher> { static int push(lua_State* L, overload_set&& set) { - pusher>{}.set_fx(L, std::make_unique>(std::move(set.set))); + typedef function_detail::overloaded_function F; + pusher>{}.set_fx(L, std::move(set.set)); return 1; } static int push(lua_State* L, const overload_set& set) { - pusher>{}.set_fx(L, std::make_unique>(set.set)); + typedef function_detail::overloaded_function F; + pusher>{}.set_fx(L, set.set); return 1; } }; @@ -8793,6 +8791,35 @@ namespace sol { else return luaL_error(L, "sol: attempt to index (set) nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.data()); } + + struct add_destructor_tag {}; + struct check_destructor_tag {}; + struct verified_tag {} const verified{}; + + template + struct is_constructor : std::false_type {}; + + template + struct is_constructor> : std::true_type {}; + + template + struct is_constructor> : std::true_type {}; + + template <> + struct is_constructor : std::true_type {}; + + template + using has_constructor = meta::any>...>; + + template + struct is_destructor : std::false_type {}; + + template + struct is_destructor> : std::true_type {}; + + template + using has_destructor = meta::any>...>; + } // usertype_detail template @@ -8855,7 +8882,7 @@ namespace sol { } template - void make_regs(regs_t&, int&, sol::call_construction, F&&) { + void make_regs(regs_t&, int&, call_construction, F&&) { callconstructfunc = call; secondarymeta = true; } @@ -8935,7 +8962,7 @@ namespace sol { } static int real_index_call(lua_State* L) { - usertype_metatable& f = stack::get>(L, up_value_index(1)); + usertype_metatable& f = stack::get>(L, upvalue_index(1)); if (stack::get(L, -1) == type::string) { string_detail::string_shim accessor = stack::get(L, -1); bool found = false; @@ -8949,7 +8976,7 @@ namespace sol { } static int real_new_index_call(lua_State* L) { - usertype_metatable& f = stack::get>(L, up_value_index(1)); + usertype_metatable& f = stack::get>(L, upvalue_index(1)); if (stack::get(L, -2) == type::string) { string_detail::string_shim accessor = stack::get(L, -2); bool found = false; @@ -8964,7 +8991,7 @@ namespace sol { template static int real_call(lua_State* L) { - usertype_metatable& f = stack::get>(L, up_value_index(1)); + usertype_metatable& f = stack::get>(L, upvalue_index(1)); return real_call_with(L, f); } @@ -9103,75 +9130,167 @@ namespace sol { // end of sol\usertype_metatable.hpp +// beginning of sol\simple_usertype_metatable.hpp + +#include + namespace sol { -namespace usertype_detail { -struct add_destructor_tag {}; -struct check_destructor_tag {}; -struct verified_tag {} const verified {}; -template -struct is_constructor : std::false_type {}; + struct simple_tag {} const simple{}; -template -struct is_constructor> : std::true_type {}; + template + struct simple_usertype_metatable : usertype_detail::registrar { + std::vector> registrations; + object callconstructfunc; + + template + void add(lua_State* L, N&& n, F&& f) { + registrations.emplace_back(make_object(L, std::forward(n)), make_object(L, std::forward(f))); + } -template -struct is_constructor> : std::true_type {}; + template + void add(lua_State* L, N&& n, constructor_wrapper c) { + registrations.emplace_back(make_object(L, std::forward(n)), make_object(L, detail::constructors_for>{std::move(c)})); + } -template <> -struct is_constructor : std::true_type {}; + template + void add(lua_State* L, N&& n, constructor_list c) { + registrations.emplace_back(make_object(L, std::forward(n)), make_object(L, detail::constructors_for>{std::move(c)})); + } -template -using has_constructor = meta::any>...>; + template + void add(lua_State* L, call_construction, F&& f) { + callconstructfunc = make_object(L, std::forward(f)); + } -template -struct is_destructor : std::false_type {}; + template + simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence, lua_State* L, Tuple&& args) + : callconstructfunc(nil) { + registrations.reserve(std::tuple_size>::value); + (void)detail::swallow{ 0, + (add(L, detail::forward_get(args), detail::forward_get(args)),0)... + }; + } -template -struct is_destructor> : std::true_type {}; + template + simple_usertype_metatable(usertype_detail::verified_tag v, lua_State* L, Args&&... args) : simple_usertype_metatable(v, std::make_index_sequence(), L, std::forward_as_tuple(std::forward(args)...)) {} -template -using has_destructor = meta::any>...>; -} // usertype_detail + template + simple_usertype_metatable(usertype_detail::add_destructor_tag, lua_State* L, Args&&... args) : simple_usertype_metatable(usertype_detail::verified, L, std::forward(args)..., "__gc", default_destructor) {} -template -class usertype { -private: - std::unique_ptr metatableregister; + template + simple_usertype_metatable(usertype_detail::check_destructor_tag, lua_State* L, Args&&... args) : simple_usertype_metatable(meta::condition, meta::neg>>, usertype_detail::add_destructor_tag, usertype_detail::verified_tag>(), L, std::forward(args)...) {} - template - usertype(usertype_detail::verified_tag, Args&&... args) : metatableregister( detail::make_unique_deleter, Args...>, detail::deleter>(std::forward(args)...) ) {} + public: - template - usertype(usertype_detail::add_destructor_tag, Args&&... args) : usertype(usertype_detail::verified, std::forward(args)..., "__gc", default_destructor) {} + template + simple_usertype_metatable(lua_State* L, Args&&... args) : simple_usertype_metatable(meta::condition, meta::neg>>, decltype(default_constructor), usertype_detail::check_destructor_tag>(), L, std::forward(args)...) {} - template - usertype(usertype_detail::check_destructor_tag, Args&&... args) : usertype(meta::condition, meta::neg>>, usertype_detail::add_destructor_tag, usertype_detail::verified_tag>(), std::forward(args)...) {} + template + simple_usertype_metatable(constructors constructorlist, lua_State* L, Args&&... args) : simple_usertype_metatable(usertype_detail::check_destructor_tag(), L, std::forward(args)..., "new", constructorlist) {} -public: + template + simple_usertype_metatable(constructor_wrapper constructorlist, lua_State* L, Args&&... args) : simple_usertype_metatable(usertype_detail::check_destructor_tag(), L, std::forward(args)..., "new", constructorlist) {} - template - usertype(Args&&... args) : usertype(meta::condition, meta::neg>>, decltype(default_constructor), usertype_detail::check_destructor_tag>(), std::forward(args)...) {} + virtual int push_um(lua_State* L) override { + return stack::push(L, std::move(*this)); + } + }; - template - usertype(constructors constructorlist, Args&&... args) : usertype(usertype_detail::check_destructor_tag(), std::forward(args)..., "new", constructorlist) {} + namespace stack { + template + struct pusher> { + typedef simple_usertype_metatable umt_t; + + static int push(lua_State* L, umt_t&& umx) { + for (std::size_t i = 0; i < 3; ++i) { + // Pointer types, AKA "references" from C++ + const char* metakey = nullptr; + switch (i) { + case 0: + metakey = &usertype_traits::metatable[0]; + break; + case 1: + metakey = &usertype_traits>::metatable[0]; + break; + case 2: + default: + metakey = &usertype_traits::metatable[0]; + break; + } + luaL_newmetatable(L, metakey); + stack_reference t(L, -1); + for (auto& kvp : umx.registrations) { + stack::set_field(L, kvp.first, kvp.second, t.stack_index()); + } - template - usertype(constructor_wrapper constructorlist, Args&&... args) : usertype(usertype_detail::check_destructor_tag(), std::forward(args)..., "new", constructorlist) {} + // Metatable indexes itself + stack::set_field(L, meta_function::index, t, t.stack_index()); - int push(lua_State* L) { - return metatableregister->push_um(L); - } -}; + // metatable on the metatable + // for call constructor purposes and such + lua_createtable(L, 0, 1); + stack_reference metabehind(L, -1); + if (umx.callconstructfunc.valid()) { + stack::set_field(L, sol::meta_function::call_function, umx.callconstructfunc, metabehind.stack_index()); + } + stack::set_field(L, metatable_key, metabehind, t.stack_index()); + metabehind.pop(); -namespace stack { -template -struct pusher> { - static int push(lua_State* L, usertype& user) { - return user.push(L); - } -}; -} // stack + if (i < 2) + t.pop(); + } + return 1; + } + }; + } // stack +} // sol + +// end of sol\simple_usertype_metatable.hpp + +namespace sol { + + template + class usertype { + private: + std::unique_ptr metatableregister; + + template + usertype(usertype_detail::verified_tag, Args&&... args) : metatableregister(detail::make_unique_deleter, Args...>, detail::deleter>(std::forward(args)...)) {} + + template + usertype(usertype_detail::add_destructor_tag, Args&&... args) : usertype(usertype_detail::verified, std::forward(args)..., "__gc", default_destructor) {} + + template + usertype(usertype_detail::check_destructor_tag, Args&&... args) : usertype(meta::condition, meta::neg>>, usertype_detail::add_destructor_tag, usertype_detail::verified_tag>(), std::forward(args)...) {} + + public: + + template + usertype(Args&&... args) : usertype(meta::condition, meta::neg>>, decltype(default_constructor), usertype_detail::check_destructor_tag>(), std::forward(args)...) {} + + template + usertype(constructors constructorlist, Args&&... args) : usertype(usertype_detail::check_destructor_tag(), std::forward(args)..., "new", constructorlist) {} + + template + usertype(constructor_wrapper constructorlist, Args&&... args) : usertype(usertype_detail::check_destructor_tag(), std::forward(args)..., "new", constructorlist) {} + + template + usertype(simple_tag, lua_State* L, Args&&... args) : metatableregister(detail::make_unique_deleter, detail::deleter>(L, std::forward(args)...)) {} + + int push(lua_State* L) { + return metatableregister->push_um(L); + } + }; + + namespace stack { + template + struct pusher> { + static int push(lua_State* L, usertype& user) { + return user.push(L); + } + }; + } // stack } // sol // end of sol\usertype.hpp @@ -9516,6 +9635,26 @@ namespace sol { return *this; } + template + basic_table_core& new_simple_usertype(const std::string& name, Args&&... args) { + usertype utype(simple, base_t::lua_state(), std::forward(args)...); + set_usertype(name, utype); + return *this; + } + + template + basic_table_core& new_simple_usertype(const std::string& name, Args&&... args) { + constructors> ctor{}; + return new_simple_usertype(name, ctor, std::forward(args)...); + } + + template + basic_table_core& new_simple_usertype(const std::string& name, constructors ctor, Args&&... args) { + usertype utype(simple, base_t::lua_state(), ctor, std::forward(args)...); + set_usertype(name, utype); + return *this; + } + template basic_table_core& new_enum(const std::string& name, Args&&... args) { if (read_only) { @@ -10089,15 +10228,33 @@ namespace sol { return *this; } - template - state_view& new_enum(const std::string& name, Args&&... args) { - global.new_enum(name, std::forward(args)...); + template + state_view& new_usertype(const std::string& name, constructors ctor, Args&&... args) { + global.new_usertype(name, ctor, std::forward(args)...); + return *this; + } + + template + state_view& new_simple_usertype(const std::string& name, Args&&... args) { + global.new_simple_usertype(name, std::forward(args)...); + return *this; + } + + template + state_view& new_simple_usertype(const std::string& name, Args&&... args) { + global.new_simple_usertype(name, std::forward(args)...); return *this; } template - state_view& new_usertype(const std::string& name, constructors ctor, Args&&... args) { - global.new_usertype(name, ctor, std::forward(args)...); + state_view& new_simple_usertype(const std::string& name, constructors ctor, Args&&... args) { + global.new_simple_usertype(name, ctor, std::forward(args)...); + return *this; + } + + template + state_view& new_enum(const std::string& name, Args&&... args) { + global.new_enum(name, std::forward(args)...); return *this; }