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() {
sol::state lua;
lua.open_libraries(sol::lib::base);
@ -50,11 +54,13 @@ int main() {
// 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<int>(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.set_function("multi", [] { return std::make_tuple(10, "goodbye"); });
lua.script("x, y = multi()");
lua.script("assert(x == 10 and y == 'goodbye')");
@ -63,7 +69,22 @@ int main() {
std::string second;
std::tie(first, second) = multi.call<int, std::string>();
// assert the values
// 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))
)");
}

View File

@ -386,14 +386,13 @@ struct pusher<overload_set<Functions...>> {
template<typename Signature>
struct getter<std::function<Signature>> {
typedef function_traits<Signature> fx_t;
typedef typename fx_t::args_type args_t;
typedef typename tuple_types_t<typename fx_t::return_type> ret_t;
typedef typename fx_t::args_type args_type;
typedef tuple_types_t<typename fx_t::return_type> return_type;
template<typename... FxArgs, typename... Ret>
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);
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 std::move(fx);
@ -414,7 +413,7 @@ struct getter<std::function<Signature>> {
}
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

View File

@ -89,11 +89,6 @@ public:
return get(tr, tr);
}
template <typename K>
decltype(auto) operator[](K&& key) const {
return get<table>()[std::forward<K>(key)];
}
~function_result() {
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)...);
}
inline bool check_types(types<>, indices<>, lua_State* L, int) {
inline bool check_types(types<>, indices<>, lua_State*, int) {
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");
}
@ -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<overload_set<Functions...>, T> : base_function
usertype_indexing_function(std::string name, Functions... fxs)
: 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");
}

View File

@ -75,7 +75,7 @@ struct static_member_function {
template<typename... Ret, typename... Args>
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);
int nargs = static_cast<int>(sizeof...(Args));
lua_pop(L, nargs);

View File

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

View File

@ -252,7 +252,8 @@ private:
template<typename Fx>
std::unique_ptr<base_function> make_function(const std::string&, Fx&& func) {
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.");
typedef std::decay_t<Fxu> function_type;
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;
}
@ -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;
};