Skip to content
Snippets Groups Projects
tokenI.H 19.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*---------------------------------------------------------------------------*\
      =========                 |
      \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
       \\    /   O peration     |
    
    OpenFOAM bot's avatar
    OpenFOAM bot committed
        \\  /    A nd           | www.openfoam.com
    
         \\/     M anipulation  |
    -------------------------------------------------------------------------------
    
    OpenFOAM bot's avatar
    OpenFOAM bot committed
        Copyright (C) 2011-2016 OpenFOAM Foundation
    
        Copyright (C) 2017-2021 OpenCFD Ltd.
    
    -------------------------------------------------------------------------------
    License
        This file is part of OpenFOAM.
    
    
        OpenFOAM is free software: you can redistribute it and/or modify it
        under the terms of the GNU General Public License as published by
        the Free Software Foundation, either version 3 of the License, or
        (at your option) any later version.
    
    
        OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
        ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
        FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        for more details.
    
        You should have received a copy of the GNU General Public License
    
        along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
    
    
    \*---------------------------------------------------------------------------*/
    
    
    #include <algorithm>
    
    
    // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
    
    
    inline Foam::token Foam::token::boolean(bool on) noexcept
    
    {
        token tok;
        tok.type_ = tokenType::BOOL;
        tok.data_.labelVal = on;
    
        return tok;
    }
    
    
    
    inline Foam::token Foam::token::flag(int bitmask) noexcept
    
    {
        token tok;
        tok.type_ = tokenType::FLAG;
        tok.data_.flagVal = bitmask;
    
        return tok;
    }
    
    
    
    inline bool Foam::token::isseparator(int c) noexcept
    
        // NOTE: keep synchronized with ISstream::read(token&)
    
    
        switch (c)
        {
            case token::END_STATEMENT :
            case token::BEGIN_LIST :
            case token::END_LIST :
            case token::BEGIN_SQR :
            case token::END_SQR :
            case token::BEGIN_BLOCK :
            case token::END_BLOCK :
            case token::COLON :
            case token::COMMA :
            case token::ASSIGN :
    
            case token::PLUS :
            // Excluded token::MINUS since it could start a number
    
            case token::MULTIPLY :
            case token::DIVIDE :
            {
                return true;
            }
    
            default:
                break;
        }
    
        return false;
    }
    
    
    
    // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
    
    
    inline void Foam::token::setUndefined() noexcept
    
    {
        type_ = tokenType::UNDEFINED;
        data_.int64Val = 0; // bit-wise zero for union content
        // leave lineNumber untouched - may still be needed
    }
    
    
    
    // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
    
    
    inline constexpr Foam::token::token() noexcept
    
        data_(), // bit-wise zero for union content
    
        type_(tokenType::UNDEFINED),
    
    inline Foam::token::token(const token& tok)
    
        data_(tok.data_), // bit-wise copy of union content
        type_(tok.type_),
    
        // Fundamental: values already handled by bit-wise copy
        // Pointer: duplicate content or increase refCount
    
    
            case tokenType::WORD:
    
            case tokenType::DIRECTIVE:
    
            {
                data_.wordPtr = new word(*tok.data_.wordPtr);
                break;
            }
    
            case tokenType::STRING:
    
            case tokenType::VARIABLE:
    
            case tokenType::VERBATIM:
    
            {
                data_.stringPtr = new string(*tok.data_.stringPtr);
                break;
            }
    
            case tokenType::COMPOUND:
    
            {
                // Identical pointers, but increase the refCount
                data_.compoundPtr = tok.data_.compoundPtr;
                data_.compoundPtr->refCount::operator++();
                break;
            }
    
    inline Foam::token::token(token&& tok) noexcept
    
    :
        data_(tok.data_), // bit-wise copy of union content
        type_(tok.type_),
    
    {
        tok.setUndefined(); // zero the union content without any checking
    
    inline Foam::token::token(punctuationToken p, label lineNum) noexcept
    
        type_(tokenType::PUNCTUATION),
    
    {
        data_.punctuationVal = p;
    }
    
    inline Foam::token::token(const label val, label lineNum) noexcept
    
        data_(),
        type_(tokenType::LABEL),
    
    {
        data_.labelVal = val;
    }
    
    inline Foam::token::token(const floatScalar val, label lineNum) noexcept
    
        type_(tokenType::FLOAT),
    
    {
        data_.floatVal = val;
    }
    
    inline Foam::token::token(const doubleScalar val, label lineNum) noexcept
    
        type_(tokenType::DOUBLE),
    
    {
        data_.doubleVal = val;
    }
    
    inline Foam::token::token(const word& w, label lineNum)
    
        data_(),
        type_(tokenType::WORD),
    
    {
        data_.wordPtr = new word(w);
    }
    
    inline Foam::token::token(const string& str, label lineNum)
    
        data_(),
        type_(tokenType::STRING),
    
    {
        data_.stringPtr = new string(str);
    }
    
    inline Foam::token::token(word&& w, label lineNum)
    
    :
        data_(),
        type_(tokenType::WORD),
    
    {
        data_.wordPtr = new word(std::move(w));
    }
    
    
    
    inline Foam::token::token(string&& str, label lineNum)
    
    :
        data_(),
        type_(tokenType::STRING),
    
    {
        data_.stringPtr = new string(std::move(str));
    }
    
    
    
    inline Foam::token::token(token::compound* ptr, label lineNum)
    :
        data_(),
        type_(tokenType::COMPOUND),
        line_(lineNum)
    {
        data_.compoundPtr = ptr;
    }
    
    
    
    // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
    
    }
    
    
    // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
    
    
    inline void Foam::token::reset()
    {
        switch (type_)
        {
            case tokenType::WORD:
    
            case tokenType::DIRECTIVE:
    
            {
                delete data_.wordPtr;
                break;
            }
    
            case tokenType::STRING:
    
            case tokenType::VARIABLE:
    
            case tokenType::VERBATIM:
    
            {
                delete data_.stringPtr;
                break;
            }
    
            case tokenType::COMPOUND:
            {
                if (data_.compoundPtr->unique())
                {
                    delete data_.compoundPtr;
                }
                else
                {
                    data_.compoundPtr->refCount::operator--();
                }
                break;
            }
    
            default:
                break;
        }
    
        setUndefined();
    }
    
    
    
    inline void Foam::token::swap(token& tok)
    
        if (this == &tok)
        {
            return;  // Self-swap is a no-op
        }
    
    
        std::swap(data_, tok.data_);
        std::swap(type_, tok.type_);
    
    inline Foam::token::tokenType Foam::token::type() const noexcept
    
    inline bool Foam::token::setType(token::tokenType tokType) noexcept
    
        if (type_ == tokType)
    
        {
            // No change required
            return true;
        }
    
    
            case tokenType::BOOL:
            case tokenType::LABEL:
            {
                switch (type_)
                {
                    case tokenType::BOOL:
                    case tokenType::LABEL:
    
                        type_ = tokType;
                        return true;
                        break;
    
                    default:
                        break;
                }
            }
            break;
    
            case tokenType::WORD:
            case tokenType::DIRECTIVE:
            {
                switch (type_)
                {
                    case tokenType::WORD:
                    case tokenType::DIRECTIVE:
                        type_ = tokType;
    
                        return true;
                        break;
    
                    default:
                        break;
                }
            }
            break;
    
    
            case tokenType::STRING:
    
            case tokenType::VARIABLE:
    
            case tokenType::VERBATIM:
    
            {
                switch (type_)
                {
                    // could also go from WORD to STRING etc - to be decided
                    case tokenType::STRING:
    
                    case tokenType::VARIABLE:
    
                    case tokenType::VERBATIM:
    
                        return true;
                        break;
    
                    default:
                        break;
                }
            }
    
    inline Foam::label Foam::token::lineNumber() const noexcept
    
    inline Foam::label Foam::token::lineNumber(const label lineNum) noexcept
    
        label old(line_);
        line_ = lineNum;
        return old;
    
    inline bool Foam::token::good() const noexcept
    
        return (type_ != tokenType::UNDEFINED && type_ != tokenType::ERROR);
    
    inline bool Foam::token::undefined() const noexcept
    
        return (type_ == tokenType::UNDEFINED);
    
    inline bool Foam::token::error() const noexcept
    
        return (type_ == tokenType::ERROR);
    
    inline bool Foam::token::isBool() const noexcept
    
    {
        return (type_ == tokenType::BOOL);
    }
    
    
    inline bool Foam::token::boolToken() const
    {
    
        if (type_ == tokenType::BOOL || type_ == tokenType::LABEL)
    
        {
            return data_.labelVal;
        }
    
        parseError("bool");
        return false;
    }
    
    
    
    inline bool Foam::token::isFlag() const noexcept
    
        return (type_ == tokenType::FLAG);
    
    inline int Foam::token::flagToken() const
    
        if (type_ == tokenType::FLAG)
    
            return data_.flagVal;
    
        parseError("flag bitmask");
        return NO_FLAG;
    
    inline bool Foam::token::isPunctuation() const noexcept
    
        return (type_ == tokenType::PUNCTUATION);
    }
    
    inline bool Foam::token::isPunctuation(const punctuationToken p) const noexcept
    
        return
        (
            type_ == tokenType::PUNCTUATION
         && data_.punctuationVal == p
        );
    
    inline bool Foam::token::isSeparator() const noexcept
    
            type_ == tokenType::PUNCTUATION
         && isseparator(data_.punctuationVal)
    
    inline Foam::token::punctuationToken Foam::token::pToken() const
    {
        if (type_ == tokenType::PUNCTUATION)
        {
            return data_.punctuationVal;
        }
    
        parseError("punctuation character");
        return punctuationToken::NULL_TOKEN;
    }
    
    
    
    inline bool Foam::token::isLabel() const noexcept
    
        return (type_ == tokenType::LABEL);
    
    inline bool Foam::token::isLabel(const label val) const noexcept
    {
        return
        (
            type_ == tokenType::LABEL
         && data_.labelVal == val
        );
    }
    
    
    
    inline Foam::label Foam::token::labelToken() const
    
        if (type_ == tokenType::LABEL)
    
            return data_.labelVal;
    
        parseError("label");
    
    inline bool Foam::token::isFloat() const noexcept
    
        return (type_ == tokenType::FLOAT);
    
    inline Foam::floatScalar Foam::token::floatToken() const
    
        if (type_ == tokenType::FLOAT)
    
            return data_.floatVal;
    
        parseError("float");
        return 0;
    
    inline bool Foam::token::isDouble() const noexcept
    
        return (type_ == tokenType::DOUBLE);
    
    inline Foam::doubleScalar Foam::token::doubleToken() const
    
        if (type_ == tokenType::DOUBLE)
    
            return data_.doubleVal;
    
        parseError("double");
        return 0;
    
    inline bool Foam::token::isScalar() const noexcept
    
            type_ == tokenType::FLOAT
         || type_ == tokenType::DOUBLE
    
    inline Foam::scalar Foam::token::scalarToken() const
    
        if (type_ == tokenType::FLOAT)
    
            return data_.floatVal;
    
        else if (type_ == tokenType::DOUBLE)
    
            return data_.doubleVal;
    
        parseError("scalar");
        return 0;
    
    inline bool Foam::token::isNumber() const noexcept
    
        return (type_ == tokenType::LABEL || isScalar());
    
    inline Foam::scalar Foam::token::number() const
    
        if (isLabel())
    
            return labelToken();
    
        if (isScalar())
    
    
        parseError("number (label or scalar)");
    
    inline bool Foam::token::isWord() const noexcept
    
        return
        (
            type_ == tokenType::WORD
         || type_ == tokenType::DIRECTIVE
        );
    }
    
    
    
    inline bool Foam::token::isWord(const std::string& s) const
    {
        return (isWord() && s == *data_.wordPtr);
    }
    
    
    
    inline bool Foam::token::isDirective() const noexcept
    
    {
        return (type_ == tokenType::DIRECTIVE);
    
    
    inline const Foam::word& Foam::token::wordToken() const
    
        if
        (
            type_ == tokenType::WORD
         || type_ == tokenType::DIRECTIVE
        )
    
            return *data_.wordPtr;
    
        parseError("word");
    
    inline bool Foam::token::isQuotedString() const noexcept
    {
        return (type_ == tokenType::STRING);
    }
    
    
    
    inline bool Foam::token::isString() const noexcept
    
    {
        return
        (
            type_ == tokenType::STRING
    
         || type_ == tokenType::EXPRESSION
    
         || type_ == tokenType::VARIABLE
    
         || type_ == tokenType::VERBATIM
    
    inline bool Foam::token::isExpression() const noexcept
    {
        return (type_ == tokenType::EXPRESSION);
    }
    
    
    
    inline bool Foam::token::isVariable() const noexcept
    
    {
        return (type_ == tokenType::VARIABLE);
    }
    
    
    
    inline bool Foam::token::isVerbatim() const noexcept
    
        return (type_ == tokenType::VERBATIM);
    
    inline bool Foam::token::isStringType() const noexcept
    
    {
        return (isWord() || isString());
    }
    
    
    
    inline const Foam::string& Foam::token::stringToken() const
    {
        if
        (
            type_ == tokenType::STRING
    
         || type_ == tokenType::EXPRESSION
    
         || type_ == tokenType::VARIABLE
    
         || type_ == tokenType::VERBATIM
    
            return *data_.stringPtr;
    
        else if
        (
            type_ == tokenType::WORD
         || type_ == tokenType::DIRECTIVE
        )
    
            // Foam::word derives from Foam::string, no need to cast.
            return *data_.wordPtr;
    
        parseError("string");
    
        return string::null;
    
    inline bool Foam::token::isCompound() const noexcept
    
        return (type_ == tokenType::COMPOUND);
    
    
    inline const Foam::token::compound& Foam::token::compoundToken() const
    
        if (type_ == tokenType::COMPOUND)
        {
            return *data_.compoundPtr;
        }
    
        parseError("compound");
        return *data_.compoundPtr;  // This is questionable.
    
        type_ = tokenType::ERROR;
    
    }
    
    
    // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
    
    
    inline void Foam::token::operator=(const token& tok)
    
        if (this == &tok)
        {
            return;  // Self-assignment is a no-op
        }
    
    
        type_ = tok.type_;
        data_ = tok.data_;  // bit-wise copy of union content
    
        // Fundamental: values already handled by bit-wise copy
        // Pointer: duplicate content or increase refCount
    
            case tokenType::WORD:
    
            case tokenType::DIRECTIVE:
    
            {
                data_.wordPtr = new word(*tok.data_.wordPtr);
            }
    
            case tokenType::STRING:
    
            case tokenType::VARIABLE:
    
            case tokenType::VERBATIM:
    
            {
                data_.stringPtr = new string(*tok.data_.stringPtr);
            }
    
            case tokenType::COMPOUND:
    
            {
                // Identical pointers, but increase the refCount
                data_.compoundPtr = tok.data_.compoundPtr;
                data_.compoundPtr->refCount::operator++();
            }
    
    inline void Foam::token::operator=(token&& tok)
    {
    
        if (this == &tok)
        {
            return;  // Self-assignment is a no-op
        }
    
    
    inline void Foam::token::operator=(const punctuationToken p)
    
        type_ = tokenType::PUNCTUATION;
    
        data_.punctuationVal = p;
    
    
    inline void Foam::token::operator=(const label val)
    
        type_ = tokenType::LABEL;
        data_.labelVal = val;
    
    
    inline void Foam::token::operator=(const floatScalar val)
    
        type_ = tokenType::FLOAT;
    
        data_.floatVal = val;
    
    
    inline void Foam::token::operator=(const doubleScalar val)
    {
    
        type_ = tokenType::DOUBLE;
    
        data_.doubleVal = val;
    }
    
    
    inline void Foam::token::operator=(const word& w)
    
        type_ = tokenType::WORD;
        data_.wordPtr = new word(w);
    
    
    inline void Foam::token::operator=(const string& str)
    
        type_ = tokenType::STRING;
        data_.stringPtr = new string(str);
    
    
    inline void Foam::token::operator=(word&& w)
    
        type_ = tokenType::WORD;
    
        data_.wordPtr = new word(std::move(w));
    
    
    inline void Foam::token::operator=(string&& s)
    
        type_ = tokenType::STRING;
    
        data_.stringPtr = new string(std::move(s));
    
    inline void Foam::token::operator=(Foam::token::compound* ptr)
    {
        reset();
        type_ = tokenType::COMPOUND;
        data_.compoundPtr = ptr;
    }
    
    
    inline void Foam::token::operator=(autoPtr<token::compound>&& ptr)
    
        type_ = tokenType::COMPOUND;
    
    inline bool Foam::token::operator==(const token& tok) const
    
        if (type_ != tok.type_)
    
            case tokenType::UNDEFINED:
    
            case tokenType::BOOL:
                return data_.labelVal == tok.data_.labelVal;
    
    
            case tokenType::FLAG:
                return data_.flagVal == tok.data_.flagVal;
    
    
            case tokenType::PUNCTUATION:
    
                return data_.punctuationVal == tok.data_.punctuationVal;
    
            case tokenType::LABEL:
    
                return data_.labelVal == tok.data_.labelVal;
    
            case tokenType::FLOAT:
    
                return equal(data_.floatVal, tok.data_.floatVal);
    
            case tokenType::DOUBLE:
    
                return equal(data_.doubleVal, tok.data_.doubleVal);
    
            case tokenType::WORD:
    
            case tokenType::DIRECTIVE:
    
                return *data_.wordPtr == *tok.data_.wordPtr;
    
            case tokenType::STRING:
    
            case tokenType::VARIABLE:
    
            case tokenType::VERBATIM:
    
                return *data_.stringPtr == *tok.data_.stringPtr;
    
            case tokenType::COMPOUND:
    
                return data_.compoundPtr == tok.data_.compoundPtr;
    
            case tokenType::ERROR:
    
    inline bool Foam::token::operator==(const punctuationToken p) const noexcept
    
        return isPunctuation(p);
    
    inline bool Foam::token::operator==(const std::string& s) const
    
          ? s == *data_.wordPtr
          : isString() && s == *data_.stringPtr
    
    inline bool Foam::token::operator==(const label val) const noexcept
    
    inline bool Foam::token::operator==(const floatScalar val) const noexcept
    
            type_ == tokenType::FLOAT
    
         && equal(data_.floatVal, val)
    
    inline bool Foam::token::operator==(const doubleScalar val) const noexcept
    
            type_ == tokenType::DOUBLE
    
         && equal(data_.doubleVal, val)
    
    inline bool Foam::token::operator!=(const token& tok) const
    
        return !operator==(tok);
    
    inline bool Foam::token::operator!=(const punctuationToken p) const noexcept
    
        return !isPunctuation(p);
    
    inline bool Foam::token::operator!=(const label val) const noexcept
    
        return !operator==(val);
    
    inline bool Foam::token::operator!=(const floatScalar val) const noexcept
    
        return !operator==(val);