diff --git a/sol/container.hpp b/sol/container.hpp index a11703ea..576f5946 100644 --- a/sol/container.hpp +++ b/sol/container.hpp @@ -37,8 +37,8 @@ struct container { namespace stack { template struct pusher::value>::type> { - template - static void push(lua_State *L, U&& t){ + template>> = 0> + static void push(lua_State* L, const T& cont) { typedef container container_t; // todo: NEED to find a different way of handling this... static std::vector> classes{}; @@ -53,27 +53,13 @@ struct pusher::value>::type> { container_t* c = static_cast(lua_newuserdata(L, sizeof(container_t))); std::allocator alloc{}; - alloc.construct(c, std::forward(t)); + alloc.construct(c, cont); auto&& meta = userdata_traits::metatable; luaL_getmetatable(L, std::addressof(meta[0])); lua_setmetatable(L, -2); } - template>> = 0> - static void push(lua_State* L, const T& cont) { - lua_createtable(L, cont.size(), 0); - unsigned index = 1; - for(auto&& i : cont) { - // push the index - pusher::push(L, index++); - // push the value - pusher>::push(L, i); - // set the table - lua_settable(L, -3); - } - } - template> = 0> static void push(lua_State* L, const T& cont) { lua_createtable(L, cont.size(), 0); diff --git a/sol/function_types.hpp b/sol/function_types.hpp index 355c2c53..195c06f1 100644 --- a/sol/function_types.hpp +++ b/sol/function_types.hpp @@ -180,7 +180,7 @@ struct base_function { struct userdata { static int call(lua_State* L) { // Zero-based template parameter, but upvalues start at 1 - return base_call(L, stack::get(L, i + 1)); + return base_call(L, stack::get(L, i + 1)); } }; diff --git a/sol/stack.hpp b/sol/stack.hpp index 33aa0a85..dbb8a251 100644 --- a/sol/stack.hpp +++ b/sol/stack.hpp @@ -286,7 +286,7 @@ template inline void push(lua_State* L, T&& t, Args&&... args) { using swallow = char[]; pusher>{}.push(L, std::forward(t)); - void(swallow{'\0', (pusher>{}.push(L, std::forward(args)), '\0')... }); + void(swallow{'\0', (pusher>{}.push(L, std::forward(args)), '\0')... }); } template> diff --git a/tests.cpp b/tests.cpp index 991342a3..b073a4dc 100644 --- a/tests.cpp +++ b/tests.cpp @@ -14,6 +14,18 @@ void test_free_func2(std::function f, int arg1) { throw sol::error("failed function call!"); } +std::function makefn () { + auto fx = []() -> int { + return 0x1456789; + }; + return fx; +} + +void takefn ( std::function purr ) { + if (purr() != 0x1456789) + throw 0; +} + std::string free_function() { std::cout << "free_function()" << std::endl; return "test"; @@ -320,7 +332,7 @@ TEST_CASE("tables/functions_variables", "Check if tables and function calls work std::cout << "stateless lambda()" << std::endl; return "test"; } -); + ); REQUIRE_NOTHROW(run_script(lua)); lua.get("os").set_function("fun", &free_function); @@ -388,6 +400,17 @@ TEST_CASE("functions/sol::function to std::function", "check if conversion to st ); } +TEST_CASE("functions/returning functions from C++ and getting in lua", "check to see if returning a functor and getting a functor from lua is possible") { + sol::state lua; + lua.open_libraries(sol::lib::base); + + lua.set_function( "makefn", makefn ); + lua.set_function( "takefn", takefn ); + lua.script( "afx = makefn()\n" + "print(afx())\n" + "takefn(afx)\n" ); +} + TEST_CASE("tables/operator[]", "Check if operator[] retrieval and setting works properly") { sol::state lua; lua.open_libraries(sol::lib::base); @@ -558,7 +581,6 @@ TEST_CASE("tables/userdata utility derived", "userdata classes must play nice wh REQUIRE((lua.get("dgn") == 7)); } - TEST_CASE("tables/self-referential userdata", "userdata classes must play nice when C++ object types are requested for C++ code") { sol::state lua; lua.open_libraries(sol::lib::base);