mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
tests for the new decaying functionality
need to test with clang++/g++ to see if it still works
This commit is contained in:
parent
d4fe51725c
commit
dbeb8b5fcb
|
@ -40,12 +40,12 @@ private:
|
||||||
int returncount;
|
int returncount;
|
||||||
|
|
||||||
template <typename T, std::size_t I>
|
template <typename T, std::size_t I>
|
||||||
T get(types<T>, indices<I>) const {
|
stack::get_return<T> get(types<T>, indices<I>) const {
|
||||||
return stack::get<T>(L, index);
|
return stack::get<T>(L, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Ret, std::size_t... I>
|
template <typename... Ret, std::size_t... I>
|
||||||
std::tuple<Ret...> get(types<Ret...>, indices<I...>) const {
|
stack::get_return<Ret...> get(types<Ret...>, indices<I...>) const {
|
||||||
auto r = std::make_tuple(stack::get<Ret>(L, index + I)...);
|
auto r = std::make_tuple(stack::get<Ret>(L, index + I)...);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -60,12 +60,21 @@ public:
|
||||||
function_result(function_result&&) = default;
|
function_result(function_result&&) = default;
|
||||||
function_result& operator=(function_result&&) = default;
|
function_result& operator=(function_result&&) = default;
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
operator T () const {
|
T get() const {
|
||||||
auto tr = tuple_types<T>();
|
tuple_types<Unqualified<T>> tr;
|
||||||
return get(tr, tr);
|
return get(tr, tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operator const char* () const {
|
||||||
|
return get<const char*>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, EnableIf<Not<std::is_same<Unqualified<T>, const char*>>, Not<std::is_same<Unqualified<T>, char>>, Not<std::is_same<Unqualified<T>, std::string>>, Not<std::is_same<Unqualified<T>, std::initializer_list<char>>>> = 0>
|
||||||
|
operator T () const {
|
||||||
|
return get<T>();
|
||||||
|
}
|
||||||
|
|
||||||
~function_result() {
|
~function_result() {
|
||||||
lua_pop(L, returncount);
|
lua_pop(L, returncount);
|
||||||
}
|
}
|
||||||
|
@ -122,12 +131,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Ret, typename... Args>
|
template<typename... Ret, typename... Args>
|
||||||
ReturnType<Ret...> operator()(types<Ret...>, Args&&... args) const {
|
auto operator()(types<Ret...>, Args&&... args) const
|
||||||
|
-> decltype(call<Ret...>(std::forward<Args>(args)...)) {
|
||||||
return call<Ret...>(std::forward<Args>(args)...);
|
return call<Ret...>(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Ret, typename... Args>
|
template<typename... Ret, typename... Args>
|
||||||
auto call(Args&&... args) const -> decltype(invoke(types<Ret...>(), types<Ret...>(), 0)) {
|
auto call(Args&&... args) const
|
||||||
|
-> decltype(invoke(types<Ret...>(), types<Ret...>(), 0)) {
|
||||||
push();
|
push();
|
||||||
int pushcount = stack::push_args(state(), std::forward<Args>(args)...);
|
int pushcount = stack::push_args(state(), std::forward<Args>(args)...);
|
||||||
auto tr = types<Ret...>();
|
auto tr = types<Ret...>();
|
||||||
|
|
|
@ -52,7 +52,7 @@ public:
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
proxy& set_function(Args&&... args) {
|
proxy& set_function(Args&&... args) {
|
||||||
tbl.set_function(key, std::forward<Args>(args)...);
|
tbl.set_function(key, std::forward<Args>(args)...);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U, EnableIf<Function<Unqualified<U>>> = 0>
|
template<typename U, EnableIf<Function<Unqualified<U>>> = 0>
|
||||||
|
@ -65,50 +65,24 @@ public:
|
||||||
tbl.set(key, std::forward<U>(other));
|
tbl.set(key, std::forward<U>(other));
|
||||||
}
|
}
|
||||||
|
|
||||||
operator nil_t() const {
|
operator const char* () const {
|
||||||
return get<nil_t>();
|
return get<const char*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
operator object() const {
|
template<typename T, EnableIf<Not<std::is_same<Unqualified<T>, const char*>>, Not<std::is_same<Unqualified<T>, char>>, Not<std::is_same<Unqualified<T>, std::string>>, Not<std::is_same<Unqualified<T>, std::initializer_list<char>>>> = 0>
|
||||||
return get<object>();
|
operator T () const {
|
||||||
}
|
return get<T>();
|
||||||
|
|
||||||
operator function() const {
|
|
||||||
return get<function>();
|
|
||||||
}
|
|
||||||
|
|
||||||
operator Unqualified<Table>() const {
|
|
||||||
return get<Unqualified<Table>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
operator std::string() const {
|
|
||||||
return get<std::string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T = void>
|
|
||||||
operator bool() const {
|
|
||||||
return get<bool>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T = void>
|
|
||||||
operator double() const {
|
|
||||||
return get<double>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T = void>
|
|
||||||
operator float() const {
|
|
||||||
return get<float>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T = void>
|
|
||||||
operator int() const {
|
|
||||||
return get<int>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Ret, typename... Args>
|
template<typename... Ret, typename... Args>
|
||||||
typename return_type<Ret...>::type call(Args&&... args) {
|
stack::get_return_or<function_result, Ret...> call(Args&&... args) {
|
||||||
return tbl.template get<function>(key)(types<Ret...>(), std::forward<Args>(args)...);
|
return tbl.template get<function>(key)(types<Ret...>(), std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
function_result operator()(Args&&... args) {
|
||||||
|
return tbl.template get<function>(key)(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Table, typename Key, typename T>
|
template<typename Table, typename Key, typename T>
|
||||||
|
|
|
@ -141,6 +141,12 @@ bool check(lua_State* L, int index) {
|
||||||
return check<T>(L, index, handler);
|
return check<T>(L, index, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename... Ret>
|
||||||
|
using get_return = ReturnType<decltype(stack::get<Ret>( nullptr, 0 ))...>;
|
||||||
|
|
||||||
|
template<typename Empty, typename... Ret>
|
||||||
|
using get_return_or = ReturnTypeOr<Empty, decltype(stack::get<Ret>( nullptr, 0 ))...>;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
const bool default_check_arguments =
|
const bool default_check_arguments =
|
||||||
#ifdef SOL_CHECK_ARGUMENTS
|
#ifdef SOL_CHECK_ARGUMENTS
|
||||||
|
@ -258,7 +264,7 @@ struct getter<T*> {
|
||||||
type t = type_of(L, index);
|
type t = type_of(L, index);
|
||||||
if (t == type::nil)
|
if (t == type::nil)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return getter<T&>{}.get(L, index);
|
return std::addressof(getter<T&>{}.get(L, index));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,24 +30,23 @@
|
||||||
namespace sol {
|
namespace sol {
|
||||||
class table : public reference {
|
class table : public reference {
|
||||||
friend class state;
|
friend class state;
|
||||||
template<typename T, typename U>
|
template<typename T, typename Key>
|
||||||
auto single_get(U&& key) const -> decltype(stack::get<T>(nullptr, 0)) {
|
stack::get_return<T> single_get(Key&& key) const {
|
||||||
push();
|
push();
|
||||||
stack::push(state(), std::forward<U>(key));
|
stack::push(state(), std::forward<Key>(key));
|
||||||
lua_gettable(state(), -2);
|
lua_gettable(state(), -2);
|
||||||
type_assert(state(), -1, type_of<T>());
|
stack::get_return<T> result = stack::pop<T>(state());
|
||||||
auto&& result = stack::pop<T>(state());
|
pop();
|
||||||
lua_pop(state(), 1);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Keys, typename... Ret, std::size_t... I>
|
template<typename Keys, typename... Ret, std::size_t... I>
|
||||||
auto tuple_get(types<Ret...>, indices<I...>, Keys&& keys) const -> decltype(std::make_tuple(single_get<Ret>(std::get<I>(keys))...)) {
|
stack::get_return<Ret...> tuple_get(types<Ret...>, indices<I...>, Keys&& keys) const {
|
||||||
return std::make_tuple(single_get<Ret>(std::get<I>(keys))...);
|
return stack::get_return<Ret...>(single_get<Ret>(std::get<I>(keys))...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Keys, std::size_t I, typename Ret>
|
template<typename Keys, typename Ret, std::size_t I>
|
||||||
auto tuple_get(types<Ret>, indices<I>, Keys&& keys) const -> decltype(single_get<Ret>(std::get<I>(keys))) {
|
stack::get_return<Ret> tuple_get(types<Ret>, indices<I>, Keys&& keys) const {
|
||||||
return single_get<Ret>(std::get<I>(keys));
|
return single_get<Ret>(std::get<I>(keys));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,9 +57,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Ret, typename... Keys>
|
template<typename... Ret, typename... Keys>
|
||||||
auto get(Keys&&... keys) const -> decltype(tuple_get(types<Ret...>(), types<Ret...>(), std::tie(std::forward<Keys>(keys)...))) {
|
stack::get_return<Ret...> get( Keys&&... keys ) const {
|
||||||
types<Ret...> tr;
|
return tuple_get(types<Ret...>(), build_indices<sizeof...(Ret)>(), std::tie(keys...));
|
||||||
return tuple_get(tr, tr, std::tie(std::forward<Keys>(keys)...));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
|
@ -116,16 +114,16 @@ public:
|
||||||
size_t result = lua_rawlen(state(), -1);
|
size_t result = lua_rawlen(state(), -1);
|
||||||
pop();
|
pop();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
proxy<table, T> operator[](T&& key) {
|
proxy<table, T> operator[]( T&& key ) {
|
||||||
return proxy<table, T>(*this, std::forward<T>(key));
|
return proxy<table, T>( *this, std::forward<T>( key ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
proxy<const table, T> operator[](T&& key) const {
|
proxy<const table, T> operator[]( T&& key ) const {
|
||||||
return proxy<const table, T>(*this, std::forward<T>(key));
|
return proxy<const table, T>( *this, std::forward<T>( key ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop(int n = 1) const noexcept {
|
void pop(int n = 1) const noexcept {
|
||||||
|
|
|
@ -122,8 +122,11 @@ struct return_type<> {
|
||||||
typedef void type;
|
typedef void type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Empty, typename... Tn>
|
||||||
|
using ReturnTypeOr = typename std::conditional<(sizeof...(Tn) < 1), Empty, typename return_type<Tn...>::type>::type;
|
||||||
|
|
||||||
template <typename... Tn>
|
template <typename... Tn>
|
||||||
using ReturnType = typename return_type<Tn...>::type;
|
using ReturnType = ReturnTypeOr<void, Tn...>;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
|
27
tests.cpp
27
tests.cpp
|
@ -488,6 +488,33 @@ TEST_CASE("functions/return_order_and_multi_get", "Check if return order is in t
|
||||||
REQUIRE(tluaget == triple);
|
REQUIRE(tluaget == triple);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("functions/deducing_return_order_and_multi_get", "Check if return order is in the same reading order specified in Lua, with regular deducing calls") {
|
||||||
|
const static std::tuple<int, int, int> triple = std::make_tuple(10, 11, 12);
|
||||||
|
sol::state lua;
|
||||||
|
lua.set_function( "f_string", []() { return "this is a string!"; } );
|
||||||
|
sol::function f_string = lua[ "f_string" ];
|
||||||
|
|
||||||
|
// Make sure there are no overload collisions / compiler errors for automatic string conversions
|
||||||
|
std::string f_string_result = f_string();
|
||||||
|
REQUIRE(f_string_result == "this is a string!");
|
||||||
|
f_string_result = f_string();
|
||||||
|
REQUIRE(f_string_result == "this is a string!");
|
||||||
|
|
||||||
|
lua.set_function("f", [] {
|
||||||
|
return std::make_tuple(10, 11, 12);
|
||||||
|
});
|
||||||
|
lua.script("function g() return 10, 11, 12 end\nx,y,z = g()");
|
||||||
|
std::tuple<int, int, int> tcpp = lua.get<sol::function>("f")();
|
||||||
|
std::tuple<int, int, int> tlua = lua.get<sol::function>("g")();
|
||||||
|
std::tuple<int, int, int> tluaget = lua.get<int, int, int>("x", "y", "z");
|
||||||
|
std::cout << "cpp: " << std::get<0>(tcpp) << ',' << std::get<1>(tcpp) << ',' << std::get<2>(tcpp) << std::endl;
|
||||||
|
std::cout << "lua: " << std::get<0>(tlua) << ',' << std::get<1>(tlua) << ',' << std::get<2>(tlua) << std::endl;
|
||||||
|
std::cout << "lua xyz: " << lua.get<int>("x") << ',' << lua.get<int>("y") << ',' << lua.get<int>("z") << std::endl;
|
||||||
|
REQUIRE(tcpp == triple);
|
||||||
|
REQUIRE(tlua == triple);
|
||||||
|
REQUIRE(tluaget == triple);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("functions/sol::function to std::function", "check if conversion to std::function works properly and calls with correct arguments") {
|
TEST_CASE("functions/sol::function to std::function", "check if conversion to std::function works properly and calls with correct arguments") {
|
||||||
sol::state lua;
|
sol::state lua;
|
||||||
lua.open_libraries(sol::lib::base);
|
lua.open_libraries(sol::lib::base);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user