Add Lua bindings to std::shared_ptr<T const>

This is required after the recent RCU change to return
const shared pointers for read (295dbd8e1).
This commit is contained in:
Robin Gareus 2023-04-19 01:32:34 +02:00
parent b4d8a3f933
commit 7094c82e75
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
2 changed files with 191 additions and 6 deletions

View File

@ -355,6 +355,28 @@ struct CFunc
}
};
template <class MemFnPtr, class T,
class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
struct CallMemberCPtr
{
typedef typename FuncTraits <MemFnPtr>::Params Params;
static int f (lua_State* L)
{
assert (isfulluserdata (L, lua_upvalueindex (1)));
std::shared_ptr<T const>* const t = Userdata::get <std::shared_ptr<T const> > (L, 1, true);
T* const tt = const_cast<T*> (t->get());
if (!tt) {
return luaL_error (L, "shared_ptr is nil");
}
MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
assert (fnptr != 0);
ArgList <Params, 2> args (L);
Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (tt, fnptr, args));
return 1;
}
};
template <class T, class R>
struct CastMemberPtr
{
@ -636,6 +658,31 @@ struct CFunc
}
};
template <class MemFnPtr, class T,
class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
struct CallMemberRefCPtr
{
typedef typename FuncTraits <MemFnPtr>::Params Params;
static int f (lua_State* L)
{
assert (isfulluserdata (L, lua_upvalueindex (1)));
std::shared_ptr<T const>* const t = Userdata::get <std::shared_ptr<T const> > (L, 1, true);
T* const tt = const_cast<T*> (t->get());
if (!tt) {
return luaL_error (L, "shared_ptr is nil");
}
MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
assert (fnptr != 0);
ArgList <Params, 2> args (L);
Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (tt, fnptr, args));
LuaRef v (newTable (L));
FuncArgs <Params, 0>::refs (v, args);
v.push(L);
return 2;
}
};
template <class MemFnPtr, class T,
class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
struct CallMemberRefWPtr
@ -726,6 +773,24 @@ struct CFunc
}
};
template <class MemFnPtr, class T>
struct CallMemberCPtr <MemFnPtr, T, void>
{
typedef typename FuncTraits <MemFnPtr>::Params Params;
static int f (lua_State* L)
{
assert (isfulluserdata (L, lua_upvalueindex (1)));
std::shared_ptr<T const>* const t = Userdata::get <std::shared_ptr<T const> > (L, 1, true);
T* const tt = const_cast<T*> (t->get());
MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
assert (fnptr != 0);
ArgList <Params, 2> args (L);
FuncTraits <MemFnPtr>::call (tt, fnptr, args);
return 0;
}
};
template <class MemFnPtr, class T>
struct CallMemberWPtr <MemFnPtr, T, void>
{
@ -817,6 +882,30 @@ struct CFunc
}
};
template <class MemFnPtr, class T>
struct CallMemberRefCPtr <MemFnPtr, T, void>
{
typedef typename FuncTraits <MemFnPtr>::Params Params;
static int f (lua_State* L)
{
assert (isfulluserdata (L, lua_upvalueindex (1)));
std::shared_ptr<T const>* const t = Userdata::get <std::shared_ptr<T const> > (L, 1, true);
T* const tt = const_cast<T*> (t->get());
if (!tt) {
return luaL_error (L, "shared_ptr is nil");
}
MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
assert (fnptr != 0);
ArgList <Params, 2> args (L);
FuncTraits <MemFnPtr>::call (tt, fnptr, args);
LuaRef v (newTable (L));
FuncArgs <Params, 0>::refs (v, args);
v.push(L);
return 1;
}
};
template <class MemFnPtr, class T>
struct CallMemberRefWPtr <MemFnPtr, T, void>
{
@ -932,6 +1021,30 @@ struct CFunc
}
};
template <class MemFnPtr>
struct CallMemberCPtrFunctionHelper
{
typedef typename FuncTraits <MemFnPtr>::ClassType T;
static void add (lua_State* L, char const* name, MemFnPtr mf)
{
new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
lua_pushcclosure (L, &CallMemberCPtr <MemFnPtr, T>::f, 1);
rawsetfield (L, -3, name); // class table
}
};
template <class MemFnPtr>
struct CallMemberRefCPtrFunctionHelper
{
typedef typename FuncTraits <MemFnPtr>::ClassType T;
static void add (lua_State* L, char const* name, MemFnPtr mf)
{
new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
lua_pushcclosure (L, &CallMemberRefCPtr <MemFnPtr, T>::f, 1);
rawsetfield (L, -3, name); // class table
}
};
template <class MemFnPtr>
struct CallMemberWPtrFunctionHelper
{

View File

@ -28,13 +28,14 @@
*/
//==============================================================================
#include <memory>
#ifdef LUABINDINGDOC
#include <iostream>
#include <typeinfo>
#include <execinfo.h>
#include <type_traits>
#include <cxxabi.h>
#include <memory>
#include <string>
#include <cstdlib>
@ -1275,6 +1276,7 @@ private:
WSPtrClass (char const* name, Namespace const* parent)
: ClassBase (parent->L)
, shared (name, parent)
, shared_const (name, parent)
, weak (name, parent)
{
#ifdef LUABINDINGDOC
@ -1285,13 +1287,14 @@ private:
parent->_name + name,
std::string(), type_name <T>())
m_stackSize = shared.m_stackSize;
parent->m_stackSize = weak.m_stackSize = shared.m_stackSize = 0;
lua_pop (L, 3);
parent->m_stackSize = weak.m_stackSize = shared.m_stackSize = shared_const.m_stackSize = 0;
lua_pop (L, 6);
}
WSPtrClass (char const* name, Namespace const* parent, void const* const sharedkey, void const* const weakkey)
WSPtrClass (char const* name, Namespace const* parent, void const* const sharedkey, void const* const sharedconstkey, void const* const weakkey)
: ClassBase (parent->L)
, shared (name, parent, sharedkey)
, shared_const (name, parent, sharedconstkey)
, weak (name, parent, weakkey)
{
#ifdef LUABINDINGDOC
@ -1299,8 +1302,8 @@ private:
_name = parent->_name + name + ":";
#endif
m_stackSize = shared.m_stackSize;
parent->m_stackSize = weak.m_stackSize = shared.m_stackSize = 0;
lua_pop (L, 3);
parent->m_stackSize = weak.m_stackSize = shared.m_stackSize = shared_const.m_stackSize = 0;
lua_pop (L, 6);
}
template <class MemFn>
@ -1310,6 +1313,9 @@ private:
set_shared_class ();
CFunc::CallMemberPtrFunctionHelper <MemFn>::add (L, name, mf);
set_const_shared_class ();
CFunc::CallMemberCPtrFunctionHelper <MemFn>::add (L, name, mf);
set_weak_class ();
CFunc::CallMemberWPtrFunctionHelper <MemFn>::add (L, name, mf);
return *this;
@ -1322,6 +1328,9 @@ private:
set_shared_class ();
CFunc::CallMemberRefPtrFunctionHelper <MemFn>::add (L, name, mf);
set_const_shared_class ();
CFunc::CallMemberRefCPtrFunctionHelper <MemFn>::add (L, name, mf);
set_weak_class ();
CFunc::CallMemberRefWPtrFunctionHelper <MemFn>::add (L, name, mf);
return *this;
@ -1336,6 +1345,11 @@ private:
&shared. template ctorPtrPlacementProxy <typename FuncTraits <MemFn>::Params, std::shared_ptr<T>, T >, 0);
rawsetfield(L, -2, "__call");
set_const_shared_class ();
lua_pushcclosure (L,
&shared_const. template ctorPtrPlacementProxy <typename FuncTraits <MemFn>::Params, std::shared_ptr<T const>, T >, 0);
rawsetfield(L, -2, "__call");
set_weak_class ();
// NOTE: this constructs an empty weak-ptr,
// ideally we'd construct a weak-ptr from a referenced shared-ptr
@ -1359,6 +1373,11 @@ private:
lua_pushcclosure (L, &CFunc::Call <FP>::f, 1);
rawsetfield (L, -2, name);
set_const_shared_class ();
new (lua_newuserdata (L, sizeof (fp))) FP (fp);
lua_pushcclosure (L, &CFunc::Call <FP>::f, 1);
rawsetfield (L, -2, name);
set_weak_class ();
new (lua_newuserdata (L, sizeof (fp))) FP (fp);
lua_pushcclosure (L, &CFunc::Call <FP>::f, 1);
@ -1374,6 +1393,11 @@ private:
&shared. template ctorNilPtrPlacementProxy <std::shared_ptr<T> >, 0);
rawsetfield(L, -2, "__call");
set_const_shared_class ();
lua_pushcclosure (L,
&shared_const. template ctorNilPtrPlacementProxy <std::shared_ptr<T const> >, 0);
rawsetfield(L, -2, "__call");
set_weak_class ();
// NOTE: this constructs an empty weak-ptr,
// ideally we'd construct a weak-ptr from a referenced shared-ptr
@ -1394,6 +1418,13 @@ private:
rawsetfield (L, -5, name); // const table
rawsetfield (L, -3, name); // class table
set_const_shared_class ();
assert (lua_istable (L, -1));
lua_pushcclosure (L, fp, 0);
lua_pushvalue (L, -1);
rawsetfield (L, -5, name); // const table
rawsetfield (L, -3, name); // class table
set_weak_class ();
assert (lua_istable (L, -1));
lua_pushcclosure (L, fp, 0);
@ -1416,6 +1447,12 @@ private:
assert (lua_istable (L, -1));
lua_pushcclosure (L, &CFunc::CastMemberPtr <T, U>::f, 0);
rawsetfield (L, -3, name); // class table
set_const_shared_class ();
assert (lua_istable (L, -1));
lua_pushcclosure (L, &CFunc::CastMemberPtr <T const, U const>::f, 0);
rawsetfield (L, -3, name); // class table
return *this;
}
@ -1427,6 +1464,11 @@ private:
lua_pushcclosure (L, &CFunc::PtrNullCheck <T>::f, 0);
rawsetfield (L, -3, "isnil"); // class table
set_const_shared_class ();
assert (lua_istable (L, -1));
lua_pushcclosure (L, &CFunc::PtrNullCheck <T const>::f, 0);
rawsetfield (L, -3, "isnil"); // class table
set_weak_class ();
assert (lua_istable (L, -1));
lua_pushcclosure (L, &CFunc::WPtrNullCheck <T>::f, 0);
@ -1442,6 +1484,11 @@ private:
lua_pushcclosure (L, &CFunc::PtrEqualCheck <T>::f, 0);
rawsetfield (L, -3, "sameinstance"); // class table
set_const_shared_class ();
assert (lua_istable (L, -1));
lua_pushcclosure (L, &CFunc::PtrEqualCheck <T const>::f, 0);
rawsetfield (L, -3, "sameinstance"); // class table
set_weak_class ();
assert (lua_istable (L, -1));
lua_pushcclosure (L, &CFunc::WPtrEqualCheck <T>::f, 0);
@ -1481,6 +1528,20 @@ private:
lua_pop (L, 1);
}
set_const_shared_class ();
assert (lua_istable (L, -1));
// Add to __propget in class and const tables.
{
rawgetfield (L, -2, "__propget");
rawgetfield (L, -4, "__propget");
new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
lua_pushcclosure (L, &CFunc::getPtrProperty <T const,U>, 1);
lua_pushvalue (L, -1);
rawsetfield (L, -4, name);
rawsetfield (L, -2, name);
lua_pop (L, 2);
}
set_shared_class ();
assert (lua_istable (L, -1));
// Add to __propget in class and const tables.
@ -1532,7 +1593,17 @@ private:
lua_insert (L, -3);
lua_insert (L, -2);
}
void set_const_shared_class () {
lua_pop (L, 3);
lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <std::shared_ptr<T const> >::getStaticKey ());
rawgetfield (L, -1, "__class");
rawgetfield (L, -1, "__const");
lua_insert (L, -3);
lua_insert (L, -2);
}
Class<std::shared_ptr<T> > shared;
Class<std::shared_ptr<T const> > shared_const;
Class<std::weak_ptr<T> > weak;
};
@ -2122,6 +2193,7 @@ public:
CLASSDOC ("[C] Derived Pointer Class", _name << name, type_name <T>(), type_name <U>())
return WSPtrClass <T> (name, this,
ClassInfo <std::shared_ptr<U> >::getStaticKey (),
ClassInfo <std::shared_ptr<U const> >::getStaticKey (),
ClassInfo <std::weak_ptr<U> >::getStaticKey ())
.addNullCheck()
.addEqualCheck();