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 {
|
||||
template<typename T>
|
||||
struct pusher<T, typename std::enable_if<has_begin_end<T>::value>::type> {
|
||||
template <typename U>
|
||||
static void push(lua_State *L, U&& t){
|
||||
template<typename U = T, EnableIf<Not<has_key_value_pair<U>>> = 0>
|
||||
static void push(lua_State* L, const T& cont) {
|
||||
typedef container<U> container_t;
|
||||
// todo: NEED to find a different way of handling this...
|
||||
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)));
|
||||
std::allocator<container_t> alloc{};
|
||||
alloc.construct(c, std::forward<U>(t));
|
||||
alloc.construct(c, cont);
|
||||
|
||||
auto&& meta = userdata_traits<T>::metatable;
|
||||
luaL_getmetatable(L, std::addressof(meta[0]));
|
||||
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>
|
||||
static void push(lua_State* L, const T& cont) {
|
||||
lua_createtable(L, cont.size(), 0);
|
||||
|
|
|
@ -180,7 +180,7 @@ struct base_function {
|
|||
struct userdata {
|
||||
static int call(lua_State* L) {
|
||||
// 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) {
|
||||
using swallow = char[];
|
||||
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>>
|
||||
|
|
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!");
|
||||
}
|
||||
|
||||
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::cout << "free_function()" << std::endl;
|
||||
return "test";
|
||||
|
@ -320,7 +332,7 @@ TEST_CASE("tables/functions_variables", "Check if tables and function calls work
|
|||
std::cout << "stateless lambda()" << std::endl;
|
||||
return "test";
|
||||
}
|
||||
);
|
||||
);
|
||||
REQUIRE_NOTHROW(run_script(lua));
|
||||
|
||||
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") {
|
||||
sol::state lua;
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("tables/self-referential userdata", "userdata classes must play nice when C++ object types are requested for C++ code") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
|
Loading…
Reference in New Issue
Block a user