Prevent deadlock when removing routes w/o engine
[ardour.git] / libs / lua / LuaBridge / detail / Namespace.h
1 //------------------------------------------------------------------------------
2 /*
3   https://github.com/vinniefalco/LuaBridge
4
5   Copyright 2016, Robin Gareus <robin@gareus.org>
6   Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
7   Copyright 2007, Nathan Reed
8
9   License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
10
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:
17
18   The above copyright notice and this permission notice shall be included in all
19   copies or substantial portions of the Software.
20
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
27   SOFTWARE.
28 */
29 //==============================================================================
30
31 #ifdef LUABINDINGDOC
32 #include <iostream>
33 #include <typeinfo>
34 #include <execinfo.h>
35 #include <type_traits>
36 #include <cxxabi.h>
37 #include <memory>
38 #include <string>
39 #include <cstdlib>
40
41 template <class T>
42 std::string type_name()
43 {
44         typedef typename std::remove_reference<T>::type TR;
45         std::unique_ptr<char, void(*)(void*)> own
46                 (
47                  abi::__cxa_demangle(typeid(TR).name(), nullptr,
48                          nullptr, nullptr),
49                  std::free
50                 );
51         std::string r = own != nullptr ? own.get() : typeid(TR).name();
52         if (std::is_const<TR>::value)
53                 r += " const";
54         if (std::is_volatile<TR>::value)
55                 r += " volatile";
56         if (std::is_lvalue_reference<T>::value)
57                 r += "&";
58         else if (std::is_rvalue_reference<T>::value)
59                 r += "&&";
60         return r;
61 }
62
63 //#define LUADOCOUT
64
65 #ifdef LUADOCOUT // lua
66 #define KEYSTA "[\""
67 #define KEYEND "\"] = "
68 #else // JSON
69 #define KEYSTA "\""
70 #define KEYEND "\" : "
71 #endif
72
73 #define CLASSDOC(TYPE, LUANAME, DECL, PARENTDECL) \
74   if (LuaBindingDoc::printBindings ()) { \
75     std::cout <<   "{ " << KEYSTA << "type"   << KEYEND << "  \""  << TYPE << "\",\n"; \
76     std::cout <<   "  " << KEYSTA << "lua"    << KEYEND << "   \"" << LUANAME << "\",\n"; \
77     std::cout <<   "  " << KEYSTA << "decl"   << KEYEND << "  \"" << DECL << "\",\n"; \
78     std::cout <<   "  " << KEYSTA << "parent" << KEYEND << "\""  << PARENTDECL << "\"\n"; \
79     std::cout <<   "},\n"; \
80   }
81
82 #define PRINTDOC(TYPE, LUANAME, RETVAL, DECL) \
83   if (LuaBindingDoc::printBindings ()) { \
84     std::cout <<   "{ " << KEYSTA << "type"   << KEYEND << "  \""  << TYPE << "\",\n"; \
85     std::cout <<   "  " << KEYSTA << "lua"    << KEYEND << "   \"" << LUANAME << "\",\n"; \
86     if (!(RETVAL).empty()) { \
87       std::cout << "  " << KEYSTA << "ret"    << KEYEND << "   \"" << (RETVAL) << "\",\n"; \
88     } \
89     std::cout <<   "  " << KEYSTA << "decl"   << KEYEND << "  \""  << DECL << "\"\n"; \
90     std::cout <<   "},\n"; \
91   }
92
93 #define FUNDOC(TYPE, NAME, FUNCTOR) \
94   PRINTDOC(TYPE, _name << NAME, \
95       type_name< typename FuncTraits <FUNCTOR>::ReturnType >(), \
96       type_name< typename FuncTraits <FUNCTOR>::DeclType >())
97
98 #define DATADOC(TYPE, NAME, FUNCTOR) \
99   PRINTDOC(TYPE, _name << NAME, \
100       std::string(), \
101       type_name< decltype(FUNCTOR) >())\
102
103
104 #else
105
106 #define CLASSDOC(TYPE, LUANAME, DECL, PARENTDECL)
107 #define PRINTDOC(TYPE, LUANAME, RETVAL, DECL)
108 #define FUNDOC(TYPE, NAME, FUNCTOR)
109 #define DATADOC(TYPE, NAME, FUNCTOR)
110
111 #endif
112
113 /** Provides C++ to Lua registration capabilities.
114
115     This class is not instantiated directly, call `getGlobalNamespace` to start
116     the registration process.
117 */
118 class Namespace
119 {
120 private:
121   Namespace& operator= (Namespace const& other);
122
123   lua_State* const L;
124   int mutable m_stackSize;
125
126 private:
127   //============================================================================
128   /**
129     Error reporting.
130
131     VF: This function looks handy, why aren't we using it?
132   */
133 #if 0
134   static int luaError (lua_State* L, std::string message)
135   {
136     assert (lua_isstring (L, lua_upvalueindex (1)));
137     std::string s;
138
139     // Get information on the caller's caller to format the message,
140     // so the error appears to originate from the Lua source.
141     lua_Debug ar;
142     int result = lua_getstack (L, 2, &ar);
143     if (result != 0)
144     {
145       lua_getinfo (L, "Sl", &ar);
146       s = ar.short_src;
147       if (ar.currentline != -1)
148       {
149         // poor mans int to string to avoid <strstrream>.
150         lua_pushnumber (L, ar.currentline);
151         s = s + ":" + lua_tostring (L, -1) + ": ";
152         lua_pop (L, 1);
153       }
154     }
155
156     s = s + message;
157
158     return luaL_error (L, s.c_str ());
159   }
160 #endif
161
162   //----------------------------------------------------------------------------
163   /**
164     Pop the Lua stack.
165   */
166   void pop (int n) const
167   {
168     if (m_stackSize >= n && lua_gettop (L) >= n)
169     {
170       lua_pop (L, n);
171       m_stackSize -= n;
172     }
173     else
174     {
175       throw std::logic_error ("invalid stack");
176     }
177   }
178
179 private:
180   /**
181     Factored base to reduce template instantiations.
182   */
183   class ClassBase
184   {
185   private:
186     ClassBase& operator= (ClassBase const& other);
187
188   protected:
189     friend class Namespace;
190
191     lua_State* const L;
192     int mutable m_stackSize;
193
194 #ifdef LUABINDINGDOC
195     std::string _name;
196     const Namespace* _parent;
197 #endif
198
199   protected:
200     //--------------------------------------------------------------------------
201     /**
202       __index metamethod for a class.
203
204       This implements member functions, data members, and property members.
205       Functions are stored in the metatable and const metatable. Data members
206       and property members are in the __propget table.
207
208       If the key is not found, the search proceeds up the hierarchy of base
209       classes.
210     */
211     static int indexMetaMethod (lua_State* L)
212     {
213       int result = 0;
214
215       assert (lua_isuserdata (L, 1));               // warn on security bypass
216       lua_getmetatable (L, 1);                      // get metatable for object
217       for (;;)
218       {
219         lua_pushvalue (L, 2);                       // push key arg2
220         lua_rawget (L, -2);                         // lookup key in metatable
221         if (lua_iscfunction (L, -1))                // ensure its a cfunction
222         {
223           lua_remove (L, -2);                       // remove metatable
224           result = 1;
225           break;
226         }
227         else if (lua_isnil (L, -1))
228         {
229           lua_pop (L, 1);
230         }
231         else
232         {
233           lua_pop (L, 2);
234           throw std::logic_error ("not a cfunction");
235         }
236
237         rawgetfield (L, -1, "__propget");           // get __propget table
238         if (lua_istable (L, -1))                    // ensure it is a table
239         {
240           lua_pushvalue (L, 2);                     // push key arg2
241           lua_rawget (L, -2);                       // lookup key in __propget
242           lua_remove (L, -2);                       // remove __propget
243           if (lua_iscfunction (L, -1))              // ensure its a cfunction
244           {
245             lua_remove (L, -2);                     // remove metatable
246             lua_pushvalue (L, 1);                   // push class arg1
247             lua_call (L, 1, 1);
248             result = 1;
249             break;
250           }
251           else if (lua_isnil (L, -1))
252           {
253             lua_pop (L, 1);
254           }
255           else
256           {
257             lua_pop (L, 2);
258
259             // We only put cfunctions into __propget.
260             throw std::logic_error ("not a cfunction");
261           }
262         }
263         else
264         {
265           lua_pop (L, 2);
266
267           // __propget is missing, or not a table.
268           throw std::logic_error ("missing __propget table");
269         }
270
271         // Repeat the lookup in the __parent metafield,
272         // or return nil if the field doesn't exist.
273         rawgetfield (L, -1, "__parent");
274         if (lua_istable (L, -1))
275         {
276           // Remove metatable and repeat the search in __parent.
277           lua_remove (L, -2);
278         }
279         else if (lua_isnil (L, -1))
280         {
281           result = 1;
282           break;
283         }
284         else
285         {
286           lua_pop (L, 2);
287
288           throw std::logic_error ("__parent is not a table");
289         }
290       }
291
292       return result;
293     }
294
295     //--------------------------------------------------------------------------
296     /**
297       __newindex metamethod for classes.
298
299       This supports writable variables and properties on class objects. The
300       corresponding object is passed in the first parameter to the set function.
301     */
302     static int newindexMetaMethod (lua_State* L)
303     {
304       int result = 0;
305
306       lua_getmetatable (L, 1);
307
308       for (;;)
309       {
310         // Check __propset
311         rawgetfield (L, -1, "__propset");
312         if (!lua_isnil (L, -1))
313         {
314           lua_pushvalue (L, 2);
315           lua_rawget (L, -2);
316           if (!lua_isnil (L, -1))
317           {
318             // found it, call the setFunction.
319             assert (lua_isfunction (L, -1));
320             lua_pushvalue (L, 1);
321             lua_pushvalue (L, 3);
322             lua_call (L, 2, 0);
323             result = 0;
324             break;
325           }
326           lua_pop (L, 1);
327         }
328         lua_pop (L, 1);
329
330         // Repeat the lookup in the __parent metafield.
331         rawgetfield (L, -1, "__parent");
332         if (lua_isnil (L, -1))
333         {
334           // Either the property or __parent must exist.
335           result = luaL_error (L,
336             "no member named '%s'", lua_tostring (L, 2));
337         }
338         lua_remove (L, -2);
339       }
340
341       return result;
342     }
343
344     //--------------------------------------------------------------------------
345     /**
346       Create the const table.
347     */
348     void createConstTable (char const* name)
349     {
350       lua_newtable (L);
351       lua_pushvalue (L, -1);
352       lua_setmetatable (L, -2);
353       lua_pushboolean (L, 1);
354       lua_rawsetp (L, -2, getIdentityKey ());
355       lua_pushstring (L, (std::string ("const ") + name).c_str ());
356       rawsetfield (L, -2, "__type");
357       lua_pushcfunction (L, &indexMetaMethod);
358       rawsetfield (L, -2, "__index");
359       lua_pushcfunction (L, &newindexMetaMethod);
360       rawsetfield (L, -2, "__newindex");
361       lua_newtable (L);
362       rawsetfield (L, -2, "__propget");
363
364       if (Security::hideMetatables ())
365       {
366         lua_pushboolean (L, false);
367         rawsetfield (L, -2, "__metatable");
368       }
369     }
370
371     //--------------------------------------------------------------------------
372     /**
373       Create the class table.
374
375       The Lua stack should have the const table on top.
376     */
377     void createClassTable (char const* name)
378     {
379       lua_newtable (L);
380       lua_pushvalue (L, -1);
381       lua_setmetatable (L, -2);
382       lua_pushboolean (L, 1);
383       lua_rawsetp (L, -2, getIdentityKey ());
384       lua_pushstring (L, name);
385       rawsetfield (L, -2, "__type");
386       lua_pushcfunction (L, &indexMetaMethod);
387       rawsetfield (L, -2, "__index");
388       lua_pushcfunction (L, &newindexMetaMethod);
389       rawsetfield (L, -2, "__newindex");
390       lua_newtable (L);
391       rawsetfield (L, -2, "__propget");
392       lua_newtable (L);
393       rawsetfield (L, -2, "__propset");
394
395       lua_pushvalue (L, -2);
396       rawsetfield (L, -2, "__const"); // point to const table
397
398       lua_pushvalue (L, -1);
399       rawsetfield (L, -3, "__class"); // point const table to class table
400
401       if (Security::hideMetatables ())
402       {
403         lua_pushboolean (L, false);
404         rawsetfield (L, -2, "__metatable");
405       }
406     }
407
408     //--------------------------------------------------------------------------
409     /**
410       Create the static table.
411
412       The Lua stack should have:
413         -1 class table
414         -2 const table
415         -3 enclosing namespace
416     */
417     void createStaticTable (char const* name)
418     {
419       lua_newtable (L);
420       lua_newtable (L);
421       lua_pushvalue (L, -1);
422       lua_setmetatable (L, -3);
423       lua_insert (L, -2);
424       rawsetfield (L, -5, name);
425
426 #if 0
427       lua_pushlightuserdata (L, this);
428       lua_pushcclosure (L, &tostringMetaMethod, 1);
429       rawsetfield (L, -2, "__tostring");
430 #endif
431       lua_pushcfunction (L, &CFunc::indexMetaMethod);
432       rawsetfield (L, -2, "__index");
433       lua_pushcfunction (L, &CFunc::newindexMetaMethod);
434       rawsetfield (L, -2, "__newindex");
435       lua_newtable (L);
436       rawsetfield (L, -2, "__propget");
437       lua_newtable (L);
438       rawsetfield (L, -2, "__propset");
439
440       lua_pushvalue (L, -2);
441       rawsetfield (L, -2, "__class"); // point to class table
442
443       if (Security::hideMetatables ())
444       {
445         lua_pushboolean (L, false);
446         rawsetfield (L, -2, "__metatable");
447       }
448     }
449
450     //==========================================================================
451     /**
452       lua_CFunction to construct a class object wrapped in a container.
453     */
454     template <class Params, class C>
455     static int ctorContainerProxy (lua_State* L)
456     {
457       typedef typename ContainerTraits <C>::Type T;
458       ArgList <Params, 2> args (L);
459       T* const p = Constructor <T, Params>::call (args);
460       UserdataSharedHelper <C, false>::push (L, p);
461       return 1;
462     }
463
464     //--------------------------------------------------------------------------
465     /**
466       lua_CFunction to construct a class object in-place in the userdata.
467     */
468     template <class Params, class T>
469     static int ctorPlacementProxy (lua_State* L)
470     {
471       ArgList <Params, 2> args (L);
472       Constructor <T, Params>::call (UserdataValue <T>::place (L), args);
473       return 1;
474     }
475
476     template <class Params, class T, class C>
477     static int ctorPtrPlacementProxy (lua_State* L)
478     {
479       ArgList <Params, 2> args (L);
480       T newobject (Constructor <C, Params>::call (args));
481       Stack<T>::push (L, newobject);
482       return 1;
483     }
484
485     template <class T>
486     static int ctorNilPtrPlacementProxy (lua_State* L)
487     {
488       const T* newobject = new T ();
489       Stack<T>::push (L, *newobject);
490       return 1;
491     }
492
493     //--------------------------------------------------------------------------
494     /**
495       Pop the Lua stack.
496     */
497     void pop (int n) const
498     {
499       if (m_stackSize >= n && lua_gettop (L) >= n)
500       {
501         lua_pop (L, n);
502         m_stackSize -= n;
503       }
504       else
505       {
506         throw std::logic_error ("invalid stack");
507       }
508     }
509
510   public:
511     //--------------------------------------------------------------------------
512     explicit ClassBase (lua_State* L_)
513       : L (L_)
514       , m_stackSize (0)
515     {
516     }
517
518     //--------------------------------------------------------------------------
519     /**
520       Copy Constructor.
521     */
522     ClassBase (ClassBase const& other)
523       : L (other.L)
524       , m_stackSize (0)
525 #ifdef LUABINDINGDOC
526       , _name (other._name)
527       , _parent (other._parent)
528 #endif
529     {
530       m_stackSize = other.m_stackSize;
531       other.m_stackSize = 0;
532     }
533
534     ~ClassBase ()
535     {
536       pop (m_stackSize);
537     }
538   };
539
540   //============================================================================
541   //
542   // Class
543   //
544   //============================================================================
545   /**
546     Provides a class registration in a lua_State.
547
548     After contstruction the Lua stack holds these objects:
549       -1 static table
550       -2 class table
551       -3 const table
552       -4 (enclosing namespace)
553   */
554   template <class T>
555   class Class : virtual public ClassBase
556   {
557   public:
558     //==========================================================================
559     /**
560       Register a new class or add to an existing class registration.
561     */
562     Class (char const* name, Namespace const* parent) : ClassBase (parent->L)
563     {
564 #ifdef LUABINDINGDOC
565       _parent = parent;
566       _name = parent->_name + name + ":";
567 #endif
568       PRINTDOC ("[C] Class", parent->_name << name, std::string(), type_name <T>())
569       m_stackSize = parent->m_stackSize + 3;
570       parent->m_stackSize = 0;
571
572       assert (lua_istable (L, -1));
573       rawgetfield (L, -1, name);
574
575       if (lua_isnil (L, -1))
576       {
577         lua_pop (L, 1);
578
579         createConstTable (name);
580         lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
581         rawsetfield (L, -2, "__gc");
582         lua_pushcclosure (L, &CFunc::ClassEqualCheck <T>::f, 0);
583         rawsetfield (L, -2, "__eq");
584
585         createClassTable (name);
586         lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
587         rawsetfield (L, -2, "__gc");
588         lua_pushcclosure (L, &CFunc::ClassEqualCheck <T>::f, 0);
589         rawsetfield (L, -2, "__eq");
590
591         createStaticTable (name);
592
593         // Map T back to its tables.
594         lua_pushvalue (L, -1);
595         lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ());
596         lua_pushvalue (L, -2);
597         lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
598         lua_pushvalue (L, -3);
599         lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
600       }
601       else
602       {
603         lua_pop (L, 1);
604         lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ());
605         rawgetfield (L, -1, "__class");
606         rawgetfield (L, -1, "__const");
607
608         // Reverse the top 3 stack elements
609         lua_insert (L, -3);
610         lua_insert (L, -2);
611       }
612     }
613
614     //==========================================================================
615     /**
616       Derive a new class.
617     */
618     Class (char const* name, Namespace const* parent, void const* const staticKey)
619       : ClassBase (parent->L)
620     {
621 #ifdef LUABINDINGDOC
622       _parent = parent;
623       _name = parent->_name + name + ":";
624 #endif
625       m_stackSize = parent->m_stackSize + 3;
626       parent->m_stackSize = 0;
627
628       assert (lua_istable (L, -1));
629
630       createConstTable (name);
631       lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
632       rawsetfield (L, -2, "__gc");
633       lua_pushcclosure (L, &CFunc::ClassEqualCheck <T>::f, 0);
634       rawsetfield (L, -2, "__eq");
635
636       createClassTable (name);
637       lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
638       rawsetfield (L, -2, "__gc");
639       lua_pushcclosure (L, &CFunc::ClassEqualCheck <T>::f, 0);
640       rawsetfield (L, -2, "__eq");
641
642       createStaticTable (name);
643
644       lua_rawgetp (L, LUA_REGISTRYINDEX, staticKey);
645       assert (lua_istable (L, -1));
646       rawgetfield (L, -1, "__class");
647       assert (lua_istable (L, -1));
648       rawgetfield (L, -1, "__const");
649       assert (lua_istable (L, -1));
650
651       rawsetfield (L, -6, "__parent");
652       rawsetfield (L, -4, "__parent");
653       rawsetfield (L, -2, "__parent");
654
655       lua_pushvalue (L, -1);
656       lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ());
657       lua_pushvalue (L, -2);
658       lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
659       lua_pushvalue (L, -3);
660       lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
661     }
662
663     //--------------------------------------------------------------------------
664     /**
665       Continue registration in the enclosing namespace.
666     */
667     Namespace endClass ()
668     {
669       return Namespace (this);
670     }
671
672     //--------------------------------------------------------------------------
673     /**
674       Add or replace a static data member.
675     */
676     template <class U>
677     Class <T>& addStaticData (char const* name, U* pu, bool isWritable = true)
678     {
679       DATADOC ("Static Data Member", name, pu)
680       assert (lua_istable (L, -1));
681
682       rawgetfield (L, -1, "__propget");
683       assert (lua_istable (L, -1));
684       lua_pushlightuserdata (L, pu);
685       lua_pushcclosure (L, &CFunc::getVariable <U>, 1);
686       rawsetfield (L, -2, name);
687       lua_pop (L, 1);
688
689       rawgetfield (L, -1, "__propset");
690       assert (lua_istable (L, -1));
691       if (isWritable)
692       {
693         lua_pushlightuserdata (L, pu);
694         lua_pushcclosure (L, &CFunc::setVariable <U>, 1);
695       }
696       else
697       {
698         lua_pushstring (L, name);
699         lua_pushcclosure (L, &CFunc::readOnlyError, 1);
700       }
701       rawsetfield (L, -2, name);
702       lua_pop (L, 1);
703
704       return *this;
705     }
706
707     //--------------------------------------------------------------------------
708 #if 0 // unused
709     /**
710       Add or replace a static property member.
711
712       If the set function is null, the property is read-only.
713     */
714     template <class U>
715     Class <T>& addStaticProperty (char const* name, U (*get)(), void (*set)(U) = 0)
716     {
717       typedef U (*get_t)();
718       typedef void (*set_t)(U);
719
720       assert (lua_istable (L, -1));
721
722       rawgetfield (L, -1, "__propget");
723       assert (lua_istable (L, -1));
724       new (lua_newuserdata (L, sizeof (get))) get_t (get);
725       lua_pushcclosure (L, &CFunc::Call <U (*) (void)>::f, 1);
726       rawsetfield (L, -2, name);
727       lua_pop (L, 1);
728
729       rawgetfield (L, -1, "__propset");
730       assert (lua_istable (L, -1));
731       if (set != 0)
732       {
733         new (lua_newuserdata (L, sizeof (set))) set_t (set);
734         lua_pushcclosure (L, &CFunc::Call <void (*) (U)>::f, 1);
735       }
736       else
737       {
738         lua_pushstring (L, name);
739         lua_pushcclosure (L, &CFunc::readOnlyError, 1);
740       }
741       rawsetfield (L, -2, name);
742       lua_pop (L, 1);
743
744       return *this;
745     }
746 #endif
747
748     //--------------------------------------------------------------------------
749     /**
750       Add or replace a static member function.
751     */
752     template <class FP>
753     Class <T>& addStaticFunction (char const* name, FP const fp)
754     {
755       FUNDOC ("Static Member Function", name, FP)
756       new (lua_newuserdata (L, sizeof (fp))) FP (fp);
757       lua_pushcclosure (L, &CFunc::Call <FP>::f, 1);
758       rawsetfield (L, -2, name);
759
760       return *this;
761     }
762
763     //--------------------------------------------------------------------------
764     /**
765       Add or replace a lua_CFunction.
766     */
767     Class <T>& addStaticCFunction (char const* name, int (*const fp)(lua_State*))
768     {
769       DATADOC ("Static C Function", name, fp)
770       lua_pushcfunction (L, fp);
771       rawsetfield (L, -2, name);
772       return *this;
773     }
774
775     //--------------------------------------------------------------------------
776     /**
777       Add or replace a data member.
778     */
779     template <class U>
780     Class <T>& addData (char const* name, const U T::* mp, bool isWritable = true)
781     {
782       DATADOC ("Data Member", name, mp)
783       typedef const U T::*mp_t;
784
785       // Add to __propget in class and const tables.
786       {
787         rawgetfield (L, -2, "__propget");
788         rawgetfield (L, -4, "__propget");
789         new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
790         lua_pushcclosure (L, &CFunc::getProperty <T,U>, 1);
791         lua_pushvalue (L, -1);
792         rawsetfield (L, -4, name);
793         rawsetfield (L, -2, name);
794         lua_pop (L, 2);
795       }
796
797       if (isWritable)
798       {
799         // Add to __propset in class table.
800         rawgetfield (L, -2, "__propset");
801         assert (lua_istable (L, -1));
802         new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
803         lua_pushcclosure (L, &CFunc::setProperty <T,U>, 1);
804         rawsetfield (L, -2, name);
805         lua_pop (L, 1);
806       }
807
808       return *this;
809     }
810
811     //--------------------------------------------------------------------------
812     /**
813       Add or replace a property member.
814     */
815     template <class TG, class TS>
816     Class <T>& addProperty (char const* name, TG (T::* get) () const, bool (T::* set) (TS))
817     {
818       DATADOC ("Property", name, get)
819       // Add to __propget in class and const tables.
820       {
821         rawgetfield (L, -2, "__propget");
822         rawgetfield (L, -4, "__propget");
823         typedef TG (T::*get_t) () const;
824         new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
825         lua_pushcclosure (L, &CFunc::CallConstMember <get_t>::f, 1);
826         lua_pushvalue (L, -1);
827         rawsetfield (L, -4, name);
828         rawsetfield (L, -2, name);
829         lua_pop (L, 2);
830       }
831
832       {
833         // Add to __propset in class table.
834         rawgetfield (L, -2, "__propset");
835         assert (lua_istable (L, -1));
836         typedef bool (T::* set_t) (TS);
837         new (lua_newuserdata (L, sizeof (set_t))) set_t (set);
838         lua_pushcclosure (L, &CFunc::CallMember <set_t>::f, 1);
839         rawsetfield (L, -2, name);
840         lua_pop (L, 1);
841       }
842
843       return *this;
844     }
845
846 #if 0 // unused
847     // read-only
848     template <class TG>
849     Class <T>& addProperty (char const* name, TG (T::* get) () const)
850     {
851       // Add to __propget in class and const tables.
852       rawgetfield (L, -2, "__propget");
853       rawgetfield (L, -4, "__propget");
854       typedef TG (T::*get_t) () const;
855       new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
856       lua_pushcclosure (L, &CFunc::CallConstMember <get_t>::f, 1);
857       lua_pushvalue (L, -1);
858       rawsetfield (L, -4, name);
859       rawsetfield (L, -2, name);
860       lua_pop (L, 2);
861
862       return *this;
863     }
864 #endif
865
866     //--------------------------------------------------------------------------
867     /**
868       Add or replace a property member, by proxy.
869
870       When a class is closed for modification and does not provide (or cannot
871       provide) the function signatures necessary to implement get or set for
872       a property, this will allow non-member functions act as proxies.
873
874       Both the get and the set functions require a T const* and T* in the first
875       argument respectively.
876     */
877     template <class TG, class TS>
878     Class <T>& addProperty (char const* name, TG (*get) (T const*), bool (*set) (T*, TS))
879     {
880       // Add to __propget in class and const tables.
881       {
882         rawgetfield (L, -2, "__propget");
883         rawgetfield (L, -4, "__propget");
884         typedef TG (*get_t) (T const*);
885         new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
886         lua_pushcclosure (L, &CFunc::Call <get_t>::f, 1);
887         lua_pushvalue (L, -1);
888         rawsetfield (L, -4, name);
889         rawsetfield (L, -2, name);
890         lua_pop (L, 2);
891       }
892
893       if (set != 0)
894       {
895         // Add to __propset in class table.
896         rawgetfield (L, -2, "__propset");
897         assert (lua_istable (L, -1));
898         typedef void (*set_t) (T*, TS);
899         new (lua_newuserdata (L, sizeof (set_t))) set_t (set);
900         lua_pushcclosure (L, &CFunc::Call <set_t>::f, 1);
901         rawsetfield (L, -2, name);
902         lua_pop (L, 1);
903       }
904
905       return *this;
906     }
907
908 #if 0 // unused
909     // read-only
910     template <class TG, class TS>
911     Class <T>& addProperty (char const* name, TG (*get) (T const*))
912     {
913       // Add to __propget in class and const tables.
914       rawgetfield (L, -2, "__propget");
915       rawgetfield (L, -4, "__propget");
916       typedef TG (*get_t) (T const*);
917       new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
918       lua_pushcclosure (L, &CFunc::Call <get_t>::f, 1);
919       lua_pushvalue (L, -1);
920       rawsetfield (L, -4, name);
921       rawsetfield (L, -2, name);
922       lua_pop (L, 2);
923
924       return *this;
925     }
926 #endif
927     //--------------------------------------------------------------------------
928     /**
929         Add or replace a member function.
930     */
931     template <class MemFn>
932     Class <T>& addFunction (char const* name, MemFn mf)
933     {
934       FUNDOC("Member Function", name, MemFn)
935       CFunc::CallMemberFunctionHelper <MemFn, FuncTraits <MemFn>::isConstMemberFunction>::add (L, name, mf);
936       return *this;
937     }
938
939     template <class MemFn>
940     Class <T>& addPtrFunction (char const* name, MemFn mf)
941     {
942       FUNDOC("Member Pointer Function", name, MemFn)
943       CFunc::CallMemberPtrFunctionHelper <MemFn>::add (L, name, mf);
944       return *this;
945     }
946
947     template <class MemFn>
948     Class <T>& addWPtrFunction (char const* name, MemFn mf)
949     {
950       FUNDOC("Member Weak Pointer Function", name, MemFn)
951       CFunc::CallMemberWPtrFunctionHelper <MemFn>::add (L, name, mf);
952       return *this;
953     }
954
955     template <class MemFn>
956     Class <T>& addRefFunction (char const* name, MemFn mf)
957     {
958       FUNDOC("Member Function RefReturn", name, MemFn)
959       CFunc::CallMemberRefFunctionHelper <MemFn, FuncTraits <MemFn>::isConstMemberFunction>::add (L, name, mf);
960       return *this;
961     }
962
963
964     //--------------------------------------------------------------------------
965     /**
966         Add or replace a member lua_CFunction.
967     */
968     Class <T>& addCFunction (char const* name, int (T::*mfp)(lua_State*))
969     {
970       DATADOC ("C Function", name, mfp)
971       typedef int (T::*MFP)(lua_State*);
972       assert (lua_istable (L, -1));
973       new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp);
974       lua_pushcclosure (L, &CFunc::CallMemberCFunction <T>::f, 1);
975       rawsetfield (L, -3, name); // class table
976
977       return *this;
978     }
979
980     // custom callback - extend existing classes
981     // with non-class member functions (e.g STL iterator)
982     Class <T>& addExtCFunction (char const* name, int (*const fp)(lua_State*))
983     {
984       DATADOC ("Ext C Function", name, fp)
985       assert (lua_istable (L, -1));
986       lua_pushcclosure (L, fp, 0);
987       lua_pushvalue (L, -1);
988       rawsetfield (L, -5, name); // const table
989       rawsetfield (L, -3, name); // class table
990       return *this;
991     }
992
993     //--------------------------------------------------------------------------
994     /**
995         Add or replace a const member lua_CFunction.
996     */
997     Class <T>& addCFunction (char const* name, int (T::*mfp)(lua_State*) const)
998     {
999       DATADOC ("Const C Member Function", name, mfp)
1000       typedef int (T::*MFP)(lua_State*) const;
1001       assert (lua_istable (L, -1));
1002       new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp);
1003       lua_pushcclosure (L, &CFunc::CallConstMemberCFunction <T>::f, 1);
1004       lua_pushvalue (L, -1);
1005       rawsetfield (L, -5, name); // const table
1006       rawsetfield (L, -3, name); // class table
1007
1008       return *this;
1009     }
1010
1011     /**
1012         Add or replace a static const data
1013     */
1014     template <typename U>
1015       Class <T>& addConst (char const* name, const U val)
1016       {
1017         DATADOC ("Constant/Enum Member", name, val)
1018         assert (lua_istable (L, -1));
1019
1020         rawgetfield (L, -1, "__propget"); // static
1021         new (lua_newuserdata (L, sizeof (val))) U (val);
1022         lua_pushcclosure (L, &CFunc::getConst <U>, 1);
1023         rawsetfield (L, -2, name);
1024         lua_pop (L, 1);
1025
1026         rawgetfield (L, -1, "__propset"); // static
1027         lua_pushstring (L, name);
1028         lua_pushcclosure (L, &CFunc::readOnlyError, 1);
1029         rawsetfield (L, -2, name);
1030         lua_pop (L, 1);
1031         return *this;
1032       }
1033
1034     //--------------------------------------------------------------------------
1035     /**
1036       Add or replace a primary Constructor.
1037
1038       The primary Constructor is invoked when calling the class type table
1039       like a function.
1040
1041       The template parameter should be a function pointer type that matches
1042       the desired Constructor (since you can't take the address of a Constructor
1043       and pass it as an argument).
1044     */
1045     template <class MemFn, class C>
1046     Class <T>& addConstructor ()
1047     {
1048       FUNDOC("Constructor", "", MemFn)
1049       lua_pushcclosure (L,
1050         &ctorContainerProxy <typename FuncTraits <MemFn>::Params, C>, 0);
1051       rawsetfield(L, -2, "__call");
1052
1053       return *this;
1054     }
1055
1056     template <class MemFn>
1057     Class <T>& addConstructor ()
1058     {
1059       FUNDOC("Constructor", "", MemFn)
1060       lua_pushcclosure (L,
1061         &ctorPlacementProxy <typename FuncTraits <MemFn>::Params, T>, 0);
1062       rawsetfield(L, -2, "__call");
1063
1064       return *this;
1065     }
1066
1067     template <class MemFn, class PT>
1068     Class <T>& addPtrConstructor ()
1069     {
1070       FUNDOC("Constructor", "", MemFn)
1071       lua_pushcclosure (L,
1072         &ctorPtrPlacementProxy <typename FuncTraits <MemFn>::Params, T, PT>, 0);
1073       rawsetfield(L, -2, "__call");
1074
1075       return *this;
1076     }
1077
1078     Class <T>& addVoidConstructor ()
1079     {
1080       return addConstructor <void (*) ()> ();
1081     }
1082
1083     template <class PT>
1084     Class <T>& addVoidPtrConstructor ()
1085     {
1086       return addPtrConstructor <void (*) (), PT> ();
1087     }
1088
1089     Class <T>& addEqualCheck ()
1090     {
1091       assert (lua_istable (L, -1));
1092       lua_pushcclosure (L, &CFunc::ClassEqualCheck <T>::f, 0);
1093       rawsetfield (L, -3, "sameinstance");
1094       return *this;
1095     }
1096
1097     template <class U>
1098     Class <T>& addCast (char const* name)
1099     {
1100       PRINTDOC("Cast", _name << name,
1101           type_name< U >(),
1102           type_name< U >() << " (" << type_name< T >() << "::*)()")
1103
1104       assert (lua_istable (L, -1));
1105       lua_pushcclosure (L, &CFunc::CastClass <T, U>::f, 0);
1106       rawsetfield (L, -3, name); // class table
1107
1108       lua_pushcclosure (L, &CFunc::CastConstClass <T, U>::f, 0);
1109       rawsetfield (L, -4, name); // const table
1110       return *this;
1111     }
1112
1113   };
1114
1115   /** C Array to/from table */
1116   template <typename T>
1117   class Array : virtual public ClassBase
1118   {
1119   public:
1120     Array (char const* name, Namespace const* parent) : ClassBase (parent->L)
1121     {
1122 #ifdef LUABINDINGDOC
1123       _parent = parent;
1124       _name = parent->_name + name + ":";
1125 #endif
1126       PRINTDOC ("[C] Array", parent->_name << name,
1127           std::string(), type_name <T>() + "*")
1128       PRINTDOC ("Ext C Function", _name << "array",
1129           std::string(""), "int (*)(lua_State*)")
1130       PRINTDOC ("Ext C Function", _name << "get_table",
1131           std::string(""), "int (*)(lua_State*)")
1132       PRINTDOC ("Ext C Function", _name << "set_table",
1133           std::string(""), "int (*)(lua_State*)")
1134       PRINTDOC("Member Function", _name << "offset",
1135           std::string(type_name <T>() + "*"), std::string(type_name <T>() + "* (*)(unsigned int)"))
1136
1137       m_stackSize = parent->m_stackSize + 3;
1138       parent->m_stackSize = 0;
1139
1140 #if 0 // don't allow to duplicates handlers for same array-type
1141       assert (lua_istable (L, -1));
1142       lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
1143       if (lua_istable (L, -1)) {
1144         lua_pushnil (L);
1145         lua_pushnil (L);
1146         return;
1147       }
1148       lua_pop (L, 1);
1149 #endif
1150
1151       assert (lua_istable (L, -1));
1152       rawgetfield (L, -1, name);
1153
1154       if (lua_isnil (L, -1))
1155       {
1156         lua_pop (L, 1);
1157
1158         // register array access in global namespace
1159         luaL_newmetatable (L, typeid(T).name());
1160         lua_pushcclosure (L, CFunc::array_index<T>, 0);
1161         lua_setfield(L, -2, "__index");
1162         lua_pushcclosure (L, CFunc::array_newindex<T>, 0);
1163         lua_setfield(L, -2, "__newindex");
1164         if (Security::hideMetatables ())
1165         {
1166           lua_pushboolean (L, false);
1167           rawsetfield (L, -2, "__metatable");
1168         }
1169         lua_pop (L, 1);
1170
1171
1172         createConstTable (name);
1173         lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
1174         rawsetfield (L, -2, "__gc");
1175         lua_pushcclosure (L, &CFunc::ClassEqualCheck <T>::f, 0);
1176         rawsetfield (L, -2, "__eq");
1177
1178         createClassTable (name);
1179         lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
1180         rawsetfield (L, -2, "__gc");
1181         lua_pushcclosure (L, &CFunc::ClassEqualCheck <T>::f, 0);
1182         rawsetfield (L, -2, "__eq");
1183
1184         createStaticTable (name);
1185
1186         // Map T back to its tables.
1187         lua_pushvalue (L, -1);
1188         lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ());
1189         lua_pushvalue (L, -2);
1190         lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
1191         lua_pushvalue (L, -3);
1192         lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
1193
1194         assert (lua_istable (L, -1));
1195         lua_pushcclosure (L, &CFunc::getArray <T>, 0);
1196         rawsetfield (L, -3, "array"); // class table
1197
1198         lua_pushcclosure (L, &CFunc::getTable <T>, 0);
1199         rawsetfield (L, -3, "get_table"); // class table
1200
1201         lua_pushcclosure (L, &CFunc::setTable <T>, 0);
1202         rawsetfield (L, -3, "set_table"); // class table
1203
1204         lua_pushcclosure (L, &CFunc::ClassEqualCheck <T>::f, 0);
1205         rawsetfield (L, -3, "sameinstance");
1206
1207         lua_pushcclosure (L, &CFunc::offsetArray <T>, 0);
1208         rawsetfield (L, -3, "offset"); // class table
1209
1210       }
1211       else
1212       {
1213         lua_pushnil (L);
1214         lua_pushnil (L);
1215       }
1216     }
1217
1218     Namespace endArray ()
1219     {
1220       return Namespace (this);
1221     }
1222   };
1223
1224   /** Boost Weak & Shared Pointer Class Wrapper */
1225   template <class T>
1226   class WSPtrClass : virtual public ClassBase
1227   {
1228   public:
1229     WSPtrClass (char const* name, Namespace const* parent)
1230       : ClassBase (parent->L)
1231       , shared (name, parent)
1232       , weak (name, parent)
1233     {
1234 #ifdef LUABINDINGDOC
1235       _parent = parent;
1236       _name = parent->_name + name + ":";
1237 #endif
1238       PRINTDOC ("[C] Weak/Shared Pointer Class",
1239           parent->_name + name,
1240           std::string(), type_name <T>())
1241       m_stackSize = shared.m_stackSize;
1242       parent->m_stackSize = weak.m_stackSize = shared.m_stackSize = 0;
1243       lua_pop (L, 3);
1244     }
1245
1246     WSPtrClass (char const* name, Namespace const* parent, void const* const sharedkey, void const* const weakkey)
1247       : ClassBase (parent->L)
1248       , shared (name, parent, sharedkey)
1249       , weak (name, parent, weakkey)
1250     {
1251 #ifdef LUABINDINGDOC
1252       _parent = parent;
1253       _name = parent->_name + name + ":";
1254 #endif
1255       m_stackSize = shared.m_stackSize;
1256       parent->m_stackSize = weak.m_stackSize = shared.m_stackSize = 0;
1257       lua_pop (L, 3);
1258     }
1259
1260     template <class MemFn>
1261     WSPtrClass <T>& addFunction (char const* name, MemFn mf)
1262     {
1263       FUNDOC ("Weak/Shared Pointer Function", name, MemFn)
1264       set_shared_class ();
1265       CFunc::CallMemberPtrFunctionHelper <MemFn>::add (L, name, mf);
1266
1267       set_weak_class ();
1268       CFunc::CallMemberWPtrFunctionHelper <MemFn>::add (L, name, mf);
1269       return *this;
1270     }
1271
1272     template <class MemFn>
1273     WSPtrClass <T>& addRefFunction (char const* name, MemFn mf)
1274     {
1275       FUNDOC ("Weak/Shared Pointer Function RefReturn", name, MemFn)
1276       set_shared_class ();
1277       CFunc::CallMemberRefPtrFunctionHelper <MemFn>::add (L, name, mf);
1278
1279       set_weak_class ();
1280       CFunc::CallMemberRefWPtrFunctionHelper <MemFn>::add (L, name, mf);
1281       return *this;
1282     }
1283
1284     template <class MemFn>
1285     WSPtrClass <T>& addConstructor ()
1286     {
1287       FUNDOC ("Weak/Shared Pointer Constructor", "", MemFn)
1288       set_shared_class ();
1289       lua_pushcclosure (L,
1290           &shared. template ctorPtrPlacementProxy <typename FuncTraits <MemFn>::Params, boost::shared_ptr<T>, T >, 0);
1291       rawsetfield(L, -2, "__call");
1292
1293       set_weak_class ();
1294       // NOTE: this constructs an empty weak-ptr,
1295       // ideally we'd construct a weak-ptr from a referenced shared-ptr
1296       lua_pushcclosure (L,
1297           &weak. template ctorPlacementProxy <typename FuncTraits <MemFn>::Params, boost::weak_ptr<T> >, 0);
1298       rawsetfield(L, -2, "__call");
1299       return *this;
1300     }
1301
1302     WSPtrClass <T>& addVoidConstructor ()
1303     {
1304       return addConstructor <void (*) ()> ();
1305     }
1306
1307     WSPtrClass <T>& addNilPtrConstructor ()
1308     {
1309       FUNDOC ("Weak/Shared Pointer NIL Constructor", "", void (*) ())
1310       set_shared_class ();
1311       lua_pushcclosure (L,
1312           &shared. template ctorNilPtrPlacementProxy <boost::shared_ptr<T> >, 0);
1313       rawsetfield(L, -2, "__call");
1314
1315       set_weak_class ();
1316       // NOTE: this constructs an empty weak-ptr,
1317       // ideally we'd construct a weak-ptr from a referenced shared-ptr
1318       lua_pushcclosure (L,
1319           &weak. template ctorNilPtrPlacementProxy <boost::weak_ptr<T> >, 0);
1320       rawsetfield(L, -2, "__call");
1321
1322       return *this;
1323     }
1324
1325     WSPtrClass <T>& addExtCFunction (char const* name, int (*const fp)(lua_State*))
1326     {
1327       DATADOC ("Weak/Shared Ext C Function", name, fp)
1328       set_shared_class ();
1329       assert (lua_istable (L, -1));
1330       lua_pushcclosure (L, fp, 0);
1331       lua_pushvalue (L, -1);
1332       rawsetfield (L, -5, name); // const table
1333       rawsetfield (L, -3, name); // class table
1334
1335       set_weak_class ();
1336       assert (lua_istable (L, -1));
1337       lua_pushcclosure (L, fp, 0);
1338       lua_pushvalue (L, -1);
1339       rawsetfield (L, -5, name); // const table
1340       rawsetfield (L, -3, name); // class table
1341
1342       return *this;
1343     }
1344
1345     template <class U>
1346     WSPtrClass <T>& addCast (char const* name)
1347     {
1348       PRINTDOC("Weak/Shared Pointer Cast", _name << name,
1349           type_name< U >(),
1350           type_name< U >() << " (" << type_name< T >() << "::*)()")
1351
1352       // TODO weak ptr
1353       set_shared_class ();
1354       assert (lua_istable (L, -1));
1355       lua_pushcclosure (L, &CFunc::CastMemberPtr <T, U>::f, 0);
1356       rawsetfield (L, -3, name); // class table
1357       return *this;
1358     }
1359
1360     WSPtrClass <T>& addNullCheck ()
1361     {
1362       PRINTDOC("Weak/Shared Null Check", _name << "isnil", std::string("bool"), std::string("void (*)()"))
1363       set_shared_class ();
1364       assert (lua_istable (L, -1));
1365       lua_pushcclosure (L, &CFunc::PtrNullCheck <T>::f, 0);
1366       rawsetfield (L, -3, "isnil"); // class table
1367
1368       set_weak_class ();
1369       assert (lua_istable (L, -1));
1370       lua_pushcclosure (L, &CFunc::WPtrNullCheck <T>::f, 0);
1371       rawsetfield (L, -3, "isnil"); // class table
1372
1373       return *this;
1374     }
1375
1376     WSPtrClass <T>& addEqualCheck ()
1377     {
1378       set_shared_class ();
1379       assert (lua_istable (L, -1));
1380       lua_pushcclosure (L, &CFunc::PtrEqualCheck <T>::f, 0);
1381       rawsetfield (L, -3, "sameinstance"); // class table
1382
1383       set_weak_class ();
1384       assert (lua_istable (L, -1));
1385       lua_pushcclosure (L, &CFunc::WPtrEqualCheck <T>::f, 0);
1386       rawsetfield (L, -3, "sameinstance"); // class table
1387
1388       return *this;
1389     }
1390
1391     template <class U>
1392     WSPtrClass <T>& addData (char const* name, const U T::* mp, bool isWritable = true)
1393     {
1394       DATADOC ("Data Member", name, mp)
1395       typedef const U T::*mp_t;
1396
1397       set_weak_class ();
1398       assert (lua_istable (L, -1));
1399       // Add to __propget in class and const tables.
1400       {
1401         rawgetfield (L, -2, "__propget");
1402         rawgetfield (L, -4, "__propget");
1403         new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
1404         lua_pushcclosure (L, &CFunc::getWPtrProperty <T,U>, 1);
1405         lua_pushvalue (L, -1);
1406         rawsetfield (L, -4, name);
1407         rawsetfield (L, -2, name);
1408         lua_pop (L, 2);
1409       }
1410
1411       if (isWritable)
1412       {
1413         // Add to __propset in class table.
1414         rawgetfield (L, -2, "__propset");
1415         assert (lua_istable (L, -1));
1416         new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
1417         lua_pushcclosure (L, &CFunc::setWPtrProperty <T,U>, 1);
1418         rawsetfield (L, -2, name);
1419         lua_pop (L, 1);
1420       }
1421
1422       set_shared_class ();
1423       assert (lua_istable (L, -1));
1424       // Add to __propget in class and const tables.
1425       {
1426         rawgetfield (L, -2, "__propget");
1427         rawgetfield (L, -4, "__propget");
1428         new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
1429         lua_pushcclosure (L, &CFunc::getPtrProperty <T,U>, 1);
1430         lua_pushvalue (L, -1);
1431         rawsetfield (L, -4, name);
1432         rawsetfield (L, -2, name);
1433         lua_pop (L, 2);
1434       }
1435
1436       if (isWritable)
1437       {
1438         // Add to __propset in class table.
1439         rawgetfield (L, -2, "__propset");
1440         assert (lua_istable (L, -1));
1441         new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
1442         lua_pushcclosure (L, &CFunc::setPtrProperty <T,U>, 1);
1443         rawsetfield (L, -2, name);
1444         lua_pop (L, 1);
1445       }
1446
1447       return *this;
1448     }
1449
1450
1451     Namespace endClass ()
1452     {
1453       return Namespace (this);
1454     }
1455
1456   private:
1457     void set_weak_class () {
1458       lua_pop (L, 3);
1459       lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <boost::weak_ptr<T> >::getStaticKey ());
1460       rawgetfield (L, -1, "__class");
1461       rawgetfield (L, -1, "__const");
1462       lua_insert (L, -3);
1463       lua_insert (L, -2);
1464     }
1465     void set_shared_class () {
1466       lua_pop (L, 3);
1467       lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <boost::shared_ptr<T> >::getStaticKey ());
1468       rawgetfield (L, -1, "__class");
1469       rawgetfield (L, -1, "__const");
1470       lua_insert (L, -3);
1471       lua_insert (L, -2);
1472     }
1473     Class<boost::shared_ptr<T> > shared;
1474     Class<boost::weak_ptr<T> > weak;
1475   };
1476
1477
1478 private:
1479   //----------------------------------------------------------------------------
1480   /**
1481       Open the global namespace for registrations.
1482   */
1483   explicit Namespace (lua_State* L_)
1484     : L (L_)
1485     , m_stackSize (0)
1486 #ifdef LUABINDINGDOC
1487     , _name ("")
1488     , _parent (0)
1489 #endif
1490   {
1491     lua_getglobal (L, "_G");
1492     ++m_stackSize;
1493   }
1494
1495 #ifdef LUABINDINGDOC
1496   std::string _name;
1497   Namespace const * _parent;
1498 #endif
1499
1500   //----------------------------------------------------------------------------
1501   /**
1502       Open a namespace for registrations.
1503
1504       The namespace is created if it doesn't already exist.
1505       The parent namespace is at the top of the Lua stack.
1506   */
1507   Namespace (char const* name, Namespace const* parent)
1508     : L (parent->L)
1509     , m_stackSize (0)
1510 #ifdef LUABINDINGDOC
1511     , _name (parent->_name + name + ":")
1512     , _parent (parent)
1513 #endif
1514   {
1515     m_stackSize = parent->m_stackSize + 1;
1516     parent->m_stackSize = 0;
1517
1518     assert (lua_istable (L, -1));
1519     rawgetfield (L, -1, name);
1520     if (lua_isnil (L, -1))
1521     {
1522       lua_pop (L, 1);
1523
1524       lua_newtable (L);
1525       lua_pushvalue (L, -1);
1526       lua_setmetatable (L, -2);
1527       lua_pushcfunction (L, &CFunc::indexMetaMethod);
1528       rawsetfield (L, -2, "__index");
1529       lua_pushcfunction (L, &CFunc::newindexMetaMethod);
1530       rawsetfield (L, -2, "__newindex");
1531       lua_newtable (L);
1532       rawsetfield (L, -2, "__propget");
1533       lua_newtable (L);
1534       rawsetfield (L, -2, "__propset");
1535       lua_pushvalue (L, -1);
1536       rawsetfield (L, -3, name);
1537 #if 0
1538       lua_pushcfunction (L, &tostringMetaMethod);
1539       rawsetfield (L, -2, "__tostring");
1540 #endif
1541       if (Security::hideMetatables ())
1542       {
1543         lua_pushboolean (L, false);
1544         rawsetfield (L, -2, "__metatable");
1545       }
1546
1547     }
1548   }
1549
1550   //----------------------------------------------------------------------------
1551   /**
1552       Creates a continued registration from a child namespace.
1553   */
1554   explicit Namespace (Namespace const* child)
1555     : L (child->L)
1556     , m_stackSize (0)
1557 #ifdef LUABINDINGDOC
1558     , _name (child->_parent ? child->_parent->_name : "")
1559     , _parent (child->_parent ? child->_parent->_parent : NULL)
1560 #endif
1561   {
1562     m_stackSize = child->m_stackSize - 1;
1563     child->m_stackSize = 1;
1564     child->pop (1);
1565
1566     // It is not necessary or valid to call
1567     // endNamespace() for the global namespace!
1568     //
1569     assert (m_stackSize != 0);
1570   }
1571
1572   //----------------------------------------------------------------------------
1573   /**
1574       Creates a continued registration from a child class.
1575   */
1576   explicit Namespace (ClassBase const* child)
1577     : L (child->L)
1578     , m_stackSize (0)
1579 #ifdef LUABINDINGDOC
1580     , _name (child->_parent ? child->_parent->_name : "")
1581     , _parent (child->_parent ? child->_parent->_parent : NULL)
1582 #endif
1583   {
1584     m_stackSize = child->m_stackSize - 3;
1585     child->m_stackSize = 3;
1586     child->pop (3);
1587   }
1588
1589 public:
1590   //----------------------------------------------------------------------------
1591   /**
1592       Copy Constructor.
1593
1594       Ownership of the stack is transferred to the new object. This happens
1595       when the compiler emits temporaries to hold these objects while chaining
1596       registrations across namespaces.
1597   */
1598   Namespace (Namespace const& other) : L (other.L)
1599   {
1600     m_stackSize = other.m_stackSize;
1601     other.m_stackSize = 0;
1602 #ifdef LUABINDINGDOC
1603     _name = other._name;
1604     _parent = other._parent;
1605 #endif
1606   }
1607
1608   //----------------------------------------------------------------------------
1609   /**
1610       Closes this namespace registration.
1611   */
1612   ~Namespace ()
1613   {
1614     pop (m_stackSize);
1615   }
1616
1617   //----------------------------------------------------------------------------
1618   /**
1619       Open the global namespace.
1620   */
1621   static Namespace getGlobalNamespace (lua_State* L)
1622   {
1623     return Namespace (L);
1624   }
1625
1626   //----------------------------------------------------------------------------
1627   /**
1628       Open a new or existing namespace for registrations.
1629   */
1630   Namespace beginNamespace (char const* name)
1631   {
1632     return Namespace (name, this);
1633   }
1634
1635   //----------------------------------------------------------------------------
1636   /**
1637       Continue namespace registration in the parent.
1638
1639       Do not use this on the global namespace.
1640   */
1641   Namespace endNamespace ()
1642   {
1643     return Namespace (this);
1644   }
1645
1646   //----------------------------------------------------------------------------
1647   /**
1648       Add or replace a variable.
1649   */
1650   template <class T>
1651   Namespace& addVariable (char const* name, T* pt, bool isWritable = true)
1652   {
1653     assert (lua_istable (L, -1));
1654
1655     rawgetfield (L, -1, "__propget");
1656     assert (lua_istable (L, -1));
1657     lua_pushlightuserdata (L, pt);
1658     lua_pushcclosure (L, &CFunc::getVariable <T>, 1);
1659     rawsetfield (L, -2, name);
1660     lua_pop (L, 1);
1661
1662     rawgetfield (L, -1, "__propset");
1663     assert (lua_istable (L, -1));
1664     if (isWritable)
1665     {
1666       lua_pushlightuserdata (L, pt);
1667       lua_pushcclosure (L, &CFunc::setVariable <T>, 1);
1668     }
1669     else
1670     {
1671       lua_pushstring (L, name);
1672       lua_pushcclosure (L, &CFunc::readOnlyError, 1);
1673     }
1674     rawsetfield (L, -2, name);
1675     lua_pop (L, 1);
1676
1677     return *this;
1678   }
1679
1680   template <typename U>
1681   Namespace& addConst (char const* name, const U val)
1682   {
1683     DATADOC ("Constant/Enum", name, val)
1684     assert (lua_istable (L, -1));
1685     rawgetfield (L, -1, "__propget");
1686     new (lua_newuserdata (L, sizeof (val))) U (val);
1687     lua_pushcclosure (L, &CFunc::getConst <U>, 1);
1688     rawsetfield (L, -2, name);
1689     lua_pop (L, 1);
1690
1691     rawgetfield (L, -1, "__propset");
1692     assert (lua_istable (L, -1));
1693     lua_pushstring (L, name);
1694     lua_pushcclosure (L, &CFunc::readOnlyError, 1);
1695     rawsetfield (L, -2, name);
1696     lua_pop (L, 1);
1697     return *this;
1698   }
1699
1700   //----------------------------------------------------------------------------
1701   /**
1702       Add or replace a property.
1703
1704       If the set function is omitted or null, the property is read-only.
1705   */
1706 #if 0 // unused
1707   template <class TG, class TS>
1708   Namespace& addProperty (char const* name, TG (*get) (), void (*set)(TS) = 0)
1709   {
1710     assert (lua_istable (L, -1));
1711
1712     rawgetfield (L, -1, "__propget");
1713     assert (lua_istable (L, -1));
1714     typedef TG (*get_t) ();
1715     new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
1716     lua_pushcclosure (L, &CFunc::Call <TG (*) (void)>::f, 1);
1717     rawsetfield (L, -2, name);
1718     lua_pop (L, 1);
1719
1720     rawgetfield (L, -1, "__propset");
1721     assert (lua_istable (L, -1));
1722     if (set != 0)
1723     {
1724       typedef void (*set_t) (TS);
1725       new (lua_newuserdata (L, sizeof (set_t))) set_t (set);
1726       lua_pushcclosure (L, &CFunc::Call <void (*) (TS)>::f, 1);
1727     }
1728     else
1729     {
1730       lua_pushstring (L, name);
1731       lua_pushcclosure (L, &CFunc::readOnlyError, 1);
1732     }
1733     rawsetfield (L, -2, name);
1734     lua_pop (L, 1);
1735
1736     return *this;
1737   }
1738 #endif
1739
1740   //----------------------------------------------------------------------------
1741   /**
1742       Add or replace a free function.
1743   */
1744   template <class FP>
1745   Namespace& addFunction (char const* name, FP const fp)
1746   {
1747     FUNDOC ("Free Function", name, FP)
1748     assert (lua_istable (L, -1));
1749
1750     new (lua_newuserdata (L, sizeof (fp))) FP (fp);
1751     lua_pushcclosure (L, &CFunc::Call <FP>::f, 1);
1752     rawsetfield (L, -2, name);
1753
1754     return *this;
1755   }
1756
1757   template <class FP>
1758   Namespace& addRefFunction (char const* name, FP const fp)
1759   {
1760     FUNDOC ("Free Function RefReturn", name, FP)
1761     assert (lua_istable (L, -1));
1762
1763     new (lua_newuserdata (L, sizeof (fp))) FP (fp);
1764     lua_pushcclosure (L, &CFunc::CallRef <FP>::f, 1);
1765     rawsetfield (L, -2, name);
1766
1767     return *this;
1768   }
1769
1770   //----------------------------------------------------------------------------
1771   /**
1772       Add or replace a array type
1773   */
1774
1775   template <typename T>
1776   Namespace registerArray (char const* name)
1777   {
1778     return Array <T> (name, this).endArray();
1779   }
1780
1781
1782   //----------------------------------------------------------------------------
1783   /**
1784       Add or replace a lua_CFunction.
1785   */
1786   Namespace& addCFunction (char const* name, int (*const fp)(lua_State*))
1787   {
1788     DATADOC ("Free C Function", name, fp)
1789     lua_pushcfunction (L, fp);
1790     rawsetfield (L, -2, name);
1791
1792     return *this;
1793   }
1794
1795   //----------------------------------------------------------------------------
1796   /**
1797       Open a new or existing class for registrations.
1798   */
1799   template <class T>
1800   Class <T> beginClass (char const* name)
1801   {
1802     return Class <T> (name, this);
1803   }
1804
1805   /** weak & shared pointer class */
1806   template <class T>
1807   WSPtrClass <T> beginWSPtrClass (char const* name)
1808   {
1809     return WSPtrClass <T> (name, this)
1810       .addNullCheck()
1811       .addEqualCheck();
1812   }
1813
1814   //----------------------------------------------------------------------------
1815
1816   template <class K, class V>
1817   Class<std::map<K, V> > beginStdMap (char const* name)
1818   {
1819     typedef std::map<K, V> LT;
1820     typedef std::pair<const K, V> T;
1821
1822     typedef typename std::map<K, V>::size_type T_SIZE;
1823
1824     return beginClass<LT> (name)
1825       .addVoidConstructor ()
1826       .addFunction ("empty", &LT::empty)
1827       .addFunction ("size", &LT::size)
1828       .addFunction ("clear", (void (LT::*)())&LT::clear)
1829       .addFunction ("count", (T_SIZE (LT::*)(const K&) const)&LT::count)
1830       .addExtCFunction ("add", &CFunc::tableToMap<K, V>)
1831       .addExtCFunction ("iter", &CFunc::mapIter<K, V>)
1832       .addExtCFunction ("table", &CFunc::mapToTable<K, V>)
1833       .addExtCFunction ("at", &CFunc::mapAt<K, V>);
1834   }
1835
1836   template <class T>
1837   Class<std::set<T> > beginStdSet (char const* name)
1838   {
1839     typedef std::set<T> LT;
1840     return beginClass<LT> (name)
1841       .addVoidConstructor ()
1842       .addFunction ("clear", (void (LT::*)())&LT::clear)
1843       .addFunction ("empty", &LT::empty)
1844       .addFunction ("size", &LT::size)
1845       .addExtCFunction ("iter", &CFunc::setIter<T, LT>)
1846       .addExtCFunction ("table", &CFunc::setToTable<T, LT>);
1847   }
1848
1849   template <unsigned int T>
1850   Class<std::bitset<T> > beginStdBitSet (char const* name)
1851   {
1852     typedef std::bitset<T> BS;
1853     return beginClass<BS> (name)
1854       .addVoidConstructor ()
1855       .addFunction ("reset", (BS& (BS::*)())&BS::reset)
1856       .addFunction ("set", (BS& (BS::*)(size_t, bool))&BS::set)
1857       .addFunction ("count", &BS::count)
1858       .addFunction ("any", &BS::any)
1859       .addFunction ("none", &BS::none)
1860       .addFunction ("test", &BS::test)
1861       .addFunction ("size", &BS::size)
1862       .addExtCFunction ("add", &CFunc::tableToBitSet<T>)
1863       .addExtCFunction ("table", &CFunc::bitSetToTable<T>);
1864   }
1865
1866   template <class T>
1867   Class<std::list<T> > beginConstStdList (char const* name)
1868   {
1869     typedef std::list<T> LT;
1870     return beginClass<LT> (name)
1871       .addVoidConstructor ()
1872       .addFunction ("empty", &LT::empty)
1873       .addFunction ("size", &LT::size)
1874       .addFunction ("reverse", &LT::reverse)
1875       .addFunction ("front", static_cast<const T& (LT::*)() const>(&LT::front))
1876       .addFunction ("back", static_cast<const T& (LT::*)() const>(&LT::back))
1877       .addExtCFunction ("iter", &CFunc::listIter<T, LT>)
1878       .addExtCFunction ("table", &CFunc::listToTable<T, LT>);
1879   }
1880
1881   template <class T>
1882   Class<std::list<T> > beginStdList (char const* name)
1883   {
1884     typedef std::list<T> LT;
1885     return beginConstStdList<T> (name)
1886       .addFunction ("unique", (void (LT::*)())&LT::unique)
1887       .addFunction ("push_back", (void (LT::*)(const T&))&LT::push_back)
1888       .addExtCFunction ("add", &CFunc::tableToList<T, LT>);
1889   }
1890
1891   template <class T>
1892   Class<std::list<T*> > beginConstStdCPtrList (char const* name)
1893   {
1894     typedef T* TP;
1895     typedef std::list<TP> LT;
1896     return beginClass<LT> (name)
1897       .addVoidConstructor ()
1898       .addFunction ("empty", &LT::empty)
1899       .addFunction ("size", &LT::size)
1900       .addFunction ("reverse", &LT::reverse)
1901       .addFunction ("front", static_cast<const TP& (LT::*)() const>(&LT::front))
1902       .addFunction ("back", static_cast<const TP& (LT::*)() const>(&LT::back))
1903       .addExtCFunction ("iter", &CFunc::listIter<T*, LT>)
1904       .addExtCFunction ("table", &CFunc::listToTable<T*, LT>);
1905   }
1906
1907   template <class T>
1908   Class<std::list<T*> > beginStdCPtrList (char const* name)
1909   {
1910     typedef T* TP;
1911     typedef std::list<TP> LT;
1912     return beginConstStdCPtrList<T> (name)
1913       .addFunction ("unique", (void (LT::*)())&LT::unique)
1914       .addFunction ("push_back", (void (LT::*)(const TP&))&LT::push_back);
1915   }
1916
1917
1918   template <class T>
1919   Class<std::vector<T> > beginConstStdVector (char const* name)
1920   {
1921     typedef std::vector<T> LT;
1922     typedef typename std::vector<T>::reference T_REF;
1923     typedef typename std::vector<T>::size_type T_SIZE;
1924
1925     return beginClass<LT> (name)
1926       .addVoidConstructor ()
1927       .addFunction ("empty", &LT::empty)
1928       .addFunction ("size", &LT::size)
1929       .addFunction ("at", (T_REF (LT::*)(T_SIZE))&LT::at)
1930       .addExtCFunction ("iter", &CFunc::listIter<T, LT>)
1931       .addExtCFunction ("table", &CFunc::listToTable<T, LT>);
1932   }
1933
1934   template <class T>
1935   Class<std::vector<T> > beginStdVector (char const* name)
1936   {
1937     typedef std::vector<T> LT;
1938     return beginConstStdVector<T> (name)
1939       .addVoidConstructor ()
1940       .addFunction ("push_back", (void (LT::*)(const T&))&LT::push_back)
1941       .addExtCFunction ("add", &CFunc::tableToList<T, LT>);
1942   }
1943
1944
1945
1946   //----------------------------------------------------------------------------
1947
1948   template <class T>
1949   Class<boost::shared_ptr<std::list<T> > > beginPtrStdList (char const* name)
1950   {
1951     typedef std::list<T> LT;
1952     return beginClass<boost::shared_ptr<LT> > (name)
1953       //.addVoidPtrConstructor<LT> ()
1954       .addPtrFunction ("empty", &LT::empty)
1955       .addPtrFunction ("size", &LT::size)
1956       .addPtrFunction ("reverse", &LT::reverse)
1957       .addPtrFunction ("unique", (void (LT::*)())&LT::unique)
1958       .addPtrFunction ("push_back", (void (LT::*)(const T&))&LT::push_back)
1959       .addExtCFunction ("add", &CFunc::ptrTableToList<T, LT>)
1960       .addExtCFunction ("iter", &CFunc::ptrListIter<T, LT>)
1961       .addExtCFunction ("table", &CFunc::ptrListToTable<T, LT>);
1962   }
1963
1964   template <class T>
1965   Class<boost::shared_ptr<std::vector<T> > > beginPtrStdVector (char const* name)
1966   {
1967     typedef std::vector<T> LT;
1968     typedef typename std::vector<T>::reference T_REF;
1969     typedef typename std::vector<T>::size_type T_SIZE;
1970
1971     return beginClass<boost::shared_ptr<LT> > (name)
1972       //.addVoidPtrConstructor<LT> ()
1973       .addPtrFunction ("empty", &LT::empty)
1974       .addPtrFunction ("empty", &LT::empty)
1975       .addPtrFunction ("size", &LT::size)
1976       .addPtrFunction ("push_back", (void (LT::*)(const T&))&LT::push_back)
1977       .addPtrFunction ("at", (T_REF (LT::*)(T_SIZE))&LT::at)
1978       .addExtCFunction ("add", &CFunc::ptrTableToList<T, LT>)
1979       .addExtCFunction ("iter", &CFunc::ptrListIter<T, LT>)
1980       .addExtCFunction ("table", &CFunc::ptrListToTable<T, LT>);
1981   }
1982
1983   //----------------------------------------------------------------------------
1984   /**
1985       Derive a new class for registrations.
1986
1987       To continue registrations for the class later, use beginClass().
1988       Do not call deriveClass() again.
1989   */
1990   template <class T, class U>
1991   Class <T> deriveClass (char const* name)
1992   {
1993     CLASSDOC ("[C] Derived Class", _name << name, type_name <T>(), type_name <U>())
1994     return Class <T> (name, this, ClassInfo <U>::getStaticKey ());
1995   }
1996
1997   template <class T, class U>
1998   WSPtrClass <T> deriveWSPtrClass (char const* name)
1999   {
2000
2001     CLASSDOC ("[C] Derived Class", _name << name, type_name <boost::shared_ptr<T> >(), type_name <boost::shared_ptr<U> >())
2002     CLASSDOC ("[C] Derived Class", _name << name, type_name <boost::weak_ptr<T> >(), type_name <boost::weak_ptr<U> >())
2003     CLASSDOC ("[C] Derived Pointer Class", _name << name, type_name <T>(), type_name <U>())
2004     return WSPtrClass <T> (name, this,
2005         ClassInfo <boost::shared_ptr<U> >::getStaticKey (),
2006         ClassInfo <boost::weak_ptr<U> >::getStaticKey ())
2007       .addNullCheck()
2008       .addEqualCheck();
2009   }
2010
2011 };
2012
2013 //------------------------------------------------------------------------------
2014 /**
2015     Retrieve the global namespace.
2016
2017     It is recommended to put your namespace inside the global namespace, and
2018     then add your classes and functions to it, rather than adding many classes
2019     and functions directly to the global namespace.
2020 */
2021 inline Namespace getGlobalNamespace (lua_State* L)
2022 {
2023   return Namespace::getGlobalNamespace (L);
2024 }
2025
2026
2027 #undef KEYSTA
2028 #undef KEYEND
2029 #undef CLASSDOC
2030 #undef PRINTDOC
2031 #undef FUNDOC
2032 #undef DATADOC
2033
2034 /* vim: set et sw=2: */