NO-OP whitespace
[ardour.git] / libs / lua / LuaBridge / detail / Namespace.h
1 //------------------------------------------------------------------------------
2 /*
3   https://github.com/vinniefalco/LuaBridge
4
5   Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
6   Copyright 2007, Nathan Reed
7
8   License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
9
10   Permission is hereby granted, free of charge, to any person obtaining a copy
11   of this software and associated documentation files (the "Software"), to deal
12   in the Software without restriction, including without limitation the rights
13   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14   copies of the Software, and to permit persons to whom the Software is
15   furnished to do so, subject to the following conditions:
16
17   The above copyright notice and this permission notice shall be included in all
18   copies or substantial portions of the Software.
19
20   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26   SOFTWARE.
27 */
28 //==============================================================================
29
30 /** Provides C++ to Lua registration capabilities.
31
32     This class is not instantiated directly, call `getGlobalNamespace` to start
33     the registration process.
34 */
35 class Namespace
36 {
37 private:
38   Namespace& operator= (Namespace const& other);
39
40   lua_State* const L;
41   int mutable m_stackSize;
42
43 private:
44   //============================================================================
45   /**
46     Error reporting.
47
48     VF: This function looks handy, why aren't we using it?
49   */
50 #if 0
51   static int luaError (lua_State* L, std::string message)
52   {
53     assert (lua_isstring (L, lua_upvalueindex (1)));
54     std::string s;
55
56     // Get information on the caller's caller to format the message,
57     // so the error appears to originate from the Lua source.
58     lua_Debug ar;
59     int result = lua_getstack (L, 2, &ar);
60     if (result != 0)
61     {
62       lua_getinfo (L, "Sl", &ar);
63       s = ar.short_src;
64       if (ar.currentline != -1)
65       {
66         // poor mans int to string to avoid <strstrream>.
67         lua_pushnumber (L, ar.currentline);
68         s = s + ":" + lua_tostring (L, -1) + ": ";
69         lua_pop (L, 1);
70       }
71     }
72
73     s = s + message;
74
75     return luaL_error (L, s.c_str ());
76   }
77 #endif
78
79   //----------------------------------------------------------------------------
80   /**
81     Pop the Lua stack.
82   */
83   void pop (int n) const
84   {
85     if (m_stackSize >= n && lua_gettop (L) >= n)
86     {
87       lua_pop (L, n);
88       m_stackSize -= n;
89     }
90     else
91     {
92       throw std::logic_error ("invalid stack");
93     }
94   }
95
96 private:
97   /**
98     Factored base to reduce template instantiations.
99   */
100   class ClassBase
101   {
102   private:
103     ClassBase& operator= (ClassBase const& other);
104
105   protected:
106     friend class Namespace;
107
108     lua_State* const L;
109     int mutable m_stackSize;
110
111   protected:
112     //--------------------------------------------------------------------------
113     /**
114       __index metamethod for a class.
115
116       This implements member functions, data members, and property members.
117       Functions are stored in the metatable and const metatable. Data members
118       and property members are in the __propget table.
119
120       If the key is not found, the search proceeds up the hierarchy of base
121       classes.
122     */
123     static int indexMetaMethod (lua_State* L)
124     {
125       int result = 0;
126
127       assert (lua_isuserdata (L, 1));               // warn on security bypass
128       lua_getmetatable (L, 1);                      // get metatable for object
129       for (;;)
130       {
131         lua_pushvalue (L, 2);                       // push key arg2
132         lua_rawget (L, -2);                         // lookup key in metatable
133         if (lua_iscfunction (L, -1))                // ensure its a cfunction
134         {
135           lua_remove (L, -2);                       // remove metatable
136           result = 1;
137           break;
138         }
139         else if (lua_isnil (L, -1))
140         {
141           lua_pop (L, 1);
142         }
143         else
144         {
145           lua_pop (L, 2);
146           throw std::logic_error ("not a cfunction");
147         }
148
149         rawgetfield (L, -1, "__propget");           // get __propget table
150         if (lua_istable (L, -1))                    // ensure it is a table
151         {
152           lua_pushvalue (L, 2);                     // push key arg2
153           lua_rawget (L, -2);                       // lookup key in __propget
154           lua_remove (L, -2);                       // remove __propget
155           if (lua_iscfunction (L, -1))              // ensure its a cfunction
156           {
157             lua_remove (L, -2);                     // remove metatable
158             lua_pushvalue (L, 1);                   // push class arg1
159             lua_call (L, 1, 1);
160             result = 1;
161             break;
162           }
163           else if (lua_isnil (L, -1))
164           {
165             lua_pop (L, 1);
166           }
167           else
168           {
169             lua_pop (L, 2);
170
171             // We only put cfunctions into __propget.
172             throw std::logic_error ("not a cfunction");
173           }
174         }
175         else
176         {
177           lua_pop (L, 2);
178
179           // __propget is missing, or not a table.
180           throw std::logic_error ("missing __propget table");
181         }
182
183         // Repeat the lookup in the __parent metafield,
184         // or return nil if the field doesn't exist.
185         rawgetfield (L, -1, "__parent");
186         if (lua_istable (L, -1))
187         {
188           // Remove metatable and repeat the search in __parent.
189           lua_remove (L, -2);
190         }
191         else if (lua_isnil (L, -1))
192         {
193           result = 1;
194           break;
195         }
196         else
197         {
198           lua_pop (L, 2);
199
200           throw std::logic_error ("__parent is not a table");
201         }
202       }
203
204       return result;
205     }
206
207     //--------------------------------------------------------------------------
208     /**
209       __newindex metamethod for classes.
210
211       This supports writable variables and properties on class objects. The
212       corresponding object is passed in the first parameter to the set function.
213     */
214     static int newindexMetaMethod (lua_State* L)
215     {
216       int result = 0;
217
218       lua_getmetatable (L, 1);
219
220       for (;;)
221       {
222         // Check __propset
223         rawgetfield (L, -1, "__propset");
224         if (!lua_isnil (L, -1))
225         {
226           lua_pushvalue (L, 2);
227           lua_rawget (L, -2);
228           if (!lua_isnil (L, -1))
229           {
230             // found it, call the setFunction.
231             assert (lua_isfunction (L, -1));
232             lua_pushvalue (L, 1);
233             lua_pushvalue (L, 3);
234             lua_call (L, 2, 0);
235             result = 0;
236             break;
237           }
238           lua_pop (L, 1);
239         }
240         lua_pop (L, 1);
241
242         // Repeat the lookup in the __parent metafield.
243         rawgetfield (L, -1, "__parent");
244         if (lua_isnil (L, -1))
245         {
246           // Either the property or __parent must exist.
247           result = luaL_error (L,
248             "no member named '%s'", lua_tostring (L, 2));
249         }
250         lua_remove (L, -2);
251       }
252
253       return result;
254     }
255
256     //--------------------------------------------------------------------------
257     /**
258       Create the const table.
259     */
260     void createConstTable (char const* name)
261     {
262       lua_newtable (L);
263       lua_pushvalue (L, -1);
264       lua_setmetatable (L, -2);
265       lua_pushboolean (L, 1);
266       lua_rawsetp (L, -2, getIdentityKey ());
267       lua_pushstring (L, (std::string ("const ") + name).c_str ());
268       rawsetfield (L, -2, "__type");
269       lua_pushcfunction (L, &indexMetaMethod);
270       rawsetfield (L, -2, "__index");
271       lua_pushcfunction (L, &newindexMetaMethod);
272       rawsetfield (L, -2, "__newindex");
273       lua_newtable (L);
274       rawsetfield (L, -2, "__propget");
275
276       if (Security::hideMetatables ())
277       {
278         lua_pushnil (L);
279         rawsetfield (L, -2, "__metatable");
280       }
281     }
282
283     //--------------------------------------------------------------------------
284     /**
285       Create the class table.
286
287       The Lua stack should have the const table on top.
288     */
289     void createClassTable (char const* name)
290     {
291       lua_newtable (L);
292       lua_pushvalue (L, -1);
293       lua_setmetatable (L, -2);
294       lua_pushboolean (L, 1);
295       lua_rawsetp (L, -2, getIdentityKey ());
296       lua_pushstring (L, name);
297       rawsetfield (L, -2, "__type");
298       lua_pushcfunction (L, &indexMetaMethod);
299       rawsetfield (L, -2, "__index");
300       lua_pushcfunction (L, &newindexMetaMethod);
301       rawsetfield (L, -2, "__newindex");
302       lua_newtable (L);
303       rawsetfield (L, -2, "__propget");
304       lua_newtable (L);
305       rawsetfield (L, -2, "__propset");
306
307       lua_pushvalue (L, -2);
308       rawsetfield (L, -2, "__const"); // point to const table
309
310       lua_pushvalue (L, -1);
311       rawsetfield (L, -3, "__class"); // point const table to class table
312
313       if (Security::hideMetatables ())
314       {
315         lua_pushnil (L);
316         rawsetfield (L, -2, "__metatable");
317       }
318     }
319
320     //--------------------------------------------------------------------------
321     /**
322       Create the static table.
323
324       The Lua stack should have:
325         -1 class table
326         -2 const table
327         -3 enclosing namespace
328     */
329     void createStaticTable (char const* name)
330     {
331       lua_newtable (L);
332       lua_newtable (L);
333       lua_pushvalue (L, -1);
334       lua_setmetatable (L, -3);
335       lua_insert (L, -2);
336       rawsetfield (L, -5, name);
337
338 #if 0
339       lua_pushlightuserdata (L, this);
340       lua_pushcclosure (L, &tostringMetaMethod, 1);
341       rawsetfield (L, -2, "__tostring");
342 #endif
343       lua_pushcfunction (L, &CFunc::indexMetaMethod);
344       rawsetfield (L, -2, "__index");
345       lua_pushcfunction (L, &CFunc::newindexMetaMethod);
346       rawsetfield (L, -2, "__newindex");
347       lua_newtable (L);
348       rawsetfield (L, -2, "__propget");
349       lua_newtable (L);
350       rawsetfield (L, -2, "__propset");
351
352       lua_pushvalue (L, -2);
353       rawsetfield (L, -2, "__class"); // point to class table
354
355       if (Security::hideMetatables ())
356       {
357         lua_pushnil (L);
358         rawsetfield (L, -2, "__metatable");
359       }
360     }
361
362     //==========================================================================
363     /**
364       lua_CFunction to construct a class object wrapped in a container.
365     */
366     template <class Params, class C>
367     static int ctorContainerProxy (lua_State* L)
368     {
369       typedef typename ContainerTraits <C>::Type T;
370       ArgList <Params, 2> args (L);
371       T* const p = Constructor <T, Params>::call (args);
372       UserdataSharedHelper <C, false>::push (L, p);
373       return 1;
374     }
375
376     //--------------------------------------------------------------------------
377     /**
378       lua_CFunction to construct a class object in-place in the userdata.
379     */
380     template <class Params, class T>
381     static int ctorPlacementProxy (lua_State* L)
382     {
383       ArgList <Params, 2> args (L);
384       Constructor <T, Params>::call (UserdataValue <T>::place (L), args);
385       return 1;
386     }
387
388     //--------------------------------------------------------------------------
389     /**
390       Pop the Lua stack.
391     */
392     void pop (int n) const
393     {
394       if (m_stackSize >= n && lua_gettop (L) >= n)
395       {
396         lua_pop (L, n);
397         m_stackSize -= n;
398       }
399       else
400       {
401         throw std::logic_error ("invalid stack");
402       }
403     }
404
405   public:
406     //--------------------------------------------------------------------------
407     explicit ClassBase (lua_State* L_)
408       : L (L_)
409       , m_stackSize (0)
410     {
411     }
412
413     //--------------------------------------------------------------------------
414     /**
415       Copy Constructor.
416     */
417     ClassBase (ClassBase const& other)
418       : L (other.L)
419       , m_stackSize (0)
420     {
421       m_stackSize = other.m_stackSize;
422       other.m_stackSize = 0;
423     }
424
425     ~ClassBase ()
426     {
427       pop (m_stackSize);
428     }
429   };
430
431   //============================================================================
432   //
433   // Class
434   //
435   //============================================================================
436   /**
437     Provides a class registration in a lua_State.
438
439     After contstruction the Lua stack holds these objects:
440       -1 static table
441       -2 class table
442       -3 const table
443       -4 (enclosing namespace)
444   */
445   template <class T>
446   class Class : public ClassBase
447   {
448   public:
449     //==========================================================================
450     /**
451       Register a new class or add to an existing class registration.
452     */
453     Class (char const* name, Namespace const* parent) : ClassBase (parent->L)
454     {
455       m_stackSize = parent->m_stackSize + 3;
456       parent->m_stackSize = 0;
457
458       assert (lua_istable (L, -1));
459       rawgetfield (L, -1, name);
460
461       if (lua_isnil (L, -1))
462       {
463         lua_pop (L, 1);
464
465         createConstTable (name);
466         lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
467         rawsetfield (L, -2, "__gc");
468
469         createClassTable (name);
470         lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
471         rawsetfield (L, -2, "__gc");
472
473         createStaticTable (name);
474
475         // Map T back to its tables.
476         lua_pushvalue (L, -1);
477         lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ());
478         lua_pushvalue (L, -2);
479         lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
480         lua_pushvalue (L, -3);
481         lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
482       }
483       else
484       {
485         rawgetfield (L, -1, "__class");
486         rawgetfield (L, -1, "__const");
487
488         // Reverse the top 3 stack elements
489         lua_insert (L, -3);
490         lua_insert (L, -2);
491       }
492     }
493
494     //==========================================================================
495     /**
496       Derive a new class.
497     */
498     Class (char const* name, Namespace const* parent, void const* const staticKey)
499       : ClassBase (parent->L)
500     {
501       m_stackSize = parent->m_stackSize + 3;
502       parent->m_stackSize = 0;
503
504       assert (lua_istable (L, -1));
505
506       createConstTable (name);
507       lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
508       rawsetfield (L, -2, "__gc");
509
510       createClassTable (name);
511       lua_pushcfunction (L, &CFunc::gcMetaMethod <T>);
512       rawsetfield (L, -2, "__gc");
513
514       createStaticTable (name);
515
516       lua_rawgetp (L, LUA_REGISTRYINDEX, staticKey);
517       assert (lua_istable (L, -1));
518       rawgetfield (L, -1, "__class");
519       assert (lua_istable (L, -1));
520       rawgetfield (L, -1, "__const");
521       assert (lua_istable (L, -1));
522
523       rawsetfield (L, -6, "__parent");
524       rawsetfield (L, -4, "__parent");
525       rawsetfield (L, -2, "__parent");
526
527       lua_pushvalue (L, -1);
528       lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ());
529       lua_pushvalue (L, -2);
530       lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
531       lua_pushvalue (L, -3);
532       lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
533     }
534
535     //--------------------------------------------------------------------------
536     /**
537       Continue registration in the enclosing namespace.
538     */
539     Namespace endClass ()
540     {
541       return Namespace (this);
542     }
543
544     //--------------------------------------------------------------------------
545     /**
546       Add or replace a static data member.
547     */
548     template <class U>
549     Class <T>& addStaticData (char const* name, U* pu, bool isWritable = true)
550     {
551       assert (lua_istable (L, -1));
552
553       rawgetfield (L, -1, "__propget");
554       assert (lua_istable (L, -1));
555       lua_pushlightuserdata (L, pu);
556       lua_pushcclosure (L, &CFunc::getVariable <U>, 1);
557       rawsetfield (L, -2, name);
558       lua_pop (L, 1);
559
560       rawgetfield (L, -1, "__propset");
561       assert (lua_istable (L, -1));
562       if (isWritable)
563       {
564         lua_pushlightuserdata (L, pu);
565         lua_pushcclosure (L, &CFunc::setVariable <U>, 1);
566       }
567       else
568       {
569         lua_pushstring (L, name);
570         lua_pushcclosure (L, &CFunc::readOnlyError, 1);
571       }
572       rawsetfield (L, -2, name);
573       lua_pop (L, 1);
574
575       return *this;
576     }
577
578     //--------------------------------------------------------------------------
579     /**
580       Add or replace a static property member.
581
582       If the set function is null, the property is read-only.
583     */
584     template <class U>
585     Class <T>& addStaticProperty (char const* name, U (*get)(), void (*set)(U) = 0)
586     {
587       typedef U (*get_t)();
588       typedef void (*set_t)(U);
589
590       assert (lua_istable (L, -1));
591
592       rawgetfield (L, -1, "__propget");
593       assert (lua_istable (L, -1));
594       new (lua_newuserdata (L, sizeof (get))) get_t (get);
595       lua_pushcclosure (L, &CFunc::Call <U (*) (void)>::f, 1);
596       rawsetfield (L, -2, name);
597       lua_pop (L, 1);
598
599       rawgetfield (L, -1, "__propset");
600       assert (lua_istable (L, -1));
601       if (set != 0)
602       {
603         new (lua_newuserdata (L, sizeof (set))) set_t (set);
604         lua_pushcclosure (L, &CFunc::Call <void (*) (U)>::f, 1);
605       }
606       else
607       {
608         lua_pushstring (L, name);
609         lua_pushcclosure (L, &CFunc::readOnlyError, 1);
610       }
611       rawsetfield (L, -2, name);
612       lua_pop (L, 1);
613
614       return *this;
615     }
616
617     //--------------------------------------------------------------------------
618     /**
619       Add or replace a static member function.
620     */
621     template <class FP>
622     Class <T>& addStaticFunction (char const* name, FP const fp)
623     {
624       new (lua_newuserdata (L, sizeof (fp))) FP (fp);
625       lua_pushcclosure (L, &CFunc::Call <FP>::f, 1);
626       rawsetfield (L, -2, name);
627
628       return *this;
629     }
630
631     //--------------------------------------------------------------------------
632     /**
633       Add or replace a lua_CFunction.
634     */
635     Class <T>& addStaticCFunction (char const* name, int (*const fp)(lua_State*))
636     {
637       lua_pushcfunction (L, fp);
638       rawsetfield (L, -2, name);
639       return *this;
640     }
641
642     //--------------------------------------------------------------------------
643     /**
644       Add or replace a data member.
645     */
646     template <class U>
647     Class <T>& addData (char const* name, const U T::* mp, bool isWritable = true)
648     {
649       typedef const U T::*mp_t;
650
651       // Add to __propget in class and const tables.
652       {
653         rawgetfield (L, -2, "__propget");
654         rawgetfield (L, -4, "__propget");
655         new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
656         lua_pushcclosure (L, &CFunc::getProperty <T,U>, 1);
657         lua_pushvalue (L, -1);
658         rawsetfield (L, -4, name);
659         rawsetfield (L, -2, name);
660         lua_pop (L, 2);
661       }
662
663       if (isWritable)
664       {
665         // Add to __propset in class table.
666         rawgetfield (L, -2, "__propset");
667         assert (lua_istable (L, -1));
668         new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp);
669         lua_pushcclosure (L, &CFunc::setProperty <T,U>, 1);
670         rawsetfield (L, -2, name);
671         lua_pop (L, 1);
672       }
673
674       return *this;
675     }
676
677     //--------------------------------------------------------------------------
678     /**
679       Add or replace a property member.
680     */
681     template <class TG, class TS>
682     Class <T>& addProperty (char const* name, TG (T::* get) () const, void (T::* set) (TS))
683     {
684       // Add to __propget in class and const tables.
685       {
686         rawgetfield (L, -2, "__propget");
687         rawgetfield (L, -4, "__propget");
688         typedef TG (T::*get_t) () const;
689         new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
690         lua_pushcclosure (L, &CFunc::CallConstMember <get_t>::f, 1);
691         lua_pushvalue (L, -1);
692         rawsetfield (L, -4, name);
693         rawsetfield (L, -2, name);
694         lua_pop (L, 2);
695       }
696
697       {
698         // Add to __propset in class table.
699         rawgetfield (L, -2, "__propset");
700         assert (lua_istable (L, -1));
701         typedef void (T::* set_t) (TS);
702         new (lua_newuserdata (L, sizeof (set_t))) set_t (set);
703         lua_pushcclosure (L, &CFunc::CallMember <set_t>::f, 1);
704         rawsetfield (L, -2, name);
705         lua_pop (L, 1);
706       }
707
708       return *this;
709     }
710
711     // read-only
712     template <class TG>
713     Class <T>& addProperty (char const* name, TG (T::* get) () const)
714     {
715       // Add to __propget in class and const tables.
716       rawgetfield (L, -2, "__propget");
717       rawgetfield (L, -4, "__propget");
718       typedef TG (T::*get_t) () const;
719       new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
720       lua_pushcclosure (L, &CFunc::CallConstMember <get_t>::f, 1);
721       lua_pushvalue (L, -1);
722       rawsetfield (L, -4, name);
723       rawsetfield (L, -2, name);
724       lua_pop (L, 2);
725
726       return *this;
727     }
728
729     //--------------------------------------------------------------------------
730     /**
731       Add or replace a property member, by proxy.
732
733       When a class is closed for modification and does not provide (or cannot
734       provide) the function signatures necessary to implement get or set for
735       a property, this will allow non-member functions act as proxies.
736
737       Both the get and the set functions require a T const* and T* in the first
738       argument respectively.
739     */
740     template <class TG, class TS>
741     Class <T>& addProperty (char const* name, TG (*get) (T const*), void (*set) (T*, TS))
742     {
743       // Add to __propget in class and const tables.
744       {
745         rawgetfield (L, -2, "__propget");
746         rawgetfield (L, -4, "__propget");
747         typedef TG (*get_t) (T const*);
748         new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
749         lua_pushcclosure (L, &CFunc::Call <get_t>::f, 1);
750         lua_pushvalue (L, -1);
751         rawsetfield (L, -4, name);
752         rawsetfield (L, -2, name);
753         lua_pop (L, 2);
754       }
755
756       if (set != 0)
757       {
758         // Add to __propset in class table.
759         rawgetfield (L, -2, "__propset");
760         assert (lua_istable (L, -1));
761         typedef void (*set_t) (T*, TS);
762         new (lua_newuserdata (L, sizeof (set_t))) set_t (set);
763         lua_pushcclosure (L, &CFunc::Call <set_t>::f, 1);
764         rawsetfield (L, -2, name);
765         lua_pop (L, 1);
766       }
767
768       return *this;
769     }
770
771     // read-only
772     template <class TG, class TS>
773     Class <T>& addProperty (char const* name, TG (*get) (T const*))
774     {
775       // Add to __propget in class and const tables.
776       rawgetfield (L, -2, "__propget");
777       rawgetfield (L, -4, "__propget");
778       typedef TG (*get_t) (T const*);
779       new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
780       lua_pushcclosure (L, &CFunc::Call <get_t>::f, 1);
781       lua_pushvalue (L, -1);
782       rawsetfield (L, -4, name);
783       rawsetfield (L, -2, name);
784       lua_pop (L, 2);
785
786       return *this;
787     }
788
789     //--------------------------------------------------------------------------
790     /**
791         Add or replace a member function.
792     */
793     template <class MemFn>
794     Class <T>& addFunction (char const* name, MemFn mf)
795     {
796       CFunc::CallMemberFunctionHelper <MemFn, FuncTraits <MemFn>::isConstMemberFunction>::add (L, name, mf);
797       return *this;
798     }
799
800     //--------------------------------------------------------------------------
801     /**
802         Add or replace a member lua_CFunction.
803     */
804     Class <T>& addCFunction (char const* name, int (T::*mfp)(lua_State*))
805     {
806       typedef int (T::*MFP)(lua_State*);
807       assert (lua_istable (L, -1));
808       new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp);
809       lua_pushcclosure (L, &CFunc::CallMemberCFunction <T>::f, 1);
810       rawsetfield (L, -3, name); // class table
811
812       return *this;
813     }
814
815     //--------------------------------------------------------------------------
816     /**
817         Add or replace a const member lua_CFunction.
818     */
819     Class <T>& addCFunction (char const* name, int (T::*mfp)(lua_State*) const)
820     {
821       typedef int (T::*MFP)(lua_State*) const;
822       assert (lua_istable (L, -1));
823       new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp);
824       lua_pushcclosure (L, &CFunc::CallConstMemberCFunction <T>::f, 1);
825       lua_pushvalue (L, -1);
826       rawsetfield (L, -5, name); // const table
827       rawsetfield (L, -3, name); // class table
828
829       return *this;
830     }
831
832     //--------------------------------------------------------------------------
833     /**
834       Add or replace a primary Constructor.
835
836       The primary Constructor is invoked when calling the class type table
837       like a function.
838
839       The template parameter should be a function pointer type that matches
840       the desired Constructor (since you can't take the address of a Constructor
841       and pass it as an argument).
842     */
843     template <class MemFn, class C>
844     Class <T>& addConstructor ()
845     {
846       lua_pushcclosure (L,
847         &ctorContainerProxy <typename FuncTraits <MemFn>::Params, C>, 0);
848       rawsetfield(L, -2, "__call");
849
850       return *this;
851     }
852
853     template <class MemFn>
854     Class <T>& addConstructor ()
855     {
856       lua_pushcclosure (L,
857         &ctorPlacementProxy <typename FuncTraits <MemFn>::Params, T>, 0);
858       rawsetfield(L, -2, "__call");
859
860       return *this;
861     }
862   };
863
864 private:
865   //----------------------------------------------------------------------------
866   /**
867       Open the global namespace for registrations.
868   */
869   explicit Namespace (lua_State* L_)
870     : L (L_)
871     , m_stackSize (0)
872   {
873     lua_getglobal (L, "_G");
874     ++m_stackSize;
875   }
876
877   //----------------------------------------------------------------------------
878   /**
879       Open a namespace for registrations.
880
881       The namespace is created if it doesn't already exist.
882       The parent namespace is at the top of the Lua stack.
883   */
884   Namespace (char const* name, Namespace const* parent)
885     : L (parent->L)
886     , m_stackSize (0)
887   {
888     m_stackSize = parent->m_stackSize + 1;
889     parent->m_stackSize = 0;
890
891     assert (lua_istable (L, -1));
892     rawgetfield (L, -1, name);
893     if (lua_isnil (L, -1))
894     {
895       lua_pop (L, 1);
896
897       lua_newtable (L);
898       lua_pushvalue (L, -1);
899       lua_setmetatable (L, -2);
900       lua_pushcfunction (L, &CFunc::indexMetaMethod);
901       rawsetfield (L, -2, "__index");
902       lua_pushcfunction (L, &CFunc::newindexMetaMethod);
903       rawsetfield (L, -2, "__newindex");
904       lua_newtable (L);
905       rawsetfield (L, -2, "__propget");
906       lua_newtable (L);
907       rawsetfield (L, -2, "__propset");
908       lua_pushvalue (L, -1);
909       rawsetfield (L, -3, name);
910 #if 0
911       lua_pushcfunction (L, &tostringMetaMethod);
912       rawsetfield (L, -2, "__tostring");
913 #endif
914     }
915   }
916
917   //----------------------------------------------------------------------------
918   /**
919       Creates a continued registration from a child namespace.
920   */
921   explicit Namespace (Namespace const* child)
922     : L (child->L)
923     , m_stackSize (0)
924   {
925     m_stackSize = child->m_stackSize - 1;
926     child->m_stackSize = 1;
927     child->pop (1);
928
929     // It is not necessary or valid to call
930     // endNamespace() for the global namespace!
931     //
932     assert (m_stackSize != 0);
933   }
934
935   //----------------------------------------------------------------------------
936   /**
937       Creates a continued registration from a child class.
938   */
939   explicit Namespace (ClassBase const* child)
940     : L (child->L)
941     , m_stackSize (0)
942   {
943     m_stackSize = child->m_stackSize - 3;
944     child->m_stackSize = 3;
945     child->pop (3);
946   }
947
948 public:
949   //----------------------------------------------------------------------------
950   /**
951       Copy Constructor.
952
953       Ownership of the stack is transferred to the new object. This happens
954       when the compiler emits temporaries to hold these objects while chaining
955       registrations across namespaces.
956   */
957   Namespace (Namespace const& other) : L (other.L)
958   {
959     m_stackSize = other.m_stackSize;
960     other.m_stackSize = 0;
961   }
962
963   //----------------------------------------------------------------------------
964   /**
965       Closes this namespace registration.
966   */
967   ~Namespace ()
968   {
969     pop (m_stackSize);
970   }
971
972   //----------------------------------------------------------------------------
973   /**
974       Open the global namespace.
975   */
976   static Namespace getGlobalNamespace (lua_State* L)
977   {
978     return Namespace (L);
979   }
980
981   //----------------------------------------------------------------------------
982   /**
983       Open a new or existing namespace for registrations.
984   */
985   Namespace beginNamespace (char const* name)
986   {
987     return Namespace (name, this);
988   }
989
990   //----------------------------------------------------------------------------
991   /**
992       Continue namespace registration in the parent.
993
994       Do not use this on the global namespace.
995   */
996   Namespace endNamespace ()
997   {
998     return Namespace (this);
999   }
1000
1001   //----------------------------------------------------------------------------
1002   /**
1003       Add or replace a variable.
1004   */
1005   template <class T>
1006   Namespace& addVariable (char const* name, T* pt, bool isWritable = true)
1007   {
1008     assert (lua_istable (L, -1));
1009
1010     rawgetfield (L, -1, "__propget");
1011     assert (lua_istable (L, -1));
1012     lua_pushlightuserdata (L, pt);
1013     lua_pushcclosure (L, &CFunc::getVariable <T>, 1);
1014     rawsetfield (L, -2, name);
1015     lua_pop (L, 1);
1016
1017     rawgetfield (L, -1, "__propset");
1018     assert (lua_istable (L, -1));
1019     if (isWritable)
1020     {
1021       lua_pushlightuserdata (L, pt);
1022       lua_pushcclosure (L, &CFunc::setVariable <T>, 1);
1023     }
1024     else
1025     {
1026       lua_pushstring (L, name);
1027       lua_pushcclosure (L, &CFunc::readOnlyError, 1);
1028     }
1029     rawsetfield (L, -2, name);
1030     lua_pop (L, 1);
1031
1032     return *this;
1033   }
1034
1035   //----------------------------------------------------------------------------
1036   /**
1037       Add or replace a property.
1038
1039       If the set function is omitted or null, the property is read-only.
1040   */
1041   template <class TG, class TS>
1042   Namespace& addProperty (char const* name, TG (*get) (), void (*set)(TS) = 0)
1043   {
1044     assert (lua_istable (L, -1));
1045
1046     rawgetfield (L, -1, "__propget");
1047     assert (lua_istable (L, -1));
1048     typedef TG (*get_t) ();
1049     new (lua_newuserdata (L, sizeof (get_t))) get_t (get);
1050     lua_pushcclosure (L, &CFunc::Call <TG (*) (void)>::f, 1);
1051     rawsetfield (L, -2, name);
1052     lua_pop (L, 1);
1053
1054     rawgetfield (L, -1, "__propset");
1055     assert (lua_istable (L, -1));
1056     if (set != 0)
1057     {
1058       typedef void (*set_t) (TS);
1059       new (lua_newuserdata (L, sizeof (set_t))) set_t (set);
1060       lua_pushcclosure (L, &CFunc::Call <void (*) (TS)>::f, 1);
1061     }
1062     else
1063     {
1064       lua_pushstring (L, name);
1065       lua_pushcclosure (L, &CFunc::readOnlyError, 1);
1066     }
1067     rawsetfield (L, -2, name);
1068     lua_pop (L, 1);
1069
1070     return *this;
1071   }
1072
1073   //----------------------------------------------------------------------------
1074   /**
1075       Add or replace a free function.
1076   */
1077   template <class FP>
1078   Namespace& addFunction (char const* name, FP const fp)
1079   {
1080     assert (lua_istable (L, -1));
1081
1082     new (lua_newuserdata (L, sizeof (fp))) FP (fp);
1083     lua_pushcclosure (L, &CFunc::Call <FP>::f, 1);
1084     rawsetfield (L, -2, name);
1085
1086     return *this;
1087   }
1088
1089   //----------------------------------------------------------------------------
1090   /**
1091       Add or replace a lua_CFunction.
1092   */
1093   Namespace& addCFunction (char const* name, int (*const fp)(lua_State*))
1094   {
1095     lua_pushcfunction (L, fp);
1096     rawsetfield (L, -2, name);
1097
1098     return *this;
1099   }
1100
1101   //----------------------------------------------------------------------------
1102   /**
1103       Open a new or existing class for registrations.
1104   */
1105   template <class T>
1106   Class <T> beginClass (char const* name)
1107   {
1108     return Class <T> (name, this);
1109   }
1110
1111   //----------------------------------------------------------------------------
1112   /**
1113       Derive a new class for registrations.
1114
1115       To continue registrations for the class later, use beginClass().
1116       Do not call deriveClass() again.
1117   */
1118   template <class T, class U>
1119   Class <T> deriveClass (char const* name)
1120   {
1121     return Class <T> (name, this, ClassInfo <U>::getStaticKey ());
1122   }
1123 };
1124
1125 //------------------------------------------------------------------------------
1126 /**
1127     Retrieve the global namespace.
1128
1129     It is recommended to put your namespace inside the global namespace, and
1130     then add your classes and functions to it, rather than adding many classes
1131     and functions directly to the global namespace.
1132 */
1133 inline Namespace getGlobalNamespace (lua_State* L)
1134 {
1135   return Namespace::getGlobalNamespace (L);
1136 }