Custom constructors, but apparently there's something on the stack and we can't get at its type?

This commit is contained in:
ThePhD 2014-04-26 00:19:36 -04:00
parent bf19dd9084
commit 4c102605e8
2 changed files with 60 additions and 26 deletions

View File

@ -23,6 +23,7 @@
#define SOL_DEMANGLE_HPP
#include <string>
#include <array>
#if defined(__GNUC__) || defined(__clang__)
#include <cxxabi.h>
@ -32,16 +33,22 @@ namespace sol {
namespace detail {
#ifdef _MSC_VER
std::string demangle(const std::type_info& id) {
const static std::string removals[2] = { "struct ", "class " };
std::string realname = id.name();
for(std::size_t r = 0; r < 2; ++r) {
const static std::array<std::string, 2> removals = { "struct ", "class " };
const static std::array<std::string, 2> replacements = { "::", "_" };
std::string realname = id.name( );
for(std::size_t r = 0; r < removals.size(); ++r) {
auto found = realname.find(removals[r]);
if(found == std::string::npos) {
continue;
while (found != std::string::npos) {
realname.erase(found, removals[r].size());
found = realname.find( removals[r] );
}
}
for(std::size_t r = 0; r < replacements.size(); r+=2) {
auto found = realname.find(replacements[r]);
while (found != std::string::npos) {
realname.replace(found, replacements[r].size(), replacements[r+1]);
found = realname.find(replacements[r], found);
}
realname.erase(found, removals[r].size());
}
return realname;
}

View File

@ -47,14 +47,39 @@ private:
std::vector<std::unique_ptr<lua_func>> functions;
std::vector<luaL_Reg> functiontable;
std::vector<luaL_Reg> metatable;
template <typename... TTypes>
struct constructor {
template <typename... Args>
static void do_constructor(lua_State* L, T* obj, int argcount, types<Args...> t) {
auto fx = [&obj] ( Args&&... args ) -> void {
std::allocator<T> alloc{};
alloc.construct(obj, std::forward<Args>(args)...);
};
stack::pop_call(L, fx, t);
}
static void match_constructor(lua_State* L, T* obj, int argcount) {
if (argcount != 0)
throw sol_error("No matching constructor for the arguments provided");
}
template<typename ...CArgs, typename... Args>
static void match_constructor(lua_State* L, T* obj, int argcount, types<CArgs...> t, Args&&... args) {
if (argcount == sizeof...(CArgs)) {
do_constructor( L, obj, argcount, t );
return;
}
match_constructor( L, obj, argcount, std::forward<Args>(args)...);
}
static int construct(lua_State* L) {
int argcount = lua_gettop(L);
// First argument is now a table that represent the class to instantiate
luaL_checktype(L, 1, LUA_TTABLE);
lua_createtable(L, 0, 0); // Create table to represent instance
luaL_checktype( L, 1, LUA_TTABLE );
// Table represents the instance
lua_createtable(L, 0, 0);
// Set first argument of new to metatable of instance
lua_pushvalue(L, 1);
lua_setmetatable(L, -2);
@ -63,16 +88,17 @@ private:
lua_pushvalue(L, 1);
lua_setfield(L, 1, "__index");
void* userdata = lua_newuserdata(L, sizeof(T));
T* obj = static_cast<T*>(userdata);
std::allocator<T> alloc{};
alloc.construct(obj);
luaL_getmetatable(L, meta.c_str());
void* udata = lua_newuserdata( L, sizeof( T ) );
T* obj = static_cast<T*>( udata );
match_constructor( L, obj, argcount - 1, std::common_type<TTypes>::type( )... );
//match_constructor( L, obj, argcount - 1, types<int>( ) );
luaL_getmetatable(L, meta.c_str());
lua_setmetatable(L, -2);
lua_setfield(L, -2, "__self");
return 1;
return 1;
}
};
@ -80,13 +106,14 @@ private:
struct destructor {
static int destruct(lua_State* L) {
for(std::size_t i = 0; i < n; ++i) {
lightuserdata_t luserdata = stack::get<lightuserdata_t>(L, i);
// make warnings shut up
(void)luserdata;
lightuserdata_t ludata = stack::get<lightuserdata_t>(L, i);
lua_func* func = static_cast<lua_func*>(ludata.value);
std::default_delete<lua_func> dx{};
dx(func);
}
userdata_t userdata = stack::get<userdata_t>(L, 0);
T* obj = static_cast<T*>(userdata.value);
userdata_t udata = stack::get<userdata_t>(L, 0);
T* obj = static_cast<T*>(udata.value);
std::allocator<T> alloc{};
alloc.destroy(obj);
@ -127,7 +154,7 @@ public:
userdata(Args&&... args) : userdata(classname, std::forward<Args>(args)...) {}
template <typename... Args>
userdata(std::string name, Args&&... args) : userdata(name, constructors<>(), std::forward<Args>(args)...) {}
userdata(std::string name, Args&&... args) : userdata(name, constructors<types<>>(), std::forward<Args>(args)...) {}
template <typename... Args, typename... CArgs>
userdata(constructors<CArgs...> c, Args&&... args) : userdata(classname, std::move(c), std::forward<Args>(args)...) {}
@ -141,7 +168,7 @@ public:
build_function_tables<0>(std::forward<Args>(args)...);
functionnames.push_back("new");
functiontable.push_back({ functionnames.back().c_str(), &constructor::construct });
functiontable.push_back({ functionnames.back().c_str(), &constructor<CArgs...>::construct });
functiontable.push_back({ nullptr, nullptr });
metatable.push_back({ "__gc", &destructor<sizeof...(Args) / 2>::destruct });