mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
metamethods for containers represented using userdata,
`#` == __len `[key] = value` == __newindex `key` == __index are not working properly for some reason, will need to investigate more deeply to find out why on bright side all tests pass including new tests added (for take/return std::function) fixed some things forgot to change with addition of upvalue_t for clarity (see previous commit about userdata/lightuserdata vs upvalue)
This commit is contained in:
parent
3306b44162
commit
6712ebe0bd
|
@ -37,8 +37,8 @@ struct container {
|
||||||
namespace stack {
|
namespace stack {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct pusher<T, typename std::enable_if<has_begin_end<T>::value>::type> {
|
struct pusher<T, typename std::enable_if<has_begin_end<T>::value>::type> {
|
||||||
template <typename U>
|
template<typename U = T, EnableIf<Not<has_key_value_pair<U>>> = 0>
|
||||||
static void push(lua_State *L, U&& t){
|
static void push(lua_State* L, const T& cont) {
|
||||||
typedef container<U> container_t;
|
typedef container<U> container_t;
|
||||||
// todo: NEED to find a different way of handling this...
|
// todo: NEED to find a different way of handling this...
|
||||||
static std::vector<std::shared_ptr<void>> classes{};
|
static std::vector<std::shared_ptr<void>> classes{};
|
||||||
|
@ -53,27 +53,13 @@ struct pusher<T, typename std::enable_if<has_begin_end<T>::value>::type> {
|
||||||
|
|
||||||
container_t* c = static_cast<container_t*>(lua_newuserdata(L, sizeof(container_t)));
|
container_t* c = static_cast<container_t*>(lua_newuserdata(L, sizeof(container_t)));
|
||||||
std::allocator<container_t> alloc{};
|
std::allocator<container_t> alloc{};
|
||||||
alloc.construct(c, std::forward<U>(t));
|
alloc.construct(c, cont);
|
||||||
|
|
||||||
auto&& meta = userdata_traits<T>::metatable;
|
auto&& meta = userdata_traits<T>::metatable;
|
||||||
luaL_getmetatable(L, std::addressof(meta[0]));
|
luaL_getmetatable(L, std::addressof(meta[0]));
|
||||||
lua_setmetatable(L, -2);
|
lua_setmetatable(L, -2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U = T, EnableIf<Not<has_key_value_pair<U>>> = 0>
|
|
||||||
static void push(lua_State* L, const T& cont) {
|
|
||||||
lua_createtable(L, cont.size(), 0);
|
|
||||||
unsigned index = 1;
|
|
||||||
for(auto&& i : cont) {
|
|
||||||
// push the index
|
|
||||||
pusher<unsigned>::push(L, index++);
|
|
||||||
// push the value
|
|
||||||
pusher<Unqualified<decltype(i)>>::push(L, i);
|
|
||||||
// set the table
|
|
||||||
lua_settable(L, -3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename U = T, EnableIf<has_key_value_pair<U>> = 0>
|
template<typename U = T, EnableIf<has_key_value_pair<U>> = 0>
|
||||||
static void push(lua_State* L, const T& cont) {
|
static void push(lua_State* L, const T& cont) {
|
||||||
lua_createtable(L, cont.size(), 0);
|
lua_createtable(L, cont.size(), 0);
|
||||||
|
|
|
@ -180,7 +180,7 @@ struct base_function {
|
||||||
struct userdata {
|
struct userdata {
|
||||||
static int call(lua_State* L) {
|
static int call(lua_State* L) {
|
||||||
// Zero-based template parameter, but upvalues start at 1
|
// Zero-based template parameter, but upvalues start at 1
|
||||||
return base_call(L, stack::get<lightuserdata_t>(L, i + 1));
|
return base_call(L, stack::get<upvalue_t>(L, i + 1));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -286,7 +286,7 @@ template<typename T, typename... Args>
|
||||||
inline void push(lua_State* L, T&& t, Args&&... args) {
|
inline void push(lua_State* L, T&& t, Args&&... args) {
|
||||||
using swallow = char[];
|
using swallow = char[];
|
||||||
pusher<Unqualified<T>>{}.push(L, std::forward<T>(t));
|
pusher<Unqualified<T>>{}.push(L, std::forward<T>(t));
|
||||||
void(swallow{'\0', (pusher<Unqualified<T>>{}.push(L, std::forward<Args>(args)), '\0')... });
|
void(swallow{'\0', (pusher<Unqualified<Args>>{}.push(L, std::forward<Args>(args)), '\0')... });
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename U = Unqualified<T>>
|
template<typename T, typename U = Unqualified<T>>
|
||||||
|
|
26
tests.cpp
26
tests.cpp
|
@ -14,6 +14,18 @@ void test_free_func2(std::function<int(int)> f, int arg1) {
|
||||||
throw sol::error("failed function call!");
|
throw sol::error("failed function call!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::function<int()> makefn () {
|
||||||
|
auto fx = []() -> int {
|
||||||
|
return 0x1456789;
|
||||||
|
};
|
||||||
|
return fx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void takefn ( std::function<int()> purr ) {
|
||||||
|
if (purr() != 0x1456789)
|
||||||
|
throw 0;
|
||||||
|
}
|
||||||
|
|
||||||
std::string free_function() {
|
std::string free_function() {
|
||||||
std::cout << "free_function()" << std::endl;
|
std::cout << "free_function()" << std::endl;
|
||||||
return "test";
|
return "test";
|
||||||
|
@ -320,7 +332,7 @@ TEST_CASE("tables/functions_variables", "Check if tables and function calls work
|
||||||
std::cout << "stateless lambda()" << std::endl;
|
std::cout << "stateless lambda()" << std::endl;
|
||||||
return "test";
|
return "test";
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
REQUIRE_NOTHROW(run_script(lua));
|
REQUIRE_NOTHROW(run_script(lua));
|
||||||
|
|
||||||
lua.get<sol::table>("os").set_function("fun", &free_function);
|
lua.get<sol::table>("os").set_function("fun", &free_function);
|
||||||
|
@ -388,6 +400,17 @@ TEST_CASE("functions/sol::function to std::function", "check if conversion to st
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("functions/returning functions from C++ and getting in lua", "check to see if returning a functor and getting a functor from lua is possible") {
|
||||||
|
sol::state lua;
|
||||||
|
lua.open_libraries(sol::lib::base);
|
||||||
|
|
||||||
|
lua.set_function( "makefn", makefn );
|
||||||
|
lua.set_function( "takefn", takefn );
|
||||||
|
lua.script( "afx = makefn()\n"
|
||||||
|
"print(afx())\n"
|
||||||
|
"takefn(afx)\n" );
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("tables/operator[]", "Check if operator[] retrieval and setting works properly") {
|
TEST_CASE("tables/operator[]", "Check if operator[] retrieval and setting works properly") {
|
||||||
sol::state lua;
|
sol::state lua;
|
||||||
lua.open_libraries(sol::lib::base);
|
lua.open_libraries(sol::lib::base);
|
||||||
|
@ -558,7 +581,6 @@ TEST_CASE("tables/userdata utility derived", "userdata classes must play nice wh
|
||||||
REQUIRE((lua.get<int>("dgn") == 7));
|
REQUIRE((lua.get<int>("dgn") == 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_CASE("tables/self-referential userdata", "userdata classes must play nice when C++ object types are requested for C++ code") {
|
TEST_CASE("tables/self-referential userdata", "userdata classes must play nice when C++ object types are requested for C++ code") {
|
||||||
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