"Fossies" - the Fresh Open Source Software Archive

Member "highlight-3.57-x64/src/core/Diluculum/LuaValue.cpp" (12 May 2020, 17396 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.cpp                                                                 *
    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 #include <cstring>
   28 #include <Diluculum/LuaValue.hpp>
   29 #include <Diluculum/LuaExceptions.hpp>
   30 
   31 
   32 namespace Diluculum
   33 {
   34    // - LuaValue::LuaValue -----------------------------------------------------
   35    LuaValue::LuaValue()
   36       : dataType_(LUA_TNIL)
   37    { }
   38 
   39 
   40    LuaValue::LuaValue (bool b)
   41       : dataType_(LUA_TBOOLEAN)
   42    {
   43       data_.typeBool = b;
   44    }
   45 
   46 
   47    LuaValue::LuaValue (float n)
   48       : dataType_(LUA_TNUMBER)
   49    {
   50       lua_Number num = static_cast<lua_Number>(n);
   51       data_.typeNumber = num;
   52    }
   53 
   54 
   55    LuaValue::LuaValue (double n)
   56       : dataType_(LUA_TNUMBER)
   57    {
   58       lua_Number num = static_cast<lua_Number>(n);
   59       data_.typeNumber = num;
   60    }
   61 
   62 
   63    LuaValue::LuaValue (long double n)
   64       : dataType_(LUA_TNUMBER)
   65    {
   66       lua_Number num = static_cast<lua_Number>(n);
   67       data_.typeNumber = num;
   68    }
   69 
   70 
   71    LuaValue::LuaValue (short n)
   72       : dataType_(LUA_TNUMBER)
   73    {
   74       lua_Number num = static_cast<lua_Number>(n);
   75       data_.typeNumber = num;
   76    }
   77 
   78 
   79    LuaValue::LuaValue (unsigned short n)
   80       : dataType_(LUA_TNUMBER)
   81    {
   82       lua_Number num = static_cast<lua_Number>(n);
   83       data_.typeNumber = num;
   84    }
   85 
   86 
   87    LuaValue::LuaValue (int n)
   88       : dataType_(LUA_TNUMBER)
   89    {
   90       lua_Number num = static_cast<lua_Number>(n);
   91       data_.typeNumber = num;
   92    }
   93 
   94 
   95    LuaValue::LuaValue (unsigned n)
   96       : dataType_(LUA_TNUMBER)
   97    {
   98       lua_Number num = static_cast<lua_Number>(n);
   99       data_.typeNumber = num;
  100    }
  101 
  102 
  103    LuaValue::LuaValue (long n)
  104       : dataType_(LUA_TNUMBER)
  105    {
  106       lua_Number num = static_cast<lua_Number>(n);
  107       data_.typeNumber = num;
  108    }
  109 
  110 
  111    LuaValue::LuaValue (unsigned long n)
  112       : dataType_(LUA_TNUMBER)
  113    {
  114       lua_Number num = static_cast<lua_Number>(n);
  115       data_.typeNumber = num;
  116    }
  117 
  118 
  119    LuaValue::LuaValue (const std::string& s)
  120       : dataType_(LUA_TSTRING)
  121    {
  122       new(&data_.typeString) std::string(s);
  123    }
  124 
  125 
  126    LuaValue::LuaValue (const char* s)
  127       : dataType_(LUA_TSTRING)
  128    {
  129       new(&data_.typeString) std::string(s);
  130    }
  131 
  132 
  133    LuaValue::LuaValue (const LuaValueMap& t)
  134       : dataType_(LUA_TTABLE)
  135    {
  136       new(&data_.typeLuaValueMap) LuaValueMap(t);
  137    }
  138 
  139 
  140    LuaValue::LuaValue (lua_CFunction f)
  141       : dataType_(LUA_TFUNCTION)
  142    {
  143       new(&data_.typeFunction) LuaFunction(f);
  144    }
  145 
  146 
  147    LuaValue::LuaValue (const LuaFunction& f)
  148       : dataType_(LUA_TFUNCTION)
  149    {
  150       new(&data_.typeFunction) LuaFunction(f);
  151    }
  152 
  153 
  154    LuaValue::LuaValue (const LuaUserData& ud)
  155       : dataType_(LUA_TUSERDATA)
  156    {
  157       new(&data_.typeUserData) LuaUserData(ud);
  158    }
  159 
  160 
  161    LuaValue::LuaValue (const LuaValueList& v)
  162       // Avoids possible memory corruption during destroyObjectAtData
  163       : dataType_(LUA_TNIL)
  164    {
  165       if (v.size() >= 1)
  166          *this = v[0];
  167       else
  168          *this = Nil;
  169    }
  170 
  171 
  172    LuaValue::LuaValue (const LuaValue& other)
  173       : dataType_ (other.dataType_)
  174    {
  175       switch (dataType_)
  176       {
  177          case LUA_TSTRING:
  178             new(&data_.typeString) std::string(other.asString());
  179             break;
  180 
  181          case LUA_TTABLE:
  182             new(&data_.typeLuaValueMap) LuaValueMap (other.asTable());
  183             break;
  184 
  185          case LUA_TUSERDATA:
  186             new(&data_.typeUserData) LuaUserData (other.asUserData());
  187             break;
  188 
  189          case LUA_TFUNCTION:
  190             new(&data_.typeFunction) LuaFunction (other.asFunction());
  191             break;
  192 
  193          default:
  194             // no constructor needed.
  195             //memcpy (&data_, &other.data_, sizeof(PossibleTypes));
  196             data_ = other.data_;
  197              break;
  198       }
  199    }
  200 
  201 
  202 
  203    // - LuaValue::operator= ----------------------------------------------------
  204    LuaValue& LuaValue::operator= (const LuaValue& rhs)
  205    {
  206       destroyObjectAtData();
  207 
  208       dataType_ = rhs.dataType_;
  209 
  210       switch (dataType_)
  211       {
  212          case LUA_TSTRING:
  213             new(&data_.typeString) std::string (rhs.asString());
  214             break;
  215 
  216          case LUA_TTABLE:
  217             new(&data_.typeLuaValueMap) LuaValueMap (rhs.asTable());
  218             break;
  219 
  220          case LUA_TUSERDATA:
  221             new(&data_.typeUserData) LuaUserData (rhs.asUserData());
  222             break;
  223 
  224          case LUA_TFUNCTION:
  225             new(&data_.typeFunction) LuaFunction (rhs.asFunction());
  226             break;
  227 
  228          default:
  229             // no constructor needed.
  230             //memcpy (&data_, &rhs.data_, sizeof(PossibleTypes));
  231             data_ = rhs.data_;
  232              break;
  233       }
  234 
  235       return *this;
  236    }
  237 
  238 
  239    const LuaValueList& LuaValue::operator= (const LuaValueList& rhs)
  240    {
  241       if (rhs.size() >= 1)
  242          *this = rhs[0];
  243       else
  244          *this = Nil;
  245 
  246       return rhs;
  247    }
  248 
  249 
  250 
  251    // - LuaValue::typeName -----------------------------------------------------
  252    std::string LuaValue::typeName() const
  253    {
  254       switch (dataType_)
  255       {
  256          case LUA_TNIL:
  257             return "nil";
  258 
  259          case LUA_TBOOLEAN:
  260             return "boolean";
  261 
  262          case LUA_TNUMBER:
  263             return "number";
  264 
  265          case LUA_TSTRING:
  266             return "string";
  267 
  268          case LUA_TTABLE:
  269             return "table";
  270 
  271          case LUA_TFUNCTION:
  272             return "function";
  273 
  274          case LUA_TUSERDATA:
  275             return "userdata";
  276 
  277          default: // can't happen
  278             assert (false
  279                     && "Invalid type found in a call to 'LuaValue::typeName()'.");
  280             return ""; // return something to make compilers happy.
  281       }
  282    }
  283 
  284 
  285 
  286    // - LuaValue::asNumber() ---------------------------------------------------
  287    lua_Number LuaValue::asNumber() const
  288    {
  289       if (dataType_ == LUA_TNUMBER)
  290       {
  291          return data_.typeNumber;
  292       }
  293       else
  294       {
  295          throw TypeMismatchError ("number", typeName());
  296       }
  297    }
  298 
  299 
  300 
  301    // - LuaValue::asInteger() --------------------------------------------------
  302    lua_Integer LuaValue::asInteger() const
  303    {
  304       if (dataType_ == LUA_TNUMBER)
  305       {
  306          return static_cast<lua_Integer>(data_.typeNumber);
  307       }
  308       else
  309       {
  310          throw TypeMismatchError ("number", typeName());
  311       }
  312    }
  313 
  314 
  315 
  316    // - LuaValue::asString -----------------------------------------------------
  317    const std::string& LuaValue::asString() const
  318    {
  319       if (dataType_ == LUA_TSTRING)
  320       {
  321          return data_.typeString;
  322       }
  323       else
  324       {
  325          throw TypeMismatchError ("string", typeName());
  326       }
  327    }
  328 
  329 
  330 
  331    // - LuaValue::asBoolean ----------------------------------------------------
  332    bool LuaValue::asBoolean() const
  333    {
  334       if (dataType_ == LUA_TBOOLEAN)
  335       {
  336          return data_.typeBool;
  337       }
  338       else
  339       {
  340          throw TypeMismatchError ("boolean", typeName());
  341       }
  342    }
  343 
  344 
  345 
  346    // - LuaValue::asTable ------------------------------------------------------
  347    LuaValueMap LuaValue::asTable() const
  348    {
  349       if (dataType_ == LUA_TTABLE)
  350       {
  351          return data_.typeLuaValueMap;
  352       }
  353       else
  354       {
  355          throw TypeMismatchError ("table", typeName());
  356       }
  357    }
  358 
  359 
  360 
  361    // - LuaValue::asFunction ---------------------------------------------------
  362    const LuaFunction& LuaValue::asFunction() const
  363    {
  364       if (dataType_ == LUA_TFUNCTION)
  365       {
  366          return data_.typeFunction;
  367       }
  368       else
  369       {
  370          throw TypeMismatchError ("function", typeName());
  371       }
  372    }
  373 
  374 
  375 
  376    // - LuaValue::asUserData ---------------------------------------------------
  377    const LuaUserData& LuaValue::asUserData() const
  378    {
  379       if (dataType_ == LUA_TUSERDATA)
  380       {
  381          return data_.typeUserData;
  382       }
  383       else
  384       {
  385          throw TypeMismatchError ("userdata", typeName());
  386       }
  387    }
  388 
  389    LuaUserData& LuaValue::asUserData()
  390    {
  391       if (dataType_ == LUA_TUSERDATA)
  392       {
  393          return data_.typeUserData;
  394       }
  395       else
  396       {
  397          throw TypeMismatchError ("userdata", typeName());
  398       }
  399    }
  400 
  401 
  402 
  403    // - LuaValue::operator< ----------------------------------------------------
  404    bool LuaValue::operator< (const LuaValue& rhs) const
  405    {
  406       std::string lhsTypeName = typeName();
  407       std::string rhsTypeName = rhs.typeName();
  408 
  409       if (lhsTypeName < rhsTypeName)
  410          return true;
  411       else if (lhsTypeName > rhsTypeName)
  412          return false;
  413       else // lhsTypeName == rhsTypeName
  414       {
  415          if (lhsTypeName == "nil")
  416             return false;
  417          else if (lhsTypeName == "boolean")
  418             return asBoolean() < rhs.asBoolean();
  419          else if (lhsTypeName == "number")
  420             return asNumber() < rhs.asNumber();
  421          else if (lhsTypeName == "string")
  422             return asString() < rhs.asString();
  423          else if (lhsTypeName == "function")
  424             return asFunction() < rhs.asFunction();
  425          else if (lhsTypeName == "userdata")
  426             return asUserData() < rhs.asUserData();
  427          else if (lhsTypeName == "table")
  428          {
  429             const LuaValueMap lhsMap = asTable();
  430             const LuaValueMap rhsMap = rhs.asTable();
  431 
  432             if (lhsMap.size() < rhsMap.size())
  433                return true;
  434             else if (lhsMap.size() > rhsMap.size())
  435                return false;
  436             else // lhsMap.size() == rhsMap.size()
  437             {
  438                typedef LuaValueMap::const_iterator iter_t;
  439 
  440                iter_t pLHS = lhsMap.begin();
  441                iter_t pRHS = rhsMap.begin();
  442                const iter_t end = lhsMap.end();
  443 
  444                while (pLHS != end)
  445                {
  446                   // check the key first
  447                   if (pLHS->first < pRHS->first)
  448                      return true;
  449                   else if (pLHS->first > pRHS->first)
  450                      return false;
  451 
  452                   // then check the value
  453                   if (pLHS->second < pRHS->second)
  454                      return true;
  455                   else if (pLHS->second > pRHS->second)
  456                      return false;
  457 
  458                   // make the iterators iterate
  459                   ++pRHS;
  460                   ++pLHS;
  461                }
  462                return false;
  463             }
  464          }
  465          else
  466          {
  467             assert (false && "Unsupported type found at a call "
  468                     "to 'LuaValue::operator<()'");
  469             return false; // make the compiler happy.
  470          }
  471       }
  472    }
  473 
  474 
  475 
  476    // - LuaValue::operator> ----------------------------------------------------
  477    bool LuaValue::operator> (const LuaValue& rhs) const
  478    {
  479       std::string lhsTypeName = typeName();
  480       std::string rhsTypeName = rhs.typeName();
  481 
  482       if (lhsTypeName > rhsTypeName)
  483          return true;
  484       else if (lhsTypeName < rhsTypeName)
  485          return false;
  486       else // lhsTypeName == rhsTypeName
  487       {
  488          if (lhsTypeName == "nil")
  489             return false;
  490          else if (lhsTypeName == "boolean")
  491             return asBoolean() > rhs.asBoolean();
  492          else if (lhsTypeName == "number")
  493             return asNumber() > rhs.asNumber();
  494          else if (lhsTypeName == "string")
  495             return asString() > rhs.asString();
  496          else if (lhsTypeName == "function")
  497             return asFunction() > rhs.asFunction();
  498          else if (lhsTypeName == "userdata")
  499             return asUserData() > rhs.asUserData();
  500          else if (lhsTypeName == "table")
  501          {
  502             const LuaValueMap lhsMap = asTable();
  503             const LuaValueMap rhsMap = rhs.asTable();
  504 
  505             if (lhsMap.size() > rhsMap.size())
  506                return true;
  507             else if (lhsMap.size() < rhsMap.size())
  508                return false;
  509             else // lhsMap.size() == rhsMap.size()
  510             {
  511                typedef LuaValueMap::const_iterator iter_t;
  512 
  513                iter_t pLHS = lhsMap.begin();
  514                iter_t pRHS = rhsMap.begin();
  515                const iter_t end = lhsMap.end();
  516 
  517                while (pLHS != end)
  518                {
  519                   // check the key first
  520                   if (pLHS->first > pRHS->first)
  521                      return true;
  522                   else if (pLHS->first < pRHS->first)
  523                      return false;
  524 
  525                   // then check the value
  526                   if (pLHS->second > pRHS->second)
  527                      return true;
  528                   else if (pLHS->second < pRHS->second)
  529                      return false;
  530 
  531                   // make the iterators iterate
  532                   ++pRHS;
  533                   ++pLHS;
  534                }
  535                return false;
  536             }
  537          }
  538          else
  539          {
  540             assert (false && "Unsupported type found at a call "
  541                     "to 'LuaValue::operator>()'");
  542             return false; // make the compiler happy.
  543          }
  544       }
  545    }
  546 
  547 
  548 
  549    // - LuaValue::operator== ---------------------------------------------------
  550    bool LuaValue::operator== (const LuaValue& rhs) const
  551    {
  552       std::string lhsTypeName = typeName();
  553       std::string rhsTypeName = rhs.typeName();
  554 
  555       if (typeName() != rhs.typeName())
  556          return false;
  557       else switch (type())
  558       {
  559          case LUA_TNIL:
  560             return true;
  561 
  562          case LUA_TBOOLEAN:
  563             return asBoolean() == rhs.asBoolean();
  564 
  565          case LUA_TNUMBER:
  566             return asNumber() == rhs.asNumber();
  567 
  568          case LUA_TSTRING:
  569             return asString() == rhs.asString();
  570 
  571          case LUA_TTABLE:
  572             return asTable() == rhs.asTable();
  573 
  574          case LUA_TFUNCTION:
  575             return asFunction() == rhs.asFunction();
  576 
  577          case LUA_TUSERDATA:
  578             return asUserData() == rhs.asUserData();
  579 
  580          default:
  581          {
  582             assert(
  583                false
  584                && "Invalid type found in a call to 'LuaValue::operator==()'.");
  585             return 0; // make compilers happy
  586          }
  587       }
  588    }
  589 
  590 
  591 
  592    // - LuaValue::operator[] ---------------------------------------------------
  593    LuaValue& LuaValue::operator[] (const LuaValue& key)
  594    {
  595       if (type() != LUA_TTABLE)
  596          throw TypeMismatchError ("table", typeName());
  597 
  598       LuaValueMap* pTable = &data_.typeLuaValueMap;
  599 
  600       return (*pTable)[key];
  601    }
  602 
  603 
  604 
  605    const LuaValue& LuaValue::operator[] (const LuaValue& key) const
  606    {
  607       if (type() != LUA_TTABLE)
  608          throw TypeMismatchError ("table", typeName());
  609 
  610       const LuaValueMap* pTable = &data_.typeLuaValueMap;
  611 
  612       LuaValueMap::const_iterator it = (*pTable).find(key);
  613 
  614       if (it == (*pTable).end())
  615          return Nil;
  616 
  617       return it->second;
  618    }
  619 
  620 
  621 
  622    // - LuaValue::destroyObjectAtData ------------------------------------------
  623    void LuaValue::destroyObjectAtData()
  624    {
  625       switch (dataType_)
  626       {
  627          case LUA_TSTRING:
  628          {
  629             std::string* ps = &data_.typeString;
  630             ps->~basic_string();
  631             break;
  632          }
  633 
  634          case LUA_TTABLE:
  635          {
  636             LuaValueMap* pm = &data_.typeLuaValueMap;
  637             pm->~LuaValueMap();
  638             break;
  639          }
  640 
  641          case LUA_TUSERDATA:
  642          {
  643             LuaUserData* pd = &data_.typeUserData;
  644             pd->~LuaUserData();
  645             break;
  646          }
  647 
  648          case LUA_TFUNCTION:
  649          {
  650             LuaFunction* pf = &data_.typeFunction;
  651             pf->~LuaFunction();
  652             break;
  653          }
  654 
  655          default:
  656             // no destructor needed.
  657             break;
  658       }
  659    }
  660 
  661 } // namespace Diluculum