diff --git a/sol/function.hpp b/sol/function.hpp index 264fc0e9..6a68d728 100644 --- a/sol/function.hpp +++ b/sol/function.hpp @@ -61,6 +61,11 @@ public: function(const function&) = default; function& operator=(const function&) = default; + template + void operator()(Args&&... args) { + call<>(std::forward(args)...); + } + template auto call(Args&&... args) -> decltype(invoke(types(), sizeof...(Args))) { push(); diff --git a/sol/stack.hpp b/sol/stack.hpp index 43212f9b..5bc59091 100644 --- a/sol/stack.hpp +++ b/sol/stack.hpp @@ -208,8 +208,8 @@ inline int push_user(lua_State* L, T& item) { namespace detail { template inline void push(lua_State* L, indices, const T& tuplen) { - using swallow = char[]; - void(swallow{'\0', (sol::stack::push(L, std::get(tuplen)), '\0')... }); + using swallow = char[ 1 + sizeof...(I) ]; + swallow {'\0', (sol::stack::push(L, std::get(tuplen)), '\0')... }; } template diff --git a/sol/table.hpp b/sol/table.hpp index 4a444e52..dcc5a10b 100644 --- a/sol/table.hpp +++ b/sol/table.hpp @@ -41,7 +41,7 @@ T* get_ptr(T* val) { } // detail class table : virtual public reference { - template struct proxy; + template struct proxy; public: table() noexcept : reference() {} table(lua_State* L, int index = -1) : reference(L, index) { @@ -82,13 +82,13 @@ public: } template - auto operator[](T&& key) -> decltype(proxy(*this, std::forward(key))) { - return proxy(*this, std::forward(key)); + proxy operator[](T&& key) { + return proxy(*this, std::forward(key)); } template - auto operator[](T&& key) const -> decltype(proxy(*this, std::forward(key))) { - return proxy(*this, std::forward(key)); + proxy operator[](T&& key) const { + return proxy(*this, std::forward(key)); } size_t size() const { diff --git a/sol/traits.hpp b/sol/traits.hpp index 9b998305..26d71634 100644 --- a/sol/traits.hpp +++ b/sol/traits.hpp @@ -72,56 +72,56 @@ template struct function_traits; template -struct function_traits { - static const std::size_t arity = sizeof...( Args ); +struct function_traits { + static const std::size_t arity = sizeof...(Args); static const bool is_member_function = true; typedef std::tuple arg_tuple_type; typedef types args_type; - typedef R( T::* function_pointer_type )( Args... ); + typedef R(T::* function_pointer_type)(Args...); typedef typename std::remove_pointer::type function_type; - typedef R( *free_function_pointer_type )( Args... ); + typedef R(*free_function_pointer_type)(Args...); typedef R return_type; template using arg = typename std::tuple_element::type; }; template -struct function_traits { - static const std::size_t arity = sizeof...( Args ); +struct function_traits { + static const std::size_t arity = sizeof...(Args); static const bool is_member_function = true; typedef std::tuple arg_tuple_type; typedef types args_type; - typedef R( T::* function_pointer_type )( Args... ); + typedef R(T::* function_pointer_type)(Args...); typedef typename std::remove_pointer::type function_type; - typedef R( *free_function_pointer_type )( Args... ); + typedef R(*free_function_pointer_type)(Args...); typedef R return_type; template using arg = typename std::tuple_element::type; }; template -struct function_traits { - static const std::size_t arity = sizeof...( Args ); +struct function_traits { + static const std::size_t arity = sizeof...(Args); static const bool is_member_function = false; typedef std::tuple arg_tuple_type; typedef types args_type; - typedef R( function_type )( Args... ); - typedef R( *function_pointer_type )( Args... ); - typedef R( *free_function_pointer_type )( Args... ); + typedef R(function_type)(Args...); + typedef R(*function_pointer_type)(Args...); + typedef R(*free_function_pointer_type)(Args...); typedef R return_type; template using arg = typename std::tuple_element::type; }; template -struct function_traits { - static const std::size_t arity = sizeof...( Args ); +struct function_traits { + static const std::size_t arity = sizeof...(Args); static const bool is_member_function = false; typedef std::tuple arg_tuple_type; typedef types args_type; - typedef R( function_type )( Args... ); - typedef R( *function_pointer_type )( Args... ); - typedef R( *free_function_pointer_type )( Args... ); + typedef R(function_type)(Args...); + typedef R(*function_pointer_type)(Args...); + typedef R(*free_function_pointer_type)(Args...); typedef R return_type; template using arg = typename std::tuple_element::type; diff --git a/tests.cpp b/tests.cpp index a24e92a4..4f23f6e4 100644 --- a/tests.cpp +++ b/tests.cpp @@ -81,7 +81,10 @@ TEST_CASE("simple/callWithParameters", "Lua function is called with a few parame REQUIRE_NOTHROW(lua.script("function my_add(i, j, k) return i + j + k end")); auto f = lua.get("my_add"); + REQUIRE_NOTHROW(lua.script("function my_nothing(i, j, k) end")); + auto fvoid = lua.get("my_nothing"); int a; + REQUIRE_NOTHROW(fvoid(1, 2, 3)); REQUIRE_NOTHROW(a = f.call(1, 2, 3)); REQUIRE(a == 6); REQUIRE_THROWS(a = f.call(1, 2, "arf")); @@ -111,15 +114,16 @@ TEST_CASE("simple/callLambda", "A C++ lambda is exposed to lua and called") { TEST_CASE("advanced/callLambdaReturns", "Checks for lambdas returning values") { sol::state lua; - lua.set_function("a", [ ] { return 42; }); - lua.set_function("b", [ ] { return 42u; }); - lua.set_function("c", [ ] { return 3.14; }); - lua.set_function("d", [ ] { return 6.28f; }); - lua.set_function("e", [ ] { return "lol"; }); - lua.set_function("f", [ ] { return true; }); - lua.set_function("g", [ ] { return std::string("str"); }); - lua.set_function("h", [ ] { }); - lua.set_function("i", [ ] { return sol::nil; }); + REQUIRE_NOTHROW(lua.set_function("a", [ ] { return 42; })); + REQUIRE_NOTHROW(lua.set_function("b", [ ] { return 42u; })); + REQUIRE_NOTHROW(lua.set_function("c", [ ] { return 3.14; })); + REQUIRE_NOTHROW(lua.set_function("d", [ ] { return 6.28f; })); + REQUIRE_NOTHROW(lua.set_function("e", [ ] { return "lol"; })); + REQUIRE_NOTHROW(lua.set_function("f", [ ] { return true; })); + REQUIRE_NOTHROW(lua.set_function("g", [ ] { return std::string("str"); })); + REQUIRE_NOTHROW(lua.set_function("h", [ ] { })); + REQUIRE_NOTHROW(lua.set_function("i", [ ] { return sol::nil; })); + REQUIRE_NOTHROW(lua.set_function("j", [ ] { return std::make_tuple(1, 6.28f, 3.14, std::string( "heh" )); } )); } TEST_CASE("advanced/callLambda2", "A C++ lambda is exposed to lua and called") { @@ -165,7 +169,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); @@ -183,7 +187,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)); // r-value, cannot optomize