1 //------------------------------------------------------------------------------
3 https://github.com/vinniefalco/LuaBridge
5 Copyright 2016, Robin Gareus <robin@gareus.org>
6 Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
7 Copyright 2007, Nathan Reed
9 License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 //==============================================================================
34 #include <type_traits>
41 std::string type_name()
43 typedef typename std::remove_reference<T>::type TR;
44 std::unique_ptr<char, void(*)(void*)> own
46 abi::__cxa_demangle(typeid(TR).name(), nullptr,
50 std::string r = own != nullptr ? own.get() : typeid(TR).name();
51 if (std::is_const<TR>::value)
53 if (std::is_volatile<TR>::value)
55 if (std::is_lvalue_reference<T>::value)
57 else if (std::is_rvalue_reference<T>::value)
64 #ifdef LUADOCOUT // lua
66 #define KEYEND "\"] = "
69 #define KEYEND "\" = "
72 #define CLASSDOC(TYPE, LUANAME, DECL, PARENTDECL) \
73 if (LuaBindingDoc::printBindings ()) { \
74 std::cout << "{ " << KEYSTA << "type" << KEYEND << " \"" << TYPE << "\",\n"; \
75 std::cout << " " << KEYSTA << "lua" << KEYEND << " \"" << LUANAME << "\",\n"; \
76 std::cout << " " << KEYSTA << "decl" << KEYEND << " \"" << DECL << "\",\n"; \
77 std::cout << " " << KEYSTA << "parent" << KEYEND << " \"" << PARENTDECL << "\"\n"; \
78 std::cout << "},\n"; \
81 #define PRINTDOC(TYPE, LUANAME, RETVAL, DECL) \
82 if (LuaBindingDoc::printBindings ()) { \
83 std::cout << "{ " << KEYSTA << "type" << KEYEND << " \"" << TYPE << "\",\n"; \
84 std::cout << " " << KEYSTA << "lua" << KEYEND << " \"" << LUANAME << "\",\n"; \
85 if (!(RETVAL).empty()) { \
86 std::cout << " " << KEYSTA << "ret" << KEYEND << " \"" << (RETVAL) << "\",\n"; \
88 std::cout << " " << KEYSTA << "decl" << KEYEND << " \"" << DECL << "\"\n"; \
89 std::cout << "},\n"; \
92 #define FUNDOC(TYPE, NAME, FUNCTOR) \
93 PRINTDOC(TYPE, _name << NAME, \
94 type_name< typename FuncTraits <FUNCTOR>::ReturnType >(), \
95 type_name< typename FuncTraits <FUNCTOR>::DeclType >())
97 #define DATADOC(TYPE, NAME, FUNCTOR) \
98 PRINTDOC(TYPE, _name << NAME, \
100 type_name< decltype(FUNCTOR) >())\
105 #define CLASSDOC(TYPE, LUANAME, DECL, PARENTDECL)
106 #define PRINTDOC(TYPE, LUANAME, RETVAL, DECL)
107 #define FUNDOC(TYPE, NAME, FUNCTOR)
108 #define DATADOC(TYPE, NAME, FUNCTOR)
112 /** Provides C++ to Lua registration capabilities.
114 This class is not instantiated directly, call `getGlobalNamespace` to start
115 the registration process.
120 Namespace& operator= (Namespace const& other);
123 int mutable m_stackSize;
126 //============================================================================
130 VF: This function looks handy, why aren't we using it?
133 static int luaError (lua_State* L, std::string message)
135 assert (lua_isstring (L, lua_upvalueindex (1)));
138 // Get information on the caller's caller to format the message,
139 // so the error appears to originate from the Lua source.
141 int result = lua_getstack (L, 2, &ar);
144 lua_getinfo (L, "Sl", &ar);
146 if (ar.currentline != -1)
148 // poor mans int to string to avoid <strstrream>.
149 lua_pushnumber (L, ar.currentline);
150 s = s + ":" + lua_tostring (L, -1) + ": ";
157 return luaL_error (L, s.c_str ());
161 //----------------------------------------------------------------------------
165 void pop (int n) const
167 if (m_stackSize >= n && lua_gettop (L) >= n)
174 throw std::logic_error ("invalid stack");
180 Factored base to reduce template instantiations.
185 ClassBase& operator= (ClassBase const& other);
188 friend class Namespace;
191 int mutable m_stackSize;
195 const Namespace* _parent;
199 //--------------------------------------------------------------------------
201 __index metamethod for a class.
203 This implements member functions, data members, and property members.
204 Functions are stored in the metatable and const metatable. Data members
205 and property members are in the __propget table.
207 If the key is not found, the search proceeds up the hierarchy of base
210 static int indexMetaMethod (lua_State* L)
214 assert (lua_isuserdata (L, 1)); // warn on security bypass
215 lua_getmetatable (L, 1); // get metatable for object
218 lua_pushvalue (L, 2); // push key arg2
219 lua_rawget (L, -2); // lookup key in metatable
220 if (lua_iscfunction (L, -1)) // ensure its a cfunction
222 lua_remove (L, -2); // remove metatable
226 else if (lua_isnil (L, -1))
233 throw std::logic_error ("not a cfunction");
236 rawgetfield (L, -1, "__propget"); // get __propget table
237 if (lua_istable (L, -1)) // ensure it is a table
239 lua_pushvalue (L, 2); // push key arg2
240 lua_rawget (L, -2); // lookup key in __propget
241 lua_remove (L, -2); // remove __propget
242 if (lua_iscfunction (L, -1)) // ensure its a cfunction
244 lua_remove (L, -2); // remove metatable
245 lua_pushvalue (L, 1); // push class arg1
250 else if (lua_isnil (L, -1))
258 // We only put cfunctions into __propget.
259 throw std::logic_error ("not a cfunction");
266 // __propget is missing, or not a table.
267 throw std::logic_error ("missing __propget table");
270 // Repeat the lookup in the __parent metafield,
271 // or return nil if the field doesn't exist.
272 rawgetfield (L, -1, "__parent");
273 if (lua_istable (L, -1))
275 // Remove metatable and repeat the search in __parent.
278 else if (lua_isnil (L, -1))
287 throw std::logic_error ("__parent is not a table");
294 //--------------------------------------------------------------------------
296 __newindex metamethod for classes.
298 This supports writable variables and properties on class objects. The
299 corresponding object is passed in the first parameter to the set function.
301 static int newindexMetaMethod (lua_State* L)
305 lua_getmetatable (L, 1);
310 rawgetfield (L, -1, "__propset");
311 if (!lua_isnil (L, -1))
313 lua_pushvalue (L, 2);
315 if (!lua_isnil (L, -1))
317 // found it, call the setFunction.
318 assert (lua_isfunction (L, -1));
319 lua_pushvalue (L, 1);
320 lua_pushvalue (L, 3);
329 // Repeat the lookup in the __parent metafield.
330 rawgetfield (L, -1, "__parent");
331 if (lua_isnil (L, -1))
333 // Either the property or __parent must exist.
334 result = luaL_error (L,
335 "no member named '%s'", lua_tostring (L, 2));
343 //--------------------------------------------------------------------------
345 Create the const table.
347 void createConstTable (char const* name)
350 lua_pushvalue (L, -1);
351 lua_setmetatable (L, -2);
352 lua_pushboolean (L, 1);
353 lua_rawsetp (L, -2, getIdentityKey ());
354 lua_pushstring (L, (std::string ("const ") + name).c_str ());
355 rawsetfield (L, -2, "__type");
356 lua_pushcfunction (L, &indexMetaMethod);
357 rawsetfield (L, -2, "__index");
358 lua_pushcfunction (L, &newindexMetaMethod);
359 rawsetfield (L, -2, "__newindex");
361 rawsetfield (L, -2, "__propget");
363 if (Security::hideMetatables ())
366 rawsetfield (L, -2, "__metatable");
370 //--------------------------------------------------------------------------
372 Create the class table.
374 The Lua stack should have the const table on top.
376 void createClassTable (char const* name)
379 lua_pushvalue (L, -1);
380 lua_setmetatable (L, -2);
381 lua_pushboolean (L, 1);
382 lua_rawsetp (L, -2, getIdentityKey ());
383 lua_pushstring (L, name);
384 rawsetfield (L, -2, "__type");
385 lua_pushcfunction (L, &indexMetaMethod);
386 rawsetfield (L, -2, "__index");
387 lua_pushcfunction (L, &newindexMetaMethod);
388 rawsetfield (L, -2, "__newindex");
390 rawsetfield (L, -2, "__propget");
392 rawsetfield (L, -2, "__propset");
394 lua_pushvalue (L, -2);
395 rawsetfield (L, -2, "__const"); // point to const table
397 lua_pushvalue (L, -1);
398 rawsetfield (L, -3, "__class"); // point const table to class table
400 if (Security::hideMetatables ())
403 rawsetfield (L, -2, "__metatable");
407 //--------------------------------------------------------------------------
409 Create the static table.
411 The Lua stack should have:
414 -3 enclosing namespace
416 void createStaticTable (char const* name)
420 lua_pushvalue (L, -1);
421 lua_setmetatable (L, -3);
423 rawsetfield (L, -5, name);
426 lua_pushlightuserdata (L, this);
427 lua_pushcclosure (L, &tostringMetaMethod, 1);
428 rawsetfield (L, -2, "__tostring");
430 lua_pushcfunction (L, &CFunc::indexMetaMethod);
431 rawsetfield (L, -2, "__index");
432 lua_pushcfunction (L, &CFunc::newindexMetaMethod);
433 rawsetfield (L, -2, "__newindex");
435 rawsetfield (L, -2, "__propget");
437 rawsetfield (L, -2, "__propset");
439 lua_pushvalue (L, -2);
440 rawsetfield (L, -2, "__class"); // point to class table
442 if (Security::hideMetatables ())
445 rawsetfield (L, -2, "__metatable");
449 //==========================================================================
451 lua_CFunction to construct a class object wrapped in a container.
453 template <class Params, class C>
454 static int ctorContainerProxy (lua_State* L)
456 typedef typename ContainerTraits <C>::Type T;
457 ArgList <Params, 2> args (L);
458 T* const p = Constructor <T, Params>::call (args);
459 UserdataSharedHelper <C, false>::push (L, p);
463 //--------------------------------------------------------------------------
465 lua_CFunction to construct a class object in-place in the userdata.
467 template <class Params, class T>
468 static int ctorPlacementProxy (lua_State* L)
470 ArgList <Params, 2> args (L);
471 Constructor <T, Params>::call (UserdataValue <T>::place (L), args);
475 //--------------------------------------------------------------------------
479 void pop (int n) const
481 if (m_stackSize >= n && lua_gettop (L) >= n)
488 throw std::logic_error ("invalid stack");
493 //--------------------------------------------------------------------------
494 explicit ClassBase (lua_State* L_)
500 //--------------------------------------------------------------------------
504 ClassBase (ClassBase const& other)
508 , _name (other._name)
509 , _parent (other._parent)
512 m_stackSize = other.m_stackSize;
513 other.m_stackSize = 0;
522 //============================================================================
526 //============================================================================
528 Provides a class registration in a lua_State.
530 After contstruction the Lua stack holds these objects:
534 -4 (enclosing namespace)
537 class Class : virtual public ClassBase
540 //==========================================================================
542 Register a new class or add to an existing class registration.
544 Class (char const* name, Namespace const* parent) : ClassBase (parent->L)
548 _name = parent->_name + name + ":";
550 PRINTDOC ("[C] Class", parent->_name << name, std::string(), type_name <T>())
551 m_stackSize = parent->m_stackSize + 3;
552 parent->m_stackSize = 0;
554 assert (lua_istable (L, -1));
555 rawgetfield (L, -1, name);
557 if (lua_isnil (L, -1))
561 createConstTable (name);
562 lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
563 rawsetfield (L, -2, "__gc");
565 createClassTable (name);
566 lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
567 rawsetfield (L, -2, "__gc");
569 createStaticTable (name);
571 // Map T back to its tables.
572 lua_pushvalue (L, -1);
573 lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ());
574 lua_pushvalue (L, -2);
575 lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
576 lua_pushvalue (L, -3);
577 lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
582 lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ());
583 rawgetfield (L, -1, "__class");
584 rawgetfield (L, -1, "__const");
586 // Reverse the top 3 stack elements
592 //==========================================================================
596 Class (char const* name, Namespace const* parent, void const* const staticKey)
597 : ClassBase (parent->L)
601 _name = parent->_name + name + ":";
603 m_stackSize = parent->m_stackSize + 3;
604 parent->m_stackSize = 0;
606 assert (lua_istable (L, -1));
608 createConstTable (name);
609 lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
610 rawsetfield (L, -2, "__gc");
612 createClassTable (name);
613 lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
614 rawsetfield (L, -2, "__gc");
616 createStaticTable (name);
618 lua_rawgetp (L, LUA_REGISTRYINDEX, staticKey);
619 assert (lua_istable (L, -1));
620 rawgetfield (L, -1, "__class");
621 assert (lua_istable (L, -1));
622 rawgetfield (L, -1, "__const");
623 assert (lua_istable (L, -1));
625 rawsetfield (L, -6, "__parent");
626 rawsetfield (L, -4, "__parent");
627 rawsetfield (L, -2, "__parent");
629 lua_pushvalue (L, -1);
630 lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ());
631 lua_pushvalue (L, -2);
632 lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
633 lua_pushvalue (L, -3);
634 lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
637 //--------------------------------------------------------------------------
639 Continue registration in the enclosing namespace.
641 Namespace endClass ()
643 return Namespace (this);
646 //--------------------------------------------------------------------------
648 Add or replace a static data member.
651 Class <T>& addStaticData (char const* name, U* pu, bool isWritable = true)
653 DATADOC ("Static Data Member", name, pu)
654 assert (lua_istable (L, -1));
656 rawgetfield (L, -1, "__propget");
657 assert (lua_istable (L, -1));
658 lua_pushlightuserdata (L, pu);
659 lua_pushcclosure (L, &CFunc::getVariable <U>, 1);
660 rawsetfield (L, -2, name);
663 rawgetfield (L, -1, "__propset");
664 assert (lua_istable (L, -1));
667 lua_pushlightuserdata (L, pu);
668 lua_pushcclosure (L, &CFunc::setVariable <U>, 1);
672 lua_pushstring (L, name);
673 lua_pushcclosure (L, &CFunc::readOnlyError, 1);
675 rawsetfield (L, -2, name);
681 //--------------------------------------------------------------------------
684 Add or replace a static property member.
686 If the set function is null, the property is read-only.
689 Class <T>& addStaticProperty (char const* name, U (*get)(), void (*set)(U) = 0)
691 typedef U (*get_t)();
692 typedef void (*set_t)(U);
694 assert (lua_istable (L, -1));
696 rawgetfield (L, -1, "__propget");
697 assert (lua_istable (L, -1));
698 new (lua_newuserdata (L, sizeof (get))) get_t (get);
699 lua_pushcclosure (L, &CFunc::Call <U (*) (void)>::f, 1);
700 rawsetfield (L, -2, name);
703 rawgetfield (L, -1, "__propset");
704 assert (lua_istable (L, -1));
707 new (lua_newuserdata (L, sizeof (set))) set_t (set);
708 lua_pushcclosure (L, &CFunc::Call <void (*) (U)>::f, 1);
712 lua_pushstring (L, name);
713 lua_pushcclosure (L, &CFunc::readOnlyError, 1);
715 rawsetfield (L, -2, name);
722 //--------------------------------------------------------------------------
724 Add or replace a static member function.
727 Class <T>& addStaticFunction (char const* name, FP const fp)
729 FUNDOC ("Static Function", name, FP)
730 new (lua_newuserdata (L, sizeof (fp))) FP (fp);
731 lua_pushcclosure (L, &CFunc::Call <FP>::f, 1);
732 rawsetfield (L, -2, name);
737 //--------------------------------------------------------------------------
739 Add or replace a lua_CFunction.
741 Class <T>& addStaticCFunction (char const* name, int (*const fp)(lua_State*))
743 DATADOC ("Static C Function", name, fp)
744 lua_pushcfunction (L, fp);
745 rawsetfield (L, -2, name);
749 //--------------------------------------------------------------------------
751 Add or replace a data member.
754 Class <T>& addData (char const* name, const U T::* mp, bool isWritable = true)
756 DATADOC ("Data Member", name, mp)
757 typedef const U T::*mp_t;
759 // Add to __propget in class and const tables.
761 rawgetfield (L, -2, "__propget");
762 rawgetfield (L, -4, "__propget");
763 new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
764 lua_pushcclosure (L, &CFunc::getProperty <T,U>, 1);
765 lua_pushvalue (L, -1);
766 rawsetfield (L, -4, name);
767 rawsetfield (L, -2, name);
773 // Add to __propset in class table.
774 rawgetfield (L, -2, "__propset");
775 assert (lua_istable (L, -1));
776 new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
777 lua_pushcclosure (L, &CFunc::setProperty <T,U>, 1);
778 rawsetfield (L, -2, name);
786 //--------------------------------------------------------------------------
788 Add or replace a property member.
790 template <class TG, class TS>
791 Class <T>& addProperty (char const* name, TG (T::* get) () const, void (T::* set) (TS))
793 // Add to __propget in class and const tables.
795 rawgetfield (L, -2, "__propget");
796 rawgetfield (L, -4, "__propget");
797 typedef TG (T::*get_t) () const;
798 new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
799 lua_pushcclosure (L, &CFunc::CallConstMember <get_t>::f, 1);
800 lua_pushvalue (L, -1);
801 rawsetfield (L, -4, name);
802 rawsetfield (L, -2, name);
807 // Add to __propset in class table.
808 rawgetfield (L, -2, "__propset");
809 assert (lua_istable (L, -1));
810 typedef void (T::* set_t) (TS);
811 new (lua_newuserdata (L, sizeof (set_t))) set_t (set);
812 lua_pushcclosure (L, &CFunc::CallMember <set_t>::f, 1);
813 rawsetfield (L, -2, name);
822 Class <T>& addProperty (char const* name, TG (T::* get) () const)
824 // Add to __propget in class and const tables.
825 rawgetfield (L, -2, "__propget");
826 rawgetfield (L, -4, "__propget");
827 typedef TG (T::*get_t) () const;
828 new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
829 lua_pushcclosure (L, &CFunc::CallConstMember <get_t>::f, 1);
830 lua_pushvalue (L, -1);
831 rawsetfield (L, -4, name);
832 rawsetfield (L, -2, name);
838 //--------------------------------------------------------------------------
840 Add or replace a property member, by proxy.
842 When a class is closed for modification and does not provide (or cannot
843 provide) the function signatures necessary to implement get or set for
844 a property, this will allow non-member functions act as proxies.
846 Both the get and the set functions require a T const* and T* in the first
847 argument respectively.
849 template <class TG, class TS>
850 Class <T>& addProperty (char const* name, TG (*get) (T const*), void (*set) (T*, TS))
852 // Add to __propget in class and const tables.
854 rawgetfield (L, -2, "__propget");
855 rawgetfield (L, -4, "__propget");
856 typedef TG (*get_t) (T const*);
857 new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
858 lua_pushcclosure (L, &CFunc::Call <get_t>::f, 1);
859 lua_pushvalue (L, -1);
860 rawsetfield (L, -4, name);
861 rawsetfield (L, -2, name);
867 // Add to __propset in class table.
868 rawgetfield (L, -2, "__propset");
869 assert (lua_istable (L, -1));
870 typedef void (*set_t) (T*, TS);
871 new (lua_newuserdata (L, sizeof (set_t))) set_t (set);
872 lua_pushcclosure (L, &CFunc::Call <set_t>::f, 1);
873 rawsetfield (L, -2, name);
881 template <class TG, class TS>
882 Class <T>& addProperty (char const* name, TG (*get) (T const*))
884 // Add to __propget in class and const tables.
885 rawgetfield (L, -2, "__propget");
886 rawgetfield (L, -4, "__propget");
887 typedef TG (*get_t) (T const*);
888 new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
889 lua_pushcclosure (L, &CFunc::Call <get_t>::f, 1);
890 lua_pushvalue (L, -1);
891 rawsetfield (L, -4, name);
892 rawsetfield (L, -2, name);
898 //--------------------------------------------------------------------------
900 Add or replace a member function.
902 template <class MemFn>
903 Class <T>& addFunction (char const* name, MemFn mf)
905 FUNDOC("Member Function", name, MemFn)
906 CFunc::CallMemberFunctionHelper <MemFn, FuncTraits <MemFn>::isConstMemberFunction>::add (L, name, mf);
910 template <class MemFn>
911 Class <T>& addPtrFunction (char const* name, MemFn mf)
913 FUNDOC("Member Pointer Function", name, MemFn)
914 CFunc::CallMemberPtrFunctionHelper <MemFn>::add (L, name, mf);
918 template <class MemFn>
919 Class <T>& addWPtrFunction (char const* name, MemFn mf)
921 FUNDOC("Member Weak Pointer Function", name, MemFn)
922 CFunc::CallMemberWPtrFunctionHelper <MemFn>::add (L, name, mf);
926 template <class MemFn>
927 Class <T>& addRefFunction (char const* name, MemFn mf)
929 FUNDOC("Member Function RefReturn", name, MemFn)
930 CFunc::CallMemberRefFunctionHelper <MemFn, FuncTraits <MemFn>::isConstMemberFunction>::add (L, name, mf);
935 //--------------------------------------------------------------------------
937 Add or replace a member lua_CFunction.
939 Class <T>& addCFunction (char const* name, int (T::*mfp)(lua_State*))
941 DATADOC ("C Function", name, mfp)
942 typedef int (T::*MFP)(lua_State*);
943 assert (lua_istable (L, -1));
944 new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp);
945 lua_pushcclosure (L, &CFunc::CallMemberCFunction <T>::f, 1);
946 rawsetfield (L, -3, name); // class table
951 // custom callback - extend existing classes
952 // with non-class member functions (e.g STL iterator)
953 Class <T>& addExtCFunction (char const* name, int (*const fp)(lua_State*))
955 DATADOC ("Ext C Function", name, fp)
956 assert (lua_istable (L, -1));
957 lua_pushcclosure (L, fp, 0);
958 rawsetfield (L, -3, name); // class table
962 //--------------------------------------------------------------------------
964 Add or replace a const member lua_CFunction.
966 Class <T>& addCFunction (char const* name, int (T::*mfp)(lua_State*) const)
968 DATADOC ("Const C Member Function", name, mfp)
969 typedef int (T::*MFP)(lua_State*) const;
970 assert (lua_istable (L, -1));
971 new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp);
972 lua_pushcclosure (L, &CFunc::CallConstMemberCFunction <T>::f, 1);
973 lua_pushvalue (L, -1);
974 rawsetfield (L, -5, name); // const table
975 rawsetfield (L, -3, name); // class table
981 Add or replace a static const data
983 template <typename U>
984 Class <T>& addConst (char const* name, const U val)
986 DATADOC ("Constant/Enum Member", name, val)
987 assert (lua_istable (L, -1));
989 rawgetfield (L, -1, "__propget"); // static
990 new (lua_newuserdata (L, sizeof (val))) U (val);
991 lua_pushcclosure (L, &CFunc::getConst <U>, 1);
992 rawsetfield (L, -2, name);
995 rawgetfield (L, -1, "__propset"); // static
996 lua_pushstring (L, name);
997 lua_pushcclosure (L, &CFunc::readOnlyError, 1);
998 rawsetfield (L, -2, name);
1003 //--------------------------------------------------------------------------
1005 Add or replace a primary Constructor.
1007 The primary Constructor is invoked when calling the class type table
1010 The template parameter should be a function pointer type that matches
1011 the desired Constructor (since you can't take the address of a Constructor
1012 and pass it as an argument).
1014 template <class MemFn, class C>
1015 Class <T>& addConstructor ()
1017 FUNDOC("Constructor", "", MemFn)
1018 lua_pushcclosure (L,
1019 &ctorContainerProxy <typename FuncTraits <MemFn>::Params, C>, 0);
1020 rawsetfield(L, -2, "__call");
1025 template <class MemFn>
1026 Class <T>& addConstructor ()
1028 FUNDOC("Constructor", "", MemFn)
1029 lua_pushcclosure (L,
1030 &ctorPlacementProxy <typename FuncTraits <MemFn>::Params, T>, 0);
1031 rawsetfield(L, -2, "__call");
1036 Class <T>& addVoidConstructor ()
1038 return addConstructor <void (*) ()> ();
1043 /** C Array to/from table */
1044 template <typename T>
1045 class Array : virtual public ClassBase
1048 Array (char const* name, Namespace const* parent) : ClassBase (parent->L)
1050 #ifdef LUABINDINGDOC
1052 _name = parent->_name + name + ".";
1054 PRINTDOC ("[C] Array", parent->_name << name, std::string(), type_name <T>())
1055 m_stackSize = parent->m_stackSize + 3;
1056 parent->m_stackSize = 0;
1058 #if 0 // don't allow to duplicates handlers for same array-type
1059 assert (lua_istable (L, -1));
1060 lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
1061 if (lua_istable (L, -1)) {
1069 assert (lua_istable (L, -1));
1070 rawgetfield (L, -1, name);
1072 if (lua_isnil (L, -1))
1076 // register array access in global namespace
1077 luaL_newmetatable (L, typeid(T).name());
1078 lua_pushcclosure (L, CFunc::array_index<T>, 0);
1079 lua_setfield(L, -2, "__index");
1080 lua_pushcclosure (L, CFunc::array_newindex<T>, 0);
1081 lua_setfield(L, -2, "__newindex");
1084 createConstTable (name);
1085 lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
1086 rawsetfield (L, -2, "__gc");
1088 createClassTable (name);
1089 lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
1090 rawsetfield (L, -2, "__gc");
1092 createStaticTable (name);
1094 // Map T back to its tables.
1095 lua_pushvalue (L, -1);
1096 lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ());
1097 lua_pushvalue (L, -2);
1098 lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
1099 lua_pushvalue (L, -3);
1100 lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
1102 assert (lua_istable (L, -1));
1103 lua_pushcclosure (L, &CFunc::getArray <T>, 0);
1104 rawsetfield (L, -3, "array"); // class table
1106 lua_pushcclosure (L, &CFunc::getTable <T>, 0);
1107 rawsetfield (L, -3, "get_table"); // class table
1109 lua_pushcclosure (L, &CFunc::setTable <T>, 0);
1110 rawsetfield (L, -3, "set_table"); // class table
1119 Namespace endArray ()
1121 return Namespace (this);
1125 /** Boost Weak & Shared Pointer Class Wrapper */
1127 class WSPtrClass : virtual public ClassBase
1130 WSPtrClass (char const* name, Namespace const* parent)
1131 : ClassBase (parent->L)
1132 , weak (name, parent)
1133 , shared (name, parent)
1135 #ifdef LUABINDINGDOC
1137 _name = parent->_name + name + ":";
1139 PRINTDOC ("[C] Weak/Shared Pointer Class",
1140 parent->_name + name,
1141 std::string(), type_name <T>())
1142 m_stackSize = weak.m_stackSize;
1143 parent->m_stackSize = weak.m_stackSize = shared.m_stackSize = 0;
1147 WSPtrClass (char const* name, Namespace const* parent, void const* const sharedkey, void const* const weakkey)
1148 : ClassBase (parent->L)
1149 , weak (name, parent, weakkey)
1150 , shared (name, parent, sharedkey)
1152 #ifdef LUABINDINGDOC
1154 _name = parent->_name + name + ":";
1156 m_stackSize = weak.m_stackSize;
1157 parent->m_stackSize = weak.m_stackSize = shared.m_stackSize = 0;
1161 template <class MemFn>
1162 WSPtrClass <T>& addFunction (char const* name, MemFn mf)
1164 FUNDOC ("Weak/Shared Pointer Function", name, MemFn)
1166 CFunc::CallMemberWPtrFunctionHelper <MemFn>::add (L, name, mf);
1168 set_shared_class ();
1169 CFunc::CallMemberPtrFunctionHelper <MemFn>::add (L, name, mf);
1173 template <class MemFn>
1174 WSPtrClass <T>& addRefFunction (char const* name, MemFn mf)
1176 FUNDOC ("Weak/Shared Pointer Function RefReturn", name, MemFn)
1178 CFunc::CallMemberRefWPtrFunctionHelper <MemFn>::add (L, name, mf);
1180 set_shared_class ();
1181 CFunc::CallMemberRefPtrFunctionHelper <MemFn>::add (L, name, mf);
1185 template <class MemFn>
1186 WSPtrClass <T>& addConstructor ()
1188 FUNDOC ("Weak/Shared Pointer Constructor", "", MemFn)
1190 lua_pushcclosure (L,
1191 &weak. template ctorPlacementProxy <typename FuncTraits <MemFn>::Params, boost::weak_ptr<T> >, 0);
1192 rawsetfield(L, -2, "__call");
1194 set_shared_class ();
1195 lua_pushcclosure (L,
1196 &shared. template ctorPlacementProxy <typename FuncTraits <MemFn>::Params, boost::shared_ptr<T> >, 0);
1197 rawsetfield(L, -2, "__call");
1201 WSPtrClass <T>& addVoidConstructor ()
1203 return addConstructor <void (*) ()> ();
1206 WSPtrClass <T>& addExtCFunction (char const* name, int (*const fp)(lua_State*))
1208 DATADOC ("Weak/Shared Ext C Function", name, fp)
1210 assert (lua_istable (L, -1));
1211 lua_pushcclosure (L, fp, 0);
1212 rawsetfield (L, -3, name); // class table
1214 set_shared_class ();
1215 assert (lua_istable (L, -1));
1216 lua_pushcclosure (L, fp, 0);
1217 rawsetfield (L, -3, name); // class table
1223 WSPtrClass <T>& addCast (char const* name)
1225 PRINTDOC("Weak/Shared Pointer Cast", _name << name,
1227 type_name< U >() << " (" << type_name< T >() << "::*)()")
1230 set_shared_class ();
1231 assert (lua_istable (L, -1));
1232 lua_pushcclosure (L, &CFunc::CastMemberPtr <T, U>::f, 0);
1233 rawsetfield (L, -3, name); // class table
1237 WSPtrClass <T>& addNullCheck ()
1239 PRINTDOC("Weak/Shared Null Check", _name << "isnil", std::string("bool"), std::string("void (*)()"))
1241 assert (lua_istable (L, -1));
1242 lua_pushcclosure (L, &CFunc::WPtrNullCheck <T>::f, 0);
1243 rawsetfield (L, -3, "isnil"); // class table
1245 set_shared_class ();
1246 assert (lua_istable (L, -1));
1247 lua_pushcclosure (L, &CFunc::PtrNullCheck <T>::f, 0);
1248 rawsetfield (L, -3, "isnil"); // class table
1254 Namespace endClass ()
1256 return Namespace (this);
1260 void set_weak_class () {
1262 lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <boost::weak_ptr<T> >::getStaticKey ());
1263 rawgetfield (L, -1, "__class");
1264 rawgetfield (L, -1, "__const");
1268 void set_shared_class () {
1270 lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <boost::shared_ptr<T> >::getStaticKey ());
1271 rawgetfield (L, -1, "__class");
1272 rawgetfield (L, -1, "__const");
1276 Class<boost::weak_ptr<T> > weak;
1277 Class<boost::shared_ptr<T> > shared;
1282 //----------------------------------------------------------------------------
1284 Open the global namespace for registrations.
1286 explicit Namespace (lua_State* L_)
1289 #ifdef LUABINDINGDOC
1294 lua_getglobal (L, "_G");
1298 #ifdef LUABINDINGDOC
1300 Namespace const * _parent;
1303 //----------------------------------------------------------------------------
1305 Open a namespace for registrations.
1307 The namespace is created if it doesn't already exist.
1308 The parent namespace is at the top of the Lua stack.
1310 Namespace (char const* name, Namespace const* parent)
1313 #ifdef LUABINDINGDOC
1314 , _name (parent->_name + name + ":")
1318 m_stackSize = parent->m_stackSize + 1;
1319 parent->m_stackSize = 0;
1321 assert (lua_istable (L, -1));
1322 rawgetfield (L, -1, name);
1323 if (lua_isnil (L, -1))
1328 lua_pushvalue (L, -1);
1329 lua_setmetatable (L, -2);
1330 lua_pushcfunction (L, &CFunc::indexMetaMethod);
1331 rawsetfield (L, -2, "__index");
1332 lua_pushcfunction (L, &CFunc::newindexMetaMethod);
1333 rawsetfield (L, -2, "__newindex");
1335 rawsetfield (L, -2, "__propget");
1337 rawsetfield (L, -2, "__propset");
1338 lua_pushvalue (L, -1);
1339 rawsetfield (L, -3, name);
1341 lua_pushcfunction (L, &tostringMetaMethod);
1342 rawsetfield (L, -2, "__tostring");
1347 //----------------------------------------------------------------------------
1349 Creates a continued registration from a child namespace.
1351 explicit Namespace (Namespace const* child)
1354 #ifdef LUABINDINGDOC
1355 , _name (child->_parent->_name)
1356 , _parent (child->_parent)
1359 m_stackSize = child->m_stackSize - 1;
1360 child->m_stackSize = 1;
1363 // It is not necessary or valid to call
1364 // endNamespace() for the global namespace!
1366 assert (m_stackSize != 0);
1369 //----------------------------------------------------------------------------
1371 Creates a continued registration from a child class.
1373 explicit Namespace (ClassBase const* child)
1376 #ifdef LUABINDINGDOC
1377 , _name (child->_parent ? child->_parent->_name : "")
1378 , _parent (child->_parent ? child->_parent->_parent : NULL)
1381 m_stackSize = child->m_stackSize - 3;
1382 child->m_stackSize = 3;
1387 //----------------------------------------------------------------------------
1391 Ownership of the stack is transferred to the new object. This happens
1392 when the compiler emits temporaries to hold these objects while chaining
1393 registrations across namespaces.
1395 Namespace (Namespace const& other) : L (other.L)
1397 m_stackSize = other.m_stackSize;
1398 other.m_stackSize = 0;
1399 #ifdef LUABINDINGDOC
1400 _name = other._name;
1401 _parent = other._parent;
1405 //----------------------------------------------------------------------------
1407 Closes this namespace registration.
1414 //----------------------------------------------------------------------------
1416 Open the global namespace.
1418 static Namespace getGlobalNamespace (lua_State* L)
1420 return Namespace (L);
1423 //----------------------------------------------------------------------------
1425 Open a new or existing namespace for registrations.
1427 Namespace beginNamespace (char const* name)
1429 return Namespace (name, this);
1432 //----------------------------------------------------------------------------
1434 Continue namespace registration in the parent.
1436 Do not use this on the global namespace.
1438 Namespace endNamespace ()
1440 return Namespace (this);
1443 //----------------------------------------------------------------------------
1445 Add or replace a variable.
1448 Namespace& addVariable (char const* name, T* pt, bool isWritable = true)
1450 assert (lua_istable (L, -1));
1452 rawgetfield (L, -1, "__propget");
1453 assert (lua_istable (L, -1));
1454 lua_pushlightuserdata (L, pt);
1455 lua_pushcclosure (L, &CFunc::getVariable <T>, 1);
1456 rawsetfield (L, -2, name);
1459 rawgetfield (L, -1, "__propset");
1460 assert (lua_istable (L, -1));
1463 lua_pushlightuserdata (L, pt);
1464 lua_pushcclosure (L, &CFunc::setVariable <T>, 1);
1468 lua_pushstring (L, name);
1469 lua_pushcclosure (L, &CFunc::readOnlyError, 1);
1471 rawsetfield (L, -2, name);
1477 template <typename U>
1478 Namespace& addConst (char const* name, const U val)
1480 DATADOC ("Constant/Enum", name, val)
1481 assert (lua_istable (L, -1));
1482 rawgetfield (L, -1, "__propget");
1483 new (lua_newuserdata (L, sizeof (val))) U (val);
1484 lua_pushcclosure (L, &CFunc::getConst <U>, 1);
1485 rawsetfield (L, -2, name);
1488 rawgetfield (L, -1, "__propset");
1489 assert (lua_istable (L, -1));
1490 lua_pushstring (L, name);
1491 lua_pushcclosure (L, &CFunc::readOnlyError, 1);
1492 rawsetfield (L, -2, name);
1497 //----------------------------------------------------------------------------
1499 Add or replace a property.
1501 If the set function is omitted or null, the property is read-only.
1503 template <class TG, class TS>
1504 Namespace& addProperty (char const* name, TG (*get) (), void (*set)(TS) = 0)
1506 assert (lua_istable (L, -1));
1508 rawgetfield (L, -1, "__propget");
1509 assert (lua_istable (L, -1));
1510 typedef TG (*get_t) ();
1511 new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
1512 lua_pushcclosure (L, &CFunc::Call <TG (*) (void)>::f, 1);
1513 rawsetfield (L, -2, name);
1516 rawgetfield (L, -1, "__propset");
1517 assert (lua_istable (L, -1));
1520 typedef void (*set_t) (TS);
1521 new (lua_newuserdata (L, sizeof (set_t))) set_t (set);
1522 lua_pushcclosure (L, &CFunc::Call <void (*) (TS)>::f, 1);
1526 lua_pushstring (L, name);
1527 lua_pushcclosure (L, &CFunc::readOnlyError, 1);
1529 rawsetfield (L, -2, name);
1535 //----------------------------------------------------------------------------
1537 Add or replace a free function.
1540 Namespace& addFunction (char const* name, FP const fp)
1542 FUNDOC ("Free Function", name, FP)
1543 assert (lua_istable (L, -1));
1545 new (lua_newuserdata (L, sizeof (fp))) FP (fp);
1546 lua_pushcclosure (L, &CFunc::Call <FP>::f, 1);
1547 rawsetfield (L, -2, name);
1553 Namespace& addRefFunction (char const* name, FP const fp)
1555 FUNDOC ("Free Function RefReturn", name, FP)
1556 assert (lua_istable (L, -1));
1558 new (lua_newuserdata (L, sizeof (fp))) FP (fp);
1559 lua_pushcclosure (L, &CFunc::CallRef <FP>::f, 1);
1560 rawsetfield (L, -2, name);
1565 //----------------------------------------------------------------------------
1567 Add or replace a array type
1570 template <typename T>
1571 Namespace registerArray (char const* name)
1573 return Array <T> (name, this).endArray();
1577 //----------------------------------------------------------------------------
1579 Add or replace a lua_CFunction.
1581 Namespace& addCFunction (char const* name, int (*const fp)(lua_State*))
1583 lua_pushcfunction (L, fp);
1584 rawsetfield (L, -2, name);
1589 //----------------------------------------------------------------------------
1591 Open a new or existing class for registrations.
1594 Class <T> beginClass (char const* name)
1596 return Class <T> (name, this);
1599 /** weak & shared pointer class */
1601 WSPtrClass <T> beginWSPtrClass (char const* name)
1603 return WSPtrClass <T> (name, this)
1607 //----------------------------------------------------------------------------
1609 template <class K, class V>
1610 Class<std::map<K, V> > beginStdMap (char const* name)
1612 typedef std::map<K, V> LT;
1613 typedef std::pair<const K, V> T;
1615 return beginClass<LT> (name)
1616 .addVoidConstructor ()
1617 .addFunction ("empty", <::empty)
1618 .addFunction ("size", <::size)
1619 .addFunction ("clear", (void (LT::*)())<::clear)
1620 .addFunction ("count", (void (LT::*)())<::count)
1621 .addExtCFunction ("add", &CFunc::tableToMap<K, V>)
1622 .addExtCFunction ("iter", &CFunc::mapIter<K, V>)
1623 .addExtCFunction ("table", &CFunc::mapToTable<K, V>);
1627 Class<std::set<T> > beginStdSet (char const* name)
1629 typedef std::set<T> LT;
1630 return beginClass<LT> (name)
1631 .addVoidConstructor ()
1632 .addFunction ("clear", (void (LT::*)())<::clear)
1633 .addFunction ("empty", <::empty)
1634 .addFunction ("size", <::size)
1635 .addExtCFunction ("add", &CFunc::tableToSet<T>)
1636 .addExtCFunction ("iter", &CFunc::setIter<T>)
1637 .addExtCFunction ("table", &CFunc::setToTable<T>);
1640 template <unsigned int T>
1641 Class<std::bitset<T> > beginStdBitSet (char const* name)
1643 typedef std::bitset<T> BS;
1644 return beginClass<BS> (name)
1645 .addVoidConstructor ()
1646 .addFunction ("reset", (BS& (BS::*)())&BS::reset)
1647 .addFunction ("set", (BS& (BS::*)(size_t, bool))&BS::set)
1648 .addFunction ("count", &BS::count)
1649 .addFunction ("any", &BS::any)
1650 .addFunction ("none", &BS::none)
1651 .addFunction ("test", &BS::test)
1652 .addFunction ("size", &BS::size)
1653 .addExtCFunction ("add", &CFunc::tableToBitSet<T>)
1654 .addExtCFunction ("table", &CFunc::bitSetToTable<T>);
1658 Class<std::list<T> > beginConstStdList (char const* name)
1660 typedef std::list<T> LT;
1661 return beginClass<LT> (name)
1662 .addVoidConstructor ()
1663 .addFunction ("empty", <::empty)
1664 .addFunction ("size", <::size)
1665 .addFunction ("reverse", <::reverse)
1666 .addExtCFunction ("iter", &CFunc::listIter<T, LT>)
1667 .addExtCFunction ("table", &CFunc::listToTable<T, LT>);
1671 Class<std::list<T> > beginStdList (char const* name)
1673 typedef std::list<T> LT;
1674 return beginConstStdList<T> (name)
1675 .addFunction ("unique", (void (LT::*)())<::unique)
1676 .addFunction ("push_back", (void (LT::*)(const T&))<::push_back)
1677 .addExtCFunction ("add", &CFunc::tableToList<T, LT>);
1681 Class<std::vector<T> > beginStdVector (char const* name)
1683 typedef std::vector<T> LT;
1684 typedef typename std::vector<T>::reference T_REF;
1685 typedef typename std::vector<T>::size_type T_SIZE;
1687 return beginClass<LT> (name)
1688 .addVoidConstructor ()
1689 .addFunction ("empty", <::empty)
1690 .addFunction ("size", <::size)
1691 .addFunction ("push_back", (void (LT::*)(const T&))<::push_back)
1692 .addFunction ("at", (T_REF (LT::*)(T_SIZE))<::at)
1693 .addExtCFunction ("add", &CFunc::tableToList<T, LT>)
1694 .addExtCFunction ("iter", &CFunc::listIter<T, LT>)
1695 .addExtCFunction ("table", &CFunc::listToTable<T, LT>);
1698 //----------------------------------------------------------------------------
1701 Class<boost::shared_ptr<std::list<T> > > beginPtrStdList (char const* name)
1703 typedef std::list<T> LT;
1705 return beginClass<boost::shared_ptr<LT> > (name)
1706 .addVoidConstructor ()
1707 .addPtrFunction ("empty", <::empty)
1708 .addPtrFunction ("size", <::size)
1709 .addPtrFunction ("reverse", <::reverse)
1710 .addPtrFunction ("unique", (void (LT::*)())<::unique)
1711 .addPtrFunction ("push_back", (void (LT::*)(const T&))<::push_back)
1712 .addExtCFunction ("add", &CFunc::ptrTableToList<T, LT>)
1713 .addExtCFunction ("iter", &CFunc::ptrListIter<T, LT>)
1714 .addExtCFunction ("table", &CFunc::ptrListToTable<T, LT>);
1718 Class<boost::shared_ptr<std::vector<T> > > beginPtrStdVector (char const* name)
1720 typedef std::vector<T> LT;
1721 typedef typename std::vector<T>::reference T_REF;
1722 typedef typename std::vector<T>::size_type T_SIZE;
1724 return beginClass<boost::shared_ptr<LT> > (name)
1725 .addVoidConstructor ()
1726 .addPtrFunction ("empty", <::empty)
1727 .addPtrFunction ("empty", <::empty)
1728 .addPtrFunction ("size", <::size)
1729 .addPtrFunction ("push_back", (void (LT::*)(const T&))<::push_back)
1730 .addPtrFunction ("at", (T_REF (LT::*)(T_SIZE))<::at)
1731 .addExtCFunction ("add", &CFunc::ptrTableToList<T, LT>)
1732 .addExtCFunction ("iter", &CFunc::ptrListIter<T, LT>)
1733 .addExtCFunction ("table", &CFunc::ptrListToTable<T, LT>);
1736 //----------------------------------------------------------------------------
1738 Derive a new class for registrations.
1740 To continue registrations for the class later, use beginClass().
1741 Do not call deriveClass() again.
1743 template <class T, class U>
1744 Class <T> deriveClass (char const* name)
1746 CLASSDOC ("[C] Derived Class", _name << name, type_name <T>(), type_name <U>())
1747 return Class <T> (name, this, ClassInfo <U>::getStaticKey ());
1750 template <class T, class U>
1751 WSPtrClass <T> deriveWSPtrClass (char const* name)
1753 CLASSDOC ("[C] Derived Pointer Class", _name << name, type_name <T>(), type_name <U>())
1754 return WSPtrClass <T> (name, this,
1755 ClassInfo <boost::shared_ptr<U> >::getStaticKey (),
1756 ClassInfo <boost::weak_ptr<U> >::getStaticKey ())
1762 //------------------------------------------------------------------------------
1764 Retrieve the global namespace.
1766 It is recommended to put your namespace inside the global namespace, and
1767 then add your classes and functions to it, rather than adding many classes
1768 and functions directly to the global namespace.
1770 inline Namespace getGlobalNamespace (lua_State* L)
1772 return Namespace::getGlobalNamespace (L);
1783 /* vim: set et sw=2: */