9f1712995a89f68a39f7b5263b55c5e7064064a4
[ardour.git] / CFunctions.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
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 // We use a structure so we can define everything in the header.
31 //
32 struct CFunc
33 {
34   //----------------------------------------------------------------------------
35   /**
36       __index metamethod for a namespace or class static members.
37
38       This handles:
39         Retrieving functions and class static methods, stored in the metatable.
40         Reading global and class static data, stored in the __propget table.
41         Reading global and class properties, stored in the __propget table.
42   */
43   static int indexMetaMethod (lua_State* L)
44   {
45     int result = 0;
46     lua_getmetatable (L, 1);                // push metatable of arg1
47     for (;;)
48     {
49       lua_pushvalue (L, 2);                 // push key arg2
50       lua_rawget (L, -2);                   // lookup key in metatable
51       if (lua_isnil (L, -1))                // not found
52       {
53         lua_pop (L, 1);                     // discard nil
54         rawgetfield (L, -1, "__propget");   // lookup __propget in metatable
55         lua_pushvalue (L, 2);               // push key arg2
56         lua_rawget (L, -2);                 // lookup key in __propget
57         lua_remove (L, -2);                 // discard __propget
58         if (lua_iscfunction (L, -1))
59         {
60           lua_remove (L, -2);               // discard metatable
61           lua_pushvalue (L, 1);             // push arg1
62           lua_call (L, 1, 1);               // call cfunction
63           result = 1;
64           break;
65         }
66         else
67         {
68           assert (lua_isnil (L, -1));
69           lua_pop (L, 1);                   // discard nil and fall through
70         }
71       }
72       else
73       {
74         assert (lua_istable (L, -1) || lua_iscfunction (L, -1));
75         lua_remove (L, -2);
76         result = 1;
77         break;
78       }
79
80       rawgetfield (L, -1, "__parent");
81       if (lua_istable (L, -1))
82       {
83         // Remove metatable and repeat the search in __parent.
84         lua_remove (L, -2);
85       }
86       else
87       {
88         // Discard metatable and return nil.
89         assert (lua_isnil (L, -1));
90         lua_remove (L, -2);
91         result = 1;
92         break;
93       }
94     }
95
96     return result;
97   }
98
99   //----------------------------------------------------------------------------
100   /**
101       __newindex metamethod for a namespace or class static members.
102
103       The __propset table stores proxy functions for assignment to:
104         Global and class static data.
105         Global and class properties.
106   */
107   static int newindexMetaMethod (lua_State* L)
108   {
109     int result = 0;
110     lua_getmetatable (L, 1);                // push metatable of arg1
111     for (;;)
112     {
113       rawgetfield (L, -1, "__propset");     // lookup __propset in metatable
114       assert (lua_istable (L, -1));
115       lua_pushvalue (L, 2);                 // push key arg2
116       lua_rawget (L, -2);                   // lookup key in __propset
117       lua_remove (L, -2);                   // discard __propset
118       if (lua_iscfunction (L, -1))          // ensure value is a cfunction
119       {
120         lua_remove (L, -2);                 // discard metatable
121         lua_pushvalue (L, 3);               // push new value arg3
122         lua_call (L, 1, 0);                 // call cfunction
123         result = 0;
124         break;
125       }
126       else
127       {
128         assert (lua_isnil (L, -1));
129         lua_pop (L, 1);
130       }
131
132       rawgetfield (L, -1, "__parent");
133       if (lua_istable (L, -1))
134       {
135         // Remove metatable and repeat the search in __parent.
136         lua_remove (L, -2);
137       }
138       else
139       {
140         assert (lua_isnil (L, -1));
141         lua_pop (L, 2);
142         result = luaL_error (L,"no writable variable '%s'", lua_tostring (L, 2));
143       }
144     }
145
146     return result;
147   }
148
149   //----------------------------------------------------------------------------
150   /**
151       lua_CFunction to report an error writing to a read-only value.
152
153       The name of the variable is in the first upvalue.
154   */
155   static int readOnlyError (lua_State* L)
156   {
157     std::string s;
158
159     s = s + "'" + lua_tostring (L, lua_upvalueindex (1)) + "' is read-only";
160
161     return luaL_error (L, s.c_str ());
162   }
163
164   //----------------------------------------------------------------------------
165   /**
166       lua_CFunction to get a variable.
167
168       This is used for global variables or class static data members.
169
170       The pointer to the data is in the first upvalue.
171   */
172   template <class T>
173   static int getVariable (lua_State* L)
174   {
175     assert (lua_islightuserdata (L, lua_upvalueindex (1)));
176     T const* ptr = static_cast <T const*> (lua_touserdata (L, lua_upvalueindex (1)));
177     assert (ptr != 0);
178     Stack <T>::push (L, *ptr);
179     return 1;
180   }
181
182   //----------------------------------------------------------------------------
183   /**
184       lua_CFunction to set a variable.
185
186       This is used for global variables or class static data members.
187
188       The pointer to the data is in the first upvalue.
189   */
190   template <class T>
191   static int setVariable (lua_State* L)
192   {
193     assert (lua_islightuserdata (L, lua_upvalueindex (1)));
194     T* ptr = static_cast <T*> (lua_touserdata (L, lua_upvalueindex (1)));
195     assert (ptr != 0);
196     *ptr = Stack <T>::get (L, 1);
197     return 0;
198   }
199
200   //----------------------------------------------------------------------------
201   /**
202       lua_CFunction to call a function with a return value.
203
204       This is used for global functions, global properties, class static methods,
205       and class static properties.
206
207       The function pointer is in the first upvalue.
208   */
209   template <class FnPtr,
210             class ReturnType = typename FuncTraits <FnPtr>::ReturnType>
211   struct Call
212   {
213     typedef typename FuncTraits <FnPtr>::Params Params;
214     static int f (lua_State* L)
215     {
216       assert (isfulluserdata (L, lua_upvalueindex (1)));
217       FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
218       assert (fnptr != 0);
219       ArgList <Params> args (L);
220       Stack <typename FuncTraits <FnPtr>::ReturnType>::push (L, FuncTraits <FnPtr>::call (fnptr, args));
221       return 1;
222     }
223   };
224
225   //----------------------------------------------------------------------------
226   /**
227       lua_CFunction to call a function with no return value.
228
229       This is used for global functions, global properties, class static methods,
230       and class static properties.
231
232       The function pointer is in the first upvalue.
233   */
234   template <class FnPtr>
235   struct Call <FnPtr, void>
236   {
237     typedef typename FuncTraits <FnPtr>::Params Params;
238     static int f (lua_State* L)
239     {
240       assert (isfulluserdata (L, lua_upvalueindex (1)));
241       FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
242       assert (fnptr != 0);
243       ArgList <Params> args (L);
244       FuncTraits <FnPtr>::call (fnptr, args);
245       return 0;
246     }
247   };
248
249   //----------------------------------------------------------------------------
250   /**
251       lua_CFunction to call a function with references as arguments.
252   */
253   template <class FnPtr,
254             class ReturnType = typename FuncTraits <FnPtr>::ReturnType>
255   struct CallRef
256   {
257     typedef typename FuncTraits <FnPtr>::Params Params;
258     static int f (lua_State* L)
259     {
260       assert (isfulluserdata (L, lua_upvalueindex (1)));
261       FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
262       assert (fnptr != 0);
263       ArgList <Params, 1> args (L);
264       Stack <typename FuncTraits <FnPtr>::ReturnType>::push (L, FuncTraits <FnPtr>::call (fnptr, args));
265       LuaRef v (newTable (L));
266       FuncArgs <Params, 0>::refs (v, args);
267       v.push(L);
268       return 2;
269     }
270   };
271
272   template <class FnPtr>
273   struct CallRef <FnPtr, void>
274   {
275     typedef typename FuncTraits <FnPtr>::Params Params;
276     static int f (lua_State* L)
277     {
278       assert (isfulluserdata (L, lua_upvalueindex (1)));
279       FnPtr const& fnptr = *static_cast <FnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
280       assert (fnptr != 0);
281       ArgList <Params, 1> args (L);
282       FuncTraits <FnPtr>::call (fnptr, args);
283       LuaRef v (newTable (L));
284       FuncArgs <Params, 0>::refs (v, args);
285       v.push(L);
286       return 1;
287     }
288   };
289
290
291   //----------------------------------------------------------------------------
292   /**
293       lua_CFunction to call a class member function with a return value.
294
295       The member function pointer is in the first upvalue.
296       The class userdata object is at the top of the Lua stack.
297   */
298   template <class MemFnPtr,
299             class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
300   struct CallMember
301   {
302     typedef typename FuncTraits <MemFnPtr>::ClassType T;
303     typedef typename FuncTraits <MemFnPtr>::Params Params;
304
305     static int f (lua_State* L)
306     {
307       assert (isfulluserdata (L, lua_upvalueindex (1)));
308       T* const t = Userdata::get <T> (L, 1, false);
309       MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
310       assert (fnptr != 0);
311       ArgList <Params, 2> args (L);
312       Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (t, fnptr, args));
313       return 1;
314     }
315   };
316
317   template <class MemFnPtr,
318             class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
319   struct CallConstMember
320   {
321     typedef typename FuncTraits <MemFnPtr>::ClassType T;
322     typedef typename FuncTraits <MemFnPtr>::Params Params;
323
324     static int f (lua_State* L)
325     {
326       assert (isfulluserdata (L, lua_upvalueindex (1)));
327       T const* const t = Userdata::get <T> (L, 1, true);
328       MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
329       assert (fnptr != 0);
330       ArgList <Params, 2> args(L);
331       Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (t, fnptr, args));
332       return 1;
333     }
334   };
335
336   template <class MemFnPtr, class T,
337            class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
338   struct CallMemberPtr
339   {
340     typedef typename FuncTraits <MemFnPtr>::Params Params;
341
342     static int f (lua_State* L)
343     {
344       assert (isfulluserdata (L, lua_upvalueindex (1)));
345       boost::shared_ptr<T>* const t = Userdata::get <boost::shared_ptr<T> > (L, 1, false);
346       T* const tt = t->get();
347       if (!tt) {
348         return luaL_error (L, "shared_ptr is nil");
349       }
350       MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
351       assert (fnptr != 0);
352       ArgList <Params, 2> args (L);
353       Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (tt, fnptr, args));
354       return 1;
355     }
356   };
357
358   template <class T, class R>
359   struct CastMemberPtr
360   {
361     static int f (lua_State* L)
362     {
363       boost::shared_ptr<T> t = luabridge::Stack<boost::shared_ptr<T> >::get (L, 1);
364       Stack <boost::shared_ptr<R> >::push (L, boost::dynamic_pointer_cast<R> (t));
365       return 1;
366     }
367   };
368
369   template <class T>
370   struct ClassEqualCheck
371   {
372     static int f (lua_State* L)
373     {
374       T const* const t0 = Userdata::get <T> (L, 1, true);
375       T const* const t1 = Userdata::get <T> (L, 2, true);
376       Stack <bool>::push (L, t0 == t1);
377       return 1;
378     }
379   };
380
381
382   template <class T, class R>
383   struct CastClass
384   {
385     static int f (lua_State* L)
386     {
387       T * const t = Userdata::get <T> (L, 1, false );
388       Stack <R*>::push (L, dynamic_cast<R*>(t));
389       return 1;
390     }
391   };
392
393   template <class T, class R>
394   struct CastConstClass
395   {
396     static int f (lua_State* L)
397     {
398       T const* const t = Userdata::get <T> (L, 1, true);
399       Stack <R const*>::push (L, dynamic_cast<R const*>(t));
400       return 1;
401     }
402   };
403
404
405   template <class T>
406   struct PtrNullCheck
407   {
408     static int f (lua_State* L)
409     {
410       boost::shared_ptr<T> t = luabridge::Stack<boost::shared_ptr<T> >::get (L, 1);
411       Stack <bool>::push (L, t == 0);
412       return 1;
413     }
414   };
415
416   template <class T>
417   struct WPtrNullCheck
418   {
419     static int f (lua_State* L)
420     {
421       bool rv = true;
422       boost::weak_ptr<T> tw = luabridge::Stack<boost::weak_ptr<T> >::get (L, 1);
423       boost::shared_ptr<T> const t = tw.lock();
424       if (t) {
425         T* const tt = t.get();
426         rv = (tt == 0);
427       }
428       Stack <bool>::push (L, rv);
429       return 1;
430     }
431   };
432
433   template <class MemFnPtr, class T,
434            class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
435   struct CallMemberWPtr
436   {
437     typedef typename FuncTraits <MemFnPtr>::Params Params;
438
439     static int f (lua_State* L)
440     {
441       assert (isfulluserdata (L, lua_upvalueindex (1)));
442       boost::weak_ptr<T>* const tw = Userdata::get <boost::weak_ptr<T> > (L, 1, false);
443       boost::shared_ptr<T> const t = tw->lock();
444       if (!t) {
445         return luaL_error (L, "cannot lock weak_ptr");
446       }
447       T* const tt = t.get();
448       if (!tt) {
449         return luaL_error (L, "weak_ptr is nil");
450       }
451       MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
452       assert (fnptr != 0);
453       ArgList <Params, 2> args (L);
454       Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (tt, fnptr, args));
455       return 1;
456     }
457   };
458
459   /**
460       lua_CFunction to calls for function references.
461   */
462   template <class MemFnPtr,
463             class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
464   struct CallMemberRef
465   {
466     typedef typename FuncTraits <MemFnPtr>::ClassType T;
467     typedef typename FuncTraits <MemFnPtr>::Params Params;
468
469     static int f (lua_State* L)
470     {
471       assert (isfulluserdata (L, lua_upvalueindex (1)));
472       T* const t = Userdata::get <T> (L, 1, false);
473       MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
474       assert (fnptr != 0);
475       ArgList <Params, 2> args (L);
476       Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (t, fnptr, args));
477       LuaRef v (newTable (L));
478       FuncArgs <Params, 0>::refs (v, args);
479       v.push(L);
480       return 2;
481     }
482   };
483
484   template <class MemFnPtr,
485             class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
486   struct CallConstMemberRef
487   {
488     typedef typename FuncTraits <MemFnPtr>::ClassType T;
489     typedef typename FuncTraits <MemFnPtr>::Params Params;
490
491     static int f (lua_State* L)
492     {
493       assert (isfulluserdata (L, lua_upvalueindex (1)));
494       T const* const t = Userdata::get <T> (L, 1, true);
495       MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
496       assert (fnptr != 0);
497       ArgList <Params, 2> args(L);
498       Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (t, fnptr, args));
499       LuaRef v (newTable (L));
500       FuncArgs <Params, 0>::refs (v, args);
501       v.push(L);
502       return 2;
503     }
504   };
505
506   template <class MemFnPtr, class T,
507             class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
508   struct CallMemberRefPtr
509   {
510     typedef typename FuncTraits <MemFnPtr>::Params Params;
511
512     static int f (lua_State* L)
513     {
514       assert (isfulluserdata (L, lua_upvalueindex (1)));
515       boost::shared_ptr<T>* const t = Userdata::get <boost::shared_ptr<T> > (L, 1, false);
516       T* const tt = t->get();
517       if (!tt) {
518         return luaL_error (L, "shared_ptr is nil");
519       }
520       MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
521       assert (fnptr != 0);
522       ArgList <Params, 2> args (L);
523       Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (tt, fnptr, args));
524       LuaRef v (newTable (L));
525       FuncArgs <Params, 0>::refs (v, args);
526       v.push(L);
527       return 2;
528     }
529   };
530
531   template <class MemFnPtr, class T,
532             class ReturnType = typename FuncTraits <MemFnPtr>::ReturnType>
533   struct CallMemberRefWPtr
534   {
535     typedef typename FuncTraits <MemFnPtr>::Params Params;
536
537     static int f (lua_State* L)
538     {
539       assert (isfulluserdata (L, lua_upvalueindex (1)));
540       boost::weak_ptr<T>* const tw = Userdata::get <boost::weak_ptr<T> > (L, 1, false);
541       boost::shared_ptr<T> const t = tw->lock();
542       if (!t) {
543         return luaL_error (L, "cannot lock weak_ptr");
544       }
545       T* const tt = t.get();
546       if (!tt) {
547         return luaL_error (L, "weak_ptr is nil");
548       }
549       MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
550       assert (fnptr != 0);
551       ArgList <Params, 2> args (L);
552       Stack <ReturnType>::push (L, FuncTraits <MemFnPtr>::call (tt, fnptr, args));
553       LuaRef v (newTable (L));
554       FuncArgs <Params, 0>::refs (v, args);
555       v.push(L);
556       return 2;
557     }
558   };
559
560   //----------------------------------------------------------------------------
561   /**
562       lua_CFunction to call a class member function with no return value.
563
564       The member function pointer is in the first upvalue.
565       The class userdata object is at the top of the Lua stack.
566   */
567   template <class MemFnPtr>
568   struct CallMember <MemFnPtr, void>
569   {
570     typedef typename FuncTraits <MemFnPtr>::ClassType T;
571     typedef typename FuncTraits <MemFnPtr>::Params Params;
572
573     static int f (lua_State* L)
574     {
575       assert (isfulluserdata (L, lua_upvalueindex (1)));
576       T* const t = Userdata::get <T> (L, 1, false);
577       MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
578       assert (fnptr != 0);
579       ArgList <Params, 2> args (L);
580       FuncTraits <MemFnPtr>::call (t, fnptr, args);
581       return 0;
582     }
583   };
584
585   template <class MemFnPtr>
586   struct CallConstMember <MemFnPtr, void>
587   {
588     typedef typename FuncTraits <MemFnPtr>::ClassType T;
589     typedef typename FuncTraits <MemFnPtr>::Params Params;
590
591     static int f (lua_State* L)
592     {
593       assert (isfulluserdata (L, lua_upvalueindex (1)));
594       T const* const t = Userdata::get <T> (L, 1, true);
595       MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
596       assert (fnptr != 0);
597       ArgList <Params, 2> args (L);
598       FuncTraits <MemFnPtr>::call (t, fnptr, args);
599       return 0;
600     }
601   };
602
603   template <class MemFnPtr, class T>
604   struct CallMemberPtr <MemFnPtr, T, void>
605   {
606     typedef typename FuncTraits <MemFnPtr>::Params Params;
607
608     static int f (lua_State* L)
609     {
610       assert (isfulluserdata (L, lua_upvalueindex (1)));
611       boost::shared_ptr<T>* const t = Userdata::get <boost::shared_ptr<T> > (L, 1, false);
612       T* const tt = t->get();
613       MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
614       assert (fnptr != 0);
615       ArgList <Params, 2> args (L);
616       FuncTraits <MemFnPtr>::call (tt, fnptr, args);
617       return 0;
618     }
619   };
620
621   template <class MemFnPtr, class T>
622   struct CallMemberWPtr <MemFnPtr, T, void>
623   {
624     typedef typename FuncTraits <MemFnPtr>::Params Params;
625
626     static int f (lua_State* L)
627     {
628       assert (isfulluserdata (L, lua_upvalueindex (1)));
629       boost::weak_ptr<T>* const tw = Userdata::get <boost::weak_ptr<T> > (L, 1, false);
630       boost::shared_ptr<T> const t = tw->lock();
631       if (!t) {
632         return luaL_error (L, "cannot lock weak_ptr");
633       }
634       T* const tt = t.get();
635       if (!tt) {
636         return luaL_error (L, "weak_ptr is nil");
637       }
638       MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
639       assert (fnptr != 0);
640       ArgList <Params, 2> args (L);
641       FuncTraits <MemFnPtr>::call (tt, fnptr, args);
642       return 0;
643     }
644   };
645
646   template <class MemFnPtr>
647   struct CallMemberRef <MemFnPtr, void>
648   {
649     typedef typename FuncTraits <MemFnPtr>::ClassType T;
650     typedef typename FuncTraits <MemFnPtr>::Params Params;
651
652     static int f (lua_State* L)
653     {
654       assert (isfulluserdata (L, lua_upvalueindex (1)));
655       T* const t = Userdata::get <T> (L, 1, false);
656       MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
657       assert (fnptr != 0);
658       ArgList <Params, 2> args (L);
659       FuncTraits <MemFnPtr>::call (t, fnptr, args);
660       LuaRef v (newTable (L));
661       FuncArgs <Params, 0>::refs (v, args);
662       v.push(L);
663       return 1;
664     }
665   };
666
667   template <class MemFnPtr>
668   struct CallConstMemberRef <MemFnPtr, void>
669   {
670     typedef typename FuncTraits <MemFnPtr>::ClassType T;
671     typedef typename FuncTraits <MemFnPtr>::Params Params;
672
673     static int f (lua_State* L)
674     {
675       assert (isfulluserdata (L, lua_upvalueindex (1)));
676       T const* const t = Userdata::get <T> (L, 1, true);
677       MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
678       assert (fnptr != 0);
679       ArgList <Params, 2> args (L);
680       FuncTraits <MemFnPtr>::call (t, fnptr, args);
681       LuaRef v (newTable (L));
682       FuncArgs <Params, 0>::refs (v, args);
683       v.push(L);
684       return 1;
685     }
686   };
687
688   template <class MemFnPtr, class T>
689   struct CallMemberRefPtr <MemFnPtr, T, void>
690   {
691     typedef typename FuncTraits <MemFnPtr>::Params Params;
692
693     static int f (lua_State* L)
694     {
695       assert (isfulluserdata (L, lua_upvalueindex (1)));
696       boost::shared_ptr<T>* const t = Userdata::get <boost::shared_ptr<T> > (L, 1, false);
697       T* const tt = t->get();
698       if (!tt) {
699         return luaL_error (L, "shared_ptr is nil");
700       }
701       MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
702       assert (fnptr != 0);
703       ArgList <Params, 2> args (L);
704       FuncTraits <MemFnPtr>::call (tt, fnptr, args);
705       LuaRef v (newTable (L));
706       FuncArgs <Params, 0>::refs (v, args);
707       v.push(L);
708       return 1;
709     }
710   };
711
712   template <class MemFnPtr, class T>
713   struct CallMemberRefWPtr <MemFnPtr, T, void>
714   {
715     typedef typename FuncTraits <MemFnPtr>::Params Params;
716
717     static int f (lua_State* L)
718     {
719       assert (isfulluserdata (L, lua_upvalueindex (1)));
720       boost::weak_ptr<T>* const tw = Userdata::get <boost::weak_ptr<T> > (L, 1, false);
721       boost::shared_ptr<T> const t = tw->lock();
722       if (!t) {
723         return luaL_error (L, "cannot lock weak_ptr");
724       }
725       T* const tt = t.get();
726       if (!tt) {
727         return luaL_error (L, "weak_ptr is nil");
728       }
729       MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
730       assert (fnptr != 0);
731       ArgList <Params, 2> args (L);
732       FuncTraits <MemFnPtr>::call (tt, fnptr, args);
733       LuaRef v (newTable (L));
734       FuncArgs <Params, 0>::refs (v, args);
735       v.push(L);
736       return 1;
737     }
738   };
739
740   //--------------------------------------------------------------------------
741   /**
742       lua_CFunction to call a class member lua_CFunction.
743
744       The member function pointer is in the first upvalue.
745       The class userdata object is at the top of the Lua stack.
746   */
747   template <class T>
748   struct CallMemberCFunction
749   {
750     static int f (lua_State* L)
751     {
752       assert (isfulluserdata (L, lua_upvalueindex (1)));
753       typedef int (T::*MFP)(lua_State* L);
754       T* const t = Userdata::get <T> (L, 1, false);
755       MFP const& fnptr = *static_cast <MFP const*> (lua_touserdata (L, lua_upvalueindex (1)));
756       assert (fnptr != 0);
757       return (t->*fnptr) (L);
758     }
759   };
760
761   template <class T>
762   struct CallConstMemberCFunction
763   {
764     static int f (lua_State* L)
765     {
766       assert (isfulluserdata (L, lua_upvalueindex (1)));
767       typedef int (T::*MFP)(lua_State* L);
768       T const* const t = Userdata::get <T> (L, 1, true);
769       MFP const& fnptr = *static_cast <MFP const*> (lua_touserdata (L, lua_upvalueindex (1)));
770       assert (fnptr != 0);
771       return (t->*fnptr) (L);
772     }
773   };
774
775   //--------------------------------------------------------------------------
776
777   // SFINAE Helpers
778
779   template <class MemFnPtr, bool isConst>
780   struct CallMemberFunctionHelper
781   {
782     static void add (lua_State* L, char const* name, MemFnPtr mf)
783     {
784       new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
785       lua_pushcclosure (L, &CallConstMember <MemFnPtr>::f, 1);
786       lua_pushvalue (L, -1);
787       rawsetfield (L, -5, name); // const table
788       rawsetfield (L, -3, name); // class table
789     }
790   };
791
792   template <class MemFnPtr>
793   struct CallMemberFunctionHelper <MemFnPtr, false>
794   {
795     static void add (lua_State* L, char const* name, MemFnPtr mf)
796     {
797       new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
798       lua_pushcclosure (L, &CallMember <MemFnPtr>::f, 1);
799       rawsetfield (L, -3, name); // class table
800     }
801   };
802
803   template <class MemFnPtr>
804   struct CallMemberPtrFunctionHelper
805   {
806     typedef typename FuncTraits <MemFnPtr>::ClassType T;
807     static void add (lua_State* L, char const* name, MemFnPtr mf)
808     {
809       new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
810       lua_pushcclosure (L, &CallMemberPtr <MemFnPtr, T>::f, 1);
811       rawsetfield (L, -3, name); // class table
812     }
813   };
814
815   template <class MemFnPtr>
816   struct CallMemberRefPtrFunctionHelper
817   {
818     typedef typename FuncTraits <MemFnPtr>::ClassType T;
819     static void add (lua_State* L, char const* name, MemFnPtr mf)
820     {
821       new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
822       lua_pushcclosure (L, &CallMemberRefPtr <MemFnPtr, T>::f, 1);
823       rawsetfield (L, -3, name); // class table
824     }
825   };
826
827   template <class MemFnPtr>
828   struct CallMemberWPtrFunctionHelper
829   {
830     typedef typename FuncTraits <MemFnPtr>::ClassType T;
831     static void add (lua_State* L, char const* name, MemFnPtr mf)
832     {
833       new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
834       lua_pushcclosure (L, &CallMemberWPtr <MemFnPtr, T>::f, 1);
835       rawsetfield (L, -3, name); // class table
836     }
837   };
838
839   template <class MemFnPtr>
840   struct CallMemberRefWPtrFunctionHelper
841   {
842     typedef typename FuncTraits <MemFnPtr>::ClassType T;
843     static void add (lua_State* L, char const* name, MemFnPtr mf)
844     {
845       new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
846       lua_pushcclosure (L, &CallMemberRefWPtr <MemFnPtr, T>::f, 1);
847       rawsetfield (L, -3, name); // class table
848     }
849   };
850
851   template <class MemFnPtr, bool isConst>
852   struct CallMemberRefFunctionHelper
853   {
854     static void add (lua_State* L, char const* name, MemFnPtr mf)
855     {
856       new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
857       lua_pushcclosure (L, &CallConstMemberRef <MemFnPtr>::f, 1);
858       lua_pushvalue (L, -1);
859       rawsetfield (L, -5, name); // const table
860       rawsetfield (L, -3, name); // class table
861     }
862   };
863
864   template <class MemFnPtr>
865   struct CallMemberRefFunctionHelper <MemFnPtr, false>
866   {
867     static void add (lua_State* L, char const* name, MemFnPtr mf)
868     {
869       new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
870       lua_pushcclosure (L, &CallMemberRef <MemFnPtr>::f, 1);
871       rawsetfield (L, -3, name); // class table
872     }
873   };
874
875   //--------------------------------------------------------------------------
876   /**
877       __gc metamethod for a class.
878   */
879   template <class C>
880   static int gcMetaMethod (lua_State* L)
881   {
882     Userdata* const ud = Userdata::getExact <C> (L, 1);
883     ud->~Userdata ();
884     return 0;
885   }
886
887   static int gcNOOPMethod (lua_State* L)
888   {
889     return 0;
890   }
891
892   //--------------------------------------------------------------------------
893   /**
894       lua_CFunction to get a class data member.
895
896       The pointer-to-member is in the first upvalue.
897       The class userdata object is at the top of the Lua stack.
898   */
899   template <class C, typename T>
900   static int getProperty (lua_State* L)
901   {
902     C const* const c = Userdata::get <C> (L, 1, true);
903     T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
904     Stack <T>::push (L, c->**mp);
905     return 1;
906   }
907
908   //--------------------------------------------------------------------------
909
910   /**
911       lua_CFunction to get a constant (enum)
912   */
913   template <typename U>
914   static int getConst (lua_State* L)
915   {
916     U *v = static_cast <U *> (lua_touserdata (L, lua_upvalueindex (1)));
917     assert (v);
918     Stack <U>::push (L, *v);
919     return 1;
920   }
921
922   //--------------------------------------------------------------------------
923   /**
924       lua_CFunction to set a class data member.
925
926       The pointer-to-member is in the first upvalue.
927       The class userdata object is at the top of the Lua stack.
928   */
929   template <class C, typename T>
930   static int setProperty (lua_State* L)
931   {
932     C* const c = Userdata::get <C> (L, 1, false);
933     T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
934     c->**mp = Stack <T>::get (L, 2);
935     return 0;
936   }
937
938   //--------------------------------------------------------------------------
939
940   // metatable callback for "array[index]"
941   template <typename T>
942   static int array_index (lua_State* L) {
943     T** parray = (T**) luaL_checkudata (L, 1, typeid(T).name());
944     int const index = luabridge::Stack<int>::get (L, 2);
945     luabridge::Stack<T>::push (L, (*parray)[index-1]);
946     return 1;
947   }
948
949   // metatable callback for "array[index] = value"
950   template <typename T>
951   static int array_newindex (lua_State* L) {
952     T** parray = (T**) luaL_checkudata (L, 1, typeid(T).name());
953     int const index = luabridge::Stack<int>::get (L, 2);
954     T const value = luabridge::Stack<T>::get (L, 3);
955     (*parray)[index-1] = value;
956     return 0;
957   }
958
959   template <typename T>
960   static int getArray (lua_State* L) {
961     T *v = luabridge::Stack<T*>::get (L, 1);
962     T** parray = (T**) lua_newuserdata(L, sizeof(T**));
963     *parray = v;
964     luaL_getmetatable(L, typeid(T).name());
965     lua_setmetatable(L, -2);
966     return 1;
967   }
968
969   // copy complete c array to lua table
970   template <typename T>
971   static int getTable (lua_State* L) {
972     T *v = luabridge::Stack<T*>::get (L, 1);
973     const int cnt = luabridge::Stack<int>::get (L, 2);
974     LuaRef t (L);
975     t = newTable (L);
976     for (int i = 0; i < cnt; ++i) {
977       t[i + 1] = v[i];
978     }
979     t.push(L);
980     return 1;
981   }
982
983   // copy lua table to c array
984   template <typename T>
985   static int setTable (lua_State* L) {
986     T *v = luabridge::Stack<T*>::get (L, 1);
987     LuaRef t (LuaRef::fromStack(L, 2));
988     const int cnt = luabridge::Stack<int>::get (L, 3);
989     for (int i = 0; i < cnt; ++i) {
990       v[i] = t[i + 1];
991     }
992     return 0;
993   }
994
995   // return same array at an offset
996   template <typename T>
997   static int offsetArray (lua_State* L) {
998     T *v = luabridge::Stack<T*>::get (L, 1);
999     const unsigned int i = luabridge::Stack<unsigned int>::get (L, 2);
1000     Stack <T*>::push (L, &v[i]);
1001     return 1;
1002   }
1003
1004   //--------------------------------------------------------------------------
1005   /**
1006     C++ STL iterators
1007    */
1008
1009   // read lua table into C++ std::list
1010   template <class T, class C>
1011   static int tableToListHelper (lua_State *L, C * const t)
1012   {
1013     if (!t) { return luaL_error (L, "invalid pointer to std::list<>/std::vector"); }
1014     if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
1015     lua_pushvalue (L, -1);
1016     lua_pushnil (L);
1017     while (lua_next (L, -2)) {
1018       lua_pushvalue (L, -2);
1019       T const value = Stack<T>::get (L, -2);
1020       t->push_back (value);
1021       lua_pop (L, 2);
1022     }
1023     lua_pop (L, 1);
1024     lua_pop (L, 2);
1025     Stack<C>::push (L, *t);
1026     return 1;
1027   }
1028
1029   template <class T, class C>
1030   static int tableToList (lua_State *L)
1031   {
1032     C * const t = Userdata::get<C> (L, 1, false);
1033     return tableToListHelper<T, C> (L, t);
1034   }
1035
1036   template <class T, class C>
1037   static int ptrTableToList (lua_State *L)
1038   {
1039     boost::shared_ptr<C> const* const t = Userdata::get<boost::shared_ptr<C> > (L, 1, true);
1040     if (!t) { return luaL_error (L, "cannot derefencee shared_ptr"); }
1041     return tableToListHelper<T, C> (L, t->get());
1042   }
1043
1044   //--------------------------------------------------------------------------
1045   template <class T, class C>
1046   static int listIterIter (lua_State *L) {
1047     typedef typename C::const_iterator IterType;
1048     IterType * const end = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (2)));
1049     IterType * const iter = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (1)));
1050     assert (end);
1051     assert (iter);
1052     if ((*iter) == (*end)) {
1053       return 0;
1054     }
1055     Stack <T>::push (L, **iter);
1056     ++(*iter);
1057     return 1;
1058   }
1059
1060   // generate an iterator
1061   template <class T, class C>
1062   static int listIterHelper (lua_State *L, C * const t)
1063   {
1064     if (!t) { return luaL_error (L, "invalid pointer to std::list<>/std::vector"); }
1065     typedef typename C::const_iterator IterType;
1066     new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->begin());
1067     new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->end());
1068     lua_pushcclosure (L, listIterIter<T, C>, 2);
1069     return 1;
1070   }
1071
1072   template <class T, class C>
1073   static int listIter (lua_State *L)
1074   {
1075     C * const t = Userdata::get <C> (L, 1, false);
1076     return listIterHelper<T, C> (L, t);
1077   }
1078
1079   template <class T, class C>
1080   static int ptrListIter (lua_State *L)
1081   {
1082     boost::shared_ptr<C> const* const t = Userdata::get <boost::shared_ptr<C> >(L, 1, true);
1083     if (!t) { return luaL_error (L, "cannot derefencee shared_ptr"); }
1084     return listIterHelper<T, C> (L, t->get());
1085   }
1086
1087   //--------------------------------------------------------------------------
1088   // generate table from std::list
1089   template <class T, class C>
1090   static int listToTableHelper (lua_State *L, C const* const t)
1091   {
1092     if (!t) { return luaL_error (L, "invalid pointer to std::list<>/std::vector"); }
1093 #if 0 // direct lua api
1094     lua_createtable(L, t->size(), 0);
1095     int newTable = lua_gettop(L);
1096     int index = 1;
1097     for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter, ++index) {
1098       Stack<T>::push(L, (*iter));
1099       lua_rawseti (L, newTable, index);
1100     }
1101 #else // luabridge way
1102     LuaRef v (L);
1103     v = newTable (L);
1104     int index = 1;
1105     for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter, ++index) {
1106       v[index] = (*iter);
1107     }
1108     v.push(L);
1109 #endif
1110     return 1;
1111   }
1112
1113   template <class T, class C>
1114   static int listToTable (lua_State *L)
1115   {
1116     C const* const t = Userdata::get <C> (L, 1, true);
1117     return listToTableHelper<T, C> (L, t);
1118   }
1119
1120   template <class T, class C>
1121   static int ptrListToTable (lua_State *L)
1122   {
1123     boost::shared_ptr<C> const* const t = Userdata::get <boost::shared_ptr<C> > (L, 1, true);
1124     if (!t) { return luaL_error (L, "cannot derefencee shared_ptr"); }
1125     return listToTableHelper<T, C> (L, t->get());
1126   }
1127
1128   //--------------------------------------------------------------------------
1129   // generate std::map from table
1130
1131   template <class K, class V>
1132   static int tableToMap (lua_State *L)
1133   {
1134     typedef std::map<K, V> C;
1135     C * const t = Userdata::get <C> (L, 1, true);
1136     if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
1137     if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
1138
1139     lua_pushvalue (L, -1);
1140     lua_pushnil (L);
1141     while (lua_next (L, -2)) {
1142       lua_pushvalue (L, -2);
1143       K const key = Stack<K>::get (L, -1);
1144       V const value = Stack<V>::get (L, -2);
1145       t->insert (std::pair<K,V> (key, value));
1146       //(*t)[key] = value;
1147       lua_pop (L, 2);
1148     }
1149     lua_pop (L, 1);
1150     lua_pop (L, 2);
1151     Stack<C>::push (L, *t);
1152     return 1;
1153   }
1154
1155   // iterate over a std::map
1156   template <class K, class V>
1157   static int mapIterIter (lua_State *L)
1158   {
1159     typedef std::map<K, V> C;
1160     typedef typename C::const_iterator IterType;
1161     IterType * const end = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (2)));
1162     IterType * const iter = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (1)));
1163     assert (end);
1164     assert (iter);
1165     if ((*iter) == (*end)) {
1166       return 0;
1167     }
1168     Stack <K>::push (L, (*iter)->first);
1169     Stack <V>::push (L, (*iter)->second);
1170     ++(*iter);
1171     return 2;
1172   }
1173
1174   // generate iterator
1175   template <class K, class V>
1176   static int mapIter (lua_State *L)
1177   {
1178     typedef std::map<K, V> C;
1179     C * const t = Userdata::get <C> (L, 1, false);
1180     if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
1181     typedef typename C::const_iterator IterType;
1182     new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->begin());
1183     new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->end());
1184     lua_pushcclosure (L, mapIterIter<K, V>, 2);
1185     return 1;
1186   }
1187
1188   // generate table from std::map
1189   template <class K, class V>
1190   static int mapToTable (lua_State *L)
1191   {
1192     typedef std::map<K, V> C;
1193     C const* const t = Userdata::get <C> (L, 1, true);
1194     if (!t) { return luaL_error (L, "invalid pointer to std::map"); }
1195
1196     LuaRef v (L);
1197     v = newTable (L);
1198     for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter) {
1199       v[(*iter).first] = (*iter).second;
1200     }
1201     v.push(L);
1202     return 1;
1203   }
1204
1205   //--------------------------------------------------------------------------
1206   // generate std::set from table keys ( table[member] = true )
1207   // http://www.lua.org/pil/11.5.html
1208
1209   template <class T>
1210   static int tableToSet (lua_State *L)
1211   {
1212     typedef std::set<T> C;
1213     C * const t = Userdata::get <C> (L, 1, true);
1214     if (!t) { return luaL_error (L, "invalid pointer to std::set"); }
1215     if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
1216
1217     lua_pushvalue (L, -1);
1218     lua_pushnil (L);
1219     while (lua_next (L, -2)) {
1220       lua_pushvalue (L, -2);
1221       T const member = Stack<T>::get (L, -1);
1222       bool const v = Stack<bool>::get (L, -2);
1223       if (v) {
1224         t->insert (member);
1225       }
1226       lua_pop (L, 2);
1227     }
1228     lua_pop (L, 1);
1229     lua_pop (L, 2);
1230     Stack<C>::push (L, *t);
1231     return 1;
1232   }
1233
1234   // iterate over a std::set, explicit "true" value.
1235   // compare to http://www.lua.org/pil/11.5.html
1236   template <class T>
1237   static int setIterIter (lua_State *L)
1238   {
1239     typedef std::set<T> C;
1240     typedef typename C::const_iterator IterType;
1241     IterType * const end = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (2)));
1242     IterType * const iter = static_cast <IterType * const> (lua_touserdata (L, lua_upvalueindex (1)));
1243     assert (end);
1244     assert (iter);
1245     if ((*iter) == (*end)) {
1246       return 0;
1247     }
1248     Stack <T>::push (L, **iter);
1249     Stack <bool>::push (L, true);
1250     ++(*iter);
1251     return 2;
1252   }
1253
1254   // generate iterator
1255   template <class T>
1256   static int setIter (lua_State *L)
1257   {
1258     typedef std::set<T> C;
1259     C * const t = Userdata::get <C> (L, 1, false);
1260     if (!t) { return luaL_error (L, "invalid pointer to std::set"); }
1261     typedef typename C::const_iterator IterType;
1262     new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->begin());
1263     new (lua_newuserdata (L, sizeof (IterType*))) IterType (t->end());
1264     lua_pushcclosure (L, setIterIter<T>, 2);
1265     return 1;
1266   }
1267
1268   // generate table from std::set
1269   template <class T>
1270   static int setToTable (lua_State *L)
1271   {
1272     typedef std::set<T> C;
1273     C const* const t = Userdata::get <C> (L, 1, true);
1274     if (!t) { return luaL_error (L, "invalid pointer to std::set"); }
1275
1276     LuaRef v (L);
1277     v = newTable (L);
1278     for (typename C::const_iterator iter = t->begin(); iter != t->end(); ++iter) {
1279       v[(*iter)] = true;
1280     }
1281     v.push(L);
1282     return 1;
1283   }
1284
1285   //--------------------------------------------------------------------------
1286   // bitset { num = true }
1287   // compare to http://www.lua.org/pil/11.5.html
1288   template <unsigned int T>
1289   static int tableToBitSet (lua_State *L)
1290   {
1291     typedef std::bitset<T> C;
1292     C * const t = Userdata::get <C> (L, 1, true);
1293     if (!t) { return luaL_error (L, "invalid pointer to std::bitset"); }
1294     if (!lua_istable (L, -1)) { return luaL_error (L, "argument is not a table"); }
1295
1296     lua_pushvalue (L, -1);
1297     lua_pushnil (L);
1298     while (lua_next (L, -2)) {
1299       lua_pushvalue (L, -2);
1300       unsigned int const member = Stack<unsigned int>::get (L, -1);
1301       bool const v = Stack<bool>::get (L, -2);
1302       if (member < T && v) {
1303         t->set (member);
1304       }
1305       lua_pop (L, 2);
1306     }
1307     lua_pop (L, 1);
1308     lua_pop (L, 2);
1309     Stack<C>::push (L, *t);
1310     return 1;
1311   }
1312
1313   // generate table from std::bitset
1314   template <unsigned int T>
1315   static int bitSetToTable (lua_State *L)
1316   {
1317     typedef std::bitset<T> C;
1318     C const* const t = Userdata::get <C> (L, 1, true);
1319     if (!t) { return luaL_error (L, "invalid pointer to std::bitset"); }
1320
1321     LuaRef v (L);
1322     v = newTable (L);
1323     for (unsigned int i = 0; i < T; ++i) {
1324       if (t->test (i)) {
1325         v[i] = true;
1326       }
1327     }
1328     v.push(L);
1329     return 1;
1330   }
1331
1332 };
1333
1334 /* vim: set et sw=2: */