*/
//==============================================================================
+#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;
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;
+ }
+
//--------------------------------------------------------------------------
/**
*/
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);
// 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
*/
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);
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
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 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 : public ClassBase
+ 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;
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
{
/** Boost Weak & Shared Pointer Class Wrapper */
template <class T>
- class WSPtrClass : public ClassBase
+ class WSPtrClass : virtual public ClassBase
{
public:
WSPtrClass (char const* name, Namespace const* parent)
, 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);
, 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);
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.ctorPlacementProxy <typename FuncTraits <MemFn>::Params, boost::weak_ptr<T> >, 0);
+ &weak. template ctorPlacementProxy <typename FuncTraits <MemFn>::Params, boost::weak_ptr<T> >, 0);
rawsetfield(L, -2, "__call");
set_shared_class ();
lua_pushcclosure (L,
- &shared.ctorPlacementProxy <typename FuncTraits <MemFn>::Params, boost::shared_ptr<T> >, 0);
+ &shared. template ctorPlacementProxy <typename FuncTraits <MemFn>::Params, boost::shared_ptr<T> >, 0);
rawsetfield(L, -2, "__call");
return *this;
}
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);
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));
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);
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
}
//----------------------------------------------------------------------------
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);
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;
+ }
//----------------------------------------------------------------------------
/**
*/
Namespace& addCFunction (char const* name, int (*const fp)(lua_State*))
{
+ DATADOC ("Free C Function", name, fp)
lua_pushcfunction (L, fp);
rawsetfield (L, -2, name);
typedef std::map<K, V> LT;
typedef std::pair<const K, V> T;
+ typedef typename std::map<K, V>::size_type T_SIZE;
+
return beginClass<LT> (name)
.addVoidConstructor ()
.addFunction ("empty", <::empty)
.addFunction ("size", <::size)
.addFunction ("clear", (void (LT::*)())<::clear)
- .addFunction ("count", (void (LT::*)())<::count)
+ .addFunction ("count", (T_SIZE (LT::*)(const K&) const)<::count)
.addExtCFunction ("add", &CFunc::tableToMap<K, V>)
.addExtCFunction ("iter", &CFunc::mapIter<K, V>)
.addExtCFunction ("table", &CFunc::mapToTable<K, V>);
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 ())
return Namespace::getGlobalNamespace (L);
}
+
+#undef KEYSTA
+#undef KEYEND
+#undef CLASSDOC
+#undef PRINTDOC
+#undef FUNDOC
+#undef DATADOC
+
/* vim: set et sw=2: */