/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
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 .
Class
Foam::token
Description
A token holds an item read from Istream.
SourceFiles
tokenI.H
token.C
tokenIO.C
\*---------------------------------------------------------------------------*/
#ifndef token_H
#define token_H
#include "label.H"
#include "uLabel.H"
#include "scalar.H"
#include "word.H"
#include "InfoProxy.H"
#include "refCount.H"
#include "typeInfo.H"
#define NoHashTableC
#include "runTimeSelectionTables.H"
#include
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
class token;
Ostream& operator<<(Ostream& os, const token& tok);
/*---------------------------------------------------------------------------*\
Class token Declaration
\*---------------------------------------------------------------------------*/
class token
{
public:
//- Enumeration defining the types of token.
// Since these values are also used to tag content in Pstream,
// the maximum number of types is limited to 30.
enum tokenType
{
UNDEFINED = 0, //!< An undefined token-type
// Fundamental types
FLAG, //!< stream flag (1-byte bitmask)
PUNCTUATION, //!< single character punctuation
BOOL, //!< boolean type
LABEL, //!< label (integer) type
FLOAT, //!< float (single-precision) type
DOUBLE, //!< double (double-precision) type
// Pointer types
WORD, //!< A Foam::word
STRING, //!< A string (usually double-quoted)
DIRECTIVE, //!< A dictionary \c \#directive (word variant)
VARIABLE, //!< A dictionary \c \$variable (string variant)
VERBATIM, //!< Verbatim string content
COMPOUND, //!< Compound type such as \c List\ etc.
ERROR, //!< A token error encountered
// Aliases
FLOAT_SCALAR = FLOAT,
DOUBLE_SCALAR = DOUBLE,
VERBATIMSTRING = VERBATIM
};
//- Stream or output control flags (1-byte width)
enum flagType
{
NO_FLAG = 0, //!< No flags
ASCII = 1, //!< ASCII-mode stream
BINARY = 2 //!< BINARY-mode stream
};
//- Standard punctuation tokens (a character)
enum punctuationToken : char
{
NULL_TOKEN = '\0', //!< Nul character
TAB = '\t', //!< Tab [isspace]
NL = '\n', //!< Newline [isspace]
SPACE = ' ', //!< Space [isspace]
COLON = ':', //!< Colon [#isseparator]
SEMICOLON = ';', //!< Semicolon [#isseparator]
COMMA = ',', //!< Comma [#isseparator]
HASH = '#', //!< Hash - directive or verbatim string
DOLLAR = '$', //!< Dollar - start variable
QUESTION = '?', //!< Question mark (eg, ternary)
ATSYM = '@', //!< The 'at' symbol
SQUOTE = '\'', //!< Single quote
DQUOTE = '"', //!< Double quote
ASSIGN = '=', //!< Assignment/equals [#isseparator]
ADD = '+', //!< Addition [#isseparator]
SUBTRACT = '-', //!< Subtract or start of negative number
MULTIPLY = '*', //!< Multiply [#isseparator]
DIVIDE = '/', //!< Divide [#isseparator]
LPAREN = '(', //!< Left parenthesis [#isseparator]
RPAREN = ')', //!< Right parenthesis [#isseparator]
LSQUARE = '[', //!< Left square bracket [#isseparator]
RSQUARE = ']', //!< Right square bracket [#isseparator]
LBRACE = '{', //!< Left brace [#isseparator]
RBRACE = '}', //!< Right brace [#isseparator]
// With semantically meaning
END_STATEMENT = SEMICOLON, //!< End entry [#isseparator]
BEGIN_LIST = LPAREN, //!< Begin list [#isseparator]
END_LIST = RPAREN, //!< End list [#isseparator]
BEGIN_SQR = LSQUARE, //!< Begin dimensions [#isseparator]
END_SQR = RSQUARE, //!< End dimensions [#isseparator]
BEGIN_BLOCK = LBRACE, //!< Begin block [#isseparator]
END_BLOCK = RBRACE, //!< End block [#isseparator]
BEGIN_STRING = DQUOTE, //!< Begin string with double quote
END_STRING = DQUOTE //!< End string with double quote
};
//- Abstract base class for complex tokens
class compound
:
public refCount
{
//- Has compound token already been transferred
bool moved_;
//- No copy construct
compound(const compound&) = delete;
//- No copy assignment
compound& operator=(const compound&) = delete;
public:
//- Declare type-name, virtual type (with debug switch)
TypeName("compound");
//- Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
compound,
Istream,
(Istream& is),
(is)
);
// Constructors
//- Default construct
constexpr compound() noexcept
:
moved_(false)
{}
//- Construct compound from Istream
static autoPtr New(const word& type, Istream& is);
//- Destructor
virtual ~compound() noexcept = default;
// Member Functions
//- Test if name is a known (registered) compound type
static bool isCompound(const word& name);
//- Get compound transferred status
bool moved() const noexcept
{
return moved_;
}
//- Set compound transferred status
void moved(bool b) noexcept
{
moved_ = b;
}
//- The size of the underlying content
virtual label size() const = 0;
//- Redirect write to underlying content
virtual void write(Ostream& os) const = 0;
// Operators
//- Output operator
friend Ostream& operator<<(Ostream& os, const compound& ct);
};
//- A templated class for holding compound tokens
template
class Compound
:
public token::compound,
public T
{
public:
//- Declare type-name, virtual type (with debug switch)
TypeName("Compound");
// Constructors
//- Copy construct
explicit Compound(const T& val)
:
T(val)
{}
//- Move construct
explicit Compound(T&& val)
:
T(std::move(val))
{}
//- Read construct from Istream
explicit Compound(Istream& is)
:
T(is)
{}
// Member Functions
//- The size of the underlying content
virtual label size() const
{
return T::size();
}
//- Redirect write to underlying content
virtual void write(Ostream& os) const
{
operator<<(os, static_cast(*this));
}
};
//- An undefined token
static const token undefinedToken;
private:
//- A %union of token types
union content
{
// Fundamental values. Largest first for any {} initialization.
int64_t int64Val;
int32_t int32Val;
int flagVal; // bitmask - stored as int, not enum
punctuationToken punctuationVal;
label labelVal;
floatScalar floatVal;
doubleScalar doubleVal;
// Pointers
word* wordPtr;
string* stringPtr;
mutable compound* compoundPtr;
};
// Private Data
//- The data content (as a union).
// For memory alignment this should appear as the first member.
content data_;
//- The token type
tokenType type_;
//- Line number in the file the token was read from
label line_;
// Private Member Functions
//- Set as UNDEFINED and zero the union content without any checking
inline void setUndefined() noexcept;
// Parse error, expected 'expected', found ...
void parseError(const char* expected) const;
public:
// Static Data Members
//- The type name is "token"
static constexpr const char* const typeName = "token";
// Constructors
//- Default construct, initialized to an UNDEFINED token.
inline constexpr token() noexcept;
//- Copy construct
inline token(const token& t);
//- Move construct. The original token is left as UNDEFINED.
inline token(token&& t) noexcept;
//- Construct punctuation character token
inline explicit token(punctuationToken p, label lineNum=0) noexcept;
//- Construct label token
inline explicit token(const label val, label lineNum=0) noexcept;
//- Construct float token
inline explicit token(const floatScalar val, label lineNum=0) noexcept;
//- Construct double token
inline explicit token(const doubleScalar val, label lineNum=0) noexcept;
//- Copy construct word token
inline explicit token(const word& w, label lineNum=0);
//- Copy construct string token
inline explicit token(const string& str, label lineNum=0);
//- Move construct word token
inline explicit token(word&& w, label lineNum=0);
//- Move construct string token
inline explicit token(string&& str, label lineNum=0);
//- Construct from a compound pointer, taking ownership
inline explicit token(token::compound* ptr, label lineNum=0);
//- Construct from Istream
explicit token(Istream& is);
//- Destructor
inline ~token();
// Static Functions
//- Create a bool token.
inline static token boolean(bool on) noexcept;
//- Create a token with stream flags, no sanity check
//
// \param bitmask the flags to set
inline static token flag(int bitmask) noexcept;
//- True if the character is a punctuation separator (eg, in ISstream).
// Since it could also start a number, SUBTRACT is not included as
// a separator.
//
// \param c the character to test, passed as int for consistency with
// isdigit, isspace etc.
inline static bool isseparator(int c) noexcept;
// Member Functions
// Status
//- Return the name of the token type
word name() const;
//- Return the token type
inline tokenType type() const noexcept;
//- Change the token type, for similar types.
// This can be used to change between string-like variants
// (eg, STRING, VARIABLE, etc)
// To change types entirely (eg, STRING to DOUBLE),
// use the corresponding assignment operator.
//
// \return true if the change was successful or no change was required
inline bool setType(const tokenType tokType) noexcept;
//- The line number for the token
inline label lineNumber() const noexcept;
//- Change token line number, return old value
inline label lineNumber(const label lineNum) noexcept;
//- True if token is not UNDEFINED or ERROR
inline bool good() const noexcept;
//- Token is UNDEFINED
inline bool undefined() const noexcept;
//- Token is ERROR
inline bool error() const noexcept;
//- Token is BOOL
inline bool isBool() const noexcept;
//- Token is FLAG
inline bool isFlag() const noexcept;
//- Token is PUNCTUATION
inline bool isPunctuation() const noexcept;
//- True if token is PUNCTUATION and equal to parameter
inline bool isPunctuation(const punctuationToken p) const noexcept;
//- Token is PUNCTUATION and isseparator
inline bool isSeparator() const noexcept;
//- Token is LABEL
inline bool isLabel() const noexcept;
//- True if token is LABEL and equal to parameter
inline bool isLabel(const label val) const noexcept;
//- Token is FLOAT
inline bool isFloat() const noexcept;
//- Token is DOUBLE
inline bool isDouble() const noexcept;
//- Token is FLOAT or DOUBLE
inline bool isScalar() const noexcept;
//- Token is LABEL, FLOAT or DOUBLE
inline bool isNumber() const noexcept;
//- Token is WORD or DIRECTIVE word
inline bool isWord() const noexcept;
//- Token is WORD or DIRECTIVE word and equal to parameter
inline bool isWord(const std::string& s) const;
//- Token is DIRECTIVE (word variant)
inline bool isDirective() const noexcept;
//- Token is (quoted) STRING (string variant)
inline bool isQuotedString() const noexcept;
//- Token is STRING, VARIABLE or VERBATIM (string variant)
inline bool isString() const noexcept;
//- Token is VARIABLE (string variant)
inline bool isVariable() const noexcept;
//- Token is VERBATIM string (string variant)
inline bool isVerbatim() const noexcept;
//- Token is WORD, DIRECTIVE, STRING, VARIABLE or VERBATIM
inline bool isStringType() const noexcept;
//- Token is COMPOUND
inline bool isCompound() const noexcept;
// Access
//- Return boolean token value.
// Report FatalIOError and return false if token is not BOOL or LABEL
inline bool boolToken() const;
//- Return flag bitmask value.
// Report FatalIOError and return NO_FLAG if token is not FLAG
inline int flagToken() const;
//- Return punctuation character.
// Report FatalIOError and return \b \\0 if token is not PUNCTUATION
inline punctuationToken pToken() const;
//- Return label value.
// Report FatalIOError and return \b 0 if token is not LABEL
inline label labelToken() const;
//- Return float value.
// Report FatalIOError and return \b 0 if token is not FLOAT
inline floatScalar floatToken() const;
//- Return double value.
// Report FatalIOError and return \b 0 if token is not DOUBLE
inline doubleScalar doubleToken() const;
//- Return float or double value.
// Report FatalIOError and return \b 0 if token is not a
// FLOAT or DOUBLE
inline scalar scalarToken() const;
//- Return label, float or double value.
// Report FatalIOError and return \b 0 if token is not a
// LABEL, FLOAT or DOUBLE
inline scalar number() const;
//- Return const reference to the word contents.
// Report FatalIOError and return \b "" if token is not a
// WORD or DIRECTIVE
inline const word& wordToken() const;
//- Return const reference to the string contents.
// Report FatalIOError and return \b "" if token is not a
// STRING, VARIABLE, VERBATIM or an upcast WORD or DIRECTIVE
inline const string& stringToken() const;
//- Read access for compound token
inline const compound& compoundToken() const;
//- Return reference to compound and mark internally as \em released.
compound& transferCompoundToken();
//- Return reference to compound and mark internally as \em released.
// The Istream is used for reference error messages only.
compound& transferCompoundToken(const Istream& is);
// Edit
//- Reset token to UNDEFINED and clear any allocated storage
inline void reset();
//- Clear token and set to be ERROR.
inline void setBad();
//- Swap token contents: type, data, line-number
inline void swap(token& tok);
// Info
//- Return info proxy for printing token information to a stream
InfoProxy info() const
{
return *this;
}
// Member Operators
// Assignment
//- Copy assign
inline void operator=(const token& tok);
//- Move assign
inline void operator=(token&& tok);
//- Copy assign from punctuation
inline void operator=(const punctuationToken p);
//- Copy assign from label
inline void operator=(const label val);
//- Copy assign from float
inline void operator=(const floatScalar val);
//- Copy assign from double
inline void operator=(const doubleScalar val);
//- Copy assign from word
inline void operator=(const word& w);
//- Copy assign from string
inline void operator=(const string& str);
//- Move assign from word
inline void operator=(word&& w);
//- Move assign from string
inline void operator=(string&& str);
//- Assign compound with reference counting to token
inline void operator=(token::compound* ptr);
//- Move assign from compound pointer
inline void operator=(autoPtr&& ptr);
// Equality
inline bool operator==(const token& tok) const;
inline bool operator==(const punctuationToken p) const noexcept;
inline bool operator==(const label val) const noexcept;
inline bool operator==(const floatScalar val) const noexcept;
inline bool operator==(const doubleScalar val) const noexcept;
inline bool operator==(const std::string& s) const;
// Inequality
inline bool operator!=(const token& tok) const;
inline bool operator!=(const punctuationToken p) const noexcept;
inline bool operator!=(const label val) const noexcept;
inline bool operator!=(const floatScalar val) const noexcept;
inline bool operator!=(const doubleScalar val) const noexcept;
inline bool operator!=(const std::string& s) const;
// IOstream Operators
friend Ostream& operator<<(Ostream& os, const token& tok);
friend Ostream& operator<<(Ostream& os, const punctuationToken& pt);
friend ostream& operator<<(ostream& os, const punctuationToken& pt);
friend ostream& operator<<(ostream& os, const InfoProxy& ct);
// Housekeeping
//- Write access for the token line number
// \deprecated(2021-03) - use lineNumber(label)
label& lineNumber() noexcept { return line_; }
//- Token is FLOAT
// \deprecated(2020-01) - isFloat()
bool isFloatScalar() const { return isFloat(); };
//- Token is DOUBLE
// \deprecated(2020-01) - isDouble()
bool isDoubleScalar() const { return isDouble(); }
//- Return float value.
// \deprecated(2020-01) - floatToken()
floatScalar floatScalarToken() const { return floatToken(); }
//- Return double value.
// \deprecated(2020-01) - doubleToken()
doubleScalar doubleScalarToken() const { return doubleToken(); }
//- Deprecated(2017-11) transfer word pointer to the token
// \deprecated(2017-11) - use move assign from word
void operator=(word*) = delete;
//- Deprecated(2017-11) transfer string pointer to the token
// \deprecated(2017-11) - use move assign from string
void operator=(string*) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// IOstream Operators
Istream& operator>>(Istream& is, token& tok);
Ostream& operator<<(Ostream& os, const token::punctuationToken& pt);
ostream& operator<<(ostream& os, const token::punctuationToken& pt);
Ostream& operator<<(Ostream& os, const token::compound& ct);
ostream& operator<<(ostream& os, const InfoProxy& ip);
template<>
Ostream& operator<<(Ostream& os, const InfoProxy& ip);
// Handling of compound types
//- Define compound using \a Type for its name
#define defineCompoundTypeName(Type, UnusedTag) \
defineTemplateTypeNameAndDebugWithName(token::Compound, #Type, 0);
//- Define compound using \a Name for its name
#define defineNamedCompoundTypeName(Type, Name) \
defineTemplateTypeNameAndDebugWithName(token::Compound, #Name, 0);
//- Add compound to selection table, lookup using typeName
#define addCompoundToRunTimeSelectionTable(Type, Tag) \
token::compound::addIstreamConstructorToTable> \
add##Tag##IstreamConstructorToTable_;
//- Add compound to selection table, lookup as \a Name
#define addNamedCompoundToRunTimeSelectionTable(Type, Tag, Name) \
token::compound::addIstreamConstructorToTable> \
add##Tag##IstreamConstructorToTable_(#Name);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "tokenI.H"
#include "Istream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //