From 2446f3f0c72dc07c6a1b01387e8d444ff35a0aff Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Mon, 25 Aug 2025 15:09:31 +0200 Subject: [PATCH 1/6] ENH: handle 'void' type in IOobject::typeHeaderOk - can be used in most places where checkType=false is used ENH: add non-const get() method to HashPtrTable - allows checking and modification (symmetric with PtrList methods) STYLE: improve annotations in fileOperations headers --- applications/test/HashPtrTable/Make/files | 2 +- ...t-HashPtrTable.C => Test-HashPtrTable.cxx} | 0 applications/test/HashTable2/Make/files | 2 +- ...{Test-HashTable2.C => Test-HashTable2.cxx} | 0 applications/test/HashTable3/Make/files | 2 +- ...{Test-HashTable3.C => Test-HashTable3.cxx} | 0 applications/test/IOobjectList/Make/files | 2 +- ...t-IOobjectList.C => Test-IOobjectList.cxx} | 0 applications/test/PtrList/Make/files | 2 +- .../{Test-PtrList.C => Test-PtrList.cxx} | 0 .../HashTables/HashPtrTable/HashPtrTable.H | 8 +++- .../HashTables/HashPtrTable/HashPtrTableI.H | 15 +++++- src/OpenFOAM/db/IOobject/IOobject.H | 46 +++++++++++-------- src/OpenFOAM/db/IOobject/IOobjectI.H | 15 +++++- src/OpenFOAM/db/IOobject/IOobjectReadHeader.C | 16 ++----- src/OpenFOAM/db/IOobject/IOobjectTemplates.C | 37 +++++++++++---- .../db/IOstreams/dummy/dummyISstream.H | 18 ++++++-- .../collatedFileOperation.H | 2 +- .../dummyFileOperation/dummyFileOperation.C | 4 +- .../dummyFileOperation/dummyFileOperation.H | 13 ++++-- .../fileOperation/fileOperation.C | 5 +- .../fileOperation/fileOperation.H | 17 ++++--- .../masterUncollatedFileOperation.C | 2 +- .../masterUncollatedFileOperation.H | 25 +++++----- .../uncollatedFileOperation.C | 2 +- .../uncollatedFileOperation.H | 17 ++++--- .../polyMesh/zones/ZoneMesh/cellZoneMesh.H | 4 +- .../polyMesh/zones/ZoneMesh/cellZoneMeshFwd.H | 6 +-- .../polyMesh/zones/ZoneMesh/faceZoneMesh.H | 4 +- .../polyMesh/zones/ZoneMesh/faceZoneMeshFwd.H | 6 +-- .../polyMesh/zones/ZoneMesh/pointZoneMesh.H | 4 +- .../zones/ZoneMesh/pointZoneMeshFwd.H | 6 +-- .../cellSources/fieldToCell/fieldToCell.C | 4 +- 33 files changed, 180 insertions(+), 106 deletions(-) rename applications/test/HashPtrTable/{Test-HashPtrTable.C => Test-HashPtrTable.cxx} (100%) rename applications/test/HashTable2/{Test-HashTable2.C => Test-HashTable2.cxx} (100%) rename applications/test/HashTable3/{Test-HashTable3.C => Test-HashTable3.cxx} (100%) rename applications/test/IOobjectList/{Test-IOobjectList.C => Test-IOobjectList.cxx} (100%) rename applications/test/PtrList/{Test-PtrList.C => Test-PtrList.cxx} (100%) diff --git a/applications/test/HashPtrTable/Make/files b/applications/test/HashPtrTable/Make/files index 00d71a8230..151efd2238 100644 --- a/applications/test/HashPtrTable/Make/files +++ b/applications/test/HashPtrTable/Make/files @@ -1,3 +1,3 @@ -Test-HashPtrTable.C +Test-HashPtrTable.cxx EXE = $(FOAM_USER_APPBIN)/Test-HashPtrTable diff --git a/applications/test/HashPtrTable/Test-HashPtrTable.C b/applications/test/HashPtrTable/Test-HashPtrTable.cxx similarity index 100% rename from applications/test/HashPtrTable/Test-HashPtrTable.C rename to applications/test/HashPtrTable/Test-HashPtrTable.cxx diff --git a/applications/test/HashTable2/Make/files b/applications/test/HashTable2/Make/files index e5bc377b8b..8deef4203f 100644 --- a/applications/test/HashTable2/Make/files +++ b/applications/test/HashTable2/Make/files @@ -1,3 +1,3 @@ -Test-HashTable2.C +Test-HashTable2.cxx EXE = $(FOAM_USER_APPBIN)/Test-HashTable2 diff --git a/applications/test/HashTable2/Test-HashTable2.C b/applications/test/HashTable2/Test-HashTable2.cxx similarity index 100% rename from applications/test/HashTable2/Test-HashTable2.C rename to applications/test/HashTable2/Test-HashTable2.cxx diff --git a/applications/test/HashTable3/Make/files b/applications/test/HashTable3/Make/files index 67aef16a29..94e9a840d7 100644 --- a/applications/test/HashTable3/Make/files +++ b/applications/test/HashTable3/Make/files @@ -1,3 +1,3 @@ -Test-HashTable3.C +Test-HashTable3.cxx EXE = $(FOAM_USER_APPBIN)/Test-HashTable3 diff --git a/applications/test/HashTable3/Test-HashTable3.C b/applications/test/HashTable3/Test-HashTable3.cxx similarity index 100% rename from applications/test/HashTable3/Test-HashTable3.C rename to applications/test/HashTable3/Test-HashTable3.cxx diff --git a/applications/test/IOobjectList/Make/files b/applications/test/IOobjectList/Make/files index c09b00ecaa..ee98a34a3a 100644 --- a/applications/test/IOobjectList/Make/files +++ b/applications/test/IOobjectList/Make/files @@ -1,3 +1,3 @@ -Test-IOobjectList.C +Test-IOobjectList.cxx EXE = $(FOAM_USER_APPBIN)/Test-IOobjectList diff --git a/applications/test/IOobjectList/Test-IOobjectList.C b/applications/test/IOobjectList/Test-IOobjectList.cxx similarity index 100% rename from applications/test/IOobjectList/Test-IOobjectList.C rename to applications/test/IOobjectList/Test-IOobjectList.cxx diff --git a/applications/test/PtrList/Make/files b/applications/test/PtrList/Make/files index e3e9b2724a..e2e598256c 100644 --- a/applications/test/PtrList/Make/files +++ b/applications/test/PtrList/Make/files @@ -1,3 +1,3 @@ -Test-PtrList.C +Test-PtrList.cxx EXE = $(FOAM_USER_APPBIN)/Test-PtrList diff --git a/applications/test/PtrList/Test-PtrList.C b/applications/test/PtrList/Test-PtrList.cxx similarity index 100% rename from applications/test/PtrList/Test-PtrList.C rename to applications/test/PtrList/Test-PtrList.cxx diff --git a/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.H b/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.H index 6239afd297..ccd0dbe566 100644 --- a/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.H +++ b/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.H @@ -149,6 +149,10 @@ public: //- if the key does not exist in the table. 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 @@ -234,7 +238,9 @@ public: inline bool emplace(const Key& key, Args&&... args); //- 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 inline T& emplace_set(const Key& key, Args&&... args); diff --git a/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTableI.H b/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTableI.H index d870d58209..6c786b27c3 100644 --- a/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTableI.H +++ b/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTableI.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018-2023 OpenCFD Ltd. + Copyright (C) 2018-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -57,6 +57,19 @@ inline const T* Foam::HashPtrTable::get(const Key& key) const } +template +inline T* Foam::HashPtrTable::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 template inline bool Foam::HashPtrTable::emplace diff --git a/src/OpenFOAM/db/IOobject/IOobject.H b/src/OpenFOAM/db/IOobject/IOobject.H index 7044a2651e..dfa1f36f27 100644 --- a/src/OpenFOAM/db/IOobject/IOobject.H +++ b/src/OpenFOAM/db/IOobject/IOobject.H @@ -537,14 +537,15 @@ public: //- True if headerClassName() is non-empty (after reading) 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 + //- Always true for a \c void type. template inline bool isHeaderClass() const; - //- Same as isHeaderClass() - template - bool isHeaderClassName() const { return isHeaderClass(); } - // Meta-data @@ -611,20 +612,18 @@ public: fileName objectRelPath() const; //- Redirect to fileHandler filePath, searching locally. - // When search is false, simply use the current instance, - // otherwise search previous instances. fileName localFilePath ( const word& typeName, + //! False: use current instance; True: search previous instances const bool search=true ) const; //- Redirect to fileHandler filePath, searching up if in parallel. - // When search is false, simply use the current instance, - // otherwise search previous instances. fileName globalFilePath ( const word& typeName, + //! False: use current instance; True: search previous instances const bool search=true ) const; @@ -645,17 +644,29 @@ public: bool readHeader(dictionary& headerDict, Istream& is); //- Read header (respects is_globalIOobject trait) and check its info. + //- A \c void type suppresses trait and type-name checks. template bool typeHeaderOk ( //! 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 const bool search = true, //! Report any check-type failures 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 + 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 //- depending on its is_globalIOobject trait. template @@ -718,19 +729,16 @@ public: //- Copy assignment, copies all values (except the registry) void operator=(const IOobject& io); + + + // Housekeeping + + //- Same as isHeaderClass() + template + bool isHeaderClassName() const { return isHeaderClass(); } }; -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -//- Specialization for \c void always returns true (no headerClassName check). -template<> -inline bool IOobject::isHeaderClass() const -{ - return true; -} - - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam diff --git a/src/OpenFOAM/db/IOobject/IOobjectI.H b/src/OpenFOAM/db/IOobject/IOobjectI.H index 9fe9023f94..da700acdeb 100644 --- a/src/OpenFOAM/db/IOobject/IOobjectI.H +++ b/src/OpenFOAM/db/IOobject/IOobjectI.H @@ -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 inline bool Foam::IOobject::isHeaderClass() const { - return (Type::typeName == headerClassName_); + if constexpr (std::is_void_v) + { + return true; + } + else + { + return (Type::typeName == headerClassName_); + } } diff --git a/src/OpenFOAM/db/IOobject/IOobjectReadHeader.C b/src/OpenFOAM/db/IOobject/IOobjectReadHeader.C index 1192714397..a84d7b34c0 100644 --- a/src/OpenFOAM/db/IOobject/IOobjectReadHeader.C +++ b/src/OpenFOAM/db/IOobject/IOobjectReadHeader.C @@ -215,17 +215,13 @@ bool Foam::IOobject::readAndCheckHeader ok = handler.readHeader(*this, fName, typeName); UPstream::parRun(oldParRun); - if - ( - ok && checkType - && !typeName.empty() && headerClassName_ != typeName - ) + if (ok && checkType && !isHeaderClass(typeName)) { ok = false; if (verbose) { WarningInFunction - << "Unexpected class name \"" << headerClassName_ + << "Unexpected class name \"" << headerClassName() << "\" expected \"" << typeName << "\" when reading " << fName << endl; } @@ -251,17 +247,13 @@ bool Foam::IOobject::readAndCheckHeader ); ok = handler.readHeader(*this, fName, typeName); - if - ( - ok && checkType - && !typeName.empty() && headerClassName_ != typeName - ) + if (ok && checkType && !isHeaderClass(typeName)) { ok = false; if (verbose) { WarningInFunction - << "Unexpected class name \"" << headerClassName_ + << "Unexpected class name \"" << headerClassName() << "\" expected \"" << typeName << "\" when reading " << fName << endl; } diff --git a/src/OpenFOAM/db/IOobject/IOobjectTemplates.C b/src/OpenFOAM/db/IOobject/IOobjectTemplates.C index bbd23108d9..3c557b34f1 100644 --- a/src/OpenFOAM/db/IOobject/IOobjectTemplates.C +++ b/src/OpenFOAM/db/IOobject/IOobjectTemplates.C @@ -42,14 +42,35 @@ bool Foam::IOobject::typeHeaderOk const bool verbose ) { - return readAndCheckHeader - ( - is_globalIOobject::value, - Type::typeName, - checkType, - search, - verbose - ); + if constexpr (std::is_void_v) + { + return readAndCheckHeader + ( + false, // isGlobal (false) + word::null, // typeName (n/a) + false, // checkType (false) + search, + verbose + ); + } + else + { + return readAndCheckHeader + ( + is_globalIOobject::value, + Type::typeName, + checkType, + search, + verbose + ); + } +} + + +template +bool Foam::IOobject::typeHeaderOk(const bool checkType, const bool verbose) +{ + return typeHeaderOk(checkType, Searching, verbose); } diff --git a/src/OpenFOAM/db/IOstreams/dummy/dummyISstream.H b/src/OpenFOAM/db/IOstreams/dummy/dummyISstream.H index ba9fce3320..1a95bf351d 100644 --- a/src/OpenFOAM/db/IOstreams/dummy/dummyISstream.H +++ b/src/OpenFOAM/db/IOstreams/dummy/dummyISstream.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2017 OpenFOAM Foundation - Copyright (C) 2019-2023 OpenCFD Ltd. + Copyright (C) 2019-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -32,7 +32,7 @@ Description taking an Istream or ISstream. Aborts at any attempt to read from it. 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. SourceFiles @@ -43,7 +43,8 @@ SourceFiles #ifndef Foam_dummyISstream_H #define Foam_dummyISstream_H -#include "StringStream.H" +#include "autoPtr.H" +#include "SpanStream.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -56,7 +57,7 @@ namespace Foam class dummyISstream : - public IStringStream + public ICharStream { public: @@ -69,6 +70,15 @@ public: virtual ~dummyISstream() = default; + // Factory Methods + + //- Return a dummyISstream + static autoPtr New() + { + return autoPtr(new dummyISstream()); + } + + // Member Functions // Stream-state diff --git a/src/OpenFOAM/global/fileOperations/collatedFileOperation/collatedFileOperation.H b/src/OpenFOAM/global/fileOperations/collatedFileOperation/collatedFileOperation.H index 04acd2ae0f..9402e89bd9 100644 --- a/src/OpenFOAM/global/fileOperations/collatedFileOperation/collatedFileOperation.H +++ b/src/OpenFOAM/global/fileOperations/collatedFileOperation/collatedFileOperation.H @@ -147,7 +147,7 @@ public: virtual fileName objectPath ( const IOobject& io, - const word& typeName + const word& typeName //!< currently unused ) const; //- Writes a regIOobject (so header, contents and divider). diff --git a/src/OpenFOAM/global/fileOperations/dummyFileOperation/dummyFileOperation.C b/src/OpenFOAM/global/fileOperations/dummyFileOperation/dummyFileOperation.C index 16abedaf68..c85bcb9a6b 100644 --- a/src/OpenFOAM/global/fileOperations/dummyFileOperation/dummyFileOperation.C +++ b/src/OpenFOAM/global/fileOperations/dummyFileOperation/dummyFileOperation.C @@ -327,7 +327,7 @@ Foam::fileOperations::dummyFileOperation::readStream ) const { NotImplemented; - return autoPtr(new dummyISstream()); + return dummyISstream::New(); } @@ -351,7 +351,7 @@ Foam::fileOperations::dummyFileOperation::NewIFstream ) const { NotImplemented; - return autoPtr(new dummyISstream()); + return dummyISstream::New(); } diff --git a/src/OpenFOAM/global/fileOperations/dummyFileOperation/dummyFileOperation.H b/src/OpenFOAM/global/fileOperations/dummyFileOperation/dummyFileOperation.H index 5195fe2eea..c53861c70d 100644 --- a/src/OpenFOAM/global/fileOperations/dummyFileOperation/dummyFileOperation.H +++ b/src/OpenFOAM/global/fileOperations/dummyFileOperation/dummyFileOperation.H @@ -203,18 +203,21 @@ public: // (reg)IOobject functionality - //- Search for an object. checkGlobal + //- Search for an object virtual fileName filePath ( + //! also check undecomposed case const bool checkGlobal, const IOobject& io, + //! The wanted object typeName [optional, likely unused] const word& typeName, const bool search ) const; - //- Search for a directory. checkGlobal + //- Search for a directory virtual fileName dirPath ( + //! also check undecomposed case const bool checkGlobal, const IOobject& io, const bool search @@ -234,7 +237,7 @@ public: ( IOobject&, const fileName&, - const word& typeName + const word& typeName //!< currently unused ) const; //- Reads header for regIOobject and returns an ISstream @@ -243,7 +246,7 @@ public: ( regIOobject&, const fileName&, - const word& typeName, + const word& typeName, //!< currently unused const bool readOnProc = true ) const; @@ -253,7 +256,7 @@ public: regIOobject&, const bool masterOnly, const IOstreamOption::streamFormat format, - const word& typeName + const word& typeName //!< forwards to regIOobject ) const; //- Generate an ISstream that reads a file diff --git a/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.C b/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.C index 8193f845ad..2d7f0839d5 100644 --- a/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.C +++ b/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.C @@ -28,7 +28,6 @@ License #include "fileOperation.H" #include "objectRegistry.H" -#include "labelIOList.H" #include "registerSwitch.H" #include "stringOps.H" #include "Time.H" @@ -728,7 +727,7 @@ bool Foam::fileOperation::exists(IOobject& io) const ( isFile(objPath) // object with local scope - && io.typeHeaderOk(false) + && io.typeHeaderOk(false) ); } @@ -750,7 +749,7 @@ bool Foam::fileOperation::exists(IOobject& io) const ( isFile(originalPath) // object with local scope - && io.typeHeaderOk(false) + && io.typeHeaderOk(false) ); } } diff --git a/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.H b/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.H index 852e0b02d6..0850d3d87c 100644 --- a/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.H +++ b/src/OpenFOAM/global/fileOperations/fileOperation/fileOperation.H @@ -684,27 +684,28 @@ public: // (reg)IOobject functionality //- Generate disk file name for object. Opposite of filePath. - // Optional wanted typeName. virtual fileName objectPath ( const IOobject& io, + //! The wanted object typeName [optional, likely unused] const word& typeName ) const; - //- Search for an object. checkGlobal : also check undecomposed case - // Optional wanted typeName. + //- Search for an object virtual fileName filePath ( + //! also check undecomposed case const bool checkGlobal, const IOobject&, + //! The wanted object typeName [optional, likely unused] const word& typeName, const bool search = true ) const = 0; - //- Search for a directory. checkGlobal : also check undecomposed - // case + //- Search for a directory virtual fileName dirPath ( + //! also check undecomposed case const bool checkGlobal, const IOobject& io, const bool search = true @@ -724,7 +725,7 @@ public: ( IOobject&, const fileName&, - const word& typeName + const word& typeName //!< frequently unused? ) const = 0; //- Reads header for regIOobject and returns an ISstream @@ -733,7 +734,7 @@ public: ( regIOobject&, const fileName&, - const word& typeName, + const word& typeName, //!< frequently unused? const bool readOnProc = true ) const = 0; @@ -742,7 +743,9 @@ public: ( regIOobject&, const bool masterOnly, + //! The format for parallel send/recv const IOstreamOption::streamFormat format, + //! forwards to regIOobject const word& typeName ) const = 0; diff --git a/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.C b/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.C index 81c2ad7c20..dd15a6eab5 100644 --- a/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.C +++ b/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.C @@ -586,7 +586,7 @@ Foam::fileOperations::masterUncollatedFileOperation::read } else { - isPtr.reset(new dummyISstream()); + return dummyISstream::New(); } } diff --git a/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.H b/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.H index 0af0a1e552..c5787dcd73 100644 --- a/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.H +++ b/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.H @@ -411,20 +411,20 @@ protected: //- Search (locally!) for object; return info on how it was found. // 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 ( + //! also check undecomposed case const bool checkGlobal, + //! True (check for file), False (check for directory) const bool isFile, const IOobject& io, const dirIndexList& pDirs, const bool search, + //! [out] how was found pathType& searchType, + //! [out] name of processor directory word& processorsDir, + //! [out] instance word& instance ) const; @@ -623,19 +623,20 @@ public: // (reg)IOobject functinality - //- Search for an object. checkGlobal : also check undecomposed case + //- Search for an object virtual fileName filePath ( + //! also check undecomposed case const bool checkGlobal, const IOobject& io, - const word& typeName, + const word& typeName, //!< currently unused const bool search ) const; - //- Search for a directory. checkGlobal : also check undecomposed - // case + //- Search for a directory virtual fileName dirPath ( + //! also check undecomposed case const bool checkGlobal, const IOobject& io, const bool search @@ -655,7 +656,7 @@ public: ( IOobject&, const fileName&, - const word& typeName + const word& typeName //!< currently unused ) const; //- Reads header for regIOobject and returns an ISstream @@ -664,7 +665,7 @@ public: ( regIOobject&, const fileName&, - const word& typeName, + const word& typeName, //!< currently unused const bool readOnProc = true ) const; @@ -673,7 +674,9 @@ public: ( regIOobject&, const bool masterOnly, + //! The format for parallel send/recv const IOstreamOption::streamFormat format, + //! forwards to regIOobject const word& typeName ) const; diff --git a/src/OpenFOAM/global/fileOperations/uncollatedFileOperation/uncollatedFileOperation.C b/src/OpenFOAM/global/fileOperations/uncollatedFileOperation/uncollatedFileOperation.C index ab41512a30..824c875d19 100644 --- a/src/OpenFOAM/global/fileOperations/uncollatedFileOperation/uncollatedFileOperation.C +++ b/src/OpenFOAM/global/fileOperations/uncollatedFileOperation/uncollatedFileOperation.C @@ -621,7 +621,7 @@ Foam::fileOperations::uncollatedFileOperation::readStream { if (!readOnProc) { - return autoPtr(new dummyISstream()); + return dummyISstream::New(); } if (fName.empty()) diff --git a/src/OpenFOAM/global/fileOperations/uncollatedFileOperation/uncollatedFileOperation.H b/src/OpenFOAM/global/fileOperations/uncollatedFileOperation/uncollatedFileOperation.H index ae9fc3d10e..16a716ca57 100644 --- a/src/OpenFOAM/global/fileOperations/uncollatedFileOperation/uncollatedFileOperation.H +++ b/src/OpenFOAM/global/fileOperations/uncollatedFileOperation/uncollatedFileOperation.H @@ -243,19 +243,20 @@ public: // (reg)IOobject functionality - //- Search for an object. checkGlobal : also check undecomposed case + //- Search for an object virtual fileName filePath ( + //! also check undecomposed case const bool checkGlobal, const IOobject& io, - const word& typeName, + const word& typeName, //!< currently unused const bool search ) const; - //- Search for a directory. checkGlobal : also check undecomposed - // case + //- Search for a directory virtual fileName dirPath ( + //! also check undecomposed case const bool checkGlobal, const IOobject& io, const bool search @@ -275,16 +276,16 @@ public: ( IOobject&, const fileName&, - const word& typeName + const word& typeName //!< currently only for debug info ) const; //- Reads header for regIOobject and returns an ISstream - // to read the contents. + //- to read the contents. virtual autoPtr readStream ( regIOobject&, const fileName&, - const word& typeName, + const word& typeName, //!< currently unused const bool readOnProc = true ) const; @@ -293,7 +294,9 @@ public: ( regIOobject&, const bool masterOnly, + //! The format for parallel send/recv const IOstreamOption::streamFormat format, + //! forwards to regIOobject const word& typeName ) const; diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/cellZoneMesh.H b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/cellZoneMesh.H index d26c2d6be5..f2b4ba6e31 100644 --- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/cellZoneMesh.H +++ b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/cellZoneMesh.H @@ -28,8 +28,8 @@ Description \*---------------------------------------------------------------------------*/ -#ifndef cellZoneMesh_H -#define cellZoneMesh_H +#ifndef Foam_cellZoneMesh_H +#define Foam_cellZoneMesh_H #include "ZoneMesh.H" #include "cellZone.H" diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/cellZoneMeshFwd.H b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/cellZoneMeshFwd.H index dc7cce7494..d64a8acc0a 100644 --- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/cellZoneMeshFwd.H +++ b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/cellZoneMeshFwd.H @@ -27,12 +27,12 @@ Typedef Foam::cellZoneMesh Description - A ZoneMesh with the type cellZone + A ZoneMesh with cellZone content on a polyMesh \*---------------------------------------------------------------------------*/ -#ifndef cellZoneMeshFwd_H -#define cellZoneMeshFwd_H +#ifndef Foam_cellZoneMeshFwd_H +#define Foam_cellZoneMeshFwd_H // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/faceZoneMesh.H b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/faceZoneMesh.H index 87a7241c73..0ab838eaa1 100644 --- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/faceZoneMesh.H +++ b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/faceZoneMesh.H @@ -28,8 +28,8 @@ Description \*---------------------------------------------------------------------------*/ -#ifndef faceZoneMesh_H -#define faceZoneMesh_H +#ifndef Foam_faceZoneMesh_H +#define Foam_faceZoneMesh_H #include "ZoneMesh.H" #include "faceZone.H" diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/faceZoneMeshFwd.H b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/faceZoneMeshFwd.H index 33c8425ff5..277d14c712 100644 --- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/faceZoneMeshFwd.H +++ b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/faceZoneMeshFwd.H @@ -27,12 +27,12 @@ Typedef Foam::faceZoneMesh Description - A ZoneMesh with the type faceZone + A ZoneMesh with faceZone content on a polyMesh \*---------------------------------------------------------------------------*/ -#ifndef faceZoneMeshFwd_H -#define faceZoneMeshFwd_H +#ifndef Foam_faceZoneMeshFwd_H +#define Foam_faceZoneMeshFwd_H // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/pointZoneMesh.H b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/pointZoneMesh.H index 5748cb67b7..c8c6e03ff9 100644 --- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/pointZoneMesh.H +++ b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/pointZoneMesh.H @@ -28,8 +28,8 @@ Description \*---------------------------------------------------------------------------*/ -#ifndef pointZoneMesh_H -#define pointZoneMesh_H +#ifndef Foam_pointZoneMesh_H +#define Foam_pointZoneMesh_H #include "ZoneMesh.H" #include "pointZone.H" diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/pointZoneMeshFwd.H b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/pointZoneMeshFwd.H index 6e0c3da370..a15559d780 100644 --- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/pointZoneMeshFwd.H +++ b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/pointZoneMeshFwd.H @@ -27,12 +27,12 @@ Typedef Foam::pointZoneMesh Description - A ZoneMesh with the type pointZone + A ZoneMesh with pointZone content on a polyMesh \*---------------------------------------------------------------------------*/ -#ifndef pointZoneMeshFwd_H -#define pointZoneMeshFwd_H +#ifndef Foam_pointZoneMeshFwd_H +#define Foam_pointZoneMeshFwd_H // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/meshTools/topoSet/cellSources/fieldToCell/fieldToCell.C b/src/meshTools/topoSet/cellSources/fieldToCell/fieldToCell.C index 6ce00a0484..f4ff780f4f 100644 --- a/src/meshTools/topoSet/cellSources/fieldToCell/fieldToCell.C +++ b/src/meshTools/topoSet/cellSources/fieldToCell/fieldToCell.C @@ -195,7 +195,7 @@ void Foam::fieldToCell::applyToSet << "Cannot read field " << fieldName_ << " from time " << mesh().time().timeName() << endl; } - else if ("volScalarField" == fieldObject.headerClassName()) + else if (fieldObject.isHeaderClass("volScalarField")) { // Note: cannot use volScalarField::typeName since that would // introduce linkage problems (finiteVolume needs meshTools) @@ -209,7 +209,7 @@ void Foam::fieldToCell::applyToSet applyToSet(action, internalVals, set); } - else if ("volVectorField" == fieldObject.headerClassName()) + else if (fieldObject.isHeaderClass("volVectorField")) { // Note: cannot use volVectorField::typeName since that would // introduce linkage problems (finiteVolume needs meshTools) From 3ad17ddf5ed38a96ae21b073e20e5b8097b9f372 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Tue, 26 Aug 2025 12:32:14 +0200 Subject: [PATCH 2/6] ENH: extend UList specializations to include any(), all(), none() - simplifies code with boolList vs. bitSet --- applications/test/bitSet1/Make/files | 2 +- .../{Test-bitSet1.C => Test-bitSet1.cxx} | 0 applications/test/bitSet2/Test-bitSet2.cxx | 19 ++++--- applications/test/boolList/Make/files | 2 +- .../{Test-boolList.C => Test-boolList.cxx} | 8 +-- src/OpenFOAM/containers/Bits/BitOps/BitOps.C | 8 ++- src/OpenFOAM/containers/Bits/BitOps/BitOps.H | 29 +++++----- src/OpenFOAM/containers/Lists/List/UList.H | 31 ++++++++++- src/OpenFOAM/containers/Lists/List/UListI.H | 53 +++++++++++-------- .../containers/Lists/ListOps/ListOps.H | 12 +++++ .../Lists/ListOps/ListOpsTemplates.C | 27 ++++++++++ src/OpenFOAM/primitives/bools/bool/bool.C | 12 ++++- src/OpenFOAM/primitives/bools/bool/bool.H | 6 ++- .../decompositionMethod/decompositionMethod.C | 2 +- 14 files changed, 151 insertions(+), 60 deletions(-) rename applications/test/bitSet1/{Test-bitSet1.C => Test-bitSet1.cxx} (100%) rename applications/test/boolList/{Test-boolList.C => Test-boolList.cxx} (96%) diff --git a/applications/test/bitSet1/Make/files b/applications/test/bitSet1/Make/files index c87b831b38..7104798002 100644 --- a/applications/test/bitSet1/Make/files +++ b/applications/test/bitSet1/Make/files @@ -1,3 +1,3 @@ -Test-bitSet1.C +Test-bitSet1.cxx EXE = $(FOAM_USER_APPBIN)/Test-bitSet1 diff --git a/applications/test/bitSet1/Test-bitSet1.C b/applications/test/bitSet1/Test-bitSet1.cxx similarity index 100% rename from applications/test/bitSet1/Test-bitSet1.C rename to applications/test/bitSet1/Test-bitSet1.cxx diff --git a/applications/test/bitSet2/Test-bitSet2.cxx b/applications/test/bitSet2/Test-bitSet2.cxx index 8f9f5d487e..6b0675b836 100644 --- a/applications/test/bitSet2/Test-bitSet2.cxx +++ b/applications/test/bitSet2/Test-bitSet2.cxx @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018-2021 OpenCFD Ltd. + Copyright (C) 2018-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -75,9 +75,9 @@ inline Ostream& info(const UList& bools) Info<< "size=" << bools.size() << " count=" << BitOps::count(bools) << " !count=" << BitOps::count(bools, false) - << " all:" << BitOps::all(bools) - << " any:" << BitOps::any(bools) - << " none:" << BitOps::none(bools) << nl; + << " all:" << bools.all() + << " any:" << bools.any() + << " none:" << bools.none() << nl; return Info; } @@ -194,8 +194,10 @@ int main(int argc, char *argv[]) { boolList bools = list1.values(); - Info<<"===============" << nl; - Info<<"bools: " << flatOutput(bools) << nl; + Info<< "===============" << nl; + Info<< "bools: " << flatOutput(bools) << nl; + Info<< " "; + info(bools); for (int i : { -10, 0, 8, 15, 32}) { @@ -238,17 +240,18 @@ int main(int argc, char *argv[]) } #ifdef TEST_SFINAE + // This should fail to compile: { labelList labels = list1.toc(); if (labels.test(0)) { - Info<<"no" << endl; + Info<< "no" << endl; } List ptrs(10, nullptr); if (ptrs.get(0)) { - Info<<"no" << endl; + Info<< "no" << endl; } } #endif diff --git a/applications/test/boolList/Make/files b/applications/test/boolList/Make/files index 9cbdcc0808..cde3a1614a 100644 --- a/applications/test/boolList/Make/files +++ b/applications/test/boolList/Make/files @@ -1,3 +1,3 @@ -Test-boolList.C +Test-boolList.cxx EXE = $(FOAM_USER_APPBIN)/Test-boolList diff --git a/applications/test/boolList/Test-boolList.C b/applications/test/boolList/Test-boolList.cxx similarity index 96% rename from applications/test/boolList/Test-boolList.C rename to applications/test/boolList/Test-boolList.cxx index a55fe67a9b..36b96440a8 100644 --- a/applications/test/boolList/Test-boolList.C +++ b/applications/test/boolList/Test-boolList.cxx @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2020-2022 OpenCFD Ltd. + Copyright (C) 2020-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -71,9 +71,9 @@ inline Ostream& info(const UList& bools) Info<< "size=" << bools.size() << " count=" << BitOps::count(bools) << " !count=" << BitOps::count(bools, false) - << " all:" << BitOps::all(bools) - << " any:" << BitOps::any(bools) - << " none:" << BitOps::none(bools) << nl; + << " all:" << bools.all() + << " any:" << bools.any() + << " none:" << bools.none() << nl; return Info; } diff --git a/src/OpenFOAM/containers/Bits/BitOps/BitOps.C b/src/OpenFOAM/containers/Bits/BitOps/BitOps.C index 83f052543c..1e0fbaf938 100644 --- a/src/OpenFOAM/containers/Bits/BitOps/BitOps.C +++ b/src/OpenFOAM/containers/Bits/BitOps/BitOps.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018-2023 OpenCFD Ltd. + Copyright (C) 2018-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -33,6 +33,12 @@ License // * * * * * * * * * * * * * * * * * BitOps * * * * * * * * * * * * * * * * // +unsigned int Foam::BitOps::count(const bitSet& bitset, const bool on) +{ + return bitset.count(on); +} + + // See bitSet::setMany for original implementation void Foam::BitOps::set(List& bools, const labelUList& locations) { diff --git a/src/OpenFOAM/containers/Bits/BitOps/BitOps.H b/src/OpenFOAM/containers/Bits/BitOps/BitOps.H index fb0e1688fb..aa3b8edea2 100644 --- a/src/OpenFOAM/containers/Bits/BitOps/BitOps.H +++ b/src/OpenFOAM/containers/Bits/BitOps/BitOps.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018-2023 OpenCFD Ltd. + Copyright (C) 2018-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -77,26 +77,17 @@ inline unsigned int count(const UList& bools, const bool val=true) 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() -inline bool all(const UList& bools) -{ - return std::all_of(bools.begin(), bools.end(), identityOp()); -} +inline bool all(const UList& bools) { return bools.all(); } //- True if any entries are 'true'. // For compatibility with bitSet::any() -inline bool any(const UList& bools) -{ - return std::any_of(bools.begin(), bools.end(), identityOp()); -} +inline bool any(const UList& bools) { return bools.any(); } //- True if no entries are 'true'. // For compatibility with bitSet::none() -inline bool none(const UList& bools) -{ - return std::none_of(bools.begin(), bools.end(), identityOp()); -} +inline bool none(const UList& bools) { return bools.none(); } //- Set the listed locations (assign 'true'). @@ -150,6 +141,10 @@ List select(const label n, const labelUList& locations); // \return a List of bools List 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. // Similar to bitSet::toc() // @@ -292,13 +287,13 @@ struct bitInfo constexpr bitInfo() noexcept : value(0) {} //- Value construct - explicit bitInfo(UIntType val) : value(val) {} + explicit bitInfo(UIntType val) noexcept : value(val) {} //- Conversion to base type - operator UIntType () const { return value; } + operator UIntType () const noexcept { return value; } //- Conversion to base type - operator UIntType& () { return value; } + operator UIntType& () noexcept { return value; } }; } // End namespace BitOps diff --git a/src/OpenFOAM/containers/Lists/List/UList.H b/src/OpenFOAM/containers/Lists/List/UList.H index a446eca351..15418892d2 100644 --- a/src/OpenFOAM/containers/Lists/List/UList.H +++ b/src/OpenFOAM/containers/Lists/List/UList.H @@ -565,11 +565,38 @@ public: // Special Methods + //- True if all entries are 'true' or if the list is empty. + // \note Method name compatibility with bitSet + template + std::enable_if_t>, bool> + inline all() const + { + return !contains(false); + } + + //- True if any entries are 'true'. + // \note Method name compatibility with bitSet + template + std::enable_if_t>, bool> + inline any() const + { + return contains(true); + } + + //- True if no entries are 'true'. + // \note Method name compatibility with bitSet + template + std::enable_if_t>, bool> + inline none() const + { + return !contains(true); + } + //- Test \c bool value at specified position, //- always false for out-of-range access. // \note Method name compatibility with bitSet, HashSet template - std::enable_if_t, bool> + std::enable_if_t>, bool> inline test(const label i) const { return (i >= 0 && i < size_ && v_[i]); @@ -579,7 +606,7 @@ public: //- always false for out-of-range access. // \note Method name compatibility with bitSet template - std::enable_if_t, bool> + std::enable_if_t>, bool> inline get(const label i) const { return (i >= 0 && i < size_ && v_[i]); diff --git a/src/OpenFOAM/containers/Lists/List/UListI.H b/src/OpenFOAM/containers/Lists/List/UListI.H index 9e544cbfcf..d90e72e74e 100644 --- a/src/OpenFOAM/containers/Lists/List/UListI.H +++ b/src/OpenFOAM/containers/Lists/List/UListI.H @@ -348,29 +348,25 @@ inline void Foam::UList::operator=(const T& val) } -namespace Foam -{ - // Template specialization for bool - template<> - inline const bool& Foam::UList::operator[](const label i) const - { - // Lazy evaluation - return false for out-of-range - if (i >= 0 && i < size_) - { - return v_[i]; - } - - return Foam::pTraits::zero; - } -} // End namespace Foam - - template inline T& Foam::UList::operator[](const label i) { - #ifdef FULLDEBUG - checkIndex(i); - #endif + if constexpr (std::is_same_v>) + { + // 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(Foam::pTraits::null()); + } + } + else + { + #ifdef FULLDEBUG + checkIndex(i); + #endif + } return v_[i]; } @@ -378,9 +374,20 @@ inline T& Foam::UList::operator[](const label i) template inline const T& Foam::UList::operator[](const label i) const { - #ifdef FULLDEBUG - checkIndex(i); - #endif + if constexpr (std::is_same_v>) + { + // Lazy evaluation - return false for out-of-range + if (i < 0 || i >= size_) + { + return Foam::pTraits::null(); + } + } + else + { + #ifdef FULLDEBUG + checkIndex(i); + #endif + } return v_[i]; } diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOps.H b/src/OpenFOAM/containers/Lists/ListOps/ListOps.H index 73b941d3a9..5343eb6384 100644 --- a/src/OpenFOAM/containers/Lists/ListOps/ListOps.H +++ b/src/OpenFOAM/containers/Lists/ListOps/ListOps.H @@ -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 +label count +( + const ListType& input, + typename ListType::const_reference val, + const label start=0 +); + + //- Count the number of matching entries. // When start is specified, any occurrences before start are ignored. // Linear search. diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C index a58efd291e..f743feaf0e 100644 --- a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C +++ b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C @@ -1154,6 +1154,33 @@ bool Foam::ListOps::equal } +template +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 Foam::label Foam::ListOps::count_if ( diff --git a/src/OpenFOAM/primitives/bools/bool/bool.C b/src/OpenFOAM/primitives/bools/bool/bool.C index cb796a5371..09770db906 100644 --- a/src/OpenFOAM/primitives/bools/bool/bool.C +++ b/src/OpenFOAM/primitives/bools/bool/bool.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2018-2021 OpenCFD Ltd. + Copyright (C) 2018-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -38,6 +38,16 @@ const char* const Foam::pTraits::componentNames[] = { "" }; const bool Foam::pTraits::zero = false; const bool Foam::pTraits::one = true; +bool Foam::pTraits::dummy = false; + + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +const bool& Foam::pTraits::null() noexcept +{ + dummy = false; + return dummy; +} // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/primitives/bools/bool/bool.H b/src/OpenFOAM/primitives/bools/bool/bool.H index 090fae4137..b766903d63 100644 --- a/src/OpenFOAM/primitives/bools/bool/bool.H +++ b/src/OpenFOAM/primitives/bools/bool/bool.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2019-2021 OpenCFD Ltd. + Copyright (C) 2019-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -97,6 +97,10 @@ public: static const char* const componentNames[]; static const bool zero; static const bool one; + static bool dummy; //!< Dummy for return reference + + //- Return reference to a (false) dummy value + static const bool& null() noexcept; // Constructors diff --git a/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C b/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C index ba67ac8902..75a30f2f29 100644 --- a/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C +++ b/src/parallel/decompose/decompositionMethods/decompositionMethod/decompositionMethod.C @@ -512,7 +512,7 @@ Foam::labelList Foam::decompositionMethod::decompose const bool hasUnblocked = returnReduceOr ( - !blockedFace.empty() && !BitOps::all(blockedFace) + !blockedFace.empty() && !blockedFace.all() ); From a85b0f073662efc1d13325210aefbd9a36cabfbc Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Wed, 27 Aug 2025 09:57:43 +0200 Subject: [PATCH 3/6] STYLE: replace UList specializations with 'if constexpr' handling --- src/OpenFOAM/Make/files | 1 - .../containers/Lists/FixedList/FixedList.C | 8 +-- .../containers/Lists/FixedList/FixedListI.H | 17 +++-- src/OpenFOAM/containers/Lists/List/UList.C | 22 ++---- src/OpenFOAM/containers/Lists/List/UList.H | 13 +--- src/OpenFOAM/containers/Lists/List/UListI.H | 36 +++++++--- src/OpenFOAM/containers/Lists/List/UListIO.C | 53 +++++++++----- .../primitives/chars/lists/charUList.C | 71 ------------------- 8 files changed, 83 insertions(+), 138 deletions(-) delete mode 100644 src/OpenFOAM/primitives/chars/lists/charUList.C diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index 300bb572bf..46375057ca 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -42,7 +42,6 @@ chars = primitives/chars $(chars)/char/char.C $(chars)/wchar/wchar.C $(chars)/lists/charList.C -$(chars)/lists/charUList.C primitives/direction/directionIO.C diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedList.C b/src/OpenFOAM/containers/Lists/FixedList/FixedList.C index 5684fcecae..43ab49c9d4 100644 --- a/src/OpenFOAM/containers/Lists/FixedList/FixedList.C +++ b/src/OpenFOAM/containers/Lists/FixedList/FixedList.C @@ -169,8 +169,8 @@ template bool Foam::FixedList::operator==(const FixedList& list) const { // Can dispatch with - // - std::execution::parallel_unsequenced_policy - // - std::execution::unsequenced_policy + // - std::execution::par_unseq + // - std::execution::unseq return ( // List sizes are identical by definition (template parameter) @@ -185,8 +185,8 @@ bool Foam::FixedList::operator<(const FixedList& list) const // List sizes are identical by definition (template parameter) // Can dispatch with - // - std::execution::parallel_unsequenced_policy - // - std::execution::unsequenced_policy + // - std::execution::par_unseq + // - std::execution::unseq return std::lexicographical_compare ( this->cbegin(), this->cend(), diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H b/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H index 1948846e10..709ea18bb9 100644 --- a/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H +++ b/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2017-2023 OpenCFD Ltd. + Copyright (C) 2017-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -356,12 +356,17 @@ inline void Foam::FixedList::fill(const T& val) template inline void Foam::FixedList::fill(Foam::zero) { - // Usually small enough that parallel execution is pointless... - // Cannot use std::fill (ambiguous conversions for bool, char, etc) - - for (unsigned i = 0; i < N; ++i) + if constexpr (std::is_arithmetic_v) { - v_[i] = Zero; + // Usually small enough that parallel execution is pointless... + std::fill_n(v_, N, T(0)); + } + else + { + for (unsigned i = 0; i < N; ++i) + { + v_[i] = Foam::zero{}; + } } } diff --git a/src/OpenFOAM/containers/Lists/List/UList.C b/src/OpenFOAM/containers/Lists/List/UList.C index d2b0cb67b3..b89edf5494 100644 --- a/src/OpenFOAM/containers/Lists/List/UList.C +++ b/src/OpenFOAM/containers/Lists/List/UList.C @@ -113,8 +113,8 @@ void Foam::UList::deepCopy(const UList& list) else if (this->size_ > 0) { // Can dispatch with - // - std::execution::parallel_unsequenced_policy - // - std::execution::unsequenced_policy + // - std::execution::par_unseq + // - std::execution::unseq std::copy(list.cbegin(), list.cend(), this->v_); } } @@ -150,16 +150,6 @@ void Foam::UList::deepCopy(const IndirectListBase& list) } -// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // - -// This is non-inlined to allow template specializations -template -void Foam::UList::operator=(Foam::zero) -{ - this->fill_uniform(Foam::zero{}); -} - - // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template @@ -244,8 +234,8 @@ template bool Foam::UList::operator==(const UList& list) const { // Can dispatch with - // - std::execution::parallel_unsequenced_policy - // - std::execution::unsequenced_policy + // - std::execution::par_unseq + // - std::execution::unseq return ( (this->size_ == list.size_) @@ -265,8 +255,8 @@ template bool Foam::UList::operator<(const UList& list) const { // Can dispatch with - // - std::execution::parallel_unsequenced_policy - // - std::execution::unsequenced_policy + // - std::execution::par_unseq + // - std::execution::unseq return std::lexicographical_compare ( this->cbegin(), this->cend(), diff --git a/src/OpenFOAM/containers/Lists/List/UList.H b/src/OpenFOAM/containers/Lists/List/UList.H index 15418892d2..bdac7f55a3 100644 --- a/src/OpenFOAM/containers/Lists/List/UList.H +++ b/src/OpenFOAM/containers/Lists/List/UList.H @@ -435,7 +435,7 @@ public: inline void operator=(const T& val); //- Assignment of all entries to zero - void operator=(Foam::zero); + inline void operator=(Foam::zero); // Random access iterator (non-const) @@ -691,17 +691,6 @@ public: }; -// * * * * * * * * * * * * Template Specializations * * * * * * * * * * * * // - -//- Character list writeEntry -template<> -void UList::writeEntry(Ostream& os) const; - -//- Character list assign zero - avoids Foam::zero casting ambiguities -template<> -void UList::operator=(Foam::zero); - - // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // //- Read List contents from Istream, list must have the proper size! diff --git a/src/OpenFOAM/containers/Lists/List/UListI.H b/src/OpenFOAM/containers/Lists/List/UListI.H index d90e72e74e..64956614d4 100644 --- a/src/OpenFOAM/containers/Lists/List/UListI.H +++ b/src/OpenFOAM/containers/Lists/List/UListI.H @@ -53,8 +53,8 @@ template inline void Foam::UList::fill_uniform(const T& val) { // Can dispatch with - // - std::execution::parallel_unsequenced_policy - // - std::execution::unsequenced_policy + // - std::execution::par_unseq + // - std::execution::unseq std::fill_n ( this->v_, this->size_, val @@ -65,15 +65,21 @@ inline void Foam::UList::fill_uniform(const T& val) template inline void Foam::UList::fill_uniform(Foam::zero) { - // Note: ambiguous conversions for char can still cause compilation - // issues. - // May also have special triggers when assigning non-contiguous from zero... - - if constexpr (is_contiguous_v) + if constexpr (std::is_arithmetic_v) { // Can dispatch with - // - std::execution::parallel_unsequenced_policy - // - std::execution::unsequenced_policy + // - std::execution::par_unseq + // - std::execution::unseq + std::fill_n + ( + this->v_, this->size_, T(0) + ); + } + else if constexpr (is_contiguous_v) + { + // Can dispatch with + // - std::execution::par_unseq + // - std::execution::unseq std::fill_n ( this->data_bytes(), this->size_bytes(), char(0) @@ -81,6 +87,9 @@ inline void Foam::UList::fill_uniform(Foam::zero) } else { + // May also have special triggers when assigning non-contiguous + // from zero... + const auto last = (this->v_ + this->size_); for (auto first = this->v_; (first != last); (void)++first) @@ -348,6 +357,15 @@ inline void Foam::UList::operator=(const T& val) } +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +template +inline void Foam::UList::operator=(Foam::zero) +{ + this->fill_uniform(Foam::zero{}); +} + + template inline T& Foam::UList::operator[](const label i) { diff --git a/src/OpenFOAM/containers/Lists/List/UListIO.C b/src/OpenFOAM/containers/Lists/List/UListIO.C index e4e59bc3d5..aac46ebe40 100644 --- a/src/OpenFOAM/containers/Lists/List/UListIO.C +++ b/src/OpenFOAM/containers/Lists/List/UListIO.C @@ -35,30 +35,45 @@ License template void Foam::UList::writeEntry(Ostream& os) const { - const word tag("List<" + word(pTraits::typeName) + '>'); - if (token::compound::isCompound(tag)) + if constexpr (std::is_same_v>) { - os << tag << token::SPACE; - } + // Char data has a compound type: + os << word("List"); - if (size()) - { - os << *this; - } - else if - ( - os.format() == IOstreamOption::BINARY - || std::is_same_v> - ) - { - // Zero-sized binary - Write size only - // NB: special treatment for char data (binary I/O only) - os << label(0); + 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 { - // Zero-sized ASCII - Write size and delimiters - os << label(0) << token::BEGIN_LIST << token::END_LIST; + const word tag("List<" + word(pTraits::typeName) + '>'); + if (token::compound::isCompound(tag)) + { + os << tag << token::SPACE; + } + + if (size()) + { + os << *this; + } + else if (os.format() == IOstreamOption::BINARY) + { + // Zero-sized binary - Write size only + os << label(0); + } + else + { + // Zero-sized ASCII - Write size and delimiters + os << label(0) << token::BEGIN_LIST << token::END_LIST; + } } } diff --git a/src/OpenFOAM/primitives/chars/lists/charUList.C b/src/OpenFOAM/primitives/chars/lists/charUList.C deleted file mode 100644 index 354d4bc073..0000000000 --- a/src/OpenFOAM/primitives/chars/lists/charUList.C +++ /dev/null @@ -1,71 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | www.openfoam.com - \\/ M anipulation | -------------------------------------------------------------------------------- - Copyright (C) 2021-2023 OpenCFD Ltd. -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see . - -\*---------------------------------------------------------------------------*/ - -#include "charList.H" -#include "Istream.H" -#include "Ostream.H" -#include "token.H" - -// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // - -namespace Foam -{ - -template<> -void UList::writeEntry(Ostream& os) const -{ - os << word("List"); - - if (this->size()) - { - // Non-zero size: write as binary, so has leading newline separator. - os << *this; - } - else - { - // Zero-sized binary - Write size only - os << token::SPACE << label(0); - } -} - -} // End namespace Foam - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -namespace Foam -{ - -template<> -void UList::operator=(const Foam::zero) -{ - UList::operator=(char(0)); -} - -} // End namespace Foam - -// ************************************************************************* // From 697b8a14366eb6e1a53e6ff2d8d8bf9406770c6d Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Wed, 27 Aug 2025 09:25:54 +0200 Subject: [PATCH 4/6] ENH: improved handling of PtrList copies/cloning - the logic has been revised to allow list copying with nullptr entries. These previously would have thrown an error. - remove PtrList trimTrailingNull() method. It was unused and would result in inconsistent addressing sizes. FIX: inconsistent sizing used for DynamicList/PtrDynList clearStorage() - older code did not reset addressable size prior to clearStorage() or transfer(). Only a latent bug until memory pools are used. --- applications/test/PtrList/Test-PtrList.cxx | 22 +-- .../Lists/DynamicList/DynamicList.H | 4 +- .../Lists/DynamicList/DynamicListI.H | 145 ++++++++++++------ .../PtrLists/PtrDynList/PtrDynList.H | 10 +- .../PtrLists/PtrDynList/PtrDynListI.H | 103 +++++++++---- .../containers/PtrLists/PtrList/PtrList.C | 92 +++++------ .../containers/PtrLists/PtrList/PtrList.H | 18 ++- .../containers/PtrLists/PtrList/PtrListI.H | 37 ++++- .../PtrLists/PtrListDetail/PtrListDetail.C | 9 +- .../PtrLists/PtrListDetail/PtrListDetail.H | 6 +- .../PtrLists/PtrListDetail/PtrListDetailIO.C | 41 ++++- .../containers/PtrLists/UPtrList/UPtrList.C | 49 +++--- .../containers/PtrLists/UPtrList/UPtrList.H | 15 +- .../fields/Fields/DynamicField/DynamicField.H | 2 +- .../Fields/DynamicField/DynamicFieldI.H | 63 +++++--- 15 files changed, 401 insertions(+), 215 deletions(-) diff --git a/applications/test/PtrList/Test-PtrList.cxx b/applications/test/PtrList/Test-PtrList.cxx index 2df2c5cbf0..88c8cfbffe 100644 --- a/applications/test/PtrList/Test-PtrList.cxx +++ b/applications/test/PtrList/Test-PtrList.cxx @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011 OpenFOAM Foundation - Copyright (C) 2018-2023 OpenCFD Ltd. + Copyright (C) 2018-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -86,20 +86,7 @@ Ostream& printAddr const UPtrList& list ) { - const label len = list.size(); - - // 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; + return list.printAddresses(os); } @@ -176,11 +163,11 @@ Ostream& print { 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); - os << "unused " << name(ptr) << nl; + os << "unused " << Foam::name(ptr) << nl; } } @@ -518,6 +505,7 @@ int main(int argc, char *argv[]) print(Info, dynlist1d); Info<< "addresses:" << nl; + dynlist1d.printAddresses(Info, true); printAddr(Info, dynlist1d); PtrList list1d; diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H index 002610037f..92932c92ba 100644 --- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H +++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H @@ -255,7 +255,7 @@ public: // Edit //- Swap with plain List content. Implies shrink_to_fit(). - inline void swap(List& list); + inline void swap(List& other); //- Swap content, independent of sizing parameter template @@ -264,7 +264,7 @@ public: //- Transfer contents of the argument List into this. inline void transfer(List& list); - //- Transfer contents of any sized DynamicList into this. + //- Transfer contents of any DynamicList into this. template inline void transfer(DynamicList& list); diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H index d452f52d7d..ed94ae38b4 100644 --- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H +++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H @@ -445,6 +445,8 @@ inline void Foam::DynamicList::clear() noexcept template inline void Foam::DynamicList::clearStorage() { + // Consistent allocated sizing + List::setAddressableSize(capacity_); List::clear(); capacity_ = 0; } @@ -465,12 +467,15 @@ inline void Foam::DynamicList::shrink_to_fit() template inline void -Foam::DynamicList::swap(List& list) +Foam::DynamicList::swap(List& other) { if ( - static_cast*>(this) - == static_cast*>(&list) + FOAM_UNLIKELY + ( + static_cast*>(this) + == static_cast*>(&other) + ) ) { return; // Self-swap is a no-op @@ -480,7 +485,7 @@ Foam::DynamicList::swap(List& list) this->shrink_to_fit(); // Swap storage and addressable size - UList::swap(list); + UList::swap(other); // Update capacity capacity_ = List::size(); @@ -496,8 +501,11 @@ inline void Foam::DynamicList::swap { if ( - static_cast*>(this) - == static_cast*>(&other) + FOAM_UNLIKELY + ( + static_cast*>(this) + == static_cast*>(&other) + ) ) { return; // Self-swap is a no-op @@ -515,6 +523,10 @@ template inline void Foam::DynamicList::transfer(List& list) { + // No check for self-assignment (different types) + + // Consistent allocated sizing + List::setAddressableSize(capacity_); List::transfer(list); capacity_ = List::size(); } @@ -530,18 +542,22 @@ Foam::DynamicList::transfer { if ( - static_cast*>(this) - == static_cast*>(&list) + FOAM_UNLIKELY + ( + static_cast*>(this) + == static_cast*>(&list) + ) ) { return; // Self-assignment is a no-op } - // Take over storage as-is (without shrink) - capacity_ = list.capacity(); - + // Consistent allocated sizing + List::setAddressableSize(capacity_); List::transfer(static_cast&>(list)); - list.clearStorage(); // capacity=0 etc. + + capacity_ = list.capacity(); + list.setCapacity_unsafe(0); // All contents moved } @@ -594,7 +610,14 @@ inline void Foam::DynamicList::push_back const UList& list ) { - if (FOAM_UNLIKELY(this == &list)) + if + ( + FOAM_UNLIKELY + ( + static_cast*>(this) + == static_cast*>(&list) + ) + ) { FatalErrorInFunction << "Attempted push_back to self" @@ -665,7 +688,14 @@ inline void Foam::DynamicList::push_back List&& list ) { - if (FOAM_UNLIKELY(this == &list)) + if + ( + FOAM_UNLIKELY + ( + static_cast*>(this) + == static_cast*>(&list) + ) + ) { FatalErrorInFunction << "Attempted push_back to self" @@ -675,6 +705,7 @@ inline void Foam::DynamicList::push_back const label idx = List::size(); resize(idx + list.size()); + // Move the elements std::move(list.begin(), list.end(), this->begin(idx)); list.clear(); @@ -688,7 +719,26 @@ inline void Foam::DynamicList::push_back DynamicList&& list ) { - push_back(std::move(static_cast&>(list))); + if + ( + FOAM_UNLIKELY + ( + static_cast*>(this) + == static_cast*>(&list) + ) + ) + { + FatalErrorInFunction + << "Attempted push_back to self" + << abort(FatalError); + } + + const label idx = List::size(); + resize(idx + list.size()); + + // Move the elements + std::move(list.begin(), list.end(), this->begin(idx)); + list.clearStorage(); // Deletion, capacity=0 etc. } @@ -866,15 +916,22 @@ inline void Foam::DynamicList::operator= template inline void Foam::DynamicList::operator= ( - const DynamicList& lst + const DynamicList& list ) { - if (this == &lst) + if + ( + FOAM_UNLIKELY + ( + static_cast*>(this) + == static_cast*>(&list) + ) + ) { return; // Self-assignment is a no-op } - doAssignDynList(lst); + doAssignDynList(list); } @@ -887,8 +944,11 @@ inline void Foam::DynamicList::operator= { if ( - static_cast*>(this) - == static_cast*>(&list) + FOAM_UNLIKELY + ( + static_cast*>(this) + == static_cast*>(&list) + ) ) { return; // Self-assignment is a no-op @@ -912,44 +972,41 @@ template template inline void Foam::DynamicList::operator= ( - const IndirectListBase& lst + const IndirectListBase& list ) { // NOTE: Self-assignment needs special handling - /// if - /// ( - /// static_cast*>(this) - /// == static_cast*>(&list.values()) - /// ) + // if + // ( + // FOAM_UNLIKELY + // ( + // static_cast*>(this) + // == static_cast*>(&list.values()) + // ) + // ) + // { ... } - doAssignDynList(lst); + doAssignDynList(list); } template inline void Foam::DynamicList::operator= ( - List&& lst + List&& list ) { - clear(); - transfer(lst); + this->transfer(list); } template inline void Foam::DynamicList::operator= ( - DynamicList&& lst + DynamicList&& list ) { - if (this == &lst) - { - return; // Self-assignment is a no-op - } - - clear(); - transfer(lst); + this->transfer(list); } @@ -960,17 +1017,7 @@ inline void Foam::DynamicList::operator= DynamicList&& list ) { - if - ( - static_cast*>(this) - == static_cast*>(&list) - ) - { - return; // Self-assignment is a no-op - } - - clear(); - transfer(list); + this->transfer(list); } diff --git a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H index d7f202e838..c0f47c88ca 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H +++ b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynList.H @@ -238,14 +238,18 @@ public: //- Auto-sizes list as required. inline autoPtr set(const label i, const tmp& 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 //- Copy (clone) assignment - inline void operator=(const PtrList& list); + inline void operator=(const UPtrList& list); //- Copy (clone) assignment inline void operator=(const PtrDynList& list); diff --git a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H index 03be2398f4..c61b342232 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H +++ b/src/OpenFOAM/containers/PtrLists/PtrDynList/PtrDynListI.H @@ -226,6 +226,8 @@ inline void Foam::PtrDynList::clear() template inline void Foam::PtrDynList::clearStorage() { + // Consistent allocated sizing + PtrList::setAddressableSize(capacity_); PtrList::clear(); capacity_ = 0; } @@ -258,8 +260,11 @@ inline void Foam::PtrDynList::swap(PtrList& list) { if ( - static_cast*>(this) - == static_cast*>(&list) + FOAM_UNLIKELY + ( + static_cast*>(this) + == static_cast*>(&list) + ) ) { return; // Self-swap is a no-op @@ -285,8 +290,11 @@ inline void Foam::PtrDynList::swap { if ( - static_cast*>(this) - == static_cast*>(&other) + FOAM_UNLIKELY + ( + static_cast*>(this) + == static_cast*>(&other) + ) ) { return; // Self-swap is a no-op @@ -303,15 +311,10 @@ inline void Foam::PtrDynList::swap template inline void Foam::PtrDynList::transfer(PtrList& list) { - if - ( - static_cast*>(this) - == static_cast*>(&list) - ) - { - return; // Self assignment is a no-op - } + // No check for self-assignment (different types) + // Consistent allocated sizing + PtrList::setAddressableSize(capacity_); PtrList::transfer(list); capacity_ = PtrList::size(); } @@ -326,18 +329,22 @@ inline void Foam::PtrDynList::transfer { if ( - static_cast*>(this) - == static_cast*>(&list) + FOAM_UNLIKELY + ( + static_cast*>(this) + == static_cast*>(&list) + ) ) { return; // Self assignment is a no-op } - // Take over storage as-is (without shrink) - capacity_ = list.capacity(); - + // Consistent allocated sizing + PtrList::setAddressableSize(capacity_); PtrList::transfer(static_cast&>(list)); - list.clearStorage(); // capacity=0 etc. + + capacity_ = list.capacity(); + list.setCapacity_unsafe(0); // All contents moved } @@ -414,8 +421,11 @@ inline void Foam::PtrDynList::push_back { if ( - static_cast*>(this) - == static_cast*>(&other) + FOAM_UNLIKELY + ( + static_cast*>(this) + == static_cast*>(&other) + ) ) { FatalErrorInFunction @@ -557,11 +567,20 @@ inline Foam::autoPtr Foam::PtrDynList::set template -inline void Foam::PtrDynList::reorder(const labelUList& oldToNew) +Foam::Ostream& Foam::PtrDynList::printAddresses +( + Ostream& os, + const bool full +) const { - // Shrinking first is a bit annoying, but saves needing a special version. - this->shrink_to_fit(); - PtrList::reorder(oldToNew); + if (full) + { + return this->ptrs_.printAddresses(os, capacity_); + } + else + { + return UPtrList::printAddresses(os); + } } @@ -570,16 +589,23 @@ inline void Foam::PtrDynList::reorder(const labelUList& oldToNew) template inline void Foam::PtrDynList::operator= ( - const PtrList& list + const UPtrList& list ) { - if (this == &list) + if + ( + FOAM_UNLIKELY + ( + static_cast*>(this) + == static_cast*>(&list) + ) + ) { return; // Self-assignment is a no-op } + this->resize(list.size()); PtrList::operator=(list); - capacity_ = PtrList::size(); } @@ -589,13 +615,20 @@ inline void Foam::PtrDynList::operator= const PtrDynList& list ) { - if (this == &list) + if + ( + FOAM_UNLIKELY + ( + static_cast*>(this) + == static_cast*>(&list) + ) + ) { return; // Self-assignment is a no-op } - PtrList::operator=(list); - capacity_ = PtrList::size(); + this->resize(list.size()); + PtrList::operator=(static_cast&>(list)); } @@ -608,14 +641,18 @@ inline void Foam::PtrDynList::operator= { if ( - static_cast*>(this) - == static_cast*>(&list) + FOAM_UNLIKELY + ( + static_cast*>(this) + == static_cast*>(&list) + ) ) { return; // Self-assignment is a no-op } - PtrList::operator=(list); + this->resize(list.size()); + PtrList::operator=(static_cast&>(list)); capacity_ = PtrList::size(); } diff --git a/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.C b/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.C index 9b082f4940..52f8b420be 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.C +++ b/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2018-2019 OpenCFD Ltd. + Copyright (C) 2018-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -29,26 +29,55 @@ License #include "PtrList.H" #include "SLPtrList.H" -// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // template -Foam::PtrList::PtrList(PtrList& list, bool reuse) -: - UPtrList(list, reuse) +template +void Foam::PtrList::copyPtrList(const UPtrList& list) { - if (!reuse) + // Check for self-assignment here instead of caller + if constexpr (CheckSelf) { - // This works like an inplace clone method - const label len = this->size(); - - for (label i=0; iptrs_[i] = (list[i]).clone().ptr(); + return; // Self-assignment is a no-op + } + } + + const label len = list.size(); + + // Truncate (frees old pointers) or extend the length + PtrList::resize(len); + + for (label i = 0; i < len; ++i) + { + 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 Foam::PtrList::PtrList(const SLPtrList& list) : @@ -122,45 +151,4 @@ void Foam::PtrList::resize(const label newLen) } -// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // - -template -void Foam::PtrList::operator=(const PtrList& 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; iptrs_[i] = (list[i]).clone().ptr(); - } - } -} - - // ************************************************************************* // diff --git a/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H b/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H index 89e4a9688a..c0f4def07e 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H +++ b/src/OpenFOAM/containers/PtrLists/PtrList/PtrList.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2018-2023 OpenCFD Ltd. + Copyright (C) 2018-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -70,6 +70,15 @@ class PtrList : public UPtrList { + // 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 + void copyPtrList(const UPtrList& list); + + protected: // Protected Member Functions @@ -103,7 +112,7 @@ public: inline PtrList(const PtrList& list, const CloneArg& cloneArgs); //- Construct as copy or re-use as specified - PtrList(PtrList& list, bool reuse); + inline PtrList(PtrList& list, bool reuse); //- Copy construct using 'clone()' on each element of SLPtrList\ explicit PtrList(const SLPtrList& list); @@ -221,6 +230,11 @@ public: // 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& list); + //- Copy assignment. // For existing list entries, values are copied from the list. // For new list entries, pointers are cloned from the list. diff --git a/src/OpenFOAM/containers/PtrLists/PtrList/PtrListI.H b/src/OpenFOAM/containers/PtrLists/PtrList/PtrListI.H index 7db0496d3b..49f8766dd9 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrList/PtrListI.H +++ b/src/OpenFOAM/containers/PtrLists/PtrList/PtrListI.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2018-2023 OpenCFD Ltd. + Copyright (C) 2018-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -60,6 +60,23 @@ inline Foam::PtrList::PtrList(PtrList&& list) noexcept {} +template +inline Foam::PtrList::PtrList(PtrList& list, bool reuse) +: + UPtrList() +{ + if (reuse) + { + transfer(list); + } + else + { + // No check for self-assignment + copyPtrList(list); + } +} + + template inline Foam::PtrList::PtrList(UList& list) : @@ -278,7 +295,7 @@ inline Foam::autoPtr Foam::PtrList::release(const label i) template inline void Foam::PtrList::transfer(PtrList& list) { - if (this == &list) + if (FOAM_UNLIKELY(this == &list)) { return; // Self-assignment is a no-op } @@ -290,6 +307,22 @@ inline void Foam::PtrList::transfer(PtrList& list) // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // +template +inline void Foam::PtrList::operator=(const UPtrList& list) +{ + // With check for self-assignment + this->copyPtrList(list); +} + + +template +inline void Foam::PtrList::operator=(const PtrList& list) +{ + // With check for self-assignment + this->copyPtrList(list); +} + + template inline void Foam::PtrList::operator=(PtrList&& list) { diff --git a/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.C b/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.C index c0917472a4..1f324116c0 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.C +++ b/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018-2024 OpenCFD Ltd. + Copyright (C) 2018-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -99,11 +99,10 @@ Foam::label Foam::Detail::PtrListDetail::find_next_not(label pos) const template void Foam::Detail::PtrListDetail::free() { - List& ptrs = *this; - const label len = ptrs.size(); - // Presume they were allocated from front to back... - for (label i = len - 1; i >= 0; --i) + List& ptrs = *this; + + for (auto i = this->size()-1; i >= 0; --i) { delete ptrs[i]; ptrs[i] = nullptr; diff --git a/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.H b/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.H index cc78942272..bd7983a3bf 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.H +++ b/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetail.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018-2024 OpenCFD Ltd. + Copyright (C) 2018-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -147,6 +147,10 @@ public: // Use with care 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 Ostream& write(Ostream& os, const bool trimNull=false) const; diff --git a/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetailIO.C b/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetailIO.C index f3713841d9..558f3394bd 100644 --- a/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetailIO.C +++ b/src/OpenFOAM/containers/PtrLists/PtrListDetail/PtrListDetailIO.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018-2024 OpenCFD Ltd. + Copyright (C) 2018-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -31,6 +31,45 @@ License // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +template +Foam::Ostream& Foam::Detail::PtrListDetail::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 Foam::Ostream& Foam::Detail::PtrListDetail::write ( diff --git a/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.C b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.C index 77b06feec8..396a027e4c 100644 --- a/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.C +++ b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2015-2022 OpenCFD Ltd. + Copyright (C) 2015-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -65,23 +65,6 @@ Foam::label Foam::UPtrList::squeezeNull() } -template -void Foam::UPtrList::trimTrailingNull() -{ - label newLen = this->size(); - - for (label i = newLen-1; i >= 0 && !ptrs_[i]; --i) - { - --newLen; - } - - // Or mutable? - // const_cast&>(ptrs_).setAddressableSize(newLen); - - ptrs_.setAddressableSize(newLen); -} - - template void Foam::UPtrList::reorder(const labelUList& oldToNew, const bool check) { @@ -98,7 +81,7 @@ void Foam::UPtrList::reorder(const labelUList& oldToNew, const bool check) Detail::PtrListDetail newList(len); - for (label i=0; i::reorder(const labelUList& oldToNew, const bool check) newList.checkNonNull(); } - ptrs_.transfer(newList); + // Copy the pointers, do not swap or transfer lists! + ptrs_ = newList; } @@ -148,7 +132,7 @@ void Foam::UPtrList::sortOrder(const labelUList& order, const bool check) Detail::PtrListDetail newList(len); Detail::PtrListDetail guard(len); - for (label i=0; i::sortOrder(const labelUList& order, const bool check) newList.checkNonNull(); } - ptrs_.transfer(newList); + // Copy the pointers, do not swap or transfer lists! + ptrs_ = newList; } // * * * * * * * * * * * * * * * Ostream Operators * * * * * * * * * * * * * // +template +Foam::Ostream& Foam::UPtrList::printAddresses(Ostream& os) const +{ + return ptrs_.printAddresses(os); +} + + +template +Foam::Ostream& Foam::UPtrList::writeList +( + Ostream& os, + const bool trimNull +) const +{ + return ptrs_.write(os, trimNull); +} + + template Foam::Ostream& Foam::operator<<(Ostream& os, const UPtrList& list) { - return list.ptrs_.write(os); + return list.writeList(os, false); // Do not ignore null } diff --git a/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H index 4ab765d034..75161187cb 100644 --- a/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H +++ b/src/OpenFOAM/containers/PtrLists/UPtrList/UPtrList.H @@ -314,10 +314,6 @@ public: // \return the number of non-null entries 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 inline void push_back(T* ptr); @@ -382,9 +378,18 @@ public: inline void operator=(UPtrList&& 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 - //- Write UPtrList to Ostream + //- Write UPtrList to Ostream. Does not ignore null entries friend Ostream& operator<< (Ostream& os, const UPtrList& list); diff --git a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H index c161fc327c..5679ca5b9c 100644 --- a/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H +++ b/src/OpenFOAM/fields/Fields/DynamicField/DynamicField.H @@ -269,7 +269,7 @@ public: // Edit //- Swap with plain List content. Implies shrink_to_fit(). - inline void swap(List& list); + inline void swap(List& other); //- Swap content, independent of sizing parameter template diff --git a/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H b/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H index ec9237be50..67ced92b34 100644 --- a/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H +++ b/src/OpenFOAM/fields/Fields/DynamicField/DynamicFieldI.H @@ -567,12 +567,12 @@ inline void Foam::DynamicField::shrink_to_fit() template inline void -Foam::DynamicField::swap(List& list) +Foam::DynamicField::swap(List& other) { if ( static_cast*>(this) - == static_cast*>(&list) + == static_cast*>(&other) ) { return; // Self-swap is a no-op @@ -582,7 +582,7 @@ Foam::DynamicField::swap(List& list) this->shrink_to_fit(); // Swap storage and addressable size - UList::swap(list); + UList::swap(other); // Update capacity capacity_ = List::size(); @@ -658,17 +658,22 @@ inline void Foam::DynamicField::transfer { if ( - static_cast*>(this) - == static_cast*>(&list) + FOAM_UNLIKELY + ( + static_cast*>(this) + == static_cast*>(&list) + ) ) { return; // Self-assignment is a no-op } - // Take over storage as-is (without shrink) - capacity_ = list.capacity(); + // Consistent allocated sizing + List::setAddressableSize(capacity_); Field::transfer(static_cast&>(list)); - list.clearStorage(); // capacity=0 etc. + + capacity_ = list.capacity(); + list.setCapacity_unsafe(0); // All contents moved } @@ -681,17 +686,22 @@ inline void Foam::DynamicField::transfer { if ( - static_cast*>(this) - == static_cast*>(&list) + FOAM_UNLIKELY + ( + static_cast*>(this) + == static_cast*>(&list) + ) ) { return; // Self-assignment is a no-op } - // Take over storage as-is (without shrink) - capacity_ = list.capacity(); + // Consistent allocated sizing + List::setAddressableSize(capacity_); Field::transfer(static_cast&>(list)); - list.clearStorage(); // capacity=0 etc. + + capacity_ = list.capacity(); + list.setCapacity_unsafe(0); // All contents moved } @@ -744,7 +754,14 @@ inline void Foam::DynamicField::push_back const UList& list ) { - if (this == &list) + if + ( + FOAM_UNLIKELY + ( + static_cast*>(this) + == static_cast*>(&list) + ) + ) { FatalErrorInFunction << "Attempted push_back to self" @@ -764,7 +781,14 @@ inline void Foam::DynamicField::push_back List&& list ) { - if (this == &list) + if + ( + FOAM_UNLIKELY + ( + static_cast*>(this) + == static_cast*>(&list) + ) + ) { FatalErrorInFunction << "Attempted push_back to self" @@ -774,6 +798,7 @@ inline void Foam::DynamicField::push_back const label idx = List::size(); resize(idx + list.size()); + // Move the elements std::move(list.begin(), list.end(), this->begin(idx)); list.clear(); @@ -880,7 +905,7 @@ inline void Foam::DynamicField::operator= List&& list ) { - transfer(list); + this->transfer(list); } @@ -890,7 +915,7 @@ inline void Foam::DynamicField::operator= DynamicField&& list ) { - transfer(list); + this->transfer(list); } @@ -901,7 +926,7 @@ inline void Foam::DynamicField::operator= DynamicField&& list ) { - transfer(list); + this->transfer(list); } @@ -912,7 +937,7 @@ inline void Foam::DynamicField::operator= DynamicList&& list ) { - transfer(list); + this->transfer(list); } From b2135600a887e89f9796495338bd81f83568a4aa Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Mon, 25 Aug 2025 15:09:31 +0200 Subject: [PATCH 5/6] ENH: add readContents to CompactIOList, CompactIOField - align some of the internal handling with each other and with CompactListList ENH: add readContentsSize to IOList, IOField etc. - sometimes just need to know how many elements are stored on disk without actually caring about the content. In those cases, can frequently just get that information from the first label token without needing to read anything else. --- applications/test/CompactIOList/Make/files | 2 +- ...CompactIOList.C => Test-CompactIOList.cxx} | 106 ++++-- .../IOobjects/CompactIOField/CompactIOField.C | 342 ++++++++++++++---- .../IOobjects/CompactIOField/CompactIOField.H | 62 +++- .../IOobjects/CompactIOList/CompactIOList.C | 314 +++++++++++----- .../IOobjects/CompactIOList/CompactIOList.H | 55 ++- .../IOobjects/GlobalIOField/GlobalIOField.C | 10 +- .../IOobjects/GlobalIOField/GlobalIOField.H | 17 +- .../db/IOobjects/GlobalIOList/GlobalIOList.C | 10 +- .../db/IOobjects/GlobalIOList/GlobalIOList.H | 17 +- src/OpenFOAM/db/IOobjects/IOField/IOField.C | 64 +++- src/OpenFOAM/db/IOobjects/IOField/IOField.H | 27 +- src/OpenFOAM/db/IOobjects/IOList/IOList.C | 62 +++- src/OpenFOAM/db/IOobjects/IOList/IOList.H | 25 +- src/OpenFOAM/db/IOobjects/IOMap/IOMap.C | 10 +- src/OpenFOAM/db/IOobjects/IOMap/IOMap.H | 15 +- .../db/IOobjects/IOPtrList/IOPtrList.C | 10 +- .../db/IOobjects/IOPtrList/IOPtrList.H | 15 +- .../IOobjects/IOdictionary/baseIOdictionary.C | 8 - .../IOobjects/IOdictionary/baseIOdictionary.H | 15 +- .../db/IOobjects/rawIOField/rawIOField.C | 1 + 21 files changed, 858 insertions(+), 329 deletions(-) rename applications/test/CompactIOList/{Test-CompactIOList.C => Test-CompactIOList.cxx} (60%) diff --git a/applications/test/CompactIOList/Make/files b/applications/test/CompactIOList/Make/files index c5513ed5c1..b318569076 100644 --- a/applications/test/CompactIOList/Make/files +++ b/applications/test/CompactIOList/Make/files @@ -1,3 +1,3 @@ -Test-CompactIOList.C +Test-CompactIOList.cxx EXE = $(FOAM_USER_APPBIN)/Test-CompactIOList diff --git a/applications/test/CompactIOList/Test-CompactIOList.C b/applications/test/CompactIOList/Test-CompactIOList.cxx similarity index 60% rename from applications/test/CompactIOList/Test-CompactIOList.C rename to applications/test/CompactIOList/Test-CompactIOList.cxx index 0db36f346c..439b4b6870 100644 --- a/applications/test/CompactIOList/Test-CompactIOList.C +++ b/applications/test/CompactIOList/Test-CompactIOList.cxx @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation - Copyright (C) 2020-2022 OpenCFD Ltd. + Copyright (C) 2020-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -25,7 +25,7 @@ License along with OpenFOAM. If not, see . Application - testCompactIOList + Test-CompactIOList Description Simple demonstration and test application for the CompactIOList container @@ -46,13 +46,20 @@ using namespace Foam; int main(int argc, char *argv[]) { + argList::addBoolOption("ascii", "use ascii format"); + argList::addOption("count", "number of faces"); + #include "setRootCase.H" #include "createTime.H" 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