Merge branch 'improve-IOobject_PtrList_CompactIOList_List' into 'develop'

general list cleanups

See merge request Development/openfoam!754
This commit is contained in:
Mattijs Janssens
2025-08-28 08:44:32 +00:00
114 changed files with 1757 additions and 943 deletions

View File

@ -1,3 +1,3 @@
Test-CompactIOList.C Test-CompactIOList.cxx
EXE = $(FOAM_USER_APPBIN)/Test-CompactIOList EXE = $(FOAM_USER_APPBIN)/Test-CompactIOList

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2020-2022 OpenCFD Ltd. Copyright (C) 2020-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -25,7 +25,7 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application Application
testCompactIOList Test-CompactIOList
Description Description
Simple demonstration and test application for the CompactIOList container Simple demonstration and test application for the CompactIOList container
@ -46,13 +46,20 @@ using namespace Foam;
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
argList::addBoolOption("ascii", "use ascii format");
argList::addOption("count", "number of faces");
#include "setRootCase.H" #include "setRootCase.H"
#include "createTime.H" #include "createTime.H"
IOstreamOption streamOpt(IOstreamOption::BINARY); IOstreamOption streamOpt(IOstreamOption::BINARY);
// IOstreamOption streamOpt(IOstreamOption::ASCII);
const label size = 20000000; if (args.found("ascii"))
{
streamOpt.format(IOstreamOption::ASCII);
}
const label size = args.getOrDefault<label>("count", 20000000);
// Old format // Old format
// ~~~~~~~~~~ // ~~~~~~~~~~
@ -63,39 +70,50 @@ int main(int argc, char *argv[])
( (
IOobject IOobject
( (
"faces2", "faces2-plain",
runTime.constant(), runTime.constant(),
polyMesh::meshSubDir, polyMesh::meshSubDir,
runTime, runTime,
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
IOobject::NO_REGISTER IOobject::NO_REGISTER
), )
size
); );
const face f(identity(4)); faces2.resize(size, face(identity(4)));
forAll(faces2, i) Info<< "Plain format faceList " << faces2.objectRelPath() << nl;
{ Info<< " constructed in = " << runTime.cpuTimeIncrement()
faces2[i] = f; << " s" << endl;
}
Info<< "Constructed faceList in = "
<< runTime.cpuTimeIncrement() << " s" << nl << endl;
faces2.writeObject(streamOpt, true); faces2.writeObject(streamOpt, true);
Info<< "Written old format faceList in = " Info<< " wrote in = "
<< runTime.cpuTimeIncrement() << " s" << nl << endl; << runTime.cpuTimeIncrement() << " s" << endl;
// Read // Read (size only)
faceIOList faces3 label count = faceIOList::readContentsSize
( (
IOobject IOobject
( (
"faces2", "faces2-plain",
runTime.constant(),
polyMesh::meshSubDir,
runTime,
IOobject::MUST_READ
)
);
Info<< " counted " << count << " faces on disk in = "
<< runTime.cpuTimeIncrement() << " s" << endl;
// Read
faceIOList faces2b
(
IOobject
(
"faces2-plain",
runTime.constant(), runTime.constant(),
polyMesh::meshSubDir, polyMesh::meshSubDir,
runTime, runTime,
@ -105,7 +123,7 @@ int main(int argc, char *argv[])
) )
); );
Info<< "Read old format " << faces3.size() << " faceList in = " Info<< " read " << faces2b.size() << " faces in = "
<< runTime.cpuTimeIncrement() << " s" << nl << endl; << runTime.cpuTimeIncrement() << " s" << nl << endl;
} }
@ -114,44 +132,54 @@ int main(int argc, char *argv[])
// ~~~~~~~~~~ // ~~~~~~~~~~
{ {
// Construct big faceList in new format // Construct big faceList in compact format
faceCompactIOList faces2 faceCompactIOList faces2
( (
IOobject IOobject
( (
"faces2", "faces2-compact",
runTime.constant(), runTime.constant(),
polyMesh::meshSubDir, polyMesh::meshSubDir,
runTime, runTime,
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
IOobject::NO_REGISTER IOobject::NO_REGISTER
), )
size
); );
const face f(identity(4)); faces2.resize(size, face(identity(4)));
forAll(faces2, i) Info<< "Compact format faceList" << faces2.objectRelPath() << nl;
{ Info<< " constructed in = "
faces2[i] = f; << runTime.cpuTimeIncrement() << " s" << endl;
}
Info<< "Constructed new format faceList in = "
<< runTime.cpuTimeIncrement() << " s" << nl << endl;
faces2.writeObject(streamOpt, true); faces2.writeObject(streamOpt, true);
Info<< "Written new format faceList in = " Info<< " wrote in = "
<< runTime.cpuTimeIncrement() << " s" << nl << endl; << runTime.cpuTimeIncrement() << " s" << endl;
// Read // Read (size only)
faceCompactIOList faces3 label count = faceCompactIOList::readContentsSize
( (
IOobject IOobject
( (
"faces2", "faces2-compact",
runTime.constant(),
polyMesh::meshSubDir,
runTime,
IOobject::MUST_READ
)
);
Info<< " counted " << count << " faces on disk in = "
<< runTime.cpuTimeIncrement() << " s" << endl;
// Read
faceCompactIOList faces2b
(
IOobject
(
"faces2-compact",
runTime.constant(), runTime.constant(),
polyMesh::meshSubDir, polyMesh::meshSubDir,
runTime, runTime,
@ -161,7 +189,7 @@ int main(int argc, char *argv[])
) )
); );
Info<< "Read new format " << faces3.size() << " faceList in = " Info<< " read " << faces2b.size() << " faces in = "
<< runTime.cpuTimeIncrement() << " s" << nl << endl; << runTime.cpuTimeIncrement() << " s" << nl << endl;
} }

View File

@ -1,3 +1,3 @@
Test-HashPtrTable.C Test-HashPtrTable.cxx
EXE = $(FOAM_USER_APPBIN)/Test-HashPtrTable EXE = $(FOAM_USER_APPBIN)/Test-HashPtrTable

View File

@ -1,3 +1,3 @@
Test-HashTable2.C Test-HashTable2.cxx
EXE = $(FOAM_USER_APPBIN)/Test-HashTable2 EXE = $(FOAM_USER_APPBIN)/Test-HashTable2

View File

@ -1,3 +1,3 @@
Test-HashTable3.C Test-HashTable3.cxx
EXE = $(FOAM_USER_APPBIN)/Test-HashTable3 EXE = $(FOAM_USER_APPBIN)/Test-HashTable3

View File

@ -1,3 +1,3 @@
Test-IOobjectList.C Test-IOobjectList.cxx
EXE = $(FOAM_USER_APPBIN)/Test-IOobjectList EXE = $(FOAM_USER_APPBIN)/Test-IOobjectList

View File

@ -1,3 +1,3 @@
Test-PtrList.C Test-PtrList.cxx
EXE = $(FOAM_USER_APPBIN)/Test-PtrList EXE = $(FOAM_USER_APPBIN)/Test-PtrList

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2018-2023 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -86,20 +86,7 @@ Ostream& printAddr
const UPtrList<T>& list const UPtrList<T>& list
) )
{ {
const label len = list.size(); return list.printAddresses(os);
// Size and start delimiter
os << nl << indent << len << nl
<< indent << token::BEGIN_LIST << incrIndent << nl;
for (label i=0; i < len; ++i)
{
os << "addr=" << Foam::name(list.get(i)) << nl;
}
// End delimiter
os << decrIndent << indent << token::END_LIST << nl;
return os;
} }
@ -176,11 +163,11 @@ Ostream& print
{ {
const label cap = list.capacity(); const label cap = list.capacity();
for (label i=len; i < cap; ++i) for (label i = len; i < cap; ++i)
{ {
const T* ptr = list.get(i); const T* ptr = list.get(i);
os << "unused " << name(ptr) << nl; os << "unused " << Foam::name(ptr) << nl;
} }
} }
@ -518,6 +505,7 @@ int main(int argc, char *argv[])
print(Info, dynlist1d); print(Info, dynlist1d);
Info<< "addresses:" << nl; Info<< "addresses:" << nl;
dynlist1d.printAddresses(Info, true);
printAddr(Info, dynlist1d); printAddr(Info, dynlist1d);
PtrList<Scalar> list1d; PtrList<Scalar> list1d;

View File

@ -1,3 +1,3 @@
Test-bitSet1.C Test-bitSet1.cxx
EXE = $(FOAM_USER_APPBIN)/Test-bitSet1 EXE = $(FOAM_USER_APPBIN)/Test-bitSet1

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018-2021 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -75,9 +75,9 @@ inline Ostream& info(const UList<bool>& bools)
Info<< "size=" << bools.size() Info<< "size=" << bools.size()
<< " count=" << BitOps::count(bools) << " count=" << BitOps::count(bools)
<< " !count=" << BitOps::count(bools, false) << " !count=" << BitOps::count(bools, false)
<< " all:" << BitOps::all(bools) << " all:" << bools.all()
<< " any:" << BitOps::any(bools) << " any:" << bools.any()
<< " none:" << BitOps::none(bools) << nl; << " none:" << bools.none() << nl;
return Info; return Info;
} }
@ -194,8 +194,10 @@ int main(int argc, char *argv[])
{ {
boolList bools = list1.values(); boolList bools = list1.values();
Info<<"===============" << nl; Info<< "===============" << nl;
Info<<"bools: " << flatOutput(bools) << nl; Info<< "bools: " << flatOutput(bools) << nl;
Info<< " ";
info(bools);
for (int i : { -10, 0, 8, 15, 32}) for (int i : { -10, 0, 8, 15, 32})
{ {
@ -238,17 +240,18 @@ int main(int argc, char *argv[])
} }
#ifdef TEST_SFINAE #ifdef TEST_SFINAE
// This should fail to compile:
{ {
labelList labels = list1.toc(); labelList labels = list1.toc();
if (labels.test(0)) if (labels.test(0))
{ {
Info<<"no" << endl; Info<< "no" << endl;
} }
List<double*> ptrs(10, nullptr); List<double*> ptrs(10, nullptr);
if (ptrs.get(0)) if (ptrs.get(0))
{ {
Info<<"no" << endl; Info<< "no" << endl;
} }
} }
#endif #endif

View File

@ -1,3 +1,3 @@
Test-boolList.C Test-boolList.cxx
EXE = $(FOAM_USER_APPBIN)/Test-boolList EXE = $(FOAM_USER_APPBIN)/Test-boolList

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2020-2022 OpenCFD Ltd. Copyright (C) 2020-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -71,9 +71,9 @@ inline Ostream& info(const UList<bool>& bools)
Info<< "size=" << bools.size() Info<< "size=" << bools.size()
<< " count=" << BitOps::count(bools) << " count=" << BitOps::count(bools)
<< " !count=" << BitOps::count(bools, false) << " !count=" << BitOps::count(bools, false)
<< " all:" << BitOps::all(bools) << " all:" << bools.all()
<< " any:" << BitOps::any(bools) << " any:" << bools.any()
<< " none:" << BitOps::none(bools) << nl; << " none:" << bools.none() << nl;
return Info; return Info;
} }

View File

