mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Merge pull request #9 from ThePhD/master
More VC++ compatibility, some features, and some warning supression for GCC.
This commit is contained in:
commit
0e31358d97
|
@ -67,7 +67,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Ret, typename... Args>
|
template<typename... Ret, typename... Args>
|
||||||
auto call(Args&&... args) -> decltype(invoke(types<Ret...>(), sizeof...(Args))) {
|
typename multi_return<Ret...>::type operator()(types<Ret...>, Args&&... args) {
|
||||||
|
return call<Ret...>(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Ret, typename... Args>
|
||||||
|
typename multi_return<Ret...>::type call(Args&&... args) {
|
||||||
push();
|
push();
|
||||||
stack::push_args(state(), std::forward<Args>(args)...);
|
stack::push_args(state(), std::forward<Args>(args)...);
|
||||||
return invoke(types<Ret...>(), sizeof...(Args));
|
return invoke(types<Ret...>(), sizeof...(Args));
|
||||||
|
|
|
@ -207,7 +207,7 @@ inline int push_user(lua_State* L, T& item) {
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T, std::size_t... I>
|
template<typename T, std::size_t... I>
|
||||||
inline void push(lua_State* L, indices<I...>, const T& tuplen) {
|
inline void push_tuple(lua_State* L, indices<I...>, T&& tuplen) {
|
||||||
using swallow = char[ 1 + sizeof...(I) ];
|
using swallow = char[ 1 + sizeof...(I) ];
|
||||||
swallow {'\0', (sol::stack::push(L, std::get<I>(tuplen)), '\0')... };
|
swallow {'\0', (sol::stack::push(L, std::get<I>(tuplen)), '\0')... };
|
||||||
}
|
}
|
||||||
|
@ -228,7 +228,12 @@ auto ltr_pop(lua_State* L, F&& f, types<Head, Tail...>, Vs&&... vs) -> decltype(
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
inline void push(lua_State* L, const std::tuple<Args...>& tuplen) {
|
inline void push(lua_State* L, const std::tuple<Args...>& tuplen) {
|
||||||
detail::push(L, build_indices<sizeof...(Args)>(), tuplen);
|
detail::push_tuple(L, build_reverse_indices<sizeof...(Args)>(), tuplen);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
inline void push(lua_State* L, std::tuple<Args...>&& tuplen) {
|
||||||
|
detail::push_tuple(L, build_reverse_indices<sizeof...(Args)>(), std::move(tuplen));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args, typename TFx>
|
template<typename... Args, typename TFx>
|
||||||
|
@ -236,9 +241,14 @@ inline auto pop_call(lua_State* L, TFx&& fx, types<Args...>) -> decltype(detail:
|
||||||
return detail::ltr_pop(L, std::forward<TFx>(fx), types<Args...>());
|
return detail::ltr_pop(L, std::forward<TFx>(fx), types<Args...>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
void push_args(lua_State*) {
|
||||||
void push_args(lua_State* L, Args&&... args) {
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Arg, typename... Args>
|
||||||
|
void push_args(lua_State* L, Arg&& arg, Args&&... args) {
|
||||||
using swallow = char[];
|
using swallow = char[];
|
||||||
|
stack::push(L, std::forward<Arg>(arg));
|
||||||
void(swallow{'\0', (stack::push(L, std::forward<Args>(args)), '\0')... });
|
void(swallow{'\0', (stack::push(L, std::forward<Args>(args)), '\0')... });
|
||||||
}
|
}
|
||||||
} // stack
|
} // stack
|
||||||
|
|
|
@ -118,6 +118,11 @@ private:
|
||||||
operator U() const {
|
operator U() const {
|
||||||
return t.get<U>(key);
|
return t.get<U>(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename... Ret, typename... Args>
|
||||||
|
typename multi_return<Ret...>::type call(Args&&... args) {
|
||||||
|
return t.get<function>(key)(types<Ret...>(), std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename TFx>
|
template<typename T, typename TFx>
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#ifndef SOL_TRAITS_HPP
|
#ifndef SOL_TRAITS_HPP
|
||||||
#define SOL_TRAITS_HPP
|
#define SOL_TRAITS_HPP
|
||||||
|
|
||||||
|
#include "tuple.hpp"
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
|
@ -62,6 +63,21 @@ struct is_function_impl<T, true> {
|
||||||
};
|
};
|
||||||
} // detail
|
} // detail
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
struct multi_return {
|
||||||
|
typedef std::tuple<Args...> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct multi_return<T> {
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct multi_return<> : types<>{
|
||||||
|
typedef void type;
|
||||||
|
};
|
||||||
|
|
||||||
template<bool B>
|
template<bool B>
|
||||||
using Bool = std::integral_constant<bool, B>;
|
using Bool = std::integral_constant<bool, B>;
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,23 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
|
template<typename... Ts>
|
||||||
|
struct reverse_tuple;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct reverse_tuple<std::tuple<>> {
|
||||||
|
using type = std::tuple<>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, typename... Ts>
|
||||||
|
struct reverse_tuple<std::tuple<T, Ts...>> {
|
||||||
|
using head = std::tuple<T>;
|
||||||
|
using tail = typename reverse_tuple<std::tuple<Ts...>>::type;
|
||||||
|
using type = decltype(std::tuple_cat(std::declval<tail>(), std::declval<head>()));
|
||||||
|
};
|
||||||
|
|
||||||
template<size_t... Ns>
|
template<size_t... Ns>
|
||||||
struct indices {};
|
struct indices { typedef indices type; };
|
||||||
|
|
||||||
template<size_t N, size_t... Ns>
|
template<size_t N, size_t... Ns>
|
||||||
struct build_indices : build_indices<N - 1, N - 1, Ns...> {};
|
struct build_indices : build_indices<N - 1, N - 1, Ns...> {};
|
||||||
|
@ -35,6 +50,12 @@ struct build_indices : build_indices<N - 1, N - 1, Ns...> {};
|
||||||
template<size_t... Ns>
|
template<size_t... Ns>
|
||||||
struct build_indices<0, Ns...> : indices<Ns...> {};
|
struct build_indices<0, Ns...> : indices<Ns...> {};
|
||||||
|
|
||||||
|
template<size_t N, size_t... Ns>
|
||||||
|
struct build_reverse_indices : build_reverse_indices<N - 1, Ns..., N - 1> {};
|
||||||
|
|
||||||
|
template<size_t... Ns>
|
||||||
|
struct build_reverse_indices<0, Ns...> : indices<Ns...> {};
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
struct types : build_indices<sizeof...(Args)> {};
|
struct types : build_indices<sizeof...(Args)> {};
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,9 @@ template<>
|
||||||
inline type type_of<bool>() {
|
inline type type_of<bool>() {
|
||||||
return type::boolean;
|
return type::boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool operator==(nil_t, nil_t) { return true; }
|
||||||
|
inline bool operator!=(nil_t, nil_t) { return false; }
|
||||||
} // sol
|
} // sol
|
||||||
|
|
||||||
#endif // SOL_TYPES_HPP
|
#endif // SOL_TYPES_HPP
|
24
tests.cpp
24
tests.cpp
|
@ -112,18 +112,38 @@ TEST_CASE("simple/callLambda", "A C++ lambda is exposed to lua and called") {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("advanced/callLambdaReturns", "Checks for lambdas returning values") {
|
TEST_CASE("advanced/callLambdaReturns", "Checks for lambdas returning values") {
|
||||||
|
const static std::string lol = "lol", str = "str";
|
||||||
|
const static std::tuple<int, float, double, std::string> heh_tuple = std::make_tuple(1, 6.28f, 3.14, std::string("heh"));
|
||||||
sol::state lua;
|
sol::state lua;
|
||||||
|
|
||||||
REQUIRE_NOTHROW(lua.set_function("a", [ ] { return 42; }));
|
REQUIRE_NOTHROW(lua.set_function("a", [ ] { return 42; }));
|
||||||
|
REQUIRE(lua["a"].call<int>() == 42);
|
||||||
|
|
||||||
REQUIRE_NOTHROW(lua.set_function("b", [ ] { return 42u; }));
|
REQUIRE_NOTHROW(lua.set_function("b", [ ] { return 42u; }));
|
||||||
|
REQUIRE(lua["b"].call<unsigned int>() == 42u);
|
||||||
|
|
||||||
REQUIRE_NOTHROW(lua.set_function("c", [ ] { return 3.14; }));
|
REQUIRE_NOTHROW(lua.set_function("c", [ ] { return 3.14; }));
|
||||||
|
REQUIRE(lua["c"].call<double>() == 3.14);
|
||||||
|
|
||||||
REQUIRE_NOTHROW(lua.set_function("d", [ ] { return 6.28f; }));
|
REQUIRE_NOTHROW(lua.set_function("d", [ ] { return 6.28f; }));
|
||||||
|
REQUIRE(lua["d"].call<float>() == 6.28f);
|
||||||
|
|
||||||
REQUIRE_NOTHROW(lua.set_function("e", [ ] { return "lol"; }));
|
REQUIRE_NOTHROW(lua.set_function("e", [ ] { return "lol"; }));
|
||||||
|
REQUIRE(lua["e"].call<std::string>() == lol);
|
||||||
|
|
||||||
REQUIRE_NOTHROW(lua.set_function("f", [ ] { return true; }));
|
REQUIRE_NOTHROW(lua.set_function("f", [ ] { return true; }));
|
||||||
|
REQUIRE(lua["f"].call<bool>());
|
||||||
|
|
||||||
REQUIRE_NOTHROW(lua.set_function("g", [ ] { return std::string("str"); }));
|
REQUIRE_NOTHROW(lua.set_function("g", [ ] { return std::string("str"); }));
|
||||||
|
REQUIRE(lua["g"].call<std::string>() == str);
|
||||||
|
|
||||||
REQUIRE_NOTHROW(lua.set_function("h", [ ] { }));
|
REQUIRE_NOTHROW(lua.set_function("h", [ ] { }));
|
||||||
|
REQUIRE_NOTHROW(lua["h"].call());
|
||||||
|
|
||||||
REQUIRE_NOTHROW(lua.set_function("i", [ ] { return sol::nil; }));
|
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" )); } ));
|
REQUIRE(lua["i"].call<sol::nil_t>() == sol::nil);
|
||||||
|
REQUIRE_NOTHROW(lua.set_function("j", [ ] { return std::make_tuple(1, 6.28f, 3.14, std::string("heh")); }));
|
||||||
|
REQUIRE((lua["j"].call<int, float, double, std::string>() == heh_tuple));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("advanced/callLambda2", "A C++ lambda is exposed to lua and called") {
|
TEST_CASE("advanced/callLambda2", "A C++ lambda is exposed to lua and called") {
|
||||||
|
@ -178,7 +198,7 @@ TEST_CASE("tables/functions_variables", "Check if tables and function calls work
|
||||||
// l-value, can optomize
|
// l-value, can optomize
|
||||||
auto lval = object();
|
auto lval = object();
|
||||||
lua.get<sol::table>("os").set_function("fun", &object::operator(), lval);
|
lua.get<sol::table>("os").set_function("fun", &object::operator(), lval);
|
||||||
REQUIRE_NOTHROW((lua));
|
REQUIRE_NOTHROW(run_script(lua));
|
||||||
|
|
||||||
// stateful lambda: non-convertible, unoptomizable
|
// stateful lambda: non-convertible, unoptomizable
|
||||||
int breakit = 50;
|
int breakit = 50;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user