From 427194bc92fc3a3ec87e33fd58dee6451c989cf7 Mon Sep 17 00:00:00 2001 From: ThePhD Date: Wed, 10 Feb 2016 12:12:09 -0500 Subject: [PATCH] Improved functions example and adjusted all errors for g++ conformance with -Wall -Werror --- examples/functions.cpp | 99 ++++++++++++++++++++------------- sol/function.hpp | 9 ++- sol/function_result.hpp | 5 -- sol/function_types_core.hpp | 2 +- sol/function_types_overload.hpp | 6 +- sol/function_types_static.hpp | 2 +- sol/reference.hpp | 2 +- sol/usertype.hpp | 3 +- tests.cpp | 10 ++-- 9 files changed, 77 insertions(+), 61 deletions(-) diff --git a/examples/functions.cpp b/examples/functions.cpp index ee85ebf3..0b3c0843 100644 --- a/examples/functions.cpp +++ b/examples/functions.cpp @@ -15,55 +15,76 @@ struct multiplier { } }; +inline std::string make_string( std::string input ) { + return "string: " + input; +} + int main() { - sol::state lua; - lua.open_libraries(sol::lib::base); + sol::state lua; + lua.open_libraries(sol::lib::base); - // setting a function is simple - lua.set_function("my_add", my_add); + // setting a function is simple + lua.set_function("my_add", my_add); - // you could even use a lambda - lua.set_function("my_mul", [](double x, double y) { return x * y; }); + // you could even use a lambda + lua.set_function("my_mul", [](double x, double y) { return x * y; }); - // member function pointers and functors as well - lua.set_function("mult_by_ten", multiplier{}); - lua.set_function("mult_by_five", &multiplier::by_five); + // member function pointers and functors as well + lua.set_function("mult_by_ten", multiplier{}); + lua.set_function("mult_by_five", &multiplier::by_five); - // assert that the functions work - lua.script("assert(my_add(10, 11) == 21)"); - lua.script("assert(my_mul(4.5, 10) == 45)"); - lua.script("assert(mult_by_ten(50) == 500)"); - lua.script("assert(mult_by_five(10) == 50)"); + // assert that the functions work + lua.script("assert(my_add(10, 11) == 21)"); + lua.script("assert(my_mul(4.5, 10) == 45)"); + lua.script("assert(mult_by_ten(50) == 500)"); + lua.script("assert(mult_by_five(10) == 50)"); - // using lambdas, functions could have state. - int x = 0; - lua.set_function("inc", [&x]() { x += 10; }); + // using lambdas, functions could have state. + int x = 0; + lua.set_function("inc", [&x]() { x += 10; }); - // calling a stateful lambda modifies the value - lua.script("inc()"); - assert(x == 10); + // calling a stateful lambda modifies the value + lua.script("inc()"); + assert(x == 10); - // this can be done as many times as you want - lua.script("inc()\ninc()\ninc()"); - assert(x == 40); + // this can be done as many times as you want + lua.script("inc()\ninc()\ninc()"); + assert(x == 40); - // retrieval of a function is done similarly - // to other variables, using sol::function - sol::function add = lua["my_add"]; - assert(add.call(10, 11) == 21); + // retrieval of a function is done similarly + // to other variables, using sol::function + sol::function add = lua["my_add"]; + int value = add(10, 11); + assert(add.call(10, 11) == 21); + assert(value == 21); - // multi-return functions are supported using - // std::tuple as the interface. - lua.set_function("multi", []{ return std::make_tuple(10, "goodbye"); }); - lua.script("x, y = multi()"); - lua.script("assert(x == 10 and y == 'goodbye')"); + // multi-return functions are supported using + // std::tuple as the interface. + lua.set_function("multi", [] { return std::make_tuple(10, "goodbye"); }); + lua.script("x, y = multi()"); + lua.script("assert(x == 10 and y == 'goodbye')"); - auto multi = lua.get("multi"); - int first; - std::string second; - std::tie(first, second) = multi.call(); + auto multi = lua.get("multi"); + int first; + std::string second; + std::tie(first, second) = multi.call(); - // assert the values - assert(first == 10); - assert(second == "goodbye"); + // use the values + assert(first == 10); + assert(second == "goodbye"); + + // you can even overload functions + // just pass in the different functions + // you want to pack into a single name: + // make SURE they take different number of + // arguments/different types! + + lua.set_function("func", sol::overload([](int x) { return x; }, make_string, my_add)); + + // All these functions are now overloaded through "func" + lua.script(R"( +print(func(1)) +print(func("bark")) +print(func(1,2)) +)"); } \ No newline at end of file diff --git a/sol/function.hpp b/sol/function.hpp index 1fa1f765..89f86f5b 100644 --- a/sol/function.hpp +++ b/sol/function.hpp @@ -386,14 +386,13 @@ struct pusher> { template struct getter> { typedef function_traits fx_t; - typedef typename fx_t::args_type args_t; - typedef typename tuple_types_t ret_t; + typedef typename fx_t::args_type args_type; + typedef tuple_types_t return_type; template static std::function get_std_func(types, types, lua_State* L, int index = -1) { - typedef typename function_traits::return_type return_t; sol::function f(L, index); - auto fx = [f, L, index](FxArgs&&... args) -> return_t { + auto fx = [f, L, index](FxArgs&&... args) -> return_type_t { return f(types(), std::forward(args)...); }; return std::move(fx); @@ -414,7 +413,7 @@ struct getter> { } static std::function get(lua_State* L, int index) { - return get_std_func(args_t(), ret_t(), L, index); + return get_std_func(args_type(), return_type(), L, index); } }; } // stack diff --git a/sol/function_result.hpp b/sol/function_result.hpp index 43f15870..c6742a60 100644 --- a/sol/function_result.hpp +++ b/sol/function_result.hpp @@ -89,11 +89,6 @@ public: return get(tr, tr); } - template - decltype(auto) operator[](K&& key) const { - return get()[std::forward(key)]; - } - ~function_result() { stack::remove(L, index, popcount); } diff --git a/sol/function_types_core.hpp b/sol/function_types_core.hpp index 463d3379..a81eb83f 100644 --- a/sol/function_types_core.hpp +++ b/sol/function_types_core.hpp @@ -49,7 +49,7 @@ function_packer function_pack( Args&&... args ) { return function_packer(std::forward(args)...); } -inline bool check_types(types<>, indices<>, lua_State* L, int) { +inline bool check_types(types<>, indices<>, lua_State*, int) { return true; } diff --git a/sol/function_types_overload.hpp b/sol/function_types_overload.hpp index 1a07cb1b..7b429178 100644 --- a/sol/function_types_overload.hpp +++ b/sol/function_types_overload.hpp @@ -37,7 +37,7 @@ struct overloaded_function : base_function { } - int match_arity(lua_State* L, std::ptrdiff_t x, indices<>) { + int match_arity(lua_State*, std::ptrdiff_t, indices<>) { throw error("no matching function call takes this number of arguments"); } @@ -99,7 +99,7 @@ struct usertype_overloaded_function : base_function { } - int match_arity(lua_State* L, std::ptrdiff_t x, indices<>) { + int match_arity(lua_State*, std::ptrdiff_t, indices<>) { throw error("no matching function call takes this number of arguments"); } @@ -154,7 +154,7 @@ struct usertype_indexing_function, T> : base_function usertype_indexing_function(std::string name, Functions... fxs) : overloads({function_traits::arity, fxs}...), name(std::move(name)) {} - int match_arity(lua_State* L, std::ptrdiff_t x, indices<>) { + int match_arity(lua_State*, std::ptrdiff_t, indices<>) { throw error("no matching function call takes this number of arguments"); } diff --git a/sol/function_types_static.hpp b/sol/function_types_static.hpp index 21a12465..c467cf6e 100644 --- a/sol/function_types_static.hpp +++ b/sol/function_types_static.hpp @@ -75,7 +75,7 @@ struct static_member_function { template static int typed_call(types tr, types ta, T& item, function_type& ifx, lua_State* L) { - auto fx = [&item, &ifx](Args&&... args) -> return_type { return (item.*ifx)(std::forward(args)...); }; + auto fx = [&item, &ifx](Args&&... args) -> return_type_t { return (item.*ifx)(std::forward(args)...); }; decltype(auto) r = stack::call(L, 0, tr, ta, fx); int nargs = static_cast(sizeof...(Args)); lua_pop(L, nargs); diff --git a/sol/reference.hpp b/sol/reference.hpp index e9e77ea8..ad6011c7 100644 --- a/sol/reference.hpp +++ b/sol/reference.hpp @@ -40,7 +40,7 @@ struct push_pop { template push_pop push_popper(T&& x) { return push_pop(std::forward(x)); -}; +} } // stack class reference { diff --git a/sol/usertype.hpp b/sol/usertype.hpp index 712af3fc..46f80a10 100644 --- a/sol/usertype.hpp +++ b/sol/usertype.hpp @@ -252,7 +252,8 @@ private: template std::unique_ptr make_function(const std::string&, Fx&& func) { typedef Unqualified Fxu; - typedef Unqualified::arg<0>>> Argu; + typedef std::tuple_element_t<0, typename function_traits::args_tuple_type> Arg0; + typedef Unqualified> Argu; static_assert(std::is_base_of::value, "Any non-member-function must have a first argument which is covariant with the desired usertype."); typedef std::decay_t function_type; return std::make_unique>(func); diff --git a/tests.cpp b/tests.cpp index e28db93b..80eb9620 100644 --- a/tests.cpp +++ b/tests.cpp @@ -85,7 +85,7 @@ struct self_test { } }; -int func_1(int a) { +int func_1(int) { return 1; } @@ -93,11 +93,11 @@ std::string func_1s(std::string a) { return "string: " + a; } -int func_2(int a, int b) { +int func_2(int, int) { return 2; } -void func_3(int a, int b, int c) { +void func_3(int, int, int) { } @@ -1006,7 +1006,7 @@ TEST_CASE("references/get-set", "properly get and set with std::ref semantics. N REQUIRE(var.boop != my_var.boop); REQUIRE(std::addressof(ref_var) == std::addressof(rvar)); - //REQUIRE(std::addressof(proxy_ref_var.get()) == std::addressof(rvar)); + REQUIRE(std::addressof(proxy_ref_var.get()) == std::addressof(rvar)); REQUIRE(rvar.boop == 5); REQUIRE(rvar.boop == ref_var.boop); } @@ -1042,7 +1042,7 @@ TEST_CASE( "functions/function_result-protected_function", "Function result shou // Does not bypass error function, will call it luaL_error( lua.lua_state(), "BIG ERROR MESSAGES!" ); }; - auto specialhandler = []( std::string message ) { + auto specialhandler = []( std::string ) { return errormessage2; };