1 //------------------------------------------------------------------------------
2 /*
3   https://github.com/vinniefalco/LuaBridge
4 
5   Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
6   Copyright 2008, Nigel Atkinson <suprapilot+LuaCode@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 //------------------------------------------------------------------------------
31 /**
32     Type tag for representing LUA_TNIL.
33 
34     Construct one of these using `Nil()` to represent a Lua nil. This is faster
35     than creating a reference in the registry to nil. Example:
36 
37         LuaRef t (LuaRef::createTable (L));
38         ...
39         t ["k"] = Nil(); // assign nil
40 */
41 struct Nil
42 {
43 };
44 
45 //------------------------------------------------------------------------------
46 /**
47     Lightweight reference to a Lua object.
48 
49     The reference is maintained for the lifetime of the C++ object.
50 */
51 class LuaRef
52 {
53 private:
54   class Proxy;
55   friend struct Stack <Proxy>;
56 
57   //----------------------------------------------------------------------------
58   /**
59       Pop the Lua stack.
60 
61       Pops the specified number of stack items on destruction. We use this
62       when returning objects, to avoid an explicit temporary variable, since
63       the destructor executes after the return statement. For example:
64 
65       \code
66           template <class U>
67           U cast (lua_State* L)
68           {
69             StackPop p (L, 1);
70             ...
71             return U (); // dtor called after this line
72           }
73       \endcode
74 
75       @note The `StackPop` object must always be a named local variable.
76   */
77   class StackPop
78   {
79   public:
80     /** Create a StackPop object.
81 
82         @param L the LuaState to modify
83         @param count The number of stack entries to pop on destruction.
84     */
85     StackPop (lua_State* L, int count)
86       : m_L (L)
87       , m_count (count)
88     {
89     }
90 
91     ~StackPop ()
92     {
93       lua_pop (m_L, m_count);
94     }
95 
96   private:
97     lua_State* m_L;
98     int m_count;
99   };
100 
101   //----------------------------------------------------------------------------
102   /**
103       A proxy for representing table values.
104   */
105   class Proxy
106   {
107   private:
108     lua_State* m_L;
109     int m_tableRef;
110     int m_keyRef;
111 
112   public:
113     //--------------------------------------------------------------------------
114     /**
115         Construct a Proxy from a table value.
116 
117         The table is in the registry, and the key is at the top of the stack.
118         The key is popped off the stack.
119     */
120     Proxy (lua_State* L, int tableRef)
121       : m_L (L)
122       , m_tableRef (tableRef)
123       , m_keyRef (luaL_ref (L, LUA_REGISTRYINDEX))
124     {
125     }
126 
127     //--------------------------------------------------------------------------
128     /**
129         Create a Proxy via copy constructor.
130 
131         It is best to avoid code paths that invoke this, because it creates
132         an extra temporary Lua reference. Typically this is done by passing
133         the Proxy parameter as a `const` reference.
134     */
135     Proxy (Proxy const& other)
136       : m_L (other.m_L)
137       , m_tableRef (other.m_tableRef)
138     {
139       // If this assert goes off it means code is taking this path,
140       // which is better avoided.
141       //
142       assert (0);
143 
144       lua_rawgeti (m_L, LUA_REGISTRYINDEX, other.m_keyRef);
145       m_keyRef = luaL_ref (m_L, LUA_REGISTRYINDEX);
146     }
147 
148     //--------------------------------------------------------------------------
149     /**
150         Destroy the proxy.
151 
152         This does not destroy the table value.
153     */
154     ~Proxy ()
155     {
156       luaL_unref (m_L, LUA_REGISTRYINDEX, m_keyRef);
157     }
158 
159     //--------------------------------------------------------------------------
160     /**
161         Return a reference to the table value.
162     */
163     int createRef () const
164     {
165       push (m_L);
166       return luaL_ref (m_L, LUA_REGISTRYINDEX);
167     }
168 
169     //--------------------------------------------------------------------------
170     /**
171         Assign a new value to this table key.
172 
173         This may invoke metamethods.
174     */
175     template <class T>
176     Proxy& operator= (T v)
177     {
178       StackPop p (m_L, 1);
179       lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef);
180       lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef);
181       Stack <T>::push (m_L, v);
182       lua_rawset (m_L, -3);
183       return *this;
184     }
185 
186     // the implementation needs UserdataPtr, which
187     // is not yet defined here.
188     // -> libs/ardour/lua_api.cc
189     Proxy& clone_instance (const void* key, void* p);
190 
191     //--------------------------------------------------------------------------
192     /**
193         Assign a new value to this table key.
194 
195         The assignment is raw, no metamethods are invoked.
196     */
197     template <class T>
198     Proxy& rawset (T v)
199     {
200       StackPop p (m_L, 1);
201       lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef);
202       lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef);
203       Stack <T>::push (m_L, v);
204       lua_settable (m_L, -3);
205       return *this;
206     }
207 
208     //==========================================================================
209     //
210     // This group of member functions mirrors the member functions in LuaRef.
211 
212     /** Retrieve the lua_State associated with the table value.
213     */
214     lua_State* state () const
215     {
216       return m_L;
217     }
218 
219     //--------------------------------------------------------------------------
220     /**
221         Push the value onto the Lua stack.
222     */
223     void push (lua_State* L) const
224     {
225       assert (equalstates (L, m_L));
226       lua_rawgeti (L, LUA_REGISTRYINDEX, m_tableRef);
227       lua_rawgeti (L, LUA_REGISTRYINDEX, m_keyRef);
228       lua_gettable (L, -2);
229       lua_remove (L, -2); // remove the table
230     }
231 
232     //--------------------------------------------------------------------------
233     /**
234         Determine the object type.
235 
236         The return values are the same as for `lua_type`.
237     */
238     int type () const
239     {
240       int result;
241       push (m_L);
242       result = lua_type (m_L, -1);
243       lua_pop (m_L, 1);
244       return result;
245     }
246 
247     inline bool isNil () const { return type () == LUA_TNIL; }
248     inline bool isBoolean () const { return type () == LUA_TBOOLEAN; }
249     inline bool isNumber () const { return type () == LUA_TNUMBER; }
250     inline bool isString () const { return type () == LUA_TSTRING; }
251     inline bool isTable () const { return type () == LUA_TTABLE; }
252     inline bool isFunction () const { return type () == LUA_TFUNCTION; }
253     inline bool isUserdata () const { return type () == LUA_TUSERDATA; }
254     inline bool isThread () const { return type () == LUA_TTHREAD; }
255     inline bool isLightUserdata () const { return type () == LUA_TLIGHTUSERDATA; }
256 
257     //--------------------------------------------------------------------------
258     /**
259         Perform an explicit conversion.
260     */
261     template <class T>
262     T cast () const
263     {
264       StackPop p (m_L, 1);
265       push (m_L);
266 
267       // lua_gettop is used because Userdata::getClass() doesn't handle
268       // negative stack indexes.
269       //
270       return Stack <T>::get (m_L, lua_gettop (m_L));
271     }
272 
273     //--------------------------------------------------------------------------
274     /**
275         Universal implicit conversion operator.
276 
277         NOTE: Visual Studio 2010 and 2012 have a bug where this function
278               is not used. See:
279 
280         http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/e30b2664-a92d-445c-9db2-e8e0fbde2014
281         https://connect.microsoft.com/VisualStudio/feedback/details/771509/correct-code-doesnt-compile
282 
283         \code
284             // This code snippet fails to compile in vs2010,vs2012
285             struct S {
286               template <class T> inline operator T () const { return T (); }
287             };
288             int main () {
289               S () || false;
290               return 0;
291             }
292         \endcode
293     */
294     template <class T>
295     inline operator T () const
296     {
297       return cast <T> ();
298     }
299 
300     //--------------------------------------------------------------------------
301     /**
302         Universal comparison operators.
303     */
304     /** @{ */
305     template <class T>
306     bool operator== (T rhs) const
307     {
308       StackPop p (m_L, 2);
309       push (m_L);
310       Stack <T>::push (m_L, rhs);
311       return lua_compare (m_L, -2, -1, LUA_OPEQ) == 1;
312     }
313 
314     template <class T>
315     bool operator< (T rhs) const
316     {
317       StackPop p (m_L, 2);
318       push (m_L);
319       Stack <T>::push (m_L, rhs);
320       return lua_compare (m_L, -2, -1, LUA_OPLT) == 1;
321     }
322 
323     template <class T>
324     bool operator<= (T rhs) const
325     {
326       StackPop p (m_L, 2);
327       push (m_L);
328       Stack <T>::push (m_L, rhs);
329       return lua_compare (m_L, -2, -1, LUA_OPLE) == 1;
330     }
331 
332     template <class T>
333     bool operator> (T rhs) const
334     {
335       StackPop p (m_L, 2);
336       push (m_L);
337       Stack <T>::push (m_L, rhs);
338       return lua_compare (m_L, -1, -2, LUA_OPLT) == 1;
339     }
340 
341     template <class T>
342     bool operator>= (T rhs) const
343     {
344       StackPop p (m_L, 2);
345       push (m_L);
346       Stack <T>::push (m_L, rhs);
347       return lua_compare (m_L, -1, -2, LUA_OPLE) == 1;
348     }
349 
350     template <class T>
351     bool rawequal (T rhs) const
352     {
353       StackPop p (m_L, 2);
354       push (m_L);
355       Stack <T>::push (m_L, rhs);
356       return lua_rawequal (m_L, -1, -2) == 1;
357     }
358     /** @} */
359 
360     //--------------------------------------------------------------------------
361     /**
362         Access a table value using a key.
363 
364         This invokes metamethods.
365     */
366     template <class T>
367     Proxy operator[] (T key) const
368     {
369       return LuaRef (*this) [key];
370     }
371 
372     //--------------------------------------------------------------------------
373     /**
374         Access a table value using a key.
375 
376         The operation is raw, metamethods are not invoked. The result is
377         passed by value and may not be modified.
378     */
379     template <class T>
380     LuaRef rawget (T key) const
381     {
382       StackPop (m_L, 1);
383       push (m_L);
384       Stack <T>::push (m_L, key);
385       lua_rawget (m_L, -2);
386       return LuaRef (m_L, FromStack ());
387     }
388 
389     //--------------------------------------------------------------------------
390     /**
391         Append a value to the table.
392 
393         If the table is a sequence this will add another element to it.
394     */
395     template <class T>
396     void append (T v) const
397     {
398       push (m_L);
399       Stack <T>::push (m_L, v);
400       luaL_ref (m_L, -2);
401       lua_pop (m_L, 1);
402     }
403 
404     //--------------------------------------------------------------------------
405     /**
406         Call the length operator.
407 
408         This is identical to applying the Lua # operator.
409     */
410     int length () const
411     {
412       StackPop p (m_L, 1);
413       push (m_L);
414       return get_length (m_L, -1);
415     }
416 
417     //--------------------------------------------------------------------------
418     /**
419         Call Lua code.
420 
421         These overloads allow Lua code to be called with up to 8 parameters.
422         The return value is provided as a LuaRef (which may be LUA_REFNIL).
423         If an error occurs, a LuaException is thrown.
424     */
425     /** @{ */
426     LuaRef const operator() () const
427     {
428       push (m_L);
429       LuaException::pcall (m_L, 0, 1);
430       return LuaRef (m_L, FromStack ());
431     }
432 
433     template <class P1>
434     LuaRef const operator() (P1 p1) const
435     {
436       push (m_L);
437       Stack <P1>::push (m_L, p1);
438       LuaException::pcall (m_L, 1, 1);
439       return LuaRef (m_L, FromStack ());
440     }
441 
442     template <class P1, class P2>
443     LuaRef const operator() (P1 p1, P2 p2) const
444     {
445       push (m_L);
446       Stack <P1>::push (m_L, p1);
447       Stack <P2>::push (m_L, p2);
448       LuaException::pcall (m_L, 2, 1);
449       return LuaRef (m_L, FromStack ());
450     }
451 
452     template <class P1, class P2, class P3>
453     LuaRef const operator() (P1 p1, P2 p2, P3 p3) const
454     {
455       push (m_L);
456       Stack <P1>::push (m_L, p1);
457       Stack <P2>::push (m_L, p2);
458       Stack <P3>::push (m_L, p3);
459       LuaException::pcall (m_L, 3, 1);
460       return LuaRef (m_L, FromStack ());
461     }
462 
463     template <class P1, class P2, class P3, class P4>
464     LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4) const
465     {
466       push (m_L);
467       Stack <P1>::push (m_L, p1);
468       Stack <P2>::push (m_L, p2);
469       Stack <P3>::push (m_L, p3);
470       Stack <P4>::push (m_L, p4);
471       LuaException::pcall (m_L, 4, 1);
472       return LuaRef (m_L, FromStack ());
473     }
474 
475     template <class P1, class P2, class P3, class P4, class P5>
476     LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const
477     {
478       push (m_L);
479       Stack <P1>::push (m_L, p1);
480       Stack <P2>::push (m_L, p2);
481       Stack <P3>::push (m_L, p3);
482       Stack <P4>::push (m_L, p4);
483       Stack <P5>::push (m_L, p5);
484       LuaException::pcall (m_L, 5, 1);
485       return LuaRef (m_L, FromStack ());
486     }
487 
488     template <class P1, class P2, class P3, class P4, class P5, class P6>
489     LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const
490     {
491       push (m_L);
492       Stack <P1>::push (m_L, p1);
493       Stack <P2>::push (m_L, p2);
494       Stack <P3>::push (m_L, p3);
495       Stack <P4>::push (m_L, p4);
496       Stack <P5>::push (m_L, p5);
497       Stack <P6>::push (m_L, p6);
498       LuaException::pcall (m_L, 6, 1);
499       return LuaRef (m_L, FromStack ());
500     }
501 
502     template <class P1, class P2, class P3, class P4, class P5, class P6, class P7>
503     LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const
504     {
505       push (m_L);
506       Stack <P1>::push (m_L, p1);
507       Stack <P2>::push (m_L, p2);
508       Stack <P3>::push (m_L, p3);
509       Stack <P4>::push (m_L, p4);
510       Stack <P5>::push (m_L, p5);
511       Stack <P6>::push (m_L, p6);
512       Stack <P7>::push (m_L, p7);
513       LuaException::pcall (m_L, 7, 1);
514       return LuaRef (m_L, FromStack ());
515     }
516 
517     template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
518     LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const
519     {
520       push (m_L);
521       Stack <P1>::push (m_L, p1);
522       Stack <P2>::push (m_L, p2);
523       Stack <P3>::push (m_L, p3);
524       Stack <P4>::push (m_L, p4);
525       Stack <P5>::push (m_L, p5);
526       Stack <P6>::push (m_L, p6);
527       Stack <P7>::push (m_L, p7);
528       Stack <P8>::push (m_L, p8);
529       LuaException::pcall (m_L, 8, 1);
530       return LuaRef (m_L, FromStack ());
531     }
532     /** @} */
533 
534     //==========================================================================
535   };
536 
537 private:
538   friend struct Stack <LuaRef>;
539 
540   //----------------------------------------------------------------------------
541   /**
542       Type tag for stack construction.
543   */
544   struct FromStack { };
545 
546   //----------------------------------------------------------------------------
547   /**
548       Create a reference to an object at the top of the Lua stack and pop it.
549 
550       This constructor is private and not invoked directly.
551       Instead, use the `fromStack` function.
552 
553       @note The object is popped.
554   */
555   LuaRef (lua_State* L, FromStack)
556     : m_L (L)
557   {
558     m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
559   }
560 
561   //----------------------------------------------------------------------------
562   /**
563       Create a reference to an object on the Lua stack.
564 
565       This constructor is private and not invoked directly.
566       Instead, use the `fromStack` function.
567 
568       @note The object is not popped.
569   */
570   LuaRef (lua_State* L, int index, FromStack)
571     : m_L (L)
572   {
573     lua_pushvalue (m_L, index);
574     m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
575   }
576 
577   //----------------------------------------------------------------------------
578 
579   // This type of construction is disallowed, since we don't have a `lua_State`.
580   //
581   template <class T>
582   LuaRef (T)
583   {
584   }
585 
586   //----------------------------------------------------------------------------
587   /**
588       Create a reference to this ref.
589 
590       This is used internally.
591   */
592   int createRef () const
593   {
594     if (m_ref != LUA_REFNIL)
595     {
596       push (m_L);
597       return luaL_ref (m_L, LUA_REGISTRYINDEX);
598     }
599     else
600     {
601       return LUA_REFNIL;
602     }
603   }
604 
605 public:
606   //----------------------------------------------------------------------------
607   /**
608       Create a nil reference.
609 
610       The LuaRef may be assigned later.
611   */
612   LuaRef (lua_State* L)
613     : m_L (L)
614     , m_ref (LUA_REFNIL)
615   {
616   }
617 
618   //----------------------------------------------------------------------------
619   /**
620       Create a reference to a value.
621   */
622   template <class T>
623   LuaRef (lua_State* L, T v)
624     : m_L (L)
625   {
626     Stack <T>::push (m_L, v);
627     m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
628   }
629 
630   //----------------------------------------------------------------------------
631   /**
632       Create a reference to a table value.
633   */
634   LuaRef (Proxy const& v)
635     : m_L (v.state ())
636     , m_ref (v.createRef ())
637   {
638   }
639 
640   //----------------------------------------------------------------------------
641   /**
642       Create a new reference to an existing reference.
643   */
644   LuaRef (LuaRef const& other)
645     : m_L (other.m_L)
646     , m_ref (other.createRef ())
647   {
648   }
649 
650   //----------------------------------------------------------------------------
651   /**
652       Destroy a reference.
653 
654       The corresponding Lua registry reference will be released.
655 
656       @note If the state refers to a thread, it is the responsibility of the
657             caller to ensure that the thread still exists when the LuaRef
658             is destroyed.
659   */
660   ~LuaRef ()
661   {
662     luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref);
663   }
664 
665   //----------------------------------------------------------------------------
666   /**
667       Return a LuaRef from a stack item.
668 
669       The stack item is not popped.
670   */
671   static LuaRef fromStack (lua_State* L, int index)
672   {
673     lua_pushvalue (L, index);
674     return LuaRef (L, FromStack ());
675   }
676 
677   //----------------------------------------------------------------------------
678   /**
679       Create a new empty table and return a reference to it.
680 
681       It is also possible to use the free function `newTable`.
682 
683       @see ::getGlobal
684   */
685   static LuaRef newTable (lua_State* L)
686   {
687     lua_newtable (L);
688     return LuaRef (L, FromStack ());
689   }
690 
691   //----------------------------------------------------------------------------
692   /**
693       Return a reference to a named global.
694 
695       It is also possible to use the free function `getGlobal`.
696 
697       @see ::getGlobal
698   */
699   static LuaRef getGlobal (lua_State *L, char const* name)
700   {
701     lua_getglobal (L, name);
702     return LuaRef (L, FromStack ());
703   }
704 
705   //----------------------------------------------------------------------------
706   /**
707       Assign a different value to this LuaRef.
708   */
709   template <class T>
710   LuaRef& operator= (T rhs)
711   {
712     luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref);
713     Stack <T>::push (m_L, rhs);
714     m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
715     return *this;
716   }
717 
718   //----------------------------------------------------------------------------
719   /**
720       Assign another LuaRef to this LuaRef.
721   */
722   LuaRef& operator= (LuaRef const& rhs)
723   {
724     luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref);
725     rhs.push (m_L);
726     m_L = rhs.state ();
727     m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
728     return *this;
729   }
730 
731   //----------------------------------------------------------------------------
732   /**
733       converts to a string using luas tostring function
734   */
735   std::string tostring() const
736   {
737     lua_getglobal (m_L, "tostring");
738     push (m_L);
739     lua_call (m_L, 1, 1);
740     const char* str = lua_tostring(m_L, 1);
741     lua_pop(m_L, 1);
742     return std::string(str);
743   }
744 
745   //----------------------------------------------------------------------------
746   /**
747       Print a text description of the value to a stream.
748 
749       This is used for diagnostics.
750   */
751   void print (std::ostream& os) const
752   {
753     switch (type ())
754     {
755     case LUA_TNIL:
756       os << "nil";
757       break;
758 
759     case LUA_TNUMBER:
760       os << cast <lua_Number> ();
761       break;
762 
763     case LUA_TBOOLEAN:
764       os << (cast <bool> () ? "true" : "false");
765       break;
766 
767     case LUA_TSTRING:
768       os << '"' << cast <std::string> () << '"';
769       break;
770 
771     case LUA_TTABLE:
772       os << "table: " << tostring();
773       break;
774 
775     case LUA_TFUNCTION:
776       os << "function: " << tostring();
777       break;
778 
779     case LUA_TUSERDATA:
780       os << "userdata: " << tostring();
781       break;
782 
783     case LUA_TTHREAD:
784       os << "thread: " << tostring();
785       break;
786 
787     case LUA_TLIGHTUSERDATA:
788       os << "lightuserdata: " << tostring();
789       break;
790 
791     default:
792       os << "unknown";
793       break;
794     }
795   }
796 
797   //============================================================================
798   //
799   // This group of member functions is mirrored in Proxy
800   //
801 
802   /** Retrieve the lua_State associated with the reference.
803   */
804   lua_State* state () const
805   {
806     return m_L;
807   }
808 
809   //----------------------------------------------------------------------------
810   /**
811       Place the object onto the Lua stack.
812   */
813   void push (lua_State* L) const
814   {
815     assert (equalstates (L, m_L));
816     lua_rawgeti (L, LUA_REGISTRYINDEX, m_ref);
817   }
818 
819   //----------------------------------------------------------------------------
820   /**
821       Pop the top of Lua stack and assign the ref to m_ref
822   */
823   void pop (lua_State* L)
824   {
825     assert (equalstates (L, m_L));
826     luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref);
827     m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
828   }
829 
830   //----------------------------------------------------------------------------
831   /**
832       Determine the object type.
833 
834       The return values are the same as for `lua_type`.
835   */
836   /** @{ */
837   int type () const
838   {
839     int result;
840     if (m_ref != LUA_REFNIL)
841     {
842       push (m_L);
843       result = lua_type (m_L, -1);
844       lua_pop (m_L, 1);
845     }
846     else
847     {
848       result = LUA_TNIL;
849     }
850 
851     return result;
852   }
853 
854   // should never happen
855   //inline bool isNone () const { return m_ref == LUA_NOREF; }
856 
857   inline bool isNil () const { return type () == LUA_TNIL; }
858   inline bool isBoolean () const { return type () == LUA_TBOOLEAN; }
859   inline bool isNumber () const { return type () == LUA_TNUMBER; }
860   inline bool isString () const { return type () == LUA_TSTRING; }
861   inline bool isTable () const { return type () == LUA_TTABLE; }
862   inline bool isFunction () const { return type () == LUA_TFUNCTION; }
863   inline bool isUserdata () const { return type () == LUA_TUSERDATA; }
864   inline bool isThread () const { return type () == LUA_TTHREAD; }
865   inline bool isLightUserdata () const { return type () == LUA_TLIGHTUSERDATA; }
866   /** @} */
867 
868   //----------------------------------------------------------------------------
869   /**
870       Perform an explicit conversion.
871   */
872   template <class T>
873   T cast () const
874   {
875     StackPop p (m_L, 1);
876     push (m_L);
877 
878     // lua_gettop is used because Userdata::getClass() doesn't handle
879     // negative stack indexes.
880     //
881     return Stack <T>::get (m_L, lua_gettop (m_L));
882   }
883 
884   //----------------------------------------------------------------------------
885   /**
886       Universal implicit conversion operator.
887 
888       NOTE: Visual Studio 2010 and 2012 have a bug where this function
889             is not used. See:
890 
891       http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/e30b2664-a92d-445c-9db2-e8e0fbde2014
892       https://connect.microsoft.com/VisualStudio/feedback/details/771509/correct-code-doesnt-compile
893 
894       \code
895           // This code snippet fails to compile in vs2010,vs2012
896           struct S {
897             template <class T> inline operator T () const { return T (); }
898           };
899           int main () {
900             S () || false;
901             return 0;
902           }
903       \endcode
904   */
905   template <class T>
906   inline operator T () const
907   {
908     return cast <T> ();
909   }
910 
911   //----------------------------------------------------------------------------
912   /**
913       Universal comparison operators.
914   */
915   /** @{ */
916   template <class T>
917   bool operator== (T rhs) const
918   {
919     StackPop p (m_L, 2);
920     push (m_L);
921     Stack <T>::push (m_L, rhs);
922     return lua_compare (m_L, -2, -1, LUA_OPEQ) == 1;
923   }
924 
925   template <class T>
926   bool operator< (T rhs) const
927   {
928     StackPop p (m_L, 2);
929     push (m_L);
930     Stack <T>::push (m_L, rhs);
931     return lua_compare (m_L, -2, -1, LUA_OPLT) == 1;
932   }
933 
934   template <class T>
935   bool operator<= (T rhs) const
936   {
937     StackPop p (m_L, 2);
938     push (m_L);
939     Stack <T>::push (m_L, rhs);
940     return lua_compare (m_L, -2, -1, LUA_OPLE) == 1;
941   }
942 
943   template <class T>
944   bool operator> (T rhs) const
945   {
946     StackPop p (m_L, 2);
947     push (m_L);
948     Stack <T>::push (m_L, rhs);
949     return lua_compare (m_L, -1, -2, LUA_OPLT) == 1;
950   }
951 
952   template <class T>
953   bool operator>= (T rhs) const
954   {
955     StackPop p (m_L, 2);
956     push (m_L);
957     Stack <T>::push (m_L, rhs);
958     return lua_compare (m_L, -1, -2, LUA_OPLE) == 1;
959   }
960 
961   template <class T>
962   bool rawequal (T rhs) const
963   {
964     StackPop p (m_L, 2);
965     push (m_L);
966     Stack <T>::push (m_L, rhs);
967     return lua_rawequal (m_L, -1, -2) == 1;
968   }
969   /** @} */
970 
971   //----------------------------------------------------------------------------
972   /**
973       Append a value to the table.
974 
975       If the table is a sequence this will add another element to it.
976   */
977   template <class T>
978   void append (T v) const
979   {
980     push (m_L);
981     Stack <T>::push (m_L, v);
982     luaL_ref (m_L, -2);
983     lua_pop (m_L, 1);
984   }
985 
986   //----------------------------------------------------------------------------
987   /**
988       Call the length operator.
989 
990       This is identical to applying the Lua # operator.
991   */
992   int length () const
993   {
994     StackPop p (m_L, 1);
995     push (m_L);
996     return get_length (m_L, -1);
997   }
998 
999   //----------------------------------------------------------------------------
1000   /**
1001       Access a table value using a key.
1002 
1003       This invokes metamethods.
1004   */
1005   template <class T>
1006   Proxy operator[] (T key) const
1007   {
1008     Stack <T>::push (m_L, key);
1009     return Proxy (m_L, m_ref);
1010   }
1011 
1012   //----------------------------------------------------------------------------
1013   /**
1014       Call Lua code.
1015 
1016       These overloads allow Lua code to be called with up to 8 parameters.
1017       The return value is provided as a LuaRef (which may be LUA_REFNIL).
1018       If an error occurs, a LuaException is thrown.
1019   */
1020   /** @{ */
1021   LuaRef const operator() () const
1022   {
1023     push (m_L);
1024     LuaException::pcall (m_L, 0, 1);
1025     return LuaRef (m_L, FromStack ());
1026   }
1027 
1028   template <class P1>
1029   LuaRef const operator() (P1 p1) const
1030   {
1031     push (m_L);
1032     Stack <P1>::push (m_L, p1);
1033     LuaException::pcall (m_L, 1, 1);
1034     return LuaRef (m_L, FromStack ());
1035   }
1036 
1037   template <class P1, class P2>
1038   LuaRef const operator() (P1 p1, P2 p2) const
1039   {
1040     push (m_L);
1041     Stack <P1>::push (m_L, p1);
1042     Stack <P2>::push (m_L, p2);
1043     LuaException::pcall (m_L, 2, 1);
1044     return LuaRef (m_L, FromStack ());
1045   }
1046 
1047   template <class P1, class P2, class P3>
1048   LuaRef const operator() (P1 p1, P2 p2, P3 p3) const
1049   {
1050     push (m_L);
1051     Stack <P1>::push (m_L, p1);
1052     Stack <P2>::push (m_L, p2);
1053     Stack <P3>::push (m_L, p3);
1054     LuaException::pcall (m_L, 3, 1);
1055     return LuaRef (m_L, FromStack ());
1056   }
1057 
1058   template <class P1, class P2, class P3, class P4>
1059   LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4) const
1060   {
1061     push (m_L);
1062     Stack <P1>::push (m_L, p1);
1063     Stack <P2>::push (m_L, p2);
1064     Stack <P3>::push (m_L, p3);
1065     Stack <P4>::push (m_L, p4);
1066     LuaException::pcall (m_L, 4, 1);
1067     return LuaRef (m_L, FromStack ());
1068   }
1069 
1070   template <class P1, class P2, class P3, class P4, class P5>
1071   LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const
1072   {
1073     push (m_L);
1074     Stack <P1>::push (m_L, p1);
1075     Stack <P2>::push (m_L, p2);
1076     Stack <P3>::push (m_L, p3);
1077     Stack <P4>::push (m_L, p4);
1078     Stack <P5>::push (m_L, p5);
1079     LuaException::pcall (m_L, 5, 1);
1080     return LuaRef (m_L, FromStack ());
1081   }
1082 
1083   template <class P1, class P2, class P3, class P4, class P5, class P6>
1084   LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const
1085   {
1086     push (m_L);
1087     Stack <P1>::push (m_L, p1);
1088     Stack <P2>::push (m_L, p2);
1089     Stack <P3>::push (m_L, p3);
1090     Stack <P4>::push (m_L, p4);
1091     Stack <P5>::push (m_L, p5);
1092     Stack <P6>::push (m_L, p6);
1093     LuaException::pcall (m_L, 6, 1);
1094     return LuaRef (m_L, FromStack ());
1095   }
1096 
1097   template <class P1, class P2, class P3, class P4, class P5, class P6, class P7>
1098   LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const
1099   {
1100     push (m_L);
1101     Stack <P1>::push (m_L, p1);
1102     Stack <P2>::push (m_L, p2);
1103     Stack <P3>::push (m_L, p3);
1104     Stack <P4>::push (m_L, p4);
1105     Stack <P5>::push (m_L, p5);
1106     Stack <P6>::push (m_L, p6);
1107     Stack <P7>::push (m_L, p7);
1108     LuaException::pcall (m_L, 7, 1);
1109     return LuaRef (m_L, FromStack ());
1110   }
1111 
1112   template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
1113   LuaRef const operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const
1114   {
1115     push (m_L);
1116     Stack <P1>::push (m_L, p1);
1117     Stack <P2>::push (m_L, p2);
1118     Stack <P3>::push (m_L, p3);
1119     Stack <P4>::push (m_L, p4);
1120     Stack <P5>::push (m_L, p5);
1121     Stack <P6>::push (m_L, p6);
1122     Stack <P7>::push (m_L, p7);
1123     Stack <P8>::push (m_L, p8);
1124     LuaException::pcall (m_L, 8, 1);
1125     return LuaRef (m_L, FromStack ());
1126   }
1127   /** @} */
1128 
1129   //============================================================================
1130 
1131 private:
1132   lua_State* m_L;
1133   int m_ref;
1134 };
1135 
1136 //------------------------------------------------------------------------------
1137 /**
1138     Stack specialization for Nil
1139 */
1140 template <>
1141 struct Stack <Nil>
1142 {
1143 public:
1144   static inline void push (lua_State* L, Nil)
1145   {
1146     lua_pushnil (L);
1147   }
1148 };
1149 
1150 //------------------------------------------------------------------------------
1151 /**
1152     Stack specialization for LuaRef.
1153 */
1154 template <>
1155 struct Stack <LuaRef>
1156 {
1157 public:
1158   // The value is const& to prevent a copy construction.
1159   //
1160   static inline void push (lua_State* L, LuaRef const& v)
1161   {
1162     v.push (L);
1163   }
1164 
1165   static inline LuaRef get (lua_State* L, int index)
1166   {
1167     return LuaRef (L, index, LuaRef::FromStack ());
1168   }
1169 };
1170 
1171 //------------------------------------------------------------------------------
1172 /**
1173     Stack specialization for Proxy.
1174 */
1175 template <>
1176 struct Stack <LuaRef::Proxy>
1177 {
1178 public:
1179   // The value is const& to prevent a copy construction.
1180   //
1181   static inline void push (lua_State* L, LuaRef::Proxy const& v)
1182   {
1183     v.push (L);
1184   }
1185 };
1186 
1187 //------------------------------------------------------------------------------
1188 /**
1189     Create a reference to a new, empty table.
1190 
1191     This is a syntactic abbreviation for LuaRef::newTable().
1192 */
1193 inline LuaRef newTable (lua_State* L)
1194 {
1195   return LuaRef::newTable (L);
1196 }
1197 
1198 //------------------------------------------------------------------------------
1199 /**
1200     Create a reference to a value in the global table.
1201 
1202     This is a syntactic abbreviation for LuaRef::getGlobal().
1203 */
1204 inline LuaRef getGlobal (lua_State *L, char const* name)
1205 {
1206   return LuaRef::getGlobal (L, name);
1207 }
1208 
1209 //------------------------------------------------------------------------------
1210 /**
1211     Write a LuaRef to a stream.
1212 
1213     This allows LuaRef and table proxies to work with streams.
1214 */
1215 inline std::ostream& operator<< (std::ostream& os, LuaRef const& ref)
1216 {
1217   ref.print (os);
1218   return os;
1219 }
1220 
1221 //------------------------------------------------------------------------------
1222 
1223 // more C++-like cast syntax
1224 //
1225 template<class T>
1226 inline T LuaRef_cast(LuaRef const& lr)
1227 {
1228   return lr.cast<T>();
1229 }
1230