diff --git a/docs/source/threading.rst b/docs/source/threading.rst index 69950f99..18d29d4d 100644 --- a/docs/source/threading.rst +++ b/docs/source/threading.rst @@ -20,6 +20,13 @@ You can mitigate some of the pressure of using coroutines and threading by using Furthermore, for every single ``sol::reference`` derived type, there exists a version prefixed with the word ``main_``, such as ``sol::main_table``, ``sol::main_function``, ``sol::main_object`` and similar. These classes, on construction, assignment and other operations, forcibly obtain the ``lua_State*`` associated with the main thread, if possible. Using these classes will allow your code to be immune when a wrapped coroutine or a lua thread is set to ``nil`` and then garbage-collected. +.. note:: + + This does **not** provide immunity from typical multithreading issues in C++, such as synchronized access and the like. Lua's coroutines are cooperative in nature and concurrent execution with things like ``std::thread`` and similar still need to follow good C++ practices for multi threading. + + +Here's an example of explicit state transferring below: + .. code-block:: cpp :caption: transfer from state function :name: state-transfer diff --git a/single/sol/sol.hpp b/single/sol/sol.hpp index a9c2d49d..7a107798 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 2017-09-14 04:46:07.441029 UTC -// This header was generated with sol v2.18.3 (revision d3620c9) +// Generated 2017-09-14 12:45:28.604426 UTC +// This header was generated with sol v2.18.3 (revision ed341e0) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -194,6 +194,7 @@ namespace sol { using stack_aligned_unsafe_function = basic_function; using stack_aligned_safe_function = basic_protected_function; using protected_function = safe_function; + using main_protected_function = main_safe_function; using stack_protected_function = stack_safe_function; using stack_aligned_protected_function = stack_aligned_safe_function; #ifdef SOL_SAFE_FUNCTIONS @@ -5215,11 +5216,11 @@ namespace sol { template struct lua_type_of> : std::integral_constant {}; - template <> - struct lua_type_of : std::integral_constant {}; + template + struct lua_type_of> : std::integral_constant {}; - template <> - struct lua_type_of : std::integral_constant {}; + template + struct lua_type_of> : std::integral_constant {}; template struct lua_type_of> : std::integral_constant {}; @@ -6152,8 +6153,9 @@ namespace sol { } basic_reference(lua_State* L, int index = -1) noexcept : luastate(detail::pick_main_thread(L, L)) { - lua_pushvalue(lua_state(), index); - ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX); + // use L to stick with that state's execution stack + lua_pushvalue(L, index); + ref = luaL_ref(L, LUA_REGISTRYINDEX); } basic_reference(lua_State* L, ref_index index) noexcept : luastate(detail::pick_main_thread(L, L)) { @@ -12203,7 +12205,7 @@ namespace sol { using base_t::lua_state; basic_function() = default; - template , basic_function>>, meta::neg>, std::is_base_of>> = meta::enabler> + template , basic_function>>, meta::neg>, is_lua_reference>> = meta::enabler> basic_function(T&& r) noexcept : base_t(std::forward(r)) { #ifdef SOL_CHECK_ARGUMENTS @@ -12224,9 +12226,14 @@ namespace sol { basic_function(stack_reference&& r) : basic_function(r.lua_state(), r.stack_index()) { } - template >, std::is_base_of>> = meta::enabler> + template >> = meta::enabler> basic_function(lua_State* L, T&& r) : base_t(L, std::forward(r)) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + constructor_handler handler{}; + stack::check(lua_state(), -1, handler); +#endif // Safety } basic_function(lua_State* L, int index = -1) : base_t(L, index) { @@ -12240,7 +12247,7 @@ namespace sol { #ifdef SOL_CHECK_ARGUMENTS auto pp = stack::push_pop(*this); constructor_handler handler{}; - stack::check(L, -1, handler); + stack::check(lua_state(), -1, handler); #endif // Safety } @@ -12555,7 +12562,7 @@ namespace sol { handler_t error_handler; basic_protected_function() = default; - template , basic_protected_function>>, meta::neg>>, meta::neg>, std::is_base_of>> = meta::enabler> + template , basic_protected_function>>, meta::neg>>, meta::neg>, is_lua_reference>> = meta::enabler> basic_protected_function(T&& r) noexcept : base_t(std::forward(r)), error_handler(get_default_handler(r.lua_state())) { #ifdef SOL_CHECK_ARGUMENTS @@ -12615,6 +12622,11 @@ namespace sol { template >> = meta::enabler> basic_protected_function(lua_State* L, T&& r, handler_t eh) : base_t(L, std::forward(r)), error_handler(std::move(eh)) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + constructor_handler handler{}; + stack::check(lua_state(), -1, handler); +#endif // Safety } basic_protected_function(lua_State* L, int index = -1) @@ -12624,7 +12636,7 @@ namespace sol { : base_t(L, index), error_handler(std::move(eh)) { #ifdef SOL_CHECK_ARGUMENTS constructor_handler handler{}; - stack::check(lua_state(), index, handler); + stack::check(L, index, handler); #endif // Safety } basic_protected_function(lua_State* L, absolute_index index) @@ -12634,7 +12646,7 @@ namespace sol { : base_t(L, index), error_handler(std::move(eh)) { #ifdef SOL_CHECK_ARGUMENTS constructor_handler handler{}; - stack::check(lua_state(), index, handler); + stack::check(L, index, handler); #endif // Safety } basic_protected_function(lua_State* L, raw_index index) @@ -12644,7 +12656,7 @@ namespace sol { : base_t(L, index), error_handler(std::move(eh)) { #ifdef SOL_CHECK_ARGUMENTS constructor_handler handler{}; - stack::check(lua_state(), index, handler); + stack::check(L, index, handler); #endif // Safety } basic_protected_function(lua_State* L, ref_index index) @@ -12655,7 +12667,7 @@ namespace sol { #ifdef SOL_CHECK_ARGUMENTS auto pp = stack::push_pop(*this); constructor_handler handler{}; - stack::check(L, -1, handler); + stack::check(lua_state(), -1, handler); #endif // Safety } @@ -13073,12 +13085,12 @@ namespace sol { template decltype(auto) as() const { - return as_stack(std::is_same()); + return as_stack(is_stack_based()); } template bool is() const { - return is_stack(std::is_same()); + return is_stack(is_stack_based()); } }; } // namespace sol @@ -13096,7 +13108,7 @@ namespace sol { using base_t::lua_state; basic_userdata() noexcept = default; - template , basic_userdata>>, meta::neg>, std::is_base_of>> = meta::enabler> + template , basic_userdata>>, meta::neg>, is_lua_reference>> = meta::enabler> basic_userdata(T&& r) noexcept : base_t(std::forward(r)) { #ifdef SOL_CHECK_ARGUMENTS @@ -13119,6 +13131,11 @@ namespace sol { template >> = meta::enabler> basic_userdata(lua_State* L, T&& r) : base_t(L, std::forward(r)) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + constructor_handler handler{}; + stack::check(L, -1, handler); +#endif // Safety } basic_userdata(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) { @@ -13132,7 +13149,7 @@ namespace sol { #ifdef SOL_CHECK_ARGUMENTS auto pp = stack::push_pop(*this); constructor_handler handler{}; - stack::check(L, index, handler); + stack::check(L, -1, handler); #endif // Safety } }; @@ -13145,7 +13162,7 @@ namespace sol { using base_t::lua_state; basic_lightuserdata() noexcept = default; - template , basic_lightuserdata>>, meta::neg>, std::is_base_of>> = meta::enabler> + template , basic_lightuserdata>>, meta::neg>, is_lua_reference>> = meta::enabler> basic_lightuserdata(T&& r) noexcept : base_t(std::forward(r)) { #ifdef SOL_CHECK_ARGUMENTS @@ -13165,9 +13182,14 @@ namespace sol { basic_lightuserdata(stack_reference&& r) : basic_lightuserdata(r.lua_state(), r.stack_index()) { } - template >, std::is_base_of>> = meta::enabler> + template >> = meta::enabler> basic_lightuserdata(lua_State* L, T&& r) : basic_lightuserdata(L, std::forward(r)) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + constructor_handler handler{}; + stack::check(lua_state(), -1, handler); +#endif // Safety } basic_lightuserdata(lua_State* L, int index = -1) : base_t(L, index) { @@ -13181,7 +13203,7 @@ namespace sol { #ifdef SOL_CHECK_ARGUMENTS auto pp = stack::push_pop(*this); constructor_handler handler{}; - stack::check(L, index, handler); + stack::check(lua_state(), index, handler); #endif // Safety } }; @@ -13658,7 +13680,7 @@ namespace sol { public: basic_object() noexcept = default; - template , basic_object>>, meta::neg>, std::is_base_of>> = meta::enabler> + template , basic_object>>, meta::neg>, is_lua_reference>> = meta::enabler> basic_object(T&& r) : base_t(std::forward(r)) { } @@ -17183,11 +17205,11 @@ namespace sol { template void tuple_set(std::index_sequence, Pairs&& pairs) { auto pp = stack::push_pop < top_level && (is_global(pairs))...>::value) > (*this); - void(detail::swallow{(stack::set_field(base_t::lua_state(), - detail::forward_get(pairs), - detail::forward_get(pairs), - lua_gettop(base_t::lua_state())), - 0)...}); + void(detail::swallow{ (stack::set_field(base_t::lua_state(), + detail::forward_get(pairs), + detail::forward_get(pairs), + lua_gettop(base_t::lua_state())), + 0)... }); } template @@ -17256,15 +17278,21 @@ namespace sol { basic_table_core(detail::no_safety_tag, lua_State* L, ref_index index) : base_t(L, index) { } - template , basic_table_core>>, meta::neg>, std::is_base_of>> = meta::enabler> + template , basic_table_core>>, meta::neg>, is_lua_reference>> = meta::enabler> basic_table_core(detail::no_safety_tag, T&& r) noexcept : base_t(std::forward(r)) { } + template >> = meta::enabler> + basic_table_core(detail::no_safety_tag, lua_State*L, T&& r) noexcept + : base_t(L, std::forward(r)) { + } public: typedef basic_table_iterator iterator; typedef iterator const_iterator; + using base_t::lua_state; + basic_table_core() noexcept = default; basic_table_core(const basic_table_core&) = default; basic_table_core(basic_table_core&&) = default; @@ -17278,7 +17306,12 @@ namespace sol { } template >> = meta::enabler> basic_table_core(lua_State* L, T&& r) - : basic_table_core(L, std::forward(r)) { + : base_t(L, std::forward(r)) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + constructor_handler handler{}; + stack::check(lua_state(), -1, handler); +#endif // Safety } basic_table_core(lua_State* L, new_table nt) : base_t(L, (lua_createtable(L, nt.sequence_hint, nt.map_hint), -1)) { @@ -17298,10 +17331,10 @@ namespace sol { #ifdef SOL_CHECK_ARGUMENTS auto pp = stack::push_pop(*this); constructor_handler handler{}; - stack::check(L, -1, handler); + stack::check(lua_state(), -1, handler); #endif // Safety } - template , basic_table_core>>, meta::neg>, std::is_base_of>> = meta::enabler> + template , basic_table_core>>, meta::neg>, is_lua_reference>> = meta::enabler> basic_table_core(T&& r) noexcept : basic_table_core(detail::no_safety, std::forward(r)) { #ifdef SOL_CHECK_ARGUMENTS @@ -17570,8 +17603,8 @@ namespace sol { template basic_table_core& add(Args&&... args) { auto pp = stack::push_pop(*this); - (void)detail::swallow{0, - (stack::set_ref(base_t::lua_state(), std::forward(args)), 0)...}; + (void)detail::swallow{ 0, + (stack::set_ref(base_t::lua_state(), std::forward(args)), 0)... }; return *this; } @@ -17744,7 +17777,7 @@ namespace sol { stack::check(L, -1, handler); #endif // Safety } - template , basic_environment>>, meta::neg>, std::is_base_of>> = meta::enabler> + template , basic_environment>>, meta::neg>, is_lua_reference>> = meta::enabler> basic_environment(T&& r) noexcept : base_t(detail::no_safety, std::forward(r)) { #ifdef SOL_CHECK_ARGUMENTS @@ -17755,6 +17788,17 @@ namespace sol { } #endif // Safety } + template >> = meta::enabler> + basic_environment(lua_State* L, T&& r) noexcept + : base_t(detail::no_safety, L, std::forward(r)) { +#ifdef SOL_CHECK_ARGUMENTS + if (!is_environment>::value) { + auto pp = stack::push_pop(*this); + constructor_handler handler{}; + stack::check(lua_state(), -1, handler); + } +#endif // Safety + } template void set_on(const T& target) const { @@ -18753,9 +18797,14 @@ namespace sol { basic_thread() noexcept = default; basic_thread(const basic_thread&) = default; basic_thread(basic_thread&&) = default; - template , basic_thread>>, std::is_base_of>> = meta::enabler> + template , basic_thread>>, is_lua_reference>> = meta::enabler> basic_thread(T&& r) : base_t(std::forward(r)) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + constructor_handler handler{}; + stack::check(L, -1, handler); +#endif // Safety } basic_thread(const stack_reference& r) : basic_thread(r.lua_state(), r.stack_index()){}; @@ -18763,16 +18812,20 @@ namespace sol { : basic_thread(r.lua_state(), r.stack_index()){}; basic_thread& operator=(const basic_thread&) = default; basic_thread& operator=(basic_thread&&) = default; - template >>> = meta::enabler> + template >> = meta::enabler> basic_thread(lua_State* L, T&& r) - : basic_thread(L, std::forward(r)) { + : base_t(L, std::forward(r)) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + constructor_handler handler{}; + stack::check(L, -1, handler); +#endif // Safety } basic_thread(lua_State* L, int index = -1) : base_t(L, index) { #ifdef SOL_CHECK_ARGUMENTS - auto pp = stack::push_pop(*this); constructor_handler handler{}; - stack::check(lua_state(), -1, handler); + stack::check(L, -1, handler); #endif // Safety } basic_thread(lua_State* L, ref_index index) @@ -18987,9 +19040,14 @@ namespace sol { basic_coroutine(stack_reference&& r) noexcept : basic_coroutine(r.lua_state(), r.stack_index()) { } - template >>> = meta::enabler> + template >> = meta::enabler> basic_coroutine(lua_State* L, T&& r) : base_t(L, std::forward(r)) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + constructor_handler handler{}; + stack::check(lua_state(), -1, handler); +#endif // Safety } basic_coroutine(lua_State* L, int index = -1) : base_t(L, index) { diff --git a/sol/coroutine.hpp b/sol/coroutine.hpp index 79df5fd1..d2aabbc8 100644 --- a/sol/coroutine.hpp +++ b/sol/coroutine.hpp @@ -87,9 +87,14 @@ namespace sol { basic_coroutine(stack_reference&& r) noexcept : basic_coroutine(r.lua_state(), r.stack_index()) { } - template >>> = meta::enabler> + template >> = meta::enabler> basic_coroutine(lua_State* L, T&& r) : base_t(L, std::forward(r)) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + constructor_handler handler{}; + stack::check(lua_state(), -1, handler); +#endif // Safety } basic_coroutine(lua_State* L, int index = -1) : base_t(L, index) { diff --git a/sol/environment.hpp b/sol/environment.hpp index 6f24e5e4..cef370c0 100644 --- a/sol/environment.hpp +++ b/sol/environment.hpp @@ -90,7 +90,7 @@ namespace sol { stack::check(L, -1, handler); #endif // Safety } - template , basic_environment>>, meta::neg>, std::is_base_of>> = meta::enabler> + template , basic_environment>>, meta::neg>, is_lua_reference>> = meta::enabler> basic_environment(T&& r) noexcept : base_t(detail::no_safety, std::forward(r)) { #ifdef SOL_CHECK_ARGUMENTS @@ -101,6 +101,17 @@ namespace sol { } #endif // Safety } + template >> = meta::enabler> + basic_environment(lua_State* L, T&& r) noexcept + : base_t(detail::no_safety, L, std::forward(r)) { +#ifdef SOL_CHECK_ARGUMENTS + if (!is_environment>::value) { + auto pp = stack::push_pop(*this); + constructor_handler handler{}; + stack::check(lua_state(), -1, handler); + } +#endif // Safety + } template void set_on(const T& target) const { diff --git a/sol/forward.hpp b/sol/forward.hpp index 95d63a4e..f8ce3576 100644 --- a/sol/forward.hpp +++ b/sol/forward.hpp @@ -76,6 +76,7 @@ namespace sol { using stack_aligned_unsafe_function = basic_function; using stack_aligned_safe_function = basic_protected_function; using protected_function = safe_function; + using main_protected_function = main_safe_function; using stack_protected_function = stack_safe_function; using stack_aligned_protected_function = stack_aligned_safe_function; #ifdef SOL_SAFE_FUNCTIONS diff --git a/sol/object.hpp b/sol/object.hpp index 39dc0fde..b0130ab3 100644 --- a/sol/object.hpp +++ b/sol/object.hpp @@ -67,7 +67,7 @@ namespace sol { public: basic_object() noexcept = default; - template , basic_object>>, meta::neg>, std::is_base_of>> = meta::enabler> + template , basic_object>>, meta::neg>, is_lua_reference>> = meta::enabler> basic_object(T&& r) : base_t(std::forward(r)) { } diff --git a/sol/object_base.hpp b/sol/object_base.hpp index 3e35a23a..cb7333d2 100644 --- a/sol/object_base.hpp +++ b/sol/object_base.hpp @@ -70,12 +70,12 @@ namespace sol { template decltype(auto) as() const { - return as_stack(std::is_same()); + return as_stack(is_stack_based()); } template bool is() const { - return is_stack(std::is_same()); + return is_stack(is_stack_based()); } }; } // namespace sol diff --git a/sol/protected_function.hpp b/sol/protected_function.hpp index 9006bbd7..4b5e4816 100644 --- a/sol/protected_function.hpp +++ b/sol/protected_function.hpp @@ -184,7 +184,7 @@ namespace sol { handler_t error_handler; basic_protected_function() = default; - template , basic_protected_function>>, meta::neg>>, meta::neg>, std::is_base_of>> = meta::enabler> + template , basic_protected_function>>, meta::neg>>, meta::neg>, is_lua_reference>> = meta::enabler> basic_protected_function(T&& r) noexcept : base_t(std::forward(r)), error_handler(get_default_handler(r.lua_state())) { #ifdef SOL_CHECK_ARGUMENTS @@ -244,6 +244,11 @@ namespace sol { template >> = meta::enabler> basic_protected_function(lua_State* L, T&& r, handler_t eh) : base_t(L, std::forward(r)), error_handler(std::move(eh)) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + constructor_handler handler{}; + stack::check(lua_state(), -1, handler); +#endif // Safety } basic_protected_function(lua_State* L, int index = -1) @@ -253,7 +258,7 @@ namespace sol { : base_t(L, index), error_handler(std::move(eh)) { #ifdef SOL_CHECK_ARGUMENTS constructor_handler handler{}; - stack::check(lua_state(), index, handler); + stack::check(L, index, handler); #endif // Safety } basic_protected_function(lua_State* L, absolute_index index) @@ -263,7 +268,7 @@ namespace sol { : base_t(L, index), error_handler(std::move(eh)) { #ifdef SOL_CHECK_ARGUMENTS constructor_handler handler{}; - stack::check(lua_state(), index, handler); + stack::check(L, index, handler); #endif // Safety } basic_protected_function(lua_State* L, raw_index index) @@ -273,7 +278,7 @@ namespace sol { : base_t(L, index), error_handler(std::move(eh)) { #ifdef SOL_CHECK_ARGUMENTS constructor_handler handler{}; - stack::check(lua_state(), index, handler); + stack::check(L, index, handler); #endif // Safety } basic_protected_function(lua_State* L, ref_index index) @@ -284,7 +289,7 @@ namespace sol { #ifdef SOL_CHECK_ARGUMENTS auto pp = stack::push_pop(*this); constructor_handler handler{}; - stack::check(L, -1, handler); + stack::check(lua_state(), -1, handler); #endif // Safety } diff --git a/sol/reference.hpp b/sol/reference.hpp index bccf0e9a..092c8f5a 100644 --- a/sol/reference.hpp +++ b/sol/reference.hpp @@ -312,8 +312,9 @@ namespace sol { } basic_reference(lua_State* L, int index = -1) noexcept : luastate(detail::pick_main_thread(L, L)) { - lua_pushvalue(lua_state(), index); - ref = luaL_ref(lua_state(), LUA_REGISTRYINDEX); + // use L to stick with that state's execution stack + lua_pushvalue(L, index); + ref = luaL_ref(L, LUA_REGISTRYINDEX); } basic_reference(lua_State* L, ref_index index) noexcept : luastate(detail::pick_main_thread(L, L)) { diff --git a/sol/table_core.hpp b/sol/table_core.hpp index 5795357d..cade6486 100644 --- a/sol/table_core.hpp +++ b/sol/table_core.hpp @@ -111,11 +111,11 @@ namespace sol { template void tuple_set(std::index_sequence, Pairs&& pairs) { auto pp = stack::push_pop < top_level && (is_global(pairs))...>::value) > (*this); - void(detail::swallow{(stack::set_field(base_t::lua_state(), - detail::forward_get(pairs), - detail::forward_get(pairs), - lua_gettop(base_t::lua_state())), - 0)...}); + void(detail::swallow{ (stack::set_field(base_t::lua_state(), + detail::forward_get(pairs), + detail::forward_get(pairs), + lua_gettop(base_t::lua_state())), + 0)... }); } template @@ -184,15 +184,21 @@ namespace sol { basic_table_core(detail::no_safety_tag, lua_State* L, ref_index index) : base_t(L, index) { } - template , basic_table_core>>, meta::neg>, std::is_base_of>> = meta::enabler> + template , basic_table_core>>, meta::neg>, is_lua_reference>> = meta::enabler> basic_table_core(detail::no_safety_tag, T&& r) noexcept : base_t(std::forward(r)) { } + template >> = meta::enabler> + basic_table_core(detail::no_safety_tag, lua_State*L, T&& r) noexcept + : base_t(L, std::forward(r)) { + } public: typedef basic_table_iterator iterator; typedef iterator const_iterator; + using base_t::lua_state; + basic_table_core() noexcept = default; basic_table_core(const basic_table_core&) = default; basic_table_core(basic_table_core&&) = default; @@ -206,7 +212,12 @@ namespace sol { } template >> = meta::enabler> basic_table_core(lua_State* L, T&& r) - : basic_table_core(L, std::forward(r)) { + : base_t(L, std::forward(r)) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + constructor_handler handler{}; + stack::check(lua_state(), -1, handler); +#endif // Safety } basic_table_core(lua_State* L, new_table nt) : base_t(L, (lua_createtable(L, nt.sequence_hint, nt.map_hint), -1)) { @@ -226,10 +237,10 @@ namespace sol { #ifdef SOL_CHECK_ARGUMENTS auto pp = stack::push_pop(*this); constructor_handler handler{}; - stack::check(L, -1, handler); + stack::check(lua_state(), -1, handler); #endif // Safety } - template , basic_table_core>>, meta::neg>, std::is_base_of>> = meta::enabler> + template , basic_table_core>>, meta::neg>, is_lua_reference>> = meta::enabler> basic_table_core(T&& r) noexcept : basic_table_core(detail::no_safety, std::forward(r)) { #ifdef SOL_CHECK_ARGUMENTS @@ -498,8 +509,8 @@ namespace sol { template basic_table_core& add(Args&&... args) { auto pp = stack::push_pop(*this); - (void)detail::swallow{0, - (stack::set_ref(base_t::lua_state(), std::forward(args)), 0)...}; + (void)detail::swallow{ 0, + (stack::set_ref(base_t::lua_state(), std::forward(args)), 0)... }; return *this; } diff --git a/sol/thread.hpp b/sol/thread.hpp index 218d0e97..f977c757 100644 --- a/sol/thread.hpp +++ b/sol/thread.hpp @@ -99,9 +99,14 @@ namespace sol { basic_thread() noexcept = default; basic_thread(const basic_thread&) = default; basic_thread(basic_thread&&) = default; - template , basic_thread>>, std::is_base_of>> = meta::enabler> + template , basic_thread>>, is_lua_reference>> = meta::enabler> basic_thread(T&& r) : base_t(std::forward(r)) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + constructor_handler handler{}; + stack::check(L, -1, handler); +#endif // Safety } basic_thread(const stack_reference& r) : basic_thread(r.lua_state(), r.stack_index()){}; @@ -109,16 +114,20 @@ namespace sol { : basic_thread(r.lua_state(), r.stack_index()){}; basic_thread& operator=(const basic_thread&) = default; basic_thread& operator=(basic_thread&&) = default; - template >>> = meta::enabler> + template >> = meta::enabler> basic_thread(lua_State* L, T&& r) - : basic_thread(L, std::forward(r)) { + : base_t(L, std::forward(r)) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + constructor_handler handler{}; + stack::check(L, -1, handler); +#endif // Safety } basic_thread(lua_State* L, int index = -1) : base_t(L, index) { #ifdef SOL_CHECK_ARGUMENTS - auto pp = stack::push_pop(*this); constructor_handler handler{}; - stack::check(lua_state(), -1, handler); + stack::check(L, -1, handler); #endif // Safety } basic_thread(lua_State* L, ref_index index) diff --git a/sol/types.hpp b/sol/types.hpp index 3a8d68cc..8e2dc744 100644 --- a/sol/types.hpp +++ b/sol/types.hpp @@ -924,11 +924,11 @@ namespace sol { template struct lua_type_of> : std::integral_constant {}; - template <> - struct lua_type_of : std::integral_constant {}; + template + struct lua_type_of> : std::integral_constant {}; - template <> - struct lua_type_of : std::integral_constant {}; + template + struct lua_type_of> : std::integral_constant {}; template struct lua_type_of> : std::integral_constant {}; diff --git a/sol/unsafe_function.hpp b/sol/unsafe_function.hpp index aa91c94f..3aa553a2 100644 --- a/sol/unsafe_function.hpp +++ b/sol/unsafe_function.hpp @@ -66,7 +66,7 @@ namespace sol { using base_t::lua_state; basic_function() = default; - template , basic_function>>, meta::neg>, std::is_base_of>> = meta::enabler> + template , basic_function>>, meta::neg>, is_lua_reference>> = meta::enabler> basic_function(T&& r) noexcept : base_t(std::forward(r)) { #ifdef SOL_CHECK_ARGUMENTS @@ -87,9 +87,14 @@ namespace sol { basic_function(stack_reference&& r) : basic_function(r.lua_state(), r.stack_index()) { } - template >, std::is_base_of>> = meta::enabler> + template >> = meta::enabler> basic_function(lua_State* L, T&& r) : base_t(L, std::forward(r)) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + constructor_handler handler{}; + stack::check(lua_state(), -1, handler); +#endif // Safety } basic_function(lua_State* L, int index = -1) : base_t(L, index) { @@ -103,7 +108,7 @@ namespace sol { #ifdef SOL_CHECK_ARGUMENTS auto pp = stack::push_pop(*this); constructor_handler handler{}; - stack::check(L, -1, handler); + stack::check(lua_state(), -1, handler); #endif // Safety } diff --git a/sol/userdata.hpp b/sol/userdata.hpp index f9b4466a..fdc08c98 100644 --- a/sol/userdata.hpp +++ b/sol/userdata.hpp @@ -34,7 +34,7 @@ namespace sol { using base_t::lua_state; basic_userdata() noexcept = default; - template , basic_userdata>>, meta::neg>, std::is_base_of>> = meta::enabler> + template , basic_userdata>>, meta::neg>, is_lua_reference>> = meta::enabler> basic_userdata(T&& r) noexcept : base_t(std::forward(r)) { #ifdef SOL_CHECK_ARGUMENTS @@ -57,6 +57,11 @@ namespace sol { template >> = meta::enabler> basic_userdata(lua_State* L, T&& r) : base_t(L, std::forward(r)) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + constructor_handler handler{}; + stack::check(L, -1, handler); +#endif // Safety } basic_userdata(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) { @@ -70,7 +75,7 @@ namespace sol { #ifdef SOL_CHECK_ARGUMENTS auto pp = stack::push_pop(*this); constructor_handler handler{}; - stack::check(L, index, handler); + stack::check(L, -1, handler); #endif // Safety } }; @@ -83,7 +88,7 @@ namespace sol { using base_t::lua_state; basic_lightuserdata() noexcept = default; - template , basic_lightuserdata>>, meta::neg>, std::is_base_of>> = meta::enabler> + template , basic_lightuserdata>>, meta::neg>, is_lua_reference>> = meta::enabler> basic_lightuserdata(T&& r) noexcept : base_t(std::forward(r)) { #ifdef SOL_CHECK_ARGUMENTS @@ -103,9 +108,14 @@ namespace sol { basic_lightuserdata(stack_reference&& r) : basic_lightuserdata(r.lua_state(), r.stack_index()) { } - template >, std::is_base_of>> = meta::enabler> + template >> = meta::enabler> basic_lightuserdata(lua_State* L, T&& r) : basic_lightuserdata(L, std::forward(r)) { +#ifdef SOL_CHECK_ARGUMENTS + auto pp = stack::push_pop(*this); + constructor_handler handler{}; + stack::check(lua_state(), -1, handler); +#endif // Safety } basic_lightuserdata(lua_State* L, int index = -1) : base_t(L, index) { @@ -119,7 +129,7 @@ namespace sol { #ifdef SOL_CHECK_ARGUMENTS auto pp = stack::push_pop(*this); constructor_handler handler{}; - stack::check(L, index, handler); + stack::check(lua_state(), index, handler); #endif // Safety } }; diff --git a/tests/tests.cpp b/tests/tests.cpp index 508ed628..f78c20f0 100644 --- a/tests/tests.cpp +++ b/tests/tests.cpp @@ -282,6 +282,60 @@ TEST_CASE("object/conversions", "make sure all basic reference types can be made REQUIRE(oenv.get_type() == sol::type::table); } +TEST_CASE("object/main_* conversions", "make sure all basic reference types can be made into objects") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + struct d {}; + + lua.safe_script("function f () print('bark') end"); + lua["d"] = d{}; + lua["l"] = static_cast(nullptr); + + sol::main_table t = lua.create_table(); + sol::main_table t2(lua, sol::create); + sol::thread th = sol::thread::create(lua); + sol::main_function f = lua["f"]; + sol::main_protected_function pf = lua["f"]; + sol::main_userdata ud = lua["d"]; + sol::main_lightuserdata lud = lua["l"]; + sol::main_environment env(lua, sol::create); + + sol::main_object ot(t); + sol::main_object ot2(t2); + sol::main_object oteq = ot; + sol::main_object oth(th); + sol::main_object of(f); + sol::main_object opf(pf); + sol::main_object od(ud); + sol::main_object ol(lud); + sol::main_object oenv(env); + + auto oni = sol::make_object(lua, 50); + auto ond = sol::make_object(lua, 50.0); + + std::string somestring = "look at this text isn't it nice"; + auto osl = sol::make_object(lua, "Bark bark bark"); + auto os = sol::make_object(lua, somestring); + + auto omn = sol::make_object(lua, sol::nil); + + REQUIRE(ot.get_type() == sol::type::table); + REQUIRE(ot2.get_type() == sol::type::table); + REQUIRE(oteq.get_type() == sol::type::table); + REQUIRE(oth.get_type() == sol::type::thread); + REQUIRE(of.get_type() == sol::type::function); + REQUIRE(opf.get_type() == sol::type::function); + REQUIRE(od.get_type() == sol::type::userdata); + REQUIRE(ol.get_type() == sol::type::lightuserdata); + REQUIRE(oni.get_type() == sol::type::number); + REQUIRE(ond.get_type() == sol::type::number); + REQUIRE(osl.get_type() == sol::type::string); + REQUIRE(os.get_type() == sol::type::string); + REQUIRE(omn.get_type() == sol::type::nil); + REQUIRE(oenv.get_type() == sol::type::table); +} + TEST_CASE("feature/indexing overrides", "make sure index functions can be overridden on types") { struct PropertySet { sol::object get_property_lua(const char* name, sol::this_state s)