Commit f1d9fea6 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: construct token::compound from object and token from compound (#1879)

- provides a more direct means of generating a compound token without
  an Istream

- add transferCompoundToken() without Istream reference

- mark more token methods as noexcept
parent de544c94
......@@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017 OpenCFD Ltd.
Copyright (C) 2017-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -33,6 +33,7 @@ Description
#include "IFstream.H"
#include "StringStream.H"
#include "cpuTime.H"
#include "labelList.H"
#include "DynamicList.H"
using namespace Foam;
......@@ -71,6 +72,47 @@ int main(int argc, char *argv[])
Info<< "assign token: " << tok3.info() << endl;
Info<< "orig: " << tok4.info() << endl;
//
// Compound
//
{
// This version is good
token ctok1(new token::Compound<labelList>(identity(10)));
Info<< "compound token: " << ctok1.info() << nl << ctok1 << endl;
}
{
// This also works, but not actually using the autoPtr directly
autoPtr<token::Compound<labelList>> ptr
(
new token::Compound<labelList>(identity(10, -9))
);
token ctok1(ptr.release()); // release() not get()!
Info<< "compound token: " << ctok1.info() << nl << ctok1 << endl;
}
#if 0
{
// This version will segfault.
// The implicit pointer cast from autoPtr to pointer wracks havoc
autoPtr<token::Compound<labelList>> ptr
(
new token::Compound<labelList>(identity(10))
);
token ctok1(ptr);
Info<< "compound token: " << ctok1.info() << nl << ctok1 << endl;
}
#endif
return 0;
}
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2019 OpenCFD Ltd.
Copyright (C) 2017-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -87,25 +87,46 @@ bool Foam::token::compound::isCompound(const word& name)
}
Foam::token::compound& Foam::token::transferCompoundToken()
{
if (type_ != tokenType::COMPOUND)
{
parseError("compound");
}
if (data_.compoundPtr->empty())
{
FatalErrorInFunction
<< "compound has already been transferred from token\n "
<< info() << abort(FatalError);
}
else
{
data_.compoundPtr->empty() = true;
}
return *data_.compoundPtr;
}
Foam::token::compound& Foam::token::transferCompoundToken(const Istream& is)
{
if (type_ == tokenType::COMPOUND)
if (type_ != tokenType::COMPOUND)
{
parseError("compound");
}
if (data_.compoundPtr->empty())
{
FatalIOErrorInFunction(is)
<< "compound has already been transferred from token\n "
<< info() << abort(FatalIOError);
}
else
{
if (data_.compoundPtr->empty())
{
FatalIOErrorInFunction(is)
<< "compound has already been transferred from token\n "
<< info() << abort(FatalIOError);
}
else
{
data_.compoundPtr->empty() = true;
}
return *data_.compoundPtr;
data_.compoundPtr->empty() = true;
}
parseError("compound");
return *data_.compoundPtr;
}
......
......@@ -62,7 +62,6 @@ namespace Foam
class token;
Ostream& operator<<(Ostream& os, const token& tok);
/*---------------------------------------------------------------------------*\
Class token Declaration
\*---------------------------------------------------------------------------*/
......@@ -178,39 +177,40 @@ public:
// Constructors
//- Default construct
compound()
constexpr compound() noexcept
:
empty_(false)
{}
// Selectors
//- Select null constructed
//- Construct compound from Istream
static autoPtr<compound> New(const word& type, Istream& is);
//- Return true if name is a known (registered) compound type
static bool isCompound(const word& name);
//- Destructor
virtual ~compound() = default;
virtual ~compound() noexcept = default;
// Member Functions
bool empty() const
//- Test if name is a known (registered) compound type
static bool isCompound(const word& name);
//- Has compound been transferred?
bool empty() const noexcept
{
return empty_;
}
bool& empty()
//- Access to empty
bool& empty() noexcept
{
return empty_;
}
//- The size of the underlying content
virtual label size() const = 0;
//- Redirect write to underlying content
virtual void write(Ostream& os) const = 0;
......@@ -233,20 +233,43 @@ public:
//- Declare type-name, virtual type (with debug switch)
TypeName("Compound<T>");
Compound(Istream& is)
:
T(is)
{}
// Constructors
label size() const
{
return T::size();
}
//- Copy construct
explicit Compound(const T& val)
:
T(val)
{}
void write(Ostream& os) const
{
operator<<(os, static_cast<const T&>(*this));
}
//- Move construct
explicit Compound(T&& val)
:
T(std::move(val))
{}
//- Read construct from Istream
explicit Compound(Istream& is)
:
T(is)
{}
// Member Functions
//- Using empty from compound refCount
using token::compound::empty;
//- 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<const T&>(*this));
}
};
......@@ -286,13 +309,13 @@ private:
tokenType type_;
//- Line number in the file the token was read from
label lineNumber_;
label line_;
// Private Member Functions
//- Set as UNDEFINED and zero the union content without any checking
inline void setUndefined();
inline void setUndefined() noexcept;
// Parse error, expected 'expected', found ...
void parseError(const char* expected) const;
......@@ -315,31 +338,34 @@ public:
inline token(const token& t);
//- Move construct. The original token is left as UNDEFINED.
inline token(token&& t);
inline token(token&& t) noexcept;
//- Construct punctuation character token
inline explicit token(punctuationToken p, label lineNumber=0);
inline explicit token(punctuationToken p, label lineNum=0) noexcept;
//- Construct label token
inline explicit token(const label val, label lineNumber=0);
inline explicit token(const label val, label lineNum=0) noexcept;
//- Construct float token
inline explicit token(const floatScalar val, label lineNumber=0);
inline explicit token(const floatScalar val, label lineNum=0) noexcept;
//- Construct double token
inline explicit token(const doubleScalar val, label lineNumber=0);
inline explicit token(const doubleScalar val, label lineNum=0) noexcept;
//- Copy construct word token
inline explicit token(const word& w, label lineNumber=0);
inline explicit token(const word& w, label lineNum=0);
//- Copy construct string token
inline explicit token(const string& str, label lineNumber=0);
inline explicit token(const string& str, label lineNum=0);
//- Move construct word token
inline explicit token(word&& w, label lineNumber=0);
inline explicit token(word&& w, label lineNum=0);
//- Move construct string token
inline explicit token(string&& str, label lineNumber=0);
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);
......@@ -352,12 +378,12 @@ public:
// Static Functions
//- Create a bool token.
inline static token boolean(bool on);
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);
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
......@@ -365,7 +391,7 @@ public:
//
// \param c the character to test, passed as int for consistency with
// isdigit, isspace etc.
inline static bool isseparator(int c);
inline static bool isseparator(int c) noexcept;
// Member Functions
......@@ -376,7 +402,7 @@ public:
word name() const;
//- Return the token type
inline tokenType type() const;
inline tokenType type() const noexcept;
//- Change the token type, for similar types.
// This can be used to change between string-like variants
......@@ -385,70 +411,70 @@ public:
// use the corresponding assignment operator.
//
// \return true if the change was successful or no change was required
inline bool setType(const tokenType tokType);
inline bool setType(const tokenType tokType) noexcept;
//- The line number for the token
inline label lineNumber() const;
inline label lineNumber() const noexcept;
//- The line number for the token
inline label& lineNumber();
inline label& lineNumber() noexcept;
//- True if token is not UNDEFINED or ERROR
inline bool good() const;
inline bool good() const noexcept;
//- Token is UNDEFINED
inline bool undefined() const;
inline bool undefined() const noexcept;
//- Token is ERROR
inline bool error() const;
inline bool error() const noexcept;
//- Token is BOOL
inline bool isBool() const;
inline bool isBool() const noexcept;
//- Token is FLAG
inline bool isFlag() const;
inline bool isFlag() const noexcept;
//- Token is PUNCTUATION
inline bool isPunctuation() const;
inline bool isPunctuation() const noexcept;
//- Token is PUNCTUATION and isseparator
inline bool isSeparator() const;
inline bool isSeparator() const noexcept;
//- Token is LABEL
inline bool isLabel() const;
inline bool isLabel() const noexcept;
//- Token is FLOAT
inline bool isFloat() const;
inline bool isFloat() const noexcept;
//- Token is DOUBLE
inline bool isDouble() const;
inline bool isDouble() const noexcept;
//- Token is FLOAT or DOUBLE
inline bool isScalar() const;
inline bool isScalar() const noexcept;
//- Token is LABEL, FLOAT or DOUBLE
inline bool isNumber() const;
inline bool isNumber() const noexcept;
//- Token is WORD or DIRECTIVE word
inline bool isWord() const;
inline bool isWord() const noexcept;
//- Token is DIRECTIVE (word variant)
inline bool isDirective() const;
inline bool isDirective() const noexcept;
//- Token is STRING, VARIABLE or VERBATIM string
inline bool isString() const;
inline bool isString() const noexcept;
//- Token is VARIABLE (string variant)
inline bool isVariable() const;
inline bool isVariable() const noexcept;
//- Token is VERBATIM string (string variant)
inline bool isVerbatim() const;
inline bool isVerbatim() const noexcept;
//- Token is WORD, DIRECTIVE, STRING, VARIABLE or VERBATIM
inline bool isStringType() const;
inline bool isStringType() const noexcept;
//- Token is COMPOUND
inline bool isCompound() const;
inline bool isCompound() const noexcept;
// Access
......@@ -500,8 +526,10 @@ public:
//- Read access for compound token
inline const compound& compoundToken() const;
//- Return reference to compound token and decrease its internal
//- refCount accordingly.
//- 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);
......@@ -562,7 +590,10 @@ public:
inline void operator=(string&& str);
//- Assign compound with reference counting to token
inline void operator=(compound* compoundPtr);
inline void operator=(token::compound* ptr);
//- Move assign from compound pointer
inline void operator=(autoPtr<token::compound>&& ptr);
// Equality
......
......@@ -30,7 +30,7 @@ License
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
inline Foam::token Foam::token::boolean(bool on)
inline Foam::token Foam::token::boolean(bool on) noexcept
{
token tok;
tok.type_ = tokenType::BOOL;
......@@ -40,7 +40,7 @@ inline Foam::token Foam::token::boolean(bool on)
}
inline Foam::token Foam::token::flag(int bitmask)
inline Foam::token Foam::token::flag(int bitmask) noexcept
{
token tok;
tok.type_ = tokenType::FLAG;
......@@ -50,7 +50,7 @@ inline Foam::token Foam::token::flag(int bitmask)
}
inline bool Foam::token::isseparator(int c)
inline bool Foam::token::isseparator(int c) noexcept
{
// NOTE: keep synchronized with ISstream::read(token&)
......@@ -84,7 +84,7 @@ inline bool Foam::token::isseparator(int c)
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
inline void Foam::token::setUndefined()
inline void Foam::token::setUndefined() noexcept
{
type_ = tokenType::UNDEFINED;
data_.int64Val = 0; // bit-wise zero for union content
......@@ -98,7 +98,7 @@ inline constexpr Foam::token::token() noexcept
:
data_(), // bit-wise zero for union content
type_(tokenType::UNDEFINED),
lineNumber_(0)
line_(0)
{}
......@@ -106,7 +106,7 @@ inline Foam::token::token(const token& tok)
:
data_(tok.data_), // bit-wise copy of union content
type_(tok.type_),
lineNumber_(tok.lineNumber_)
line_(tok.line_)
{
// Fundamental: values already handled by bit-wise copy
// Pointer: duplicate content or increase refCount
......@@ -142,97 +142,107 @@ inline Foam::token::token(const token& tok)
}
inline Foam::token::token(token&& tok)
inline Foam::token::token(token&& tok) noexcept
:
data_(tok.data_), // bit-wise copy of union content
type_(tok.type_),
lineNumber_(tok.lineNumber_)
line_(tok.line_)
{
tok.setUndefined(); // zero the union content without any checking
tok.lineNumber_ = 0;
tok.line_ = 0;
}
inline Foam::token::token(punctuationToken p, label lineNumber)
inline Foam::token::token(punctuationToken p, label lineNum) noexcept
:
data_(),
type_(tokenType::PUNCTUATION),
lineNumber_(lineNumber)
line_(lineNum)
{
data_.punctuationVal = p;
}
inline Foam::token::token(const label val, label lineNumber)
inline Foam::token::token(const label val, label lineNum) noexcept
:
data_(),
type_(tokenType::LABEL),
lineNumber_(lineNumber)
line_(lineNum)
{
data_.labelVal = val;
}
inline Foam::token::token(const floatScalar val, label lineNumber)
inline Foam::token::token(const floatScalar val, label lineNum) noexcept
:
data_(),
type_(tokenType::FLOAT),
lineNumber_(lineNumber)
line_(lineNum)
{
data_.floatVal = val;
}
inline Foam::token::token(const doubleScalar val, label lineNumber)
inline Foam::token::token(const doubleScalar val, label lineNum) noexcept
:
data_(),
type_(tokenType::DOUBLE),
lineNumber_(lineNumber)
line_(lineNum)
{
data_.doubleVal = val;
}
inline Foam::token::token(const word& w, label lineNumber)
inline Foam::token::token(const word& w, label lineNum)
:
data_(),
type_(tokenType::WORD),
lineNumber_(lineNumber)
line_(lineNum)
{
data_.wordPtr = new word(w);
}
inline Foam::token::token(const string& str, label lineNumber)
inline Foam::token::token(const string& str, label lineNum)
:
data_(),
type_(tokenType::STRING),
lineNumber_(lineNumber)
line_(lineNum)
{
data_.stringPtr = new string(str);
}
inline Foam::token::token(word&& w, label lineNumber)
inline Foam::token::token(word&& w, label lineNum)
:
data_(),
type_(tokenType::WORD),
lineNumber_(lineNumber)
line_(lineNum)
{
data_.wordPtr = new word(std::move(w));
}
inline Foam::token::token(string&& str, label lineNumber)
inline Foam::token::token(string&& str, label lineNum)
:
data_(),
type_(tokenType::STRING),
lineNumber_(lineNumber)
line_(lineNum)
{
data_.stringPtr = new string(std::move(str));
}
inline Foam::token::token