Fix LuaBindings TypeList copy-ctor
[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_pushnil (L);
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_pushnil (L);
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_pushnil (L);
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       rawsetfield (L, -3, name); // class table
988       return *this;
989     }
990
991     //--------------------------------------------------------------------------
992     /**
993         Add or replace a const member lua_CFunction.
994     */
995     Class <T>& addCFunction (char const* name, int (T::*mfp)(lua_State*) const)
996     {
997       DATADOC ("Const C Member Function", name, mfp)
998       typedef int (T::*MFP)(lua_State*) const;
999       assert (lua_istable (L, -1));
1000       new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp);
1001       lua_pushcclosure (L, &CFunc::CallConstMemberCFunction <T>::f, 1);
1002       lua_pushvalue (L, -1);
1003       rawsetfield (L, -5, name); // const table
1004       rawsetfield (L, -3, name); // class table
1005
1006       return *this;
1007     }
1008
1009     /**
1010         Add or replace a static const data
1011     */
1012     template <typename U>
1013       Class <T>& addConst (char const* name, const U val)
1014       {
1015         DATADOC ("Constant/Enum Member", name, val)
1016         assert (lua_istable (L, -1));
1017
1018         rawgetfield (L, -1, "__propget"); // static
1019         new (lua_newuserdata (L, sizeof (val))) U (val);
1020         lua_pushcclosure (L, &CFunc::getConst <U>, 1);
1021         rawsetfield (L, -2, name);
1022         lua_pop (L, 1);
1023
1024         rawgetfield (L, -1, "__propset"); // static
1025         lua_pushstring (L, name);
1026         lua_pushcclosure (L, &CFunc::readOnlyError, 1);
1027         rawsetfield (L, -2, name);
1028         lua_pop (L, 1);
1029         return *this;
1030       }
1031
1032     //--------------------------------------------------------------------------
1033     /**
1034       Add or replace a primary Constructor.
1035
1036       The primary Constructor is invoked when calling the class type table
1037       like a function.
1038
1039       The template parameter should be a function pointer type that matches
1040       the desired Constructor (since you can't take the address of a Constructor
1041       and pass it as an argument).
1042     */
1043     template <class MemFn, class C>
1044     Class <T>& addConstructor ()
1045     {
1046       FUNDOC("Constructor", "", MemFn)
1047       lua_pushcclosure (L,
1048         &ctorContainerProxy <typename FuncTraits <MemFn>::Params, C>, 0);
1049       rawsetfield(L, -2, "__call");
1050
1051       return *this;
1052     }
1053
1054     template <class MemFn>
1055     Class <T>& addConstructor ()
1056     {
1057       FUNDOC("Constructor", "", MemFn)
1058       lua_pushcclosure (L,
1059         &ctorPlacementProxy <typename FuncTraits <MemFn>::Params, T>, 0);
1060       rawsetfield(L, -2, "__call");
1061
1062       return *this;
1063     }
1064
1065     template <class MemFn, class PT>
1066     Class <T>& addPtrConstructor ()
1067     {
1068       FUNDOC("Constructor", "", MemFn)
1069       lua_pushcclosure (L,
1070         &ctorPtrPlacementProxy <typename FuncTraits <MemFn>::Params, T, PT>, 0);
1071       rawsetfield(L, -2, "__call");
1072
1073       return *this;
1074     }
1075
1076     Class <T>& addVoidConstructor ()
1077     {
1078       return addConstructor <void (*) ()> ();
1079     }
1080
1081     template <class PT>
1082     Class <T>& addVoidPtrConstructor ()
1083     {
1084       return addPtrConstructor <void (*) (), PT> ();
1085     }
1086
1087     Class <T>& addEqualCheck ()
1088     {
1089       assert (lua_istable (L, -1));
1090       lua_pushcclosure (L, &CFunc::ClassEqualCheck <T>::f, 0);
1091       rawsetfield (L, -3, "sameinstance");
1092       return *this;
1093     }
1094
1095     template <class U>
1096     Class <T>& addCast (char const* name)
1097     {
1098       PRINTDOC("Cast", _name << name,
1099           type_name< U >(),
1100           type_name< U >() << " (" << type_name< T >() << "::*)()")
1101
1102       assert (lua_istable (L, -1));
1103       lua_pushcclosure (L, &CFunc::CastClass <T, U>::f, 0);
1104       rawsetfield (L, -3, name); // class table
1105
1106       lua_pushcclosure (L, &CFunc::CastConstClass <T, U>::f, 0);
1107       rawsetfield (L, -4, name); // const table
1108       return *this;
1109     }
1110
1111   };
1112
1113   /** C Array to/from table */
1114   template <typename T>
1115   class Array : virtual public ClassBase
1116   {
1117   public:
1118     Array (char const* name, Namespace const* parent) : ClassBase (parent->L)
1119     {
1120 #ifdef LUABINDINGDOC
1121       _parent = parent;
1122       _name = parent->_name + name + ":";
1123 #endif
1124       PRINTDOC ("[C] Array", parent->_name << name,
1125           std::string(), type_name <T>() + "*")
1126       PRINTDOC ("Ext C Function", _name << "array",
1127           std::string(""), "int (*)(lua_State*)")
1128       PRINTDOC ("Ext C Function", _name << "get_table",
1129           std::string(""), "int (*)(lua_State*)")
1130       PRINTDOC ("Ext C Function", _name << "set_table",
1131           std::string(""), "int (*)(lua_State*)")
1132       PRINTDOC("Member Function", _name << "offset",
1133           std::string(type_name <T>() + "*"), std::string(type_name <T>() + "* (*)(unsigned int)"))
1134
1135       m_stackSize = parent->m_stackSize + 3;
1136       parent->m_stackSize = 0;
1137
1138 #if 0 // don't allow to duplicates handlers for same array-type
1139       assert (lua_istable (L, -1));
1140       lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
1141       if (lua_istable (L, -1)) {
1142         lua_pushnil (L);
1143         lua_pushnil (L);
1144         return;
1145       }
1146       lua_pop (L, 1);
1147 #endif
1148
1149       assert (lua_istable (L, -1));
1150       rawgetfield (L, -1, name);
1151
1152       if (lua_isnil (L, -1))
1153       {
1154         lua_pop (L, 1);
1155
1156         // register array access in global namespace
1157         luaL_newmetatable (L, typeid(T).name());
1158         lua_pushcclosure (L, CFunc::array_index<T>, 0);
1159         lua_setfield(L, -2, "__index");
1160         lua_pushcclosure (L, CFunc::array_newindex<T>, 0);
1161         lua_setfield(L, -2, "__newindex");
1162         lua_pop (L, 1);
1163
1164         createConstTable (name);
1165         lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
1166         rawsetfield (L, -2, "__gc");
1167         lua_pushcclosure (L, &CFunc::ClassEqualCheck <T>::f, 0);
1168         rawsetfield (L, -2, "__eq");
1169
1170         createClassTable (name);
1171         lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
1172         rawsetfield (L, -2, "__gc");
1173         lua_pushcclosure (L, &CFunc::ClassEqualCheck <T>::f, 0);
1174         rawsetfield (L, -2, "__eq");
1175
1176         createStaticTable (name);
1177
1178         // Map T back to its tables.
1179         lua_pushvalue (L, -1);
1180         lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ());
1181         lua_pushvalue (L, -2);
1182         lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
1183         lua_pushvalue (L, -3);
1184         lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
1185
1186         assert (lua_istable (L, -1));
1187         lua_pushcclosure (L, &CFunc::getArray <T>, 0);
1188         rawsetfield (L, -3, "array"); // class table
1189
1190         lua_pushcclosure (L, &CFunc::getTable <T>, 0);
1191         rawsetfield (L, -3, "get_table"); // class table
1192
1193         lua_pushcclosure (L, &CFunc::setTable <T>, 0);
1194         rawsetfield (L, -3, "set_table"); // class table
1195
1196         lua_pushcclosure (L, &CFunc::ClassEqualCheck <T>::f, 0);
1197         rawsetfield (L, -3, "sameinstance");
1198
1199         lua_pushcclosure (L, &CFunc::offsetArray <T>, 0);
1200         rawsetfield (L, -3, "offset"); // class table
1201
1202       }
1203       else
1204       {
1205         lua_pushnil (L);
1206         lua_pushnil (L);
1207       }
1208     }
1209
1210     Namespace endArray ()
1211     {
1212       return Namespace (this);
1213     }
1214   };
1215
1216   /** Boost Weak & Shared Pointer Class Wrapper */
1217   template <class T>
1218   class WSPtrClass : virtual public ClassBase
1219   {
1220   public:
1221     WSPtrClass (char const* name, Namespace const* parent)
1222       : ClassBase (parent->L)
1223       , shared (name, parent)
1224       , weak (name, parent)
1225     {
1226 #ifdef LUABINDINGDOC
1227       _parent = parent;
1228       _name = parent->_name + name + ":";
1229 #endif
1230       PRINTDOC ("[C] Weak/Shared Pointer Class",
1231           parent->_name + name,
1232           std::string(), type_name <T>())
1233       m_stackSize = shared.m_stackSize;
1234       parent->m_stackSize = weak.m_stackSize = shared.m_stackSize = 0;
1235       lua_pop (L, 3);
1236     }
1237
1238     WSPtrClass (char const* name, Namespace const* parent, void const* const sharedkey, void const* const weakkey)
1239       : ClassBase (parent->L)
1240       , shared (name, parent, sharedkey)
1241       , weak (name, parent, weakkey)
1242     {
1243 #ifdef LUABINDINGDOC
1244       _parent = parent;
1245       _name = parent->_name + name + ":";
1246 #endif
1247       m_stackSize = shared.m_stackSize;
1248       parent->m_stackSize = weak.m_stackSize = shared.m_stackSize = 0;
1249       lua_pop (L, 3);
1250     }
1251
1252     template <class MemFn>
1253     WSPtrClass <T>& addFunction (char const* name, MemFn mf)
1254     {
1255       FUNDOC ("Weak/Shared Pointer Function", name, MemFn)
1256       set_shared_class ();
1257       CFunc::CallMemberPtrFunctionHelper <MemFn>::add (L, name, mf);
1258
1259       set_weak_class ();
1260       CFunc::CallMemberWPtrFunctionHelper <MemFn>::add (L, name, mf);
1261       return *this;
1262     }
1263
1264     template <class MemFn>
1265     WSPtrClass <T>& addRefFunction (char const* name, MemFn mf)
1266     {
1267       FUNDOC ("Weak/Shared Pointer Function RefReturn", name, MemFn)
1268       set_shared_class ();
1269       CFunc::CallMemberRefPtrFunctionHelper <MemFn>::add (L, name, mf);
1270
1271       set_weak_class ();
1272       CFunc::CallMemberRefWPtrFunctionHelper <MemFn>::add (L, name, mf);
1273       return *this;
1274     }
1275
1276     template <class MemFn>
1277     WSPtrClass <T>& addConstructor ()
1278     {
1279       FUNDOC ("Weak/Shared Pointer Constructor", "", MemFn)
1280       set_shared_class ();
1281       lua_pushcclosure (L,
1282           &shared. template ctorPtrPlacementProxy <typename FuncTraits <MemFn>::Params, boost::shared_ptr<T>, T >, 0);
1283       rawsetfield(L, -2, "__call");
1284
1285       set_weak_class ();
1286       // NOTE: this constructs an empty weak-ptr,
1287       // ideally we'd construct a weak-ptr from a referenced shared-ptr
1288       lua_pushcclosure (L,
1289           &weak. template ctorPlacementProxy <typename FuncTraits <MemFn>::Params, boost::weak_ptr<T> >, 0);
1290       rawsetfield(L, -2, "__call");
1291       return *this;
1292     }
1293
1294     WSPtrClass <T>& addVoidConstructor ()
1295     {
1296       return addConstructor <void (*) ()> ();
1297     }
1298
1299     WSPtrClass <T>& addNilPtrConstructor ()
1300     {
1301       FUNDOC ("Weak/Shared Pointer NIL Constructor", "", void (*) ())
1302       set_shared_class ();
1303       lua_pushcclosure (L,
1304           &shared. template ctorNilPtrPlacementProxy <boost::shared_ptr<T> >, 0);
1305       rawsetfield(L, -2, "__call");
1306
1307       set_weak_class ();
1308       // NOTE: this constructs an empty weak-ptr,
1309       // ideally we'd construct a weak-ptr from a referenced shared-ptr
1310       lua_pushcclosure (L,
1311           &weak. template ctorNilPtrPlacementProxy <boost::weak_ptr<T> >, 0);
1312       rawsetfield(L, -2, "__call");
1313
1314       return *this;
1315     }
1316
1317     WSPtrClass <T>& addExtCFunction (char const* name, int (*const fp)(lua_State*))
1318     {
1319       DATADOC ("Weak/Shared Ext C Function", name, fp)
1320       set_shared_class ();
1321       assert (lua_istable (L, -1));
1322       lua_pushcclosure (L, fp, 0);
1323       rawsetfield (L, -3, name); // class table
1324
1325       set_weak_class ();
1326       assert (lua_istable (L, -1));
1327       lua_pushcclosure (L, fp, 0);
1328       rawsetfield (L, -3, name); // class table
1329
1330       return *this;
1331     }
1332
1333     template <class U>
1334     WSPtrClass <T>& addCast (char const* name)
1335     {
1336       PRINTDOC("Weak/Shared Pointer Cast", _name << name,
1337           type_name< U >(),
1338           type_name< U >() << " (" << type_name< T >() << "::*)()")
1339
1340       // TODO weak ptr
1341       set_shared_class ();
1342       assert (lua_istable (L, -1));
1343       lua_pushcclosure (L, &CFunc::CastMemberPtr <T, U>::f, 0);
1344       rawsetfield (L, -3, name); // class table
1345       return *this;
1346     }
1347
1348     WSPtrClass <T>& addNullCheck ()
1349     {
1350       PRINTDOC("Weak/Shared Null Check", _name << "isnil", std::string("bool"), std::string("void (*)()"))
1351       set_shared_class ();
1352       assert (lua_istable (L, -1));
1353       lua_pushcclosure (L, &CFunc::PtrNullCheck <T>::f, 0);
1354       rawsetfield (L, -3, "isnil"); // class table
1355
1356       set_weak_class ();
1357       assert (lua_istable (L, -1));
1358       lua_pushcclosure (L, &CFunc::WPtrNullCheck <T>::f, 0);
1359       rawsetfield (L, -3, "isnil"); // class table
1360
1361       return *this;
1362     }
1363
1364     WSPtrClass <T>& addEqualCheck ()
1365     {
1366       set_shared_class ();
1367       assert (lua_istable (L, -1));
1368       lua_pushcclosure (L, &CFunc::PtrEqualCheck <T>::f, 0);
1369       rawsetfield (L, -3, "sameinstance"); // class table
1370
1371       set_weak_class ();
1372       assert (lua_istable (L, -1));
1373       lua_pushcclosure (L, &CFunc::WPtrEqualCheck <T>::f, 0);
1374       rawsetfield (L, -3, "sameinstance"); // class table
1375
1376       return *this;
1377     }
1378
1379     template <class U>
1380     WSPtrClass <T>& addData (char const* name, const U T::* mp, bool isWritable = true)
1381     {
1382       DATADOC ("Data Member", name, mp)
1383       typedef const U T::*mp_t;
1384
1385       set_weak_class ();
1386       assert (lua_istable (L, -1));
1387       // Add to __propget in class and const tables.
1388       {
1389         rawgetfield (L, -2, "__propget");
1390         rawgetfield (L, -4, "__propget");
1391         new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
1392         lua_pushcclosure (L, &CFunc::getWPtrProperty <T,U>, 1);
1393         lua_pushvalue (L, -1);
1394         rawsetfield (L, -4, name);
1395         rawsetfield (L, -2, name);
1396         lua_pop (L, 2);
1397       }
1398
1399       if (isWritable)
1400       {
1401         // Add to __propset in class table.
1402         rawgetfield (L, -2, "__propset");
1403         assert (lua_istable (L, -1));
1404         new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
1405         lua_pushcclosure (L, &CFunc::setWPtrProperty <T,U>, 1);
1406         rawsetfield (L, -2, name);
1407         lua_pop (L, 1);
1408       }
1409
1410       set_shared_class ();
1411       assert (lua_istable (L, -1));
1412       // Add to __propget in class and const tables.
1413       {
1414         rawgetfield (L, -2, "__propget");
1415         rawgetfield (L, -4, "__propget");
1416         new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
1417         lua_pushcclosure (L, &CFunc::getPtrProperty <T,U>, 1);
1418         lua_pushvalue (L, -1);
1419         rawsetfield (L, -4, name);
1420         rawsetfield (L, -2, name);
1421         lua_pop (L, 2);
1422       }
1423
1424       if (isWritable)
1425       {
1426         // Add to __propset in class table.
1427         rawgetfield (L, -2, "__propset");
1428         assert (lua_istable (L, -1));
1429         new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
1430         lua_pushcclosure (L, &CFunc::setPtrProperty <T,U>, 1);
1431         rawsetfield (L, -2, name);
1432         lua_pop (L, 1);
1433       }
1434
1435       return *this;
1436     }
1437
1438
1439     Namespace endClass ()
1440     {
1441       return Namespace (this);
1442     }
1443
1444   private:
1445     void set_weak_class () {
1446       lua_pop (L, 3);
1447       lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <boost::weak_ptr<T> >::getStaticKey ());
1448       rawgetfield (L, -1, "__class");
1449       rawgetfield (L, -1, "__const");
1450       lua_insert (L, -3);
1451       lua_insert (L, -2);
1452     }
1453     void set_shared_class () {
1454       lua_pop (L, 3);
1455       lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <boost::shared_ptr<T> >::getStaticKey ());
1456       rawgetfield (L, -1, "__class");
1457       rawgetfield (L, -1, "__const");
1458       lua_insert (L, -3);
1459       lua_insert (L, -2);
1460     }
1461     Class<boost::shared_ptr<T> > shared;
1462     Class<boost::weak_ptr<T> > weak;
1463   };
1464
1465
1466 private:
1467   //----------------------------------------------------------------------------
1468   /**
1469       Open the global namespace for registrations.
1470   */
1471   explicit Namespace (lua_State* L_)
1472     : L (L_)
1473     , m_stackSize (0)
1474 #ifdef LUABINDINGDOC
1475     , _name ("")
1476     , _parent (0)
1477 #endif
1478   {
1479     lua_getglobal (L, "_G");
1480     ++m_stackSize;
1481   }
1482
1483 #ifdef LUABINDINGDOC
1484   std::string _name;
1485   Namespace const * _parent;
1486 #endif
1487
1488   //----------------------------------------------------------------------------
1489   /**
1490       Open a namespace for registrations.
1491
1492       The namespace is created if it doesn't already exist.
1493       The parent namespace is at the top of the Lua stack.
1494   */
1495   Namespace (char const* name, Namespace const* parent)
1496     : L (parent->L)
1497     , m_stackSize (0)
1498 #ifdef LUABINDINGDOC
1499     , _name (parent->_name + name + ":")
1500     , _parent (parent)
1501 #endif
1502   {
1503     m_stackSize = parent->m_stackSize + 1;
1504     parent->m_stackSize = 0;
1505
1506     assert (lua_istable (L, -1));
1507     rawgetfield (L, -1, name);
1508     if (lua_isnil (L, -1))
1509     {
1510       lua_pop (L, 1);
1511
1512       lua_newtable (L);
1513       lua_pushvalue (L, -1);
1514       lua_setmetatable (L, -2);
1515       lua_pushcfunction (L, &CFunc::indexMetaMethod);
1516       rawsetfield (L, -2, "__index");
1517       lua_pushcfunction (L, &CFunc::newindexMetaMethod);
1518       rawsetfield (L, -2, "__newindex");
1519       lua_newtable (L);
1520       rawsetfield (L, -2, "__propget");
1521       lua_newtable (L);
1522       rawsetfield (L, -2, "__propset");
1523       lua_pushvalue (L, -1);
1524       rawsetfield (L, -3, name);
1525 #if 0
1526       lua_pushcfunction (L, &tostringMetaMethod);
1527       rawsetfield (L, -2, "__tostring");
1528 #endif
1529     }
1530   }
1531
1532   //----------------------------------------------------------------------------
1533   /**
1534       Creates a continued registration from a child namespace.
1535   */
1536   explicit Namespace (Namespace const* child)
1537     : L (child->L)
1538     , m_stackSize (0)
1539 #ifdef LUABINDINGDOC
1540     , _name (child->_parent ? child->_parent->_name : "")
1541     , _parent (child->_parent ? child->_parent->_parent : NULL)
1542 #endif
1543   {
1544     m_stackSize = child->m_stackSize - 1;
1545     child->m_stackSize = 1;
1546     child->pop (1);
1547
1548     // It is not necessary or valid to call
1549     // endNamespace() for the global namespace!
1550     //
1551     assert (m_stackSize != 0);
1552   }
1553
1554   //----------------------------------------------------------------------------
1555   /**
1556       Creates a continued registration from a child class.
1557   */
1558   explicit Namespace (ClassBase const* child)
1559     : L (child->L)
1560     , m_stackSize (0)
1561 #ifdef LUABINDINGDOC
1562     , _name (child->_parent ? child->_parent->_name : "")
1563     , _parent (child->_parent ? child->_parent->_parent : NULL)
1564 #endif
1565   {
1566     m_stackSize = child->m_stackSize - 3;
1567     child->m_stackSize = 3;
1568     child->pop (3);
1569   }
1570
1571 public:
1572   //----------------------------------------------------------------------------
1573   /**
1574       Copy Constructor.
1575
1576       Ownership of the stack is transferred to the new object. This happens
1577       when the compiler emits temporaries to hold these objects while chaining
1578       registrations across namespaces.
1579   */
1580   Namespace (Namespace const& other) : L (other.L)
1581   {
1582     m_stackSize = other.m_stackSize;
1583     other.m_stackSize = 0;
1584 #ifdef LUABINDINGDOC
1585     _name = other._name;
1586     _parent = other._parent;
1587 #endif
1588   }
1589
1590   //----------------------------------------------------------------------------
1591   /**
1592       Closes this namespace registration.
1593   */
1594   ~Namespace ()
1595   {
1596     pop (m_stackSize);
1597   }
1598
1599   //----------------------------------------------------------------------------
1600   /**
1601       Open the global namespace.
1602   */
1603   static Namespace getGlobalNamespace (lua_State* L)
1604   {
1605     return Namespace (L);
1606   }
1607
1608   //----------------------------------------------------------------------------
1609   /**
1610       Open a new or existing namespace for registrations.
1611   */
1612   Namespace beginNamespace (char const* name)
1613   {
1614     return Namespace (name, this);
1615   }
1616
1617   //----------------------------------------------------------------------------
1618   /**
1619       Continue namespace registration in the parent.
1620
1621       Do not use this on the global namespace.
1622   */
1623   Namespace endNamespace ()
1624   {
1625     return Namespace (this);
1626   }
1627
1628   //----------------------------------------------------------------------------
1629   /**
1630       Add or replace a variable.
1631   */
1632   template <class T>
1633   Namespace& addVariable (char const* name, T* pt, bool isWritable = true)
1634   {
1635     assert (lua_istable (L, -1));
1636
1637     rawgetfield (L, -1, "__propget");
1638     assert (lua_istable (L, -1));
1639     lua_pushlightuserdata (L, pt);
1640     lua_pushcclosure (L, &CFunc::getVariable <T>, 1);
1641     rawsetfield (L, -2, name);
1642     lua_pop (L, 1);
1643
1644     rawgetfield (L, -1, "__propset");
1645     assert (lua_istable (L, -1));
1646     if (isWritable)
1647     {
1648       lua_pushlightuserdata (L, pt);
1649       lua_pushcclosure (L, &CFunc::setVariable <T>, 1);
1650     }
1651     else
1652     {
1653       lua_pushstring (L, name);
1654       lua_pushcclosure (L, &CFunc::readOnlyError, 1);
1655     }
1656     rawsetfield (L, -2, name);
1657     lua_pop (L, 1);
1658
1659     return *this;
1660   }
1661
1662   template <typename U>
1663   Namespace& addConst (char const* name, const U val)
1664   {
1665     DATADOC ("Constant/Enum", name, val)
1666     assert (lua_istable (L, -1));
1667     rawgetfield (L, -1, "__propget");
1668     new (lua_newuserdata (L, sizeof (val))) U (val);
1669     lua_pushcclosure (L, &CFunc::getConst <U>, 1);
1670     rawsetfield (L, -2, name);
1671     lua_pop (L, 1);
1672
1673     rawgetfield (L, -1, "__propset");
1674     assert (lua_istable (L, -1));
1675     lua_pushstring (L, name);
1676     lua_pushcclosure (L, &CFunc::readOnlyError, 1);
1677     rawsetfield (L, -2, name);
1678     lua_pop (L, 1);
1679     return *this;
1680   }
1681
1682   //----------------------------------------------------------------------------
1683   /**
1684       Add or replace a property.
1685
1686       If the set function is omitted or null, the property is read-only.
1687   */
1688 #if 0 // unused
1689   template <class TG, class TS>
1690   Namespace& addProperty (char const* name, TG (*get) (), void (*set)(TS) = 0)
1691   {
1692     assert (lua_istable (L, -1));
1693
1694     rawgetfield (L, -1, "__propget");
1695     assert (lua_istable (L, -1));
1696     typedef TG (*get_t) ();
1697     new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
1698     lua_pushcclosure (L, &CFunc::Call <TG (*) (void)>::f, 1);
1699     rawsetfield (L, -2, name);
1700     lua_pop (L, 1);
1701
1702     rawgetfield (L, -1, "__propset");
1703     assert (lua_istable (L, -1));
1704     if (set != 0)
1705     {
1706       typedef void (*set_t) (TS);
1707       new (lua_newuserdata (L, sizeof (set_t))) set_t (set);
1708       lua_pushcclosure (L, &CFunc::Call <void (*) (TS)>::f, 1);
1709     }
1710     else
1711     {
1712       lua_pushstring (L, name);
1713       lua_pushcclosure (L, &CFunc::readOnlyError, 1);
1714     }
1715     rawsetfield (L, -2, name);
1716     lua_pop (L, 1);
1717
1718     return *this;
1719   }
1720 #endif
1721
1722   //----------------------------------------------------------------------------
1723   /**
1724       Add or replace a free function.
1725   */
1726   template <class FP>
1727   Namespace& addFunction (char const* name, FP const fp)
1728   {
1729     FUNDOC ("Free Function", name, FP)
1730     assert (lua_istable (L, -1));
1731
1732     new (lua_newuserdata (L, sizeof (fp))) FP (fp);
1733     lua_pushcclosure (L, &CFunc::Call <FP>::f, 1);
1734     rawsetfield (L, -2, name);
1735
1736     return *this;
1737   }
1738
1739   template <class FP>
1740   Namespace& addRefFunction (char const* name, FP const fp)
1741   {
1742     FUNDOC ("Free Function RefReturn", name, FP)
1743     assert (lua_istable (L, -1));
1744
1745     new (lua_newuserdata (L, sizeof (fp))) FP (fp);
1746     lua_pushcclosure (L, &CFunc::CallRef <FP>::f, 1);
1747     rawsetfield (L, -2, name);
1748
1749     return *this;
1750   }
1751
1752   //----------------------------------------------------------------------------
1753   /**
1754       Add or replace a array type
1755   */
1756
1757   template <typename T>
1758   Namespace registerArray (char const* name)
1759   {
1760     return Array <T> (name, this).endArray();
1761   }
1762
1763
1764   //----------------------------------------------------------------------------
1765   /**
1766       Add or replace a lua_CFunction.
1767   */
1768   Namespace& addCFunction (char const* name, int (*const fp)(lua_State*))
1769   {
1770     DATADOC ("Free C Function", name, fp)
1771     lua_pushcfunction (L, fp);
1772     rawsetfield (L, -2, name);
1773
1774     return *this;
1775   }
1776
1777   //----------------------------------------------------------------------------
1778   /**
1779       Open a new or existing class for registrations.
1780   */
1781   template <class T>
1782   Class <T> beginClass (char const* name)
1783   {
1784     return Class <T> (name, this);
1785   }
1786
1787   /** weak & shared pointer class */
1788   template <class T>
1789   WSPtrClass <T> beginWSPtrClass (char const* name)
1790   {
1791     return WSPtrClass <T> (name, this)
1792       .addNullCheck()
1793       .addEqualCheck();
1794   }
1795
1796   //----------------------------------------------------------------------------
1797
1798   template <class K, class V>
1799   Class<std::map<K, V> > beginStdMap (char const* name)
1800   {
1801     typedef std::map<K, V> LT;
1802     typedef std::pair<const K, V> T;
1803
1804     typedef typename std::map<K, V>::size_type T_SIZE;
1805
1806     return beginClass<LT> (name)
1807       .addVoidConstructor ()
1808       .addFunction ("empty", &LT::empty)
1809       .addFunction ("size", &LT::size)
1810       .addFunction ("clear", (void (LT::*)())&LT::clear)
1811       .addFunction ("count", (T_SIZE (LT::*)(const K&) const)&LT::count)
1812       .addExtCFunction ("add", &CFunc::tableToMap<K, V>)
1813       .addExtCFunction ("iter", &CFunc::mapIter<K, V>)
1814       .addExtCFunction ("table", &CFunc::mapToTable<K, V>)
1815       .addExtCFunction ("at", &CFunc::mapAt<K, V>);
1816   }
1817
1818   template <class T>
1819   Class<std::set<T> > beginStdSet (char const* name)
1820   {
1821     typedef std::set<T> LT;
1822     return beginClass<LT> (name)
1823       .addVoidConstructor ()
1824       .addFunction ("clear", (void (LT::*)())&LT::clear)
1825       .addFunction ("empty", &LT::empty)
1826       .addFunction ("size", &LT::size)
1827       .addExtCFunction ("iter", &CFunc::setIter<T, LT>)
1828       .addExtCFunction ("table", &CFunc::setToTable<T, LT>);
1829   }
1830
1831   template <unsigned int T>
1832   Class<std::bitset<T> > beginStdBitSet (char const* name)
1833   {
1834     typedef std::bitset<T> BS;
1835     return beginClass<BS> (name)
1836       .addVoidConstructor ()
1837       .addFunction ("reset", (BS& (BS::*)())&BS::reset)
1838       .addFunction ("set", (BS& (BS::*)(size_t, bool))&BS::set)
1839       .addFunction ("count", &BS::count)
1840       .addFunction ("any", &BS::any)
1841       .addFunction ("none", &BS::none)
1842       .addFunction ("test", &BS::test)
1843       .addFunction ("size", &BS::size)
1844       .addExtCFunction ("add", &CFunc::tableToBitSet<T>)
1845       .addExtCFunction ("table", &CFunc::bitSetToTable<T>);
1846   }
1847
1848   template <class T>
1849   Class<std::list<T> > beginConstStdList (char const* name)
1850   {
1851     typedef std::list<T> LT;
1852     return beginClass<LT> (name)
1853       .addVoidConstructor ()
1854       .addFunction ("empty", &LT::empty)
1855       .addFunction ("size", &LT::size)
1856       .addFunction ("reverse", &LT::reverse)
1857       .addFunction ("front", static_cast<const T& (LT::*)() const>(&LT::front))
1858       .addFunction ("back", static_cast<const T& (LT::*)() const>(&LT::back))
1859       .addExtCFunction ("iter", &CFunc::listIter<T, LT>)
1860       .addExtCFunction ("table", &CFunc::listToTable<T, LT>);
1861   }
1862
1863   template <class T>
1864   Class<std::list<T> > beginStdList (char const* name)
1865   {
1866     typedef std::list<T> LT;
1867     return beginConstStdList<T> (name)
1868       .addFunction ("unique", (void (LT::*)())&LT::unique)
1869       .addFunction ("push_back", (void (LT::*)(const T&))&LT::push_back)
1870       .addExtCFunction ("add", &CFunc::tableToList<T, LT>);
1871   }
1872
1873   template <class T>
1874   Class<std::list<T*> > beginConstStdCPtrList (char const* name)
1875   {
1876     typedef T* TP;
1877     typedef std::list<TP> LT;
1878     return beginClass<LT> (name)
1879       .addVoidConstructor ()
1880       .addFunction ("empty", &LT::empty)
1881       .addFunction ("size", &LT::size)
1882       .addFunction ("reverse", &LT::reverse)
1883       .addFunction ("front", static_cast<const TP& (LT::*)() const>(&LT::front))
1884       .addFunction ("back", static_cast<const TP& (LT::*)() const>(&LT::back))
1885       .addExtCFunction ("iter", &CFunc::listIter<T*, LT>)
1886       .addExtCFunction ("table", &CFunc::listToTable<T*, LT>);
1887   }
1888
1889   template <class T>
1890   Class<std::list<T*> > beginStdCPtrList (char const* name)
1891   {
1892     typedef T* TP;
1893     typedef std::list<TP> LT;
1894     return beginConstStdCPtrList<T> (name)
1895       .addFunction ("unique", (void (LT::*)())&LT::unique)
1896       .addFunction ("push_back", (void (LT::*)(const TP&))&LT::push_back);
1897   }
1898
1899
1900   template <class T>
1901   Class<std::vector<T> > beginConstStdVector (char const* name)
1902   {
1903     typedef std::vector<T> LT;
1904     typedef typename std::vector<T>::reference T_REF;
1905     typedef typename std::vector<T>::size_type T_SIZE;
1906
1907     return beginClass<LT> (name)
1908       .addVoidConstructor ()
1909       .addFunction ("empty", &LT::empty)
1910       .addFunction ("size", &LT::size)
1911       .addFunction ("at", (T_REF (LT::*)(T_SIZE))&LT::at)
1912       .addExtCFunction ("iter", &CFunc::listIter<T, LT>)
1913       .addExtCFunction ("table", &CFunc::listToTable<T, LT>);
1914   }
1915
1916   template <class T>
1917   Class<std::vector<T> > beginStdVector (char const* name)
1918   {
1919     typedef std::vector<T> LT;
1920     return beginConstStdVector<T> (name)
1921       .addVoidConstructor ()
1922       .addFunction ("push_back", (void (LT::*)(const T&))&LT::push_back)
1923       .addExtCFunction ("add", &CFunc::tableToList<T, LT>);
1924   }
1925
1926
1927
1928   //----------------------------------------------------------------------------
1929
1930   template <class T>
1931   Class<boost::shared_ptr<std::list<T> > > beginPtrStdList (char const* name)
1932   {
1933     typedef std::list<T> LT;
1934     return beginClass<boost::shared_ptr<LT> > (name)
1935       //.addVoidPtrConstructor<LT> ()
1936       .addPtrFunction ("empty", &LT::empty)
1937       .addPtrFunction ("size", &LT::size)
1938       .addPtrFunction ("reverse", &LT::reverse)
1939       .addPtrFunction ("unique", (void (LT::*)())&LT::unique)
1940       .addPtrFunction ("push_back", (void (LT::*)(const T&))&LT::push_back)
1941       .addExtCFunction ("add", &CFunc::ptrTableToList<T, LT>)
1942       .addExtCFunction ("iter", &CFunc::ptrListIter<T, LT>)
1943       .addExtCFunction ("table", &CFunc::ptrListToTable<T, LT>);
1944   }
1945
1946   template <class T>
1947   Class<boost::shared_ptr<std::vector<T> > > beginPtrStdVector (char const* name)
1948   {
1949     typedef std::vector<T> LT;
1950     typedef typename std::vector<T>::reference T_REF;
1951     typedef typename std::vector<T>::size_type T_SIZE;
1952
1953     return beginClass<boost::shared_ptr<LT> > (name)
1954       //.addVoidPtrConstructor<LT> ()
1955       .addPtrFunction ("empty", &LT::empty)
1956       .addPtrFunction ("empty", &LT::empty)
1957       .addPtrFunction ("size", &LT::size)
1958       .addPtrFunction ("push_back", (void (LT::*)(const T&))&LT::push_back)
1959       .addPtrFunction ("at", (T_REF (LT::*)(T_SIZE))&LT::at)
1960       .addExtCFunction ("add", &CFunc::ptrTableToList<T, LT>)
1961       .addExtCFunction ("iter", &CFunc::ptrListIter<T, LT>)
1962       .addExtCFunction ("table", &CFunc::ptrListToTable<T, LT>);
1963   }
1964
1965   //----------------------------------------------------------------------------
1966   /**
1967       Derive a new class for registrations.
1968
1969       To continue registrations for the class later, use beginClass().
1970       Do not call deriveClass() again.
1971   */
1972   template <class T, class U>
1973   Class <T> deriveClass (char const* name)
1974   {
1975     CLASSDOC ("[C] Derived Class", _name << name, type_name <T>(), type_name <U>())
1976     return Class <T> (name, this, ClassInfo <U>::getStaticKey ());
1977   }
1978
1979   template <class T, class U>
1980   WSPtrClass <T> deriveWSPtrClass (char const* name)
1981   {
1982
1983     CLASSDOC ("[C] Derived Class", _name << name, type_name <boost::shared_ptr<T> >(), type_name <boost::shared_ptr<U> >())
1984     CLASSDOC ("[C] Derived Class", _name << name, type_name <boost::weak_ptr<T> >(), type_name <boost::weak_ptr<U> >())
1985     CLASSDOC ("[C] Derived Pointer Class", _name << name, type_name <T>(), type_name <U>())
1986     return WSPtrClass <T> (name, this,
1987         ClassInfo <boost::shared_ptr<U> >::getStaticKey (),
1988         ClassInfo <boost::weak_ptr<U> >::getStaticKey ())
1989       .addNullCheck()
1990       .addEqualCheck();
1991   }
1992
1993 };
1994
1995 //------------------------------------------------------------------------------
1996 /**
1997     Retrieve the global namespace.
1998
1999     It is recommended to put your namespace inside the global namespace, and
2000     then add your classes and functions to it, rather than adding many classes
2001     and functions directly to the global namespace.
2002 */
2003 inline Namespace getGlobalNamespace (lua_State* L)
2004 {
2005   return Namespace::getGlobalNamespace (L);
2006 }
2007
2008
2009 #undef KEYSTA
2010 #undef KEYEND
2011 #undef CLASSDOC
2012 #undef PRINTDOC
2013 #undef FUNDOC
2014 #undef DATADOC
2015
2016 /* vim: set et sw=2: */