?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

  1. // https://github.com/vinniefalco/LuaBridge
  2. // Copyright 2018, Dmitry Tarakanov
  3. // Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
  4. // Copyright 2008, Nigel Atkinson <suprapilot+LuaCode@gmail.com>
  5. // SPDX-License-Identifier: MIT
  6.  
  7. #pragma once
  8.  
  9. #include <LuaBridge/detail/LuaException.h>
  10. #include <LuaBridge/detail/Stack.h>
  11.  
  12. #include <iostream>
  13. #include <map>
  14. #include <string>
  15. #include <vector>
  16.  
  17. namespace luabridge {
  18.  
  19. //------------------------------------------------------------------------------
  20. /**
  21.     Type tag for representing LUA_TNIL.
  22.  
  23.     Construct one of these using `Nil ()` to represent a Lua nil. This is faster
  24.     than creating a reference in the registry to nil. Example:
  25.  
  26.         LuaRef t (LuaRef::createTable (L));
  27.         ...
  28.         t ["k"] = Nil (); // assign nil
  29. */
  30. struct Nil
  31. {
  32. };
  33.  
  34. //------------------------------------------------------------------------------
  35. /**
  36.     Stack specialization for Nil.
  37. */
  38. template<>
  39. struct Stack<Nil>
  40. {
  41.     static void push(lua_State* L, Nil) { lua_pushnil(L); }
  42.  
  43.     static bool isInstance(lua_State* L, int index) { return lua_type(L, index) == LUA_TNIL; }
  44. };
  45.  
  46. /**
  47.  * Base class for Lua variables and table item reference classes.
  48.  */
  49. template<class Impl, class LuaRef>
  50. class LuaRefBase
  51. {
  52. protected:
  53.     //----------------------------------------------------------------------------
  54.     /**
  55.         Pop the Lua stack.
  56.  
  57.         Pops the specified number of stack items on destruction. We use this
  58.         when returning objects, to avoid an explicit temporary variable, since
  59.         the destructor executes after the return statement. For example:
  60.  
  61.             template <class U>
  62.             U cast (lua_State* L)
  63.             {
  64.               StackPop p (L, 1);
  65.               ...
  66.               return U (); // dtor called after this line
  67.             }
  68.  
  69.         @note The `StackPop` object must always be a named local variable.
  70.     */
  71.     class StackPop
  72.     {
  73.     public:
  74.         /** Create a StackPop object.
  75.  
  76.             @param L     A Lua state.
  77.             @param count The number of stack entries to pop on destruction.
  78.         */
  79.         StackPop(lua_State* L, int count) : m_L(L), m_count(count) {}
  80.  
  81.         ~StackPop() { lua_pop(m_L, m_count); }
  82.  
  83.     private:
  84.         lua_State* m_L;
  85.         int m_count;
  86.     };
  87.  
  88.     friend struct Stack<LuaRef>;
  89.  
  90.     //----------------------------------------------------------------------------
  91.     /**
  92.         Type tag for stack construction.
  93.     */
  94.     struct FromStack
  95.     {
  96.     };
  97.  
  98.     LuaRefBase(lua_State* L) : m_L(L) {}
  99.  
  100.     //----------------------------------------------------------------------------
  101.     /**
  102.         Create a reference to this reference.
  103.  
  104.         @returns An index in the Lua registry.
  105.     */
  106.     int createRef() const
  107.     {
  108.         impl().push();
  109.         return luaL_ref(m_L, LUA_REGISTRYINDEX);
  110.     }
  111.  
  112. public:
  113.     //----------------------------------------------------------------------------
  114.     /**
  115.         Convert to a string using lua_tostring function.
  116.  
  117.         @returns A string representation of the referred Lua value.
  118.     */
  119.     std::string tostring() const
  120.     {
  121.         lua_getglobal(m_L, "tostring");
  122.         impl().push();
  123.         lua_call(m_L, 1, 1);
  124.         const char* str = lua_tostring(m_L, -1);
  125.         lua_pop(m_L, 1);
  126.         return str;
  127.     }
  128.  
  129.     //----------------------------------------------------------------------------
  130.     /**
  131.         Print a text description of the value to a stream.
  132.         This is used for diagnostics.
  133.  
  134.         @param os An output stream.
  135.     */
  136.     void print(std::ostream& os) const
  137.     {
  138.         switch (type())
  139.         {
  140.         case LUA_TNIL:
  141.             os << "nil";
  142.             break;
  143.  
  144.         case LUA_TNUMBER:
  145.             os << cast<lua_Number>();
  146.             break;
  147.  
  148.         case LUA_TBOOLEAN:
  149.             os << (cast<bool>() ? "true" : "false");
  150.             break;
  151.  
  152.         case LUA_TSTRING:
  153.             os << '"' << cast<std::string>() << '"';
  154.             break;
  155.  
  156.         case LUA_TTABLE:
  157.             os << "table: " << tostring();
  158.             break;
  159.  
  160.         case LUA_TFUNCTION:
  161.             os << "function: " << tostring();
  162.             break;
  163.  
  164.         case LUA_TUSERDATA:
  165.             os << "userdata: " << tostring();
  166.             break;
  167.  
  168.         case LUA_TTHREAD:
  169.             os << "thread: " << tostring();
  170.             break;
  171.  
  172.         case LUA_TLIGHTUSERDATA:
  173.             os << "lightuserdata: " << tostring();
  174.             break;
  175.  
  176.         default:
  177.             os << "unknown";
  178.             break;
  179.         }
  180.     }
  181.  
  182.     //------------------------------------------------------------------------------
  183.     /**
  184.       Insert a Lua value or table item reference to a stream.
  185.  
  186.       @param os  An output stream.
  187.       @param ref A Lua reference.
  188.       @returns The output stream.
  189.     */
  190.     friend std::ostream& operator<<(std::ostream& os, LuaRefBase const& ref)
  191.     {
  192.         ref.print(os);
  193.         return os;
  194.     }
  195.  
  196.     //============================================================================
  197.     //
  198.     // This group of member functions is mirrored in TableItem
  199.     //
  200.  
  201.     /** Retrieve the lua_State associated with the reference.
  202.  
  203.       @returns A Lua state.
  204.     */
  205.     lua_State* state() const { return m_L; }
  206.  
  207.     //----------------------------------------------------------------------------
  208.     /**
  209.         Place the object onto the Lua stack.
  210.  
  211.         @param L A Lua state.
  212.     */
  213.     void push(lua_State* L) const
  214.     {
  215.         assert(equalstates(L, m_L));
  216.         (void) L;
  217.         impl().push();
  218.     }
  219.  
  220.     //----------------------------------------------------------------------------
  221.     /**
  222.         Pop the top of Lua stack and assign it to the reference.
  223.  
  224.         @param L A Lua state.
  225.     */
  226.     void pop(lua_State* L)
  227.     {
  228.         assert(equalstates(L, m_L));
  229.         (void) L;
  230.         impl().pop();
  231.     }
  232.  
  233.     //----------------------------------------------------------------------------
  234.     /**
  235.         Return the Lua type of the referred value. This invokes lua_type().
  236.  
  237.         @returns The type of the referred value.
  238.         @see lua_type()
  239.     */
  240.     /** @{ */
  241.     int type() const
  242.     {
  243.         impl().push();
  244.         StackPop p(m_L, 1);
  245.         return lua_type(m_L, -1);
  246.     }
  247.  
  248.     // should never happen
  249.     // bool isNone () const { return m_ref == LUA_NOREF; }
  250.  
  251.     /// Indicate whether it is a nil reference.
  252.     ///
  253.     /// @returns True if this is a nil reference, false otherwice.
  254.     ///
  255.     bool isNil() const { return type() == LUA_TNIL; }
  256.  
  257.     /// Indicate whether it is a reference to a boolean.
  258.     ///
  259.     /// @returns True if it is a reference to a boolean, false otherwice.
  260.     ///
  261.     bool isBool() const { return type() == LUA_TBOOLEAN; }
  262.  
  263.     /// Indicate whether it is a reference to a number.
  264.     ///
  265.     /// @returns True if it is a reference to a number, false otherwise.
  266.     ///
  267.     bool isNumber() const { return type() == LUA_TNUMBER; }
  268.  
  269.     /// Indicate whether it is a reference to a string.
  270.     ///
  271.     /// @returns True if it is a reference to a string, false otherwise.
  272.     ///
  273.     bool isString() const { return type() == LUA_TSTRING; }
  274.  
  275.     /// Indicate whether it is a reference to a table.
  276.     ///
  277.     /// @returns True if it is a reference to a table, false otherwise.
  278.     ///
  279.     bool isTable() const { return type() == LUA_TTABLE; }
  280.  
  281.     /// Indicate whether it is a reference to a function.
  282.     ///
  283.     /// @returns True if it is a reference to a function, false otherwise.
  284.     ///
  285.     bool isFunction() const { return type() == LUA_TFUNCTION; }
  286.  
  287.     /// Indicate whether it is a reference to a full userdata.
  288.     ///
  289.     /// @returns True if it is a reference to a full userdata, false otherwise.
  290.     ///
  291.     bool isUserdata() const { return type() == LUA_TUSERDATA; }
  292.  
  293.     /// Indicate whether it is a reference to a Lua thread.
  294.     ///
  295.     /// @returns True if it is a reference to a Lua thread, false otherwise.
  296.     ///
  297.     bool isThread() const { return type() == LUA_TTHREAD; }
  298.  
  299.     /// Indicate whether it is a reference to a light userdata.
  300.     ///
  301.     /// @returns True if it is a reference to a light userdata, false otherwise.
  302.     ///
  303.     bool isLightUserdata() const { return type() == LUA_TLIGHTUSERDATA; }
  304.  
  305.     /** @} */
  306.  
  307.     //----------------------------------------------------------------------------
  308.     /**
  309.         Perform an explicit conversion to the type T.
  310.  
  311.         @returns A value of the type T converted from this reference.
  312.     */
  313.     template<class T>
  314.     T cast() const
  315.     {
  316.         StackPop p(m_L, 1);
  317.         impl().push();
  318.         return Stack<T>::get(m_L, -1);
  319.     }
  320.  
  321.     //----------------------------------------------------------------------------
  322.     /**
  323.         Indicate if this reference is convertible to the type T.
  324.  
  325.         @returns True if the referred value is convertible to the type T,
  326.                 false otherwise.
  327.     */
  328.     template<class T>
  329.     bool isInstance() const
  330.     {
  331.         StackPop p(m_L, 1);
  332.         impl().push();
  333.         return Stack<T>::isInstance(m_L, -1);
  334.     }
  335.  
  336.     //----------------------------------------------------------------------------
  337.     /**
  338.         Type cast operator.
  339.  
  340.         @returns A value of the type T converted from this reference.
  341.     */
  342.     template<class T>
  343.     operator T() const
  344.     {
  345.         return cast<T>();
  346.     }
  347.  
  348.     //----------------------------------------------------------------------------
  349.     /** @{ */
  350.     /**
  351.         Compare this reference with a specified value using lua_compare().
  352.         This invokes metamethods.
  353.  
  354.         @param rhs A value to compare with.
  355.         @returns True if the referred value is equal to the specified one.
  356.     */
  357.     template<class T>
  358.     bool operator==(T const& rhs) const
  359.     {
  360.         StackPop p(m_L, 2);
  361.         impl().push();
  362.         Stack<T>::push(m_L, rhs);
  363.         return lua_compare(m_L, -2, -1, LUA_OPEQ) == 1;
  364.     }
  365.  
  366.     /**
  367.         Compare this reference with a specified value using lua_compare().
  368.         This invokes metamethods.
  369.  
  370.         @param rhs A value to compare with.
  371.         @returns True if the referred value is less than the specified one.
  372.     */
  373.     template<class T>
  374.     bool operator<(T const& rhs) const
  375.     {
  376.         StackPop p(m_L, 2);
  377.         impl().push();
  378.         ;
  379.         Stack<T>::push(m_L, rhs);
  380.         int lhsType = lua_type(m_L, -2);
  381.         int rhsType = lua_type(m_L, -1);
  382.         if (lhsType != rhsType)
  383.         {
  384.             return lhsType < rhsType;
  385.         }
  386.         return lua_compare(m_L, -2, -1, LUA_OPLT) == 1;
  387.     }
  388.  
  389.     /**
  390.         Compare this reference with a specified value using lua_compare().
  391.         This invokes metamethods.
  392.  
  393.         @param rhs A value to compare with.
  394.         @returns True if the referred value is less than or equal to the specified one.
  395.     */
  396.     template<class T>
  397.     bool operator<=(T const& rhs) const
  398.     {
  399.         StackPop p(m_L, 2);
  400.         impl().push();
  401.         ;
  402.         Stack<T>::push(m_L, rhs);
  403.         int lhsType = lua_type(m_L, -2);
  404.         int rhsType = lua_type(m_L, -1);
  405.         if (lhsType != rhsType)
  406.         {
  407.             return lhsType <= rhsType;
  408.         }
  409.         return lua_compare(m_L, -2, -1, LUA_OPLE) == 1;
  410.     }
  411.  
  412.     /**
  413.         Compare this reference with a specified value using lua_compare().
  414.         This invokes metamethods.
  415.  
  416.         @param rhs A value to compare with.
  417.         @returns True if the referred value is greater than the specified one.
  418.     */
  419.     template<class T>
  420.     bool operator>(T const& rhs) const
  421.     {
  422.         StackPop p(m_L, 2);
  423.         impl().push();
  424.         ;
  425.         Stack<T>::push(m_L, rhs);
  426.         int lhsType = lua_type(m_L, -2);
  427.         int rhsType = lua_type(m_L, -1);
  428.         if (lhsType != rhsType)
  429.         {
  430.             return lhsType > rhsType;
  431.         }
  432.         return lua_compare(m_L, -1, -2, LUA_OPLT) == 1;
  433.     }
  434.  
  435.     /**
  436.         Compare this reference with a specified value using lua_compare().
  437.         This invokes metamethods.
  438.  
  439.         @param rhs A value to compare with.
  440.         @returns True if the referred value is greater than or equal to the specified one.
  441.     */
  442.     template<class T>
  443.     bool operator>=(T rhs) const
  444.     {
  445.         StackPop p(m_L, 2);
  446.         impl().push();
  447.         ;
  448.         Stack<T>::push(m_L, rhs);
  449.         int lhsType = lua_type(m_L, -2);
  450.         int rhsType = lua_type(m_L, -1);
  451.         if (lhsType != rhsType)
  452.         {
  453.             return lhsType >= rhsType;
  454.         }
  455.         return lua_compare(m_L, -1, -2, LUA_OPLE) == 1;
  456.     }
  457.  
  458.     /**
  459.         Compare this reference with a specified value using lua_compare().
  460.         This does not invoke metamethods.
  461.  
  462.         @param rhs A value to compare with.
  463.         @returns True if the referred value is equal to the specified one.
  464.     */
  465.     template<class T>
  466.     bool rawequal(T const& rhs) const
  467.     {
  468.         StackPop p(m_L, 2);
  469.         impl().push();
  470.         ;
  471.         Stack<T>::push(m_L, rhs);
  472.         return lua_rawequal(m_L, -1, -2) == 1;
  473.     }
  474.     /** @} */
  475.  
  476.     //----------------------------------------------------------------------------
  477.     /**
  478.         Append a value to a referred table.
  479.         If the table is a sequence this will add another element to it.
  480.  
  481.         @param v A value to append to the table.
  482.     */
  483.     template<class T>
  484.     void append(T const& v) const
  485.     {
  486.         impl().push();
  487.         ;
  488.         Stack<T>::push(m_L, v);
  489.         luaL_ref(m_L, -2);
  490.         lua_pop(m_L, 1);
  491.     }
  492.  
  493.     //----------------------------------------------------------------------------
  494.     /**
  495.         Return the length of a referred array.
  496.         This is identical to applying the Lua # operator.
  497.  
  498.         @returns The length of the referred array.
  499.     */
  500.     int length() const
  501.     {
  502.         StackPop p(m_L, 1);
  503.         impl().push();
  504.         ;
  505.         return get_length(m_L, -1);
  506.     }
  507.  
  508.     //----------------------------------------------------------------------------
  509.     /**
  510.         Call Lua code with a variable amount of parameters.
  511.         The return value is provided as a LuaRef (which may be LUA_REFNIL).
  512.         If an error occurs, a LuaException is thrown.
  513.  
  514.         @returns A result of the call.
  515.     */
  516.     template<typename... Arguments>
  517.     LuaRef operator()(Arguments&&... arguments) const
  518.     {
  519.         impl().push();
  520.         pushArguments(std::forward<Arguments>(arguments)...);
  521.         LuaException::pcall(m_L, sizeof...(arguments), 1);
  522.         return LuaRef::fromStack(m_L);
  523.     }
  524.  
  525.     //============================================================================
  526.  
  527. protected:
  528.     lua_State* m_L;
  529.  
  530. private:
  531.     const Impl& impl() const { return static_cast<const Impl&>(*this); }
  532.  
  533.     Impl& impl() { return static_cast<Impl&>(*this); }
  534.  
  535.     void pushArguments() const {}
  536.  
  537.     template<typename T, typename... Arguments>
  538.     void pushArguments(T const& argument, Arguments&&... arguments) const
  539.     {
  540.         Stack<T>::push(m_L, argument);
  541.  
  542.         pushArguments(std::forward<Arguments>(arguments)...);
  543.     }
  544. };
  545.  
  546. //------------------------------------------------------------------------------
  547. /**
  548.     Lightweight reference to a Lua object.
  549.  
  550.     The reference is maintained for the lifetime of the C++ object.
  551. */
  552. class LuaRef : public LuaRefBase<LuaRef, LuaRef>
  553. {
  554.     //----------------------------------------------------------------------------
  555.     /**
  556.         A proxy for representing table values.
  557.     */
  558.     class TableItem : public LuaRefBase<TableItem, LuaRef>
  559.     {
  560.         friend class LuaRef;
  561.  
  562.     public:
  563.         //--------------------------------------------------------------------------
  564.         /**
  565.             Construct a TableItem from a table value.
  566.             The table is in the registry, and the key is at the top of the stack.
  567.             The key is popped off the stack.
  568.  
  569.             @param L        A lua state.
  570.             @param tableRef The index of a table in the Lua registry.
  571.         */
  572.         TableItem(lua_State* L, int tableRef)
  573.             : LuaRefBase(L), m_tableRef(LUA_NOREF), m_keyRef(luaL_ref(L, LUA_REGISTRYINDEX))
  574.         {
  575.             lua_rawgeti(m_L, LUA_REGISTRYINDEX, tableRef);
  576.             m_tableRef = luaL_ref(L, LUA_REGISTRYINDEX);
  577.         }
  578.  
  579.         //--------------------------------------------------------------------------
  580.         /**
  581.             Create a TableItem via copy constructor.
  582.             It is best to avoid code paths that invoke this, because it creates
  583.             an extra temporary Lua reference. Typically this is done by passing
  584.             the TableItem parameter as a `const` reference.
  585.  
  586.             @param other Another Lua table item reference.
  587.         */
  588.         TableItem(TableItem const& other)
  589.             : LuaRefBase(other.m_L), m_tableRef(LUA_NOREF), m_keyRef(LUA_NOREF)
  590.         {
  591.             lua_rawgeti(m_L, LUA_REGISTRYINDEX, other.m_tableRef);
  592.             m_tableRef = luaL_ref(m_L, LUA_REGISTRYINDEX);
  593.  
  594.             lua_rawgeti(m_L, LUA_REGISTRYINDEX, other.m_keyRef);
  595.             m_keyRef = luaL_ref(m_L, LUA_REGISTRYINDEX);
  596.         }
  597.  
  598.         //--------------------------------------------------------------------------
  599.         /**
  600.             Destroy the proxy.
  601.             This does not destroy the table value.
  602.         */
  603.         ~TableItem()
  604.         {
  605.             luaL_unref(m_L, LUA_REGISTRYINDEX, m_keyRef);
  606.             luaL_unref(m_L, LUA_REGISTRYINDEX, m_tableRef);
  607.         }
  608.  
  609.         //--------------------------------------------------------------------------
  610.         /**
  611.             Assign a new value to this table key.
  612.             This may invoke metamethods.
  613.  
  614.             @tparam T The type of a value to assing.
  615.             @param  v A value to assign.
  616.             @returns This reference.
  617.         */
  618.         template<class T>
  619.         TableItem& operator=(T const& v)
  620.         {
  621.             StackPop p(m_L, 1);
  622.             lua_rawgeti(m_L, LUA_REGISTRYINDEX, m_tableRef);
  623.             lua_rawgeti(m_L, LUA_REGISTRYINDEX, m_keyRef);
  624.             Stack<T>::push(m_L, v);
  625.             lua_settable(m_L, -3);
  626.             return *this;
  627.         }
  628.  
  629.         //--------------------------------------------------------------------------
  630.         /**
  631.             Assign a new value to this table key.
  632.             The assignment is raw, no metamethods are invoked.
  633.  
  634.             @tparam T The type of a value to assing.
  635.             @param  v A value to assign.
  636.             @returns This reference.
  637.         */
  638.         template<class T>
  639.         TableItem& rawset(T const& v)
  640.         {
  641.             StackPop p(m_L, 1);
  642.             lua_rawgeti(m_L, LUA_REGISTRYINDEX, m_tableRef);
  643.             lua_rawgeti(m_L, LUA_REGISTRYINDEX, m_keyRef);
  644.             Stack<T>::push(m_L, v);
  645.             lua_rawset(m_L, -3);
  646.             return *this;
  647.         }
  648.  
  649.         //--------------------------------------------------------------------------
  650.         /**
  651.             Push the value onto the Lua stack.
  652.         */
  653.         using LuaRefBase::push;
  654.  
  655.         void push() const
  656.         {
  657.             lua_rawgeti(m_L, LUA_REGISTRYINDEX, m_tableRef);
  658.             lua_rawgeti(m_L, LUA_REGISTRYINDEX, m_keyRef);
  659.             lua_gettable(m_L, -2);
  660.             lua_remove(m_L, -2); // remove the table
  661.         }
  662.  
  663.         //--------------------------------------------------------------------------
  664.         /**
  665.             Access a table value using a key.
  666.             This invokes metamethods.
  667.  
  668.             @tparam T   The type of a key.
  669.             @param  key A key value.
  670.             @returns A Lua table item reference.
  671.         */
  672.         template<class T>
  673.         TableItem operator[](T const& key) const
  674.         {
  675.             return LuaRef(*this)[key];
  676.         }
  677.  
  678.         //--------------------------------------------------------------------------
  679.         /**
  680.             Access a table value using a key.
  681.             The operation is raw, metamethods are not invoked. The result is
  682.             passed by value and may not be modified.
  683.  
  684.             @tparam T   The type of a key.
  685.             @param  key A key value.
  686.             @returns A Lua value reference.
  687.         */
  688.         template<class T>
  689.         LuaRef rawget(T const& key) const
  690.         {
  691.             return LuaRef(*this).rawget(key);
  692.         }
  693.  
  694.     private:
  695.         int m_tableRef;
  696.         int m_keyRef;
  697.     };
  698.  
  699.     friend struct Stack<TableItem>;
  700.     friend struct Stack<TableItem&>;
  701.  
  702.     //----------------------------------------------------------------------------
  703.     /**
  704.         Create a reference to an object at the top of the Lua stack and pop it.
  705.         This constructor is private and not invoked directly.
  706.         Instead, use the `fromStack` function.
  707.  
  708.         @param L A Lua state.
  709.         @note The object is popped.
  710.     */
  711.     LuaRef(lua_State* L, FromStack) : LuaRefBase(L), m_ref(luaL_ref(m_L, LUA_REGISTRYINDEX)) {}
  712.  
  713.     //----------------------------------------------------------------------------
  714.     /**
  715.         Create a reference to an object on the Lua stack.
  716.         This constructor is private and not invoked directly.
  717.         Instead, use the `fromStack` function.
  718.  
  719.         @param L     A Lua state.
  720.         @param index The index of the value on the Lua stack.
  721.         @note The object is not popped.
  722.     */
  723.     LuaRef(lua_State* L, int index, FromStack) : LuaRefBase(L), m_ref(LUA_NOREF)
  724.     {
  725.         lua_pushvalue(m_L, index);
  726.         m_ref = luaL_ref(m_L, LUA_REGISTRYINDEX);
  727.     }
  728.  
  729. public:
  730.     //----------------------------------------------------------------------------
  731.     /**
  732.         Create a nil reference.
  733.         The Lua reference may be assigned later.
  734.  
  735.         @param L A Lua state.
  736.     */
  737.     LuaRef(lua_State* L) : LuaRefBase(L), m_ref(LUA_NOREF) {}
  738.  
  739.     //----------------------------------------------------------------------------
  740.     /**
  741.         Push a value onto a Lua stack and return a reference to it.
  742.  
  743.         @param L A Lua state.
  744.         @param v A value to push.
  745.     */
  746.     template<class T>
  747.     LuaRef(lua_State* L, T v) : LuaRefBase(L), m_ref(LUA_NOREF)
  748.     {
  749.         Stack<T>::push(m_L, v);
  750.         m_ref = luaL_ref(m_L, LUA_REGISTRYINDEX);
  751.     }
  752.  
  753.     //----------------------------------------------------------------------------
  754.     /**
  755.         Create a reference to a table item.
  756.  
  757.         @param v A table item reference.
  758.     */
  759.     LuaRef(TableItem const& v) : LuaRefBase(v.state()), m_ref(v.createRef()) {}
  760.  
  761.     //----------------------------------------------------------------------------
  762.     /**
  763.         Create a new reference to an existing Lua value.
  764.  
  765.         @param other An existing reference.
  766.     */
  767.     LuaRef(LuaRef const& other) : LuaRefBase(other.m_L), m_ref(other.createRef()) {}
  768.  
  769.     //----------------------------------------------------------------------------
  770.     /**
  771.         Destroy a reference.
  772.  
  773.         The corresponding Lua registry reference will be released.
  774.  
  775.         @note If the state refers to a thread, it is the responsibility of the
  776.               caller to ensure that the thread still exists when the LuaRef
  777.               is destroyed.
  778.     */
  779.     ~LuaRef() { luaL_unref(m_L, LUA_REGISTRYINDEX, m_ref); }
  780.  
  781.     //----------------------------------------------------------------------------
  782.     /**
  783.         Return a reference to a top Lua stack item.
  784.         The stack item is not popped.
  785.  
  786.         @param L A Lua state.
  787.         @returns A reference to a value on the top of a Lua stack.
  788.     */
  789.     static LuaRef fromStack(lua_State* L) { return LuaRef(L, FromStack()); }
  790.  
  791.     //----------------------------------------------------------------------------
  792.     /**
  793.         Return a reference to a Lua stack item with a specified index.
  794.         The stack item is not removed.
  795.  
  796.         @param L     A Lua state.
  797.         @param index An index in the Lua stack.
  798.         @returns A reference to a value in a Lua stack.
  799.     */
  800.     static LuaRef fromStack(lua_State* L, int index)
  801.     {
  802.         lua_pushvalue(L, index);
  803.         return LuaRef(L, FromStack());
  804.     }
  805.  
  806.     //----------------------------------------------------------------------------
  807.     /**
  808.         Create a new empty table on the top of a Lua stack
  809.         and return a reference to it.
  810.  
  811.         @param L A Lua state.
  812.         @returns A reference to the newly created table.
  813.         @see luabridge::newTable()
  814.     */
  815.     static LuaRef newTable(lua_State* L)
  816.     {
  817.         lua_newtable(L);
  818.         return LuaRef(L, FromStack());
  819.     }
  820.  
  821.     //----------------------------------------------------------------------------
  822.     /**
  823.         Return a reference to a named global Lua variable.
  824.  
  825.         @param L    A Lua state.
  826.         @param name The name of a global variable.
  827.         @returns A reference to the Lua variable.
  828.         @see luabridge::getGlobal()
  829.     */
  830.     static LuaRef getGlobal(lua_State* L, char const* name)
  831.     {
  832.         lua_getglobal(L, name);
  833.         return LuaRef(L, FromStack());
  834.     }
  835.  
  836.     //----------------------------------------------------------------------------
  837.     /**
  838.         Assign another LuaRef to this LuaRef.
  839.  
  840.         @param rhs A reference to assign from.
  841.         @returns This reference.
  842.     */
  843.     LuaRef& operator=(LuaRef const& rhs)
  844.     {
  845.         LuaRef ref(rhs);
  846.         swap(ref);
  847.         return *this;
  848.     }
  849.  
  850.     //----------------------------------------------------------------------------
  851.     /**
  852.         Assign a table item reference.
  853.  
  854.         @param rhs A table item reference.
  855.         @returns This reference.
  856.     */
  857.     LuaRef& operator=(LuaRef::TableItem const& rhs)
  858.     {
  859.         LuaRef ref(rhs);
  860.         swap(ref);
  861.         return *this;
  862.     }
  863.  
  864.     //----------------------------------------------------------------------------
  865.     /**
  866.       Assign nil to this reference.
  867.  
  868.       @returns This reference.
  869.     */
  870.     LuaRef& operator=(Nil const&)
  871.     {
  872.         LuaRef ref(m_L);
  873.         swap(ref);
  874.         return *this;
  875.     }
  876.  
  877.     //----------------------------------------------------------------------------
  878.     /**
  879.         Assign a different value to this reference.
  880.  
  881.         @param rhs A value to assign.
  882.         @returns This reference.
  883.     */
  884.     template<class T>
  885.     LuaRef& operator=(T const& rhs)
  886.     {
  887.         LuaRef ref(m_L, rhs);
  888.         swap(ref);
  889.         return *this;
  890.     }
  891.  
  892.     //----------------------------------------------------------------------------
  893.     /**
  894.         Place the object onto the Lua stack.
  895.     */
  896.     using LuaRefBase::push;
  897.  
  898.     void push() const { lua_rawgeti(m_L, LUA_REGISTRYINDEX, m_ref); }
  899.  
  900.     //----------------------------------------------------------------------------
  901.     /**
  902.         Pop the top of Lua stack and assign the ref to m_ref
  903.     */
  904.     void pop()
  905.     {
  906.         luaL_unref(m_L, LUA_REGISTRYINDEX, m_ref);
  907.         m_ref = luaL_ref(m_L, LUA_REGISTRYINDEX);
  908.     }
  909.  
  910.     //----------------------------------------------------------------------------
  911.     /**
  912.         Access a table value using a key.
  913.         This invokes metamethods.
  914.  
  915.         @param key A key in the table.
  916.         @returns A reference to the table item.
  917.     */
  918.     template<class T>
  919.     TableItem operator[](T key) const
  920.     {
  921.         Stack<T>::push(m_L, key);
  922.         return TableItem(m_L, m_ref);
  923.     }
  924.  
  925.     //--------------------------------------------------------------------------
  926.     /**
  927.         Access a table value using a key.
  928.         The operation is raw, metamethods are not invoked. The result is
  929.         passed by value and may not be modified.
  930.  
  931.         @param key A key in the table.
  932.         @returns A reference to the table item.
  933.     */
  934.     template<class T>
  935.     LuaRef rawget(T const& key) const
  936.     {
  937.         StackPop(m_L, 1);
  938.         push(m_L);
  939.         Stack<T>::push(m_L, key);
  940.         lua_rawget(m_L, -2);
  941.         return LuaRef(m_L, FromStack());
  942.     }
  943.  
  944. private:
  945.     void swap(LuaRef& other)
  946.     {
  947.         std::swap(m_L, other.m_L);
  948.         std::swap(m_ref, other.m_ref);
  949.     }
  950.  
  951.     int m_ref;
  952. };
  953.  
  954. //------------------------------------------------------------------------------
  955. /**
  956.  * Stack specialization for `LuaRef`.
  957.  */
  958. template<>
  959. struct Stack<LuaRef>
  960. {
  961.     // The value is const& to prevent a copy construction.
  962.     //
  963.     static void push(lua_State* L, LuaRef const& v) { v.push(L); }
  964.  
  965.     static LuaRef get(lua_State* L, int index) { return LuaRef::fromStack(L, index); }
  966. };
  967.  
  968. //------------------------------------------------------------------------------
  969. /**
  970.  * Stack specialization for `TableItem`.
  971.  */
  972. template<>
  973. struct Stack<LuaRef::TableItem>
  974. {
  975.     // The value is const& to prevent a copy construction.
  976.     //
  977.     static void push(lua_State* L, LuaRef::TableItem const& v) { v.push(L); }
  978. };
  979.  
  980. //------------------------------------------------------------------------------
  981. /**
  982.     Create a reference to a new, empty table.
  983.  
  984.     This is a syntactic abbreviation for LuaRef::newTable ().
  985. */
  986. inline LuaRef newTable(lua_State* L)
  987. {
  988.     return LuaRef::newTable(L);
  989. }
  990.  
  991. //------------------------------------------------------------------------------
  992. /**
  993.     Create a reference to a value in the global table.
  994.  
  995.     This is a syntactic abbreviation for LuaRef::getGlobal ().
  996. */
  997. inline LuaRef getGlobal(lua_State* L, char const* name)
  998. {
  999.     return LuaRef::getGlobal(L, name);
  1000. }
  1001.  
  1002. //------------------------------------------------------------------------------
  1003.  
  1004. // more C++-like cast syntax
  1005. //
  1006. template<class T>
  1007. T LuaRef_cast(LuaRef const& lr)
  1008. {
  1009.     return lr.cast<T>();
  1010. }
  1011.  
  1012. } // namespace luabridge
  1013.