diff --git a/applications/test/IOobjectList/Test-IOobjectList.C b/applications/test/IOobjectList/Test-IOobjectList.C index ec7ce76299f17dfb26db64063d74926e625422d6..3e0850c0d7336bfcaf62dfe5a4f1c9b39cebaedf 100644 --- a/applications/test/IOobjectList/Test-IOobjectList.C +++ b/applications/test/IOobjectList/Test-IOobjectList.C @@ -32,6 +32,8 @@ Description #include "timeSelector.H" #include "IOobjectList.H" #include "hashedWordList.H" +#include "labelIOList.H" +#include "scalarIOList.H" using namespace Foam; @@ -80,6 +82,67 @@ void reportDetail(const IOobjectList& objects) } +template<class Type> +void filterTest(const IOobjectList& objs, const wordRe& re) +{ + Info<< "Filter = " << re << nl; + + const word& typeName = Type::typeName; + + Info<< " <" << typeName <<">(" << re << ") : " + << objs.count<Type>(re) << nl + << " (" << typeName << "::typeName, " << re << ") : " + << objs.count(typeName, re) << nl; + + Info<< " <" << typeName << ">(" << re << ") : " + << flatOutput(objs.sortedNames<Type>(re)) << nl + // << flatOutput(objs.names<Type>(re)) << nl + << " (" << typeName << "::typeName, " << re << ") : " + << flatOutput(objs.sortedNames(typeName, re)) << nl + //<< flatOutput(objs.names(typeName, re)) << nl + ; + + + wordRe reClass("vol.*Field", wordRe::REGEX); + wordRe re2(re, wordRe::REGEX_ICASE); + + Info<< "General" << nl + << " <void>(" << re << ") : " + << flatOutput(objs.sortedNames<void>(re)) << nl + << " (" << reClass << ", " << re2 <<" ignore-case) : " + << flatOutput(objs.sortedNames(reClass, re2)) << nl + ; + + Info<< nl; +} + + +void registryTests(const IOobjectList& objs) +{ + Info<< nl << "IOobjectList " << flatOutput(objs.sortedNames()) << nl; + + Info<< "count" << nl + << " <void>() : " << objs.count<void>() << nl + << " <labelList>() : " << objs.count<labelIOList>() << nl + << " <scalarList>() : " << objs.count<scalarIOList>() << nl + << nl; + Info<< " <volScalarField>() : " + << objs.count<volScalarField>() << nl + << " (volScalarField::typeName) : " + << objs.count(volScalarField::typeName) << nl; + Info<< " <volVectorField>() : " + << objs.count<volVectorField>() << nl + << " (volVectorField::typeName) : " + << objs.count(volVectorField::typeName) << nl; + + + Info<< nl << "Filter on names:" << nl; + filterTest<volScalarField>(objs, wordRe("[p-z].*", wordRe::DETECT)); + + Info<< nl; +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Main program: @@ -165,6 +228,8 @@ int main(int argc, char *argv[]) Info<<"remove: " << flatOutput(subsetTypes) << nl; Info<<"Pruned: " << classes << nl; + registryTests(objects); + // On last time if (timeI == timeDirs.size()-1) { diff --git a/applications/test/objectRegistry/Test-objectRegistry.C b/applications/test/objectRegistry/Test-objectRegistry.C index 73e9f193d392cfdbe31a37dbb2e95c67e3bbec99..ba56f115be6743a726c9bc9a9b7a4491bc87f243 100644 --- a/applications/test/objectRegistry/Test-objectRegistry.C +++ b/applications/test/objectRegistry/Test-objectRegistry.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -34,8 +34,8 @@ Description #include "Time.H" #include "polyMesh.H" #include "IOstreams.H" +#include "FlatOutput.H" #include "objectRegistry.H" -#include "hashedWordList.H" using namespace Foam; @@ -45,22 +45,6 @@ using namespace Foam; bool recursive = false; -template<class Type> -Foam::Ostream& printList(Foam::Ostream& os, const UList<Type>& list) -{ - // list with out any linebreaks - os << '('; - forAll(list, i) - { - if (i) os << ' '; - os << list[i]; - } - os << ')'; - - return os; -} - - void printRegistry ( Foam::Ostream& os, @@ -76,8 +60,8 @@ void printRegistry Foam::label indent ) { - wordList names = obr.sortedNames(); - hashedWordList regs = obr.sortedNames<objectRegistry>(); + wordList names(obr.sortedNames()); + wordList regs(obr.sortedNames<objectRegistry>()); std::string prefix; for (label i=indent; i; --i) @@ -88,23 +72,13 @@ void printRegistry os << '#' << prefix.c_str() << obr.name() << " parent:" << obr.parent().name() << nl; - // all names - { - os << ' ' << prefix.c_str() << "objects: "; - printList(os, names) << nl; - } + os << ' ' << prefix.c_str() << "objects: " << flatOutput(names) << nl; + os << ' ' << prefix.c_str() << "registries: " << flatOutput(regs) << nl; - // sub-registry names - { - os << ' ' << prefix.c_str() << "registries: "; - printList(os, regs) << nl; - } // Print, but skip expansion of sub-registries for now - forAll(names, i) + for (const word& name : names) { - const word& name = names[i]; - os << (regs.found(name) ? '-' : ' ') << prefix.c_str() << name << " => " << obr[name]->type() << nl; } @@ -115,9 +89,8 @@ void printRegistry os << '\n'; // Now descend into the sub-registries - forAll(regs, i) + for (const word& name : regs) { - const word& name = regs[i]; const objectRegistry& next = obr.lookupObject<objectRegistry> ( name, @@ -240,8 +213,8 @@ int main(int argc, char *argv[]) ); } - Info<< "after adding some entries, top-level now contains: "; - printList(Info, db.names()) << endl; + Info<< "after adding some entries, top-level now contains: " + << flatOutput(db.names()) << endl; Info<<"## Now attempt to add a few more entries ##" << nl; diff --git a/applications/test/objectRegistry2/Make/files b/applications/test/objectRegistry2/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..208771853c25a1483c3222f71cd5639587c9247f --- /dev/null +++ b/applications/test/objectRegistry2/Make/files @@ -0,0 +1,3 @@ +Test-objectRegistry2.C + +EXE = $(FOAM_USER_APPBIN)/Test-objectRegistry2 diff --git a/applications/test/objectRegistry2/Make/options b/applications/test/objectRegistry2/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..969020c4afaf5d784299462b9e1af282040ba6b4 --- /dev/null +++ b/applications/test/objectRegistry2/Make/options @@ -0,0 +1,8 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude + +EXE_LIBS = \ + -lfiniteVolume \ + -lmeshTools \ + -lgenericPatchFields diff --git a/applications/test/objectRegistry2/Test-objectRegistry2.C b/applications/test/objectRegistry2/Test-objectRegistry2.C new file mode 100644 index 0000000000000000000000000000000000000000..eab159ccfc28deecff5009d2e046047fc0ed49b7 --- /dev/null +++ b/applications/test/objectRegistry2/Test-objectRegistry2.C @@ -0,0 +1,307 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2018 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Application + Test-objectRegistry2 + +Description + Print objectRegistry information, with some additional tests. + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" +#include "Time.H" +#include "fvCFD.H" +#include "fvMesh.H" +#include "volFields.H" +#include "IOobjectList.H" +#include "timeSelector.H" +#include "ReadFields.H" +#include "IOstreams.H" + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template<class Type> +bool loadField(fvMesh& mesh, const word& fieldName) +{ + typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType; + typedef GeometricField<Type, fvsPatchField, surfaceMesh> SurfaceFieldType; + + if (mesh.objectRegistry::found(fieldName)) + { + // Info<< fieldName << " already in database" << endl; + return false; + } + + IOobject fieldHeader + ( + fieldName, + mesh.time().timeName(), + mesh, + IOobject::MUST_READ, + IOobject::NO_WRITE + ); + + if (fieldHeader.typeHeaderOk<VolFieldType>(true, true, false)) + { + // Store field on mesh database + VolFieldType* ptr = new VolFieldType(fieldHeader, mesh); + mesh.objectRegistry::store(ptr); + return true; + } + else if (fieldHeader.typeHeaderOk<SurfaceFieldType>(true, true, false)) + { + // Store field on mesh database + SurfaceFieldType* ptr = new SurfaceFieldType(fieldHeader, mesh); + mesh.objectRegistry::store(ptr); + return true; + } + + return false; +} + + +bool loadField(fvMesh& mesh, const word& fieldName) +{ + return + ( + !mesh.objectRegistry::found(fieldName) + && + ( + loadField<scalar>(mesh, fieldName) + || loadField<vector>(mesh, fieldName) + || loadField<sphericalTensor>(mesh, fieldName) + || loadField<symmTensor>(mesh, fieldName) + || loadField<tensor>(mesh, fieldName) + ) + ); +} + + +void loadFields(fvMesh& mesh, const IOobjectList& objects) +{ + for (const word& fieldName : objects.names()) + { + loadField(mesh, fieldName); + } +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +void printRegistry +( + Foam::Ostream& os, + const Foam::objectRegistry& obr, + Foam::label indent = 4 +); + + +void printRegistry +( + Foam::Ostream& os, + const Foam::objectRegistry& obr, + Foam::label indent +) +{ + wordList names(obr.sortedNames()); + wordList regs(obr.sortedNames<objectRegistry>()); + + std::string prefix; + for (label i=indent; i; --i) + { + prefix += ' '; + } + + os << '#' << prefix.c_str() << obr.name() + << " parent:" << obr.parent().name() << nl; + + os << ' ' << prefix.c_str() << "objects: " << flatOutput(names) << nl; + os << ' ' << prefix.c_str() << "registries: " << flatOutput(regs) << nl; + + + // Print, but skip expansion of sub-registries for now + for (const word& name : names) + { + os << (regs.found(name) ? '-' : ' ') + << prefix.c_str() << name << " => " << obr[name]->type() << nl; + } + for (label i=indent; i; --i) + { + os << '-'; // divider + } + os << '\n'; + + // Now descend into the sub-registries + for (const word& name : regs) + { + const objectRegistry& next = obr.lookupObject<objectRegistry> + ( + name, + false // non-recursive + ); + + os << prefix.c_str() + << "current:" << obr.name() << " next:" + << next.name() << " next-parent:" << next.parent().name() << nl; + + os << prefix.c_str() << name << " => " << obr[name]->type(); + + if ("dictionary" == obr[name]->type()) + { + os << " (skip dictionary)" << nl; + } + else + { + os << nl; + printRegistry(os, next, indent + 4); + } + } +} + + +template<class Type> +void filterTest(const objectRegistry& obr, const wordRe& re) +{ + Info<< nl << "Filter on names:" << nl; + + Info<< "Filter = " << re << nl; + + const word& typeName = Type::typeName; + + Info<< " <" << typeName <<">(" << re << ") : " + << obr.count<Type>(re) << nl + << " (" << typeName << "::typeName, " << re << ") : " + << obr.count(typeName, re) << nl; + + Info<< " <" << typeName << ">(" << re << ") : " + << flatOutput(obr.sortedNames<Type>(re)) << nl + // << flatOutput(obr.names<Type>(re)) << nl + << " (" << typeName << "::typeName, " << re << ") : " + << flatOutput(obr.sortedNames(typeName, re)) << nl + //<< flatOutput(obr.names(typeName, re)) << nl + ; + + + wordRe reClass("vol.*Field", wordRe::REGEX); + wordRe re2(re, wordRe::REGEX_ICASE); + + Info<< "General" << nl + << " <void>(" << re << ") : " + << flatOutput(obr.sortedNames<void>(re)) << nl + << " (" << reClass << ", " << re2 <<" ignore-case) : " + << flatOutput(obr.sortedNames(reClass, re2)) << nl + ; + + Info<< nl; +} + + +void registryTests(const objectRegistry& obr) +{ + Info<< nl << "Registry: " << obr.name() << nl + << " names: " << flatOutput(obr.sortedNames()) << nl; + + Info<< "count" << nl + << " <void>() : " << obr.count<void>() << nl + << " <labelList>() : " << obr.count<labelList>() << nl + << " <labelList>(strict) : " << obr.count<labelList>(true) << nl + << " <scalarList>() : " << obr.count<scalarList>() << nl + << " <scalarList>(strict) : " << obr.count<scalarList>(true) << nl; + Info<< " <volScalarField>() : " + << obr.count<volScalarField>() << nl + << " (volScalarField::typeName) : " + << obr.count(volScalarField::typeName) << nl; + Info<< " <volVectorField>() : " + << obr.count<volVectorField>() << nl + << " (volVectorField::typeName) : " + << obr.count(volVectorField::typeName) << nl; + + Info<< nl << "Filter on names:" << nl; + + filterTest<volScalarField>(obr, wordRe("[p-z].*", wordRe::DETECT)); + + Info<< nl; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Main program: + +int main(int argc, char *argv[]) +{ + argList::noBanner(); + argList::noParallel(); +// argList::addOption +// ( +// "filter", +// "wordRes", +// "filter keys with names or regexs" +// ); + + // timeSelector::addOptions(); + timeSelector::addOptions(true, true); + + #include "setRootCase.H" + +// wordRes matcher; +// if (args.readListIfPresent<wordRe>("filter", matcher)) +// { +// Info<<"limit names: " << matcher << nl; +// } + + #include "createTime.H" + #include "createMesh.H" + + instantList timeDirs = timeSelector::select0(runTime, args); + + forAll(timeDirs, timeI) + { + runTime.setTime(timeDirs[timeI], timeI); + + Info<< "Time: " << runTime.timeName() << endl; + + // Read objects in time directory + IOobjectList objects(mesh, runTime.timeName()); + + // Read volFields + loadFields(mesh, objects); + + printRegistry(Info, mesh); + + registryTests(mesh); + + Info<< nl; + } + + + Info<<"\nEnd\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOobjectList/IOobjectList.C b/src/OpenFOAM/db/IOobjectList/IOobjectList.C index 95f84c49c1a19b27964f2c50c5189977b6fbe5e4..8d914a1b470f49c32fe6ae0a9a13214b2bb5805f 100644 --- a/src/OpenFOAM/db/IOobjectList/IOobjectList.C +++ b/src/OpenFOAM/db/IOobjectList/IOobjectList.C @@ -33,7 +33,8 @@ License bool Foam::IOobjectList::checkNames(wordList& masterNames, const bool syncPar) { - // Sort for consistent order on all processors + // Sort for consistent order on all processors. + // Even do this for serial runs, for consistent behaviour Foam::sort(masterNames); if (syncPar && Pstream::parRun()) @@ -273,6 +274,13 @@ Foam::HashTable<Foam::wordHashSet> Foam::IOobjectList::classes() const } +Foam::label Foam::IOobjectList::count(const char* clsName) const +{ + // No nullptr check - only called with string literals + return count(static_cast<word>(clsName)); +} + + Foam::wordList Foam::IOobjectList::names() const { return HashPtrTable<IOobject>::toc(); @@ -288,37 +296,33 @@ Foam::wordList Foam::IOobjectList::names(const bool syncPar) const } -Foam::wordList Foam::IOobjectList::names -( - const word& clsName -) const +Foam::wordList Foam::IOobjectList::names(const char* clsName) const { - // sort/sync: false, false - return namesImpl(*this, clsName, predicates::always(), false, false); + // No nullptr check - only called with string literals + return names(static_cast<word>(clsName)); } Foam::wordList Foam::IOobjectList::names ( - const word& clsName, + const char* clsName, const bool syncPar ) const { - // sort: false - return namesImpl(*this, clsName, predicates::always(), false, syncPar); + // No nullptr check - only called with string literals + return names(static_cast<word>(clsName), syncPar); } +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + Foam::wordList Foam::IOobjectList::sortedNames() const { return HashPtrTable<IOobject>::sortedToc(); } -Foam::wordList Foam::IOobjectList::sortedNames -( - const bool syncPar -) const +Foam::wordList Foam::IOobjectList::sortedNames(const bool syncPar) const { wordList objNames(HashPtrTable<IOobject>::sortedToc()); @@ -327,24 +331,56 @@ Foam::wordList Foam::IOobjectList::sortedNames } -Foam::wordList Foam::IOobjectList::sortedNames -( - const word& clsName -) const +Foam::wordList Foam::IOobjectList::sortedNames(const char* clsName) const { - // sort/sync: true, false - return namesImpl(*this, clsName, predicates::always(), true, false); + // No nullptr check - only called with string literals + return sortedNames(static_cast<word>(clsName)); } Foam::wordList Foam::IOobjectList::sortedNames ( - const word& clsName, + const char* clsName, const bool syncPar ) const { - // sort: true - return namesImpl(*this, clsName, predicates::always(), true, syncPar); + // No nullptr check - only called with string literals + return names(static_cast<word>(clsName), syncPar); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +Foam::label Foam::IOobjectList::prune_0() +{ + return + HashPtrTable<IOobject>::filterKeys + ( + [](const word& k){ return k.endsWith("_0"); }, + true // prune + ); +} + + +Foam::wordList Foam::IOobjectList::allNames() const +{ + wordList objNames(HashPtrTable<IOobject>::toc()); + + syncNames(objNames); + return objNames; +} + + +bool Foam::IOobjectList::checkNames(const bool syncPar) const +{ + if (syncPar && Pstream::parRun()) + { + wordList objNames(HashPtrTable<IOobject>::toc()); + + return checkNames(objNames, syncPar); + } + + return true; } diff --git a/src/OpenFOAM/db/IOobjectList/IOobjectList.H b/src/OpenFOAM/db/IOobjectList/IOobjectList.H index 3496e47d20c3b27c95d2f746c225b1d122da47d8..692e81c8905776b82a1961bd9efb7d6f0285a703 100644 --- a/src/OpenFOAM/db/IOobjectList/IOobjectList.H +++ b/src/OpenFOAM/db/IOobjectList/IOobjectList.H @@ -76,6 +76,24 @@ class IOobjectList const MatchPredicate& matchName ); + //- Templated implementation for count() + // The number of items with a matching class + template<class MatchPredicate1, class MatchPredicate2> + static label countImpl + ( + const IOobjectList& list, + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName + ); + + //- Templated implementation for count() + template<class Type, class MatchPredicate> + static label countTypeImpl + ( + const IOobjectList& list, + const MatchPredicate& matchName + ); + //- Templated implementation for names(), sortedNames() template<class MatchPredicate1, class MatchPredicate2> static wordList namesImpl @@ -83,8 +101,16 @@ class IOobjectList const IOobjectList& list, const MatchPredicate1& matchClass, const MatchPredicate2& matchName, - const bool doSort, - const bool syncPar + const bool doSort + ); + + //- Templated implementation for names(), sortedNames() + template<class Type, class MatchPredicate> + static wordList namesTypeImpl + ( + const IOobjectList& list, + const MatchPredicate& matchName, + const bool doSort ); //- Templated implementation for lookup() @@ -104,6 +130,14 @@ class IOobjectList const MatchPredicate2& matchName ); + //- Templated implementation for lookupClass() + template<class Type, class MatchPredicate> + static IOobjectList lookupClassTypeImpl + ( + const IOobjectList& list, + const MatchPredicate& matchName + ); + public: @@ -181,17 +215,38 @@ public: // Lookup multiple items - //- The list of all IOobjects that have a matching object name. + //- The list of IOobjects that have a matching object name. template<class MatchPredicate> IOobjectList lookup(const MatchPredicate& matchName) const; - //- The list of all IOobjects with the given headerClassName + //- The list of IOobjects with the given headerClassName IOobjectList lookupClass(const char* clsName) const; - //- The list of all IOobjects with matching headerClassName + //- The list of IOobjects with matching headerClassName template<class MatchPredicate> IOobjectList lookupClass(const MatchPredicate& matchClass) const; + //- The list of IOobjects with matching headerClassName + //- that also have a matching object name. + template<class MatchPredicate1, class MatchPredicate2> + IOobjectList lookupClass + ( + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName + ) const; + + //- The list of IOobjects with headerClassName == Type::typeName + // + // \note If \a Type is \c void, no headerClassName check is used + // (always true). + template<class Type> + IOobjectList lookupClass() const; + + //- The list of IOobjects with headerClassName == Type::typeName + //- that also have a matching object name. + template<class Type, class MatchPredicate> + IOobjectList lookupClass(const MatchPredicate& matchName) const; + // Summary of classes @@ -273,6 +328,41 @@ public: HashTable<wordHashSet> classes(const MatchPredicate& matchName) const; + // Number of items + + //- The number of objects of the given headerClassName + // \note uses the class type() method + label count(const char* clsName) const; + + //- The number of objects of the given headerClassName + template<class MatchPredicate> + label count + ( + const MatchPredicate& matchClass + ) const; + + //- The number of objects of the given headerClassName + //- that also have a matching object name. + template<class MatchPredicate1, class MatchPredicate2> + label count + ( + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName + ) const; + + //- The number of objects with headerClassName == Type::typeName + template<class Type> + label count() const; + + //- The number of objects with headerClassName == Type::typeName + //- that also have a matching object name. + // + // \note If \a Type is \c void, no headerClassName check is used + // (always true). + template<class Type, class MatchPredicate> + label count(const MatchPredicate& matchName) const; + + // Summary of names //- The names of the IOobjects @@ -283,31 +373,74 @@ public: // if the names are not consistent on all processors. wordList names(const bool syncPar) const; - //- The names of IOobjects with the given class - wordList names(const word& clsName) const; + //- The names of IOobjects with the given headerClassName + wordList names(const char* clsName) const; //- The names of the IOobjects with the given headerClassName // With syncPar = true, sorts the names and triggers FatalError // if the names are not consistent on all processors. - wordList names(const word& clsName, const bool syncPar) const; + wordList names(const char* clsName, const bool syncPar) const; //- The names of IOobjects with the given headerClassName - //- that also have a matching object name. + template<class MatchPredicate> + wordList names(const MatchPredicate& matchClass) const; + + //- The names of the IOobjects with the given headerClassName + // With syncPar = true, sorts the names and triggers FatalError + // if the names are not consistent on all processors. template<class MatchPredicate> wordList names ( - const word& clsName, - const MatchPredicate& matchName + const MatchPredicate& matchClass, + const bool syncPar + ) const; + + //- The names of IOobjects with the given headerClassName + //- that also have a matching object name. + template<class MatchPredicate1, class MatchPredicate2> + wordList names + ( + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName ) const; //- The names of the IOobjects with the given headerClassName //- that also have a matching object name. // With syncPar = true, sorts the names and triggers FatalError // if the names are not consistent on all processors. - template<class MatchPredicate> + template<class MatchPredicate1, class MatchPredicate2> + wordList names + ( + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName, + const bool syncPar + ) const; + + + //- The names of objects with headerClassName == Type::typeName + template<class Type> + wordList names() const; + + //- The names of objects with headerClassName == Type::typeName + // With syncPar = true, sorts the names and triggers FatalError + // if the names are not consistent on all processors. + template<class Type> + wordList names(bool syncPar) const; + + //- The names of objects with headerClassName == Type::typeName + //- that also have a matching object name. + // With syncPar = true, sorts the names and triggers FatalError + // if the names are not consistent on all processors. + template<class Type, class MatchPredicate> + wordList names(const MatchPredicate& matchName) const; + + //- The names of objects with headerClassName == Type::typeName + //- that also have a matching object name. + // With syncPar = true, sorts the names and triggers FatalError + // if the names are not consistent on all processors. + template<class Type, class MatchPredicate> wordList names ( - const word& clsName, const MatchPredicate& matchName, const bool syncPar ) const; @@ -318,41 +451,125 @@ public: //- The sorted names of the IOobjects wordList sortedNames() const; - //- The sorted names of the IOobjects - // With syncPar = true, a FatalError is - // triggered if the names are not consistent on all processors. + //- The sorted names of the IOobjects. + // With syncPar = true, sorts the names and triggers FatalError + // if the names are not consistent on all processors. wordList sortedNames(const bool syncPar) const; //- The sorted names of IOobjects with the given headerClassName - wordList sortedNames(const word& clsName) const; + wordList sortedNames(const char* clsName) const; //- The sorted names of the IOobjects with the given headerClassName // With syncPar = true, sorts the names and triggers FatalError // if the names are not consistent on all processors. - wordList sortedNames(const word& clsName, const bool syncPar) const; + wordList sortedNames(const char* clsName, const bool syncPar) const; //- The sorted names of IOobjects with the given headerClassName - //- that also have a matching object name. + template<class MatchPredicate> + wordList sortedNames(const MatchPredicate& matchClass) const; + + //- The sorted names of the IOobjects with the given headerClassName + // With syncPar = true, sorts the names and triggers FatalError + // if the names are not consistent on all processors. template<class MatchPredicate> wordList sortedNames ( - const word& clsName, - const MatchPredicate& matchName + const MatchPredicate& matchClass, + const bool syncPar + ) const; + + //- The sorted names of IOobjects with the given headerClassName + //- that also have a matching object name. + template<class MatchPredicate1, class MatchPredicate2> + wordList sortedNames + ( + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName ) const; //- The sorted names of the IOobjects with the given headerClassName //- that also have a matching object name. // With syncPar = true, sorts the names and triggers FatalError // if the names are not consistent on all processors. - template<class MatchPredicate> + template<class MatchPredicate1, class MatchPredicate2> + wordList sortedNames + ( + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName, + const bool syncPar + ) const; + + + //- The sorted names of objects with headerClassName == Type::typeName + template<class Type> + wordList sortedNames() const; + + //- The sorted names of objects with headerClassName == Type::typeName + // With syncPar = true, sorts the names and triggers FatalError + // if the names are not consistent on all processors. + template<class Type> + wordList sortedNames(bool syncPar) const; + + //- The sorted names of objects with headerClassName == Type::typeName + //- that also have a matching object name. + // With syncPar = true, sorts the names and triggers FatalError + // if the names are not consistent on all processors. + template<class Type, class MatchPredicate> + wordList sortedNames(const MatchPredicate& matchName) const; + + //- The sorted names of objects with headerClassName == Type::typeName + //- that also have a matching object name. + // With syncPar = true, sorts the names and triggers FatalError + // if the names are not consistent on all processors. + template<class Type, class MatchPredicate> wordList sortedNames ( - const word& clsName, const MatchPredicate& matchName, const bool syncPar ) const; + // Edit + + //- Filter to retain or prune given classes + // \return The number of items changed (removed) + template<class UnaryPredicate> + label filterClasses + ( + const UnaryPredicate& pred, + const bool pruning = false + ); + + //- Filter to retain or prune given object names + // \return The number of items changed (removed) + template<class UnaryPredicate> + label filterObjects + ( + const UnaryPredicate& pred, + const bool pruning = false + ); + + //- Remove objects with names ending with "_0" (restart fields) + // \return The number of items changed (removed) + label prune_0(); + + + // Parallel + + //- The sorted names of all objects (synchronised across processors) + wordList allNames() const; + + //- The sorted names of all objects (synchronised across processors) + //- with headerClassName == Type::typeName + template<class Type> + wordList allNames() const; + + //- Verify that object names are synchronised across processors + // Triggers FatalError if the names are not consistent on all + // processors. + bool checkNames(const bool syncPar = true) const; + + // Member Operators //- No copy assignment diff --git a/src/OpenFOAM/db/IOobjectList/IOobjectListTemplates.C b/src/OpenFOAM/db/IOobjectList/IOobjectListTemplates.C index 2dd17f84060fd6562e29d7e1fa1df58e4a95a248..b7dc5b9b37305d0be87692ad736dac1b23d02ba3 100644 --- a/src/OpenFOAM/db/IOobjectList/IOobjectListTemplates.C +++ b/src/OpenFOAM/db/IOobjectList/IOobjectListTemplates.C @@ -55,6 +55,55 @@ Foam::HashTable<Foam::wordHashSet> Foam::IOobjectList::classesImpl } +// Templated implementation for count() +template<class MatchPredicate1, class MatchPredicate2> +Foam::label Foam::IOobjectList::countImpl +( + const IOobjectList& list, + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName +) +{ + label count = 0; + + forAllConstIters(list, iter) + { + const IOobject* io = iter.object(); + + if (matchClass(io->headerClassName()) && matchName(io->name())) + { + ++count; + } + } + + return count; +} + + +// Templated implementation for count() +template<class Type, class MatchPredicate> +Foam::label Foam::IOobjectList::countTypeImpl +( + const IOobjectList& list, + const MatchPredicate& matchName +) +{ + label count = 0; + + forAllConstIters(list, iter) + { + const IOobject* io = iter.object(); + + if (io->isHeaderClassName<Type>() && matchName(io->name())) + { + ++count; + } + } + + return count; +} + + // Templated implementation for names(), sortedNames() template<class MatchPredicate1, class MatchPredicate2> Foam::wordList Foam::IOobjectList::namesImpl @@ -62,8 +111,7 @@ Foam::wordList Foam::IOobjectList::namesImpl const IOobjectList& list, const MatchPredicate1& matchClass, const MatchPredicate2& matchName, - const bool doSort, - const bool syncPar + const bool doSort ) { wordList objNames(list.size()); @@ -81,14 +129,47 @@ Foam::wordList Foam::IOobjectList::namesImpl } } - objNames.setSize(count); + objNames.resize(count); if (doSort) { Foam::sort(objNames); } - checkNames(objNames, syncPar); + return objNames; +} + + +// Templated implementation for names(), sortedNames() +template<class Type, class MatchPredicate> +Foam::wordList Foam::IOobjectList::namesTypeImpl +( + const IOobjectList& list, + const MatchPredicate& matchName, + const bool doSort +) +{ + wordList objNames(list.size()); + + label count = 0; + forAllConstIters(list, iter) + { + const word& key = iter.key(); + const IOobject* io = iter.object(); + + if (io->isHeaderClassName<Type>() && matchName(key)) + { + objNames[count] = key; + ++count; + } + } + + objNames.resize(count); + + if (doSort) + { + Foam::sort(objNames); + } return objNames; } @@ -155,6 +236,36 @@ Foam::IOobjectList Foam::IOobjectList::lookupClassImpl } +// Templated implementation for lookupClass() +template<class Type, class MatchPredicate> +Foam::IOobjectList Foam::IOobjectList::lookupClassTypeImpl +( + const IOobjectList& list, + const MatchPredicate& matchName +) +{ + IOobjectList results(list.size()); + + forAllConstIters(list, iter) + { + const word& key = iter.key(); + const IOobject* io = iter.object(); + + if (io->isHeaderClassName<Type>() && matchName(key)) + { + if (IOobject::debug) + { + InfoInFunction << "Found " << key << endl; + } + + results.set(key, new IOobject(*io)); + } + } + + return results; +} + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // template<class MatchPredicate> @@ -177,6 +288,34 @@ Foam::IOobjectList Foam::IOobjectList::lookupClass } +template<class MatchPredicate1, class MatchPredicate2> +Foam::IOobjectList Foam::IOobjectList::lookupClass +( + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName +) const +{ + return lookupClassImpl(*this, matchClass, matchName); +} + + +template<class Type> +Foam::IOobjectList Foam::IOobjectList::lookupClass() const +{ + return lookupClassTypeImpl<Type>(*this, predicates::always()); +} + + +template<class Type, class MatchPredicate> +Foam::IOobjectList Foam::IOobjectList::lookupClass +( + const MatchPredicate& matchName +) const +{ + return lookupClassImpl<Type>(*this, matchName); +} + + template<class MatchPredicate> Foam::HashTable<Foam::wordHashSet> Foam::IOobjectList::classes @@ -189,52 +328,283 @@ Foam::IOobjectList::classes template<class MatchPredicate> -Foam::wordList Foam::IOobjectList::names +Foam::label Foam::IOobjectList::count +( + const MatchPredicate& matchClass +) const +{ + return countImpl(*this, matchClass, predicates::always()); +} + + +template<class MatchPredicate1, class MatchPredicate2> +Foam::label Foam::IOobjectList::count +( + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName +) const +{ + return countImpl(*this, matchClass, matchName); +} + + +template<class Type> +Foam::label Foam::IOobjectList::count() const +{ + return countTypeImpl<Type>(*this, predicates::always()); +} + + +template<class Type, class MatchPredicate> +Foam::label Foam::IOobjectList::count ( - const word& clsName, const MatchPredicate& matchName ) const { - // sort/sync: false, false - return namesImpl(*this, clsName, matchName, false, false); + return countTypeImpl<Type>(*this, matchName); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template<class MatchPredicate> +Foam::wordList Foam::IOobjectList::names +( + const MatchPredicate& matchClass +) const +{ + return namesImpl(*this, matchClass, predicates::always(), false); } template<class MatchPredicate> Foam::wordList Foam::IOobjectList::names ( - const word& clsName, + const MatchPredicate& matchClass, + const bool syncPar +) const +{ + wordList objNames + ( + namesImpl(*this, matchClass, predicates::always(), false) + ); + + checkNames(objNames, syncPar); + return objNames; +} + + +template<class MatchPredicate1, class MatchPredicate2> +Foam::wordList Foam::IOobjectList::names +( + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName +) const +{ + return namesImpl(*this, matchClass, matchName, false); +} + + +template<class MatchPredicate1, class MatchPredicate2> +Foam::wordList Foam::IOobjectList::names +( + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName, + const bool syncPar +) const +{ + wordList objNames(namesImpl(*this, matchClass, matchName, false)); + + checkNames(objNames, syncPar); + return objNames; +} + + +template<class Type> +Foam::wordList Foam::IOobjectList::names() const +{ + return namesTypeImpl<Type>(*this, predicates::always(), false); +} + + +template<class Type> +Foam::wordList Foam::IOobjectList::names(const bool syncPar) const +{ + wordList objNames(namesTypeImpl<Type>(*this, predicates::always(), false)); + + checkNames(objNames, syncPar); + return objNames; +} + + +template<class Type, class MatchPredicate> +Foam::wordList Foam::IOobjectList::names +( + const MatchPredicate& matchName +) const +{ + return namesTypeImpl<Type>(*this, matchName, false); +} + + +template<class Type, class MatchPredicate> +Foam::wordList Foam::IOobjectList::names +( const MatchPredicate& matchName, const bool syncPar ) const { - // sort: false - return namesImpl(*this, clsName, matchName, false, syncPar); + wordList objNames(namesTypeImpl<Type>(*this, matchName, false)); + + checkNames(objNames, syncPar); + return objNames; } +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + template<class MatchPredicate> Foam::wordList Foam::IOobjectList::sortedNames ( - const word& clsName, - const MatchPredicate& matchName + const MatchPredicate& matchClass ) const { - // sort/sync: true, false - return namesImpl(*this, clsName, matchName, true, false); + return namesImpl(*this, matchClass, predicates::always(), true); } template<class MatchPredicate> Foam::wordList Foam::IOobjectList::sortedNames ( - const word& clsName, + const MatchPredicate& matchClass, + const bool syncPar +) const +{ + wordList objNames + ( + namesImpl(*this, matchClass, predicates::always(), true) + ); + + checkNames(objNames, syncPar); + return objNames; +} + + +template<class MatchPredicate1, class MatchPredicate2> +Foam::wordList Foam::IOobjectList::sortedNames +( + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName +) const +{ + return namesImpl(*this, matchClass, matchName, true); +} + +template<class MatchPredicate1, class MatchPredicate2> +Foam::wordList Foam::IOobjectList::sortedNames +( + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName, + const bool syncPar +) const +{ + wordList objNames(namesImpl(*this, matchClass, matchName, true)); + + checkNames(objNames, syncPar); + return objNames; +} + + +template<class Type> +Foam::wordList Foam::IOobjectList::sortedNames() const +{ + return namesTypeImpl<Type>(*this, predicates::always(), true); +} + + +template<class Type> +Foam::wordList Foam::IOobjectList::sortedNames(const bool syncPar) const +{ + wordList objNames(namesTypeImpl<Type>(*this, predicates::always(), true)); + + checkNames(objNames, syncPar); + return objNames; +} + + +template<class Type, class MatchPredicate> +Foam::wordList Foam::IOobjectList::sortedNames +( + const MatchPredicate& matchName +) const +{ + return namesTypeImpl<Type>(*this, matchName, true); +} + + +template<class Type, class MatchPredicate> +Foam::wordList Foam::IOobjectList::sortedNames +( const MatchPredicate& matchName, const bool syncPar ) const { - // sort: true - return namesImpl(*this, clsName, matchName, true, syncPar); + return namesTypeImpl<Type>(*this, matchName, true, syncPar); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template<class UnaryPredicate> +Foam::label Foam::IOobjectList::filterClasses +( + const UnaryPredicate& pred, + const bool pruning +) +{ +// return HashPtrTable<IOobject>::filterValues +// ( +// [&](const IOobject* io){ return pred(io->headerClassName()); }, +// pruning +// ); + + label changed = 0; + + for (iterator iter = begin(); iter != end(); ++iter) + { + // Matches? either prune (pruning) or keep (!pruning) + if + ( + (pred(iter.object()->headerClassName()) ? pruning : !pruning) + && erase(iter) + ) + { + ++changed; + } + } + + return changed; +} + + +template<class UnaryPredicate> +Foam::label Foam::IOobjectList::filterObjects +( + const UnaryPredicate& pred, + const bool pruning +) +{ + return HashPtrTable<IOobject>::filterKeys(pred, pruning); +} + + +template<class Type> +Foam::wordList Foam::IOobjectList::allNames() const +{ + wordList objNames(namesTypeImpl<Type>(*this, predicates::always(), false)); + + syncNames(objNames); + return objNames; } diff --git a/src/OpenFOAM/db/objectRegistry/objectRegistry.C b/src/OpenFOAM/db/objectRegistry/objectRegistry.C index b91a94d228d1fc45c0690b2af572a24280391e04..a747de2c83a49580e23445227fbf380ea3387e8f 100644 --- a/src/OpenFOAM/db/objectRegistry/objectRegistry.C +++ b/src/OpenFOAM/db/objectRegistry/objectRegistry.C @@ -111,24 +111,10 @@ Foam::HashTable<Foam::wordHashSet> Foam::objectRegistry::classes() const } -Foam::HashTable<Foam::wordHashSet> -Foam::objectRegistry::classes(const wordRe& matchName) const +Foam::label Foam::objectRegistry::count(const char* clsName) const { - return classesImpl(*this, matchName); -} - - -Foam::HashTable<Foam::wordHashSet> -Foam::objectRegistry::classes(const wordRes& matchName) const -{ - return classesImpl(*this, matchName); -} - - -Foam::HashTable<Foam::wordHashSet> -Foam::objectRegistry::classes(const wordHashSet& matchName) const -{ - return classesImpl(*this, matchName); + // No nullptr check - only called with string literals + return count(static_cast<word>(clsName)); } @@ -144,31 +130,17 @@ Foam::wordList Foam::objectRegistry::sortedNames() const } -Foam::wordList Foam::objectRegistry::names(const word& clsName) const +Foam::wordList Foam::objectRegistry::names(const char* clsName) const { - wordList objNames(size()); - - label count=0; - for (const_iterator iter = cbegin(); iter != cend(); ++iter) - { - if (iter()->type() == clsName) - { - objNames[count++] = iter.key(); - } - } - - objNames.setSize(count); - - return objNames; + // No nullptr check - only called with string literals + return names(static_cast<word>(clsName)); } -Foam::wordList Foam::objectRegistry::sortedNames(const word& clsName) const +Foam::wordList Foam::objectRegistry::sortedNames(const char* clsName) const { - wordList objNames = names(clsName); - Foam::sort(objNames); - - return objNames; + // No nullptr check - only called with string literals + return sortedNames(static_cast<word>(clsName)); } diff --git a/src/OpenFOAM/db/objectRegistry/objectRegistry.H b/src/OpenFOAM/db/objectRegistry/objectRegistry.H index 8a92fbd26e59873bdece219401e61a0cbbd15bb8..d05f5edf0a4cc15430bc44c3cab8f1948acfc387 100644 --- a/src/OpenFOAM/db/objectRegistry/objectRegistry.H +++ b/src/OpenFOAM/db/objectRegistry/objectRegistry.H @@ -81,6 +81,25 @@ class objectRegistry // Used to terminate searching within the ancestors bool parentNotTime() const; + //- Templated implementation for count() + // The number of items with a matching class + template<class MatchPredicate1, class MatchPredicate2> + static label countImpl + ( + const objectRegistry& list, + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName + ); + + //- Templated implementation for count() + // The number of items with a matching class + template<class Type, class MatchPredicate> + static label countTypeImpl + ( + const objectRegistry& list, + const MatchPredicate& matchName + ); + //- Templated implementation for classes() template<class MatchPredicate> static HashTable<wordHashSet> classesImpl @@ -89,6 +108,16 @@ class objectRegistry const MatchPredicate& matchName ); + //- Templated implementation for names(), sortedNames() + template<class MatchPredicate1, class MatchPredicate2> + static wordList namesImpl + ( + const objectRegistry& list, + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName, + const bool doSort + ); + //- Templated implementation for names(), sortedNames() template<class Type, class MatchPredicate> static wordList namesTypeImpl @@ -157,90 +186,125 @@ public: // Behaviour and usage as per IOobjectList::classes HashTable<wordHashSet> classes() const; - //- A summary hash of classes used and their associated object names - //- restricted to objects with names that satisfy the input matcher - HashTable<wordHashSet> classes(const wordRe& matchName) const; - - //- A summary hash of classes used and their associated object names - //- restricted to objects with names that satisfy the input matcher - HashTable<wordHashSet> classes(const wordRes& matchName) const; + //- A summary hash of classes used and their associated object names, + //- restricted to objects that have a matching object name. + template<class MatchPredicate> + HashTable<wordHashSet> classes(const MatchPredicate& matchName) const; - //- A summary hash of classes used and their associated object names - //- restricted to objects with names that satisfy the input matcher - HashTable<wordHashSet> classes(const wordHashSet& matchName) const; + // Number of items - // Summary of names + //- The number of objects of the given class name + // \note uses the class type() method + label count(const char* clsName) const; - //- The names of the objects - wordList names() const; + //- The number of objects of the given class name + // \note uses the class type() method + template<class MatchPredicate> + label count(const MatchPredicate& matchClass) const; - //- The names of objects with the given class - wordList names(const word& clsName) const; + //- The number of objects of the given class name + // \note uses the class type() method + template<class MatchPredicate1, class MatchPredicate2> + label count + ( + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName + ) const; - //- The names of objects with a class satisfying \c isA\<Type\>. + //- The names of objects with a class satisfying \c isA\<Type\> + // + // \param strict use \c isType\<Type\> instead of \c isA\<Type\> // + // \note The values of \c count\<Type\>() and \c count(Type::typeName) + // may be inconsistent, since they use different mechanisms for + // testing the class type. // \note If \a Type is \c void, no isA check is used (always true). template<class Type> - wordList names() const; + label count(const bool strict = false) const; //- The names of objects with a class satisfying \c isA\<Type\> - //- that also have a name satisfying the input matcher + //- that also have a matching object name. // // \note If \a Type is \c void, no isA check is used (always true). - template<class Type> - wordList names(const wordRe& matchName) const; + template<class Type, class MatchPredicate> + label count(const MatchPredicate& matchName) const; - //- The names of objects with a class satisfying \c isA\<Type\> - //- that also have a name satisfying the input matcher + + // Summary of names + + //- The names of all objects + wordList names() const; + + //- The names of objects with the given class name. + // \note uses the class type() method + wordList names(const char* clsName) const; + + //- The names of objects with a matching class name + // \note uses the class type() method + template<class MatchPredicate> + wordList names(const MatchPredicate& matchClass) const; + + //- The names of objects with a matching class name + //- that also have a matching object name. + // \note uses the class type() method + template<class MatchPredicate1, class MatchPredicate2> + wordList names + ( + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName + ) const; + + //- The names of objects with a class satisfying \c isA\<Type\>. // // \note If \a Type is \c void, no isA check is used (always true). template<class Type> - wordList names(const wordRes& matchName) const; + wordList names() const; //- The names of objects with a class satisfying \c isA\<Type\> - //- that also have a name satisfying the input matcher + //- that also have a matching object name. // // \note If \a Type is \c void, no isA check is used (always true). - template<class Type> - wordList names(const wordHashSet& matchName) const; + template<class Type, class MatchPredicate> + wordList names(const MatchPredicate& matchName) const; // Summary of names (sorted) - //- The sorted names of the objects + //- The sorted names of all objects wordList sortedNames() const; - //- The sorted names of objects with the given class - wordList sortedNames(const word& clsName) const; + //- The sorted names of objects with the given class name. + // \note uses the class type() method + wordList sortedNames(const char* clsName) const; - //- The sorted names of objects with a class satisfying \c isA\<Type\> - //- that also have a name satisfying the input matcher - // - // \note If \a Type is \c void, no isA check is used (always true). - template<class Type> - wordList sortedNames() const; + //- The sorted names objects with a matching class name + // \note uses the class type() method + template<class MatchPredicate> + wordList sortedNames(const MatchPredicate& matchClass) const; - //- The sorted names of objects with a class satisfying \c isA\<Type\> - //- that also have a name satisfying the input matcher - // - // \note If \a Type is \c void, no isA check is used (always true). - template<class Type> - wordList sortedNames(const wordRe& matchName) const; + //- The sorted names of objects with a matching class name + //- that also have a matching object name. + // \note uses the class type() method + template<class MatchPredicate1, class MatchPredicate2> + wordList sortedNames + ( + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName + ) const; //- The sorted names of objects with a class satisfying \c isA\<Type\> - //- that also have a name satisfying the input matcher // // \note If \a Type is \c void, no isA check is used (always true). template<class Type> - wordList sortedNames(const wordRes& matchName) const; + wordList sortedNames() const; //- The sorted names of objects with a class satisfying \c isA\<Type\> - //- that also have a name satisfying the input matcher + //- that also have a matching object name. // // \note If \a Type is \c void, no isA check is used (always true). - template<class Type> - wordList sortedNames(const wordHashSet& matchName) const; + template<class Type, class MatchPredicate> + wordList sortedNames(const MatchPredicate& matchName) const; // Lookup diff --git a/src/OpenFOAM/db/objectRegistry/objectRegistryTemplates.C b/src/OpenFOAM/db/objectRegistry/objectRegistryTemplates.C index 20740e07d05b8ac8f70d3071ec083ebe660c8520..e75a304edae4462e03284506fe9de255f4eb001c 100644 --- a/src/OpenFOAM/db/objectRegistry/objectRegistryTemplates.C +++ b/src/OpenFOAM/db/objectRegistry/objectRegistryTemplates.C @@ -42,10 +42,12 @@ Foam::HashTable<Foam::wordHashSet> Foam::objectRegistry::classesImpl // Summary (key,val) = (class-name, object-names) forAllConstIters(list, iter) { - if (matchName(iter.key())) + const regIOobject* obj = iter.object(); + + if (matchName(obj->name())) { // Create entry (if needed) and insert - summary(iter.object()->type()).insert(iter.key()); + summary(iter.object()->type()).insert(obj->name()); } } @@ -53,6 +55,94 @@ Foam::HashTable<Foam::wordHashSet> Foam::objectRegistry::classesImpl } +// Templated implementation for count() +template<class MatchPredicate1, class MatchPredicate2> +Foam::label Foam::objectRegistry::countImpl +( + const objectRegistry& list, + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName +) +{ + label count = 0; + + forAllConstIters(list, iter) + { + const regIOobject* obj = iter.object(); + + if (matchClass(obj->type()) && matchName(obj->name())) + { + ++count; + } + } + + return count; +} + + +// Templated implementation for count() +template<class Type, class MatchPredicate> +Foam::label Foam::objectRegistry::countTypeImpl +( + const objectRegistry& list, + const MatchPredicate& matchName +) +{ + label count = 0; + + forAllConstIters(list, iter) + { + const regIOobject* obj = iter.object(); + + if + ( + (std::is_void<Type>::value || isA<Type>(*obj)) + && matchName(obj->name()) + ) + { + ++count; + } + } + + return count; +} + + +// Templated implementation for names(), sortedNames() +template<class MatchPredicate1, class MatchPredicate2> +Foam::wordList Foam::objectRegistry::namesImpl +( + const objectRegistry& list, + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName, + const bool doSort +) +{ + wordList objNames(list.size()); + + label count=0; + forAllConstIters(list, iter) + { + const regIOobject* obj = iter.object(); + + if (matchClass(obj->type()) && matchName(obj->name())) + { + objNames[count] = obj->name(); + ++count; + } + } + + objNames.resize(count); + + if (doSort) + { + Foam::sort(objNames); + } + + return objNames; +} + + // Templated implementation for names(), sortedNames() template<class Type, class MatchPredicate> Foam::wordList Foam::objectRegistry::namesTypeImpl @@ -75,7 +165,7 @@ Foam::wordList Foam::objectRegistry::namesTypeImpl && matchName(obj->name()) ) { - objNames[count] = iter()->name(); + objNames[count] = obj->name(); ++count; } } @@ -93,59 +183,144 @@ Foam::wordList Foam::objectRegistry::namesTypeImpl // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -template<class Type> -Foam::wordList Foam::objectRegistry::names() const +template<class MatchPredicate> +Foam::HashTable<Foam::wordHashSet> +Foam::objectRegistry::classes +( + const MatchPredicate& matchName +) const { - return namesTypeImpl<Type>(*this, predicates::always(), false); + return classesImpl(*this, matchName); } -template<class Type> -Foam::wordList Foam::objectRegistry::names(const wordRe& matchName) const +template<class MatchPredicate> +Foam::label Foam::objectRegistry::count +( + const MatchPredicate& matchClass +) const { - return namesTypeImpl<Type>(*this, matchName, false); + return countImpl(*this, matchClass, predicates::always()); +} + + +template<class MatchPredicate1, class MatchPredicate2> +Foam::label Foam::objectRegistry::count +( + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName +) const +{ + return countImpl(*this, matchClass, matchName); +} + + +template<class Type, class MatchPredicate> +Foam::label Foam::objectRegistry::count +( + const MatchPredicate& matchName +) const +{ + return countTypeImpl<Type>(*this, matchName); } template<class Type> -Foam::wordList Foam::objectRegistry::names(const wordRes& matchName) const +Foam::label Foam::objectRegistry::count +( + const bool strict +) const { - return namesTypeImpl<Type>(*this, matchName, false); + label nObjects = 0; + + forAllConstIters(*this, iter) + { + const regIOobject* obj = iter.object(); + + if + ( + std::is_void<Type>::value + || (strict ? isType<Type>(*obj) : bool(isA<Type>(*obj))) + ) + { + ++nObjects; + } + } + + return nObjects; +} + + +template<class MatchPredicate> +Foam::wordList Foam::objectRegistry::names +( + const MatchPredicate& matchClass +) const +{ + return namesImpl(*this, matchClass, predicates::always(), false); +} + + +template<class MatchPredicate1, class MatchPredicate2> +Foam::wordList Foam::objectRegistry::names +( + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName +) const +{ + return namesImpl(*this, matchClass, matchName, false); } template<class Type> -Foam::wordList Foam::objectRegistry::names(const wordHashSet& matchName) const +Foam::wordList Foam::objectRegistry::names() const +{ + return namesTypeImpl<Type>(*this, predicates::always(), false); +} + + +template<class Type, class MatchPredicate> +Foam::wordList Foam::objectRegistry::names +( + const MatchPredicate& matchName +) const { return namesTypeImpl<Type>(*this, matchName, false); } -template<class Type> -Foam::wordList Foam::objectRegistry::sortedNames() const +template<class MatchPredicate> +Foam::wordList Foam::objectRegistry::sortedNames +( + const MatchPredicate& matchClass +) const { - return namesTypeImpl<Type>(*this, predicates::always(), true); + return namesImpl(*this, matchClass, predicates::always(), true); } -template<class Type> -Foam::wordList Foam::objectRegistry::sortedNames(const wordRe& matchName) const +template<class MatchPredicate1, class MatchPredicate2> +Foam::wordList Foam::objectRegistry::sortedNames +( + const MatchPredicate1& matchClass, + const MatchPredicate2& matchName +) const { - return namesTypeImpl<Type>(*this, matchName, true); + return namesImpl(*this, matchClass, matchName, true); } template<class Type> -Foam::wordList Foam::objectRegistry::sortedNames(const wordRes& matchName) const +Foam::wordList Foam::objectRegistry::sortedNames() const { - return namesTypeImpl<Type>(*this, matchName, true); + return namesTypeImpl<Type>(*this, predicates::always(), true); } -template<class Type> +template<class Type, class MatchPredicate> Foam::wordList Foam::objectRegistry::sortedNames ( - const wordHashSet& matchName + const MatchPredicate& matchName ) const { return namesTypeImpl<Type>(*this, matchName, true); @@ -162,13 +337,11 @@ Foam::HashTable<const Type*> Foam::objectRegistry::lookupClass forAllConstIters(*this, iter) { - if (strict ? isType<Type>(*iter()) : bool(isA<Type>(*iter()))) + const regIOobject* obj = iter.object(); + + if (strict ? isType<Type>(*obj) : bool(isA<Type>(*obj))) { - objectsOfClass.insert - ( - iter()->name(), - dynamic_cast<const Type*>(iter()) - ); + objectsOfClass.insert(obj->name(), dynamic_cast<const Type*>(obj)); } } @@ -186,13 +359,11 @@ Foam::HashTable<Type*> Foam::objectRegistry::lookupClass forAllIters(*this, iter) { - if (strict ? isType<Type>(*iter()) : bool(isA<Type>(*iter()))) + regIOobject* obj = iter.object(); + + if (strict ? isType<Type>(*obj) : bool(isA<Type>(*obj))) { - objectsOfClass.insert - ( - iter()->name(), - dynamic_cast<Type*>(iter()) - ); + objectsOfClass.insert(obj->name(), dynamic_cast<Type*>(obj)); } }