From 55e92056c1d31300b82e52ac863ab8f7a9c8a541 Mon Sep 17 00:00:00 2001 From: ThePhD Date: Wed, 21 Nov 2018 07:34:32 -0500 Subject: [PATCH] Fiiiiixes. --- single/sol/sol.hpp | 133 ++++++++++++++++++++-------- single/sol/sol_forward.hpp | 4 +- sol/coroutine.hpp | 53 ++++++----- sol/function_types.hpp | 2 +- sol/function_types_stateful.hpp | 11 ++- sol/stack_check_get_unqualified.hpp | 17 ++++ sol/stack_core.hpp | 54 +++++++---- sol/stack_get_unqualified.hpp | 6 ++ sol/usertype_metatable.hpp | 3 + tests/test_usertypes.cpp | 8 +- tests/test_utility.cpp | 59 +++++++++++- 11 files changed, 259 insertions(+), 91 deletions(-) diff --git a/single/sol/sol.hpp b/single/sol/sol.hpp index 95abf0eb..91307e0d 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 2018-11-10 19:02:00.192743 UTC -// This header was generated with sol v2.20.5 (revision 2cfbc8c) +// Generated 2018-11-21 12:34:11.276133 UTC +// This header was generated with sol v2.20.5 (revision 157db07) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -7147,6 +7147,9 @@ namespace sol { #include #include #include +#if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES +#include +#endif // C++17 namespace sol { namespace detail { @@ -7444,7 +7447,7 @@ namespace sol { return false; } allocated_size -= sizeof(T*); - + adjusted = static_cast(static_cast(pointer_adjusted) + sizeof(T*)); dx_adjusted = align(std::alignment_of::value, sizeof(unique_destructor), adjusted, allocated_size); if (dx_adjusted == nullptr) { @@ -7452,7 +7455,7 @@ namespace sol { return false; } allocated_size -= sizeof(unique_destructor); - + adjusted = static_cast(static_cast(dx_adjusted) + sizeof(unique_destructor)); id_adjusted = align(std::alignment_of::value, sizeof(unique_tag), adjusted, allocated_size); @@ -7461,7 +7464,7 @@ namespace sol { return false; } allocated_size -= sizeof(unique_tag); - + adjusted = static_cast(static_cast(id_adjusted) + sizeof(unique_tag)); data_adjusted = align(std::alignment_of::value, sizeof(Real), adjusted, allocated_size); if (data_adjusted == nullptr) { @@ -7928,6 +7931,13 @@ namespace sol { return stack_detail::unchecked_unqualified_get>(L, index, tracking); } +#if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES + template + inline decltype(auto) tagged_unqualified_get(types>, lua_State* L, int index, record& tracking) { + return stack_detail::unchecked_unqualified_get>(L, index, tracking); + } +#endif // shitty optional + template inline auto tagged_get(types, lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_get(L, index, tracking)) { if (is_lua_reference::value) { @@ -7941,6 +7951,14 @@ namespace sol { inline decltype(auto) tagged_get(types>, lua_State* L, int index, record& tracking) { return stack_detail::unchecked_get>(L, index, tracking); } + +#if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES + template + inline decltype(auto) tagged_get(types>, lua_State* L, int index, record& tracking) { + return stack_detail::unchecked_get>(L, index, tracking); + } +#endif // shitty optional + #else template inline decltype(auto) tagged_unqualified_get(types, lua_State* L, int index, record& tracking) { @@ -9295,7 +9313,11 @@ namespace stack { if (i == 0) { break; } +#if defined(LUA_NILINTABLE) && LUA_NILINTABLE + lua_pop(L, vi); +#else lua_pop(L, (vi + 1)); +#endif return arr; } } @@ -10006,6 +10028,7 @@ namespace stack { }; #if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES + #if defined(SOL_STD_VARIANT) && SOL_STD_VARIANT template struct getter> { @@ -10101,6 +10124,9 @@ namespace stack { // beginning of sol/stack_check_get_unqualified.hpp +#if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES +#endif // C++17 + namespace sol { namespace stack { template @@ -10207,6 +10233,17 @@ namespace stack { }; #if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES + template + struct getter> { + static std::optional get(lua_State* L, int index, record& tracking) { + if (!unqualified_check(L, index, no_panic)) { + tracking.use(static_cast(!lua_isnone(L, index))); + return std::nullopt; + } + return stack_detail::unchecked_unqualified_get(L, index, tracking); + } + }; + #if defined(SOL_STD_VARIANT) && SOL_STD_VARIANT template struct check_getter> { @@ -10846,7 +10883,7 @@ namespace stack { template struct pusher { static int push(lua_State* L, const char (&str)[N]) { - lua_pushlstring(L, str, N - 1); + lua_pushlstring(L, str, std::char_traits::length(str)); return 1; } @@ -11125,7 +11162,7 @@ namespace stack { template struct pusher { static int push(lua_State* L, const wchar_t (&str)[N]) { - return push(L, str, N - 1); + return push(L, str, std::char_traits::length(str)); } static int push(lua_State* L, const wchar_t (&str)[N], std::size_t sz) { @@ -11136,7 +11173,7 @@ namespace stack { template struct pusher { static int push(lua_State* L, const char16_t (&str)[N]) { - return push(L, str, N - 1); + return push(L, str, std::char_traits::length(str)); } static int push(lua_State* L, const char16_t (&str)[N], std::size_t sz) { @@ -11147,7 +11184,7 @@ namespace stack { template struct pusher { static int push(lua_State* L, const char32_t (&str)[N]) { - return push(L, str, N - 1); + return push(L, str, std::char_traits::length(str)); } static int push(lua_State* L, const char32_t (&str)[N], std::size_t sz) { @@ -11263,6 +11300,17 @@ namespace stack { }; #if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES + template + struct pusher> { + template + static int push(lua_State* L, T&& t) { + if (t == std::nullopt) { + return stack::push(L, nullopt); + } + return stack::push(L, static_cast::value, O&, O&&>>(t.value())); + } + }; + #if defined(SOL_STD_VARIANT) && SOL_STD_VARIANT namespace stack_detail { @@ -14068,7 +14116,7 @@ namespace function_detail { namespace sol { namespace function_detail { - template + template struct functor_function { typedef std::decay_t> function_type; function_type fx; @@ -14089,8 +14137,13 @@ namespace function_detail { } int operator()(lua_State* L) { - auto f = [&](lua_State*) -> int { return this->call(L); }; - return detail::trampoline(L, f); + if (!no_trampoline) { + auto f = [&](lua_State*) -> int { return this->call(L); }; + return detail::trampoline(L, f); + } + else { + return call(L); + } } }; @@ -14368,7 +14421,7 @@ namespace sol { template static void select_convertible(std::false_type, types, lua_State* L, Fx&& fx, Args&&... args) { typedef std::remove_pointer_t> clean_fx; - typedef function_detail::functor_function F; + typedef function_detail::functor_function F; set_fx(L, std::forward(fx), std::forward(args)...); } @@ -18850,6 +18903,9 @@ namespace sol { if (member != nullptr) { return (member)(L, static_cast(&f), static_cast(f), runtime_target); } + if (is_meta_bound && toplevel && !is_index) { + return usertype_detail::metatable_new_index(L); + } string_view accessor = stack::get(L, keyidx); int ret = 0; bool found = false; @@ -21825,7 +21881,12 @@ namespace sol { call_status stats = call_status::yielded; void luacall(std::ptrdiff_t argcount, std::ptrdiff_t) { +#if SOL_LUA_VERSION >= 504 + int nres; + stats = static_cast(lua_resume(lua_state(), nullptr, static_cast(argcount), &nres)); +#else stats = static_cast(lua_resume(lua_state(), nullptr, static_cast(argcount))); +#endif } template @@ -21868,7 +21929,7 @@ namespace sol { basic_coroutine() = default; template , basic_coroutine>>, meta::neg>>, meta::neg>, meta::neg>>, is_lua_reference>> = meta::enabler> basic_coroutine(T&& r) noexcept - : base_t(std::forward(r)), error_handler(detail::get_default_handler::value>(r.lua_state())) { + : base_t(std::forward(r)), error_handler(detail::get_default_handler::value>(r.lua_state())) { #if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES if (!is_function>::value) { auto pp = stack::push_pop(*this); @@ -21882,50 +21943,50 @@ namespace sol { basic_coroutine(basic_coroutine&&) = default; basic_coroutine& operator=(basic_coroutine&&) = default; basic_coroutine(const basic_function& b) - : basic_coroutine(b, detail::get_default_handler::value>(b.lua_state())) { + : basic_coroutine(b, detail::get_default_handler::value>(b.lua_state())) { } basic_coroutine(basic_function&& b) - : basic_coroutine(std::move(b), detail::get_default_handler::value>(b.lua_state())) { + : basic_coroutine(std::move(b), detail::get_default_handler::value>(b.lua_state())) { } basic_coroutine(const basic_function& b, handler_t eh) - : base_t(b), error_handler(std::move(eh)) { + : base_t(b), error_handler(std::move(eh)) { } basic_coroutine(basic_function&& b, handler_t eh) - : base_t(std::move(b)), error_handler(std::move(eh)) { + : base_t(std::move(b)), error_handler(std::move(eh)) { } basic_coroutine(const stack_reference& r) - : basic_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler::value>(r.lua_state())) { + : basic_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler::value>(r.lua_state())) { } basic_coroutine(stack_reference&& r) - : basic_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler::value>(r.lua_state())) { + : basic_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler::value>(r.lua_state())) { } basic_coroutine(const stack_reference& r, handler_t eh) - : basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) { + : basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) { } basic_coroutine(stack_reference&& r, handler_t eh) - : basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) { + : basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) { } template basic_coroutine(const proxy_base& p) - : basic_coroutine(p, detail::get_default_handler::value>(p.lua_state())) { + : basic_coroutine(p, detail::get_default_handler::value>(p.lua_state())) { } template basic_coroutine(proxy_base&& p) - : basic_coroutine(std::move(p), detail::get_default_handler::value>(p.lua_state())) { + : basic_coroutine(std::move(p), detail::get_default_handler::value>(p.lua_state())) { } template >, meta::neg>>> = meta::enabler> basic_coroutine(Proxy&& p, Handler&& eh) - : basic_coroutine(detail::force_cast(p), std::forward(eh)) { + : basic_coroutine(detail::force_cast(p), std::forward(eh)) { } template >> = meta::enabler> basic_coroutine(lua_State* L, T&& r) - : basic_coroutine(L, std::forward(r), detail::get_default_handler::value>(L)) { + : basic_coroutine(L, std::forward(r), detail::get_default_handler::value>(L)) { } template >> = meta::enabler> basic_coroutine(lua_State* L, T&& r, handler_t eh) - : base_t(L, std::forward(r)), error_handler(std::move(eh)) { + : base_t(L, std::forward(r)), error_handler(std::move(eh)) { #if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES auto pp = stack::push_pop(*this); constructor_handler handler{}; @@ -21934,44 +21995,44 @@ namespace sol { } basic_coroutine(lua_nil_t n) - : base_t(n), error_handler(n) { + : base_t(n), error_handler(n) { } basic_coroutine(lua_State* L, int index = -1) - : basic_coroutine(L, index, detail::get_default_handler::value>(L)) { + : basic_coroutine(L, index, detail::get_default_handler::value>(L)) { } basic_coroutine(lua_State* L, int index, handler_t eh) - : base_t(L, index), error_handler(std::move(eh)) { + : base_t(L, index), error_handler(std::move(eh)) { #ifdef SOL_SAFE_REFERENCES constructor_handler handler{}; stack::check(L, index, handler); #endif // Safety } basic_coroutine(lua_State* L, absolute_index index) - : basic_coroutine(L, index, detail::get_default_handler::value>(L)) { + : basic_coroutine(L, index, detail::get_default_handler::value>(L)) { } basic_coroutine(lua_State* L, absolute_index index, handler_t eh) - : base_t(L, index), error_handler(std::move(eh)) { + : base_t(L, index), error_handler(std::move(eh)) { #if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES constructor_handler handler{}; stack::check(L, index, handler); #endif // Safety } basic_coroutine(lua_State* L, raw_index index) - : basic_coroutine(L, index, detail::get_default_handler::value>(L)) { + : basic_coroutine(L, index, detail::get_default_handler::value>(L)) { } basic_coroutine(lua_State* L, raw_index index, handler_t eh) - : base_t(L, index), error_handler(std::move(eh)) { + : base_t(L, index), error_handler(std::move(eh)) { #if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES constructor_handler handler{}; stack::check(L, index, handler); #endif // Safety } basic_coroutine(lua_State* L, ref_index index) - : basic_coroutine(L, index, detail::get_default_handler::value>(L)) { + : basic_coroutine(L, index, detail::get_default_handler::value>(L)) { } basic_coroutine(lua_State* L, ref_index index, handler_t eh) - : base_t(L, index), error_handler(std::move(eh)) { + : base_t(L, index), error_handler(std::move(eh)) { #if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES auto pp = stack::push_pop(*this); constructor_handler handler{}; diff --git a/single/sol/sol_forward.hpp b/single/sol/sol_forward.hpp index 03ce394e..7d252a6d 100644 --- a/single/sol/sol_forward.hpp +++ b/single/sol/sol_forward.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 2018-11-10 19:02:00.404748 UTC -// This header was generated with sol v2.20.5 (revision 2cfbc8c) +// Generated 2018-11-21 12:34:11.544452 UTC +// This header was generated with sol v2.20.5 (revision 157db07) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP diff --git a/sol/coroutine.hpp b/sol/coroutine.hpp index 2ecf1fac..105a97ba 100644 --- a/sol/coroutine.hpp +++ b/sol/coroutine.hpp @@ -1,4 +1,4 @@ -// sol2 +// sol2 // The MIT License (MIT) @@ -41,7 +41,12 @@ namespace sol { call_status stats = call_status::yielded; void luacall(std::ptrdiff_t argcount, std::ptrdiff_t) { +#if SOL_LUA_VERSION >= 504 + int nres; + stats = static_cast(lua_resume(lua_state(), nullptr, static_cast(argcount), &nres)); +#else stats = static_cast(lua_resume(lua_state(), nullptr, static_cast(argcount))); +#endif } template @@ -84,7 +89,7 @@ namespace sol { basic_coroutine() = default; template , basic_coroutine>>, meta::neg>>, meta::neg>, meta::neg>>, is_lua_reference>> = meta::enabler> basic_coroutine(T&& r) noexcept - : base_t(std::forward(r)), error_handler(detail::get_default_handler::value>(r.lua_state())) { + : base_t(std::forward(r)), error_handler(detail::get_default_handler::value>(r.lua_state())) { #if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES if (!is_function>::value) { auto pp = stack::push_pop(*this); @@ -98,50 +103,50 @@ namespace sol { basic_coroutine(basic_coroutine&&) = default; basic_coroutine& operator=(basic_coroutine&&) = default; basic_coroutine(const basic_function& b) - : basic_coroutine(b, detail::get_default_handler::value>(b.lua_state())) { + : basic_coroutine(b, detail::get_default_handler::value>(b.lua_state())) { } basic_coroutine(basic_function&& b) - : basic_coroutine(std::move(b), detail::get_default_handler::value>(b.lua_state())) { + : basic_coroutine(std::move(b), detail::get_default_handler::value>(b.lua_state())) { } basic_coroutine(const basic_function& b, handler_t eh) - : base_t(b), error_handler(std::move(eh)) { + : base_t(b), error_handler(std::move(eh)) { } basic_coroutine(basic_function&& b, handler_t eh) - : base_t(std::move(b)), error_handler(std::move(eh)) { + : base_t(std::move(b)), error_handler(std::move(eh)) { } basic_coroutine(const stack_reference& r) - : basic_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler::value>(r.lua_state())) { + : basic_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler::value>(r.lua_state())) { } basic_coroutine(stack_reference&& r) - : basic_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler::value>(r.lua_state())) { + : basic_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler::value>(r.lua_state())) { } basic_coroutine(const stack_reference& r, handler_t eh) - : basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) { + : basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) { } basic_coroutine(stack_reference&& r, handler_t eh) - : basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) { + : basic_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) { } template basic_coroutine(const proxy_base& p) - : basic_coroutine(p, detail::get_default_handler::value>(p.lua_state())) { + : basic_coroutine(p, detail::get_default_handler::value>(p.lua_state())) { } template basic_coroutine(proxy_base&& p) - : basic_coroutine(std::move(p), detail::get_default_handler::value>(p.lua_state())) { + : basic_coroutine(std::move(p), detail::get_default_handler::value>(p.lua_state())) { } template >, meta::neg>>> = meta::enabler> basic_coroutine(Proxy&& p, Handler&& eh) - : basic_coroutine(detail::force_cast(p), std::forward(eh)) { + : basic_coroutine(detail::force_cast(p), std::forward(eh)) { } template >> = meta::enabler> basic_coroutine(lua_State* L, T&& r) - : basic_coroutine(L, std::forward(r), detail::get_default_handler::value>(L)) { + : basic_coroutine(L, std::forward(r), detail::get_default_handler::value>(L)) { } template >> = meta::enabler> basic_coroutine(lua_State* L, T&& r, handler_t eh) - : base_t(L, std::forward(r)), error_handler(std::move(eh)) { + : base_t(L, std::forward(r)), error_handler(std::move(eh)) { #if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES auto pp = stack::push_pop(*this); constructor_handler handler{}; @@ -150,44 +155,44 @@ namespace sol { } basic_coroutine(lua_nil_t n) - : base_t(n), error_handler(n) { + : base_t(n), error_handler(n) { } basic_coroutine(lua_State* L, int index = -1) - : basic_coroutine(L, index, detail::get_default_handler::value>(L)) { + : basic_coroutine(L, index, detail::get_default_handler::value>(L)) { } basic_coroutine(lua_State* L, int index, handler_t eh) - : base_t(L, index), error_handler(std::move(eh)) { + : base_t(L, index), error_handler(std::move(eh)) { #ifdef SOL_SAFE_REFERENCES constructor_handler handler{}; stack::check(L, index, handler); #endif // Safety } basic_coroutine(lua_State* L, absolute_index index) - : basic_coroutine(L, index, detail::get_default_handler::value>(L)) { + : basic_coroutine(L, index, detail::get_default_handler::value>(L)) { } basic_coroutine(lua_State* L, absolute_index index, handler_t eh) - : base_t(L, index), error_handler(std::move(eh)) { + : base_t(L, index), error_handler(std::move(eh)) { #if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES constructor_handler handler{}; stack::check(L, index, handler); #endif // Safety } basic_coroutine(lua_State* L, raw_index index) - : basic_coroutine(L, index, detail::get_default_handler::value>(L)) { + : basic_coroutine(L, index, detail::get_default_handler::value>(L)) { } basic_coroutine(lua_State* L, raw_index index, handler_t eh) - : base_t(L, index), error_handler(std::move(eh)) { + : base_t(L, index), error_handler(std::move(eh)) { #if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES constructor_handler handler{}; stack::check(L, index, handler); #endif // Safety } basic_coroutine(lua_State* L, ref_index index) - : basic_coroutine(L, index, detail::get_default_handler::value>(L)) { + : basic_coroutine(L, index, detail::get_default_handler::value>(L)) { } basic_coroutine(lua_State* L, ref_index index, handler_t eh) - : base_t(L, index), error_handler(std::move(eh)) { + : base_t(L, index), error_handler(std::move(eh)) { #if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES auto pp = stack::push_pop(*this); constructor_handler handler{}; diff --git a/sol/function_types.hpp b/sol/function_types.hpp index ad2b4bda..09576c72 100644 --- a/sol/function_types.hpp +++ b/sol/function_types.hpp @@ -46,7 +46,7 @@ namespace sol { template static void select_convertible(std::false_type, types, lua_State* L, Fx&& fx, Args&&... args) { typedef std::remove_pointer_t> clean_fx; - typedef function_detail::functor_function F; + typedef function_detail::functor_function F; set_fx(L, std::forward(fx), std::forward(args)...); } diff --git a/sol/function_types_stateful.hpp b/sol/function_types_stateful.hpp index 375682f2..8b737f82 100644 --- a/sol/function_types_stateful.hpp +++ b/sol/function_types_stateful.hpp @@ -28,7 +28,7 @@ namespace sol { namespace function_detail { - template + template struct functor_function { typedef std::decay_t> function_type; function_type fx; @@ -49,8 +49,13 @@ namespace function_detail { } int operator()(lua_State* L) { - auto f = [&](lua_State*) -> int { return this->call(L); }; - return detail::trampoline(L, f); + if (!no_trampoline) { + auto f = [&](lua_State*) -> int { return this->call(L); }; + return detail::trampoline(L, f); + } + else { + return call(L); + } } }; diff --git a/sol/stack_check_get_unqualified.hpp b/sol/stack_check_get_unqualified.hpp index 4bb3ed95..d7cd25bf 100644 --- a/sol/stack_check_get_unqualified.hpp +++ b/sol/stack_check_get_unqualified.hpp @@ -28,8 +28,14 @@ #include "stack_get.hpp" #include "stack_check.hpp" #include "optional.hpp" + #include #include +#if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES +#include +#endif // C++17 + + namespace sol { namespace stack { @@ -137,6 +143,17 @@ namespace stack { }; #if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES + template + struct getter> { + static std::optional get(lua_State* L, int index, record& tracking) { + if (!unqualified_check(L, index, no_panic)) { + tracking.use(static_cast(!lua_isnone(L, index))); + return std::nullopt; + } + return stack_detail::unchecked_unqualified_get(L, index, tracking); + } + }; + #if defined(SOL_STD_VARIANT) && SOL_STD_VARIANT template struct check_getter> { diff --git a/sol/stack_core.hpp b/sol/stack_core.hpp index 92d34146..d67a461c 100644 --- a/sol/stack_core.hpp +++ b/sol/stack_core.hpp @@ -1,4 +1,4 @@ -// sol2 +// sol2 // The MIT License (MIT) @@ -40,6 +40,9 @@ #include #include #include +#if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES +#include +#endif // C++17 namespace sol { namespace detail { @@ -337,7 +340,7 @@ namespace sol { return false; } allocated_size -= sizeof(T*); - + adjusted = static_cast(static_cast(pointer_adjusted) + sizeof(T*)); dx_adjusted = align(std::alignment_of::value, sizeof(unique_destructor), adjusted, allocated_size); if (dx_adjusted == nullptr) { @@ -345,7 +348,7 @@ namespace sol { return false; } allocated_size -= sizeof(unique_destructor); - + adjusted = static_cast(static_cast(dx_adjusted) + sizeof(unique_destructor)); id_adjusted = align(std::alignment_of::value, sizeof(unique_tag), adjusted, allocated_size); @@ -354,7 +357,7 @@ namespace sol { return false; } allocated_size -= sizeof(unique_tag); - + adjusted = static_cast(static_cast(id_adjusted) + sizeof(unique_tag)); data_adjusted = align(std::alignment_of::value, sizeof(Real), adjusted, allocated_size); if (data_adjusted == nullptr) { @@ -821,6 +824,13 @@ namespace sol { return stack_detail::unchecked_unqualified_get>(L, index, tracking); } +#if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES + template + inline decltype(auto) tagged_unqualified_get(types>, lua_State* L, int index, record& tracking) { + return stack_detail::unchecked_unqualified_get>(L, index, tracking); + } +#endif // shitty optional + template inline auto tagged_get(types, lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_get(L, index, tracking)) { if (is_lua_reference::value) { @@ -834,6 +844,14 @@ namespace sol { inline decltype(auto) tagged_get(types>, lua_State* L, int index, record& tracking) { return stack_detail::unchecked_get>(L, index, tracking); } + +#if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES + template + inline decltype(auto) tagged_get(types>, lua_State* L, int index, record& tracking) { + return stack_detail::unchecked_get>(L, index, tracking); + } +#endif // shitty optional + #else template inline decltype(auto) tagged_unqualified_get(types, lua_State* L, int index, record& tracking) { @@ -1005,22 +1023,22 @@ namespace sol { set_field(L, std::forward(key), std::forward(value), tableindex); } - template - inline void modify_unique_usertype_as(const stack_reference& obj, F&& f) { - typedef unique_usertype_traits u_traits; - void* raw = lua_touserdata(obj.lua_state(), obj.stack_index()); - void* ptr_memory = detail::align_usertype_pointer(raw); - void* uu_memory = detail::align_usertype_unique(raw); - T& uu = *static_cast(uu_memory); - f(uu); - *static_cast(ptr_memory) = static_cast(u_traits::get(uu)); + template + inline void modify_unique_usertype_as(const stack_reference& obj, F&& f) { + typedef unique_usertype_traits u_traits; + void* raw = lua_touserdata(obj.lua_state(), obj.stack_index()); + void* ptr_memory = detail::align_usertype_pointer(raw); + void* uu_memory = detail::align_usertype_unique(raw); + T& uu = *static_cast(uu_memory); + f(uu); + *static_cast(ptr_memory) = static_cast(u_traits::get(uu)); } - template - inline void modify_unique_usertype(const stack_reference& obj, F&& f) { - typedef meta::bind_traits> bt; - typedef typename bt::template arg_at<0> T; - modify_unique_usertype_as>(obj, std::forward(f)); + template + inline void modify_unique_usertype(const stack_reference& obj, F&& f) { + typedef meta::bind_traits> bt; + typedef typename bt::template arg_at<0> T; + modify_unique_usertype_as>(obj, std::forward(f)); } } // namespace stack } // namespace sol diff --git a/sol/stack_get_unqualified.hpp b/sol/stack_get_unqualified.hpp index 1d388220..9c31bd0e 100644 --- a/sol/stack_get_unqualified.hpp +++ b/sol/stack_get_unqualified.hpp @@ -171,7 +171,11 @@ namespace stack { if (i == 0) { break; } +#if defined(LUA_NILINTABLE) && LUA_NILINTABLE + lua_pop(L, vi); +#else lua_pop(L, (vi + 1)); +#endif return arr; } } @@ -882,6 +886,8 @@ namespace stack { }; #if defined(SOL_CXX17_FEATURES) && SOL_CXX17_FEATURES + + #if defined(SOL_STD_VARIANT) && SOL_STD_VARIANT template struct getter> { diff --git a/sol/usertype_metatable.hpp b/sol/usertype_metatable.hpp index cc511cee..03a1843a 100644 --- a/sol/usertype_metatable.hpp +++ b/sol/usertype_metatable.hpp @@ -593,6 +593,9 @@ namespace sol { if (member != nullptr) { return (member)(L, static_cast(&f), static_cast(f), runtime_target); } + if (is_meta_bound && toplevel && !is_index) { + return usertype_detail::metatable_new_index(L); + } string_view accessor = stack::get(L, keyidx); int ret = 0; bool found = false; diff --git a/tests/test_usertypes.cpp b/tests/test_usertypes.cpp index d647d6b6..4d9aa3e2 100644 --- a/tests/test_usertypes.cpp +++ b/tests/test_usertypes.cpp @@ -1635,8 +1635,6 @@ TEST_CASE("usertype/runtime-extensibility", "Check if usertypes are runtime exte class derived_b : public base_a { }; - - SECTION("just functions") { sol::state lua; lua.open_libraries(sol::lib::base); @@ -1747,8 +1745,12 @@ end REQUIRE(pfr0.valid()); auto pfr1 = lua.safe_script("function B:c() print('B') return 2 end", sol::script_pass_on_error); REQUIRE(pfr1.valid()); - auto pfr2 = lua.safe_script("local obja = A.new() local objb = B.new() assert(obja:c() == 1) assert(objb:c() == 2)", sol::script_pass_on_error); + auto pfr2 = lua.safe_script("obja = A.new() objb = B.new()", sol::script_default_on_error); REQUIRE(pfr2.valid()); + auto pfr3 = lua.safe_script("assert(obja:c() == 1)", sol::script_default_on_error); + REQUIRE(pfr3.valid()); + auto pfr4 = lua.safe_script("assert(objb:c() == 2)", sol::script_default_on_error); + REQUIRE(pfr4.valid()); } } diff --git a/tests/test_utility.cpp b/tests/test_utility.cpp index dbd6372b..062c7ac8 100644 --- a/tests/test_utility.cpp +++ b/tests/test_utility.cpp @@ -72,10 +72,14 @@ TEST_CASE("utility/variant", "test that variant can be round-tripped") { return v == 2; }); lua["v"] = std::variant(2); - REQUIRE_NOTHROW([&]() { - lua.safe_script("assert(f(v))"); - lua.safe_script("assert(g(v))"); - }()); + { + auto result = lua.safe_script("assert(f(v))", sol::script_pass_on_error); + REQUIRE(result.valid()); + }; + { + auto result = lua.safe_script("assert(g(v))", sol::script_pass_on_error); + REQUIRE(result.valid()); + }; } SECTION("throws") { sol::state lua; @@ -103,6 +107,53 @@ TEST_CASE("utility/variant", "test that variant can be round-tripped") { #endif // C++17 } +TEST_CASE("utility/optional", "test that shit optional can be round-tripped") { +#ifdef SOL_CXX17_FEATURES + SECTION("okay") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.set_function("f", [](int v) { + return v == 2; + }); + lua.set_function("g", [](std::optional vv) { + return vv && *vv == 2; + }); + lua["v"] = std::optional(2); + { + auto result = lua.safe_script("assert(f(v))", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + { + auto result = lua.safe_script("assert(g(v))", sol::script_pass_on_error); + REQUIRE(result.valid()); + } + } + SECTION("throws") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.set_function("f", [](int v) { + return v == 2; + }); + lua.set_function("g", [](std::optional vv) { + return vv && *vv == 2; + }); + lua["v"] = std::optional(std::nullopt); + { + auto result = lua.safe_script("assert(f(v))", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + }; + { + auto result = lua.safe_script("assert(g(v))", sol::script_pass_on_error); + REQUIRE_FALSE(result.valid()); + }; + } +#else + REQUIRE(true); +#endif // C++17 +} + TEST_CASE("utility/string_view", "test that string_view can be taken as an argument") { #ifdef SOL_CXX17_FEATURES sol::state lua;