Improved functions example and adjusted all errors for g++ conformance with -Wall -Werror

This commit is contained in:
ThePhD 2016-02-10 12:12:09 -05:00
parent 2788abb34e
commit 427194bc92
9 changed files with 77 additions and 61 deletions

View File

@ -15,6 +15,10 @@ struct multiplier {
} }
}; };
inline std::string make_string( std::string input ) {
return "string: " + input;
}
int main() { int main() {
sol::state lua; sol::state lua;
lua.open_libraries(sol::lib::base); lua.open_libraries(sol::lib::base);
@ -50,7 +54,9 @@ int main() {
// retrieval of a function is done similarly // retrieval of a function is done similarly
// to other variables, using sol::function // to other variables, using sol::function
sol::function add = lua["my_add"]; sol::function add = lua["my_add"];
int value = add(10, 11);
assert(add.call<int>(10, 11) == 21); assert(add.call<int>(10, 11) == 21);
assert(value == 21);
// multi-return functions are supported using // multi-return functions are supported using
// std::tuple as the interface. // std::tuple as the interface.
@ -63,7 +69,22 @@ int main() {
std::string second; std::string second;
std::tie(first, second) = multi.call<int, std::string>(); std::tie(first, second) = multi.call<int, std::string>();
// assert the values // use the values
assert(first == 10); assert(first == 10);
assert(second == "goodbye"); 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))
)");
} }

View File

@ -386,14 +386,13 @@ struct pusher<overload_set<Functions...>> {
template<typename Signature> template<typename Signature>
struct getter<std::function<Signature>> { struct getter<std::function<Signature>> {
typedef function_traits<Signature> fx_t; typedef function_traits<Signature> fx_t;
typedef typename fx_t::args_type args_t; typedef typename fx_t::args_type args_type;
typedef typename tuple_types_t<typename fx_t::return_type> ret_t; typedef tuple_types_t<typename fx_t::return_type> return_type;
template<typename... FxArgs, typename... Ret> template<typename... FxArgs, typename... Ret>
static std::function<Signature> get_std_func(types<FxArgs...>, types<Ret...>, lua_State* L, int index = -1) { static std::function<Signature> get_std_func(types<FxArgs...>, types<Ret...>, lua_State* L, int index = -1) {
typedef typename function_traits<Signature>::return_type return_t;
sol::function f(L, index); sol::function f(L, index);
auto fx = [f, L, index](FxArgs&&... args) -> return_t { auto fx = [f, L, index](FxArgs&&... args) -> return_type_t<Ret...> {
return f(types<Ret...>(), std::forward<FxArgs>(args)...); return f(types<Ret...>(), std::forward<FxArgs>(args)...);
}; };
return std::move(fx); return std::move(fx);
@ -414,7 +413,7 @@ struct getter<std::function<Signature>> {
} }
static std::function<Signature> get(lua_State* L, int index) { static std::function<Signature> 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 } // stack

View File

@ -89,11 +89,6 @@ public:
return get(tr, tr); return get(tr, tr);
} }
template <typename K>
decltype(auto) operator[](K&& key) const {
return get<table>()[std::forward<K>(key)];
}
~function_result() { ~function_result() {
stack::remove(L, index, popcount); stack::remove(L, index, popcount);
} }

View File

@ -49,7 +49,7 @@ function_packer<Sig, Args...> function_pack( Args&&... args ) {
return function_packer<Sig, Args...>(std::forward<Args>(args)...); return function_packer<Sig, Args...>(std::forward<Args>(args)...);
} }
inline bool check_types(types<>, indices<>, lua_State* L, int) { inline bool check_types(types<>, indices<>, lua_State*, int) {
return true; return true;
} }

View File

@ -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"); 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"); throw error("no matching function call takes this number of arguments");
} }
@ -154,7 +154,7 @@ struct usertype_indexing_function<overload_set<Functions...>, T> : base_function
usertype_indexing_function(std::string name, Functions... fxs) usertype_indexing_function(std::string name, Functions... fxs)
: overloads({function_traits<Functions>::arity, fxs}...), name(std::move(name)) {} : overloads({function_traits<Functions>::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"); throw error("no matching function call takes this number of arguments");
} }

View File

@ -75,7 +75,7 @@ struct static_member_function {
template<typename... Ret, typename... Args> template<typename... Ret, typename... Args>
static int typed_call(types<Ret...> tr, types<Args...> ta, T& item, function_type& ifx, lua_State* L) { static int typed_call(types<Ret...> tr, types<Args...> ta, T& item, function_type& ifx, lua_State* L) {
auto fx = [&item, &ifx](Args&&... args) -> return_type { return (item.*ifx)(std::forward<Args>(args)...); }; auto fx = [&item, &ifx](Args&&... args) -> return_type_t<Ret...> { return (item.*ifx)(std::forward<Args>(args)...); };
decltype(auto) r = stack::call(L, 0, tr, ta, fx); decltype(auto) r = stack::call(L, 0, tr, ta, fx);
int nargs = static_cast<int>(sizeof...(Args)); int nargs = static_cast<int>(sizeof...(Args));
lua_pop(L, nargs); lua_pop(L, nargs);

View File

@ -40,7 +40,7 @@ struct push_pop<true, T> {
template <bool top_level = false, typename T> template <bool top_level = false, typename T>
push_pop<top_level, T> push_popper(T&& x) { push_pop<top_level, T> push_popper(T&& x) {
return push_pop<top_level, T>(std::forward<T>(x)); return push_pop<top_level, T>(std::forward<T>(x));
}; }
} // stack } // stack
class reference { class reference {

View File

@ -252,7 +252,8 @@ private:
template<typename Fx> template<typename Fx>
std::unique_ptr<base_function> make_function(const std::string&, Fx&& func) { std::unique_ptr<base_function> make_function(const std::string&, Fx&& func) {
typedef Unqualified<Fx> Fxu; typedef Unqualified<Fx> Fxu;
typedef Unqualified<std::remove_pointer_t<function_traits<Fxu>::arg<0>>> Argu; typedef std::tuple_element_t<0, typename function_traits<Fxu>::args_tuple_type> Arg0;
typedef Unqualified<std::remove_pointer_t<Arg0>> Argu;
static_assert(std::is_base_of<Argu, T>::value, "Any non-member-function must have a first argument which is covariant with the desired usertype."); static_assert(std::is_base_of<Argu, T>::value, "Any non-member-function must have a first argument which is covariant with the desired usertype.");
typedef std::decay_t<Fxu> function_type; typedef std::decay_t<Fxu> function_type;
return std::make_unique<usertype_function<function_type, T>>(func); return std::make_unique<usertype_function<function_type, T>>(func);

View File

@ -85,7 +85,7 @@ struct self_test {
} }
}; };
int func_1(int a) { int func_1(int) {
return 1; return 1;
} }
@ -93,11 +93,11 @@ std::string func_1s(std::string a) {
return "string: " + a; return "string: " + a;
} }
int func_2(int a, int b) { int func_2(int, int) {
return 2; 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(var.boop != my_var.boop);
REQUIRE(std::addressof(ref_var) == std::addressof(rvar)); 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 == 5);
REQUIRE(rvar.boop == ref_var.boop); 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 // Does not bypass error function, will call it
luaL_error( lua.lua_state(), "BIG ERROR MESSAGES!" ); luaL_error( lua.lua_state(), "BIG ERROR MESSAGES!" );
}; };
auto specialhandler = []( std::string message ) { auto specialhandler = []( std::string ) {
return errormessage2; return errormessage2;
}; };