diff --git a/applications/test/IOobjectList/Test-IOobjectList.C b/applications/test/IOobjectList/Test-IOobjectList.C index 40b1f42e7e4282b51eb52fd4f70e6935857f1f8c..38031bee7fde784d1b5d4af4d74fb18b76142736 100644 --- a/applications/test/IOobjectList/Test-IOobjectList.C +++ b/applications/test/IOobjectList/Test-IOobjectList.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -23,6 +23,7 @@ License Description Basic tests of IOobjectList + \*---------------------------------------------------------------------------*/ #include "argList.H" @@ -34,13 +35,52 @@ Description using namespace Foam; +void report(const IOobjectList& objects) +{ + Info<< "Names: " << flatOutput(objects.sortedNames()) << nl + << "Objects: " << objects << nl + << "----" << nl; +} + + +void reportDetail(const IOobjectList& objects) +{ + Info<<"Details:" << nl; + + for (const word& key : objects.sortedNames()) + { + IOobject* io = objects.lookup(key); + + Info<< key << " (" << io->headerClassName() + << ") = addr " << long(io) << nl; + } + + Info<<"====" << nl; +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Main program: int main(int argc, char *argv[]) { argList::noParallel(); - argList::addOption("re", "wordRes"); + argList::addOption + ( + "filter", + "wordRes", + "filter keys with names or regexs" + ); + argList::addBoolOption + ( + "copy-append", + "test move append lists (requires -filter)" + ); + argList::addBoolOption + ( + "move-append", + "test move append lists (requires -filter)" + ); // timeSelector::addOptions(); timeSelector::addOptions(true, true); @@ -49,11 +89,25 @@ int main(int argc, char *argv[]) #include "createTime.H" wordRes matcher; - if (args.readListIfPresent<wordRe>("re", matcher)) + if (args.readListIfPresent<wordRe>("filter", matcher)) { Info<<"limit names: " << matcher << nl; } + if (args.found("copy-append") && matcher.empty()) + { + FatalError + << nl << "The -copy-append test also requires -filter" << nl + << exit(FatalError); + } + if (args.found("move-append") && matcher.empty()) + { + FatalError + << nl << "The -move-append test also requires -filter" << nl + << exit(FatalError); + } + + const hashedWordList subsetTypes { volScalarField::typeName, @@ -79,9 +133,7 @@ int main(int argc, char *argv[]) Info<< "Time: " << runTime.timeName() << nl; - Info<<"Name: " << flatOutput(objects.sortedNames()) << nl - <<"Objects: " << objects << nl - <<"Classes: " << classes << nl; + report(objects); classes.filterKeys(subsetTypes); Info<<"only retain: " << flatOutput(subsetTypes) << nl; @@ -91,6 +143,50 @@ int main(int argc, char *argv[]) classes.erase(subsetTypes); Info<<"remove: " << flatOutput(subsetTypes) << nl; Info<<"Pruned: " << classes << nl; + + // On last time + if (timeI == timeDirs.size()-1) + { + if (args.found("copy-append")) + { + Info<< nl << "Test move append" << nl; + } + else if (args.found("move-append")) + { + Info<< nl << "Test move append" << nl; + } + else + { + continue; + } + + IOobjectList other(runTime, runTime.timeName()); + + Info<< "==original==" << nl; reportDetail(objects); + + objects.filterKeys(matcher); + + Info<< "==target==" << nl; reportDetail(objects); + Info<< "==source==" << nl; reportDetail(other); + + if (args.found("copy-append")) + { + objects.append(other); + + Info<< nl << "After copy-append" << nl; + } + else + { + objects.append(std::move(other)); + + Info<< nl << "After move-append" << nl; + } + + Info<< "==target==" << nl; reportDetail(objects); + Info<< "==source==" << nl; reportDetail(other); + + Info<< nl; + } } Info<< "\nEnd\n" << endl; diff --git a/src/OpenFOAM/db/IOobjectList/IOobjectList.C b/src/OpenFOAM/db/IOobjectList/IOobjectList.C index c8147464dfa8ff01369b98b1154e28257ee8134d..b96667dc82fc3df1be9aa2a39e6bdb76336b8584 100644 --- a/src/OpenFOAM/db/IOobjectList/IOobjectList.C +++ b/src/OpenFOAM/db/IOobjectList/IOobjectList.C @@ -298,6 +298,56 @@ bool Foam::IOobjectList::add(autoPtr<IOobject>&& objectPtr) } +Foam::label Foam::IOobjectList::append(const IOobjectList& other) +{ + label count = 0; + + forAllConstIters(other, iter) + { + if (!found(iter.key())) + { + if (IOobject::debug) + { + InfoInFunction << "Copy append " << iter.key() << nl; + } + + set(iter.key(), new IOobject(*(iter.object()))); + ++count; + } + } + + return count; +} + + +Foam::label Foam::IOobjectList::append(IOobjectList&& other) +{ + // Remove by name to avoid uncertainties about invalid iterators + + label count = 0; + + wordList keys(other.toc()); + + for (const word& key : keys) + { + if (!found(key)) + { + if (IOobject::debug) + { + InfoInFunction << "Move append " << key << nl; + } + + if (add(other.remove(key))) + { + ++count; + } + } + } + + return count; +} + + bool Foam::IOobjectList::remove(const IOobject& io) { return erase(io.name()); @@ -317,15 +367,12 @@ Foam::IOobject* Foam::IOobjectList::lookup(const word& name) const return const_cast<IOobject*>(*iter); } - else - { - if (IOobject::debug) - { - InfoInFunction << "Could not find " << name << endl; - } - return nullptr; + if (IOobject::debug) + { + InfoInFunction << "Could not find " << name << endl; } + return nullptr; } diff --git a/src/OpenFOAM/db/IOobjectList/IOobjectList.H b/src/OpenFOAM/db/IOobjectList/IOobjectList.H index e1922945fcfcca1ec4cb359a0167df2c110c1958..f3d206d8506005eba226ee51ea6b4ed8cf8bd970 100644 --- a/src/OpenFOAM/db/IOobjectList/IOobjectList.H +++ b/src/OpenFOAM/db/IOobjectList/IOobjectList.H @@ -94,16 +94,34 @@ public: // Basic methods - //- Add an IOobject to the list + //- Add IOobject to the list bool add(autoPtr<IOobject>& objectPtr); - //- Add an IOobject to the list + //- Add IOobject to the list bool add(autoPtr<IOobject>&& objectPtr); - //- Remove an IOobject from the list, by iterator + //- Copy append objects from other to this list, but do not overwrite + //- existing keys. + // + // \return number of items added + label append(const IOobjectList& other); + + //- Move append objects from other to this list, but do not overwrite + //- existing keys. + // After calling this, the other parameter will contains any items + // that could not be moved. + // + // \return number of items added + label append(IOobjectList&& other); + + //- Remove IOobject from the list, by name or by iterator. + // + // \return autoPtr<IOobject> using HashPtrTable<IOobject>::remove; - //- Remove an IOobject from the list + //- Remove IOobject from the list. + // + // \return True if object was removed bool remove(const IOobject& io);