"Fossies" - the Fresh Open Source Software Archive

Member "highlight-3.57-x64/src/include/Diluculum/LuaValue.hpp" (12 May 2020, 14874 Bytes) of package /windows/www/highlight-3.57-x64.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /******************************************************************************\
    2 * LuaValue.hpp                                                                 *
    3 * A class that somewhat mimics a Lua value.                                    *
    4 *                                                                              *
    5 *                                                                              *
    6 * Copyright (C) 2005-2013 by Leandro Motta Barros.                             *
    7 *                                                                              *
    8 * Permission is hereby granted, free of charge, to any person obtaining a copy *
    9 * of this software and associated documentation files (the "Software"), to     *
   10 * deal in the Software without restriction, including without limitation the   *
   11 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or  *
   12 * sell copies of the Software, and to permit persons to whom the Software is   *
   13 * furnished to do so, subject to the following conditions:                     *
   14 *                                                                              *
   15 * The above copyright notice and this permission notice shall be included in   *
   16 * all copies or substantial portions of the Software.                          *
   17 *                                                                              *
   18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR   *
   19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,     *
   20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE *
   21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER       *
   22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      *
   23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS *
   24 * IN THE SOFTWARE.                                                             *
   25 \******************************************************************************/
   26 
   27 #ifndef _DILUCULUM_LUA_VALUE_HPP_
   28 #define _DILUCULUM_LUA_VALUE_HPP_
   29 
   30 #include <lua.hpp>
   31 #include <map>
   32 #include <stdexcept>
   33 #include <string>
   34 #include <Diluculum/CppObject.hpp>
   35 #include <Diluculum/LuaUserData.hpp>
   36 #include <Diluculum/LuaFunction.hpp>
   37 #include <Diluculum/Types.hpp>
   38 
   39 
   40 namespace Diluculum
   41 {
   42    /** A class that somewhat mimics a Lua value. Notice that a \c LuaValue is
   43     *  a C++-side thing. There is absolutely no relationship between a
   44     *  \c LuaValue and a Lua state. This is particularly important for tables
   45     *  and userdata: in Lua, these things are garbage-collectible objects, and
   46     *  variables are just references to them. In Diluculum, a \c LuaValue
   47     *  represents the value (hence the name!). So, if a \c LuaValue holds a
   48     *  table, then it contains a collection of keys and values. Similarly, if it
   49     *  holds a userdata, it actually contains a block of memory with some data.
   50     */
   51    class LuaValue
   52    {
   53       public:
   54          /// Constructs a \c LuaValue with a \c nil value.
   55          LuaValue();
   56 
   57          /// Constructs a \c LuaValue with boolean type and \c b value.
   58          LuaValue (bool b);
   59 
   60          /// Constructs a \c LuaValue with number type and \c n value.
   61          LuaValue (float n);
   62 
   63          /// Constructs a \c LuaValue with number type and \c n value.
   64          LuaValue (double n);
   65 
   66          /// Constructs a \c LuaValue with number type and \c n value.
   67          LuaValue (long double n);
   68 
   69          /// Constructs a \c LuaValue with number type and \c n value.
   70          LuaValue (short n);
   71 
   72          /// Constructs a \c LuaValue with number type and \c n value.
   73          LuaValue (unsigned short n);
   74 
   75          /// Constructs a \c LuaValue with number type and \c n value.
   76          LuaValue (int n);
   77 
   78          /// Constructs a \c LuaValue with number type and \c n value.
   79          LuaValue (unsigned n);
   80 
   81          /// Constructs a \c LuaValue with number type and \c n value.
   82          LuaValue (long n);
   83 
   84          /// Constructs a \c LuaValue with number type and \c n value.
   85          LuaValue (unsigned long n);
   86 
   87          /// Constructs a \c LuaValue with string type and \c s value.
   88          LuaValue (const std::string& s);
   89 
   90          /// Constructs a \c LuaValue with string type and \c s value.
   91          LuaValue (const char* s);
   92 
   93          /// Constructs a \c LuaValue with table type and \c t value.
   94          LuaValue (const LuaValueMap& t);
   95 
   96          /// Constructs a \c LuaValue with function type and \c f value.
   97          LuaValue (lua_CFunction f);
   98 
   99          /// Constructs a \c LuaValue with function type and \c f value.
  100          LuaValue (const LuaFunction& f);
  101 
  102          /// Constructs a \c LuaValue with "user data" type and \c ud value.
  103          LuaValue (const LuaUserData& ud);
  104 
  105          /** Constructs a \c LuaValue from a \c LuaValueList. The first value on
  106           *  the list is used to initialize the \c LuaValue. If the
  107           *  \c LuaValueList is empty, initializes the constructed \c LuaValue
  108           *  to \c Nil.
  109           */
  110          LuaValue (const LuaValueList& v);
  111 
  112          /// Copy constructor.
  113          LuaValue (const LuaValue& other);
  114 
  115          /// Destroys the \c LuaValue, freeing all the resources owned by it.
  116          ~LuaValue() { destroyObjectAtData(); }
  117 
  118          /// Assignment operator.
  119          LuaValue& operator= (const LuaValue& rhs);
  120 
  121          /** Assigns a \c LuaValueList to a \c LuaValue. The first value on
  122           *  the list is used to initialize the \c LuaValue. If the
  123           *  \c LuaValueList is empty, sets the \c LuaValue to \c Nil.
  124           */
  125          const LuaValueList& operator= (const LuaValueList& rhs);
  126 
  127          /** Returns one of the <tt>LUA_T*</tt> constants from <tt>lua.h</tt>,
  128           *  representing the type stored in this \c LuaValue.
  129           */
  130          int type() const { return dataType_; }
  131 
  132          /** Returns the type of this \c LuaValue as a string, just like the Lua
  133           *  built-in function \c type().
  134           *  @return One of the following strings: <tt>"nil"</tt>,
  135           *          <tt>"boolean"</tt>, <tt>"number"</tt>, <tt>"string"</tt>,
  136           *          <tt>"table"</tt>, <tt>"function"</tt>, <tt>"userdata"</tt>.
  137           */
  138          std::string typeName() const;
  139 
  140          /** Return the value as a number.
  141           *  @throw TypeMismatchError If the value is not a number (this is a
  142           *         strict check; no type conversion is performed).
  143           */
  144          lua_Number asNumber() const;
  145 
  146          /** Return the value as an integer.
  147           *  @throw TypeMismatchError If the value is not a number (this is a
  148           *         strict check; no type conversion is performed -- no other
  149           *         than the conversion from \c lua_Number to \c lua_Integer,
  150           *         that is).
  151           */
  152          lua_Integer asInteger() const;
  153 
  154          /** Return the value as a string.
  155           *  @throw TypeMismatchError If the value is not a string (this is a
  156           *         strict check; no type conversion is performed).
  157           */
  158          const std::string& asString() const;
  159 
  160          /** Return the value as a boolean.
  161           *  @throw TypeMismatchError If the value is not a boolean (this is a
  162           *         strict check; no type conversion is performed).
  163           */
  164          bool asBoolean() const;
  165 
  166          /** Returns the value as a table (\c LuaValueMap).
  167           *  @note Notice that the table is returned by value. You may strongly
  168           *        consider using the subscript operator (that returns a
  169           *        reference) for accessing the values stored in a table-typed
  170           *        \c LuaValue.
  171           *  @throw TypeMismatchError If the value is not a table (this is a
  172           *         strict check; no type conversion is performed).
  173           */
  174          LuaValueMap asTable() const;
  175 
  176          /** Return the value as a \c const Lua function.
  177           *  @throw TypeMismatchError If the value is not a Lua function.
  178           *         (this is a strict check; no type conversion is performed).
  179           */
  180          const LuaFunction& asFunction() const;
  181 
  182          /** Return the value as a \c const (full) user data.
  183           *  @throw TypeMismatchError If the value is not a (full) user data
  184           *         (this is a strict check; no type conversion is performed).
  185           */
  186          const LuaUserData& asUserData() const;
  187 
  188          /** Return the value as a (full) user data.
  189           *  @note Since this is returned as a non-\c const reference, the
  190           *        \c LuaUserData::getData() method can be used to get
  191           *        read/write access to the raw user data.
  192           *  @throw TypeMismatchError If the value is not a (full) user data
  193           *         (this is a strict check; no type conversion is performed).
  194           */
  195          LuaUserData& asUserData();
  196 
  197          /** Assuming that the value stores a C++ object exported to or
  198           *  instantiated in Lua, returns a pointer to the (\c const) C++
  199           *  object.
  200           */
  201          template<class T>
  202          T asObjectPtr() const
  203          {
  204             return static_cast<T>(
  205                static_cast<const Impl::CppObject*>(asUserData().getData())->ptr);
  206          }
  207 
  208          /** Assuming that the value stores a C++ object exported to or
  209           *  instantiated in Lua, returns a pointer to the C++ object.
  210           */
  211          template<class T>
  212          T asObjectPtr()
  213          {
  214             return static_cast<T>(
  215                static_cast<Impl::CppObject*>(asUserData().getData())->ptr);
  216          }
  217 
  218          /** "Less than" operator for <tt>LuaValue</tt>s.
  219           *  @return The order relationship is quite arbitrary for
  220           *          <tt>LuaValue</tt>s, but this has to be defined in order to
  221           *          \c LuaValueMap work nicely. Anyway, here are the rules used
  222           *          to determine who is less than who:
  223           *          - First, \c typeName() is called for both
  224           *            <tt>LuaValue</tt>s and they are compared with the usual
  225           *            "less than" operator for strings.
  226           *          - If both type names are equal, but something different
  227           *            than <tt>"nil"</tt> and <tt>"table"</tt>, then the values
  228           *            contained in the <tt>LuaValue</tt>s are compared using
  229           *            the "less than" operator for that type.
  230           *          - If both type names are <tt>"nil"</tt>, the function
  231           *            returns \c false.
  232           *          - If both type names are <tt>"table"</tt>, then the number
  233           *            of elements in each table are compared. The shorter table
  234           *            is "less than" the larger table.
  235           *          - If both tables have the same size, then each entry is
  236           *            recursively compared (that is, using the rules described
  237           *            here). For each entry, the key is compared first, than
  238           *            the value. This is done until finding something "less
  239           *            than" the other thing.
  240           *          - If no differences are found, \c false is obviously
  241           *            returned.
  242           */
  243          bool operator< (const LuaValue& rhs) const;
  244 
  245          /** "Greater than" operator for <tt>LuaValue</tt>s.
  246           *  @return The rules for determining who is greater than who are
  247           *          similar to the ones described in \c operator<.
  248           */
  249          bool operator> (const LuaValue& rhs) const;
  250 
  251          /** "Equal" operator for <tt>LuaValue</tt>s.
  252           *  @return \c true if <tt>*this</tt> and \c rhs have the same value.
  253           *          \c false otherwise.
  254           */
  255          bool operator== (const LuaValue& rhs) const;
  256 
  257          /** "Different" operator for <tt>LuaValue</tt>s.
  258           *  @return \c true if <tt>*this</tt> and \c rhs don't have the same
  259           *          value. \c false otherwise.
  260           */
  261          bool operator!= (const LuaValue& rhs) const
  262          { return !(*this == rhs); }
  263 
  264          /** Returns a reference to a field of this \c LuaValue (assuming it is
  265           *  a table). If there is no value associated with the key passed as
  266           *  parameter, inserts a new value (\c nil) and returns a reference to
  267           *  it.
  268           *  @throw TypeMismatchError If this \c LuaValue does not hold a table.
  269           */
  270          LuaValue& operator[] (const LuaValue& key);
  271 
  272          /** Returns a \c const reference to a field of this \c LuaValue
  273           *  (assuming it is a table). If there is no value associated with the
  274           *  key passed as parameter, returns \c Nil.
  275           *  @throw TypeMismatchError If this \c LuaValue does not hold a table.
  276           */
  277          const LuaValue& operator[] (const LuaValue& key) const;
  278 
  279       private:
  280 
  281          /** Destroys the object allocated at the \c data_ member, freeing its
  282           *  resources.
  283           */
  284          void destroyObjectAtData();
  285 
  286          /// This is used to allow the \c data_ member to store multiple types.
  287          union PossibleTypes
  288          {
  289                lua_Number typeNumber;
  290                std::string typeString;
  291                bool typeBool;
  292                LuaValueMap typeLuaValueMap;
  293                LuaFunction typeFunction;
  294                LuaUserData typeUserData;
  295 
  296                PossibleTypes() {}
  297                ~PossibleTypes() {}
  298                
  299                // introduced because of gcc8 memcpy warnings
  300                PossibleTypes& operator= (const PossibleTypes& rhs)
  301                 {
  302                     typeNumber = rhs.typeNumber;
  303                  //   typeString = rhs.typeString;
  304                     typeBool = rhs.typeBool;
  305                  //   typeLuaValueMap = rhs.typeLuaValueMap;
  306                  //   typeFunction = rhs.typeFunction;
  307                  //   typeUserData = rhs.typeUserData;
  308 
  309                     return *this;
  310                 }
  311                
  312          };
  313 
  314          /** This stores the actual data of this \c LuaValue.
  315           *  <p>Implementation details: The values are allocated here using
  316           *  placement new, with destructors explicitly called whenever
  317           *  necessary.
  318           */
  319          PossibleTypes data_;
  320 
  321          /** The actual type stored in this \c LuaValue. The values here are the
  322           *  type constants defined by Lua, like \c LUA_TNUMBER and \c LUA_TNIL.
  323           */
  324          int dataType_;
  325    };
  326 
  327 
  328 
  329    /// A constant with the value of \c nil.
  330    const LuaValue Nil;
  331 
  332    /// A constant that is an empty \c LuaValueMap.
  333    const LuaValueMap EmptyLuaValueMap;
  334 
  335    /// A constant with value of an empty table.
  336    const LuaValue EmptyTable (EmptyLuaValueMap);
  337 
  338 } // namespace Diluculum
  339 
  340 
  341 #endif // _DILUCULUM_LUA_VALUE_HPP_