From 8ef3ceb8a00c3c7d538414948867a362e4204dec Mon Sep 17 00:00:00 2001 From: ThePhD Date: Sun, 15 Dec 2013 16:27:20 -0500 Subject: [PATCH] New test cases for the order of returns. Apparently, its screwing up between both lua and C++. Have to test thoroughly. Changes currently are half-working. --- sol/function.hpp | 2 +- sol/lua_function.hpp | 69 +++++++++++++++++++++++++++++--------------- sol/stack.hpp | 35 +++++++++++++++++++++- sol/tuple.hpp | 11 ++++++- tests.cpp | 15 ++++++++++ 5 files changed, 105 insertions(+), 27 deletions(-) diff --git a/sol/function.hpp b/sol/function.hpp index 1f60a257..aac52037 100644 --- a/sol/function.hpp +++ b/sol/function.hpp @@ -36,7 +36,7 @@ private: template std::tuple invoke(types, std::size_t n) { luacall(n, sizeof...(Ret)); - return stack::pop_call(state(), std::make_tuple, types()); + return stack::pop_reverse_call(state(), std::make_tuple, types()); } template diff --git a/sol/lua_function.hpp b/sol/lua_function.hpp index 89c56614..0d278f7b 100644 --- a/sol/lua_function.hpp +++ b/sol/lua_function.hpp @@ -62,6 +62,11 @@ template struct static_lua_func { typedef typename std::remove_pointer::type>::type fx_t; typedef function_traits fx_traits; + + template + static int typed_call(types<>, types t, fx_t* fx, lua_State* L) { + return (*this)(types(), t, fx, L); + } template static int typed_call(types, types t, fx_t* fx, lua_State* L) { @@ -69,11 +74,11 @@ struct static_lua_func { return 0; } - template - static int typed_call(types, types t, fx_t* fx, lua_State* L) { + template + static int typed_call(types, types t, fx_t* fx, lua_State* L) { auto r = stack::pop_call(L, fx, t); - stack::push(L, std::move(r)); - return sizeof...(TRn); + stack::push_reverse(L, std::move(r)); + return sizeof...(Ret); } static int call(lua_State* L) { @@ -101,9 +106,9 @@ struct static_object_lua_func { return 0; } - template - static int typed_call(types, types, T& item, fx_t& ifx, lua_State* L) { - auto fx = [&item, &ifx](Args&&... args) -> TR { + template + static int typed_call(types, types, T& item, fx_t& ifx, lua_State* L) { + auto fx = [&item, &ifx](Args&&... args) -> Ret { return (item.*ifx)(std::forward(args)...); }; auto r = stack::pop_call(L, fx, types()); @@ -111,12 +116,12 @@ struct static_object_lua_func { return 1; } - template - static int typed_call(types, types, T& item, fx_t& ifx, lua_State* L) { - auto fx = [&item, &ifx](Args&&... args) -> std::tuple { return (item.*ifx)(std::forward(args)...); }; + template + static int typed_call(types, types, T& item, fx_t& ifx, lua_State* L) { + auto fx = [&item, &ifx](Args&&... args) -> std::tuple { return (item.*ifx)(std::forward(args)...); }; auto r = stack::pop_call(L, fx, types()); - stack::push(L, std::move(r)); - return sizeof...(TRn); + stack::push_reverse(L, std::move(r)); + return sizeof...(Ret); } static int call(lua_State* L) { @@ -182,17 +187,23 @@ struct lambda_lua_func : public lua_func { return (*this)(tuple_types(), typename fx_traits::args_type(), L); } + template + int operator()(types<>, types t, lua_State* L) { + stack::pop_call(L, fx, t); + return 0; + } + template int operator()(types, types t, lua_State* L) { stack::pop_call(L, fx, t); return 0; } - template - int operator()(types, types t, lua_State* L) { + template + int operator()(types, types t, lua_State* L) { auto r = stack::pop_call(L, fx, t); - stack::push(L, r); - return sizeof...(TRn); + stack::push_reverse(L, r); + return sizeof...(Ret); } }; @@ -209,17 +220,22 @@ struct explicit_lua_func : public lua_func { return (*this)(tuple_types(), typename fx_traits::args_type(), L); } + template + int operator()(types<>, types t, lua_State* L) { + return (*this)(types(), t, L); + } + template int operator()(types, types t, lua_State* L) { stack::pop_call(L, fx, t); return 0; } - template - int operator()(types, types t, lua_State* L) { + template + int operator()(types, types t, lua_State* L) { auto r = stack::pop_call(L, fx, t); - stack::push(L, std::move(r)); - return sizeof...(TRn); + stack::push_reverse(L, std::move(r)); + return sizeof...(Ret); } }; @@ -247,17 +263,22 @@ struct explicit_lua_func : public lua_func { return (*this)(tuple_types(), typename fx_traits::args_type(), L); } + template + int operator()(types<>, types t, lua_State* L) { + return (*this)(types(), t, L); + } + template int operator()(types, types t, lua_State* L) { stack::pop_call(L, fx, t); return 0; } - template - int operator()(types, types t, lua_State* L) { + template + int operator()(types, types t, lua_State* L) { auto r = stack::pop_call(L, fx, t); - stack::push(L, r); - return sizeof...(TRn); + stack::push_reverse(L, r); + return sizeof...(Ret); } }; diff --git a/sol/stack.hpp b/sol/stack.hpp index 782bd98d..a0c5c230 100644 --- a/sol/stack.hpp +++ b/sol/stack.hpp @@ -224,15 +224,43 @@ template auto ltr_pop(lua_State* L, F&& f, types, Vs&&... vs) -> decltype(f(std::forward(vs)..., std::declval(), std::declval()...)) { return ltr_pop(L, std::forward(f), types(), std::forward(vs)..., pop(L)); } + +template +auto rtl_pop(lua_State*, F&& f, types<>, Vs&&... vs) -> decltype(f(std::forward(vs)...)) { + return f(std::forward(vs)...); +} +template +auto rtl_pop(lua_State* L, F&& f, types, Vs&&... vs) -> decltype(rtl_pop(L, std::forward(f), types<>(), pop(L), std::forward(vs)...)) { + return rtl_pop(L, std::forward(f), types<>(), pop(L), std::forward(vs)...); +} +template +auto rtl_pop(lua_State* L, F&& f, types, Vs&&... vs) -> decltype(rtl_pop(L, std::forward(f), types(), pop(L), std::forward(vs)...)) { + return rtl_pop(L, std::forward(f), types(), pop(L), std::forward(vs)...); +} } // detail template inline void push(lua_State* L, const std::tuple& tuplen) { - detail::push_tuple(L, build_reverse_indices(), tuplen); + detail::push_tuple(L, build_indices(), tuplen); } template inline void push(lua_State* L, std::tuple&& tuplen) { + detail::push_tuple(L, build_indices(), std::move(tuplen)); +} + +template +inline void push_reverse(lua_State* L, T&& item) { + push(L, std::forward(item)); +} + +template +inline void push_reverse(lua_State* L, const std::tuple& tuplen) { + detail::push_tuple(L, build_reverse_indices(), tuplen); +} + +template +inline void push_reverse(lua_State* L, std::tuple&& tuplen) { detail::push_tuple(L, build_reverse_indices(), std::move(tuplen)); } @@ -241,6 +269,11 @@ inline auto pop_call(lua_State* L, TFx&& fx, types) -> decltype(detail: return detail::ltr_pop(L, std::forward(fx), types()); } +template +inline auto pop_reverse_call(lua_State* L, TFx&& fx, types) -> decltype(detail::rtl_pop(L, std::forward(fx), types())) { + return detail::rtl_pop(L, std::forward(fx), reversed()); +} + void push_args(lua_State*) { } diff --git a/sol/tuple.hpp b/sol/tuple.hpp index 31285b04..cecaa3e8 100644 --- a/sol/tuple.hpp +++ b/sol/tuple.hpp @@ -57,7 +57,16 @@ template struct build_reverse_indices<0, Ns...> : indices {}; template -struct types : build_indices {}; +struct types : build_indices { typedef types type; }; + +template +struct reversed_ : Acc{}; + +template +struct reversed_, Arg, Args...> : reversed_, Args...>{}; + +template +struct reversed : reversed_, Args...>{}; template struct tuple_types : types, std::false_type {}; diff --git a/tests.cpp b/tests.cpp index 5b020278..d9749f9b 100644 --- a/tests.cpp +++ b/tests.cpp @@ -220,6 +220,21 @@ TEST_CASE("tables/functions_variables", "Check if tables and function calls work REQUIRE_NOTHROW(run_script(lua)); } +TEST_CASE("functions/return _order", "Check if return order is in the same reading order specified in Lua" ) { + const static std::tuple triple = std::make_tuple(10, 11, 12); + sol::state lua; + lua.set_function( "f", [ ] { + return std::make_tuple( 10, 11, 12 ); + } ); + lua.script( "function g() return 10, 11, 12 end" ); + auto tcpp = lua.get( "f" ).call( ); + auto tlua = lua.get( "g" ).call( ); + std::cout << std::get<0>( tcpp ) << ',' << std::get<1>( tcpp ) << ',' << std::get<2>( tcpp ) << std::endl; + std::cout << std::get<0>( tlua ) << ',' << std::get<1>( tlua ) << ',' << std::get<2>( tlua ) << std::endl; + REQUIRE( tcpp == triple ); + REQUIRE( tlua == triple ); +} + TEST_CASE("tables/operator[]", "Check if operator[] retrieval and setting works properly") { sol::state lua; lua.open_libraries(sol::lib::base);