diff --git a/single/sol/sol.hpp b/single/sol/sol.hpp index c6baf5cb..e5de84a7 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-07-15 14:14:12.808198 UTC -// This header was generated with sol v2.9.3 (revision f1965a4) +// Generated 2016-07-29 05:11:56.948443 UTC +// This header was generated with sol v2.10.0 (revision 045d937) // https://github.com/ThePhD/sol2 #ifndef SOL_SINGLE_INCLUDE_HPP @@ -3288,6 +3288,9 @@ 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 { }; @@ -3354,6 +3357,12 @@ 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 {}; @@ -3366,12 +3375,6 @@ 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> >::value >> : std::integral_constant {}; + + template class V, typename... Args> + struct accumulate : std::integral_constant {}; + + template class V, typename T, typename... Args> + struct accumulate : accumulate::value, V, Args...> {}; } // detail template struct lua_type_of : detail::lua_type_of {}; + template + struct lua_size : std::integral_constant { }; + + template + struct lua_size> : std::integral_constant::value + lua_size::value> { }; + + template + struct lua_size> : std::integral_constant::value> { }; + template struct is_lua_primitive : std::integral_constant>::value + || (lua_size::value > 1) || std::is_base_of>::value || std::is_base_of>::value || meta::is_specialization_of>::value @@ -3516,6 +3535,17 @@ namespace sol { namespace sol { namespace stack { + template + struct push_popper_n { + lua_State* L; + int t; + push_popper_n(lua_State* L, int x) : L(L), t(x) { } + ~push_popper_n() { lua_pop(L, t); } + }; + template <> + struct push_popper_n { + push_popper_n(lua_State*, int) { } + }; template struct push_popper { T t; @@ -3531,6 +3561,10 @@ namespace sol { push_popper push_pop(T&& x) { return push_popper(std::forward(x)); } + template + push_popper_n pop_n(lua_State* L, int x) { + return push_popper_n(L, x); + } } // stack namespace detail { @@ -3624,9 +3658,8 @@ namespace sol { } type get_type() const noexcept { - push(); + auto pp = stack::push_pop(*this); int result = lua_type(L, -1); - lua_pop(L, 1); return static_cast(result); } @@ -3697,6 +3730,11 @@ namespace sol { namespace sol { + namespace detail { + template + struct is_speshul : std::false_type {}; + } + template struct tie_size : std::tuple_size {}; @@ -3719,15 +3757,23 @@ namespace sol { typedef tie_size> tie_size; typedef std::conditional_t<(value_size::value < tie_size::value), value_size, tie_size> indices_size; typedef std::make_index_sequence indices; - set(indices(), std::forward(target)); + set_extra(detail::is_speshul>(), indices(), std::forward(target)); } template - void set(std::index_sequence, T&& target) { + void set_extra(std::true_type, std::index_sequence, T&& target) { using std::get; (void)detail::swallow{ 0, - (get(*this) = get(target), 0)... - , 0 }; + (get(*this) = get(types(), target), 0)... + , 0 }; + } + + template + void set_extra(std::false_type, std::index_sequence, T&& target) { + using std::get; + (void)detail::swallow{ 0, + (get(*this) = get(target), 0)... + , 0 }; } public: @@ -3735,8 +3781,8 @@ namespace sol { template tie_t& operator= (T&& value) { - typedef is_tieable> bondable; - set(bondable(), std::forward(value)); + typedef is_tieable> tieable; + set(tieable(), std::forward(value)); return *this; } @@ -3810,6 +3856,17 @@ namespace sol { operator bool() const { return success; }; }; + struct record { + int last; + int used; + + record() : last(), used() {} + void use(int count) { + last = count; + used += count; + } + }; + namespace stack_detail { template struct strip { @@ -3836,8 +3893,8 @@ namespace sol { false; #endif template - inline decltype(auto) unchecked_get(lua_State* L, int index = -1) { - return getter>{}.get(L, index); + inline decltype(auto) unchecked_get(lua_State* L, int index, record& tracking) { + return getter>{}.get(L, index, tracking); } } // stack_detail @@ -3892,12 +3949,18 @@ namespace sol { } template - bool check(lua_State* L, int index, Handler&& handler) { + bool check(lua_State* L, int index, Handler&& handler, record& tracking) { typedef meta::unqualified_t Tu; checker c; // VC++ has a bad warning here: shut it up (void)c; - return c.check(L, index, std::forward(handler)); + return c.check(L, index, std::forward(handler), tracking); + } + + template + bool check(lua_State* L, int index, Handler&& handler) { + record tracking{}; + return check(L, index, std::forward(handler), tracking); } template @@ -3906,9 +3969,15 @@ namespace sol { return check(L, index, handler); } + template + inline decltype(auto) check_get(lua_State* L, int index, Handler&& handler, record& tracking) { + return check_getter>{}.get(L, index, std::forward(handler), tracking); + } + template inline decltype(auto) check_get(lua_State* L, int index, Handler&& handler) { - return check_getter>{}.get(L, index, std::forward(handler)); + record tracking{}; + return check_get(L, index, handler, tracking); } template @@ -3921,20 +3990,20 @@ namespace sol { #ifdef SOL_CHECK_ARGUMENTS template - inline auto tagged_get(types, lua_State* L, int index = -1) -> decltype(stack_detail::unchecked_get(L, index)) { - auto op = check_get(L, index, type_panic); + inline auto tagged_get(types, lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_get(L, index, tracking)) { + auto op = check_get(L, index, type_panic, tracking); return *op; } #else template - inline decltype(auto) tagged_get(types, lua_State* L, int index = -1) { - return stack_detail::unchecked_get(L, index); + inline decltype(auto) tagged_get(types, lua_State* L, int index, record& tracking) { + return stack_detail::unchecked_get(L, index, tracking); } #endif template - inline decltype(auto) tagged_get(types>, lua_State* L, int index = -1) { - return stack_detail::unchecked_get>(L, index); + inline decltype(auto) tagged_get(types>, lua_State* L, int index, record& tracking) { + return stack_detail::unchecked_get>(L, index, tracking); } template @@ -3946,11 +4015,72 @@ namespace sol { return 0; } + template + struct check_types { + template + static bool check(types, lua_State* L, int firstargument, Handler&& handler, record& tracking) { + if (!stack::check(L, firstargument + tracking.used, handler, tracking)) + return false; + return check(types(), L, firstargument, std::forward(handler), tracking); + } + + template + static bool check(types<>, lua_State*, int, Handler&&, record&) { + return true; + } + }; + + template <> + struct check_types { + template + static bool check(types, lua_State*, int, Handler&&, record&) { + return true; + } + }; + } // stack_detail + template + bool multi_check(lua_State* L, int index, Handler&& handler, record& tracking) { + return stack_detail::check_types{}.check(types...>(), L, index, std::forward(handler), tracking); + } + + template + bool multi_check(lua_State* L, int index, Handler&& handler) { + record tracking{}; + return multi_check(L, index, std::forward(handler), tracking); + } + + template + bool multi_check(lua_State* L, int index) { + auto handler = no_panic; + return multi_check(L, index, handler); + } + + template + bool multi_check(lua_State* L, int index, Handler&& handler, record& tracking) { + return multi_check(L, index, std::forward(handler), tracking); + } + + template + bool multi_check(lua_State* L, int index, Handler&& handler) { + return multi_check(L, index, std::forward(handler)); + } + + template + bool multi_check(lua_State* L, int index) { + return multi_check(L, index); + } + + template + inline decltype(auto) get(lua_State* L, int index, record& tracking) { + return stack_detail::tagged_get(types(), L, index, tracking); + } + template inline decltype(auto) get(lua_State* L, int index = -1) { - return stack_detail::tagged_get(types(), L, index); + record tracking{}; + return get(L, index, tracking); } template @@ -4187,9 +4317,7 @@ namespace sol { // beginning of sol\inheritance.hpp -#if defined(SOL_NO_RTTI) && defined(SOL_NO_EXCEPTIONS) #include -#endif // No Runtime Type Information and No Exceptions namespace sol { template @@ -4210,7 +4338,6 @@ namespace sol { template bool has_derived::value = false; -#if defined(SOL_NO_RTTI) && defined(SOL_NO_EXCEPTIONS) inline std::size_t unique_id() { static std::atomic x(0); return ++x; @@ -4223,7 +4350,6 @@ namespace sol { template const std::size_t id_for::value = unique_id(); -#endif // No Runtime Type Information / No Exceptions inline decltype(auto) base_class_check_key() { static const auto& key = u8"♡o。.(✿ฺ。 ✿ฺ)"; @@ -4235,112 +4361,39 @@ namespace sol { return key; } -#ifndef SOL_NO_EXCEPTIONS - - template - void throw_as(void* p) { - throw static_cast(p); - } - - using throw_cast = decltype(&throw_as); - - template - inline T* catch_cast(void* p, throw_cast f) { - try { - f(static_cast(p)); - } - catch (T* ptr) { - return ptr; - } - catch (...) { - return static_cast(p); - } - return static_cast(p); - } - - template - inline bool catch_check(throw_cast f) { - try { - f(nullptr); - } - catch (T*) { - return true; - } - catch (...) { - return false; - } - return false; - } - -#elif !defined(SOL_NO_RTTI) template struct inheritance { - static bool type_check(types<>, const std::type_info&) { + static bool type_check_bases(types<>, std::size_t) { return false; } template - static bool type_check(types, const std::type_info& ti) { - return ti != typeid(Base) || type_check(types(), ti); - } - - static bool type_check(const std::type_info& ti) { - return ti != typeid(T) || type_check(types(), ti); - } - - static void* type_cast(types<>, T*, const std::type_info& ti) { - return nullptr; - } - - template - static void* type_cast(types, T* data, const std::type_info& ti) { - // Make sure to convert to T first, and then dynamic cast to the proper type - return ti != typeid(Base) ? type_cast(types(), data, ti) : static_cast(dynamic_cast(static_cast(data))); - } - - static void* type_cast(void* voiddata, const std::type_info& ti) { - T* data = static_cast(voiddata); - return static_cast(ti != typeid(T) ? type_cast(types(), data, ti) : data); - } - }; - - using inheritance_check_function = decltype(&inheritance::type_check); - using inheritance_cast_function = decltype(&inheritance::type_cast); -#else - template - struct inheritance { - static bool type_check(types<>, std::size_t) { - return false; - } - - template - static bool type_check(types, std::size_t ti) { - return ti != id_for::value || type_check(types(), ti); + static bool type_check_bases(types, std::size_t ti) { + return ti != id_for::value || type_check_bases(types(), ti); } static bool type_check(std::size_t ti) { - return ti != id_for::value || type_check(types(), ti); + return ti != id_for::value || type_check_bases(types(), ti); } - static void* type_cast(types<>, T*, std::size_t) { + static void* type_cast_bases(types<>, T*, std::size_t) { return nullptr; } template - static void* type_cast(types, T* data, std::size_t ti) { + static void* type_cast_bases(types, T* data, std::size_t ti) { // Make sure to convert to T first, and then dynamic cast to the proper type - return ti != id_for::value ? type_cast(types(), data, ti) : static_cast(static_cast(data)); + return ti != id_for::value ? type_cast_bases(types(), data, ti) : static_cast(static_cast(data)); } static void* type_cast(void* voiddata, std::size_t ti) { T* data = static_cast(voiddata); - return static_cast(ti != id_for::value ? type_cast(types(), data, ti) : data); + return static_cast(ti != id_for::value ? type_cast_bases(types(), data, ti) : data); } }; using inheritance_check_function = decltype(&inheritance::type_check); using inheritance_cast_function = decltype(&inheritance::type_cast); -#endif // No Exceptions and/or No Runtime Type Information } // detail } // sol @@ -4370,7 +4423,8 @@ namespace sol { template struct basic_check { template - static bool check(lua_State* L, int index, Handler&& handler) { + static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { + tracking.use(1); bool success = check_func(L, index) == 1; if (!success) { // expected type, actual type @@ -4379,35 +4433,13 @@ namespace sol { return success; } }; - - template - struct check_types { - template - static bool check(types, std::index_sequence, lua_State* L, int firstargument, Handler&& handler) { - if (!stack::check(L, firstargument + I0, handler)) - return false; - return check(types(), std::index_sequence(), L, firstargument - static_cast(is_transparent_argument>::value), std::forward(handler)); - } - - template - static bool check(types<>, std::index_sequence<>, lua_State*, int, Handler&&) { - return true; - } - }; - - template <> - struct check_types { - template - static bool check(types, std::index_sequence, lua_State*, int, Handler&&) { - return true; - } - }; } // stack_detail template struct checker { template - static bool check(lua_State* L, int index, Handler&& handler) { + static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { + tracking.use(1); const type indextype = type_of(L, index); bool success = expected == indextype; if (!success) { @@ -4418,19 +4450,17 @@ namespace sol { } }; - template - struct checker { - template - static bool check(lua_State*, int, Handler&&) { - return true; - } - }; - template struct checker { template - static bool check(lua_State* L, int index, Handler&& handler) { - bool success = lua_isnoneornil(L, index); + static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { + bool success = lua_isnil(L, index); + if (success) { + tracking.use(1); + return success; + } + tracking.use(0); + success = lua_isnone(L, index); if (!success) { // expected type, actual type handler(L, index, expected, type_of(L, index)); @@ -4443,9 +4473,10 @@ namespace sol { struct checker : checker {}; template - struct checker { + struct checker { template - static bool check(lua_State*, int, Handler&&) { + static bool check(lua_State*, int, Handler&&, record& tracking) { + tracking.use(0); return true; } }; @@ -4453,7 +4484,17 @@ namespace sol { template struct checker { template - static bool check(lua_State*, int, Handler&&) { + static bool check(lua_State*, int, Handler&&, record& tracking) { + tracking.use(0); + return true; + } + }; + + template + struct checker { + template + static bool check(lua_State*, int, Handler&&, record& tracking) { + tracking.use(0); return true; } }; @@ -4461,7 +4502,8 @@ namespace sol { template struct checker { template - static bool check(lua_State* L, int index, Handler&& handler) { + static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { + tracking.use(1); bool success = !lua_isnone(L, index); if (!success) { // expected type, actual type @@ -4474,7 +4516,8 @@ namespace sol { template struct checker { template - static bool check(lua_State* L, int index, Handler&& handler) { + static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { + tracking.use(1); type t = type_of(L, index); bool success = t == type::userdata || t == type::lightuserdata; if (!success) { @@ -4488,7 +4531,8 @@ namespace sol { template struct checker { template - static bool check(lua_State* L, int index, Handler&& handler) { + static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { + tracking.use(1); type t = type_of(L, index); bool success = t == type::userdata; if (!success) { @@ -4515,7 +4559,8 @@ namespace sol { template struct checker { template - static bool check(lua_State* L, int index, Handler&& handler) { + static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { + tracking.use(1); type t = type_of(L, index); if (t == type::nil || t == type::none || t == type::function) { // allow for nil to be returned @@ -4529,14 +4574,14 @@ namespace sol { static const auto& callkey = name_of(meta_function::call); lua_getmetatable(L, index); if (lua_isnoneornil(L, -1)) { - handler(L, index, t, type::function); lua_pop(L, 1); + handler(L, index, t, type::function); return false; } lua_getfield(L, -1, &callkey[0]); if (lua_isnoneornil(L, -1)) { - handler(L, index, t, type::function); lua_pop(L, 2); + handler(L, index, t, type::function); return false; } // has call, is definitely a function @@ -4548,7 +4593,8 @@ namespace sol { template struct checker { template - static bool check(lua_State* L, int index, Handler&& handler) { + static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { + tracking.use(1); type t = type_of(L, index); if (t == type::table) { return true; @@ -4564,20 +4610,22 @@ namespace sol { template struct checker { template - static bool check(lua_State* L, int index, Handler&& handler) { + static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { + tracking.use(1); const type indextype = type_of(L, index); // Allow nil to be transformed to nullptr if (indextype == type::nil) { return true; } - return checker{}.check(types(), L, indextype, index, std::forward(handler)); + return checker{}.check(types(), L, indextype, index, std::forward(handler), tracking); } }; template struct checker { template - static bool check(types, lua_State* L, type indextype, int index, Handler&& handler) { + static bool check(types, lua_State* L, type indextype, int index, Handler&& handler, record& tracking) { + tracking.use(1); if (indextype != type::userdata) { handler(L, index, type::userdata, indextype); return false; @@ -4594,30 +4642,15 @@ namespace sol { if (stack_detail::check_metatable>(L)) return true; bool success = false; -#ifndef SOL_NO_EXCEPTIONS - lua_getfield(L, -1, &detail::base_class_check_key()[0]); - if (type_of(L, -1) != type::nil) { - void* basecastdata = lua_touserdata(L, -1); - detail::throw_cast basecast = (detail::throw_cast)basecastdata; - success = detail::catch_check(basecast); + { + auto pn = stack::pop_n(L, 2); + lua_getfield(L, -1, &detail::base_class_check_key()[0]); + if (type_of(L, -1) != type::nil) { + void* basecastdata = lua_touserdata(L, -1); + detail::inheritance_check_function ic = (detail::inheritance_check_function)basecastdata; + success = ic(detail::id_for::value); + } } -#elif !defined(SOL_NO_RTTI) - lua_getfield(L, -1, &detail::base_class_check_key()[0]); - if (type_of(L, -1) != type::nil) { - void* basecastdata = lua_touserdata(L, -1); - detail::inheritance_check_function ic = (detail::inheritance_check_function)basecastdata; - success = ic(typeid(T)); - } -#else - // Topkek - lua_getfield(L, -1, &detail::base_class_check_key()[0]); - if (type_of(L, -1) != type::nil) { - void* basecastdata = lua_touserdata(L, -1); - detail::inheritance_check_function ic = (detail::inheritance_check_function)basecastdata; - success = ic(detail::id_for::value); - } -#endif // No Runtime Type Information || Exceptions - lua_pop(L, 2); if (!success) { handler(L, index, type::userdata, indextype); return false; @@ -4626,56 +4659,54 @@ namespace sol { } template - static bool check(lua_State* L, int index, Handler&& handler) { + static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { const type indextype = type_of(L, index); - return check(types(), L, indextype, index, std::forward(handler)); + return check(types(), L, indextype, index, std::forward(handler), tracking); } }; template struct checker::value>> { template - static bool check(lua_State* L, int index, Handler&& handler) { - return checker::type, type::userdata>{}.check(L, index, std::forward(handler)); + static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { + return checker::type, type::userdata>{}.check(L, index, std::forward(handler), tracking); } }; template struct checker, type::userdata, C> { template - static bool check(lua_State* L, int index, Handler&& handler) { - return checker{}.check(L, index, std::forward(handler)); + static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { + return checker{}.check(L, index, std::forward(handler), tracking); } }; template struct checker, type::poly, C> { - template - static bool apply(std::index_sequence is, lua_State* L, int index, Handler&& handler) { - index = index < 0 ? lua_absindex(L, index) - (sizeof...(I)-1) : index; - return stack_detail::check_types{}.check(types(), is, L, index, handler); - } - template - static bool check(lua_State* L, int index, Handler&& handler) { - return apply(std::make_index_sequence(), L, index, std::forward(handler)); + static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { + return stack::multi_check(L, index, std::forward(handler), tracking); } }; template struct checker, type::poly, C> { template - static bool check(lua_State* L, int index, Handler&& handler) { - index = index < 0 ? lua_absindex(L, index) - 1 : index; - return stack::check(L, index, handler) && stack::check(L, index + 1, handler); + static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { + return stack::multi_check(L, index, std::forward(handler), tracking); } }; template struct checker, type::poly, C> { template - static bool check(lua_State* L, int index, Handler&& handler) { - return lua_isnoneornil(L, index) || stack::check(L, index, std::forward(handler)); + static bool check(lua_State* L, int index, Handler&& handler, record& tracking) { + type t = type_of(L, index); + if (t == type::none) { + tracking.use(0); + return true; + } + return t == type::nil || stack::check(L, index, std::forward(handler), tracking); } }; } // stack @@ -4712,98 +4743,111 @@ namespace sol { template struct getter { - static T& get(lua_State* L, int index = -1) { - return getter{}.get(L, index); + static T& get(lua_State* L, int index, record& tracking) { + return getter{}.get(L, index, tracking); } }; template struct getter::value>> { - static T get(lua_State* L, int index = -1) { + static T get(lua_State* L, int index, record& tracking) { + tracking.use(1); return static_cast(lua_tonumber(L, index)); } }; template struct getter, std::is_signed>::value>> { - static T get(lua_State* L, int index = -1) { + static T get(lua_State* L, int index, record& tracking) { + tracking.use(1); return static_cast(lua_tointeger(L, index)); } }; template struct getter, std::is_unsigned>::value>> { - static T get(lua_State* L, int index = -1) { + static T get(lua_State* L, int index, record& tracking) { + tracking.use(1); return static_cast(lua_tointeger(L, index)); } }; template struct getter::value>> { - static T get(lua_State* L, int index = -1) { + static T get(lua_State* L, int index, record& tracking) { + tracking.use(1); return static_cast(lua_tointegerx(L, index, nullptr)); } }; template struct getter::value || std::is_base_of::value>> { - static T get(lua_State* L, int index = -1) { + static T get(lua_State* L, int index, record& tracking) { + tracking.use(1); return T(L, index); } }; template<> struct getter { - static userdata_value get(lua_State* L, int index = -1) { + static userdata_value get(lua_State* L, int index, record& tracking) { + tracking.use(1); return userdata_value(lua_touserdata(L, index)); } }; template<> struct getter { - static lightuserdata_value get(lua_State* L, int index = -1) { + static lightuserdata_value get(lua_State* L, int index, record& tracking) { + tracking.use(1); return lightuserdata_value(lua_touserdata(L, index)); } }; template struct getter> { - static light get(lua_State* L, int index = -1) { + static light get(lua_State* L, int index, record& tracking) { + tracking.use(1); return light(static_cast(lua_touserdata(L, index))); } }; template struct getter> { - static T& get(lua_State* L, int index = -1) { + static T& get(lua_State* L, int index, record& tracking) { + tracking.use(1); return *static_cast(lua_touserdata(L, index)); } }; template struct getter> { - static T* get(lua_State* L, int index = -1) { + static T* get(lua_State* L, int index, record& tracking) { + tracking.use(1); return static_cast(lua_touserdata(L, index)); } }; template<> struct getter { - static type get(lua_State *L, int index) { + static type get(lua_State *L, int index, record& tracking) { + tracking.use(1); return static_cast(lua_type(L, index)); } }; template<> struct getter { - static bool get(lua_State* L, int index) { + static bool get(lua_State* L, int index, record& tracking) { + tracking.use(1); return lua_toboolean(L, index) != 0; } }; template<> struct getter { - static std::string get(lua_State* L, int index = -1) { + static std::string get(lua_State* L, int index, record& tracking) { + tracking.use(1); std::size_t len; auto str = lua_tolstring(L, index, &len); return{ str, len }; @@ -4812,7 +4856,8 @@ namespace sol { template <> struct getter { - string_detail::string_shim get(lua_State* L, int index) { + string_detail::string_shim get(lua_State* L, int index, record& tracking) { + tracking.use(1); size_t len; const char* p = lua_tolstring(L, index, &len); return string_detail::string_shim(p, len); @@ -4821,15 +4866,17 @@ namespace sol { template<> struct getter { - static const char* get(lua_State* L, int index = -1) { + static const char* get(lua_State* L, int index, record& tracking) { + tracking.use(1); return lua_tostring(L, index); } }; template<> struct getter { - static meta_function get(lua_State *L, int index) { - const char* name = getter{}.get(L, index); + static meta_function get(lua_State *L, int index, record& tracking) { + tracking.use(1); + const char* name = getter{}.get(L, index, tracking); for (std::size_t i = 0; i < meta_function_names.size(); ++i) if (meta_function_names[i] == name) return static_cast(i); @@ -4839,7 +4886,8 @@ namespace sol { template<> struct getter { - static char get(lua_State* L, int index = -1) { + static char get(lua_State* L, int index, record& tracking) { + tracking.use(1); size_t len; auto str = lua_tolstring(L, index, &len); return len > 0 ? str[0] : '\0'; @@ -4850,28 +4898,32 @@ namespace sol { template<> struct getter { - static std::wstring get(lua_State* L, int index = -1) { + static std::wstring get(lua_State* L, int index, record& tracking) { + tracking.use(1); return{}; } }; template<> struct getter { - static std::u16string get(lua_State* L, int index = -1) { + static std::u16string get(lua_State* L, int index, record& tracking) { + tracking.use(1); return{}; } }; template<> struct getter { - static std::u32string get(lua_State* L, int index = -1) { + static std::u32string get(lua_State* L, int index, record& tracking) { + tracking.use(1); return{}; } }; template<> struct getter { - static wchar_t get(lua_State* L, int index = -1) { + static wchar_t get(lua_State* L, int index, record& tracking) { + tracking.use(1); auto str = getter{}.get(L, index); return str.size() > 0 ? str[0] : '\0'; } @@ -4879,7 +4931,8 @@ namespace sol { template<> struct getter { - static char get(lua_State* L, int index = -1) { + static char get(lua_State* L, int index, record& tracking) { + tracking.use(1); auto str = getter{}.get(L, index); return str.size() > 0 ? str[0] : '\0'; } @@ -4887,7 +4940,8 @@ namespace sol { template<> struct getter { - static char32_t get(lua_State* L, int index = -1) { + static char32_t get(lua_State* L, int index, record& tracking) { + tracking.use(1); auto str = getter{}.get(L, index); return str.size() > 0 ? str[0] : '\0'; } @@ -4897,49 +4951,56 @@ namespace sol { template<> struct getter { - static nil_t get(lua_State*, int = -1) { + static nil_t get(lua_State*, int, record& tracking) { + tracking.use(1); return nil; } }; template<> - struct pusher { - static std::nullptr_t get(lua_State*, int = -1) { + struct getter { + static std::nullptr_t get(lua_State*, int, record& tracking) { + tracking.use(1); return nullptr; } }; template<> struct getter { - static nullopt_t get(lua_State*, int = -1) { + static nullopt_t get(lua_State*, int, record& tracking) { + tracking.use(1); return nullopt; } }; template<> struct getter { - static this_state get(lua_State* L, int = -1) { + static this_state get(lua_State* L, int, record& tracking) { + tracking.use(0); return this_state{ L }; } }; template<> struct getter { - static lua_CFunction get(lua_State* L, int index = -1) { + static lua_CFunction get(lua_State* L, int index, record& tracking) { + tracking.use(1); return lua_tocfunction(L, index); } }; template<> struct getter { - static c_closure get(lua_State* L, int index = -1) { + static c_closure get(lua_State* L, int index, record& tracking) { + tracking.use(1); return c_closure(lua_tocfunction(L, index), -1); } }; template<> struct getter { - static error get(lua_State* L, int index = -1) { + static error get(lua_State* L, int index, record& tracking) { + tracking.use(1); size_t sz = 0; const char* err = lua_tolstring(L, index, &sz); if (err == nullptr) { @@ -4951,38 +5012,22 @@ namespace sol { template<> struct getter { - static void* get(lua_State* L, int index = -1) { + static void* get(lua_State* L, int index, record& tracking) { + tracking.use(1); return lua_touserdata(L, index); } }; template struct getter { - static T* get_no_nil(lua_State* L, int index = -1) { + static T* get_no_nil(lua_State* L, int index, record& tracking) { + tracking.use(1); void** pudata = static_cast(lua_touserdata(L, index)); void* udata = *pudata; - return get_no_nil_from(L, udata, index); + return get_no_nil_from(L, udata, index, tracking); } - static T* get_no_nil_from(lua_State* L, void* udata, int index = -1) { -#ifndef SOL_NO_EXCEPTIONS - if (detail::has_derived::value && luaL_getmetafield(L, index, &detail::base_class_check_key()[0]) != 0) { - void* basecastdata = lua_touserdata(L, -1); - detail::throw_cast basecast = (detail::throw_cast)basecastdata; - // use the casting function to properly adjust the pointer for the desired T - udata = detail::catch_cast(udata, basecast); - lua_pop(L, 1); - } -#elif !defined(SOL_NO_RTTI) - if (detail::has_derived::value && luaL_getmetafield(L, index, &detail::base_class_cast_key()[0]) != 0) { - void* basecastdata = lua_touserdata(L, -1); - detail::inheritance_cast_function ic = (detail::inheritance_cast_function)basecastdata; - // use the casting function to properly adjust the pointer for the desired T - udata = ic(udata, typeid(T)); - lua_pop(L, 1); - } -#else - // Lol, you motherfucker + static T* get_no_nil_from(lua_State* L, void* udata, int index, record&) { if (detail::has_derived::value && luaL_getmetafield(L, index, &detail::base_class_cast_key()[0]) != 0) { void* basecastdata = lua_touserdata(L, -1); detail::inheritance_cast_function ic = (detail::inheritance_cast_function)basecastdata; @@ -4990,30 +5035,31 @@ namespace sol { udata = ic(udata, detail::id_for::value); lua_pop(L, 1); } -#endif // No Runtime Type Information || Exceptions T* obj = static_cast(udata); return obj; } - static T* get(lua_State* L, int index = -1) { + static T* get(lua_State* L, int index, record& tracking) { type t = type_of(L, index); - if (t == type::nil) + if (t == type::nil) { + tracking.use(1); return nullptr; - return get_no_nil(L, index); + } + return get_no_nil(L, index, tracking); } }; template struct getter> { - static T* get(lua_State* L, int index = -1) { - return getter::get_no_nil(L, index); + static T* get(lua_State* L, int index, record& tracking) { + return getter::get_no_nil(L, index, tracking); } }; template struct getter { - static T& get(lua_State* L, int index = -1) { - return *getter::get_no_nil(L, index); + static T& get(lua_State* L, int index, record& tracking) { + return *getter::get_no_nil(L, index, tracking); } }; @@ -5022,7 +5068,8 @@ namespace sol { typedef typename unique_usertype_traits::type P; typedef typename unique_usertype_traits::actual_type Real; - static Real& get(lua_State* L, int index = -1) { + static Real& get(lua_State* L, int index, record& tracking) { + tracking.use(1); P** pref = static_cast(lua_touserdata(L, index)); detail::special_destruct_func* fx = static_cast(static_cast(pref + 1)); Real* mem = static_cast(static_cast(fx + 1)); @@ -5032,29 +5079,27 @@ namespace sol { template struct getter> { - static T& get(lua_State* L, int index = -1) { - return getter{}.get(L, index); + static T& get(lua_State* L, int index, record& tracking) { + return getter{}.get(L, index, tracking); } }; template struct getter> { template - static decltype(auto) apply(std::index_sequence, lua_State* L, int index = -1) { - index = index < 0 ? lua_absindex(L, index) - (sizeof...(I)-1) : index; - return std::tuple(L, index + I))...>(stack::get(L, index + I)...); + static decltype(auto) apply(std::index_sequence, lua_State* L, int index, record& tracking) { + return std::tuple(L, index))...>{stack::get(L, index + tracking.used, tracking)...}; } - static decltype(auto) get(lua_State* L, int index = -1) { - return apply(std::make_index_sequence(), L, index); + static decltype(auto) get(lua_State* L, int index, record& tracking) { + return apply(std::make_index_sequence(), L, index, tracking); } }; template struct getter> { - static decltype(auto) get(lua_State* L, int index = -1) { - index = index < 0 ? lua_absindex(L, index) - 1 : index; - return std::pair(L, index)), decltype(stack::get(L, index))>(stack::get(L, index), stack::get(L, index + 1)); + static decltype(auto) get(lua_State* L, int index, record& tracking) { + return std::pair(L, index)), decltype(stack::get(L, index))>{stack::get(L, index, tracking), stack::get(L, index + tracking.used, tracking)}; } }; @@ -5069,35 +5114,39 @@ namespace sol { namespace stack { template struct check_getter { - typedef stack_detail::strip_t U; - typedef std::conditional_t::value, U, U&> R; + typedef decltype(stack_detail::unchecked_get(nullptr, 0, std::declval())) R; template - static optional get(lua_State* L, int index, Handler&& handler) { - if (!check(L, index, std::forward(handler))) + static optional get(lua_State* L, int index, Handler&& handler, record& tracking) { + if (!check(L, index, std::forward(handler))) { + tracking.use(static_cast(!lua_isnone(L, index))); return nullopt; - return stack_detail::unchecked_get(L, index); + } + return stack_detail::unchecked_get(L, index, tracking); } }; template struct check_getter> { template - static decltype(auto) get(lua_State* L, int index, Handler&&) { - return check_get(L, index, no_panic); + static decltype(auto) get(lua_State* L, int index, Handler&&, record& tracking) { + return check_get(L, index, no_panic, tracking); } }; template struct check_getter::value && lua_type_of::value == type::number>> { template - static optional get(lua_State* L, int index, Handler&& handler) { + static optional get(lua_State* L, int index, Handler&& handler, record& tracking) { int isnum = 0; lua_Integer value = lua_tointegerx(L, index, &isnum); if (isnum == 0) { - handler(L, index, type::number, type_of(L, index)); + type t = type_of(L, index); + tracking.use(static_cast(t != type::none)); + handler(L, index, type::number, t); return nullopt; } + tracking.use(1); return static_cast(value); } }; @@ -5105,13 +5154,16 @@ namespace sol { template struct check_getter::value && !meta::any_same::value>> { template - static optional get(lua_State* L, int index, Handler&& handler) { + static optional get(lua_State* L, int index, Handler&& handler, record& tracking) { int isnum = 0; lua_Integer value = lua_tointegerx(L, index, &isnum); if (isnum == 0) { - handler(L, index, type::number, type_of(L, index)); + type t = type_of(L, index); + tracking.use(static_cast(t != type::none)); + handler(L, index, type::number, t); return nullopt; } + tracking.use(1); return static_cast(value); } }; @@ -5119,21 +5171,24 @@ namespace sol { template struct check_getter::value>> { template - static optional get(lua_State* L, int index, Handler&& handler) { + static optional get(lua_State* L, int index, Handler&& handler, record& tracking) { int isnum = 0; lua_Number value = lua_tonumberx(L, index, &isnum); if (isnum == 0) { - handler(L, index, type::number, type_of(L, index)); + type t = type_of(L, index); + tracking.use(static_cast(t != type::none)); + handler(L, index, type::number, t); return nullopt; } + tracking.use(1); return static_cast(value); } }; template struct getter> { - static decltype(auto) get(lua_State* L, int index) { - return check_get(L, index, no_panic); + static decltype(auto) get(lua_State* L, int index, record& tracking) { + return check_get(L, index, no_panic, tracking); } }; } // stack @@ -5735,6 +5790,13 @@ namespace sol { } }; + template<> + struct pusher { + static int push(lua_State* L, std::nullptr_t) { + return stack::push(L, nil); + } + }; + template<> struct pusher { static int push(lua_State*, const this_state&) { @@ -5753,26 +5815,9 @@ namespace sol { template struct popper { inline static decltype(auto) pop(lua_State* L) { - decltype(auto) r = get(L); - lua_pop(L, 1); - return r; - } - }; - - template - struct popper> { - inline static decltype(auto) pop(lua_State* L) { - decltype(auto) r = get>(L); - lua_pop(L, static_cast(sizeof...(Args))); - return r; - } - }; - - template - struct popper> { - inline static decltype(auto) pop(lua_State* L) { - decltype(auto) r = get>(L); - lua_pop(L, 2); + record tracking{}; + decltype(auto) r = get(L, -lua_size::value, tracking); + lua_pop(L, tracking.used); return r; } }; @@ -6101,13 +6146,26 @@ namespace sol { return std::pair(*reinterpret_cast(static_cast(voiddata.data())), index); } + struct evaluator { + template + static decltype(auto) eval(types<>, std::index_sequence<>, lua_State*, int, record&, Fx&& fx, Args&&... args) { + return std::forward(fx)(std::forward(args)...); + } + + template + static decltype(auto) eval(types, std::index_sequence, lua_State* L, int start, record& tracking, Fx&& fx, FxArgs&&... fxargs) { + return eval(types(), std::index_sequence(), L, start, tracking, std::forward(fx), std::forward(fxargs)..., stack_detail::unchecked_get(L, start + tracking.used, tracking)); + } + }; + template ::value>> inline decltype(auto) call(types, types ta, std::index_sequence tai, lua_State* L, int start, Fx&& fx, FxArgs&&... args) { #ifndef _MSC_VER static_assert(meta::all...>::value, "One of the arguments being bound is a move-only type, and it is not being taken by reference: this will break your code. Please take a reference and std::move it manually if this was your intention."); #endif // This compiler make me so fucking sad - check_types{}.check(ta, tai, L, start, type_panic); - return fx(std::forward(args)..., stack_detail::unchecked_get(L, start + I - meta::count_for_to_pack::value)...); + multi_check(L, start, type_panic); + record tracking{}; + return evaluator{}.eval(ta, tai, L, start, tracking, std::forward(fx), std::forward(args)...); } template @@ -6115,8 +6173,9 @@ namespace sol { #ifndef _MSC_VER static_assert(meta::all...>::value, "One of the arguments being bound is a move-only type, and it is not being taken by reference: this will break your code. Please take a reference and std::move it manually if this was your intention."); #endif // This compiler make me so fucking sad - check_types{}.check(ta, tai, L, start, type_panic); - fx(std::forward(args)..., stack_detail::unchecked_get(L, start + I - meta::count_for_to_pack::value)...); + multi_check(L, start, type_panic); + record tracking{}; + evaluator{}.eval(ta, tai, L, start, tracking, std::forward(fx), std::forward(args)...); } } // stack_detail @@ -6183,12 +6242,14 @@ namespace sol { template inline int call_into_lua(types tr, types ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) { call(tr, ta, L, start, std::forward(fx), std::forward(fxargs)...); + lua_settop(L, 0); return 0; } template>::value>> inline int call_into_lua(types, types ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) { decltype(auto) r = call(types>(), ta, L, start, std::forward(fx), std::forward(fxargs)...); + lua_settop(L, 0); return push_reference(L, std::forward(r)); } @@ -6202,11 +6263,10 @@ namespace sol { inline call_syntax get_call_syntax(lua_State* L, const std::string& key, int index = -2) { luaL_getmetatable(L, key.c_str()); + auto pn = pop_n(L, 1); if (lua_compare(L, -1, index, LUA_OPEQ) == 1) { - lua_pop(L, 1); return call_syntax::colon; } - lua_pop(L, 1); return call_syntax::dot; } @@ -6225,8 +6285,8 @@ namespace sol { inline void luajit_exception_handler(lua_State* L, int(*handler)(lua_State*, lua_CFunction) = detail::c_trampoline) { #ifdef SOL_LUAJIT lua_pushlightuserdata(L, (void*)handler); + auto pn = pop_n(L, 1); luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_ON); - lua_pop(L, 1); #else (void)L; (void)handler; @@ -6719,7 +6779,6 @@ namespace sol { typedef lua_bind_traits> traits; typedef meta::tuple_types return_types; typedef typename traits::free_args_list args_list; - typedef typename args_list::indices args_indices; // compile-time eliminate any functions that we know ahead of time are of improper arity if (meta::find_in_pack_v, index_value...>::value) { return overload_match_arity(types(), std::index_sequence(), std::index_sequence(), std::forward(matchfx), L, fxarity, start, std::forward(args)...); @@ -6727,7 +6786,8 @@ namespace sol { 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)...); } - if (!stack::stack_detail::check_types().check(args_list(), args_indices(), L, start, no_panic)) { + stack::record tracking{}; + if (!stack::stack_detail::check_types{}.check(args_list(), L, start, no_panic, tracking)) { return overload_match_arity(types(), std::index_sequence(), std::index_sequence(), std::forward(matchfx), L, fxarity, start, std::forward(args)...); } return matchfx(types(), index_value(), return_types(), args_list(), L, fxarity, start, std::forward(args)...); @@ -7001,7 +7061,7 @@ namespace sol { int operator()(types, index_value, types r, types a, lua_State* L, int, int start, F& f) { const auto& metakey = usertype_traits::metatable; T** pointerpointer = reinterpret_cast(lua_newuserdata(L, sizeof(T*) + sizeof(T))); - stack_reference userdataref(L, -1); + reference userdataref(L, -1); T*& referencepointer = *pointerpointer; T* obj = reinterpret_cast(pointerpointer + 1); referencepointer = obj; @@ -7851,13 +7911,13 @@ namespace sol { template auto invoke(types, std::index_sequence, std::ptrdiff_t n) const { - luacall(n, sizeof...(Ret)); + luacall(n, lua_size>::value); return stack::pop>(base_t::lua_state()); } template Ret invoke(types, std::index_sequence, std::ptrdiff_t n) const { - luacall(n, 1); + luacall(n, lua_size::value); return stack::pop(base_t::lua_state()); } @@ -7915,7 +7975,7 @@ namespace sol { typedef meta::tuple_types return_types; template - static std::function get_std_func(types, types, lua_State* L, int index = -1) { + static std::function get_std_func(types, types, lua_State* L, int index) { sol::function f(L, index); auto fx = [f, L, index](Args&&... args) -> meta::return_type_t { return f.call(std::forward(args)...); @@ -7924,7 +7984,7 @@ namespace sol { } template - static std::function get_std_func(types, types, lua_State* L, int index = -1) { + static std::function get_std_func(types, types, lua_State* L, int index) { sol::function f(L, index); auto fx = [f, L, index](FxArgs&&... args) -> void { f(std::forward(args)...); @@ -7933,11 +7993,13 @@ namespace sol { } template - static std::function get_std_func(types<>, types t, lua_State* L, int index = -1) { + static std::function get_std_func(types<>, types t, lua_State* L, int index) { return get_std_func(types(), t, L, index); } - static std::function get(lua_State* L, int index) { + static std::function get(lua_State* L, int index, record& tracking) { + tracking.last = 1; + tracking.used += 1; type t = type_of(L, index); if (t == type::none || t == type::nil) { return nullptr; @@ -8248,6 +8310,23 @@ namespace sol { }; } // stack + namespace detail { + template <> + struct is_speshul : std::true_type {}; + template <> + struct is_speshul : std::true_type {}; + + template + stack_proxy get(types, index_value<0>, index_value, const T& fr) { + return stack_proxy(fr.lua_state(), static_cast(fr.stack_index() + I)); + } + + template 0)>> = meta::enabler> + stack_proxy get(types, index_value, index_value, const T& fr) { + return get(types(), index_value(), index_value::value>(), fr); + } + } + template <> struct tie_size : std::integral_constant {}; @@ -8256,6 +8335,11 @@ namespace sol { return stack_proxy(fr.lua_state(), static_cast(fr.stack_index() + I)); } + template + stack_proxy get(types t, const function_result& fr) { + return detail::get(t, index_value(), index_value<0>(), fr); + } + template <> struct tie_size : std::integral_constant {}; @@ -8263,6 +8347,11 @@ namespace sol { stack_proxy get(const protected_function_result& fr) { return stack_proxy(fr.lua_state(), static_cast(fr.stack_index() + I)); } + + template + stack_proxy get(types t, const protected_function_result& fr) { + return detail::get(t, index_value(), index_value<0>(), fr); + } } // sol // end of sol\stack_proxy.hpp @@ -8461,7 +8550,8 @@ namespace sol { namespace stack { template <> struct getter { - static variadic_args get(lua_State* L, int index = -1) { + static variadic_args get(lua_State* L, int index, record& tracking) { + tracking.last = 0; return variadic_args(L, index); } }; @@ -8543,7 +8633,9 @@ namespace sol { object make_reference(lua_State* L, Args&&... args) { int backpedal = stack::push(L, std::forward(args)...); object r = stack::get(L, -backpedal); - lua_pop(L, backpedal); + if (should_pop) { + lua_pop(L, backpedal); + } return r; } @@ -8905,20 +8997,11 @@ namespace sol { return; } (void)detail::swallow{ 0, ((detail::has_derived::value = true), 0)... }; -#ifndef SOL_NO_EXCEPTIONS - static_assert(sizeof(void*) <= sizeof(detail::throw_cast), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report."); - baseclasscheck = baseclasscast = (void*)&detail::throw_as; -#elif !defined(SOL_NO_RTTI) + static_assert(sizeof(void*) <= sizeof(detail::inheritance_check_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report."); static_assert(sizeof(void*) <= sizeof(detail::inheritance_cast_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report."); - baseclasscheck = (void*)&detail::inheritance::type_check; - baseclasscast = (void*)&detail::inheritance::type_cast; -#else - static_assert(sizeof(void*) <= sizeof(detail::inheritance_check_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report."); - static_assert(sizeof(void*) <= sizeof(detail::inheritance_cast_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report."); - baseclasscheck = (void*)&detail::inheritance::type_check; - baseclasscast = (void*)&detail::inheritance::type_cast; -#endif // No Runtime Type Information vs. Throw-Style Inheritance + baseclasscheck = (void*)&detail::inheritance::type_check; + baseclasscast = (void*)&detail::inheritance::type_cast; } template , base_classes_tag, call_construction>::value>> @@ -9464,8 +9547,8 @@ namespace sol { sol::object key(base_t::lua_state(), -2); sol::object value(base_t::lua_state(), -1); std::pair keyvalue(key, value); + auto pn = stack::pop_n(base_t::lua_state(), 1); fx(keyvalue); - lua_pop(base_t::lua_state(), 1); } } @@ -9476,8 +9559,8 @@ namespace sol { while (lua_next(base_t::lua_state(), -2)) { sol::object key(base_t::lua_state(), -2); sol::object value(base_t::lua_state(), -1); + auto pn = stack::pop_n(base_t::lua_state(), 1); fx(key, value); - lua_pop(base_t::lua_state(), 1); } } @@ -9641,8 +9724,8 @@ namespace sol { template basic_table_core& traverse_set(Keys&&... keys) { auto pp = stack::push_pop::value>(*this); + auto pn = stack::pop_n(base_t::lua_state(), static_cast(sizeof...(Keys)-2)); traverse_set_deep(std::forward(keys)...); - lua_pop(base_t::lua_state(), static_cast(sizeof...(Keys)-2)); return *this; }