@ -64,7 +64,7 @@ Foam::label Foam::parLagrangianDistributor::readAllFields
); \ ); \
\ \
nTotal += parLagrangianDistributor::readFields \ nTotal += parLagrangianDistributor::readFields \
<CompactIOField<Field<Type>, Type>> \ <CompactIOField<Field<Type>>> \
( \ ( \
cloud, \ cloud, \
haveCloud, \ haveCloud, \
@ -177,7 +177,7 @@ Foam::label Foam::parLagrangianDistributor::distributeAllStoredFields
); \ ); \
\ \
nTotal += this->distributeStoredFields \ nTotal += this->distributeStoredFields \
<CompactIOField<Field<Type>, Type>> \ <CompactIOField<Field<Type>>> \
( \ ( \
lagrangianMap, \ lagrangianMap, \
cloud \ cloud \

View File

@ -156,14 +156,15 @@ Foam::label Foam::parLagrangianDistributor::distributeFieldFields
const wordRes& selectedFields const wordRes& selectedFields
) const ) const
{ {
typedef CompactIOField<Field<Type>, Type> Container; typedef CompactIOField<Field<Type>> Container;
typedef IOField<Field<Type>> fallbackType;
DynamicList<word> fieldNames; DynamicList<word> fieldNames;
// CompactIOField Field names // CompactIOField Field names
fieldNames.push_back fieldNames.push_back
( (
filterObjects<CompactIOField<Field<Type>, Type>> filterObjects<Container>
( (
objects, objects,
selectedFields selectedFields
@ -173,7 +174,7 @@ Foam::label Foam::parLagrangianDistributor::distributeFieldFields
// IOField Field names // IOField Field names
fieldNames.push_back fieldNames.push_back
( (
filterObjects<IOField<Field<Type>>> filterObjects<fallbackType>
( (
objects, objects,
selectedFields selectedFields

View File

@ -129,7 +129,7 @@ void MapLagrangianFields
MapLagrangianFields MapLagrangianFields
< <
IOField<Field<Type>>, IOField<Field<Type>>,
CompactIOField<Field<Type>, Type> CompactIOField<Field<Type>>
> >
( (
cloudName, cloudName,
@ -141,8 +141,8 @@ void MapLagrangianFields
MapLagrangianFields MapLagrangianFields
< <
CompactIOField<Field<Type>, Type>, CompactIOField<Field<Type>>,
CompactIOField<Field<Type>, Type> CompactIOField<Field<Type>>
> >
( (
cloudName, cloudName,

View File

@ -133,7 +133,7 @@ void MapLagrangianFields
MapLagrangianFields MapLagrangianFields
< <
IOField<Field<Type>>, IOField<Field<Type>>,
CompactIOField<Field<Type>, Type> CompactIOField<Field<Type>>
> >
( (
cloudName, cloudName,
@ -145,8 +145,8 @@ void MapLagrangianFields
MapLagrangianFields MapLagrangianFields
< <
CompactIOField<Field<Type>, Type>, CompactIOField<Field<Type>>,
CompactIOField<Field<Type>, Type> CompactIOField<Field<Type>>
> >
( (
cloudName, cloudName,

View File

@ -42,7 +42,6 @@ chars = primitives/chars
$(chars)/char/char.C $(chars)/char/char.C
$(chars)/wchar/wchar.C $(chars)/wchar/wchar.C
$(chars)/lists/charList.C $(chars)/lists/charList.C
$(chars)/lists/charUList.C
primitives/direction/directionIO.C primitives/direction/directionIO.C

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018-2023 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -33,6 +33,12 @@ License
// * * * * * * * * * * * * * * * * * BitOps * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * BitOps * * * * * * * * * * * * * * * * //
unsigned int Foam::BitOps::count(const bitSet& bitset, const bool on)
{
return bitset.count(on);
}
// See bitSet::setMany for original implementation // See bitSet::setMany for original implementation
void Foam::BitOps::set(List<bool>& bools, const labelUList& locations) void Foam::BitOps::set(List<bool>& bools, const labelUList& locations)
{ {

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018-2023 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -77,26 +77,17 @@ inline unsigned int count(const UList<bool>& bools, const bool val=true)
return std::count(bools.begin(), bools.end(), val); return std::count(bools.begin(), bools.end(), val);
} }
//- True if all entries are 'true' or if the set is empty. //- True if all entries are 'true' or if the list is empty.
// For compatibility with bitSet::all() // For compatibility with bitSet::all()
inline bool all(const UList<bool>& bools) inline bool all(const UList<bool>& bools) { return bools.all(); }
{
return std::all_of(bools.begin(), bools.end(), identityOp());
}
//- True if any entries are 'true'. //- True if any entries are 'true'.
// For compatibility with bitSet::any() // For compatibility with bitSet::any()
inline bool any(const UList<bool>& bools) inline bool any(const UList<bool>& bools) { return bools.any(); }
{
return std::any_of(bools.begin(), bools.end(), identityOp());
}
//- True if no entries are 'true'. //- True if no entries are 'true'.
// For compatibility with bitSet::none() // For compatibility with bitSet::none()
inline bool none(const UList<bool>& bools) inline bool none(const UList<bool>& bools) { return bools.none(); }
{
return std::none_of(bools.begin(), bools.end(), identityOp());
}
//- Set the listed locations (assign 'true'). //- Set the listed locations (assign 'true').
@ -150,6 +141,10 @@ List<bool> select(const label n, const labelUList& locations);
// \return a List of bools // \return a List of bools
List<bool> select(const labelUList& locations); List<bool> select(const labelUList& locations);
//- Forward to bitSet::count()
unsigned int count(const bitSet& bitset, const bool on=true);
//- Return the (sorted) values corresponding to 'true' entries. //- Return the (sorted) values corresponding to 'true' entries.
// Similar to bitSet::toc() // Similar to bitSet::toc()
// //
@ -292,13 +287,13 @@ struct bitInfo
constexpr bitInfo() noexcept : value(0) {} constexpr bitInfo() noexcept : value(0) {}
//- Value construct //- Value construct
explicit bitInfo(UIntType val) : value(val) {} explicit bitInfo(UIntType val) noexcept : value(val) {}
//- Conversion to base type //- Conversion to base type
operator UIntType () const { return value; } operator UIntType () const noexcept { return value; }
//- Conversion to base type //- Conversion to base type
operator UIntType& () { return value; } operator UIntType& () noexcept { return value; }
}; };
} // End namespace BitOps } // End namespace BitOps

View File

@ -149,6 +149,10 @@ public:
//- if the key does not exist in the table. //- if the key does not exist in the table.
inline const T* get(const Key& key) const; inline const T* get(const Key& key) const;
//- Return pointer associated with given entry or a nullptr
//- if the key does not exist in the table.
inline T* get(const Key& key);
// Edit // Edit
@ -234,7 +238,9 @@ public:
inline bool emplace(const Key& key, Args&&... args); inline bool emplace(const Key& key, Args&&... args);
//- Emplace set an entry, overwriting any existing entries. //- Emplace set an entry, overwriting any existing entries.
// \return Reference to the new element. // \param key - the location to set
// \param args arguments to forward to the constructor of the element
// \return reference to the new element.
template<class... Args> template<class... Args>
inline T& emplace_set(const Key& key, Args&&... args); inline T& emplace_set(const Key& key, Args&&... args);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018-2023 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -57,6 +57,19 @@ inline const T* Foam::HashPtrTable<T, Key, Hash>::get(const Key& key) const
} }
template<class T, class Key, class Hash>
inline T* Foam::HashPtrTable<T, Key, Hash>::get(const Key& key)
{
// Like lookup() with a nullptr + const_cast
iterator iter(this->find(key));
if (iter.good())
{
return iter.val();
}
return nullptr;
}
template<class T, class Key, class Hash> template<class T, class Key, class Hash>
template<class... Args> template<class... Args>
inline bool Foam::HashPtrTable<T, Key, Hash>::emplace inline bool Foam::HashPtrTable<T, Key, Hash>::emplace

View File

@ -255,7 +255,7 @@ public:
// Edit // Edit
//- Swap with plain List content. Implies shrink_to_fit(). //- Swap with plain List content. Implies shrink_to_fit().
inline void swap(List<T>& list); inline void swap(List<T>& other);
//- Swap content, independent of sizing parameter //- Swap content, independent of sizing parameter
template<int AnySizeMin> template<int AnySizeMin>
@ -264,7 +264,7 @@ public:
//- Transfer contents of the argument List into this. //- Transfer contents of the argument List into this.
inline void transfer(List<T>& list); inline void transfer(List<T>& list);
//- Transfer contents of any sized DynamicList into this. //- Transfer contents of any DynamicList into this.
template<int AnySizeMin> template<int AnySizeMin>
inline void transfer(DynamicList<T, AnySizeMin>& list); inline void transfer(DynamicList<T, AnySizeMin>& list);

View File

@ -445,6 +445,8 @@ inline void Foam::DynamicList<T, SizeMin>::clear() noexcept
template<class T, int SizeMin> template<class T, int SizeMin>
inline void Foam::DynamicList<T, SizeMin>::clearStorage() inline void Foam::DynamicList<T, SizeMin>::clearStorage()
{ {
// Consistent allocated sizing
List<T>::setAddressableSize(capacity_);
List<T>::clear(); List<T>::clear();
capacity_ = 0; capacity_ = 0;
} }
@ -465,12 +467,15 @@ inline void Foam::DynamicList<T, SizeMin>::shrink_to_fit()
template<class T, int SizeMin> template<class T, int SizeMin>
inline void inline void
Foam::DynamicList<T, SizeMin>::swap(List<T>& list) Foam::DynamicList<T, SizeMin>::swap(List<T>& other)
{ {
if if
(
FOAM_UNLIKELY
( (
static_cast<const List<T>*>(this) static_cast<const List<T>*>(this)
== static_cast<const List<T>*>(&list) == static_cast<const List<T>*>(&other)
)
) )
{ {
return; // Self-swap is a no-op return; // Self-swap is a no-op
@ -480,7 +485,7 @@ Foam::DynamicList<T, SizeMin>::swap(List<T>& list)
this->shrink_to_fit(); this->shrink_to_fit();
// Swap storage and addressable size // Swap storage and addressable size
UList<T>::swap(list); UList<T>::swap(other);
// Update capacity // Update capacity
capacity_ = List<T>::size(); capacity_ = List<T>::size();
@ -495,10 +500,13 @@ inline void Foam::DynamicList<T, SizeMin>::swap
) noexcept ) noexcept
{ {
if if
(
FOAM_UNLIKELY
( (
static_cast<const List<T>*>(this) static_cast<const List<T>*>(this)
== static_cast<const List<T>*>(&other) == static_cast<const List<T>*>(&other)
) )
)
{ {
return; // Self-swap is a no-op return; // Self-swap is a no-op
} }
@ -515,6 +523,10 @@ template<class T, int SizeMin>
inline void inline void
Foam::DynamicList<T, SizeMin>::transfer(List<T>& list) Foam::DynamicList<T, SizeMin>::transfer(List<T>& list)
{ {
// No check for self-assignment (different types)
// Consistent allocated sizing
List<T>::setAddressableSize(capacity_);
List<T>::transfer(list); List<T>::transfer(list);
capacity_ = List<T>::size(); capacity_ = List<T>::size();
} }
@ -529,19 +541,23 @@ Foam::DynamicList<T, SizeMin>::transfer
) )
{ {
if if
(
FOAM_UNLIKELY
( (
static_cast<const List<T>*>(this) static_cast<const List<T>*>(this)
== static_cast<const List<T>*>(&list) == static_cast<const List<T>*>(&list)
) )
)
{ {
return; // Self-assignment is a no-op return; // Self-assignment is a no-op
} }
// Take over storage as-is (without shrink) // Consistent allocated sizing
capacity_ = list.capacity(); List<T>::setAddressableSize(capacity_);
List<T>::transfer(static_cast<List<T>&>(list)); List<T>::transfer(static_cast<List<T>&>(list));
list.clearStorage(); // capacity=0 etc.
capacity_ = list.capacity();
list.setCapacity_unsafe(0); // All contents moved
} }
@ -594,7 +610,14 @@ inline void Foam::DynamicList<T, SizeMin>::push_back
const UList<T>& list const UList<T>& list
) )
{ {
if (FOAM_UNLIKELY(this == &list)) if
(
FOAM_UNLIKELY
(
static_cast<const List<T>*>(this)
== static_cast<const List<T>*>(&list)
)
)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Attempted push_back to self" << "Attempted push_back to self"
@ -665,7 +688,14 @@ inline void Foam::DynamicList<T, SizeMin>::push_back
List<T>&& list List<T>&& list
) )
{ {
if (FOAM_UNLIKELY(this == &list)) if
(
FOAM_UNLIKELY
(
static_cast<const List<T>*>(this)
== static_cast<const List<T>*>(&list)
)
)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Attempted push_back to self" << "Attempted push_back to self"
@ -675,6 +705,7 @@ inline void Foam::DynamicList<T, SizeMin>::push_back
const label idx = List<T>::size(); const label idx = List<T>::size();
resize(idx + list.size()); resize(idx + list.size());
// Move the elements
std::move(list.begin(), list.end(), this->begin(idx)); std::move(list.begin(), list.end(), this->begin(idx));
list.clear(); list.clear();
@ -688,7 +719,26 @@ inline void Foam::DynamicList<T, SizeMin>::push_back
DynamicList<T, AnySizeMin>&& list DynamicList<T, AnySizeMin>&& list
) )
{ {
push_back(std::move(static_cast<List<T>&>(list))); if
(
FOAM_UNLIKELY
(
static_cast<const List<T>*>(this)
== static_cast<const List<T>*>(&list)
)
)
{
FatalErrorInFunction
<< "Attempted push_back to self"
<< abort(FatalError);
}
const label idx = List<T>::size();
resize(idx + list.size());
// Move the elements
std::move(list.begin(), list.end(), this->begin(idx));
list.clearStorage(); // Deletion, capacity=0 etc. list.clearStorage(); // Deletion, capacity=0 etc.
} }
@ -866,15 +916,22 @@ inline void Foam::DynamicList<T, SizeMin>::operator=
template<class T, int SizeMin> template<class T, int SizeMin>
inline void Foam::DynamicList<T, SizeMin>::operator= inline void Foam::DynamicList<T, SizeMin>::operator=
( (
const DynamicList<T, SizeMin>& lst const DynamicList<T, SizeMin>& list
) )
{ {
if (this == &lst) if
(
FOAM_UNLIKELY
(
static_cast<const List<T>*>(this)
== static_cast<const List<T>*>(&list)
)
)
{ {
return; // Self-assignment is a no-op return; // Self-assignment is a no-op
} }
doAssignDynList(lst); doAssignDynList(list);
} }
@ -886,10 +943,13 @@ inline void Foam::DynamicList<T, SizeMin>::operator=
) )
{ {
if if
(
FOAM_UNLIKELY
( (
static_cast<const List<T>*>(this) static_cast<const List<T>*>(this)
== static_cast<const List<T>*>(&list) == static_cast<const List<T>*>(&list)
) )
)
{ {
return; // Self-assignment is a no-op return; // Self-assignment is a no-op
} }
@ -912,44 +972,41 @@ template<class T, int SizeMin>
template<class Addr> template<class Addr>
inline void Foam::DynamicList<T, SizeMin>::operator= inline void Foam::DynamicList<T, SizeMin>::operator=
( (
const IndirectListBase<T, Addr>& lst const IndirectListBase<T, Addr>& list
) )
{ {
// NOTE: Self-assignment needs special handling // NOTE: Self-assignment needs special handling
/// if // if
/// ( // (
/// static_cast<const UList<T>*>(this) // FOAM_UNLIKELY
/// == static_cast<const UList<T>*>(&list.values()) // (
/// ) // static_cast<const UList<T>*>(this)
// == static_cast<const UList<T>*>(&list.values())
// )
// )
// { ... }
doAssignDynList(lst); doAssignDynList(list);
} }
template<class T, int SizeMin> template<class T, int SizeMin>
inline void Foam::DynamicList<T, SizeMin>::operator= inline void Foam::DynamicList<T, SizeMin>::operator=
( (
List<T>&& lst List<T>&& list
) )
{ {
clear(); this->transfer(list);
transfer(lst);
} }
template<class T, int SizeMin> template<class T, int SizeMin>
inline void Foam::DynamicList<T, SizeMin>::operator= inline void Foam::DynamicList<T, SizeMin>::operator=
( (
DynamicList<T, SizeMin>&& lst DynamicList<T, SizeMin>&& list
) )
{ {
if (this == &lst) this->transfer(list);
{
return; // Self-assignment is a no-op
}
clear();
transfer(lst);
} }
@ -960,17 +1017,7 @@ inline void Foam::DynamicList<T, SizeMin>::operator=
DynamicList<T, AnySizeMin>&& list DynamicList<T, AnySizeMin>&& list
) )
{ {
if this->transfer(list);
(
static_cast<const List<T>*>(this)
== static_cast<const List<T>*>(&list)
)
{
return; // Self-assignment is a no-op
}
clear();
transfer(list);
} }

View File

@ -169,8 +169,8 @@ template<class T, unsigned N>
bool Foam::FixedList<T, N>::operator==(const FixedList<T, N>& list) const bool Foam::FixedList<T, N>::operator==(const FixedList<T, N>& list) const
{ {
// Can dispatch with // Can dispatch with
// - std::execution::parallel_unsequenced_policy // - std::execution::par_unseq
// - std::execution::unsequenced_policy // - std::execution::unseq
return return
( (
// List sizes are identical by definition (template parameter) // List sizes are identical by definition (template parameter)
@ -185,8 +185,8 @@ bool Foam::FixedList<T, N>::operator<(const FixedList<T, N>& list) const
// List sizes are identical by definition (template parameter) // List sizes are identical by definition (template parameter)
// Can dispatch with // Can dispatch with
// - std::execution::parallel_unsequenced_policy // - std::execution::par_unseq
// - std::execution::unsequenced_policy // - std::execution::unseq
return std::lexicographical_compare return std::lexicographical_compare
( (
this->cbegin(), this->cend(), this->cbegin(), this->cend(),

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2023 OpenCFD Ltd. Copyright (C) 2017-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -356,12 +356,17 @@ inline void Foam::FixedList<T, N>::fill(const T& val)
template<class T, unsigned N> template<class T, unsigned N>
inline void Foam::FixedList<T, N>::fill(Foam::zero) inline void Foam::FixedList<T, N>::fill(Foam::zero)
{ {
if constexpr (std::is_arithmetic_v<T>)
{
// Usually small enough that parallel execution is pointless... // Usually small enough that parallel execution is pointless...
// Cannot use std::fill (ambiguous conversions for bool, char, etc) std::fill_n(v_, N, T(0));
}
else
{
for (unsigned i = 0; i < N; ++i) for (unsigned i = 0; i < N; ++i)
{ {
v_[i] = Zero; v_[i] = Foam::zero{};
}
} }
} }

View File

@ -113,8 +113,8 @@ void Foam::UList<T>::deepCopy(const UList<T>& list)
else if (this->size_ > 0) else if (this->size_ > 0)
{ {
// Can dispatch with // Can dispatch with
// - std::execution::parallel_unsequenced_policy // - std::execution::par_unseq
// - std::execution::unsequenced_policy // - std::execution::unseq
std::copy(list.cbegin(), list.cend(), this->v_); std::copy(list.cbegin(), list.cend(), this->v_);
} }
} }
@ -150,16 +150,6 @@ void Foam::UList<T>::deepCopy(const IndirectListBase<T, Addr>& list)
} }
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
// This is non-inlined to allow template specializations
template<class T>
void Foam::UList<T>::operator=(Foam::zero)
{
this->fill_uniform(Foam::zero{});
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T> template<class T>
@ -244,8 +234,8 @@ template<class T>
bool Foam::UList<T>::operator==(const UList<T>& list) const bool Foam::UList<T>::operator==(const UList<T>& list) const
{ {
// Can dispatch with // Can dispatch with
// - std::execution::parallel_unsequenced_policy // - std::execution::par_unseq
// - std::execution::unsequenced_policy // - std::execution::unseq
return return
( (
(this->size_ == list.size_) (this->size_ == list.size_)
@ -265,8 +255,8 @@ template<class T>
bool Foam::UList<T>::operator<(const UList<T>& list) const bool Foam::UList<T>::operator<(const UList<T>& list) const
{ {
// Can dispatch with // Can dispatch with
// - std::execution::parallel_unsequenced_policy // - std::execution::par_unseq
// - std::execution::unsequenced_policy // - std::execution::unseq
return std::lexicographical_compare return std::lexicographical_compare
( (
this->cbegin(), this->cend(), this->cbegin(), this->cend(),

View File

@ -435,7 +435,7 @@ public:
inline void operator=(const T& val); inline void operator=(const T& val);
//- Assignment of all entries to zero //- Assignment of all entries to zero
void operator=(Foam::zero); inline void operator=(Foam::zero);
// Random access iterator (non-const) // Random access iterator (non-const)
@ -565,11 +565,38 @@ public:
// Special Methods // Special Methods
//- True if all entries are 'true' or if the list is empty.
// \note Method name compatibility with bitSet
template<class TypeT = T>
std::enable_if_t<std::is_same_v<bool, std::remove_cv_t<TypeT>>, bool>
inline all() const
{
return !contains(false);
}
//- True if any entries are 'true'.
// \note Method name compatibility with bitSet
template<class TypeT = T>
std::enable_if_t<std::is_same_v<bool, std::remove_cv_t<TypeT>>, bool>
inline any() const
{
return contains(true);
}
//- True if no entries are 'true'.
// \note Method name compatibility with bitSet
template<class TypeT = T>
std::enable_if_t<std::is_same_v<bool, std::remove_cv_t<TypeT>>, bool>
inline none() const
{
return !contains(true);
}
//- Test \c bool value at specified position, //- Test \c bool value at specified position,
//- always false for out-of-range access. //- always false for out-of-range access.
// \note Method name compatibility with bitSet, HashSet // \note Method name compatibility with bitSet, HashSet
template<class TypeT = T> template<class TypeT = T>
std::enable_if_t<std::is_same_v<bool, TypeT>, bool> std::enable_if_t<std::is_same_v<bool, std::remove_cv_t<TypeT>>, bool>
inline test(const label i) const inline test(const label i) const
{ {
return (i >= 0 && i < size_ && v_[i]); return (i >= 0 && i < size_ && v_[i]);
@ -579,7 +606,7 @@ public:
//- always false for out-of-range access. //- always false for out-of-range access.
// \note Method name compatibility with bitSet // \note Method name compatibility with bitSet
template<class TypeT = T> template<class TypeT = T>
std::enable_if_t<std::is_same_v<bool, TypeT>, bool> std::enable_if_t<std::is_same_v<bool, std::remove_cv_t<TypeT>>, bool>
inline get(const label i) const inline get(const label i) const
{ {
return (i >= 0 && i < size_ && v_[i]); return (i >= 0 && i < size_ && v_[i]);
@ -664,17 +691,6 @@ public:
}; };
// * * * * * * * * * * * * Template Specializations * * * * * * * * * * * * //
//- Character list writeEntry
template<>
void UList<char>::writeEntry(Ostream& os) const;
//- Character list assign zero - avoids Foam::zero casting ambiguities
template<>
void UList<char>::operator=(Foam::zero);
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
//- Read List contents from Istream, list must have the proper size! //- Read List contents from Istream, list must have the proper size!

View File

@ -53,8 +53,8 @@ template<class T>
inline void Foam::UList<T>::fill_uniform(const T& val) inline void Foam::UList<T>::fill_uniform(const T& val)
{ {
// Can dispatch with // Can dispatch with
// - std::execution::parallel_unsequenced_policy // - std::execution::par_unseq
// - std::execution::unsequenced_policy // - std::execution::unseq
std::fill_n std::fill_n
( (
this->v_, this->size_, val this->v_, this->size_, val
@ -65,15 +65,21 @@ inline void Foam::UList<T>::fill_uniform(const T& val)
template<class T> template<class T>
inline void Foam::UList<T>::fill_uniform(Foam::zero) inline void Foam::UList<T>::fill_uniform(Foam::zero)
{ {
// Note: ambiguous conversions for char can still cause compilation if constexpr (std::is_arithmetic_v<T>)
// issues.
// May also have special triggers when assigning non-contiguous from zero...
if constexpr (is_contiguous_v<T>)
{ {
// Can dispatch with // Can dispatch with
// - std::execution::parallel_unsequenced_policy // - std::execution::par_unseq
// - std::execution::unsequenced_policy // - std::execution::unseq
std::fill_n
(
this->v_, this->size_, T(0)
);
}
else if constexpr (is_contiguous_v<T>)
{
// Can dispatch with
// - std::execution::par_unseq
// - std::execution::unseq
std::fill_n std::fill_n
( (
this->data_bytes(), this->size_bytes(), char(0) this->data_bytes(), this->size_bytes(), char(0)
@ -81,6 +87,9 @@ inline void Foam::UList<T>::fill_uniform(Foam::zero)
} }
else else
{ {
// May also have special triggers when assigning non-contiguous
// from zero...
const auto last = (this->v_ + this->size_); const auto last = (this->v_ + this->size_);
for (auto first = this->v_; (first != last); (void)++first) for (auto first = this->v_; (first != last); (void)++first)
@ -348,29 +357,34 @@ inline void Foam::UList<T>::operator=(const T& val)
} }
namespace Foam // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
{
// Template specialization for bool
template<>
inline const bool& Foam::UList<bool>::operator[](const label i) const
{
// Lazy evaluation - return false for out-of-range
if (i >= 0 && i < size_)
{
return v_[i];
}
return Foam::pTraits<bool>::zero; template<class T>
} inline void Foam::UList<T>::operator=(Foam::zero)
} // End namespace Foam {
this->fill_uniform(Foam::zero{});
}
template<class T> template<class T>
inline T& Foam::UList<T>::operator[](const label i) inline T& Foam::UList<T>::operator[](const label i)
{ {
if constexpr (std::is_same_v<bool, std::remove_cv_t<T>>)
{
// Lazy evaluation - return false for out-of-range
// Note: strictly speaking should not be modifiable but we cannot
// alway control which signature (const or non-const) is called
if (i < 0 || i >= size_)
{
return const_cast<bool&>(Foam::pTraits<bool>::null());
}
}
else
{
#ifdef FULLDEBUG #ifdef FULLDEBUG
checkIndex(i); checkIndex(i);
#endif #endif
}
return v_[i]; return v_[i];
} }
@ -378,9 +392,20 @@ inline T& Foam::UList<T>::operator[](const label i)
template<class T> template<class T>
inline const T& Foam::UList<T>::operator[](const label i) const inline const T& Foam::UList<T>::operator[](const label i) const
{ {
if constexpr (std::is_same_v<bool, std::remove_cv_t<T>>)
{
// Lazy evaluation - return false for out-of-range
if (i < 0 || i >= size_)
{
return Foam::pTraits<bool>::null();
}
}
else
{
#ifdef FULLDEBUG #ifdef FULLDEBUG
checkIndex(i); checkIndex(i);
#endif #endif
}
return v_[i]; return v_[i];
} }

View File

@ -35,6 +35,25 @@ License
template<class T> template<class T>
void Foam::UList<T>::writeEntry(Ostream& os) const void Foam::UList<T>::writeEntry(Ostream& os) const
{ {
if constexpr (std::is_same_v<char, std::remove_cv_t<T>>)
{
// Char data has a compound type:
os << word("List<char>");
if (this->size())
{
// Non-zero size: write as binary, so has leading newline separator.
os << *this;
}
else
{
// Zero-sized binary - Write size only
// Note that char data is always binary I/O only
os << token::SPACE << label(0);
}
}
else
{
const word tag("List<" + word(pTraits<T>::typeName) + '>'); const word tag("List<" + word(pTraits<T>::typeName) + '>');
if (token::compound::isCompound(tag)) if (token::compound::isCompound(tag))
{ {
@ -45,14 +64,9 @@ void Foam::UList<T>::writeEntry(Ostream& os) const
{ {
os << *this; os << *this;
} }
else if else if (os.format() == IOstreamOption::BINARY)
(
os.format() == IOstreamOption::BINARY
|| std::is_same_v<char, std::remove_cv_t<T>>
)
{ {
// Zero-sized binary - Write size only // Zero-sized binary - Write size only
// NB: special treatment for char data (binary I/O only)
os << label(0); os << label(0);
} }
else else
@ -60,6 +74,7 @@ void Foam::UList<T>::writeEntry(Ostream& os) const
// Zero-sized ASCII - Write size and delimiters // Zero-sized ASCII - Write size and delimiters
os << label(0) << token::BEGIN_LIST << token::END_LIST; os << label(0) << token::BEGIN_LIST << token::END_LIST;
} }
}
} }

View File

@ -658,6 +658,18 @@ inline void identity(labelUList& map, label start = 0)
} }
//- Count the occurrences of the given element.
// When start is specified, any occurrences before start are ignored.
// Like std::count but works with list indexing
template<class ListType>
label count
(
const ListType& input,
typename ListType::const_reference val,
const label start=0
);
//- Count the number of matching entries. //- Count the number of matching entries.
// When start is specified, any occurrences before start are ignored. // When start is specified, any occurrences before start are ignored.
// Linear search. // Linear search.

View File

@ -1154,6 +1154,33 @@ bool Foam::ListOps::equal
} }
template<class ListType>
Foam::label Foam::ListOps::count
(
const ListType& input,
typename ListType::const_reference val,
const label start
)
{
label num = 0;
const label len = input.size();
if (start >= 0)
{
for (label i = start; i < len; ++i)
{
if (val == input[i])
{
++num;
}
}
}
return num;
}
template<class ListType, class UnaryPredicate> template<class ListType, class UnaryPredicate>
Foam::label Foam::ListOps::count_if Foam::label Foam::ListOps::count_if
( (

View File

@ -238,14 +238,18 @@ public:
//- Auto-sizes list as required. //- Auto-sizes list as required.
inline autoPtr<T> set(const label i, const tmp<T>& ptr); inline autoPtr<T> set(const label i, const tmp<T>& ptr);
//- Reorder elements. Reordering must be unique (ie, shuffle).
inline void reorder(const labelUList& oldToNew); // Writing
//- Print pointer addresses to Ostream (debugging only).
// Optionally print addresses within the upper (capacity) region
Ostream& printAddresses(Ostream& os, const bool full=false) const;
// Member Operators // Member Operators
//- Copy (clone) assignment //- Copy (clone) assignment
inline void operator=(const PtrList<T>& list); inline void operator=(const UPtrList<T>& list);
//- Copy (clone) assignment //- Copy (clone) assignment
inline void operator=(const PtrDynList<T, SizeMin>& list); inline void operator=(const PtrDynList<T, SizeMin>& list);

View File

@ -226,6 +226,8 @@ inline void Foam::PtrDynList<T, SizeMin>::clear()
template<class T, int SizeMin> template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::clearStorage() inline void Foam::PtrDynList<T, SizeMin>::clearStorage()
{ {
// Consistent allocated sizing
PtrList<T>::setAddressableSize(capacity_);
PtrList<T>::clear(); PtrList<T>::clear();
capacity_ = 0; capacity_ = 0;
} }
@ -257,10 +259,13 @@ template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::swap(PtrList<T>& list) inline void Foam::PtrDynList<T, SizeMin>::swap(PtrList<T>& list)
{ {
if if
(
FOAM_UNLIKELY
( (
static_cast<const PtrList<T>*>(this) static_cast<const PtrList<T>*>(this)
== static_cast<const PtrList<T>*>(&list) == static_cast<const PtrList<T>*>(&list)
) )
)
{ {
return; // Self-swap is a no-op return; // Self-swap is a no-op
} }
@ -284,10 +289,13 @@ inline void Foam::PtrDynList<T, SizeMin>::swap
) noexcept ) noexcept
{ {
if if
(
FOAM_UNLIKELY
( (
static_cast<const PtrList<T>*>(this) static_cast<const PtrList<T>*>(this)
== static_cast<const PtrList<T>*>(&other) == static_cast<const PtrList<T>*>(&other)
) )
)
{ {
return; // Self-swap is a no-op return; // Self-swap is a no-op
} }
@ -303,15 +311,10 @@ inline void Foam::PtrDynList<T, SizeMin>::swap
template<class T, int SizeMin> template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::transfer(PtrList<T>& list) inline void Foam::PtrDynList<T, SizeMin>::transfer(PtrList<T>& list)
{ {
if // No check for self-assignment (different types)
(
static_cast<const PtrList<T>*>(this)
== static_cast<const PtrList<T>*>(&list)
)
{
return; // Self assignment is a no-op
}
// Consistent allocated sizing
PtrList<T>::setAddressableSize(capacity_);
PtrList<T>::transfer(list); PtrList<T>::transfer(list);
capacity_ = PtrList<T>::size(); capacity_ = PtrList<T>::size();
} }
@ -325,19 +328,23 @@ inline void Foam::PtrDynList<T, SizeMin>::transfer
) )
{ {
if if
(
FOAM_UNLIKELY
( (
static_cast<const PtrList<T>*>(this) static_cast<const PtrList<T>*>(this)
== static_cast<const PtrList<T>*>(&list) == static_cast<const PtrList<T>*>(&list)
) )
)
{ {
return; // Self assignment is a no-op return; // Self assignment is a no-op
} }
// Take over storage as-is (without shrink) // Consistent allocated sizing
capacity_ = list.capacity(); PtrList<T>::setAddressableSize(capacity_);
PtrList<T>::transfer(static_cast<PtrList<T>&>(list)); PtrList<T>::transfer(static_cast<PtrList<T>&>(list));
list.clearStorage(); // capacity=0 etc.
capacity_ = list.capacity();
list.setCapacity_unsafe(0); // All contents moved
} }
@ -413,10 +420,13 @@ inline void Foam::PtrDynList<T, SizeMin>::push_back
) )
{ {
if if
(
FOAM_UNLIKELY
( (
static_cast<const PtrList<T>*>(this) static_cast<const PtrList<T>*>(this)
== static_cast<const PtrList<T>*>(&other) == static_cast<const PtrList<T>*>(&other)
) )
)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Attempted push_back to self" << "Attempted push_back to self"
@ -557,11 +567,20 @@ inline Foam::autoPtr<T> Foam::PtrDynList<T, SizeMin>::set
template<class T, int SizeMin> template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::reorder(const labelUList& oldToNew) Foam::Ostream& Foam::PtrDynList<T, SizeMin>::printAddresses
(
Ostream& os,
const bool full
) const
{ {
// Shrinking first is a bit annoying, but saves needing a special version. if (full)
this->shrink_to_fit(); {
PtrList<T>::reorder(oldToNew); return this->ptrs_.printAddresses(os, capacity_);
}
else
{
return UPtrList<T>::printAddresses(os);
}
} }
@ -570,16 +589,23 @@ inline void Foam::PtrDynList<T, SizeMin>::reorder(const labelUList& oldToNew)
template<class T, int SizeMin> template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::operator= inline void Foam::PtrDynList<T, SizeMin>::operator=
( (
const PtrList<T>& list const UPtrList<T>& list
) )
{ {
if (this == &list) if
(
FOAM_UNLIKELY
(
static_cast<const UPtrList<T>*>(this)
== static_cast<const UPtrList<T>*>(&list)
)
)
{ {
return; // Self-assignment is a no-op return; // Self-assignment is a no-op
} }
this->resize(list.size());
PtrList<T>::operator=(list); PtrList<T>::operator=(list);
capacity_ = PtrList<T>::size();
} }
@ -589,13 +615,20 @@ inline void Foam::PtrDynList<T, SizeMin>::operator=
const PtrDynList<T, SizeMin>& list const PtrDynList<T, SizeMin>& list
) )
{ {
if (this == &list) if
(
FOAM_UNLIKELY
(
static_cast<const UPtrList<T>*>(this)
== static_cast<const UPtrList<T>*>(&list)
)
)
{ {
return; // Self-assignment is a no-op return; // Self-assignment is a no-op
} }
PtrList<T>::operator=(list); this->resize(list.size());
capacity_ = PtrList<T>::size(); PtrList<T>::operator=(static_cast<UPtrList<T>&>(list));
} }
@ -607,15 +640,19 @@ inline void Foam::PtrDynList<T, SizeMin>::operator=
) )
{ {
if if
(
FOAM_UNLIKELY
( (
static_cast<const PtrList<T>*>(this) static_cast<const PtrList<T>*>(this)
== static_cast<const PtrList<T>*>(&list) == static_cast<const PtrList<T>*>(&list)
) )
)
{ {
return; // Self-assignment is a no-op return; // Self-assignment is a no-op
} }
PtrList<T>::operator=(list); this->resize(list.size());
PtrList<T>::operator=(static_cast<UPtrList<T>&>(list));
capacity_ = PtrList<T>::size(); capacity_ = PtrList<T>::size();
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2019 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -29,26 +29,55 @@ License
#include "PtrList.H" #include "PtrList.H"
#include "SLPtrList.H" #include "SLPtrList.H"
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class T> template<class T>
Foam::PtrList<T>::PtrList(PtrList<T>& list, bool reuse) template<bool CheckSelf>
: void Foam::PtrList<T>::copyPtrList(const UPtrList<T>& list)
UPtrList<T>(list, reuse)
{ {
if (!reuse) // Check for self-assignment here instead of caller
if constexpr (CheckSelf)
{ {
// This works like an inplace clone method if (FOAM_UNLIKELY(this == &list))
const label len = this->size(); {
return; // Self-assignment is a no-op
}
}
for (label i=0; i<len; ++i) const label len = list.size();
// Truncate (frees old pointers) or extend the length
PtrList<T>::resize(len);
for (label i = 0; i < len; ++i)
{ {
this->ptrs_[i] = (list[i]).clone().ptr(); const T* src = list.get(i);
if (src)
{
if (this->ptrs_[i])
{
// Deep copy values into existing destination
*(this->ptrs_[i]) = *src;
}
else
{
// Clone pointers for new entries
this->ptrs_[i] = src->clone().ptr();
}
}
else
{
// No source pointer, so remove destination (if any) too
delete this->ptrs_[i];
this->ptrs_[i] = nullptr;
} }
} }
} }
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
template<class T> template<class T>
Foam::PtrList<T>::PtrList(const SLPtrList<T>& list) Foam::PtrList<T>::PtrList(const SLPtrList<T>& list)
: :
@ -122,45 +151,4 @@ void Foam::PtrList<T>::resize(const label newLen)
} }
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class T>
void Foam::PtrList<T>::operator=(const PtrList<T>& list)
{
if (this == &list)
{
return; // Self-assignment is a no-op
}
const label oldLen = this->size();
const label newLen = list.size();
// Truncate (frees old pointers) or extend the length
resize(newLen);
if (newLen < oldLen)
{
// Copy values for existing entries
for (label i=0; i<newLen; ++i)
{
(*this)[i] = list[i];
}
}
else
{
// Copy values for existing entries
for (label i=0; i<oldLen; ++i)
{
(*this)[i] = list[i];
}
// Clone pointers for new entries
for (label i=oldLen; i<newLen; ++i)
{
this->ptrs_[i] = (list[i]).clone().ptr();
}
}
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2023 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -70,6 +70,15 @@ class PtrList
: :
public UPtrList<T> public UPtrList<T>
{ {
// Private Member Functions
//- Copy assignment.
// For existing list entries, values are copied from the list.
// For new list entries, pointers are cloned from the list.
template<bool CheckSelf>
void copyPtrList(const UPtrList<T>& list);
protected: protected:
// Protected Member Functions // Protected Member Functions
@ -103,7 +112,7 @@ public:
inline PtrList(const PtrList<T>& list, const CloneArg& cloneArgs); inline PtrList(const PtrList<T>& list, const CloneArg& cloneArgs);
//- Construct as copy or re-use as specified //- Construct as copy or re-use as specified
PtrList(PtrList<T>& list, bool reuse); inline PtrList(PtrList<T>& list, bool reuse);
//- Copy construct using 'clone()' on each element of SLPtrList\<T\> //- Copy construct using 'clone()' on each element of SLPtrList\<T\>
explicit PtrList(const SLPtrList<T>& list); explicit PtrList(const SLPtrList<T>& list);
@ -221,6 +230,11 @@ public:
// Member Operators // Member Operators
//- Copy assignment.
// For existing list entries, values are copied from the list.
// For new list entries, pointers are cloned from the list.
void operator=(const UPtrList<T>& list);
//- Copy assignment. //- Copy assignment.
// For existing list entries, values are copied from the list. // For existing list entries, values are copied from the list.
// For new list entries, pointers are cloned from the list. // For new list entries, pointers are cloned from the list.

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2023 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -60,6 +60,23 @@ inline Foam::PtrList<T>::PtrList(PtrList<T>&& list) noexcept
{} {}
template<class T>
inline Foam::PtrList<T>::PtrList(PtrList<T>& list, bool reuse)
:
UPtrList<T>()
{
if (reuse)
{
transfer(list);
}
else
{
// No check for self-assignment
copyPtrList<false>(list);
}
}
template<class T> template<class T>
inline Foam::PtrList<T>::PtrList(UList<T*>& list) inline Foam::PtrList<T>::PtrList(UList<T*>& list)
: :
@ -278,7 +295,7 @@ inline Foam::autoPtr<T> Foam::PtrList<T>::release(const label i)
template<class T> template<class T>
inline void Foam::PtrList<T>::transfer(PtrList<T>& list) inline void Foam::PtrList<T>::transfer(PtrList<T>& list)
{ {
if (this == &list) if (FOAM_UNLIKELY(this == &list))
{ {
return; // Self-assignment is a no-op return; // Self-assignment is a no-op
} }
@ -290,6 +307,22 @@ inline void Foam::PtrList<T>::transfer(PtrList<T>& list)
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class T>
inline void Foam::PtrList<T>::operator=(const UPtrList<T>& list)
{
// With check for self-assignment
this->copyPtrList<true>(list);
}
template<class T>
inline void Foam::PtrList<T>::operator=(const PtrList<T>& list)
{
// With check for self-assignment
this->copyPtrList<true>(list);
}
template<class T> template<class T>
inline void Foam::PtrList<T>::operator=(PtrList<T>&& list) inline void Foam::PtrList<T>::operator=(PtrList<T>&& list)
{ {

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018-2024 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -99,11 +99,10 @@ Foam::label Foam::Detail::PtrListDetail<T>::find_next_not(label pos) const
template<class T> template<class T>
void Foam::Detail::PtrListDetail<T>::free() void Foam::Detail::PtrListDetail<T>::free()
{ {
List<T*>& ptrs = *this;
const label len = ptrs.size();
// Presume they were allocated from front to back... // Presume they were allocated from front to back...
for (label i = len - 1; i >= 0; --i) List<T*>& ptrs = *this;
for (auto i = this->size()-1; i >= 0; --i)
{ {
delete ptrs[i]; delete ptrs[i];
ptrs[i] = nullptr; ptrs[i] = nullptr;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018-2024 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -147,6 +147,10 @@ public:
// Use with care // Use with care
inline void setAddressableSize(const label n) noexcept; inline void setAddressableSize(const label n) noexcept;
//- Write pointer values to Ostream (debugging only).
// Optionally allow addressing beyond the regular range
Ostream& printAddresses(Ostream& os, label maxLen = -1) const;
//- Write output, optionally silently trimming nullptrs //- Write output, optionally silently trimming nullptrs
Ostream& write(Ostream& os, const bool trimNull=false) const; Ostream& write(Ostream& os, const bool trimNull=false) const;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018-2024 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -31,6 +31,45 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
Foam::Ostream& Foam::Detail::PtrListDetail<T>::printAddresses
(
Ostream& os,
label maxLen
) const
{
if (maxLen <= 0)
{
maxLen = this->size();
}
const label len = Foam::min(this->size(), maxLen);
// The (output) size and start delimiter
os << nl << indent << maxLen << nl
<< indent << token::BEGIN_LIST << nl;
// const T* const * iter = this->cdata();
const auto* iter = this->cdata();
// Contents
for (label i = 0; i < len; ++i)
{
os << indent << " " << Foam::name(iter[i]) << nl;
}
for (label i = len; i < maxLen; ++i)
{
os << indent << " [" << Foam::name(iter[i]) << ']' << nl;
}
// End delimiter
os << indent << token::END_LIST << nl;
os.check(FUNCTION_NAME);
return os;
}
template<class T> template<class T>
Foam::Ostream& Foam::Detail::PtrListDetail<T>::write Foam::Ostream& Foam::Detail::PtrListDetail<T>::write
( (

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2015-2022 OpenCFD Ltd. Copyright (C) 2015-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -65,23 +65,6 @@ Foam::label Foam::UPtrList<T>::squeezeNull()
} }
template<class T>
void Foam::UPtrList<T>::trimTrailingNull()
{
label newLen = this->size();
for (label i = newLen-1; i >= 0 && !ptrs_[i]; --i)
{
--newLen;
}
// Or mutable?
// const_cast<Detail::PtrListDetail<T>&>(ptrs_).setAddressableSize(newLen);
ptrs_.setAddressableSize(newLen);
}
template<class T> template<class T>
void Foam::UPtrList<T>::reorder(const labelUList& oldToNew, const bool check) void Foam::UPtrList<T>::reorder(const labelUList& oldToNew, const bool check)
{ {
@ -98,7 +81,7 @@ void Foam::UPtrList<T>::reorder(const labelUList& oldToNew, const bool check)
Detail::PtrListDetail<T> newList(len); Detail::PtrListDetail<T> newList(len);
for (label i=0; i<len; ++i) for (label i = 0; i < len; ++i)
{ {
const label newIdx = oldToNew[i]; const label newIdx = oldToNew[i];
@ -127,7 +110,8 @@ void Foam::UPtrList<T>::reorder(const labelUList& oldToNew, const bool check)
newList.checkNonNull(); newList.checkNonNull();
} }
ptrs_.transfer(newList); // Copy the pointers, do not swap or transfer lists!
ptrs_ = newList;
} }
@ -148,7 +132,7 @@ void Foam::UPtrList<T>::sortOrder(const labelUList& order, const bool check)
Detail::PtrListDetail<T> newList(len); Detail::PtrListDetail<T> newList(len);
Detail::PtrListDetail<T> guard(len); Detail::PtrListDetail<T> guard(len);
for (label i=0; i<len; ++i) for (label i = 0; i < len; ++i)
{ {
const label oldIdx = order[i]; const label oldIdx = order[i];
@ -179,16 +163,35 @@ void Foam::UPtrList<T>::sortOrder(const labelUList& order, const bool check)
newList.checkNonNull(); newList.checkNonNull();
} }
ptrs_.transfer(newList); // Copy the pointers, do not swap or transfer lists!
ptrs_ = newList;
} }
// * * * * * * * * * * * * * * * Ostream Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Ostream Operators * * * * * * * * * * * * * //
template<class T>
Foam::Ostream& Foam::UPtrList<T>::printAddresses(Ostream& os) const
{
return ptrs_.printAddresses(os);
}
template<class T>
Foam::Ostream& Foam::UPtrList<T>::writeList
(
Ostream& os,
const bool trimNull
) const
{
return ptrs_.write(os, trimNull);
}
template<class T> template<class T>
Foam::Ostream& Foam::operator<<(Ostream& os, const UPtrList<T>& list) Foam::Ostream& Foam::operator<<(Ostream& os, const UPtrList<T>& list)
{ {
return list.ptrs_.write(os); return list.writeList(os, false); // Do not ignore null
} }

View File

@ -314,10 +314,6 @@ public:
// \return the number of non-null entries // \return the number of non-null entries
label squeezeNull(); label squeezeNull();
//- Reduce addressable list size to ignore any trailing null pointers.
// The reduces the effective list length without reallocation
void trimTrailingNull();
//- Append an element to the end of the list //- Append an element to the end of the list
inline void push_back(T* ptr); inline void push_back(T* ptr);
@ -382,9 +378,18 @@ public:
inline void operator=(UPtrList<T>&& list); inline void operator=(UPtrList<T>&& list);
// Writing
//- Print pointer addresses to Ostream (debugging only)
Ostream& printAddresses(Ostream& os) const;
//- Write UPtrList to Ostream, optionally ignoring null entries
Ostream& writeList(Ostream& os, const bool trimNull=false) const;
// IOstream Operators // IOstream Operators
//- Write UPtrList to Ostream //- Write UPtrList to Ostream. Does not ignore null entries
friend Ostream& operator<< <T>(Ostream& os, const UPtrList<T>& list); friend Ostream& operator<< <T>(Ostream& os, const UPtrList<T>& list);

View File

@ -537,14 +537,15 @@ public:
//- True if headerClassName() is non-empty (after reading) //- True if headerClassName() is non-empty (after reading)
inline bool hasHeaderClass() const noexcept; inline bool hasHeaderClass() const noexcept;
//- Check if headerClassName() equals the expected type.
//- Always true if the expected type is empty.
inline bool isHeaderClass(const word& expectedType) const;
//- Check if headerClassName() equals Type::typeName //- Check if headerClassName() equals Type::typeName
//- Always true for a \c void type.
template<class Type> template<class Type>
inline bool isHeaderClass() const; inline bool isHeaderClass() const;
//- Same as isHeaderClass()
template<class Type>
bool isHeaderClassName() const { return isHeaderClass<Type>(); }
// Meta-data // Meta-data
@ -611,20 +612,18 @@ public:
fileName objectRelPath() const; fileName objectRelPath() const;
//- Redirect to fileHandler filePath, searching locally. //- Redirect to fileHandler filePath, searching locally.
// When search is false, simply use the current instance,
// otherwise search previous instances.
fileName localFilePath fileName localFilePath
( (
const word& typeName, const word& typeName,
//! False: use current instance; True: search previous instances
const bool search=true const bool search=true
) const; ) const;
//- Redirect to fileHandler filePath, searching up if in parallel. //- Redirect to fileHandler filePath, searching up if in parallel.
// When search is false, simply use the current instance,
// otherwise search previous instances.
fileName globalFilePath fileName globalFilePath
( (
const word& typeName, const word& typeName,
//! False: use current instance; True: search previous instances
const bool search=true const bool search=true
) const; ) const;
@ -645,17 +644,29 @@ public:
bool readHeader(dictionary& headerDict, Istream& is); bool readHeader(dictionary& headerDict, Istream& is);
//- Read header (respects is_globalIOobject trait) and check its info. //- Read header (respects is_globalIOobject trait) and check its info.
//- A \c void type suppresses trait and type-name checks.
template<class Type> template<class Type>
bool typeHeaderOk bool typeHeaderOk
( (
//! Check headerClassName against the type-name //! Check headerClassName against the type-name
const bool checkType = true, [[maybe_unused]] const bool checkType = true,
//! Also search previous instances if not found at current instance //! Also search previous instances if not found at current instance
const bool search = true, const bool search = true,
//! Report any check-type failures //! Report any check-type failures
const bool verbose = true const bool verbose = true
); );
//- Forwards to single-parameter version with the specified search type.
//- A \c void type suppresses trait and type-name checks.
template<class Type, bool Searching>
bool typeHeaderOk
(
//! Check headerClassName against the type-name
const bool checkType = true,
//! Report any check-type failures
const bool verbose = true
);
//- Call localFilePath or globalFilePath for given type //- Call localFilePath or globalFilePath for given type
//- depending on its is_globalIOobject trait. //- depending on its is_globalIOobject trait.
template<class Type> template<class Type>
@ -718,19 +729,16 @@ public:
//- Copy assignment, copies all values (except the registry) //- Copy assignment, copies all values (except the registry)
void operator=(const IOobject& io); void operator=(const IOobject& io);
// Housekeeping
//- Same as isHeaderClass()
template<class Type>
bool isHeaderClassName() const { return isHeaderClass<Type>(); }
}; };
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Specialization for \c void always returns true (no headerClassName check).
template<>
inline bool IOobject::isHeaderClass<void>() const
{
return true;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam

View File

@ -261,10 +261,23 @@ inline bool Foam::IOobject::hasHeaderClass() const noexcept
} }
inline bool Foam::IOobject::isHeaderClass(const word& expectedType) const
{
return (expectedType.empty() || (expectedType == headerClassName_));
}
template<class Type> template<class Type>
inline bool Foam::IOobject::isHeaderClass() const inline bool Foam::IOobject::isHeaderClass() const
{ {
if constexpr (std::is_void_v<Type>)
{
return true;
}
else
{
return (Type::typeName == headerClassName_); return (Type::typeName == headerClassName_);
}
} }

View File

@ -215,17 +215,13 @@ bool Foam::IOobject::readAndCheckHeader
ok = handler.readHeader(*this, fName, typeName); ok = handler.readHeader(*this, fName, typeName);
UPstream::parRun(oldParRun); UPstream::parRun(oldParRun);
if if (ok && checkType && !isHeaderClass(typeName))
(
ok && checkType
&& !typeName.empty() && headerClassName_ != typeName
)
{ {
ok = false; ok = false;
if (verbose) if (verbose)
{ {
WarningInFunction WarningInFunction
<< "Unexpected class name \"" << headerClassName_ << "Unexpected class name \"" << headerClassName()
<< "\" expected \"" << typeName << "\" expected \"" << typeName
<< "\" when reading " << fName << endl; << "\" when reading " << fName << endl;
} }
@ -251,17 +247,13 @@ bool Foam::IOobject::readAndCheckHeader
); );
ok = handler.readHeader(*this, fName, typeName); ok = handler.readHeader(*this, fName, typeName);
if if (ok && checkType && !isHeaderClass(typeName))
(
ok && checkType
&& !typeName.empty() && headerClassName_ != typeName
)
{ {
ok = false; ok = false;
if (verbose) if (verbose)
{ {
WarningInFunction WarningInFunction
<< "Unexpected class name \"" << headerClassName_ << "Unexpected class name \"" << headerClassName()
<< "\" expected \"" << typeName << "\" expected \"" << typeName
<< "\" when reading " << fName << endl; << "\" when reading " << fName << endl;
} }

View File

@ -42,6 +42,19 @@ bool Foam::IOobject::typeHeaderOk
const bool verbose const bool verbose
) )
{ {
if constexpr (std::is_void_v<Type>)
{
return readAndCheckHeader
(
false, // isGlobal (false)
word::null, // typeName (n/a)
false, // checkType (false)
search,
verbose
);
}
else
{
return readAndCheckHeader return readAndCheckHeader
( (
is_globalIOobject<Type>::value, is_globalIOobject<Type>::value,
@ -50,6 +63,14 @@ bool Foam::IOobject::typeHeaderOk
search, search,
verbose verbose
); );
}
}
template<class Type, bool Searching>
bool Foam::IOobject::typeHeaderOk(const bool checkType, const bool verbose)
{
return typeHeaderOk<Type>(checkType, Searching, verbose);
} }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2018-2024 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -27,41 +27,43 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "CompactIOField.H" #include "CompactIOField.H"
#include "labelList.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class T, class BaseType> template<class T>
bool Foam::CompactIOField<T, BaseType>::readIOcontents(bool readOnProc) bool Foam::CompactIOField<T>::readIOcontents(bool readOnProc)
{ {
typedef IOField<T> plain_type;
if (isReadRequired() || (isReadOptional() && headerOk())) if (isReadRequired() || (isReadOptional() && headerOk()))
{ {
// Do reading
Istream& is = readStream(word::null, readOnProc); Istream& is = readStream(word::null, readOnProc);
if (readOnProc) if (!readOnProc)
{ {
if (headerClassName() == IOField<T>::typeName) // no-op
{
is >> static_cast<Field<T>&>(*this);
close();
} }
else if (headerClassName() == typeName) else if (isHeaderClass(typeName))
{ {
is >> *this; // Compact form
close(); is >> *this; // or: this->readCompact(is);
}
else if (isHeaderClass<plain_type>())
{
// Non-compact form
is >> static_cast<content_type&>(*this);
} }
else else
{ {
FatalIOErrorInFunction(is) FatalIOErrorInFunction(is)
<< "Unexpected class name " << headerClassName() << "Unexpected class name " << headerClassName()
<< " expected " << typeName << " expected " << typeName
<< " or " << IOField<T>::typeName << nl << " or " << plain_type::typeName << nl
<< " while reading object " << name() << " while reading object " << name()
<< exit(FatalIOError); << exit(FatalIOError);
} }
}
close();
return true; return true;
} }
@ -69,10 +71,100 @@ bool Foam::CompactIOField<T, BaseType>::readIOcontents(bool readOnProc)
} }
template<class T>
Foam::label Foam::CompactIOField<T>::readIOsize(bool readOnProc)
{
typedef IOField<T> plain_type;
label count(-1);
if (isReadRequired() || (isReadOptional() && headerOk()))
{
Istream& is = readStream(word::null, readOnProc);
if (!readOnProc)
{
// no-op
}
else
{
token tok(is);
if (tok.isLabel())
{
// The majority of files will have lists with sizing prefix
count = tok.labelToken();
if (isHeaderClass(typeName))
{
// Compact form: read offsets, not content
if (--count < 0)
{
count = 0;
}
}
}
else
{
is.putBack(tok);
if (isHeaderClass(typeName))
{
// Compact form: can just read the offsets
labelList offsets(is);
count = Foam::max(0, (offsets.size()-1));
}
else if (isHeaderClass<plain_type>())
{
// Non-compact form: need to read everything
Field<T> list(is);
count = list.size();
}
else
{
FatalIOErrorInFunction(is)
<< "Unexpected class name " << headerClassName()
<< " expected " << typeName
<< " or " << plain_type::typeName << endl
<< " while reading object " << name()
<< exit(FatalIOError);
}
}
}
close();
}
return count;
}
template<class T>
bool Foam::CompactIOField<T>::overflows() const
{
// Can safely assume that int64 will not overflow
if constexpr (sizeof(label) < sizeof(int64_t))
{
const UList<T>& lists = *this;
label total = 0;
for (const auto& sublist : lists)
{
const label prev = total;
total += sublist.size();
if (total < prev)
{
return true;
}
}
}
return false;
}
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
template<class T, class BaseType> template<class T>
Foam::CompactIOField<T, BaseType>::CompactIOField(const IOobject& io) Foam::CompactIOField<T>::CompactIOField(const IOobject& io)
: :
regIOobject(io) regIOobject(io)
{ {
@ -80,8 +172,8 @@ Foam::CompactIOField<T, BaseType>::CompactIOField(const IOobject& io)
} }
template<class T, class BaseType> template<class T>
Foam::CompactIOField<T, BaseType>::CompactIOField Foam::CompactIOField<T>::CompactIOField
( (
const IOobject& io, const IOobject& io,
const bool readOnProc const bool readOnProc
@ -93,8 +185,8 @@ Foam::CompactIOField<T, BaseType>::CompactIOField
} }
template<class T, class BaseType> template<class T>
Foam::CompactIOField<T, BaseType>::CompactIOField Foam::CompactIOField<T>::CompactIOField
( (
const IOobject& io, const IOobject& io,
Foam::zero Foam::zero
@ -106,8 +198,8 @@ Foam::CompactIOField<T, BaseType>::CompactIOField
} }
template<class T, class BaseType> template<class T>
Foam::CompactIOField<T, BaseType>::CompactIOField Foam::CompactIOField<T>::CompactIOField
( (
const IOobject& io, const IOobject& io,
const label len const label len
@ -122,8 +214,8 @@ Foam::CompactIOField<T, BaseType>::CompactIOField
} }
template<class T, class BaseType> template<class T>
Foam::CompactIOField<T, BaseType>::CompactIOField Foam::CompactIOField<T>::CompactIOField
( (
const IOobject& io, const IOobject& io,
const UList<T>& content const UList<T>& content
@ -138,8 +230,8 @@ Foam::CompactIOField<T, BaseType>::CompactIOField
} }
template<class T, class BaseType> template<class T>
Foam::CompactIOField<T, BaseType>::CompactIOField Foam::CompactIOField<T>::CompactIOField
( (
const IOobject& io, const IOobject& io,
Field<T>&& content Field<T>&& content
@ -153,16 +245,69 @@ Foam::CompactIOField<T, BaseType>::CompactIOField
} }
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<class T>
Foam::label Foam::CompactIOField<T>::readContentsSize(const IOobject& io)
{
IOobject rio(io, IOobjectOption::NO_REGISTER);
if (rio.readOpt() == IOobjectOption::READ_MODIFIED)
{
rio.readOpt(IOobjectOption::MUST_READ);
}
rio.resetHeader();
// Construct NO_READ, changing after construction
const auto rOpt = rio.readOpt(IOobjectOption::NO_READ);
CompactIOField<T> reader(rio);
reader.readOpt(rOpt);
return reader.readIOsize();
}
template<class T>
Foam::Field<T> Foam::CompactIOField<T>::readContents(const IOobject& io)
{
IOobject rio(io, IOobjectOption::NO_REGISTER);
if (rio.readOpt() == IOobjectOption::READ_MODIFIED)
{
rio.readOpt(IOobjectOption::MUST_READ);
}
rio.resetHeader();
CompactIOField<T> reader(rio);
return Field<T>(std::move(static_cast<Field<T>&>(reader)));
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T, class BaseType> template<class T>
bool Foam::CompactIOField<T, BaseType>::writeObject bool Foam::CompactIOField<T>::writeObject
( (
IOstreamOption streamOpt, IOstreamOption streamOpt,
const bool writeOnProc const bool writeOnProc
) const ) const
{ {
if (streamOpt.format() == IOstreamOption::ASCII) if
(
streamOpt.format() == IOstreamOption::BINARY
&& overflows()
)
{
streamOpt.format(IOstreamOption::ASCII);
WarningInFunction
<< "Overall number of elements of CompactIOField (size:"
<< this->size() << ") overflows a label (int"
<< (8*sizeof(label)) << ')' << nl
<< " Switching to ascii writing" << endl;
}
if (streamOpt.format() != IOstreamOption::BINARY)
{ {
// Change type to be non-compact format type // Change type to be non-compact format type
const word oldTypeName(typeName); const word oldTypeName(typeName);
@ -181,99 +326,136 @@ bool Foam::CompactIOField<T, BaseType>::writeObject
} }
template<class T, class BaseType> template<class T>
bool Foam::CompactIOField<T, BaseType>::writeData(Ostream& os) const bool Foam::CompactIOField<T>::writeData(Ostream& os) const
{ {
return (os << *this).good(); return (os << *this).good();
} }
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class T, class BaseType> template<class T>
void Foam::CompactIOField<T, BaseType>::operator= Foam::Istream& Foam::CompactIOField<T>::readCompact(Istream& is)
(
const CompactIOField<T, BaseType>& rhs
)
{ {
if (this == &rhs) Field<T>& lists = *this;
// The base type for packed values
typedef typename T::value_type base_type;
// Read compact: offsets + packed values
const labelList offsets(is);
Field<base_type> values(is);
// Transcribe
const label len = Foam::max(0, (offsets.size()-1));
lists.resize_nocopy(len);
auto iter = values.begin();
for (label i = 0; i < len; ++i)
{ {
return; // Self-assigment is a no-op auto& list = lists[i];
} const label count = (offsets[i+1] - offsets[i]);
Field<T>::operator=(rhs); list.resize_nocopy(count);
}
std::move(iter, iter + count, list.begin());
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * // iter += count;
template<class T, class BaseType>
Foam::Istream& Foam::operator>>
(
Foam::Istream& is,
Foam::CompactIOField<T, BaseType>& L
)
{
// Read compact
const labelList start(is);
const Field<BaseType> elems(is);
// Convert
L.setSize(start.size()-1);
forAll(L, i)
{
T& subField = L[i];
label index = start[i];
subField.setSize(start[i+1] - index);
forAll(subField, j)
{
subField[j] = elems[index++];
}
} }
return is; return is;
} }
template<class T, class BaseType> template<class T>
Foam::Ostream& Foam::CompactIOField<T>::writeCompact(Ostream& os) const
{
const Field<T>& lists = *this;
// The base type for packed values
typedef typename T::value_type base_type;
// Convert to compact format
label total = 0;
const label len = lists.size();
// offsets
{
labelList offsets(len+1);
for (label i = 0; i < len; ++i)
{
offsets[i] = total;
total += lists[i].size();
if (total < offsets[i])
{
FatalIOErrorInFunction(os)
<< "Overall number of elements of CompactIOField (size:"
<< len
<< ") overflows the representation of a label" << nl
<< "Please recompile with a larger representation"
<< " for label" << exit(FatalIOError);
}
}
offsets[len] = total;
os << offsets;
}
// packed values: make deepCopy for writing
{
Field<base_type> values(total);
auto iter = values.begin();
for (const auto& list : lists)
{
iter = std::copy_n(list.begin(), list.size(), iter);
// With IndirectList? [unlikely]
// const label count = list.size();
// for (label i = 0; i < count; (void)++i, (void)++iter)
// {
// *iter = list[i];
// }
}
os << values;
}
return os;
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
template<class T>
Foam::Istream& Foam::operator>>
(
Foam::Istream& is,
Foam::CompactIOField<T>& lists
)
{
return lists.readCompact(is);
}
template<class T>
Foam::Ostream& Foam::operator<< Foam::Ostream& Foam::operator<<
( (
Foam::Ostream& os, Foam::Ostream& os,
const Foam::CompactIOField<T, BaseType>& L const Foam::CompactIOField<T>& lists
) )
{ {
// Keep ASCII writing same // Keep ASCII writing same
if (os.format() == IOstreamOption::ASCII) if (os.format() != IOstreamOption::BINARY)
{ {
os << static_cast<const Field<T>&>(L); os << static_cast<const Field<T>&>(lists);
} }
else else
{ {
// Convert to compact format lists.writeCompact(os);
labelList start(L.size()+1);
start[0] = 0;
for (label i = 1; i < start.size(); i++)
{
start[i] = start[i-1]+L[i-1].size();
}
Field<BaseType> elems(start[start.size()-1]);
label elemI = 0;
forAll(L, i)
{
const T& subField = L[i];
forAll(subField, j)
{
elems[elemI++] = subField[j];
}
}
os << start << elems;
} }
return os; return os;

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2020-2024 OpenCFD Ltd. Copyright (C) 2020-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -50,25 +50,16 @@ namespace Foam
{ {
// Forward Declarations // Forward Declarations
template<class T, class BaseType> class CompactIOField; template<class T> class CompactIOField;
template<class T, class BaseType> Istream& operator>> template<class T> Istream& operator>>(Istream&, CompactIOField<T>&);
( template<class T> Ostream& operator<<(Ostream&, const CompactIOField<T>&);
Istream&,
CompactIOField<T, BaseType>&
);
template<class T, class BaseType> Ostream& operator<<
(
Ostream&,
const CompactIOField<T, BaseType>&
);
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class CompactIOField Declaration Class CompactIOField Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
template<class T, class BaseType> template<class T>
class CompactIOField class CompactIOField
: :
public regIOobject, public regIOobject,
@ -81,8 +72,18 @@ class CompactIOField
// Return true if read (only accurate when readOnProc == true). // Return true if read (only accurate when readOnProc == true).
bool readIOcontents(bool readOnProc = true); bool readIOcontents(bool readOnProc = true);
//- Read the content size.
// Return the size if read, -1 otherwise
label readIOsize(bool readOnProc = true);
//- Has too many elements in it?
bool overflows() const;
public: public:
//- The underlying content type
typedef Field<T> content_type;
//- Runtime type information //- Runtime type information
TypeName("FieldField"); TypeName("FieldField");
@ -92,7 +93,7 @@ public:
//- Default copy construct //- Default copy construct
CompactIOField(const CompactIOField&) = default; CompactIOField(const CompactIOField&) = default;
//- Construct from IOobject //- Construct from IOobject. Will be zero size if not read.
explicit CompactIOField(const IOobject& io); explicit CompactIOField(const IOobject& io);
//- Construct from IOobject, with local processor conditional reading //- Construct from IOobject, with local processor conditional reading
@ -111,29 +112,55 @@ public:
CompactIOField(const IOobject& io, Field<T>&& content); CompactIOField(const IOobject& io, Field<T>&& content);
// Factory Methods
//- Read and return content size, -1 if not read.
// The IOobject is never registered
static label readContentsSize(const IOobject& io);
//- Read and return contents. The IOobject is never registered
static Field<T> readContents(const IOobject& io);
//- Destructor //- Destructor
virtual ~CompactIOField() = default; virtual ~CompactIOField() = default;
// Member Functions // Member Functions
//- Write using stream options //- Read as offsets/packed-values and transcribe into *this
Istream& readCompact(Istream& is);
//- Write as offsets/packed-values
Ostream& writeCompact(Ostream& os) const;
//- Write using stream options. Checks for overflow in binary
virtual bool writeObject virtual bool writeObject
( (
IOstreamOption streamOpt, IOstreamOption streamOpt,
const bool writeOnProc const bool writeOnProc
) const; ) const;
//- Write as plain or compact content (depends on stream format)
virtual bool writeData(Ostream& os) const; virtual bool writeData(Ostream& os) const;
// Member Operators // Member Operators
//- Copy assignment of entries
void operator=(const CompactIOField<T, BaseType>& rhs);
//- Copy or move assignment of entries //- Copy or move assignment of entries
using Field<T>::operator=; using Field<T>::operator=;
//- Copy assignment of entries
void operator=(const CompactIOField<T>& rhs)
{
Field<T>::operator=(rhs);
}
//- Move assignment of entries
void operator=(CompactIOField<T>&& rhs)
{
Field<T>::operator=(std::move(static_cast<Field<T>&>(rhs)));
}
}; };

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2024 OpenCFD Ltd. Copyright (C) 2015-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -27,41 +27,39 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "CompactIOList.H" #include "CompactIOList.H"
#include "labelList.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class T, class BaseType> template<class T>
bool Foam::CompactIOList<T, BaseType>::readIOcontents() bool Foam::CompactIOList<T>::readIOcontents()
{ {
if typedef IOList<T> plain_type;
(
readOpt() == IOobject::MUST_READ if (isReadRequired() || (isReadOptional() && headerOk()))
|| (isReadOptional() && headerOk())
)
{ {
Istream& is = readStream(word::null); Istream& is = readStream(word::null);
if (headerClassName() == IOList<T>::typeName) if (isHeaderClass(typeName))
{ {
is >> static_cast<List<T>&>(*this); // Compact form
close(); is >> *this; // or: this->readCompact(is);
} }
else if (headerClassName() == typeName) else if (isHeaderClass<plain_type>())
{ {
is >> *this; // Non-compact form
close(); is >> static_cast<content_type&>(*this);
} }
else else
{ {
FatalIOErrorInFunction(is) FatalIOErrorInFunction(is)
<< "Unexpected class name " << headerClassName() << "Unexpected class name " << headerClassName()
<< " expected " << typeName << " expected " << typeName
<< " or " << IOList<T>::typeName << endl << " or " << plain_type::typeName << endl
<< " while reading object " << name() << " while reading object " << name()
<< exit(FatalIOError); << exit(FatalIOError);
} }
close();
return true; return true;
} }
@ -69,29 +67,93 @@ bool Foam::CompactIOList<T, BaseType>::readIOcontents()
} }
template<class T, class BaseType> template<class T>
bool Foam::CompactIOList<T, BaseType>::overflows() const Foam::label Foam::CompactIOList<T>::readIOsize()
{ {
const List<T>& lists = *this; typedef IOList<T> plain_type;
label count(-1);
if (isReadRequired() || (isReadOptional() && headerOk()))
{
Istream& is = readStream(word::null);
token tok(is);
if (tok.isLabel())
{
// The majority of files will have lists with sizing prefix
count = tok.labelToken();
if (isHeaderClass(typeName))
{
// Compact form: read offsets, not content
if (--count < 0)
{
count = 0;
}
}
}
else
{
is.putBack(tok);
if (isHeaderClass(typeName))
{
// Compact form: can just read the offsets
labelList offsets(is);
count = Foam::max(0, (offsets.size()-1));
}
else if (isHeaderClass<plain_type>())
{
// Non-compact form: need to read everything
List<T> list(is);
count = list.size();
}
else
{
FatalIOErrorInFunction(is)
<< "Unexpected class name " << headerClassName()
<< " expected " << typeName
<< " or " << plain_type::typeName << endl
<< " while reading object " << name()
<< exit(FatalIOError);
}
}
close();
}
return count;
}
template<class T>
bool Foam::CompactIOList<T>::overflows() const
{
// Can safely assume that int64 will not overflow
if constexpr (sizeof(label) < sizeof(int64_t))
{
const UList<T>& lists = *this;
label total = 0; label total = 0;
for (const auto& sublist : lists) for (const auto& list : lists)
{ {
const label prev = total; const label prev = total;
total += sublist.size(); total += list.size();
if (total < prev) if (total < prev)
{ {
return true; return true;
} }
} }
}
return false; return false;
} }
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
template<class T, class BaseType> template<class T>
Foam::CompactIOList<T, BaseType>::CompactIOList(const IOobject& io) Foam::CompactIOList<T>::CompactIOList(const IOobject& io)
: :
regIOobject(io) regIOobject(io)
{ {
@ -99,8 +161,8 @@ Foam::CompactIOList<T, BaseType>::CompactIOList(const IOobject& io)
} }
template<class T, class BaseType> template<class T>
Foam::CompactIOList<T, BaseType>::CompactIOList Foam::CompactIOList<T>::CompactIOList
( (
const IOobject& io, const IOobject& io,
Foam::zero Foam::zero
@ -112,8 +174,8 @@ Foam::CompactIOList<T, BaseType>::CompactIOList
} }
template<class T, class BaseType> template<class T>
Foam::CompactIOList<T, BaseType>::CompactIOList Foam::CompactIOList<T>::CompactIOList
( (
const IOobject& io, const IOobject& io,
const label len const label len
@ -128,8 +190,8 @@ Foam::CompactIOList<T, BaseType>::CompactIOList
} }
template<class T, class BaseType> template<class T>
Foam::CompactIOList<T, BaseType>::CompactIOList Foam::CompactIOList<T>::CompactIOList
( (
const IOobject& io, const IOobject& io,
const UList<T>& content const UList<T>& content
@ -144,8 +206,8 @@ Foam::CompactIOList<T, BaseType>::CompactIOList
} }
template<class T, class BaseType> template<class T>
Foam::CompactIOList<T, BaseType>::CompactIOList Foam::CompactIOList<T>::CompactIOList
( (
const IOobject& io, const IOobject& io,
List<T>&& content List<T>&& content
@ -159,10 +221,48 @@ Foam::CompactIOList<T, BaseType>::CompactIOList
} }
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<class T>
Foam::label Foam::CompactIOList<T>::readContentsSize(const IOobject& io)
{
IOobject rio(io, IOobjectOption::NO_REGISTER);
if (rio.readOpt() == IOobjectOption::READ_MODIFIED)
{
rio.readOpt(IOobjectOption::MUST_READ);
}
rio.resetHeader();
// Construct NO_READ, changing after construction
const auto rOpt = rio.readOpt(IOobjectOption::NO_READ);
CompactIOList<T> reader(rio);
reader.readOpt(rOpt);
return reader.readIOsize();
}
template<class T>
Foam::List<T> Foam::CompactIOList<T>::readContents(const IOobject& io)
{
IOobject rio(io, IOobjectOption::NO_REGISTER);
if (rio.readOpt() == IOobjectOption::READ_MODIFIED)
{
rio.readOpt(IOobjectOption::MUST_READ);
}
rio.resetHeader();
CompactIOList<T> reader(rio);
return List<T>(std::move(static_cast<List<T>&>(reader)));
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T, class BaseType> template<class T>
bool Foam::CompactIOList<T, BaseType>::writeObject bool Foam::CompactIOList<T>::writeObject
( (
IOstreamOption streamOpt, IOstreamOption streamOpt,
const bool writeOnProc const bool writeOnProc
@ -177,12 +277,13 @@ bool Foam::CompactIOList<T, BaseType>::writeObject
streamOpt.format(IOstreamOption::ASCII); streamOpt.format(IOstreamOption::ASCII);
WarningInFunction WarningInFunction
<< "Overall number of elements of CompactIOList of size " << "Overall number of elements of CompactIOList (size:"
<< this->size() << " overflows the representation of a label" << this->size() << ") overflows a label (int"
<< nl << " Switching to ascii writing" << endl; << (8*sizeof(label)) << ')' << nl
<< " Switching to ascii writing" << endl;
} }
if (streamOpt.format() == IOstreamOption::ASCII) if (streamOpt.format() != IOstreamOption::BINARY)
{ {
// Change type to be non-compact format type // Change type to be non-compact format type
const word oldTypeName(typeName); const word oldTypeName(typeName);
@ -201,105 +302,136 @@ bool Foam::CompactIOList<T, BaseType>::writeObject
} }
template<class T, class BaseType> template<class T>
bool Foam::CompactIOList<T, BaseType>::writeData(Ostream& os) const bool Foam::CompactIOList<T>::writeData(Ostream& os) const
{ {
return (os << *this).good(); return (os << *this).good();
} }
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class T, class BaseType> template<class T>
void Foam::CompactIOList<T, BaseType>::operator= Foam::Istream& Foam::CompactIOList<T>::readCompact(Istream& is)
(
const CompactIOList<T, BaseType>& rhs
)
{ {
List<T>::operator=(rhs); List<T>& lists = *this;
}
// The base type for packed values
typedef typename T::value_type base_type;
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * // // Read compact: offsets + packed values
const labelList offsets(is);
List<base_type> values(is);
template<class T, class BaseType> // Transcribe
Foam::Istream& Foam::operator>> const label len = Foam::max(0, (offsets.size()-1));
( lists.resize_nocopy(len);
Foam::Istream& is,
Foam::CompactIOList<T, BaseType>& L
)
{
// Read compact
const labelList start(is);
const List<BaseType> elems(is);
// Convert auto iter = values.begin();
L.setSize(start.size()-1);
forAll(L, i) for (label i = 0; i < len; ++i)
{ {
T& subList = L[i]; auto& list = lists[i];
const label count = (offsets[i+1] - offsets[i]);
label index = start[i]; list.resize_nocopy(count);
subList.setSize(start[i+1] - index);
forAll(subList, j) std::move(iter, iter + count, list.begin());
{
subList[j] = elems[index++]; iter += count;
}
} }
return is; return is;
} }
template<class T, class BaseType> template<class T>
Foam::Ostream& Foam::operator<< Foam::Ostream& Foam::CompactIOList<T>::writeCompact(Ostream& os) const
(
Foam::Ostream& os,
const Foam::CompactIOList<T, BaseType>& L
)
{ {
// Keep ASCII writing same const List<T>& lists = *this;
if (os.format() == IOstreamOption::ASCII)
{ // The base type for packed values
os << static_cast<const List<T>&>(L); typedef typename T::value_type base_type;
}
else
{
// Convert to compact format // Convert to compact format
labelList start(L.size()+1); label total = 0;
const label len = lists.size();
start[0] = 0; // offsets
for (label i = 1; i < start.size(); i++)
{ {
const label prev = start[i-1]; labelList offsets(len+1);
start[i] = prev+L[i-1].size();
if (start[i] < prev) for (label i = 0; i < len; ++i)
{
offsets[i] = total;
total += lists[i].size();
if (total < offsets[i])
{ {
FatalIOErrorInFunction(os) FatalIOErrorInFunction(os)
<< "Overall number of elements " << start[i] << "Overall number of elements of CompactIOList (size:"
<< " of CompactIOList of size " << len
<< L.size() << " overflows the representation of a label" << ") overflows the representation of a label" << nl
<< endl << "Please recompile with a larger representation" << "Please recompile with a larger representation"
<< " for label" << exit(FatalIOError); << " for label" << exit(FatalIOError);
} }
} }
offsets[len] = total;
List<BaseType> elems(start[start.size()-1]); os << offsets;
label elemI = 0;
forAll(L, i)
{
const T& subList = L[i];
forAll(subList, j)
{
elems[elemI++] = subList[j];
} }
// packed values: make deepCopy for writing
{
List<base_type> values(total);
auto iter = values.begin();
for (const auto& list : lists)
{
iter = std::copy_n(list.begin(), list.size(), iter);
// With IndirectList? [unlikely]
// const label count = list.size();
// for (label i = 0; i < count; (void)++i, (void)++iter)
// {
// *iter = list[i];
// }
} }
os << start << elems; os << values;
}
return os;
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
template<class T>
Foam::Istream& Foam::operator>>
(
Foam::Istream& is,
Foam::CompactIOList<T>& lists
)
{
return lists.readCompact(is);
}
template<class T>
Foam::Ostream& Foam::operator<<
(
Foam::Ostream& os,
const Foam::CompactIOList<T>& lists
)
{
// Keep ASCII writing same
if (os.format() != IOstreamOption::BINARY)
{
os << static_cast<const List<T>&>(lists);
}
else
{
lists.writeCompact(os);
} }
return os; return os;

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2018-2024 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -50,24 +50,16 @@ namespace Foam
{ {
// Forward Declarations // Forward Declarations
template<class T, class BaseType> class CompactIOList; template<class T> class CompactIOList;
template<class T, class BaseType> Istream& operator>> template<class T> Istream& operator>>(Istream&, CompactIOList<T>&);
( template<class T> Ostream& operator<<(Ostream&, const CompactIOList<T>&);
Istream&,
CompactIOList<T, BaseType>&
);
template<class T, class BaseType> Ostream& operator<<
(
Ostream&,
const CompactIOList<T, BaseType>&
);
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class CompactIOList Declaration Class CompactIOList Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
template<class T, class BaseType> template<class T>
class CompactIOList class CompactIOList
: :
public regIOobject, public regIOobject,
@ -80,6 +72,10 @@ class CompactIOList
// Return true if read. // Return true if read.
bool readIOcontents(); bool readIOcontents();
//- Read the content size.
// Return the size if read, -1 otherwise
label readIOsize();
//- Has too many elements in it? //- Has too many elements in it?
bool overflows() const; bool overflows() const;
@ -98,7 +94,7 @@ public:
//- Default copy construct //- Default copy construct
CompactIOList(const CompactIOList&) = default; CompactIOList(const CompactIOList&) = default;
//- Construct from IOobject //- Construct from IOobject. Will be zero size if not read.
explicit CompactIOList(const IOobject& io); explicit CompactIOList(const IOobject& io);
//- Construct from IOobject and zero size (if not read) //- Construct from IOobject and zero size (if not read)
@ -114,12 +110,28 @@ public:
CompactIOList(const IOobject& io, List<T>&& content); CompactIOList(const IOobject& io, List<T>&& content);
// Factory Methods
//- Read and return content size, -1 if not read.
// The IOobject will not be registered
static label readContentsSize(const IOobject& io);
//- Read and return contents. The IOobject will not be registered
static List<T> readContents(const IOobject& io);
//- Destructor //- Destructor
virtual ~CompactIOList() = default; virtual ~CompactIOList() = default;
// Member Functions // Member Functions
//- Read as offsets/packed-values and transcribe into *this
Istream& readCompact(Istream& is);
//- Write as offsets/packed-values
Ostream& writeCompact(Ostream& os) const;
//- Write using stream options. Checks for overflow in binary //- Write using stream options. Checks for overflow in binary
virtual bool writeObject virtual bool writeObject
( (
@ -127,16 +139,26 @@ public:
const bool writeOnProc const bool writeOnProc
) const; ) const;
//- Write as plain or compact content (depends on stream format)
virtual bool writeData(Ostream& os) const; virtual bool writeData(Ostream& os) const;
// Member Operators // Member Operators
//- Copy assignment of entries
void operator=(const CompactIOList<T, BaseType>& rhs);
//- Copy or move assignment of entries //- Copy or move assignment of entries
using List<T>::operator=; using List<T>::operator=;
//- Copy assignment of entries
void operator=(const CompactIOList<T>& rhs)
{
List<T>::operator=(rhs);
}
//- Move assignment of entries
void operator=(CompactIOList<T>&& rhs)
{
List<T>::operator=(std::move(static_cast<List<T>&>(rhs)));
}
}; };

View File

@ -132,6 +132,7 @@ Foam::Field<Type> Foam::GlobalIOField<Type>::readContents(const IOobject& io)
{ {
rio.readOpt(IOobjectOption::MUST_READ); rio.readOpt(IOobjectOption::MUST_READ);
} }
rio.resetHeader();
// The object is global // The object is global
rio.globalObject(true); rio.globalObject(true);
@ -160,13 +161,4 @@ bool Foam::GlobalIOField<Type>::writeData(Ostream& os) const
} }
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class Type>
void Foam::GlobalIOField<Type>::operator=(const GlobalIOField<Type>& rhs)
{
Field<Type>::operator=(rhs);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -69,7 +69,7 @@ public:
//- Default copy construct //- Default copy construct
GlobalIOField(const GlobalIOField&) = default; GlobalIOField(const GlobalIOField&) = default;
//- Construct from IOobject //- Construct from IOobject. Will be zero size if not read.
explicit GlobalIOField(const IOobject& io); explicit GlobalIOField(const IOobject& io);
//- Construct from IOobject and field size (if not read) //- Construct from IOobject and field size (if not read)
@ -119,11 +119,20 @@ public:
// Member Operators // Member Operators
//- Copy assignment of entries
void operator=(const GlobalIOField<Type>& rhs);
//- Copy or move assignment of entries //- Copy or move assignment of entries
using Field<Type>::operator=; using Field<Type>::operator=;
//- Copy assignment of entries
void operator=(const GlobalIOField<Type>& rhs)
{
Field<Type>::operator=(rhs);
}
//- Move assignment of entries
void operator=(GlobalIOField<Type>&& rhs)
{
Field<Type>::operator=(std::move(static_cast<Field<Type>&>(rhs)));
}
}; };

View File

@ -116,6 +116,7 @@ Foam::List<Type> Foam::GlobalIOList<Type>::readContents(const IOobject& io)
{ {
rio.readOpt(IOobjectOption::MUST_READ); rio.readOpt(IOobjectOption::MUST_READ);
} }
rio.resetHeader();
// The object is global // The object is global
rio.globalObject(true); rio.globalObject(true);
@ -144,13 +145,4 @@ bool Foam::GlobalIOList<Type>::writeData(Ostream& os) const
} }
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class Type>
void Foam::GlobalIOList<Type>::operator=(const GlobalIOList<Type>& rhs)
{
List<Type>::operator=(rhs);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -69,7 +69,7 @@ public:
//- Default copy construct //- Default copy construct
GlobalIOList(const GlobalIOList&) = default; GlobalIOList(const GlobalIOList&) = default;
//- Construct from IOobject //- Construct from IOobject. Will be zero size if not read.
explicit GlobalIOList(const IOobject& io); explicit GlobalIOList(const IOobject& io);
//- Construct from IOobject and zero size (if not read) //- Construct from IOobject and zero size (if not read)
@ -119,11 +119,20 @@ public:
// Member Operators // Member Operators
//- Copy assignment of entries
void operator=(const GlobalIOList<Type>& rhs);
//- Copy or move assignment of entries //- Copy or move assignment of entries
using List<Type>::operator=; using List<Type>::operator=;
//- Copy assignment of entries
void operator=(const GlobalIOList<Type>& rhs)
{
List<Type>::operator=(rhs);
}
//- Move assignment of entries
void operator=(GlobalIOList<Type>&& rhs)
{
List<Type>::operator=(std::move(static_cast<List<Type>&>(rhs)));
}
}; };

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2016-2024 OpenCFD Ltd. Copyright (C) 2016-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -50,6 +50,38 @@ bool Foam::IOField<Type>::readIOcontents(bool readOnProc)
} }
template<class T>
Foam::label Foam::IOField<T>::readIOsize()
{
label count(-1);
if (isReadRequired() || (isReadOptional() && headerOk()))
{
Istream& is = readStream(typeName);
token tok(is);
const bool quick = tok.isLabel();
if (quick)
{
// The majority of files will have lists with sizing info
count = tok.labelToken();
}
is.putBack(tok);
if (!quick)
{
List<T> list(is);
close();
count = list.size();
}
}
return count;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type> template<class Type>
@ -167,6 +199,26 @@ Foam::IOFieldRef<Type>::IOFieldRef
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<class Type>
Foam::label Foam::IOField<Type>::readContentsSize(const IOobject& io)
{
IOobject rio(io, IOobjectOption::NO_REGISTER);
if (rio.readOpt() == IOobjectOption::READ_MODIFIED)
{
rio.readOpt(IOobjectOption::MUST_READ);
}
rio.resetHeader();
// Construct NO_READ, changing after construction
const auto rOpt = rio.readOpt(IOobjectOption::NO_READ);
IOField<Type> reader(rio);
reader.readOpt(rOpt);
return reader.readIOsize();
}
template<class Type> template<class Type>
Foam::Field<Type> Foam::IOField<Type>::readContents(const IOobject& io) Foam::Field<Type> Foam::IOField<Type>::readContents(const IOobject& io)
{ {
@ -175,6 +227,7 @@ Foam::Field<Type> Foam::IOField<Type>::readContents(const IOobject& io)
{ {
rio.readOpt(IOobjectOption::MUST_READ); rio.readOpt(IOobjectOption::MUST_READ);
} }
rio.resetHeader();
IOField<Type> reader(rio); IOField<Type> reader(rio);
@ -200,13 +253,4 @@ bool Foam::IOFieldRef<Type>::writeData(Ostream& os) const
} }
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class Type>
void Foam::IOField<Type>::operator=(const IOField<Type>& rhs)
{
Field<Type>::operator=(rhs);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2018-2024 OpenCFD Ltd. Copyright (C) 2018-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -62,6 +62,10 @@ class IOField
// Return true if read (only accurate when readOnProc == true). // Return true if read (only accurate when readOnProc == true).
bool readIOcontents(bool readOnProc = true); bool readIOcontents(bool readOnProc = true);
//- Read the content size.
// Return the size if read, -1 otherwise
label readIOsize();
public: public:
//- The underlying content type //- The underlying content type
@ -76,7 +80,7 @@ public:
//- Default copy construct //- Default copy construct
IOField(const IOField&) = default; IOField(const IOField&) = default;
//- Construct from IOobject //- Construct from IOobject. Will be zero size if not read.
explicit IOField(const IOobject& io); explicit IOField(const IOobject& io);
//- Construct from IOobject, with local processor conditional reading //- Construct from IOobject, with local processor conditional reading
@ -100,6 +104,10 @@ public:
// Factory Methods // Factory Methods
//- Read and return content size, -1 if not read.
// The IOobject will not be registered
static label readContentsSize(const IOobject& io);
//- Read and return contents. The IOobject will not be registered //- Read and return contents. The IOobject will not be registered
static Field<Type> readContents(const IOobject& io); static Field<Type> readContents(const IOobject& io);
@ -116,11 +124,20 @@ public:
// Member Operators // Member Operators
//- Copy assignment of entries
void operator=(const IOField<Type>& rhs);
//- Copy or move assignment of entries //- Copy or move assignment of entries
using Field<Type>::operator=; using Field<Type>::operator=;
//- Copy assignment of entries
void operator=(const IOField<Type>& rhs)
{
Field<Type>::operator=(rhs);
}
//- Move assignment of entries
void operator=(IOField<Type>&& rhs)
{
Field<Type>::operator=(std::move(static_cast<Field<Type>&>(rhs)));
}
}; };

View File

@ -44,6 +44,38 @@ bool Foam::IOList<T>::readIOcontents()
} }
template<class T>
Foam::label Foam::IOList<T>::readIOsize()
{
label count(-1);
if (isReadRequired() || (isReadOptional() && headerOk()))
{
Istream& is = readStream(typeName);
token tok(is);
const bool quick = tok.isLabel();
if (quick)
{
// The majority of files will have lists with sizing info
count = tok.labelToken();
}
is.putBack(tok);
if (!quick)
{
List<T> list(is);
close();
count = list.size();
}
}
return count;
}
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
template<class T> template<class T>
@ -128,6 +160,26 @@ Foam::IOListRef<T>::IOListRef
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
template<class T>
Foam::label Foam::IOList<T>::readContentsSize(const IOobject& io)
{
IOobject rio(io, IOobjectOption::NO_REGISTER);
if (rio.readOpt() == IOobjectOption::READ_MODIFIED)
{
rio.readOpt(IOobjectOption::MUST_READ);
}
rio.resetHeader();
// Construct NO_READ, changing after construction
const auto rOpt = rio.readOpt(IOobjectOption::NO_READ);
IOList<T> reader(rio);
reader.readOpt(rOpt);
return reader.readIOsize();
}
template<class T> template<class T>
Foam::List<T> Foam::IOList<T>::readContents(const IOobject& io) Foam::List<T> Foam::IOList<T>::readContents(const IOobject& io)
{ {
@ -136,6 +188,7 @@ Foam::List<T> Foam::IOList<T>::readContents(const IOobject& io)
{ {
rio.readOpt(IOobjectOption::MUST_READ); rio.readOpt(IOobjectOption::MUST_READ);
} }
rio.resetHeader();
IOList<T> reader(rio); IOList<T> reader(rio);
@ -178,13 +231,4 @@ bool Foam::IOListRef<T>::writeData(Ostream& os) const
} }
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class T>
void Foam::IOList<T>::operator=(const IOList<T>& rhs)
{
List<T>::operator=(rhs);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -61,6 +61,10 @@ class IOList
//- Read if IOobject flags set. Return true if read. //- Read if IOobject flags set. Return true if read.
bool readIOcontents(); bool readIOcontents();
//- Read the content size.
// Return the size if read, -1 otherwise
label readIOsize();
public: public:
//- The underlying content type //- The underlying content type
@ -75,7 +79,7 @@ public:
//- Default copy construct //- Default copy construct
IOList(const IOList&) = default; IOList(const IOList&) = default;
//- Construct from IOobject //- Construct from IOobject. Will be zero size if not read.
explicit IOList(const IOobject& io); explicit IOList(const IOobject& io);
//- Construct from IOobject and zero size (if not read) //- Construct from IOobject and zero size (if not read)
@ -93,6 +97,10 @@ public:
// Factory Methods // Factory Methods
//- Read and return content size, -1 if not read.
// The IOobject is never registered
static label readContentsSize(const IOobject& io);
//- Read and return contents. The IOobject is never registered //- Read and return contents. The IOobject is never registered
static List<T> readContents(const IOobject& io); static List<T> readContents(const IOobject& io);
@ -113,11 +121,20 @@ public:
// Member Operators // Member Operators
//- Copy assignment of entries
void operator=(const IOList<T>& rhs);
//- Copy or move assignment of entries //- Copy or move assignment of entries
using List<T>::operator=; using List<T>::operator=;
//- Copy assignment of entries
void operator=(const IOList<T>& rhs)
{
List<T>::operator=(rhs);
}
//- Move assignment of entries
void operator=(IOList<T>&& rhs)
{
List<T>::operator=(std::move(static_cast<List<T>&>(rhs)));
}
}; };

View File

@ -104,6 +104,7 @@ Foam::Map<T> Foam::IOMap<T>::readContents(const IOobject& io)
{ {
rio.readOpt(IOobjectOption::MUST_READ); rio.readOpt(IOobjectOption::MUST_READ);
} }
rio.resetHeader();
// The object is global // The object is global
rio.globalObject(true); rio.globalObject(true);
@ -124,13 +125,4 @@ bool Foam::IOMap<T>::writeData(Ostream& os) const
} }
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class T>
void Foam::IOMap<T>::operator=(const IOMap<T>& rhs)
{
Map<T>::operator=(rhs);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -120,11 +120,20 @@ public:
// Member Operators // Member Operators
//- Copy assignment of entries
void operator=(const IOMap<T>& rhs);
//- Copy or move assignment of entries //- Copy or move assignment of entries
using Map<T>::operator=; using Map<T>::operator=;
//- Copy assignment of entries
void operator=(const IOMap<T>& rhs)
{
Map<T>::operator=(rhs);
}
//- Move assignment of entries
void operator=(IOMap<T>&& rhs)
{
Map<T>::operator=(std::move(static_cast<Map<T>&>(rhs)));
}
}; };

View File

@ -126,6 +126,7 @@ Foam::PtrList<T> Foam::IOPtrList<T>::readContents(const IOobject& io)
{ {
rio.readOpt(IOobjectOption::MUST_READ); rio.readOpt(IOobjectOption::MUST_READ);
} }
rio.resetHeader();
IOPtrList<T> reader(rio); IOPtrList<T> reader(rio);
@ -142,13 +143,4 @@ bool Foam::IOPtrList<T>::writeData(Ostream& os) const
} }
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class T>
void Foam::IOPtrList<T>::operator=(const IOPtrList<T>& rhs)
{
PtrList<T>::operator=(rhs);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -101,11 +101,20 @@ public:
// Member Operators // Member Operators
//- Copy assignment of entries
void operator=(const IOPtrList<T>& rhs);
//- Copy or move assignment of entries //- Copy or move assignment of entries
using PtrList<T>::operator=; using PtrList<T>::operator=;
//- Copy assignment of entries
void operator=(const IOPtrList<T>& rhs)
{
PtrList<T>::operator=(rhs);
}
//- Move assignment of entries
void operator=(IOPtrList<T>&& rhs)
{
PtrList<T>::operator=(std::move(static_cast<PtrList<T>&>(rhs)));
}
}; };

View File

@ -113,12 +113,4 @@ bool Foam::baseIOdictionary::writeData(Ostream& os) const
} }
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void Foam::baseIOdictionary::operator=(const baseIOdictionary& rhs)
{
dictionary::operator=(rhs);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -123,11 +123,20 @@ public:
// Member Operators // Member Operators
//- Copy assignment of dictionary entries (leave regIOobject untouched)
void operator=(const baseIOdictionary& rhs);
//- Copy assignment of dictionary entries //- Copy assignment of dictionary entries
using dictionary::operator=; using dictionary::operator=;
//- Copy assignment of dictionary entries
void operator=(const baseIOdictionary& rhs)
{
dictionary::operator=(rhs);
}
//- Move assignment of dictionary entries
void operator=(baseIOdictionary&& rhs)
{
dictionary::operator=(std::move(static_cast<dictionary&>(rhs)));
}
}; };

View File

@ -198,6 +198,7 @@ Foam::Field<Type> Foam::rawIOField<Type>::readContents(const IOobject& io)
{ {
rio.readOpt(IOobjectOption::MUST_READ); rio.readOpt(IOobjectOption::MUST_READ);
} }
rio.resetHeader();
rawIOField<Type> reader(rio); rawIOField<Type> reader(rio);

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2017 OpenFOAM Foundation Copyright (C) 2017 OpenFOAM Foundation
Copyright (C) 2019-2023 OpenCFD Ltd. Copyright (C) 2019-2025 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,7 +32,7 @@ Description
taking an Istream or ISstream. Aborts at any attempt to read from it. taking an Istream or ISstream. Aborts at any attempt to read from it.
Note Note
The inheritance from an empty IStringStream is solely for convenience The inheritance from an empty ICharStream is solely for convenience
of implementation and should not be relied upon. of implementation and should not be relied upon.
SourceFiles SourceFiles
@ -43,7 +43,8 @@ SourceFiles
#ifndef Foam_dummyISstream_H #ifndef Foam_dummyISstream_H
#define Foam_dummyISstream_H #define Foam_dummyISstream_H
#include "StringStream.H" #include "autoPtr.H"
#include "SpanStream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -56,7 +57,7 @@ namespace Foam
class dummyISstream class dummyISstream
: :
public IStringStream public ICharStream
{ {
public: public:
@ -69,6 +70,15 @@ public:
virtual ~dummyISstream() = default; virtual ~dummyISstream() = default;
// Factory Methods
//- Return a dummyISstream
static autoPtr<ISstream> New()
{
return autoPtr<ISstream>(new dummyISstream());
}
// Member Functions // Member Functions
// Stream-state // Stream-state

View File

@ -269,7 +269,7 @@ public:
// Edit // Edit
//- Swap with plain List content. Implies shrink_to_fit(). //- Swap with plain List content. Implies shrink_to_fit().
inline void swap(List<T>& list); inline void swap(List<T>& other);
//- Swap content, independent of sizing parameter //- Swap content, independent of sizing parameter
template<int AnySizeMin> template<int AnySizeMin>

View File

@ -567,12 +567,12 @@ inline void Foam::DynamicField<T, SizeMin>::shrink_to_fit()
template<class T, int SizeMin> template<class T, int SizeMin>
inline void inline void
Foam::DynamicField<T, SizeMin>::swap(List<T>& list) Foam::DynamicField<T, SizeMin>::swap(List<T>& other)
{ {
if if
( (
static_cast<const List<T>*>(this) static_cast<const List<T>*>(this)
== static_cast<const List<T>*>(&list) == static_cast<const List<T>*>(&other)
) )
{ {
return; // Self-swap is a no-op return; // Self-swap is a no-op
@ -582,7 +582,7 @@ Foam::DynamicField<T, SizeMin>::swap(List<T>& list)
this->shrink_to_fit(); this->shrink_to_fit();
// Swap storage and addressable size // Swap storage and addressable size
UList<T>::swap(list); UList<T>::swap(other);
// Update capacity // Update capacity
capacity_ = List<T>::size(); capacity_ = List<T>::size();
@ -658,17 +658,22 @@ inline void Foam::DynamicField<T, SizeMin>::transfer
{ {
if if
( (
static_cast<const List<T>*>(this) FOAM_UNLIKELY
== static_cast<const List<T>*>(&list) (
static_cast<const UList<T>*>(this)
== static_cast<const UList<T>*>(&list)
)
) )
{ {
return; // Self-assignment is a no-op return; // Self-assignment is a no-op
} }
// Take over storage as-is (without shrink) // Consistent allocated sizing
capacity_ = list.capacity(); List<T>::setAddressableSize(capacity_);
Field<T>::transfer(static_cast<List<T>&>(list)); Field<T>::transfer(static_cast<List<T>&>(list));
list.clearStorage(); // capacity=0 etc.
capacity_ = list.capacity();
list.setCapacity_unsafe(0); // All contents moved
} }
@ -681,17 +686,22 @@ inline void Foam::DynamicField<T, SizeMin>::transfer
{ {
if if
( (
static_cast<const List<T>*>(this) FOAM_UNLIKELY
== static_cast<const List<T>*>(&list) (
static_cast<const UList<T>*>(this)
== static_cast<const UList<T>*>(&list)
)
) )
{ {
return; // Self-assignment is a no-op return; // Self-assignment is a no-op
} }
// Take over storage as-is (without shrink) // Consistent allocated sizing
capacity_ = list.capacity(); List<T>::setAddressableSize(capacity_);
Field<T>::transfer(static_cast<List<T>&>(list)); Field<T>::transfer(static_cast<List<T>&>(list));
list.clearStorage(); // capacity=0 etc.
capacity_ = list.capacity();
list.setCapacity_unsafe(0); // All contents moved
} }
@ -744,7 +754,14 @@ inline void Foam::DynamicField<T, SizeMin>::push_back
const UList<T>& list const UList<T>& list
) )
{ {
if (this == &list) if
(
FOAM_UNLIKELY
(
static_cast<const UList<T>*>(this)
== static_cast<const UList<T>*>(&list)
)
)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Attempted push_back to self" << "Attempted push_back to self"
@ -764,7 +781,14 @@ inline void Foam::DynamicField<T, SizeMin>::push_back
List<T>&& list List<T>&& list
) )
{ {
if (this == &list) if
(
FOAM_UNLIKELY
(
static_cast<const UList<T>*>(this)
== static_cast<const UList<T>*>(&list)
)
)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Attempted push_back to self" << "Attempted push_back to self"
@ -774,6 +798,7 @@ inline void Foam::DynamicField<T, SizeMin>::push_back
const label idx = List<T>::size(); const label idx = List<T>::size();
resize(idx + list.size()); resize(idx + list.size());
// Move the elements
std::move(list.begin(), list.end(), this->begin(idx)); std::move(list.begin(), list.end(), this->begin(idx));
list.clear(); list.clear();
@ -880,7 +905,7 @@ inline void Foam::DynamicField<T, SizeMin>::operator=
List<T>&& list List<T>&& list
) )
{ {
transfer(list); this->transfer(list);
} }
@ -890,7 +915,7 @@ inline void Foam::DynamicField<T, SizeMin>::operator=
DynamicField<T, SizeMin>&& list DynamicField<T, SizeMin>&& list
) )
{ {
transfer(list); this->transfer(list);
} }
@ -901,7 +926,7 @@ inline void Foam::DynamicField<T, SizeMin>::operator=
DynamicField<T, AnySizeMin>&& list DynamicField<T, AnySizeMin>&& list
) )
{ {
transfer(list); this->transfer(list);
} }
@ -912,7 +937,7 @@ inline void Foam::DynamicField<T, SizeMin>::operator=
DynamicList<T, AnySizeMin>&& list DynamicList<T, AnySizeMin>&& list
) )
{ {
transfer(list); this->transfer(list);
} }

View File

@ -39,8 +39,7 @@ namespace Foam
typedef IOField<diagTensorField> diagTensorFieldIOField; typedef IOField<diagTensorField> diagTensorFieldIOField;
//! Compact IO for a Field of diagTensorField //! Compact IO for a Field of diagTensorField
typedef CompactIOField<diagTensorField, diagTensor> typedef CompactIOField<diagTensorField> diagTensorFieldCompactIOField;
diagTensorFieldCompactIOField;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -40,7 +40,7 @@ namespace Foam
typedef IOField<labelField> labelFieldIOField; typedef IOField<labelField> labelFieldIOField;
//! Compact IO for a Field of labelField //! Compact IO for a Field of labelField
typedef CompactIOField<labelField, label> labelFieldCompactIOField; typedef CompactIOField<labelField> labelFieldCompactIOField;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -39,7 +39,7 @@ namespace Foam
typedef IOField<scalarField> scalarFieldIOField; typedef IOField<scalarField> scalarFieldIOField;
//! Compact IO for a Field of scalarField //! Compact IO for a Field of scalarField
typedef CompactIOField<scalarField, scalar> scalarFieldCompactIOField; typedef CompactIOField<scalarField> scalarFieldCompactIOField;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -39,7 +39,7 @@ namespace Foam
typedef IOField<sphericalTensorField> sphericalTensorFieldIOField; typedef IOField<sphericalTensorField> sphericalTensorFieldIOField;
//! Compact IO for a Field of sphericalTensorField //! Compact IO for a Field of sphericalTensorField
typedef CompactIOField<sphericalTensorField, sphericalTensor> typedef CompactIOField<sphericalTensorField>
sphericalTensorFieldCompactIOField; sphericalTensorFieldCompactIOField;
} }

View File

@ -39,8 +39,7 @@ namespace Foam
typedef IOField<symmTensorField> symmTensorFieldIOField; typedef IOField<symmTensorField> symmTensorFieldIOField;
//! Compact IO for a Field of symmTensorField //! Compact IO for a Field of symmTensorField
typedef CompactIOField<symmTensorField, symmTensor> typedef CompactIOField<symmTensorField> symmTensorFieldCompactIOField;
symmTensorFieldCompactIOField;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -39,7 +39,7 @@ namespace Foam
typedef IOField<tensorField> tensorFieldIOField; typedef IOField<tensorField> tensorFieldIOField;
//! Compact IO for a Field of tensorField //! Compact IO for a Field of tensorField
typedef CompactIOField<tensorField, tensor> tensorFieldCompactIOField; typedef CompactIOField<tensorField> tensorFieldCompactIOField;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -39,7 +39,7 @@ namespace Foam
typedef IOField<vector2DField> vector2DFieldIOField; typedef IOField<vector2DField> vector2DFieldIOField;
//! Compact IO for a Field of vector2DField //! Compact IO for a Field of vector2DField
typedef CompactIOField<vector2DField, vector2D> vector2DFieldCompactIOField; typedef CompactIOField<vector2DField> vector2DFieldCompactIOField;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -39,7 +39,7 @@ namespace Foam
typedef IOField<vectorField> vectorFieldIOField; typedef IOField<vectorField> vectorFieldIOField;
//! Compact IO for a Field of vectorField //! Compact IO for a Field of vectorField
typedef CompactIOField<vectorField, vector> vectorFieldCompactIOField; typedef CompactIOField<vectorField> vectorFieldCompactIOField;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -147,7 +147,7 @@ public:
virtual fileName objectPath virtual fileName objectPath
( (
const IOobject& io, const IOobject& io,
const word& typeName const word& typeName //!< currently unused
) const; ) const;
//- Writes a regIOobject (so header, contents and divider). //- Writes a regIOobject (so header, contents and divider).

View File

@ -327,7 +327,7 @@ Foam::fileOperations::dummyFileOperation::readStream
) const ) const
{ {
NotImplemented; NotImplemented;
return autoPtr<ISstream>(new dummyISstream()); return dummyISstream::New();
} }
@ -351,7 +351,7 @@ Foam::fileOperations::dummyFileOperation::NewIFstream
) const ) const
{ {
NotImplemented; NotImplemented;
return autoPtr<ISstream>(new dummyISstream()); return dummyISstream::New();
} }

View File

@ -203,18 +203,21 @@ public:
// (reg)IOobject functionality // (reg)IOobject functionality
//- Search for an object. checkGlobal //- Search for an object
virtual fileName filePath virtual fileName filePath
( (
//! also check undecomposed case
const bool checkGlobal, const bool checkGlobal,
const IOobject& io, const IOobject& io,
//! The wanted object typeName [optional, likely unused]
const word& typeName, const word& typeName,
const bool search const bool search
) const; ) const;
//- Search for a directory. checkGlobal //- Search for a directory
virtual fileName dirPath virtual fileName dirPath
( (
//! also check undecomposed case
const bool checkGlobal, const bool checkGlobal,
const IOobject& io, const IOobject& io,
const bool search const bool search
@ -234,7 +237,7 @@ public:
( (
IOobject&, IOobject&,
const fileName&, const fileName&,
const word& typeName const word& typeName //!< currently unused
) const; ) const;
//- Reads header for regIOobject and returns an ISstream //- Reads header for regIOobject and returns an ISstream
@ -243,7 +246,7 @@ public:
( (
regIOobject&, regIOobject&,
const fileName&, const fileName&,
const word& typeName, const word& typeName, //!< currently unused
const bool readOnProc = true const bool readOnProc = true
) const; ) const;
@ -253,7 +256,7 @@ public:
regIOobject&, regIOobject&,
const bool masterOnly, const bool masterOnly,
const IOstreamOption::streamFormat format, const IOstreamOption::streamFormat format,
const word& typeName const word& typeName //!< forwards to regIOobject
) const; ) const;
//- Generate an ISstream that reads a file //- Generate an ISstream that reads a file

View File

@ -28,7 +28,6 @@ License
#include "fileOperation.H" #include "fileOperation.H"
#include "objectRegistry.H" #include "objectRegistry.H"
#include "labelIOList.H"
#include "registerSwitch.H" #include "registerSwitch.H"
#include "stringOps.H" #include "stringOps.H"
#include "Time.H" #include "Time.H"
@ -728,7 +727,7 @@ bool Foam::fileOperation::exists(IOobject& io) const
( (
isFile(objPath) isFile(objPath)
// object with local scope // object with local scope
&& io.typeHeaderOk<labelIOList>(false) && io.typeHeaderOk<regIOobject>(false)
); );
} }
@ -750,7 +749,7 @@ bool Foam::fileOperation::exists(IOobject& io) const
( (
isFile(originalPath) isFile(originalPath)
// object with local scope // object with local scope
&& io.typeHeaderOk<labelIOList>(false) && io.typeHeaderOk<regIOobject>(false)
); );
} }
} }

View File

@ -684,27 +684,28 @@ public:
// (reg)IOobject functionality // (reg)IOobject functionality
//- Generate disk file name for object. Opposite of filePath. //- Generate disk file name for object. Opposite of filePath.
// Optional wanted typeName.
virtual fileName objectPath virtual fileName objectPath
( (
const IOobject& io, const IOobject& io,
//! The wanted object typeName [optional, likely unused]
const word& typeName const word& typeName
) const; ) const;
//- Search for an object. checkGlobal : also check undecomposed case //- Search for an object
// Optional wanted typeName.
virtual fileName filePath virtual fileName filePath
( (
//! also check undecomposed case
const bool checkGlobal, const bool checkGlobal,
const IOobject&, const IOobject&,
//! The wanted object typeName [optional, likely unused]
const word& typeName, const word& typeName,
const bool search = true const bool search = true
) const = 0; ) const = 0;
//- Search for a directory. checkGlobal : also check undecomposed //- Search for a directory
// case
virtual fileName dirPath virtual fileName dirPath
( (
//! also check undecomposed case
const bool checkGlobal, const bool checkGlobal,
const IOobject& io, const IOobject& io,
const bool search = true const bool search = true
@ -724,7 +725,7 @@ public:
( (
IOobject&, IOobject&,
const fileName&, const fileName&,
const word& typeName const word& typeName //!< frequently unused?
) const = 0; ) const = 0;
//- Reads header for regIOobject and returns an ISstream //- Reads header for regIOobject and returns an ISstream
@ -733,7 +734,7 @@ public:
( (
regIOobject&, regIOobject&,
const fileName&, const fileName&,
const word& typeName, const word& typeName, //!< frequently unused?
const bool readOnProc = true const bool readOnProc = true
) const = 0; ) const = 0;
@ -742,7 +743,9 @@ public:
( (
regIOobject&, regIOobject&,
const bool masterOnly, const bool masterOnly,
//! The format for parallel send/recv
const IOstreamOption::streamFormat format, const IOstreamOption::streamFormat format,
//! forwards to regIOobject
const word& typeName const word& typeName
) const = 0; ) const = 0;

View File

@ -586,7 +586,7 @@ Foam::fileOperations::masterUncollatedFileOperation::read
} }
else else
{ {
isPtr.reset(new dummyISstream()); return dummyISstream::New();
} }
} }

View File

@ -411,20 +411,20 @@ protected:
//- Search (locally!) for object; return info on how it was found. //- Search (locally!) for object; return info on how it was found.
// Does not do any parallel communication. // Does not do any parallel communication.
// checkGlobal : also check undecomposed case
// isFile : true:check for file false:check for directory
// searchType : how was found
// processorsDir : name of processor directory
// instance : instance
virtual fileName filePathInfo virtual fileName filePathInfo
( (
//! also check undecomposed case
const bool checkGlobal, const bool checkGlobal,
//! True (check for file), False (check for directory)
const bool isFile, const bool isFile,
const IOobject& io, const IOobject& io,
const dirIndexList& pDirs, const dirIndexList& pDirs,
const bool search, const bool search,
//! [out] how was found
pathType& searchType, pathType& searchType,
//! [out] name of processor directory
word& processorsDir, word& processorsDir,
//! [out] instance
word& instance word& instance
) const; ) const;
@ -623,19 +623,20 @@ public:
// (reg)IOobject functinality // (reg)IOobject functinality
//- Search for an object. checkGlobal : also check undecomposed case //- Search for an object
virtual fileName filePath virtual fileName filePath
( (
//! also check undecomposed case
const bool checkGlobal, const bool checkGlobal,
const IOobject& io, const IOobject& io,
const word& typeName, const word& typeName, //!< currently unused
const bool search const bool search
) const; ) const;
//- Search for a directory. checkGlobal : also check undecomposed //- Search for a directory
// case
virtual fileName dirPath virtual fileName dirPath
( (
//! also check undecomposed case
const bool checkGlobal, const bool checkGlobal,
const IOobject& io, const IOobject& io,
const bool search const bool search
@ -655,7 +656,7 @@ public:
( (
IOobject&, IOobject&,
const fileName&, const fileName&,
const word& typeName const word& typeName //!< currently unused
) const; ) const;
//- Reads header for regIOobject and returns an ISstream //- Reads header for regIOobject and returns an ISstream
@ -664,7 +665,7 @@ public:
( (
regIOobject&, regIOobject&,
const fileName&, const fileName&,
const word& typeName, const word& typeName, //!< currently unused
const bool readOnProc = true const bool readOnProc = true
) const; ) const;
@ -673,7 +674,9 @@ public:
( (
regIOobject&, regIOobject&,
const bool masterOnly, const bool masterOnly,
//! The format for parallel send/recv
const IOstreamOption::streamFormat format, const IOstreamOption::streamFormat format,
//! forwards to regIOobject
const word& typeName const word& typeName
) const; ) const;

View File

@ -621,7 +621,7 @@ Foam::fileOperations::uncollatedFileOperation::readStream
{ {
if (!readOnProc) if (!readOnProc)
{ {
return autoPtr<ISstream>(new dummyISstream()); return dummyISstream::New();
} }
if (fName.empty()) if (fName.empty())

View File

@ -243,19 +243,20 @@ public:
// (reg)IOobject functionality // (reg)IOobject functionality
//- Search for an object. checkGlobal : also check undecomposed case //- Search for an object
virtual fileName filePath virtual fileName filePath
( (
//! also check undecomposed case
const bool checkGlobal, const bool checkGlobal,
const IOobject& io, const IOobject& io,
const word& typeName, const word& typeName, //!< currently unused
const bool search const bool search
) const; ) const;
//- Search for a directory. checkGlobal : also check undecomposed //- Search for a directory
// case
virtual fileName dirPath virtual fileName dirPath
( (
//! also check undecomposed case
const bool checkGlobal, const bool checkGlobal,
const IOobject& io, const IOobject& io,
const bool search const bool search
@ -275,16 +276,16 @@ public:
( (
IOobject&, IOobject&,
const fileName&, const fileName&,
const word& typeName const word& typeName //!< currently only for debug info
) const; ) const;
//- Reads header for regIOobject and returns an ISstream //- Reads header for regIOobject and returns an ISstream
// to read the contents. //- to read the contents.
virtual autoPtr<ISstream> readStream virtual autoPtr<ISstream> readStream
( (
regIOobject&, regIOobject&,
const fileName&, const fileName&,
const word& typeName, const word& typeName, //!< currently unused
const bool readOnProc = true const bool readOnProc = true
) const; ) const;
@ -293,7 +294,9 @@ public:
( (
regIOobject&, regIOobject&,
const bool masterOnly, const bool masterOnly,
//! The format for parallel send/recv
const IOstreamOption::streamFormat format, const IOstreamOption::streamFormat format,
//! forwards to regIOobject
const word& typeName const word& typeName
) const; ) const;

View File

@ -39,7 +39,7 @@ namespace Foam
typedef IOList<cell> cellIOList; typedef IOList<cell> cellIOList;
//! Compact IO for a List of cell //! Compact IO for a List of cell
typedef CompactIOList<cell, label> cellCompactIOList; typedef CompactIOList<cell> cellCompactIOList;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -39,7 +39,7 @@ namespace Foam
typedef IOList<edge> edgeIOList; typedef IOList<edge> edgeIOList;
//! Compact IO for a List of edge //! Compact IO for a List of edge
typedef CompactIOList<edge, label> edgeCompactIOList; typedef CompactIOList<edge> edgeCompactIOList;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -39,7 +39,7 @@ namespace Foam
typedef IOList<face> faceIOList; typedef IOList<face> faceIOList;
//! Compact IO for a List of face //! Compact IO for a List of face
typedef CompactIOList<face, label> faceCompactIOList; typedef CompactIOList<face> faceCompactIOList;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -28,8 +28,8 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef cellZoneMesh_H #ifndef Foam_cellZoneMesh_H
#define cellZoneMesh_H #define Foam_cellZoneMesh_H
#include "ZoneMesh.H" #include "ZoneMesh.H"
#include "cellZone.H" #include "cellZone.H"

View File

@ -27,12 +27,12 @@ Typedef
Foam::cellZoneMesh Foam::cellZoneMesh
Description Description
A ZoneMesh with the type cellZone A ZoneMesh with cellZone content on a polyMesh
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef cellZoneMeshFwd_H #ifndef Foam_cellZoneMeshFwd_H
#define cellZoneMeshFwd_H #define Foam_cellZoneMeshFwd_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -28,8 +28,8 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef faceZoneMesh_H #ifndef Foam_faceZoneMesh_H
#define faceZoneMesh_H #define Foam_faceZoneMesh_H
#include "ZoneMesh.H" #include "ZoneMesh.H"
#include "faceZone.H" #include "faceZone.H"

View File

@ -27,12 +27,12 @@ Typedef
Foam::faceZoneMesh Foam::faceZoneMesh
Description Description
A ZoneMesh with the type faceZone A ZoneMesh with faceZone content on a polyMesh
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef faceZoneMeshFwd_H #ifndef Foam_faceZoneMeshFwd_H
#define faceZoneMeshFwd_H #define Foam_faceZoneMeshFwd_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -28,8 +28,8 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef pointZoneMesh_H #ifndef Foam_pointZoneMesh_H
#define pointZoneMesh_H #define Foam_pointZoneMesh_H
#include "ZoneMesh.H" #include "ZoneMesh.H"
#include "pointZone.H" #include "pointZone.H"

View File

@ -27,12 +27,12 @@ Typedef
Foam::pointZoneMesh Foam::pointZoneMesh
Description Description
A ZoneMesh with the type pointZone A ZoneMesh with pointZone content on a polyMesh
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef pointZoneMeshFwd_H #ifndef Foam_pointZoneMeshFwd_H
#define pointZoneMeshFwd_H #define Foam_pointZoneMeshFwd_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -39,7 +39,7 @@ namespace Foam
typedef IOList<scalarList> scalarListIOList; typedef IOList<scalarList> scalarListIOList;
//! Compact IO for a List of scalarList //! Compact IO for a List of scalarList
typedef CompactIOList<scalarList, scalar> scalarListCompactIOList; typedef CompactIOList<scalarList> scalarListCompactIOList;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -39,7 +39,7 @@ namespace Foam
typedef IOList<vectorList> vectorListIOList; typedef IOList<vectorList> vectorListIOList;
//! Compact IO for a List of vectorList //! Compact IO for a List of vectorList
typedef CompactIOList<vectorList, vector> vectorListCompactIOList; typedef CompactIOList<vectorList> vectorListCompactIOList;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

Some files were not shown because too many files have changed in this diff Show More