/*
https://github.com/vinniefalco/LuaBridge
+ Copyright 2016, Robin Gareus <robin@gareus.org>
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
Copyright 2007, Nathan Reed
*/
//==============================================================================
+#ifdef LUABINDINGDOC
+#include <iostream>
+#include <typeinfo>
+#include <execinfo.h>
+#include <type_traits>
+#include <cxxabi.h>
+#include <memory>
+#include <string>
+#include <cstdlib>
+
+template <class T>
+std::string type_name()
+{
+ typedef typename std::remove_reference<T>::type TR;
+ std::unique_ptr<char, void(*)(void*)> own
+ (
+ abi::__cxa_demangle(typeid(TR).name(), nullptr,
+ nullptr, nullptr),
+ std::free
+ );
+ std::string r = own != nullptr ? own.get() : typeid(TR).name();
+ if (std::is_const<TR>::value)
+ r += " const";
+ if (std::is_volatile<TR>::value)
+ r += " volatile";
+ if (std::is_lvalue_reference<T>::value)
+ r += "&";
+ else if (std::is_rvalue_reference<T>::value)
+ r += "&&";
+ return r;
+}
+
+//#define LUADOCOUT
+
+#ifdef LUADOCOUT // lua
+#define KEYSTA "[\""
+#define KEYEND "\"] = "
+#else // JSON
+#define KEYSTA "\""
+#define KEYEND "\" : "
+#endif
+
+#define CLASSDOC(TYPE, LUANAME, DECL, PARENTDECL) \
+ if (LuaBindingDoc::printBindings ()) { \
+ std::cout << "{ " << KEYSTA << "type" << KEYEND << " \"" << TYPE << "\",\n"; \
+ std::cout << " " << KEYSTA << "lua" << KEYEND << " \"" << LUANAME << "\",\n"; \
+ std::cout << " " << KEYSTA << "decl" << KEYEND << " \"" << DECL << "\",\n"; \
+ std::cout << " " << KEYSTA << "parent" << KEYEND << "\"" << PARENTDECL << "\"\n"; \
+ std::cout << "},\n"; \
+ }
+
+#define PRINTDOC(TYPE, LUANAME, RETVAL, DECL) \
+ if (LuaBindingDoc::printBindings ()) { \
+ std::cout << "{ " << KEYSTA << "type" << KEYEND << " \"" << TYPE << "\",\n"; \
+ std::cout << " " << KEYSTA << "lua" << KEYEND << " \"" << LUANAME << "\",\n"; \
+ if (!(RETVAL).empty()) { \
+ std::cout << " " << KEYSTA << "ret" << KEYEND << " \"" << (RETVAL) << "\",\n"; \
+ } \
+ std::cout << " " << KEYSTA << "decl" << KEYEND << " \"" << DECL << "\"\n"; \
+ std::cout << "},\n"; \
+ }
+
+#define FUNDOC(TYPE, NAME, FUNCTOR) \
+ PRINTDOC(TYPE, _name << NAME, \
+ type_name< typename FuncTraits <FUNCTOR>::ReturnType >(), \
+ type_name< typename FuncTraits <FUNCTOR>::DeclType >())
+
+#define DATADOC(TYPE, NAME, FUNCTOR) \
+ PRINTDOC(TYPE, _name << NAME, \
+ std::string(), \
+ type_name< decltype(FUNCTOR) >())\
+
+
+#else
+
+#define CLASSDOC(TYPE, LUANAME, DECL, PARENTDECL)
+#define PRINTDOC(TYPE, LUANAME, RETVAL, DECL)
+#define FUNDOC(TYPE, NAME, FUNCTOR)
+#define DATADOC(TYPE, NAME, FUNCTOR)
+
+#endif
+
/** Provides C++ to Lua registration capabilities.
This class is not instantiated directly, call `getGlobalNamespace` to start
lua_State* const L;
int mutable m_stackSize;
+#ifdef LUABINDINGDOC
+ std::string _name;
+ const Namespace* _parent;
+#endif
+
protected:
//--------------------------------------------------------------------------
/**
ClassBase (ClassBase const& other)
: L (other.L)
, m_stackSize (0)
+#ifdef LUABINDINGDOC
+ , _name (other._name)
+ , _parent (other._parent)
+#endif
{
m_stackSize = other.m_stackSize;
other.m_stackSize = 0;
-4 (enclosing namespace)
*/
template <class T>
- class Class : public ClassBase
+ class Class : virtual public ClassBase
{
public:
//==========================================================================
*/
Class (char const* name, Namespace const* parent) : ClassBase (parent->L)
{
+#ifdef LUABINDINGDOC
+ _parent = parent;
+ _name = parent->_name + name + ":";
+#endif
+ PRINTDOC ("[C] Class", parent->_name << name, std::string(), type_name <T>())
m_stackSize = parent->m_stackSize + 3;
parent->m_stackSize = 0;
}
else
{
+ lua_pop (L, 1);
+ lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ());
rawgetfield (L, -1, "__class");
rawgetfield (L, -1, "__const");
Class (char const* name, Namespace const* parent, void const* const staticKey)
: ClassBase (parent->L)
{
+#ifdef LUABINDINGDOC
+ _parent = parent;
+ _name = parent->_name + name + ":";
+#endif
m_stackSize = parent->m_stackSize + 3;
parent->m_stackSize = 0;
template <class U>
Class <T>& addStaticData (char const* name, U* pu, bool isWritable = true)
{
+ DATADOC ("Static Data Member", name, pu)
assert (lua_istable (L, -1));
rawgetfield (L, -1, "__propget");
}
//--------------------------------------------------------------------------
+#if 0 // unused
/**
Add or replace a static property member.
return *this;
}
+#endif
//--------------------------------------------------------------------------
/**
template <class FP>
Class <T>& addStaticFunction (char const* name, FP const fp)
{
+ FUNDOC ("Static Member Function", name, FP)
new (lua_newuserdata (L, sizeof (fp))) FP (fp);
lua_pushcclosure (L, &CFunc::Call <FP>::f, 1);
rawsetfield (L, -2, name);
*/
Class <T>& addStaticCFunction (char const* name, int (*const fp)(lua_State*))
{
+ DATADOC ("Static C Function", name, fp)
lua_pushcfunction (L, fp);
rawsetfield (L, -2, name);
return *this;
template <class U>
Class <T>& addData (char const* name, const U T::* mp, bool isWritable = true)
{
+ DATADOC ("Data Member", name, mp)
typedef const U T::*mp_t;
// Add to __propget in class and const tables.
return *this;
}
+#if 0 // unused
//--------------------------------------------------------------------------
/**
Add or replace a property member.
return *this;
}
-
+#endif
//--------------------------------------------------------------------------
/**
Add or replace a member function.
template <class MemFn>
Class <T>& addFunction (char const* name, MemFn mf)
{
+ FUNDOC("Member Function", name, MemFn)
CFunc::CallMemberFunctionHelper <MemFn, FuncTraits <MemFn>::isConstMemberFunction>::add (L, name, mf);
return *this;
}
+ template <class MemFn>
+ Class <T>& addPtrFunction (char const* name, MemFn mf)
+ {
+ FUNDOC("Member Pointer Function", name, MemFn)
+ CFunc::CallMemberPtrFunctionHelper <MemFn>::add (L, name, mf);
+ return *this;
+ }
+
+ template <class MemFn>
+ Class <T>& addWPtrFunction (char const* name, MemFn mf)
+ {
+ FUNDOC("Member Weak Pointer Function", name, MemFn)
+ CFunc::CallMemberWPtrFunctionHelper <MemFn>::add (L, name, mf);
+ return *this;
+ }
+
+ template <class MemFn>
+ Class <T>& addRefFunction (char const* name, MemFn mf)
+ {
+ FUNDOC("Member Function RefReturn", name, MemFn)
+ CFunc::CallMemberRefFunctionHelper <MemFn, FuncTraits <MemFn>::isConstMemberFunction>::add (L, name, mf);
+ return *this;
+ }
+
+
//--------------------------------------------------------------------------
/**
Add or replace a member lua_CFunction.
*/
Class <T>& addCFunction (char const* name, int (T::*mfp)(lua_State*))
{
+ DATADOC ("C Function", name, mfp)
typedef int (T::*MFP)(lua_State*);
assert (lua_istable (L, -1));
new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp);
return *this;
}
+ // custom callback - extend existing classes
+ // with non-class member functions (e.g STL iterator)
+ Class <T>& addExtCFunction (char const* name, int (*const fp)(lua_State*))
+ {
+ DATADOC ("Ext C Function", name, fp)
+ assert (lua_istable (L, -1));
+ lua_pushcclosure (L, fp, 0);
+ rawsetfield (L, -3, name); // class table
+ return *this;
+ }
+
//--------------------------------------------------------------------------
/**
Add or replace a const member lua_CFunction.
*/
Class <T>& addCFunction (char const* name, int (T::*mfp)(lua_State*) const)
{
+ DATADOC ("Const C Member Function", name, mfp)
typedef int (T::*MFP)(lua_State*) const;
assert (lua_istable (L, -1));
new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp);
return *this;
}
+ /**
+ Add or replace a static const data
+ */
+ template <typename U>
+ Class <T>& addConst (char const* name, const U val)
+ {
+ DATADOC ("Constant/Enum Member", name, val)
+ assert (lua_istable (L, -1));
+
+ rawgetfield (L, -1, "__propget"); // static
+ new (lua_newuserdata (L, sizeof (val))) U (val);
+ lua_pushcclosure (L, &CFunc::getConst <U>, 1);
+ rawsetfield (L, -2, name);
+ lua_pop (L, 1);
+
+ rawgetfield (L, -1, "__propset"); // static
+ lua_pushstring (L, name);
+ lua_pushcclosure (L, &CFunc::readOnlyError, 1);
+ rawsetfield (L, -2, name);
+ lua_pop (L, 1);
+ return *this;
+ }
+
//--------------------------------------------------------------------------
/**
Add or replace a primary Constructor.
template <class MemFn, class C>
Class <T>& addConstructor ()
{
+ FUNDOC("Constructor", "", MemFn)
lua_pushcclosure (L,
&ctorContainerProxy <typename FuncTraits <MemFn>::Params, C>, 0);
rawsetfield(L, -2, "__call");
template <class MemFn>
Class <T>& addConstructor ()
{
+ FUNDOC("Constructor", "", MemFn)
lua_pushcclosure (L,
&ctorPlacementProxy <typename FuncTraits <MemFn>::Params, T>, 0);
rawsetfield(L, -2, "__call");
return *this;
}
+
+ Class <T>& addVoidConstructor ()
+ {
+ return addConstructor <void (*) ()> ();
+ }
+
+ Class <T>& addEqualCheck ()
+ {
+ PRINTDOC("Member Function", _name << "sameinstance", std::string("bool"), std::string("void (*)(" + type_name <T>() + ")"))
+ assert (lua_istable (L, -1));
+ lua_pushcclosure (L, &CFunc::ClassEqualCheck <T>::f, 0);
+ rawsetfield (L, -3, "sameinstance");
+ return *this;
+ }
+
+ template <class U>
+ Class <T>& addCast (char const* name)
+ {
+ PRINTDOC("Cast", _name << name,
+ type_name< U >(),
+ type_name< U >() << " (" << type_name< T >() << "::*)()")
+
+ assert (lua_istable (L, -1));
+ lua_pushcclosure (L, &CFunc::CastClass <T, U>::f, 0);
+ rawsetfield (L, -3, name); // class table
+
+ lua_pushcclosure (L, &CFunc::CastConstClass <T, U>::f, 0);
+ rawsetfield (L, -4, name); // const table
+ return *this;
+ }
+
+ };
+
+ /** C Array to/from table */
+ template <typename T>
+ class Array : virtual public ClassBase
+ {
+ public:
+ Array (char const* name, Namespace const* parent) : ClassBase (parent->L)
+ {
+#ifdef LUABINDINGDOC
+ _parent = parent;
+ _name = parent->_name + name + ":";
+#endif
+ PRINTDOC ("[C] Array", parent->_name << name,
+ std::string(), type_name <T>() + "*")
+ PRINTDOC ("Ext C Function", _name << "array",
+ std::string(""), "int (*)(lua_State*)")
+ PRINTDOC ("Ext C Function", _name << "get_table",
+ std::string(""), "int (*)(lua_State*)")
+ PRINTDOC ("Ext C Function", _name << "set_table",
+ std::string(""), "int (*)(lua_State*)")
+ PRINTDOC("Member Function", _name << "sameinstance",
+ std::string("bool"), std::string("bool (*)(" + type_name <T>() + "*)"))
+ PRINTDOC("Member Function", _name << "offset",
+ std::string(type_name <T>() + "*"), std::string(type_name <T>() + "* (*)(unsigned int)"))
+
+ m_stackSize = parent->m_stackSize + 3;
+ parent->m_stackSize = 0;
+
+#if 0 // don't allow to duplicates handlers for same array-type
+ assert (lua_istable (L, -1));
+ lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
+ if (lua_istable (L, -1)) {
+ lua_pushnil (L);
+ lua_pushnil (L);
+ return;
+ }
+ lua_pop (L, 1);
+#endif
+
+ assert (lua_istable (L, -1));
+ rawgetfield (L, -1, name);
+
+ if (lua_isnil (L, -1))
+ {
+ lua_pop (L, 1);
+
+ // register array access in global namespace
+ luaL_newmetatable (L, typeid(T).name());
+ lua_pushcclosure (L, CFunc::array_index<T>, 0);
+ lua_setfield(L, -2, "__index");
+ lua_pushcclosure (L, CFunc::array_newindex<T>, 0);
+ lua_setfield(L, -2, "__newindex");
+ lua_pop (L, 1);
+
+ createConstTable (name);
+ lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
+ rawsetfield (L, -2, "__gc");
+
+ createClassTable (name);
+ lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
+ rawsetfield (L, -2, "__gc");
+
+ createStaticTable (name);
+
+ // Map T back to its tables.
+ lua_pushvalue (L, -1);
+ lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ());
+ lua_pushvalue (L, -2);
+ lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
+ lua_pushvalue (L, -3);
+ lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
+
+ assert (lua_istable (L, -1));
+ lua_pushcclosure (L, &CFunc::getArray <T>, 0);
+ rawsetfield (L, -3, "array"); // class table
+
+ lua_pushcclosure (L, &CFunc::getTable <T>, 0);
+ rawsetfield (L, -3, "get_table"); // class table
+
+ lua_pushcclosure (L, &CFunc::setTable <T>, 0);
+ rawsetfield (L, -3, "set_table"); // class table
+
+ lua_pushcclosure (L, &CFunc::ClassEqualCheck <T>::f, 0);
+ rawsetfield (L, -3, "sameinstance");
+
+ lua_pushcclosure (L, &CFunc::offsetArray <T>, 0);
+ rawsetfield (L, -3, "offset"); // class table
+
+ }
+ else
+ {
+ lua_pushnil (L);
+ lua_pushnil (L);
+ }
+ }
+
+ Namespace endArray ()
+ {
+ return Namespace (this);
+ }
+ };
+
+ /** Boost Weak & Shared Pointer Class Wrapper */
+ template <class T>
+ class WSPtrClass : virtual public ClassBase
+ {
+ public:
+ WSPtrClass (char const* name, Namespace const* parent)
+ : ClassBase (parent->L)
+ , weak (name, parent)
+ , shared (name, parent)
+ {
+#ifdef LUABINDINGDOC
+ _parent = parent;
+ _name = parent->_name + name + ":";
+#endif
+ PRINTDOC ("[C] Weak/Shared Pointer Class",
+ parent->_name + name,
+ std::string(), type_name <T>())
+ m_stackSize = weak.m_stackSize;
+ parent->m_stackSize = weak.m_stackSize = shared.m_stackSize = 0;
+ lua_pop (L, 3);
+ }
+
+ WSPtrClass (char const* name, Namespace const* parent, void const* const sharedkey, void const* const weakkey)
+ : ClassBase (parent->L)
+ , weak (name, parent, weakkey)
+ , shared (name, parent, sharedkey)
+ {
+#ifdef LUABINDINGDOC
+ _parent = parent;
+ _name = parent->_name + name + ":";
+#endif
+ m_stackSize = weak.m_stackSize;
+ parent->m_stackSize = weak.m_stackSize = shared.m_stackSize = 0;
+ lua_pop (L, 3);
+ }
+
+ template <class MemFn>
+ WSPtrClass <T>& addFunction (char const* name, MemFn mf)
+ {
+ FUNDOC ("Weak/Shared Pointer Function", name, MemFn)
+ set_weak_class ();
+ CFunc::CallMemberWPtrFunctionHelper <MemFn>::add (L, name, mf);
+
+ set_shared_class ();
+ CFunc::CallMemberPtrFunctionHelper <MemFn>::add (L, name, mf);
+ return *this;
+ }
+
+ template <class MemFn>
+ WSPtrClass <T>& addRefFunction (char const* name, MemFn mf)
+ {
+ FUNDOC ("Weak/Shared Pointer Function RefReturn", name, MemFn)
+ set_weak_class ();
+ CFunc::CallMemberRefWPtrFunctionHelper <MemFn>::add (L, name, mf);
+
+ set_shared_class ();
+ CFunc::CallMemberRefPtrFunctionHelper <MemFn>::add (L, name, mf);
+ return *this;
+ }
+
+ template <class MemFn>
+ WSPtrClass <T>& addConstructor ()
+ {
+ FUNDOC ("Weak/Shared Pointer Constructor", "", MemFn)
+ set_weak_class ();
+ lua_pushcclosure (L,
+ &weak. template ctorPlacementProxy <typename FuncTraits <MemFn>::Params, boost::weak_ptr<T> >, 0);
+ rawsetfield(L, -2, "__call");
+
+ set_shared_class ();
+ lua_pushcclosure (L,
+ &shared. template ctorPlacementProxy <typename FuncTraits <MemFn>::Params, boost::shared_ptr<T> >, 0);
+ rawsetfield(L, -2, "__call");
+ return *this;
+ }
+
+ WSPtrClass <T>& addVoidConstructor ()
+ {
+ return addConstructor <void (*) ()> ();
+ }
+
+ WSPtrClass <T>& addExtCFunction (char const* name, int (*const fp)(lua_State*))
+ {
+ DATADOC ("Weak/Shared Ext C Function", name, fp)
+ set_weak_class ();
+ assert (lua_istable (L, -1));
+ lua_pushcclosure (L, fp, 0);
+ rawsetfield (L, -3, name); // class table
+
+ set_shared_class ();
+ assert (lua_istable (L, -1));
+ lua_pushcclosure (L, fp, 0);
+ rawsetfield (L, -3, name); // class table
+
+ return *this;
+ }
+
+ template <class U>
+ WSPtrClass <T>& addCast (char const* name)
+ {
+ PRINTDOC("Weak/Shared Pointer Cast", _name << name,
+ type_name< U >(),
+ type_name< U >() << " (" << type_name< T >() << "::*)()")
+
+ // TODO weak ptr
+ set_shared_class ();
+ assert (lua_istable (L, -1));
+ lua_pushcclosure (L, &CFunc::CastMemberPtr <T, U>::f, 0);
+ rawsetfield (L, -3, name); // class table
+ return *this;
+ }
+
+ WSPtrClass <T>& addNullCheck ()
+ {
+ PRINTDOC("Weak/Shared Null Check", _name << "isnil", std::string("bool"), std::string("void (*)()"))
+ set_weak_class ();
+ assert (lua_istable (L, -1));
+ lua_pushcclosure (L, &CFunc::WPtrNullCheck <T>::f, 0);
+ rawsetfield (L, -3, "isnil"); // class table
+
+ set_shared_class ();
+ assert (lua_istable (L, -1));
+ lua_pushcclosure (L, &CFunc::PtrNullCheck <T>::f, 0);
+ rawsetfield (L, -3, "isnil"); // class table
+
+ return *this;
+ }
+
+
+ Namespace endClass ()
+ {
+ return Namespace (this);
+ }
+
+ private:
+ void set_weak_class () {
+ lua_pop (L, 3);
+ lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <boost::weak_ptr<T> >::getStaticKey ());
+ rawgetfield (L, -1, "__class");
+ rawgetfield (L, -1, "__const");
+ lua_insert (L, -3);
+ lua_insert (L, -2);
+ }
+ void set_shared_class () {
+ lua_pop (L, 3);
+ lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <boost::shared_ptr<T> >::getStaticKey ());
+ rawgetfield (L, -1, "__class");
+ rawgetfield (L, -1, "__const");
+ lua_insert (L, -3);
+ lua_insert (L, -2);
+ }
+ Class<boost::weak_ptr<T> > weak;
+ Class<boost::shared_ptr<T> > shared;
};
+
private:
//----------------------------------------------------------------------------
/**
explicit Namespace (lua_State* L_)
: L (L_)
, m_stackSize (0)
+#ifdef LUABINDINGDOC
+ , _name ("")
+ , _parent (0)
+#endif
{
lua_getglobal (L, "_G");
++m_stackSize;
}
+#ifdef LUABINDINGDOC
+ std::string _name;
+ Namespace const * _parent;
+#endif
+
//----------------------------------------------------------------------------
/**
Open a namespace for registrations.
Namespace (char const* name, Namespace const* parent)
: L (parent->L)
, m_stackSize (0)
+#ifdef LUABINDINGDOC
+ , _name (parent->_name + name + ":")
+ , _parent (parent)
+#endif
{
m_stackSize = parent->m_stackSize + 1;
parent->m_stackSize = 0;
explicit Namespace (Namespace const* child)
: L (child->L)
, m_stackSize (0)
+#ifdef LUABINDINGDOC
+ , _name (child->_parent ? child->_parent->_name : "")
+ , _parent (child->_parent ? child->_parent->_parent : NULL)
+#endif
{
m_stackSize = child->m_stackSize - 1;
child->m_stackSize = 1;
explicit Namespace (ClassBase const* child)
: L (child->L)
, m_stackSize (0)
+#ifdef LUABINDINGDOC
+ , _name (child->_parent ? child->_parent->_name : "")
+ , _parent (child->_parent ? child->_parent->_parent : NULL)
+#endif
{
m_stackSize = child->m_stackSize - 3;
child->m_stackSize = 3;
{
m_stackSize = other.m_stackSize;
other.m_stackSize = 0;
+#ifdef LUABINDINGDOC
+ _name = other._name;
+ _parent = other._parent;
+#endif
}
//----------------------------------------------------------------------------
return *this;
}
+ template <typename U>
+ Namespace& addConst (char const* name, const U val)
+ {
+ DATADOC ("Constant/Enum", name, val)
+ assert (lua_istable (L, -1));
+ rawgetfield (L, -1, "__propget");
+ new (lua_newuserdata (L, sizeof (val))) U (val);
+ lua_pushcclosure (L, &CFunc::getConst <U>, 1);
+ rawsetfield (L, -2, name);
+ lua_pop (L, 1);
+
+ rawgetfield (L, -1, "__propset");
+ assert (lua_istable (L, -1));
+ lua_pushstring (L, name);
+ lua_pushcclosure (L, &CFunc::readOnlyError, 1);
+ rawsetfield (L, -2, name);
+ lua_pop (L, 1);
+ return *this;
+ }
+
//----------------------------------------------------------------------------
/**
Add or replace a property.
template <class FP>
Namespace& addFunction (char const* name, FP const fp)
{
+ FUNDOC ("Free Function", name, FP)
assert (lua_istable (L, -1));
new (lua_newuserdata (L, sizeof (fp))) FP (fp);
return *this;
}
+ template <class FP>
+ Namespace& addRefFunction (char const* name, FP const fp)
+ {
+ FUNDOC ("Free Function RefReturn", name, FP)
+ assert (lua_istable (L, -1));
+
+ new (lua_newuserdata (L, sizeof (fp))) FP (fp);
+ lua_pushcclosure (L, &CFunc::CallRef <FP>::f, 1);
+ rawsetfield (L, -2, name);
+
+ return *this;
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ Add or replace a array type
+ */
+
+ template <typename T>
+ Namespace registerArray (char const* name)
+ {
+ return Array <T> (name, this).endArray();
+ }
+
+
//----------------------------------------------------------------------------
/**
Add or replace a lua_CFunction.
*/
Namespace& addCFunction (char const* name, int (*const fp)(lua_State*))
{
+ DATADOC ("Free C Function", name, fp)
lua_pushcfunction (L, fp);
rawsetfield (L, -2, name);
return Class <T> (name, this);
}
+ /** weak & shared pointer class */
+ template <class T>
+ WSPtrClass <T> beginWSPtrClass (char const* name)
+ {
+ return WSPtrClass <T> (name, this)
+ .addNullCheck();
+ }
+
+ //----------------------------------------------------------------------------
+
+ template <class K, class V>
+ Class<std::map<K, V> > beginStdMap (char const* name)
+ {
+ typedef std::map<K, V> LT;
+ typedef std::pair<const K, V> T;
+
+ return beginClass<LT> (name)
+ .addVoidConstructor ()
+ .addFunction ("empty", <::empty)
+ .addFunction ("size", <::size)
+ .addFunction ("clear", (void (LT::*)())<::clear)
+ .addFunction ("count", (void (LT::*)())<::count)
+ .addExtCFunction ("add", &CFunc::tableToMap<K, V>)
+ .addExtCFunction ("iter", &CFunc::mapIter<K, V>)
+ .addExtCFunction ("table", &CFunc::mapToTable<K, V>);
+ }
+
+ template <class T>
+ Class<std::set<T> > beginStdSet (char const* name)
+ {
+ typedef std::set<T> LT;
+ return beginClass<LT> (name)
+ .addVoidConstructor ()
+ .addFunction ("clear", (void (LT::*)())<::clear)
+ .addFunction ("empty", <::empty)
+ .addFunction ("size", <::size)
+ .addExtCFunction ("add", &CFunc::tableToSet<T>)
+ .addExtCFunction ("iter", &CFunc::setIter<T>)
+ .addExtCFunction ("table", &CFunc::setToTable<T>);
+ }
+
+ template <unsigned int T>
+ Class<std::bitset<T> > beginStdBitSet (char const* name)
+ {
+ typedef std::bitset<T> BS;
+ return beginClass<BS> (name)
+ .addVoidConstructor ()
+ .addFunction ("reset", (BS& (BS::*)())&BS::reset)
+ .addFunction ("set", (BS& (BS::*)(size_t, bool))&BS::set)
+ .addFunction ("count", &BS::count)
+ .addFunction ("any", &BS::any)
+ .addFunction ("none", &BS::none)
+ .addFunction ("test", &BS::test)
+ .addFunction ("size", &BS::size)
+ .addExtCFunction ("add", &CFunc::tableToBitSet<T>)
+ .addExtCFunction ("table", &CFunc::bitSetToTable<T>);
+ }
+
+ template <class T>
+ Class<std::list<T> > beginConstStdList (char const* name)
+ {
+ typedef std::list<T> LT;
+ return beginClass<LT> (name)
+ .addVoidConstructor ()
+ .addFunction ("empty", <::empty)
+ .addFunction ("size", <::size)
+ .addFunction ("reverse", <::reverse)
+ .addExtCFunction ("iter", &CFunc::listIter<T, LT>)
+ .addExtCFunction ("table", &CFunc::listToTable<T, LT>);
+ }
+
+ template <class T>
+ Class<std::list<T> > beginStdList (char const* name)
+ {
+ typedef std::list<T> LT;
+ return beginConstStdList<T> (name)
+ .addFunction ("unique", (void (LT::*)())<::unique)
+ .addFunction ("push_back", (void (LT::*)(const T&))<::push_back)
+ .addExtCFunction ("add", &CFunc::tableToList<T, LT>);
+ }
+
+ template <class T>
+ Class<std::vector<T> > beginStdVector (char const* name)
+ {
+ typedef std::vector<T> LT;
+ typedef typename std::vector<T>::reference T_REF;
+ typedef typename std::vector<T>::size_type T_SIZE;
+
+ return beginClass<LT> (name)
+ .addVoidConstructor ()
+ .addFunction ("empty", <::empty)
+ .addFunction ("size", <::size)
+ .addFunction ("push_back", (void (LT::*)(const T&))<::push_back)
+ .addFunction ("at", (T_REF (LT::*)(T_SIZE))<::at)
+ .addExtCFunction ("add", &CFunc::tableToList<T, LT>)
+ .addExtCFunction ("iter", &CFunc::listIter<T, LT>)
+ .addExtCFunction ("table", &CFunc::listToTable<T, LT>);
+ }
+
+ //----------------------------------------------------------------------------
+
+ template <class T>
+ Class<boost::shared_ptr<std::list<T> > > beginPtrStdList (char const* name)
+ {
+ typedef std::list<T> LT;
+
+ return beginClass<boost::shared_ptr<LT> > (name)
+ .addVoidConstructor ()
+ .addPtrFunction ("empty", <::empty)
+ .addPtrFunction ("size", <::size)
+ .addPtrFunction ("reverse", <::reverse)
+ .addPtrFunction ("unique", (void (LT::*)())<::unique)
+ .addPtrFunction ("push_back", (void (LT::*)(const T&))<::push_back)
+ .addExtCFunction ("add", &CFunc::ptrTableToList<T, LT>)
+ .addExtCFunction ("iter", &CFunc::ptrListIter<T, LT>)
+ .addExtCFunction ("table", &CFunc::ptrListToTable<T, LT>);
+ }
+
+ template <class T>
+ Class<boost::shared_ptr<std::vector<T> > > beginPtrStdVector (char const* name)
+ {
+ typedef std::vector<T> LT;
+ typedef typename std::vector<T>::reference T_REF;
+ typedef typename std::vector<T>::size_type T_SIZE;
+
+ return beginClass<boost::shared_ptr<LT> > (name)
+ .addVoidConstructor ()
+ .addPtrFunction ("empty", <::empty)
+ .addPtrFunction ("empty", <::empty)
+ .addPtrFunction ("size", <::size)
+ .addPtrFunction ("push_back", (void (LT::*)(const T&))<::push_back)
+ .addPtrFunction ("at", (T_REF (LT::*)(T_SIZE))<::at)
+ .addExtCFunction ("add", &CFunc::ptrTableToList<T, LT>)
+ .addExtCFunction ("iter", &CFunc::ptrListIter<T, LT>)
+ .addExtCFunction ("table", &CFunc::ptrListToTable<T, LT>);
+ }
+
//----------------------------------------------------------------------------
/**
Derive a new class for registrations.
template <class T, class U>
Class <T> deriveClass (char const* name)
{
+ CLASSDOC ("[C] Derived Class", _name << name, type_name <T>(), type_name <U>())
return Class <T> (name, this, ClassInfo <U>::getStaticKey ());
}
+
+ template <class T, class U>
+ WSPtrClass <T> deriveWSPtrClass (char const* name)
+ {
+
+ CLASSDOC ("[C] Derived Class", _name << name, type_name <boost::shared_ptr<T> >(), type_name <boost::shared_ptr<U> >())
+ CLASSDOC ("[C] Derived Class", _name << name, type_name <boost::weak_ptr<T> >(), type_name <boost::weak_ptr<U> >())
+ CLASSDOC ("[C] Derived Pointer Class", _name << name, type_name <T>(), type_name <U>())
+ return WSPtrClass <T> (name, this,
+ ClassInfo <boost::shared_ptr<U> >::getStaticKey (),
+ ClassInfo <boost::weak_ptr<U> >::getStaticKey ())
+ .addNullCheck();
+ }
+
};
//------------------------------------------------------------------------------
{
return Namespace::getGlobalNamespace (L);
}
+
+
+#undef KEYSTA
+#undef KEYEND
+#undef CLASSDOC
+#undef PRINTDOC
+#undef FUNDOC
+#undef DATADOC
+
+/* vim: set et sw=2: */