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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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)...);
|
||||
return r;
|
||||
}
|
||||
|
@ -60,12 +60,21 @@ public:
|
|||
function_result(function_result&&) = default;
|
||||
function_result& operator=(function_result&&) = default;
|
||||
|
||||
template <typename T>
|
||||
operator T () const {
|
||||
auto tr = tuple_types<T>();
|
||||
template<typename T>
|
||||
T get() const {
|
||||
tuple_types<Unqualified<T>> 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() {
|
||||
lua_pop(L, returncount);
|
||||
}
|
||||
|
@ -122,12 +131,14 @@ public:
|
|||
}
|
||||
|
||||
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)...);
|
||||
}
|
||||
|
||||
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();
|
||||
int pushcount = stack::push_args(state(), std::forward<Args>(args)...);
|
||||
auto tr = types<Ret...>();
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
template<typename... Args>
|
||||
proxy& set_function(Args&&... args) {
|
||||
tbl.set_function(key, std::forward<Args>(args)...);
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename U, EnableIf<Function<Unqualified<U>>> = 0>
|
||||
|
@ -65,50 +65,24 @@ public:
|
|||
tbl.set(key, std::forward<U>(other));
|
||||
}
|
||||
|
||||
operator nil_t() const {
|
||||
return get<nil_t>();
|
||||
operator const char* () const {
|
||||
return get<const char*>();
|
||||
}
|
||||
|
||||
operator object() const {
|
||||
return get<object>();
|
||||
}
|
||||
|
||||
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 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>();
|
||||
}
|
||||
|
||||
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)...);
|
||||
}
|
||||
|
||||
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>
|
||||
|
|
|
@ -141,6 +141,12 @@ bool check(lua_State* L, int index) {
|
|||
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 {
|
||||
const bool default_check_arguments =
|
||||
#ifdef SOL_CHECK_ARGUMENTS
|
||||
|
@ -258,7 +264,7 @@ struct getter<T*> {
|
|||
type t = type_of(L, index);
|
||||
if (t == type::nil)
|
||||
return nullptr;
|
||||
return getter<T&>{}.get(L, index);
|
||||
return std::addressof(getter<T&>{}.get(L, index));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -30,24 +30,23 @@
|
|||
namespace sol {
|
||||
class table : public reference {
|
||||
friend class state;
|
||||
template<typename T, typename U>
|
||||
auto single_get(U&& key) const -> decltype(stack::get<T>(nullptr, 0)) {
|
||||
template<typename T, typename Key>
|
||||
stack::get_return<T> single_get(Key&& key) const {
|
||||
push();
|
||||
stack::push(state(), std::forward<U>(key));
|
||||
stack::push(state(), std::forward<Key>(key));
|
||||
lua_gettable(state(), -2);
|
||||
type_assert(state(), -1, type_of<T>());
|
||||
auto&& result = stack::pop<T>(state());
|
||||
lua_pop(state(), 1);
|
||||
stack::get_return<T> result = stack::pop<T>(state());
|
||||
pop();
|
||||
return result;
|
||||
}
|
||||
|
||||
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))...)) {
|
||||
return std::make_tuple(single_get<Ret>(std::get<I>(keys))...);
|
||||
stack::get_return<Ret...> tuple_get(types<Ret...>, indices<I...>, Keys&& keys) const {
|
||||
return stack::get_return<Ret...>(single_get<Ret>(std::get<I>(keys))...);
|
||||
}
|
||||
|
||||
template<typename Keys, std::size_t I, typename Ret>
|
||||
auto tuple_get(types<Ret>, indices<I>, Keys&& keys) const -> decltype(single_get<Ret>(std::get<I>(keys))) {
|
||||
template<typename Keys, typename Ret, std::size_t I>
|
||||
stack::get_return<Ret> tuple_get(types<Ret>, indices<I>, Keys&& keys) const {
|
||||
return single_get<Ret>(std::get<I>(keys));
|
||||
}
|
||||
|
||||
|
@ -58,9 +57,8 @@ public:
|
|||
}
|
||||
|
||||
template<typename... Ret, typename... Keys>
|
||||
auto get(Keys&&... keys) const -> decltype(tuple_get(types<Ret...>(), types<Ret...>(), std::tie(std::forward<Keys>(keys)...))) {
|
||||
types<Ret...> tr;
|
||||
return tuple_get(tr, tr, std::tie(std::forward<Keys>(keys)...));
|
||||
stack::get_return<Ret...> get( Keys&&... keys ) const {
|
||||
return tuple_get(types<Ret...>(), build_indices<sizeof...(Ret)>(), std::tie(keys...));
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
|
@ -116,16 +114,16 @@ public:
|
|||
size_t result = lua_rawlen(state(), -1);
|
||||
pop();
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
proxy<table, T> operator[](T&& key) {
|
||||
return proxy<table, T>(*this, std::forward<T>(key));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
proxy<const table, T> operator[](T&& key) const {
|
||||
return proxy<const table, T>(*this, std::forward<T>(key));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
proxy<table, T> operator[]( T&& key ) {
|
||||
return proxy<table, T>( *this, std::forward<T>( key ) );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
proxy<const table, T> operator[]( T&& key ) const {
|
||||
return proxy<const table, T>( *this, std::forward<T>( key ) );
|
||||
}
|
||||
|
||||
void pop(int n = 1) const noexcept {
|
||||
|
|
|
@ -122,8 +122,11 @@ struct return_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>
|
||||
using ReturnType = typename return_type<Tn...>::type;
|
||||
using ReturnType = ReturnTypeOr<void, Tn...>;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
|
Loading…
Reference in New Issue
Block a user