diff --git a/sol/function.hpp b/sol/function.hpp index 6a68d728..33d5971b 100644 --- a/sol/function.hpp +++ b/sol/function.hpp @@ -65,9 +65,14 @@ public: void operator()(Args&&... args) { call<>(std::forward(args)...); } + + template + typename multi_return::type operator()(types, Args&&... args) { + return call(std::forward(args)...); + } template - auto call(Args&&... args) -> decltype(invoke(types(), sizeof...(Args))) { + typename multi_return::type call(Args&&... args) { push(); stack::push_args(state(), std::forward(args)...); return invoke(types(), sizeof...(Args)); diff --git a/sol/stack.hpp b/sol/stack.hpp index 5bc59091..617bc605 100644 --- a/sol/stack.hpp +++ b/sol/stack.hpp @@ -45,7 +45,7 @@ inline T get_unsigned(lua_State* L, std::false_type, int index = -1) { template inline T get_arithmetic(lua_State* L, std::false_type, int index = -1) { // T is a floating point - return lua_tonumber(L, index); + return static_cast(lua_tonumber(L, index)); } template diff --git a/sol/table.hpp b/sol/table.hpp index dcc5a10b..dc117917 100644 --- a/sol/table.hpp +++ b/sol/table.hpp @@ -118,6 +118,21 @@ private: operator U() const { return t.get(key); } + + template + void operator()( Args&&... args ) { + call<>( std::forward( args )... ); + } + + template + typename multi_return::type operator()(types, Args&&... args) { + return call(std::forward(args)...); + } + + template + typename multi_return::type call(Args&&... args) { + return t.get(key)(types(), std::forward(args)...); + } }; template diff --git a/sol/traits.hpp b/sol/traits.hpp index 26d71634..b782973e 100644 --- a/sol/traits.hpp +++ b/sol/traits.hpp @@ -22,6 +22,7 @@ #ifndef SOL_TRAITS_HPP #define SOL_TRAITS_HPP +#include "tuple.hpp" #include namespace sol { @@ -62,6 +63,21 @@ struct is_function_impl { }; } // detail +template +struct multi_return { + typedef std::tuple type; +}; + +template +struct multi_return { + typedef T type; +}; + +template <> +struct multi_return<> : types<>{ + typedef void type; +}; + template using Bool = std::integral_constant; diff --git a/sol/types.hpp b/sol/types.hpp index 44976ae6..c1cf4b4e 100644 --- a/sol/types.hpp +++ b/sol/types.hpp @@ -113,6 +113,8 @@ template<> inline type type_of() { return type::boolean; } + +inline bool operator==(nil_t, nil_t) { return true; } } // sol #endif // SOL_TYPES_HPP \ No newline at end of file diff --git a/tests.cpp b/tests.cpp index 4f23f6e4..1c400c15 100644 --- a/tests.cpp +++ b/tests.cpp @@ -112,18 +112,40 @@ TEST_CASE("simple/callLambda", "A C++ lambda is exposed to lua and called") { } TEST_CASE("advanced/callLambdaReturns", "Checks for lambdas returning values") { + const static std::string lol = "lol", str = "str"; + const static std::tuple heh_tuple = std::make_tuple(1, 6.28f, 3.14, std::string("heh")); sol::state lua; REQUIRE_NOTHROW(lua.set_function("a", [ ] { return 42; })); + REQUIRE(lua["a"]( sol::types() ) == 42); + REQUIRE_NOTHROW(lua.set_function("b", [ ] { return 42u; })); + REQUIRE(lua["b"](sol::types()) == 42u); + REQUIRE_NOTHROW(lua.set_function("c", [ ] { return 3.14; })); + REQUIRE(lua["c"](sol::types()) == 3.14); + REQUIRE_NOTHROW(lua.set_function("d", [ ] { return 6.28f; })); + REQUIRE(lua["d"](sol::types()) == 6.28f); + REQUIRE_NOTHROW(lua.set_function("e", [ ] { return "lol"; })); + REQUIRE(lua["e"](sol::types()) == lol); + REQUIRE_NOTHROW(lua.set_function("f", [ ] { return true; })); + REQUIRE(lua["f"](sol::types())); + REQUIRE_NOTHROW(lua.set_function("g", [ ] { return std::string("str"); })); + REQUIRE(lua["g"](sol::types()) == str); + REQUIRE_NOTHROW(lua.set_function("h", [ ] { })); + REQUIRE_NOTHROW(lua["h"](sol::types<>())); + REQUIRE_THROWS(lua["h"](sol::types())); + REQUIRE_NOTHROW(lua.set_function("i", [ ] { return sol::nil; })); + REQUIRE(lua["i"](sol::types()) == sol::nil); + REQUIRE_NOTHROW(lua.set_function("j", [ ] { return std::make_tuple(1, 6.28f, 3.14, std::string( "heh" )); } )); + //REQUIRE(lua["j"](sol::types()) == heh_tuple); } TEST_CASE("advanced/callLambda2", "A C++ lambda is exposed to lua and called") {