mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: simplify direct creation of dictionary primitive entries
- can now create an empty entry and add/overwrite with tokens afterwards, or copy/move construct from a list of tokens. ENH: provided named token setter methods (disambiguates bool/char/label) COMP: use 'if constexpr' for FlatOutput DOC: more description for Field
This commit is contained in:
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -42,33 +42,55 @@ Description
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
class Scalar
|
||||
bool verbosity = true;
|
||||
|
||||
// Gratuitous class inheritance
|
||||
template<class T>
|
||||
class BoxedType
|
||||
{
|
||||
scalar data_;
|
||||
T data_;
|
||||
|
||||
public:
|
||||
|
||||
static bool verbose;
|
||||
|
||||
constexpr Scalar() noexcept : data_(0) {}
|
||||
Scalar(scalar val) noexcept : data_(val) {}
|
||||
constexpr BoxedType() noexcept : data_(0) {}
|
||||
BoxedType(T val) noexcept : data_(val) {}
|
||||
|
||||
~BoxedType()
|
||||
{
|
||||
if (verbosity) Info<< " [delete BoxedType: " << value() << ']' << nl;
|
||||
}
|
||||
|
||||
T value() const noexcept { return data_; }
|
||||
T& value() noexcept { return data_; }
|
||||
|
||||
auto clone() const { return autoPtr<BoxedType<T>>::New(*this); }
|
||||
};
|
||||
|
||||
template<class T> Ostream& operator<<(Ostream& os, const BoxedType<T>& item)
|
||||
{
|
||||
return (os << " -> " << item.value());
|
||||
}
|
||||
|
||||
|
||||
class Scalar : public BoxedType<scalar>
|
||||
{
|
||||
public:
|
||||
|
||||
using BoxedType<scalar>::BoxedType;
|
||||
|
||||
~Scalar()
|
||||
{
|
||||
if (verbose) Info<< "delete Scalar: " << data_ << endl;
|
||||
}
|
||||
|
||||
const scalar& value() const noexcept { return data_; }
|
||||
scalar& value() noexcept { return data_; }
|
||||
|
||||
friend Ostream& operator<<(Ostream& os, const Scalar& item)
|
||||
{
|
||||
os << item.value();
|
||||
return os;
|
||||
if (verbosity) Info<< "delete Scalar: " << value() << nl;
|
||||
}
|
||||
auto clone() const { return autoPtr<Scalar>::New(*this); }
|
||||
};
|
||||
|
||||
bool Scalar::verbose = true;
|
||||
Ostream& operator<<(Ostream& os, const Scalar& item)
|
||||
{
|
||||
return (os << item.value());
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
Test-ISLList.C
|
||||
Test-ISLList.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-ISLList
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
Test-PtrDictionary1.C
|
||||
Test-PtrDictionary1.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-PtrDictionary1
|
||||
|
||||
@ -42,6 +42,8 @@ Description
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
bool verbosity = true;
|
||||
|
||||
class ent
|
||||
:
|
||||
public Dictionary<ent>::link
|
||||
@ -73,14 +75,12 @@ class Scalar
|
||||
|
||||
public:
|
||||
|
||||
static bool verbose;
|
||||
|
||||
constexpr Scalar() noexcept : data_(0) {}
|
||||
Scalar(scalar val) noexcept : data_(val) {}
|
||||
|
||||
~Scalar()
|
||||
{
|
||||
if (verbose) Info<< "delete Scalar: " << data_ << endl;
|
||||
if (verbosity) Info<< "delete Scalar: " << data_ << endl;
|
||||
}
|
||||
|
||||
scalar value() const noexcept { return data_; }
|
||||
@ -93,8 +93,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
bool Scalar::verbose = true;
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
@ -41,35 +41,85 @@ Description
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
class Scalar
|
||||
bool verbosity = true;
|
||||
|
||||
// Gratuitous class inheritance
|
||||
template<class T>
|
||||
class BoxedType
|
||||
{
|
||||
scalar data_;
|
||||
T data_;
|
||||
|
||||
public:
|
||||
|
||||
static bool verbose;
|
||||
|
||||
constexpr Scalar() noexcept : data_(0) {}
|
||||
Scalar(scalar val) noexcept : data_(val) {}
|
||||
constexpr BoxedType() noexcept : data_(0) {}
|
||||
BoxedType(T val) noexcept : data_(val) {}
|
||||
|
||||
~BoxedType()
|
||||
{
|
||||
if (verbosity) Info<< " [delete BoxedType: " << value() << ']' << nl;
|
||||
}
|
||||
|
||||
T value() const noexcept { return data_; }
|
||||
T& value() noexcept { return data_; }
|
||||
|
||||
auto clone() const { return autoPtr<BoxedType<T>>::New(*this); }
|
||||
};
|
||||
|
||||
template<class T> Ostream& operator<<(Ostream& os, const BoxedType<T>& item)
|
||||
{
|
||||
return (os << " -> " << item.value());
|
||||
}
|
||||
|
||||
|
||||
class Scalar : public BoxedType<scalar>
|
||||
{
|
||||
public:
|
||||
|
||||
using BoxedType<scalar>::BoxedType;
|
||||
|
||||
~Scalar()
|
||||
{
|
||||
if (verbose) Info<< "delete Scalar: " << data_ << endl;
|
||||
}
|
||||
|
||||
scalar value() const noexcept { return data_; }
|
||||
scalar& value() noexcept { return data_; }
|
||||
|
||||
autoPtr<Scalar> clone() const { return autoPtr<Scalar>::New(data_); }
|
||||
|
||||
friend Ostream& operator<<(Ostream& os, const Scalar& item)
|
||||
{
|
||||
os << item.value();
|
||||
return os;
|
||||
if (verbosity) Info<< "delete Scalar: " << value() << nl;
|
||||
}
|
||||
auto clone() const { return autoPtr<Scalar>::New(*this); }
|
||||
};
|
||||
|
||||
bool Scalar::verbose = true;
|
||||
Ostream& operator<<(Ostream& os, const Scalar& item)
|
||||
{
|
||||
return (os << item.value());
|
||||
}
|
||||
|
||||
|
||||
class Integer : public BoxedType<label>
|
||||
{
|
||||
public:
|
||||
|
||||
using BoxedType<label>::BoxedType;
|
||||
|
||||
~Integer()
|
||||
{
|
||||
if (verbosity) Info<< "delete Integer: " << value() << nl;
|
||||
}
|
||||
auto clone() const { return autoPtr<Integer>::New(*this); }
|
||||
};
|
||||
|
||||
Ostream& operator<<(Ostream& os, const Integer& item)
|
||||
{
|
||||
return (os << item.value());
|
||||
}
|
||||
|
||||
|
||||
//- Permit up-casting to the base class (eg, fvMesh to polyMesh).
|
||||
// Usually only for holding (const) references.
|
||||
// Exercise caution with the
|
||||
template<class Base, class Derived>
|
||||
std::enable_if_t<std::is_base_of_v<Base, Derived>, const UPtrList<Base>&>
|
||||
upcast(const UPtrList<Derived>& This)
|
||||
{
|
||||
return *reinterpret_cast<const UPtrList<Base>*>(&This);
|
||||
}
|
||||
|
||||
|
||||
// As per
|
||||
@ -251,9 +301,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
Info<< "DLPtrList: " << llist1 << endl;
|
||||
|
||||
Scalar::verbose = false;
|
||||
verbosity = false;
|
||||
llist1.clear();
|
||||
Scalar::verbose = true;
|
||||
verbosity = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -331,6 +381,44 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
// Test upcasting - dangerous
|
||||
{
|
||||
const auto& base =
|
||||
*reinterpret_cast<UPtrList<BoxedType<scalar>>*>(&list1);
|
||||
|
||||
Info<< "list :" << list1 << nl;
|
||||
Info<< "base :" << base << nl;
|
||||
}
|
||||
|
||||
// Expect bad things to happen!!
|
||||
{
|
||||
const auto& base =
|
||||
*reinterpret_cast<UPtrList<BoxedType<label>>*>(&list1);
|
||||
|
||||
Info<< "list :" << list1 << nl;
|
||||
Info<< "base :" << base << nl;
|
||||
}
|
||||
|
||||
// Test upcasting - compile safer (make as member function?)
|
||||
{
|
||||
// const auto& base = list1.upcast<BoxedType<scalar>>();
|
||||
const auto& base = upcast<BoxedType<scalar>>(list1);
|
||||
|
||||
Info<< "list :" << list1 << nl;
|
||||
Info<< "base :" << base << nl;
|
||||
}
|
||||
|
||||
// Refuse to compile (good!)
|
||||
#if 0
|
||||
{
|
||||
// const auto& base = list1.upcast<BoxedType<label>>();
|
||||
const auto& base = upcast<BoxedType<label>>(list1);
|
||||
|
||||
Info<< "list :" << list1 << nl;
|
||||
Info<< "base :" << base << nl;
|
||||
}
|
||||
#endif
|
||||
|
||||
PtrList<Scalar> list2(15);
|
||||
Info<< "Emplace set " << list2.size() << " values" << nl;
|
||||
forAll(list2, i)
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
Test-PtrListDictionary.C
|
||||
Test-PtrListDictionary.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-PtrListDictionary
|
||||
|
||||
@ -39,26 +39,26 @@ Description
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
bool verbosity = true;
|
||||
|
||||
class Scalar
|
||||
{
|
||||
scalar data_;
|
||||
|
||||
public:
|
||||
|
||||
static bool verbose;
|
||||
|
||||
constexpr Scalar() noexcept : data_(0) {}
|
||||
Scalar(scalar val) noexcept : data_(val) {}
|
||||
|
||||
~Scalar()
|
||||
{
|
||||
if (verbose) Info<< "delete Scalar: " << data_ << endl;
|
||||
if (verbosity) Info<< "delete Scalar: " << value() << nl;
|
||||
}
|
||||
|
||||
const scalar& value() const noexcept { return data_; }
|
||||
scalar value() const noexcept { return data_; }
|
||||
scalar& value() noexcept { return data_; }
|
||||
|
||||
autoPtr<Scalar> clone() const { return autoPtr<Scalar>::New(data_); }
|
||||
auto clone() const { return autoPtr<Scalar>::New(*this); }
|
||||
|
||||
friend Ostream& operator<<(Ostream& os, const Scalar& item)
|
||||
{
|
||||
@ -67,8 +67,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
bool Scalar::verbose = true;
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
@ -1,3 +1,3 @@
|
||||
Test-dictionary.C
|
||||
Test-dictionary.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-dictionary
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
Test-dictionary2.C
|
||||
Test-dictionary2.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-dictionary2
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -47,8 +47,18 @@ void entryInfo(entry* e)
|
||||
{
|
||||
if (e)
|
||||
{
|
||||
Info<<"added "
|
||||
<< e->keyword() << ": " << typeid(e).name() << nl;
|
||||
Info<< "added "
|
||||
<< e->keyword() << ": " << typeid(e).name();
|
||||
|
||||
if (auto* stream = e->streamPtr())
|
||||
{
|
||||
Info<< " tokens: "; stream->tokens().writeList(Info);
|
||||
}
|
||||
if (auto* dict = e->dictPtr())
|
||||
{
|
||||
Info<< " dictionary:";
|
||||
}
|
||||
Info<< nl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,12 +210,31 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
dictionary tmpdict;
|
||||
|
||||
// Add an empty entry and populate afterwards
|
||||
if (entry* e = dict1.set(word::printf("entry%d", i), nullptr))
|
||||
{
|
||||
entry* e = dict1.add
|
||||
(
|
||||
word::printf("entry%d", i),
|
||||
string("entry" + Foam::name(i))
|
||||
);
|
||||
auto& toks = e->stream();
|
||||
toks.resize(2);
|
||||
|
||||
toks[0] = word("value" + Foam::name(i));
|
||||
toks[1] = 10*i;
|
||||
entryInfo(e);
|
||||
}
|
||||
|
||||
// Add an entry from given list of tokens
|
||||
{
|
||||
tokenList toks(2);
|
||||
toks[0] = word("value" + Foam::name(i));
|
||||
toks[1] = 10*i;
|
||||
|
||||
Info<< "set token0: " << Foam::name(&(toks[0])) << nl;
|
||||
|
||||
entry* e = dict1.set(word::printf("_entry%d", i), std::move(toks));
|
||||
|
||||
// verify that the address is identical (ie, move semantics worked)
|
||||
auto& newToks = e->stream();
|
||||
Info<< "get token0: " << Foam::name(&(newToks[0])) << nl;
|
||||
|
||||
entryInfo(e);
|
||||
}
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
Test-dictionaryCopy.C
|
||||
Test-dictionaryCopy.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-dictionaryCopy
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -32,8 +32,8 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef FlatOutput_H
|
||||
#define FlatOutput_H
|
||||
#ifndef Foam_FlatOutput_H
|
||||
#define Foam_FlatOutput_H
|
||||
|
||||
#include "Ostream.H"
|
||||
|
||||
@ -134,8 +134,8 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from component
|
||||
explicit OutputAdaptor(const Container& obj)
|
||||
//- Construct from const reference
|
||||
explicit OutputAdaptor(const Container& obj) noexcept
|
||||
:
|
||||
values(obj)
|
||||
{}
|
||||
@ -151,30 +151,22 @@ public:
|
||||
// No special handling for newline separators.
|
||||
inline Ostream& write(Ostream& os) const
|
||||
{
|
||||
bool started = false;
|
||||
[[maybe_unused]] bool started = false;
|
||||
|
||||
// In c++17, can use constexpr if
|
||||
|
||||
if (Delimiters::open)
|
||||
if constexpr (Delimiters::open) // Not nul char
|
||||
{
|
||||
os << Delimiters::open;
|
||||
os << Delimiters::open;
|
||||
}
|
||||
for (const auto& item : values)
|
||||
{
|
||||
if (started)
|
||||
{
|
||||
if (Delimiters::separator)
|
||||
{
|
||||
os << Delimiters::separator;
|
||||
}
|
||||
}
|
||||
else
|
||||
if constexpr (Delimiters::separator) // Not nul char
|
||||
{
|
||||
if (started) os << Delimiters::separator;
|
||||
started = true;
|
||||
}
|
||||
os << item;
|
||||
os << item;
|
||||
}
|
||||
if (Delimiters::close)
|
||||
if constexpr (Delimiters::close) // Not nul char
|
||||
{
|
||||
os << Delimiters::close;
|
||||
}
|
||||
|
||||
@ -717,6 +717,9 @@ public:
|
||||
// Report FatalIOError and return false if token is not BOOL or LABEL
|
||||
inline bool boolToken() const;
|
||||
|
||||
//- Assign to a boolean token
|
||||
inline void boolToken(bool on);
|
||||
|
||||
//- Return flag bitmask value.
|
||||
// Report FatalIOError and return NO_FLAG if token is not FLAG
|
||||
inline int flagToken() const;
|
||||
@ -725,10 +728,16 @@ public:
|
||||
// Report FatalIOError and return \b \\0 if token is not PUNCTUATION
|
||||
inline punctuationToken pToken() const;
|
||||
|
||||
//- Assign to a punctuation token
|
||||
inline void pToken(const punctuationToken p);
|
||||
|
||||
//- Return label value.
|
||||
// Report FatalIOError and return \b 0 if token is not LABEL
|
||||
inline label labelToken() const;
|
||||
|
||||
//- Assign to a label token
|
||||
inline void labelToken(const label val);
|
||||
|
||||
//- Return float value.
|
||||
// Report FatalIOError and return \b 0 if token is not FLOAT
|
||||
inline float floatToken() const;
|
||||
|
||||
@ -547,6 +547,14 @@ inline bool Foam::token::boolToken() const
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::token::boolToken(bool on)
|
||||
{
|
||||
reset();
|
||||
type_ = tokenType::BOOL;
|
||||
data_.labelVal = on;
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::token::isFlag() const noexcept
|
||||
{
|
||||
return (type_ == tokenType::FLAG);
|
||||
@ -603,6 +611,14 @@ inline Foam::token::punctuationToken Foam::token::pToken() const
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::token::pToken(const punctuationToken p)
|
||||
{
|
||||
reset();
|
||||
type_ = tokenType::PUNCTUATION;
|
||||
data_.punctuationVal = p;
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::token::isLabel() const noexcept
|
||||
{
|
||||
return
|
||||
@ -649,6 +665,14 @@ inline Foam::label Foam::token::labelToken() const
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::token::labelToken(const label val)
|
||||
{
|
||||
reset();
|
||||
type_ = tokenType::LABEL;
|
||||
data_.labelVal = val;
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::token::isFloat() const noexcept
|
||||
{
|
||||
return (type_ == tokenType::FLOAT);
|
||||
@ -1031,17 +1055,13 @@ inline void Foam::token::operator=(token&& tok)
|
||||
|
||||
inline void Foam::token::operator=(const punctuationToken p)
|
||||
{
|
||||
reset();
|
||||
type_ = tokenType::PUNCTUATION;
|
||||
data_.punctuationVal = p;
|
||||
token::pToken(p);
|
||||
}
|
||||
|
||||
|
||||
inline void Foam::token::operator=(const label val)
|
||||
{
|
||||
reset();
|
||||
type_ = tokenType::LABEL;
|
||||
data_.labelVal = val;
|
||||
token::labelToken(val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||
Copyright (C) 2015-2023 OpenCFD Ltd.
|
||||
Copyright (C) 2015-2025 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -803,6 +803,24 @@ Foam::entry* Foam::dictionary::set(const keyType& k, const dictionary& v)
|
||||
}
|
||||
|
||||
|
||||
Foam::entry* Foam::dictionary::set(const keyType& k, std::nullptr_t)
|
||||
{
|
||||
return set(new primitiveEntry(k));
|
||||
}
|
||||
|
||||
|
||||
Foam::entry* Foam::dictionary::set(const keyType& k, const UList<token>& tokens)
|
||||
{
|
||||
return set(new primitiveEntry(k, tokens));
|
||||
}
|
||||
|
||||
|
||||
Foam::entry* Foam::dictionary::set(const keyType& k, List<token>&& tokens)
|
||||
{
|
||||
return set(new primitiveEntry(k, std::move(tokens)));
|
||||
}
|
||||
|
||||
|
||||
bool Foam::dictionary::merge(const dictionary& dict)
|
||||
{
|
||||
if (this == &dict)
|
||||
|
||||
@ -953,6 +953,21 @@ public:
|
||||
// \return pointer to inserted entry or nullptr on failure
|
||||
entry* set(const keyType& k, const dictionary& v);
|
||||
|
||||
//- Assign an empty primitive entry,
|
||||
//- overwriting any existing entry.
|
||||
// \return pointer to entry or nullptr on failure
|
||||
entry* set(const keyType& k, std::nullptr_t);
|
||||
|
||||
//- Assign a primitive entry from a list of tokens,
|
||||
//- overwriting any existing entry.
|
||||
// \return pointer to entry or nullptr on failure
|
||||
entry* set(const keyType& k, const UList<token>& tokens);
|
||||
|
||||
//- Assign a primitive entry from a list of tokens,
|
||||
//- overwriting any existing entry.
|
||||
// \return pointer to entry or nullptr on failure
|
||||
entry* set(const keyType& k, List<token>&& tokens);
|
||||
|
||||
//- Assign a T entry, overwriting any existing entry.
|
||||
// \return pointer to inserted entry or nullptr on failure
|
||||
template<class T>
|
||||
|
||||
@ -28,7 +28,13 @@ Class
|
||||
Foam::Field
|
||||
|
||||
Description
|
||||
Generic templated field type.
|
||||
Generic templated field type that is much like a Foam::List
|
||||
except that it is expected to hold numerical content
|
||||
(not generic elements such as strings etc).
|
||||
|
||||
In addition to methods specific to numerical fields
|
||||
(e.g., clamp, min, max, transpose, ...), it also has a reference
|
||||
counter that is used by Foam::tmp handling.
|
||||
|
||||
SourceFiles
|
||||
FieldFunctions.H
|
||||
|
||||
Reference in New Issue
Block a user