ENH: adjust return type for token compound factory method
- return autoPtr<token::compound> instead of the derived type, otherwise cannot easily construct a token from it ENH: additional typed version of refCompoundToken() - symmetric with typed version of transferCompoundToken() and isCompound() - add ITstream::findCompound<Type>() method. Useful for searching within token streams
This commit is contained in:
parent
880215e8e6
commit
411ac5fcfa
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2024 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -35,6 +35,9 @@ Description
|
||||
#include "labelList.H"
|
||||
#include "scalarList.H"
|
||||
#include "DynamicList.H"
|
||||
#include "labelField.H"
|
||||
#include "scalarField.H"
|
||||
#include "SubField.H"
|
||||
#include "SpanStream.H"
|
||||
#include "formattingEntry.H"
|
||||
|
||||
@ -90,7 +93,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
// This also works, but not actually using the autoPtr directly
|
||||
|
||||
autoPtr<token::Compound<labelList>> ptr
|
||||
autoPtr<token::compound> ptr
|
||||
(
|
||||
new token::Compound<labelList>(identity(10, -9))
|
||||
);
|
||||
@ -131,44 +134,50 @@ int main(int argc, char *argv[])
|
||||
Info<< "resized: "
|
||||
<< ctok1.info() << nl << ctok1 << endl;
|
||||
|
||||
const scalarList* listptr = ctok1.compoundToken().isA<scalarList>();
|
||||
if (listptr)
|
||||
{
|
||||
for (scalar& val : const_cast<scalarList&>(*listptr))
|
||||
// Using isA<> on compoundToken()
|
||||
const auto* listptr = ctok1.compoundToken().isA<scalarList>();
|
||||
if (listptr)
|
||||
{
|
||||
val *= 5;
|
||||
}
|
||||
// sneaky, SubField bypasses const!
|
||||
scalarField::subField fld(*listptr);
|
||||
fld *= 5;
|
||||
|
||||
Info<< "multiplied List<scalar>: "
|
||||
<< ctok1.info() << nl << ctok1 << endl;
|
||||
Info<< "multiplied List<scalar>: "
|
||||
<< ctok1.info() << nl << ctok1 << endl;
|
||||
}
|
||||
}
|
||||
|
||||
listptr = ctok1.isCompound<scalarList>();
|
||||
if (listptr)
|
||||
{
|
||||
for (scalar& val : const_cast<scalarList&>(*listptr))
|
||||
{
|
||||
val /= 2;
|
||||
}
|
||||
// Using isCompound<...> - combined check
|
||||
|
||||
Info<< "divided List<scalar>: "
|
||||
<< ctok1.info() << nl << ctok1 << endl;
|
||||
const auto* listptr = ctok1.isCompound<scalarList>();
|
||||
if (listptr)
|
||||
{
|
||||
scalarField::subField fld(*listptr);
|
||||
fld /= 2;
|
||||
|
||||
Info<< "divided List<scalar>: "
|
||||
<< ctok1.info() << nl << ctok1 << endl;
|
||||
}
|
||||
}
|
||||
|
||||
const labelList* listptr2 = ctok1.isCompound<labelList>();
|
||||
if (listptr2)
|
||||
{
|
||||
for (label& val : const_cast<labelList&>(*listptr2))
|
||||
{
|
||||
val /= 2;
|
||||
}
|
||||
// Using isCompound<...> - combined check
|
||||
|
||||
Info<< "divided List<label>: "
|
||||
<< ctok1.info() << nl << ctok1 << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "compound is not List<label>" << nl;
|
||||
const auto* listptr = ctok1.isCompound<labelList>();
|
||||
if (listptr)
|
||||
{
|
||||
labelField::subField fld(*listptr);
|
||||
fld /= 2;
|
||||
|
||||
Info<< "divided List<label>: "
|
||||
<< ctok1.info() << nl << ctok1 << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "compound is not List<label>" << nl;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "Before fill_zero: " << ctok1 << endl;
|
||||
@ -183,57 +192,33 @@ int main(int argc, char *argv[])
|
||||
auto& ct = ctok1.refCompoundToken();
|
||||
|
||||
ct.resize(20);
|
||||
bool handled = true;
|
||||
bool handled = false;
|
||||
|
||||
switch (ct.typeCode())
|
||||
{
|
||||
case token::tokenType::BOOL :
|
||||
{
|
||||
UList<bool> cmpts
|
||||
(
|
||||
reinterpret_cast<bool*>(ct.data_bytes()),
|
||||
label(ct.size_bytes() / sizeof(bool))
|
||||
);
|
||||
cmpts = false;
|
||||
#undef doLocalCode
|
||||
#define doLocalCode(TokenType, cmptType, cmptValue) \
|
||||
\
|
||||
case TokenType : \
|
||||
{ \
|
||||
UList<cmptType> cmpts \
|
||||
( \
|
||||
reinterpret_cast<cmptType*>(ct.data_bytes()), \
|
||||
label(ct.size_bytes() / sizeof(cmptType)) \
|
||||
); \
|
||||
cmpts = cmptValue; \
|
||||
handled = true; \
|
||||
break; \
|
||||
}
|
||||
break;
|
||||
|
||||
case token::tokenType::LABEL :
|
||||
{
|
||||
UList<label> cmpts
|
||||
(
|
||||
reinterpret_cast<label*>(ct.data_bytes()),
|
||||
label(ct.size_bytes() / sizeof(label))
|
||||
);
|
||||
cmpts = 123;
|
||||
}
|
||||
break;
|
||||
doLocalCode(token::tokenType::BOOL, bool, false);
|
||||
doLocalCode(token::tokenType::LABEL, label, 123);
|
||||
doLocalCode(token::tokenType::FLOAT, float, 2.7);
|
||||
doLocalCode(token::tokenType::DOUBLE, double, 3.1415);
|
||||
|
||||
case token::tokenType::FLOAT :
|
||||
{
|
||||
UList<float> cmpts
|
||||
(
|
||||
reinterpret_cast<float*>(ct.data_bytes()),
|
||||
label(ct.size_bytes() / sizeof(float))
|
||||
);
|
||||
cmpts = 2.7;
|
||||
}
|
||||
break;
|
||||
#undef doLocalCode
|
||||
|
||||
case token::tokenType::DOUBLE :
|
||||
{
|
||||
UList<double> cmpts
|
||||
(
|
||||
reinterpret_cast<double*>(ct.data_bytes()),
|
||||
label(ct.size_bytes() / sizeof(double))
|
||||
);
|
||||
cmpts = 3.1415;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
handled = false;
|
||||
break;
|
||||
default : break;
|
||||
}
|
||||
|
||||
|
||||
@ -241,6 +226,10 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
Info<< "assigned: " << ctok1 << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "Warning: not handled!" << nl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -327,6 +316,65 @@ int main(int argc, char *argv[])
|
||||
Info<< "content" << nl << entry3 << nl;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
primitiveEntry entry0("entry");
|
||||
|
||||
Info<< "empty: " << entry0 << nl;
|
||||
|
||||
// populate
|
||||
{
|
||||
tokenList& toks = entry0.stream();
|
||||
toks.resize(2);
|
||||
toks[0] = word("nonuniform");
|
||||
toks[1] = token::Compound<scalarList>::New(10, scalar(1));
|
||||
}
|
||||
|
||||
Info<< entry0 << nl;
|
||||
|
||||
// Modify contents
|
||||
for (auto& tok : entry0.stream())
|
||||
{
|
||||
if (tok.isCompound<scalarList>())
|
||||
{
|
||||
tok.refCompoundToken<scalarList>() = 2;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< entry0 << nl;
|
||||
|
||||
|
||||
// Find and 'capture' contents
|
||||
|
||||
{
|
||||
typedef List<scalar> ListType;
|
||||
|
||||
auto* inputDataPtr =
|
||||
const_cast<ListType*>(entry0.stream().findCompound<ListType>());
|
||||
|
||||
if (inputDataPtr)
|
||||
{
|
||||
Info<< "found input data" << nl;
|
||||
Info<< entry0 << nl;
|
||||
|
||||
ListType inputData(std::move(*inputDataPtr));
|
||||
|
||||
Info<< "input data, after move" << nl;
|
||||
Info<< entry0 << nl;
|
||||
|
||||
ListType replaceData(5, scalar(3.145));
|
||||
|
||||
// some manipulation
|
||||
replaceData.back() = scalar(1.414);
|
||||
|
||||
inputDataPtr->swap(replaceData);
|
||||
Info<< "with replaced values" << nl;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< entry0 << nl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -433,7 +433,7 @@ public:
|
||||
using tokenList::find;
|
||||
|
||||
//- Find range containing matching delimiter pair, starting at the
|
||||
//- the specified position. The position -1 indicates to continue
|
||||
//- specified position. The position -1 indicates to continue
|
||||
//- from the present tokenIndex() position.
|
||||
labelRange find
|
||||
(
|
||||
@ -442,6 +442,13 @@ public:
|
||||
label pos = 0
|
||||
) const;
|
||||
|
||||
//- Find compoundToken of specified Type, starting at the
|
||||
//- specified position. The position -1 indicates to continue
|
||||
//- from the present tokenIndex() position.
|
||||
// \return nullptr if not found
|
||||
template<class Type>
|
||||
const Type* findCompound(label pos = 0) const;
|
||||
|
||||
|
||||
// Token list modification
|
||||
|
||||
@ -636,6 +643,10 @@ public:
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "ITstreamI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
|
52
src/OpenFOAM/db/IOstreams/Tstreams/ITstreamI.H
Normal file
52
src/OpenFOAM/db/IOstreams/Tstreams/ITstreamI.H
Normal file
@ -0,0 +1,52 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2024 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/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class Type>
|
||||
const Type* Foam::ITstream::findCompound(label pos) const
|
||||
{
|
||||
if (pos < 0)
|
||||
{
|
||||
pos = tokenIndex_;
|
||||
}
|
||||
|
||||
const Type* ptr = nullptr;
|
||||
|
||||
for (; pos < tokenList::size(); ++pos)
|
||||
{
|
||||
ptr = tokenList::operator[](pos).isCompound<Type>();
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -105,9 +105,9 @@ public:
|
||||
CHAR_DATA, //!< String-variant: plain character content
|
||||
|
||||
// Aliases
|
||||
FLOAT_SCALAR = FLOAT,
|
||||
DOUBLE_SCALAR = DOUBLE,
|
||||
VERBATIMSTRING = VERBATIM
|
||||
FLOAT_SCALAR = FLOAT, //!< compatibility name for FLOAT
|
||||
DOUBLE_SCALAR = DOUBLE, //!< compatibility name for DOUBLE
|
||||
VERBATIMSTRING = VERBATIM //!< compatibility name for VERBATIM
|
||||
};
|
||||
|
||||
|
||||
@ -222,7 +222,8 @@ public:
|
||||
const bool readContent = true
|
||||
);
|
||||
|
||||
//- Check if dynamic_cast to \c Type is possible.
|
||||
//- Attempt dynamic_cast to \c Type
|
||||
//- returns nullptr if cast is not possible
|
||||
template<class Type>
|
||||
const Type* isA() const
|
||||
{
|
||||
@ -367,11 +368,13 @@ public:
|
||||
|
||||
// Selectors
|
||||
|
||||
//- Construct autoPtr compound type with forwarding arguments
|
||||
//- Construct autoPtr compound with forwarding arguments.
|
||||
// The return type is compound, not Compound since that
|
||||
// is what the token interface requires.
|
||||
template<class... Args>
|
||||
static autoPtr<Compound<T>> New(Args&&... args)
|
||||
static autoPtr<compound> New(Args&&... args)
|
||||
{
|
||||
return autoPtr<Compound<T>>
|
||||
return autoPtr<compound>
|
||||
(
|
||||
new Compound<T>(T(std::forward<Args>(args)...))
|
||||
);
|
||||
@ -386,7 +389,7 @@ public:
|
||||
return T::size();
|
||||
}
|
||||
|
||||
//- Change the size of the underlying container content
|
||||
//- Change the size of the underlying content
|
||||
virtual void resize(const label n)
|
||||
{
|
||||
T::resize(n);
|
||||
@ -759,8 +762,15 @@ public:
|
||||
inline const compound& compoundToken() const;
|
||||
|
||||
//- Return reference to compound token. Fatal if the wrong type.
|
||||
//- No checks for \em released or \em pending states
|
||||
inline compound& refCompoundToken();
|
||||
|
||||
//- Return reference to the underlying encapsulated container
|
||||
//- (eg, \c List<label> etc) of a compound token.
|
||||
//- No checks for \em released or \em pending states
|
||||
template<class Type>
|
||||
inline Type& refCompoundToken();
|
||||
|
||||
//- Default construct the specified compound type and read from stream.
|
||||
// A no-op and returns false if compound type is unknown.
|
||||
// Modify the token and return true on success.
|
||||
|
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2024 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -873,6 +873,23 @@ inline Foam::token::compound& Foam::token::refCompoundToken()
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
inline Type& Foam::token::refCompoundToken()
|
||||
{
|
||||
if (type_ != tokenType::COMPOUND)
|
||||
{
|
||||
parseError("compound");
|
||||
}
|
||||
return static_cast<Type&>
|
||||
(
|
||||
dynamicCast<token::Compound<Type>>
|
||||
(
|
||||
*data_.compoundPtr
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::token::compound&
|
||||
Foam::token::transferCompoundToken(const Istream& is)
|
||||
{
|
||||
|
@ -281,9 +281,7 @@ bool Foam::mappedPatchBase::constructIOField
|
||||
objectRegistry& obr
|
||||
)
|
||||
{
|
||||
const word tag("List<" + word(pTraits<Type>::typeName) + '>');
|
||||
|
||||
if (tok.isCompound(tag))
|
||||
if (tok.isCompound<List<Type>>())
|
||||
{
|
||||
auto* fldPtr = obr.getObjectPtr<IOField<Type>>(name);
|
||||
if (!fldPtr)
|
||||
|
Loading…
Reference in New Issue
Block a user