diff --git a/include/sol/filters.hpp b/include/sol/filters.hpp index fbd8811e..1cead6df 100644 --- a/include/sol/filters.hpp +++ b/include/sol/filters.hpp @@ -25,6 +25,7 @@ #define SOL_FILTERS_HPP #include "traits.hpp" + #include namespace sol { @@ -86,6 +87,14 @@ namespace sol { auto filters(F&& f, Args&&... args) { return filter_wrapper, std::decay_t...>(std::forward(f), std::forward(args)...); } + + namespace detail { + template + using is_filter = meta::is_specialization_of; + + template + inline constexpr bool is_filter_v = is_filter::value; + } } // namespace sol #endif // SOL_FILTERS_HPP diff --git a/include/sol/function_types.hpp b/include/sol/function_types.hpp index a4df4220..5caf0072 100644 --- a/include/sol/function_types.hpp +++ b/include/sol/function_types.hpp @@ -370,13 +370,13 @@ namespace sol { struct unqualified_pusher> { static int push(lua_State* L, property_wrapper&& pw) { if constexpr (std::is_void_v) { - return stack::push(L, std::move(pw.write)); + return stack::push(L, std::move(pw.write())); } else if constexpr (std::is_void_v) { - return stack::push(L, std::move(pw.read)); + return stack::push(L, std::move(pw.read())); } else { - return stack::push(L, overload(std::move(pw.read), std::move(pw.write))); + return stack::push(L, overload(std::move(pw.read()), std::move(pw.write()))); } } @@ -396,10 +396,10 @@ namespace sol { template struct unqualified_pusher> { static int push(lua_State* L, var_wrapper&& vw) { - return stack::push(L, std::move(vw.value)); + return stack::push(L, std::move(vw.value())); } static int push(lua_State* L, const var_wrapper& vw) { - return stack::push(L, vw.value); + return stack::push(L, vw.value()); } }; @@ -442,6 +442,18 @@ namespace sol { } }; + template + struct unqualified_pusher> { + static int push(lua_State* L, no_construction) { + lua_CFunction cf = &function_detail::no_construction_error; + return stack::push(L, cf); + } + + static int push(lua_State* L, no_construction c, function_detail::call_indicator) { + return push(L, c); + } + }; + template struct unqualified_pusher>> { static int push(lua_State* L, detail::tagged>) { @@ -466,23 +478,43 @@ namespace sol { template struct unqualified_pusher>> { - template - static int push(lua_State* L, C&& c) { + static int push(lua_State* L, detail::tagged>&& c) { + return push(L, std::move(c.value())); + } + + static int push(lua_State* L, const detail::tagged>& c) { + return push(L, c.value()); + } + + static int push(lua_State* L, constructor_wrapper&& c) { lua_CFunction cf = call_detail::call_user, 2>; int upvalues = 0; upvalues += stack::push(L, nullptr); - upvalues += stack::push>>(L, std::forward(c)); + upvalues += stack::push>>(L, std::move(c)); + return stack::push(L, c_closure(cf, upvalues)); + } + + static int push(lua_State* L, const constructor_wrapper& c) { + lua_CFunction cf = call_detail::call_user, 2>; + int upvalues = 0; + upvalues += stack::push(L, nullptr); + upvalues += stack::push>>(L, c); return stack::push(L, c_closure(cf, upvalues)); } }; template struct unqualified_pusher> { - template - static int push(lua_State* L, C&& c) { + static int push(lua_State* L, const constructor_wrapper& c) { typedef typename meta::bind_traits::template arg_at<0> arg0; typedef meta::unqualified_t> T; - return stack::push>>(L, std::forward(c)); + return stack::push>>(L, c); + } + + static int push(lua_State* L, constructor_wrapper&& c) { + typedef typename meta::bind_traits::template arg_at<0> arg0; + typedef meta::unqualified_t> T; + return stack::push>>(L, std::move(c)); } }; @@ -553,6 +585,28 @@ namespace sol { } }; + template + struct unqualified_pusher>> { + using P = filter_wrapper; + using Tagged = detail::tagged; + + static int push(lua_State* L, const Tagged& p) { + lua_CFunction cf = call_detail::call_user; + int upvalues = 0; + upvalues += stack::push(L, nullptr); + upvalues += stack::push>(L, p.value()); + return stack::push(L, c_closure(cf, upvalues)); + } + + static int push(lua_State* L, Tagged&& p) { + lua_CFunction cf = call_detail::call_user; + int upvalues = 0; + upvalues += stack::push(L, nullptr); + upvalues += stack::push>(L, std::move(p.value())); + return stack::push(L, c_closure(cf, upvalues)); + } + }; + template struct unqualified_pusher> { static int push(lua_State* L, push_invoke_t&& pi) { diff --git a/include/sol/raii.hpp b/include/sol/raii.hpp index f8129f2b..c927bd64 100644 --- a/include/sol/raii.hpp +++ b/include/sol/raii.hpp @@ -78,10 +78,25 @@ namespace sol { template struct tagged { - T value; + private: + T value_; + + public: template , tagged>> = meta::enabler> tagged(Arg&& arg, Args&&... args) - : value(std::forward(arg), std::forward(args)...) { + : value_(std::forward(arg), std::forward(args)...) { + } + + T& value() & { + return value_; + } + + T const& value() const& { + return value_; + } + + T&& value() && { + return std::move(value_); } }; } // namespace detail diff --git a/include/sol/state_view.hpp b/include/sol/state_view.hpp index 7f64ae41..cb5f1ead 100644 --- a/include/sol/state_view.hpp +++ b/include/sol/state_view.hpp @@ -29,7 +29,9 @@ #include "environment.hpp" #include "load_result.hpp" #include "state_handling.hpp" + #include +#include namespace sol { diff --git a/include/sol/types.hpp b/include/sol/types.hpp index 6469f655..ec97127a 100644 --- a/include/sol/types.hpp +++ b/include/sol/types.hpp @@ -1290,6 +1290,9 @@ namespace sol { template <> struct is_non_factory_constructor : std::true_type {}; + template + inline constexpr bool is_non_factory_constructor_v = is_non_factory_constructor::value; + template struct is_constructor : is_non_factory_constructor {}; @@ -1302,6 +1305,9 @@ namespace sol { template struct is_constructor> : is_constructor> {}; + template + inline constexpr bool is_constructor_v = is_constructor::value; + template using any_is_constructor = meta::any>...>; @@ -1319,11 +1325,6 @@ namespace sol { template inline constexpr bool any_is_destructor_v = any_is_destructor::value; - - struct add_destructor_tag {}; - struct check_destructor_tag {}; - struct verified_tag { - } const verified{}; } // namespace detail template diff --git a/include/sol/usertype.hpp b/include/sol/usertype.hpp index 1ab9f77a..d340e10c 100644 --- a/include/sol/usertype.hpp +++ b/include/sol/usertype.hpp @@ -45,25 +45,10 @@ namespace sol { friend class basic_table_core; template - void tuple_set(std::index_sequence indices, std::tuple&& args) { - using args_tuple = std::tuple&&; - lua_State* L = this->lua_state(); - optional&> maybe_uts = u_detail::maybe_get_usertype_storage(L); - if constexpr (sizeof...(I) > 0) { - if (maybe_uts) { - u_detail::usertype_storage& uts = *maybe_uts; - (void)detail::swallow{ 0, - (uts.set(L, std::get(std::forward(args)), std::get(std::forward(args))), - 0)... }; - } - else { - table_base_t::template tuple_set(indices, std::move(args)); - } - } - else { - (void)indices; - (void)args; - } + void tuple_set(std::index_sequence, std::tuple&& args) { + (void)args; + (void)detail::swallow{ 0, + (this->set(std::get(std::move(args)), std::get(std::move(args))), 0)... }; } public: @@ -86,7 +71,15 @@ namespace sol { uts.set(this->lua_state(), std::forward(key), std::forward(value)); } else { - base_t::set(std::forward(key), std::forward(value)); + using ValueU = meta::unqualified_t; + // cannot get metatable: try regular table set? + if constexpr (detail::is_non_factory_constructor_v || detail::is_filter_v) { + // tag constructors so we don't get destroyed by lack of info + table_base_t::set(std::forward(key), detail::tagged(std::forward(value))); + } + else { + table_base_t::set(std::forward(key), std::forward(value)); + } } } diff --git a/single/include/sol/forward.hpp b/single/include/sol/forward.hpp index 6beeb18a..81150abe 100644 --- a/single/include/sol/forward.hpp +++ b/single/include/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 2019-04-28 13:40:08.826493 UTC -// This header was generated with sol v3.0.1-beta2 (revision 2d47085) +// Generated 2019-04-28 20:45:14.775010 UTC +// This header was generated with sol v3.0.1-beta2 (revision 3426947) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP diff --git a/single/include/sol/sol.hpp b/single/include/sol/sol.hpp index 182d04ad..5c22485b 100644 --- a/single/include/sol/sol.hpp +++ b/single/include/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 2019-04-28 13:40:08.534101 UTC -// This header was generated with sol v3.0.1-beta2 (revision 2d47085) +// Generated 2019-04-28 20:45:14.470847 UTC +// This header was generated with sol v3.0.1-beta2 (revision 3426947) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -5900,10 +5900,25 @@ namespace sol { template struct tagged { - T value; + private: + T value_; + + public: template , tagged>> = meta::enabler> tagged(Arg&& arg, Args&&... args) - : value(std::forward(arg), std::forward(args)...) { + : value_(std::forward(arg), std::forward(args)...) { + } + + T& value() & { + return value_; + } + + T const& value() const& { + return value_; + } + + T&& value() && { + return std::move(value_); } }; } // namespace detail @@ -6033,6 +6048,14 @@ namespace sol { auto filters(F&& f, Args&&... args) { return filter_wrapper, std::decay_t...>(std::forward(f), std::forward(args)...); } + + namespace detail { + template + using is_filter = meta::is_specialization_of; + + template + inline constexpr bool is_filter_v = is_filter::value; + } } // namespace sol // end of sol/filters.hpp @@ -7420,6 +7443,9 @@ namespace sol { template <> struct is_non_factory_constructor : std::true_type {}; + template + inline constexpr bool is_non_factory_constructor_v = is_non_factory_constructor::value; + template struct is_constructor : is_non_factory_constructor {}; @@ -7432,6 +7458,9 @@ namespace sol { template struct is_constructor> : is_constructor> {}; + template + inline constexpr bool is_constructor_v = is_constructor::value; + template using any_is_constructor = meta::any>...>; @@ -7449,11 +7478,6 @@ namespace sol { template inline constexpr bool any_is_destructor_v = any_is_destructor::value; - - struct add_destructor_tag {}; - struct check_destructor_tag {}; - struct verified_tag { - } const verified{}; } // namespace detail template @@ -17636,13 +17660,13 @@ namespace sol { struct unqualified_pusher> { static int push(lua_State* L, property_wrapper&& pw) { if constexpr (std::is_void_v) { - return stack::push(L, std::move(pw.write)); + return stack::push(L, std::move(pw.write())); } else if constexpr (std::is_void_v) { - return stack::push(L, std::move(pw.read)); + return stack::push(L, std::move(pw.read())); } else { - return stack::push(L, overload(std::move(pw.read), std::move(pw.write))); + return stack::push(L, overload(std::move(pw.read()), std::move(pw.write()))); } } @@ -17662,10 +17686,10 @@ namespace sol { template struct unqualified_pusher> { static int push(lua_State* L, var_wrapper&& vw) { - return stack::push(L, std::move(vw.value)); + return stack::push(L, std::move(vw.value())); } static int push(lua_State* L, const var_wrapper& vw) { - return stack::push(L, vw.value); + return stack::push(L, vw.value()); } }; @@ -17708,6 +17732,18 @@ namespace sol { } }; + template + struct unqualified_pusher> { + static int push(lua_State* L, no_construction) { + lua_CFunction cf = &function_detail::no_construction_error; + return stack::push(L, cf); + } + + static int push(lua_State* L, no_construction c, function_detail::call_indicator) { + return push(L, c); + } + }; + template struct unqualified_pusher>> { static int push(lua_State* L, detail::tagged>) { @@ -17732,23 +17768,43 @@ namespace sol { template struct unqualified_pusher>> { - template - static int push(lua_State* L, C&& c) { + static int push(lua_State* L, detail::tagged>&& c) { + return push(L, std::move(c.value())); + } + + static int push(lua_State* L, const detail::tagged>& c) { + return push(L, c.value()); + } + + static int push(lua_State* L, constructor_wrapper&& c) { lua_CFunction cf = call_detail::call_user, 2>; int upvalues = 0; upvalues += stack::push(L, nullptr); - upvalues += stack::push>>(L, std::forward(c)); + upvalues += stack::push>>(L, std::move(c)); + return stack::push(L, c_closure(cf, upvalues)); + } + + static int push(lua_State* L, const constructor_wrapper& c) { + lua_CFunction cf = call_detail::call_user, 2>; + int upvalues = 0; + upvalues += stack::push(L, nullptr); + upvalues += stack::push>>(L, c); return stack::push(L, c_closure(cf, upvalues)); } }; template struct unqualified_pusher> { - template - static int push(lua_State* L, C&& c) { + static int push(lua_State* L, const constructor_wrapper& c) { typedef typename meta::bind_traits::template arg_at<0> arg0; typedef meta::unqualified_t> T; - return stack::push>>(L, std::forward(c)); + return stack::push>>(L, c); + } + + static int push(lua_State* L, constructor_wrapper&& c) { + typedef typename meta::bind_traits::template arg_at<0> arg0; + typedef meta::unqualified_t> T; + return stack::push>>(L, std::move(c)); } }; @@ -17819,6 +17875,28 @@ namespace sol { } }; + template + struct unqualified_pusher>> { + using P = filter_wrapper; + using Tagged = detail::tagged; + + static int push(lua_State* L, const Tagged& p) { + lua_CFunction cf = call_detail::call_user; + int upvalues = 0; + upvalues += stack::push(L, nullptr); + upvalues += stack::push>(L, p.value()); + return stack::push(L, c_closure(cf, upvalues)); + } + + static int push(lua_State* L, Tagged&& p) { + lua_CFunction cf = call_detail::call_user; + int upvalues = 0; + upvalues += stack::push(L, nullptr); + upvalues += stack::push>(L, std::move(p.value())); + return stack::push(L, c_closure(cf, upvalues)); + } + }; + template struct unqualified_pusher> { static int push(lua_State* L, push_invoke_t&& pi) { @@ -22928,25 +23006,10 @@ namespace sol { friend class basic_table_core; template - void tuple_set(std::index_sequence indices, std::tuple&& args) { - using args_tuple = std::tuple&&; - lua_State* L = this->lua_state(); - optional&> maybe_uts = u_detail::maybe_get_usertype_storage(L); - if constexpr (sizeof...(I) > 0) { - if (maybe_uts) { - u_detail::usertype_storage& uts = *maybe_uts; - (void)detail::swallow{ 0, - (uts.set(L, std::get(std::forward(args)), std::get(std::forward(args))), - 0)... }; - } - else { - table_base_t::template tuple_set(indices, std::move(args)); - } - } - else { - (void)indices; - (void)args; - } + void tuple_set(std::index_sequence, std::tuple&& args) { + (void)args; + (void)detail::swallow{ 0, + (this->set(std::get(std::move(args)), std::get(std::move(args))), 0)... }; } public: @@ -22969,7 +23032,15 @@ namespace sol { uts.set(this->lua_state(), std::forward(key), std::forward(value)); } else { - base_t::set(std::forward(key), std::forward(value)); + using ValueU = meta::unqualified_t; + // cannot get metatable: try regular table set? + if constexpr (detail::is_non_factory_constructor_v || detail::is_filter_v) { + // tag constructors so we don't get destroyed by lack of info + table_base_t::set(std::forward(key), detail::tagged(std::forward(value))); + } + else { + table_base_t::set(std::forward(key), std::forward(value)); + } } }