From 32916fa8458e4cfdd0debfc47ce4c20e069c1d22 Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@esi-group.com> Date: Tue, 21 May 2019 19:10:14 +0100 Subject: [PATCH] ENH: dictionary checking methods with predicates on the input values - can be used to check the validity of input values. Example: dict.getCheck<label>("nIters", greaterOp1<label>(0)); dict.getCheck<scalar>("relax", scalarMinMax::zero_one()); - use 'get' prefix for more regular dictionary methods. Eg, getOrDefault() as alternative to lookupOrDefault() - additional ops for convenient construction of predicates ENH: make dictionary writeOptionalEntries integer - allow triggering of Fatal if default values are used ENH: additional scalarRange static methods: ge0, gt0, zero_one - use GREAT instead of VGREAT for internal placeholders - additional MinMax static methods: gt, le --- .../test/dictionary2/Test-dictionary2.C | 61 +++- .../scalarPredicates/Test-scalarPredicates.C | 38 ++- etc/controlDict | 2 + src/OpenFOAM/db/dictionary/dictionary.C | 48 ++- src/OpenFOAM/db/dictionary/dictionary.H | 173 +++++++++-- src/OpenFOAM/db/dictionary/dictionaryCompat.C | 10 +- src/OpenFOAM/db/dictionary/dictionarySearch.C | 16 +- .../db/dictionary/dictionaryTemplates.C | 280 +++++++++++++++--- src/OpenFOAM/db/dictionary/entry/entry.C | 21 +- src/OpenFOAM/db/dictionary/entry/entry.H | 36 ++- src/OpenFOAM/db/dictionary/entry/entryIO.C | 6 +- .../functionEntries/removeEntry/removeEntry.C | 2 +- .../dimensionedType/dimensionedType.C | 26 +- .../dimensionedType/dimensionedType.H | 69 ++++- src/OpenFOAM/global/argList/argList.C | 2 +- src/OpenFOAM/global/argList/argList.H | 47 ++- src/OpenFOAM/global/argList/argListI.H | 4 +- src/OpenFOAM/primitives/bools/Switch/Switch.C | 10 +- src/OpenFOAM/primitives/bools/Switch/Switch.H | 18 +- src/OpenFOAM/primitives/enums/Enum.C | 14 +- src/OpenFOAM/primitives/enums/Enum.H | 38 ++- src/OpenFOAM/primitives/ops/ops.H | 31 +- .../primitives/ranges/MinMax/MinMax.H | 6 + .../primitives/ranges/MinMax/MinMaxI.H | 14 + .../ranges/scalarRange/scalarRange.C | 12 +- .../ranges/scalarRange/scalarRange.H | 18 +- .../ranges/scalarRange/scalarRangeI.H | 64 ++-- .../ranges/scalarRange/scalarRanges.H | 6 +- 28 files changed, 882 insertions(+), 190 deletions(-) diff --git a/applications/test/dictionary2/Test-dictionary2.C b/applications/test/dictionary2/Test-dictionary2.C index d66e0d05900..b05c18c3c34 100644 --- a/applications/test/dictionary2/Test-dictionary2.C +++ b/applications/test/dictionary2/Test-dictionary2.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -34,6 +34,8 @@ Description #include "IOobject.H" #include "IFstream.H" #include "dictionary.H" +#include "ops.H" +#include "scalarRange.H" #include "stringOps.H" using namespace Foam; @@ -108,6 +110,42 @@ scalar try_getScalar(const dictionary& dict, const word& k) } +// Try with getCheck<scalar> +template<class Predicate> +scalar try_getCheckScalar +( + const dictionary& dict, + const word& k, + const Predicate& pred +) +{ + scalar val(-GREAT); + + const bool throwingIOError = FatalIOError.throwExceptions(); + const bool throwingError = FatalError.throwExceptions(); + + try + { + val = dict.getCheck<scalar>(k, pred); + Info<< "getCheck<scalar>(" << k << ") = " << val << nl; + } + catch (const Foam::IOerror& err) + { + Info<< "getCheck<scalar>(" << k << ") Caught FatalIOError " + << err << nl << endl; + } + catch (const Foam::error& err) + { + Info<< "getCheck<scalar>(" << k << ") Caught FatalError " + << err << nl << endl; + } + FatalError.throwExceptions(throwingError); + FatalIOError.throwExceptions(throwingIOError); + + return val; +} + + // Try with *entry (from findEntry) and get<scalar> scalar try_getScalar(const entry* eptr, const word& k) { @@ -311,6 +349,7 @@ int main(int argc, char *argv[]) IStringStream ( "good 3.14159;\n" + "negative -3.14159;\n" "empty;\n" // "bad text;\n" // always fails // "bad 3.14159 1234;\n" // fails for readScalar @@ -338,6 +377,26 @@ int main(int argc, char *argv[]) try_getScalar(dict2, "empty"); } + + // With getCheck<scalar> + { + Info<< nl << "Test some input with getCheck<scalar>()" << nl; + + try_getCheckScalar(dict2, "good", scalarRange::gt0()); + try_getCheckScalar(dict2, "negative", scalarRange::gt0()); + + try_getCheckScalar(dict2, "good", greaterOp1<scalar>(0)); + try_getCheckScalar(dict2, "negative", greaterOp1<scalar>(0)); + + Info<< nl << "with lambda" << nl; + try_getCheckScalar + ( + dict2, + "good", + [](const scalar x) { return x > 0; } + ); + } + // With findEntry and get<scalar> { Info<< nl diff --git a/applications/test/scalarPredicates/Test-scalarPredicates.C b/applications/test/scalarPredicates/Test-scalarPredicates.C index 22338e91746..587ca38b0d4 100644 --- a/applications/test/scalarPredicates/Test-scalarPredicates.C +++ b/applications/test/scalarPredicates/Test-scalarPredicates.C @@ -36,6 +36,8 @@ Description #include "FlatOutput.H" #include "Tuple2.H" #include "StringStream.H" +#include "ops.H" +#include "bitSet.H" using namespace Foam; @@ -44,7 +46,7 @@ void doTest(const scalarList& values, const predicates::scalars& accept) { // Also tests that output is suppressed Info<<"Have: " << accept.size() << " predicates" << accept << endl; - Info<<"values: " << flatOutput(values) << endl; + Info<<"values: " << flatOutput(values) << endl; for (const scalar& value : values) { @@ -60,6 +62,30 @@ void doTest(const scalarList& values, const predicates::scalars& accept) } +template<class Predicate> +void testPredicate(const scalarList& values, const Predicate& pred) +{ + bitSet matches; + + label i=0; + + for (const scalar& value : values) + { + if (pred(value)) + { + matches.set(i); + } + + ++i; + } + + IndirectList<scalar> matched(values, matches.toc()); + + Info<< "matched: " << flatOutput(matched.addressing()) + << " = " << flatOutput(matched) << nl; +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Main program: @@ -149,6 +175,16 @@ int main(int argc, char *argv[]) } + Info<< nl << "Test with ops" << nl; + Info<<"values: " << flatOutput(values) << endl; + { + testPredicate(values, lessOp1<scalar>(10)); + testPredicate(values, greaterOp1<scalar>(100)); + + // Also with dissimilar type + testPredicate(values, lessEqOp1<label>(0)); + } + Info<< "\nEnd\n" << endl; return 0; diff --git a/etc/controlDict b/etc/controlDict index 5e03e45e20e..223f28e3abd 100644 --- a/etc/controlDict +++ b/etc/controlDict @@ -37,6 +37,8 @@ InfoSwitches writePrecision 6; writeDictionaries 0; + + // Report optional dictionary entries. For value > 1, treat as fatal. writeOptionalEntries 0; // Write lagrangian "positions" file in v1706 format (and earlier) diff --git a/src/OpenFOAM/db/dictionary/dictionary.C b/src/OpenFOAM/db/dictionary/dictionary.C index 775d90ea597..a15a73c8559 100644 --- a/src/OpenFOAM/db/dictionary/dictionary.C +++ b/src/OpenFOAM/db/dictionary/dictionary.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2015-2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2015-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2017 OpenFOAM Foundation @@ -42,13 +42,12 @@ namespace Foam const Foam::dictionary Foam::dictionary::null; -bool Foam::dictionary::writeOptionalEntries +int Foam::dictionary::writeOptionalEntries ( Foam::debug::infoSwitch("writeOptionalEntries", 0) ); - // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::dictionary::dictionary() @@ -311,13 +310,30 @@ void Foam::dictionary::checkITstream } +void Foam::dictionary::raiseBadInput(const word& keyword) const +{ + // Can use FatalIOError instead of SafeFatalIOError + // since predicate checks are not used at the earliest stages + FatalIOError + ( + "", // functionName + "", // sourceFileName + 0, // sourceFileLineNumber + *this // ios + ) + << "Entry '" << keyword << "' with invalid input in dictionary " + << name() << nl << nl + << exit(FatalIOError); +} + + bool Foam::dictionary::found ( const word& keyword, enum keyType::option matchOpt ) const { - return csearch(keyword, matchOpt).found(); + return csearch(keyword, matchOpt).good(); } @@ -359,11 +375,11 @@ const Foam::entry& Foam::dictionary::lookupEntry { const const_searcher finder(csearch(keyword, matchOpt)); - if (!finder.found()) + if (!finder.good()) { FatalIOErrorInFunction(*this) << "Entry '" << keyword << "' not found in dictionary " - << name() + << name() << nl << exit(FatalIOError); } @@ -395,7 +411,7 @@ bool Foam::dictionary::substituteKeyword(const word& keyword, bool mergeEntry) const const_searcher finder(csearch(varName, keyType::REGEX_RECURSIVE)); // If defined insert its entries into this dictionary - if (finder.found()) + if (finder.good()) { for (const entry& e : finder.dict()) { @@ -427,7 +443,7 @@ bool Foam::dictionary::substituteScopedKeyword const auto finder(csearchScoped(varName, keyType::REGEX_RECURSIVE)); // If defined insert its entries into this dictionary - if (finder.found()) + if (finder.good()) { for (const entry& e : finder.dict()) { @@ -473,11 +489,11 @@ const Foam::dictionary& Foam::dictionary::subDict(const word& keyword) const // Allow patterns, non-recursive const const_searcher finder(csearch(keyword, keyType::REGEX)); - if (!finder.found()) + if (!finder.good()) { FatalIOErrorInFunction(*this) << "Entry '" << keyword << "' not found in dictionary " - << name() + << name() << nl << exit(FatalIOError); } @@ -490,11 +506,11 @@ Foam::dictionary& Foam::dictionary::subDict(const word& keyword) // Allow patterns, non-recursive searcher finder(search(keyword, keyType::REGEX)); - if (!finder.found()) + if (!finder.good()) { FatalIOErrorInFunction(*this) << "Entry '" << keyword << "' not found in dictionary " - << name() + << name() << nl << exit(FatalIOError); } @@ -526,7 +542,7 @@ Foam::dictionary Foam::dictionary::subOrEmptyDict << exit(FatalIOError); } - if (finder.found()) + if (finder.good()) { IOWarningInFunction(*this) << "Entry '" << keyword @@ -552,7 +568,7 @@ const Foam::dictionary& Foam::dictionary::optionalSubDict return finder.dict(); } - if (finder.found()) + if (finder.good()) { IOWarningInFunction(*this) << "Entry '" << keyword @@ -611,7 +627,7 @@ Foam::entry* Foam::dictionary::add(entry* entryPtr, bool mergeEntry) auto iter = hashedEntries_.find(entryPtr->keyword()); - if (mergeEntry && iter.found()) + if (mergeEntry && iter.good()) { // Merge dictionary with dictionary if (iter()->isDict() && entryPtr->isDict()) @@ -786,7 +802,7 @@ bool Foam::dictionary::merge(const dictionary& dict) { auto fnd = hashedEntries_.find(e.keyword()); - if (fnd.found()) + if (fnd.good()) { // Recursively merge sub-dictionaries // TODO: merge without copying diff --git a/src/OpenFOAM/db/dictionary/dictionary.H b/src/OpenFOAM/db/dictionary/dictionary.H index 1a510281d82..7200a507edb 100644 --- a/src/OpenFOAM/db/dictionary/dictionary.H +++ b/src/OpenFOAM/db/dictionary/dictionary.H @@ -62,8 +62,8 @@ Note key2 $..key1; // use key1 value from parent subdict2 { - key2 val2; - key3 $...key1; // use key1 value from grandparent + key2 val2; + key3 $...key1; // use key1 value from grandparent } } @@ -285,8 +285,9 @@ private: // Private Data //- Report optional keywords and values if not present in dictionary + // For value greater than 1: fatal. // Set/unset via an InfoSwitch - static bool writeOptionalEntries; + static int writeOptionalEntries; //- The dictionary name fileName name_; @@ -359,6 +360,10 @@ private: ) const; + //- Emit IOError about bad input for the entry + void raiseBadInput(const word& keyword) const; + + public: // Declare name of the class and its debug switch @@ -532,7 +537,6 @@ public: enum keyType::option matchOpt = keyType::REGEX ); - //- Search for an entry (const access) with the given keyword. //- Find and return a sub-dictionary pointer if present // (and a sub-dictionary) otherwise return nullptr. // @@ -543,6 +547,7 @@ public: enum keyType::option matchOpt = keyType::REGEX ) const; + //- Search for an entry (const access) with the given keyword. // // \param matchOpt the default search is non-recursive with patterns // @@ -553,22 +558,22 @@ public: enum keyType::option matchOpt ) const; - //- Find and return a T. + //- Find and return an entry data stream. //- FatalIOError if not found, or if the number of tokens is incorrect. // // \param matchOpt the default search is non-recursive with patterns - template<class T> - T get + ITstream& lookup ( const word& keyword, enum keyType::option matchOpt = keyType::REGEX ) const; - //- Find and return an entry data stream. + //- Find and return a T. //- FatalIOError if not found, or if the number of tokens is incorrect. // // \param matchOpt the default search is non-recursive with patterns - ITstream& lookup + template<class T> + T get ( const word& keyword, enum keyType::option matchOpt = keyType::REGEX @@ -579,7 +584,7 @@ public: // // \param matchOpt the default search is non-recursive with patterns template<class T> - T lookupOrDefault + T getOrDefault ( const word& keyword, const T& deflt, @@ -592,7 +597,7 @@ public: // // \param matchOpt the default search is non-recursive with patterns template<class T> - T lookupOrAddDefault + T getOrAdd ( const word& keyword, const T& deflt, @@ -633,6 +638,86 @@ public: enum keyType::option matchOpt = keyType::REGEX ) const; + //- Find and return a T with additional checking + //- FatalIOError if not found, or if the number of tokens is incorrect. + // + // \param pred the value check predicate + // \param matchOpt the default search is non-recursive with patterns + template<class T, class Predicate> + T getCheck + ( + const word& keyword, + const Predicate& pred, + enum keyType::option matchOpt = keyType::REGEX + ) const; + + //- Find and return a T, or return the given default value. + //- FatalIOError if it is found and the number of tokens is incorrect. + // + // \param pred the value check predicate + // \param matchOpt the default search is non-recursive with patterns + template<class T, class Predicate> + T getCheckOrDefault + ( + const word& keyword, + const T& deflt, + const Predicate& pred, + enum keyType::option matchOpt = keyType::REGEX + ) const; + + //- Find and return a T, or return the given default value + //- and add it to dictionary. + //- FatalIOError if it is found and the number of tokens is incorrect. + // + // \param pred the value check predicate + // \param matchOpt the default search is non-recursive with patterns + template<class T, class Predicate> + T getCheckOrAdd + ( + const word& keyword, + const T& deflt, + const Predicate& pred, + enum keyType::option matchOpt = keyType::REGEX + ); + + //- Find entry and assign to T val. + //- FatalIOError if it is found and the number of tokens is incorrect, + //- or it is mandatory and not found. + // + // \param val the value to read into + // \param pred the value check predicate + // \param matchOpt the default search is non-recursive with patterns + // \param mandatory the keyword is mandatory + // + // \return true if the entry was found. + template<class T, class Predicate> + bool readCheck + ( + const word& keyword, + T& val, + const Predicate& pred, + enum keyType::option matchOpt = keyType::REGEX, + bool mandatory = true + ) const; + + //- Find an entry if present, and assign to T val. + //- FatalIOError if it is found and the number of tokens is incorrect. + // Default search: non-recursive with patterns. + // + // \param val the value to read into + // \param pred the value check predicate + // \param matchOpt the default search is non-recursive with patterns + // + // \return true if the entry was found. + template<class T, class Predicate> + bool readCheckIfPresent + ( + const word& keyword, + T& val, + const Predicate& pred, + enum keyType::option matchOpt = keyType::REGEX + ) const; + //- Check if entry is found and and is a sub-dictionary. // // Search type: non-recursive with patterns. @@ -983,32 +1068,32 @@ public: enum keyType::option ) const; - //- Find and return a T + //- Find and return an entry data stream, //- using any compatibility names if needed. - //- FatalIOError if not found, or if there are excess tokens. // Default search: non-recursive with patterns. // // \param compat list of old compatibility keywords and the last // OpenFOAM version for which they were used. // \param recursive search parent dictionaries // \param patternMatch use regular expressions - template<class T> - T getCompat + ITstream& lookupCompat ( const word& keyword, std::initializer_list<std::pair<const char*,int>> compat, enum keyType::option = keyType::REGEX ) const; - //- Find and return an entry data stream, + //- Find and return a T //- using any compatibility names if needed. + //- FatalIOError if not found, or if there are excess tokens. // Default search: non-recursive with patterns. // // \param compat list of old compatibility keywords and the last // OpenFOAM version for which they were used. // \param recursive search parent dictionaries // \param patternMatch use regular expressions - ITstream& lookupCompat + template<class T> + T getCompat ( const word& keyword, std::initializer_list<std::pair<const char*,int>> compat, @@ -1024,7 +1109,7 @@ public: // \param recursive search parent dictionaries // \param patternMatch use regular expressions template<class T> - T lookupOrDefaultCompat + T getOrDefaultCompat ( const word& keyword, std::initializer_list<std::pair<const char*,int>> compat, @@ -1105,6 +1190,58 @@ public: // Housekeeping + //- Find and return a T, or return the given default value. + //- FatalIOError if it is found and the number of tokens is incorrect. + // + // \param matchOpt the default search is non-recursive with patterns + template<class T> + T lookupOrDefault + ( + const word& keyword, + const T& deflt, + enum keyType::option matchOpt = keyType::REGEX + ) const + { + return getOrDefault<T>(keyword, deflt, matchOpt); + } + + + //- Find and return a T, or return the given default value + //- and add it to dictionary. + //- FatalIOError if it is found and the number of tokens is incorrect. + // + // \param matchOpt the default search is non-recursive with patterns + template<class T> + T lookupOrAddDefault + ( + const word& keyword, + const T& deflt, + enum keyType::option matchOpt = keyType::REGEX + ) + { + return getOrAdd<T>(keyword, deflt, matchOpt); + } + + //- Find and return a T, or return the given default value + //- using any compatibility names if needed. + // Default search: non-recursive with patterns. + // + // \param compat list of old compatibility keywords and the last + // OpenFOAM version for which they were used. + // \param recursive search parent dictionaries + // \param patternMatch use regular expressions + template<class T> + T lookupOrDefaultCompat + ( + const word& keyword, + std::initializer_list<std::pair<const char*,int>> compat, + const T& deflt, + enum keyType::option matchOpt = keyType::REGEX + ) const + { + return getOrDefaultCompat<T>(keyword, compat, deflt, matchOpt); + } + //- Deprecated(2018-07) find and return an entry data stream // // \deprecated(2018-07) - use lookup() method diff --git a/src/OpenFOAM/db/dictionary/dictionaryCompat.C b/src/OpenFOAM/db/dictionary/dictionaryCompat.C index c35d7f6b234..ca4a9a7cbb8 100644 --- a/src/OpenFOAM/db/dictionary/dictionaryCompat.C +++ b/src/OpenFOAM/db/dictionary/dictionaryCompat.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -54,7 +54,7 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchCompat { const_searcher finder(csearch(keyword, matchOpt)); - if (finder.found()) + if (finder.good()) { return finder; } @@ -63,7 +63,7 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchCompat { finder = csearch(word::validate(iter.first), matchOpt); - if (finder.found()) + if (finder.good()) { // Only want a single warning (on master), but guard with a // parRun check to avoid Pstream::master() when Pstream has not @@ -101,7 +101,7 @@ bool Foam::dictionary::foundCompat enum keyType::option matchOpt ) const { - return csearchCompat(keyword, compat, matchOpt).found(); + return csearchCompat(keyword, compat, matchOpt).good(); } @@ -125,7 +125,7 @@ const Foam::entry& Foam::dictionary::lookupEntryCompat { const const_searcher finder(csearchCompat(keyword, compat, matchOpt)); - if (!finder.found()) + if (!finder.good()) { FatalIOErrorInFunction(*this) << "Entry '" << keyword << "' not found in dictionary " diff --git a/src/OpenFOAM/db/dictionary/dictionarySearch.C b/src/OpenFOAM/db/dictionary/dictionarySearch.C index d3fcee91c45..59cebc461dd 100644 --- a/src/OpenFOAM/db/dictionary/dictionarySearch.C +++ b/src/OpenFOAM/db/dictionary/dictionarySearch.C @@ -130,7 +130,7 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchDotScoped // a.b.c.d it would try // a.b, a.b.c, a.b.c.d - if (!finder.found()) + if (!finder.good()) { while (!finder.isDict()) { @@ -225,7 +225,7 @@ Foam::dictionary::const_searcher Foam::dictionary::csearchSlashScoped auto finder = dictPtr->csearch(key, matchOpt); - if (finder.found()) + if (finder.good()) { if (remaining) { @@ -269,7 +269,7 @@ Foam::dictionary::const_searcher Foam::dictionary::csearch auto iter = hashedEntries_.cfind(keyword); - if (iter.found()) + if (iter.good()) { finder.set(iter.val()); return finder; @@ -425,7 +425,7 @@ const Foam::dictionary* Foam::dictionary::cfindScopedDict auto iter = dictPtr->hashedEntries_.cfind(cmpt); - if (iter.found()) + if (iter.good()) { const entry *eptr = iter.val(); @@ -532,7 +532,7 @@ Foam::dictionary* Foam::dictionary::makeScopedDict(const fileName& dictPath) auto iter = dictPtr->hashedEntries_.find(cmptName); - if (iter.found()) + if (iter.good()) { entry *eptr = iter.val(); @@ -581,7 +581,7 @@ bool Foam::dictionary::remove(const word& keyword) { auto iter = hashedEntries_.find(keyword); - if (iter.found()) + if (iter.good()) { // Delete from patterns auto wcLink = patterns_.begin(); @@ -621,7 +621,7 @@ bool Foam::dictionary::changeKeyword // Check that oldKeyword exists and can be changed auto iter = hashedEntries_.find(oldKeyword); - if (!iter.found()) + if (!iter.good()) { return false; } @@ -638,7 +638,7 @@ bool Foam::dictionary::changeKeyword auto iter2 = hashedEntries_.find(newKeyword); // newKeyword already exists - if (iter2.found()) + if (iter2.good()) { if (overwrite) { diff --git a/src/OpenFOAM/db/dictionary/dictionaryTemplates.C b/src/OpenFOAM/db/dictionary/dictionaryTemplates.C index 31737707232..1ae164b5eca 100644 --- a/src/OpenFOAM/db/dictionary/dictionaryTemplates.C +++ b/src/OpenFOAM/db/dictionary/dictionaryTemplates.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2017 OpenFOAM Foundation @@ -64,6 +64,20 @@ T Foam::dictionary::get } +template<class T, class Predicate> +T Foam::dictionary::getCheck +( + const word& keyword, + const Predicate& pred, + enum keyType::option matchOpt +) const +{ + T val; + readCheck<T, Predicate>(keyword, val, pred, matchOpt); + return val; +} + + template<class T> T Foam::dictionary::getCompat ( @@ -79,49 +93,111 @@ T Foam::dictionary::getCompat template<class T> -bool Foam::dictionary::readCompat +T Foam::dictionary::getOrDefault ( const word& keyword, - std::initializer_list<std::pair<const char*,int>> compat, - T& val, - enum keyType::option matchOpt, - bool mandatory + const T& deflt, + enum keyType::option matchOpt ) const { - const const_searcher finder(csearchCompat(keyword, compat, matchOpt)); + const const_searcher finder(csearch(keyword, matchOpt)); - if (finder.found()) + if (finder.good()) { + T val; + ITstream& is = finder.ptr()->stream(); is >> val; checkITstream(is, keyword); - return true; + return val; } - else if (mandatory) + else if (writeOptionalEntries) { - FatalIOErrorInFunction(*this) - << "Entry '" << keyword << "' not found in dictionary " - << name() - << exit(FatalIOError); + if (writeOptionalEntries > 1) + { + FatalIOErrorInFunction(*this) + << "Optional entry '" << keyword + << "' not found. Default '" << deflt << "' ignored" << nl + << exit(FatalIOError); + } + else + { + IOInfoInFunction(*this) + << "Optional entry '" << keyword + << "' not found. Using default '" << deflt << "'" << nl; + } } - return false; + return deflt; } template<class T> -T Foam::dictionary::lookupOrDefault +T Foam::dictionary::getOrAdd +( + const word& keyword, + const T& deflt, + enum keyType::option matchOpt +) +{ + const const_searcher finder(csearch(keyword, matchOpt)); + + if (finder.good()) + { + T val; + + ITstream& is = finder.ptr()->stream(); + is >> val; + + checkITstream(is, keyword); + + return val; + } + else if (writeOptionalEntries) + { + if (writeOptionalEntries > 1) + { + FatalIOErrorInFunction(*this) + << "Optional entry '" << keyword + << "' not found. Default '" << deflt << "' ignored" << nl + << exit(FatalIOError); + } + else + { + IOInfoInFunction(*this) + << "Optional entry '" << keyword + << "' not found. Adding default '" << deflt << "'" << nl; + } + } + + add(new primitiveEntry(keyword, deflt)); + return deflt; +} + + +template<class T, class Predicate> +T Foam::dictionary::getCheckOrDefault ( const word& keyword, const T& deflt, + const Predicate& pred, enum keyType::option matchOpt ) const { + if (!pred(deflt)) + { + // Could be as FULLDEBUG instead? + FatalIOErrorInFunction(*this) + << "Entry '" << keyword << "' with invalid default in dictionary " + << name() + << exit(FatalIOError); + } + const const_searcher finder(csearch(keyword, matchOpt)); - if (finder.found()) + if (finder.good()) { T val; @@ -130,31 +206,55 @@ T Foam::dictionary::lookupOrDefault checkITstream(is, keyword); + if (!pred(val)) + { + raiseBadInput(keyword); + } + return val; } else if (writeOptionalEntries) { - IOInfoInFunction(*this) - << "Optional entry '" << keyword - << "' not found, using default value '" << deflt << "'" - << nl; + if (writeOptionalEntries > 1) + { + FatalIOErrorInFunction(*this) + << "Optional entry '" << keyword + << "' not found. Default '" << deflt << "' ignored" << nl + << exit(FatalIOError); + } + else + { + IOInfoInFunction(*this) + << "Optional entry '" << keyword + << "' not found. Using default '" << deflt << "'" << nl; + } } return deflt; } -template<class T> -T Foam::dictionary::lookupOrAddDefault +template<class T, class Predicate> +T Foam::dictionary::getCheckOrAdd ( const word& keyword, const T& deflt, + const Predicate& pred, enum keyType::option matchOpt ) { + if (!pred(deflt)) + { + // Could be as FULLDEBUG instead? + FatalIOErrorInFunction(*this) + << "Entry '" << keyword << "' with invalid default in dictionary " + << name() + << exit(FatalIOError); + } + const const_searcher finder(csearch(keyword, matchOpt)); - if (finder.found()) + if (finder.good()) { T val; @@ -163,14 +263,28 @@ T Foam::dictionary::lookupOrAddDefault checkITstream(is, keyword); + if (!pred(val)) + { + raiseBadInput(keyword); + } + return val; } else if (writeOptionalEntries) { - IOInfoInFunction(*this) - << "Optional entry '" << keyword - << "' not found, adding default value '" << deflt << "'" - << nl; + if (writeOptionalEntries > 1) + { + FatalIOErrorInFunction(*this) + << "Optional entry '" << keyword + << "' not found. Default '" << deflt << "' ignored" << nl + << exit(FatalIOError); + } + else + { + IOInfoInFunction(*this) + << "Optional entry '" << keyword + << "' not found. Adding default '" << deflt << "'" << nl; + } } add(new primitiveEntry(keyword, deflt)); @@ -189,7 +303,7 @@ bool Foam::dictionary::readEntry { const const_searcher finder(csearch(keyword, matchOpt)); - if (finder.found()) + if (finder.good()) { ITstream& is = finder.ptr()->stream(); is >> val; @@ -202,7 +316,78 @@ bool Foam::dictionary::readEntry { FatalIOErrorInFunction(*this) << "Entry '" << keyword << "' not found in dictionary " - << name() + << name() << nl + << exit(FatalIOError); + } + + return false; +} + + +template<class T, class Predicate> +bool Foam::dictionary::readCheck +( + const word& keyword, + T& val, + const Predicate& pred, + enum keyType::option matchOpt, + bool mandatory +) const +{ + const const_searcher finder(csearch(keyword, matchOpt)); + + if (finder.good()) + { + ITstream& is = finder.ptr()->stream(); + is >> val; + + checkITstream(is, keyword); + + if (!pred(val)) + { + raiseBadInput(keyword); + } + + return true; + } + else if (mandatory) + { + FatalIOErrorInFunction(*this) + << "Entry '" << keyword << "' not found in dictionary " + << name() << nl + << exit(FatalIOError); + } + + return false; +} + + +template<class T> +bool Foam::dictionary::readCompat +( + const word& keyword, + std::initializer_list<std::pair<const char*,int>> compat, + T& val, + enum keyType::option matchOpt, + bool mandatory +) const +{ + const const_searcher finder(csearchCompat(keyword, compat, matchOpt)); + + if (finder.good()) + { + ITstream& is = finder.ptr()->stream(); + is >> val; + + checkITstream(is, keyword); + + return true; + } + else if (mandatory) + { + FatalIOErrorInFunction(*this) + << "Entry '" << keyword << "' not found in dictionary " + << name() << nl << exit(FatalIOError); } @@ -223,8 +408,22 @@ bool Foam::dictionary::readIfPresent } +template<class T, class Predicate> +bool Foam::dictionary::readCheckIfPresent +( + const word& keyword, + T& val, + const Predicate& pred, + enum keyType::option matchOpt +) const +{ + // Read is non-mandatory + return readCheck<T, Predicate>(keyword, val, pred, matchOpt, false); +} + + template<class T> -T Foam::dictionary::lookupOrDefaultCompat +T Foam::dictionary::getOrDefaultCompat ( const word& keyword, std::initializer_list<std::pair<const char*,int>> compat, @@ -234,7 +433,7 @@ T Foam::dictionary::lookupOrDefaultCompat { const const_searcher finder(csearchCompat(keyword, compat, matchOpt)); - if (finder.found()) + if (finder.good()) { T val; @@ -247,10 +446,19 @@ T Foam::dictionary::lookupOrDefaultCompat } else if (writeOptionalEntries) { - IOInfoInFunction(*this) - << "Optional entry '" << keyword << "' not found," - << " using default value '" << deflt << "'" - << nl; + if (writeOptionalEntries > 1) + { + FatalIOErrorInFunction(*this) + << "Optional entry '" << keyword + << "' not found. Default '" << deflt << "' ignored" << nl + << exit(FatalIOError); + } + else + { + IOInfoInFunction(*this) + << "Optional entry '" << keyword + << "' not found. Using default '" << deflt << "'" << nl; + } } return deflt; diff --git a/src/OpenFOAM/db/dictionary/entry/entry.C b/src/OpenFOAM/db/dictionary/entry/entry.C index 9bd55a3e050..7583c7bc81f 100644 --- a/src/OpenFOAM/db/dictionary/entry/entry.C +++ b/src/OpenFOAM/db/dictionary/entry/entry.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | + \\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2015 OpenFOAM Foundation @@ -73,6 +73,25 @@ Foam::autoPtr<Foam::entry> Foam::entry::clone() const // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +void Foam::entry::raiseBadInput(const ITstream& is) const +{ + const word& keyword = keyword_; + + // Can use FatalIOError instead of SafeFatalIOError + // since predicate checks are not used at the earliest stages + FatalIOError + ( + "", // functionName + "", // sourceFileName + 0, // sourceFileLineNumber + this->name(), // ioFileName + is.lineNumber() // ioStartLineNumber + ) + << "Entry '" << keyword << "' with invalid input" << nl << nl + << exit(FatalIOError); +} + + void Foam::entry::checkITstream(const ITstream& is) const { const word& keyword = keyword_; diff --git a/src/OpenFOAM/db/dictionary/entry/entry.H b/src/OpenFOAM/db/dictionary/entry/entry.H index 1fe2e6b2d84..58180f5955b 100644 --- a/src/OpenFOAM/db/dictionary/entry/entry.H +++ b/src/OpenFOAM/db/dictionary/entry/entry.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2016 OpenFOAM Foundation @@ -109,6 +109,9 @@ private: // \return True if it is a valid keyType. static bool getKeyword(keyType& keyword, Istream& is); + //- Emit IOError about bad input for the entry + void raiseBadInput(const ITstream& is) const; + public: @@ -272,6 +275,37 @@ public: checkITstream(is); } + //- Get a T from the stream, + //- FatalIOError if the number of tokens is incorrect. + // + // \param pred the value check predicate + template<class T, class Predicate> + T getCheck(const Predicate& pred) const + { + T val; + readCheck<T>(val, pred); + return val; + } + + //- Assign to T val, + //- FatalIOError if the number of tokens is incorrect. + // + // \param val the value to read into + // \param pred the value check predicate + template<class T, class Predicate> + void readCheck(T& val, const Predicate& pred) const + { + ITstream& is = this->stream(); + is >> val; + + checkITstream(is); + if (!pred(val)) + { + raiseBadInput(is); + } + } + + // Write //- Write diff --git a/src/OpenFOAM/db/dictionary/entry/entryIO.C b/src/OpenFOAM/db/dictionary/entry/entryIO.C index 60b62f60d01..fbd29788289 100644 --- a/src/OpenFOAM/db/dictionary/entry/entryIO.C +++ b/src/OpenFOAM/db/dictionary/entry/entryIO.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2016 OpenFOAM Foundation @@ -246,7 +246,7 @@ bool Foam::entry::New const auto finder = parentDict.csearchScoped(varName, keyType::REGEX_RECURSIVE); - if (finder.found()) + if (finder.good()) { // Read as primitiveEntry const keyType newKeyword(finder.ptr()->stream()); @@ -311,7 +311,7 @@ bool Foam::entry::New // How to manage duplicate entries bool mergeEntry = false; - if (finder.found()) + if (finder.good()) { // Use keyword from the found entry (ie, eliminate scoping chars) const keyType key = finder.ref().keyword(); diff --git a/src/OpenFOAM/db/dictionary/functionEntries/removeEntry/removeEntry.C b/src/OpenFOAM/db/dictionary/functionEntries/removeEntry/removeEntry.C index 6ab5618fa7d..b067fb76c48 100644 --- a/src/OpenFOAM/db/dictionary/functionEntries/removeEntry/removeEntry.C +++ b/src/OpenFOAM/db/dictionary/functionEntries/removeEntry/removeEntry.C @@ -65,7 +65,7 @@ bool Foam::functionEntries::removeEntry::execute // Remove scoped keyword, or keyword in the local scope auto finder(parentDict.searchScoped(key, keyType::LITERAL)); - if (finder.found()) + if (finder.good()) { finder.context().remove(finder.ptr()->keyword()); } diff --git a/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.C b/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.C index 20487de8c95..cc0240be0ba 100644 --- a/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.C +++ b/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.C @@ -274,38 +274,38 @@ Foam::dimensioned<Type>::dimensioned // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // template<class Type> -Foam::dimensioned<Type> Foam::dimensioned<Type>::lookupOrDefault +Foam::dimensioned<Type> Foam::dimensioned<Type>::getOrDefault ( const word& name, const dictionary& dict, const dimensionSet& dims, - const Type& defaultValue + const Type& deflt ) { // checkDims = true - return dimensioned<Type>(name, dims, defaultValue, dict); + return dimensioned<Type>(name, dims, deflt, dict); } template<class Type> -Foam::dimensioned<Type> Foam::dimensioned<Type>::lookupOrDefault +Foam::dimensioned<Type> Foam::dimensioned<Type>::getOrDefault ( const word& name, const dictionary& dict, - const Type& defaultValue + const Type& deflt ) { - return dimensioned<Type>(name, dimless, defaultValue, dict); + return dimensioned<Type>(name, dimless, deflt, dict); } template<class Type> -Foam::dimensioned<Type> Foam::dimensioned<Type>::lookupOrAddToDict +Foam::dimensioned<Type> Foam::dimensioned<Type>::getOrAddToDict ( const word& name, dictionary& dict, const dimensionSet& dims, - const Type& defaultValue + const Type& deflt ) { if (dict.found(name)) @@ -313,20 +313,20 @@ Foam::dimensioned<Type> Foam::dimensioned<Type>::lookupOrAddToDict return dimensioned<Type>(name, dims, dict); } - (void) dict.add(name, defaultValue); - return dimensioned<Type>(name, dims, defaultValue); + (void) dict.add(name, deflt); + return dimensioned<Type>(name, dims, deflt); } template<class Type> -Foam::dimensioned<Type> Foam::dimensioned<Type>::lookupOrAddToDict +Foam::dimensioned<Type> Foam::dimensioned<Type>::getOrAddToDict ( const word& name, dictionary& dict, - const Type& defaultValue + const Type& deflt ) { - return lookupOrAddToDict(name, dict, dimless, defaultValue); + return getOrAddToDict(name, dict, dimless, deflt); } diff --git a/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.H b/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.H index 982ab31c7df..2e768cbda56 100644 --- a/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.H +++ b/src/OpenFOAM/dimensionedTypes/dimensionedType/dimensionedType.H @@ -207,42 +207,42 @@ public: //- Construct dimensioned from dictionary, with default value. //- FatalIOError if there are excess tokens. - static dimensioned<Type> lookupOrDefault + static dimensioned<Type> getOrDefault ( const word& name, const dictionary& dict, const dimensionSet& dims = dimless, - const Type& defaultValue = Type(Zero) + const Type& deflt = Type(Zero) ); //- Construct dimensionless from dictionary, with default value. // FatalIOError if it is found and there are excess tokens. - static dimensioned<Type> lookupOrDefault + static dimensioned<Type> getOrDefault ( const word& name, const dictionary& dict, - const Type& defaultValue = Type(Zero) + const Type& deflt = Type(Zero) ); //- Construct dimensioned from dictionary, with default value. // If the value is not found, it is added into the dictionary. // FatalIOError if it is found and there are excess tokens. - static dimensioned<Type> lookupOrAddToDict + static dimensioned<Type> getOrAddToDict ( const word& name, dictionary& dict, const dimensionSet& dims = dimless, - const Type& defaultValue = Type(Zero) + const Type& deflt = Type(Zero) ); //- Construct dimensionless from dictionary, with default value. // If the value is not found, it is added into the dictionary. // FatalIOError if it is found and there are excess tokens. - static dimensioned<Type> lookupOrAddToDict + static dimensioned<Type> getOrAddToDict ( const word& name, dictionary& dict, - const Type& defaultValue = Type(Zero) + const Type& deflt = Type(Zero) ); @@ -361,6 +361,59 @@ public: // dictionary instead (additional checks on the input stream). dimensioned(const word& name, const dimensionSet& dims, Istream& is) FOAM_DEPRECATED(2018-11); + + + //- Construct dimensioned from dictionary, with default value. + //- FatalIOError if there are excess tokens. + static dimensioned<Type> lookupOrDefault + ( + const word& name, + const dictionary& dict, + const dimensionSet& dims = dimless, + const Type& deflt = Type(Zero) + ) + { + return getOrDefault(name, dict, dims, deflt); + } + + //- Construct dimensionless from dictionary, with default value. + // FatalIOError if it is found and there are excess tokens. + static dimensioned<Type> lookupOrDefault + ( + const word& name, + const dictionary& dict, + const Type& deflt = Type(Zero) + ) + { + return getOrDefault(name, dict, deflt); + } + + //- Construct dimensioned from dictionary, with default value. + // If the value is not found, it is added into the dictionary. + // FatalIOError if it is found and there are excess tokens. + static dimensioned<Type> lookupOrAddToDict + ( + const word& name, + dictionary& dict, + const dimensionSet& dims = dimless, + const Type& deflt = Type(Zero) + ) + { + return getOrAddToDict(name, dict, dims, deflt); + } + + //- Construct dimensionless from dictionary, with default value. + // If the value is not found, it is added into the dictionary. + // FatalIOError if it is found and there are excess tokens. + static dimensioned<Type> lookupOrAddToDict + ( + const word& name, + dictionary& dict, + const Type& deflt = Type(Zero) + ) + { + return getOrAddToDict(name, dict, deflt); + } }; diff --git a/src/OpenFOAM/global/argList/argList.C b/src/OpenFOAM/global/argList/argList.C index f9daf29dc8b..2ac39189fe8 100644 --- a/src/OpenFOAM/global/argList/argList.C +++ b/src/OpenFOAM/global/argList/argList.C @@ -1168,7 +1168,7 @@ void Foam::argList::parse decompDict.readEntry("numberOfSubdomains", dictNProcs); - if (decompDict.lookupOrDefault("distributed", false)) + if (decompDict.getOrDefault("distributed", false)) { parRunControl_.distributed(true); decompDict.readEntry("roots", roots); diff --git a/src/OpenFOAM/global/argList/argList.H b/src/OpenFOAM/global/argList/argList.H index d505a534aef..422818c5a28 100644 --- a/src/OpenFOAM/global/argList/argList.H +++ b/src/OpenFOAM/global/argList/argList.H @@ -124,7 +124,7 @@ namespace Foam class argList { - // Private data + // Private Data //- Track if command arguments are mandatory/optional static bool argsMandatory_; @@ -383,7 +383,7 @@ public: inline T opt(const word& optName) const; //- Get a value from the named option if present, or return default. - // Identical to lookupOrDefault(). + // Identical to getOrDefault(). template<class T> inline T opt(const word& optName, const T& deflt) const; @@ -405,7 +405,7 @@ public: //- Get a value from the named option if present, or return default. template<class T> - inline T lookupOrDefault + inline T getOrDefault ( const word& optName, const T& deflt @@ -590,6 +590,16 @@ public: inline const string& operator[](const word& optName) const; + // Housekeeping + + //- Get a value from the named option if present, or return default. + template<class T> + T lookupOrDefault(const word& optName, const T& deflt) const + { + return getOrDefault<T>(optName, deflt); + } + + // Older style access (including 1712 release) #ifdef Foam_argList_1712 @@ -598,7 +608,8 @@ public: // Index 1 is the first (non-option) argument. // \deprecated(2018-08) - use get() method template<class T> - inline T read(const label index) const + T FOAM_DEPRECATED_FOR(2018-08, "get() method") + read(const label index) const { return this->get<T>(index); } @@ -607,21 +618,24 @@ public: // Index 1 is the first (non-option) argument. // \deprecated(2018-01) - use get() method template<class T> - inline T argRead(const label index) const + T FOAM_DEPRECATED_FOR(2018-01, "get() method") + argRead(const label index) const { return this->get<T>(index); } //- Deprecated(2018-01) return true if the named option is found // \deprecated(2018-01) - use found() method - inline bool optionFound(const word& optName) const + bool FOAM_DEPRECATED_FOR(2018-01, "found() method") + optionFound(const word& optName) const { return found(optName); } //- Deprecated(2018-01) return an input stream from the named option // \deprecated(2018-01) - use lookup() method - inline ITstream optionLookup(const word& optName) const + ITstream FOAM_DEPRECATED_FOR(2018-01, "lookup() method") + optionLookup(const word& optName) const { return lookup(optName); } @@ -629,7 +643,8 @@ public: //- Deprecated(2018-01) read a value from the named option // \deprecated(2018-01) - use opt() method template<class T> - inline T optionRead(const word& optName) const + T FOAM_DEPRECATED_FOR(2018-01, "opt() method") + optionRead(const word& optName) const { return opt<T>(optName); } @@ -638,7 +653,8 @@ public: // Return true if the named option was found. // \deprecated(2018-01) - use readIfPresent() method template<class T> - inline bool optionReadIfPresent + bool FOAM_DEPRECATED_FOR(2018-01, "readIfPresent() method") + optionReadIfPresent ( const word& optName, T& val @@ -652,7 +668,8 @@ public: // use the supplied default and return false. // \deprecated(2018-01) - use readIfPresent() method template<class T> - inline bool optionReadIfPresent + bool FOAM_DEPRECATED_FOR(2018-01, "readIfPresent() method") + optionReadIfPresent ( const word& optName, T& val, @@ -664,21 +681,23 @@ public: //- Deprecated(2018-01) read a value from the named option if present. // Return supplied default otherwise. - // \deprecated(2018-01) - use lookupOrDefault() method + // \deprecated(2018-01) - use getOrDefault() method template<class T> - inline T optionLookupOrDefault + T FOAM_DEPRECATED_FOR(2018-01, "getOrDefault() method") + optionLookupOrDefault ( const word& optName, const T& deflt ) const { - return lookupOrDefault<T>(optName, deflt); + return getOrDefault<T>(optName, deflt); } //- Deprecated(2018-01) read a List of values from the named option // \deprecated(2018-01) - use getList() method template<class T> - inline List<T> optionReadList(const word& optName) const + List<T> FOAM_DEPRECATED_FOR(2018-01, "getList() method") + optionReadList(const word& optName) const { return this->getList<T>(optName); } diff --git a/src/OpenFOAM/global/argList/argListI.H b/src/OpenFOAM/global/argList/argListI.H index 4186d6e4af8..54e4ac9d8e2 100644 --- a/src/OpenFOAM/global/argList/argListI.H +++ b/src/OpenFOAM/global/argList/argListI.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2013 OpenFOAM Foundation @@ -316,7 +316,7 @@ inline bool Foam::argList::readIfPresent template<class T> -inline T Foam::argList::lookupOrDefault +inline T Foam::argList::getOrDefault ( const word& optName, const T& deflt diff --git a/src/OpenFOAM/primitives/bools/Switch/Switch.C b/src/OpenFOAM/primitives/bools/Switch/Switch.C index 56fc8fee687..7d7e780fdf6 100644 --- a/src/OpenFOAM/primitives/bools/Switch/Switch.C +++ b/src/OpenFOAM/primitives/bools/Switch/Switch.C @@ -110,14 +110,14 @@ Foam::Switch::switchType Foam::Switch::parse } -Foam::Switch Foam::Switch::lookupOrAddToDict +Foam::Switch Foam::Switch::getOrAddToDict ( const word& name, dictionary& dict, - const Switch defaultValue + const Switch deflt ) { - return dict.lookupOrAddDefault<Switch>(name, defaultValue); + return dict.getOrAdd<Switch>(name, deflt); } @@ -146,10 +146,10 @@ Foam::Switch::Switch ( const word& key, const dictionary& dict, - const Switch defaultValue + const Switch deflt ) : - Switch(defaultValue) + Switch(deflt) { const entry* eptr = dict.findEntry(key, keyType::LITERAL); diff --git a/src/OpenFOAM/primitives/bools/Switch/Switch.H b/src/OpenFOAM/primitives/bools/Switch/Switch.H index 0ab2a3ae0d2..90723889754 100644 --- a/src/OpenFOAM/primitives/bools/Switch/Switch.H +++ b/src/OpenFOAM/primitives/bools/Switch/Switch.H @@ -169,7 +169,7 @@ public: ( const word& key, //!< Lookup key. Uses LITERAL (not REGEX) const dictionary& dict, //!< dictionary - const Switch defaultValue //!< fallback if not found + const Switch deflt //!< fallback if not found ); //- Construct from Istream @@ -180,11 +180,11 @@ public: //- Construct from dictionary, supplying default value so that if the //- value is not found, it is added into the dictionary. - static Switch lookupOrAddToDict + static Switch getOrAddToDict ( const word& name, //!< Lookup key. Uses REGEX! dictionary& dict, //!< dictionary - const Switch defaultValue = switchType::FALSE //!< default to add + const Switch deflt = switchType::FALSE //!< default to add ); @@ -235,6 +235,18 @@ public: // Housekeeping + //- Construct from dictionary, supplying default value so that if the + //- value is not found, it is added into the dictionary. + static Switch lookupOrAddToDict + ( + const word& name, //!< Lookup key. Uses REGEX! + dictionary& dict, //!< dictionary + const Switch deflt = switchType::FALSE //!< default to add + ) + { + return getOrAddToDict(name, dict, deflt); + } + //- Deprecated(2018-03) text representation of the Switch value // \deprecated(2018-03) - use c_str() method inline const char* asText() const { return c_str(); }; diff --git a/src/OpenFOAM/primitives/enums/Enum.C b/src/OpenFOAM/primitives/enums/Enum.C index 1e269ff4ede..1ef0c4cc51c 100644 --- a/src/OpenFOAM/primitives/enums/Enum.C +++ b/src/OpenFOAM/primitives/enums/Enum.C @@ -81,14 +81,14 @@ template<class EnumType> EnumType Foam::Enum<EnumType>::get ( const word& enumName, - const EnumType defaultValue + const EnumType deflt ) const { const label idx = find(enumName); if (idx < 0) { - return defaultValue; + return deflt; } return EnumType(vals_[idx]); @@ -136,11 +136,11 @@ EnumType Foam::Enum<EnumType>::get template<class EnumType> -EnumType Foam::Enum<EnumType>::lookupOrDefault +EnumType Foam::Enum<EnumType>::getOrDefault ( const word& key, const dictionary& dict, - const EnumType defaultValue, + const EnumType deflt, const bool failsafe ) const { @@ -163,8 +163,8 @@ EnumType Foam::Enum<EnumType>::lookupOrDefault { IOWarningInFunction(dict) << enumName << " is not in enumeration: " << *this << nl - << "using failsafe " << get(defaultValue) - << " (value " << int(defaultValue) << ")" << endl; + << "using failsafe " << get(deflt) + << " (value " << int(deflt) << ")" << endl; } else { @@ -174,7 +174,7 @@ EnumType Foam::Enum<EnumType>::lookupOrDefault } } - return defaultValue; + return deflt; } diff --git a/src/OpenFOAM/primitives/enums/Enum.H b/src/OpenFOAM/primitives/enums/Enum.H index b5ef2a36244..ede847bfc90 100644 --- a/src/OpenFOAM/primitives/enums/Enum.H +++ b/src/OpenFOAM/primitives/enums/Enum.H @@ -132,7 +132,7 @@ public: //- The enumeration corresponding to the given name. // \return The enumeration or default if not found. - EnumType get(const word& enumName, const EnumType defaultValue) const; + EnumType get(const word& enumName, const EnumType deflt) const; //- The name corresponding to the given enumeration. // Return an empty word if not found. @@ -155,11 +155,11 @@ public: // // \return The value found or default if not found in dictionary. // FatalError (or Warning) if the enumerated name was incorrect. - EnumType lookupOrDefault + EnumType getOrDefault ( const word& key, //!< Lookup key. Uses LITERAL (not REGEX) const dictionary& dict, //!< dictionary - const EnumType defaultValue, //!< fallback if not found + const EnumType deflt, //!< fallback if not found const bool failsafe = false //!< Warn only on bad enumeration ) const; @@ -216,33 +216,51 @@ public: inline const word& operator[](const EnumType e) const; //- Return the enumeration corresponding to the given name or - //- defaultValue if the name is not found. + //- deflt if the name is not found. inline EnumType operator() ( const word& enumName, - const EnumType defaultValue + const EnumType deflt ) const; // Housekeeping + //- Find the key in the dictionary and return the corresponding + //- enumeration element based on its name. + // + // \return The value found or default if not found in dictionary. + // FatalError (or Warning) if the enumerated name was incorrect. + EnumType lookupOrDefault + ( + const word& key, //!< Lookup key. Uses LITERAL (not REGEX) + const dictionary& dict, //!< dictionary + const EnumType deflt, //!< fallback if not found + const bool failsafe = false //!< Warn only on bad enumeration + ) const + { + return getOrDefault(key, dict, deflt, failsafe); + } + //- Deprecated(2018-10) same as two-parameter get() // \deprecated(2018-10) - use two-parameter get() method - inline EnumType lookup(const word& key, const dictionary& dict) const + EnumType FOAM_DEPRECATED_FOR(2018-10, "get() method") + lookup(const word& key, const dictionary& dict) const { return get(key, dict); } //- Deprecated(2018-10) lookupOrDefault with warnings instead of error. - // \deprecated(2018-10) - use lookupOrDefault() with failsafe option - EnumType lookupOrFailsafe + // \deprecated(2018-10) - use getOrDefault() with failsafe option + EnumType FOAM_DEPRECATED_FOR(2018-10, "getOrDefault() method") + lookupOrFailsafe ( const word& key, const dictionary& dict, - const EnumType defaultValue + const EnumType deflt ) const { - return lookupOrDefault(key, dict, defaultValue, true); + return getOrDefault(key, dict, deflt, true); } }; diff --git a/src/OpenFOAM/primitives/ops/ops.H b/src/OpenFOAM/primitives/ops/ops.H index c47888e8d78..2692eff18f6 100644 --- a/src/OpenFOAM/primitives/ops/ops.H +++ b/src/OpenFOAM/primitives/ops/ops.H @@ -27,9 +27,9 @@ InNamespace Foam Description - Various function objects for unary and binary operations. + Various functors for unary and binary operations. Can be used for parallel combine-reduce operations or other places - requiring a function object. + requiring a functor. \*---------------------------------------------------------------------------*/ @@ -159,6 +159,25 @@ EqOp(nopEq, (void)x) }; +// Operations taking one parameter, returning bool. +// The comparison value is defined during construction + +#define Bool1Op(opName, op) \ + \ + template<class T> \ + struct opName##Op1 \ + { \ + const T& value; \ + \ + opName##Op1(const T& v) : value(v) {} \ + \ + bool operator()(const T& x) const WARNRETURN \ + { \ + return op; \ + } \ + }; + + // Weighting operations #define WeightedOp(opName, op) \ @@ -216,10 +235,18 @@ BoolOp(lessEq, x <= y) BoolOp(greater, x > y) BoolOp(greaterEq, x >= y) +Bool1Op(equal, x == value) +Bool1Op(notEqual, x != value) +Bool1Op(less, x < value) +Bool1Op(lessEq, x <= value) +Bool1Op(greater, x > value) +Bool1Op(greaterEq, x >= value) + WeightedOp(multiply, (weight*y)) #undef Op #undef BoolOp +#undef Bool1Op #undef WeightedOp // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/primitives/ranges/MinMax/MinMax.H b/src/OpenFOAM/primitives/ranges/MinMax/MinMax.H index 59b1f162010..6c78dfccc9d 100644 --- a/src/OpenFOAM/primitives/ranges/MinMax/MinMax.H +++ b/src/OpenFOAM/primitives/ranges/MinMax/MinMax.H @@ -161,6 +161,12 @@ public: // Static Member Functions + //- A semi-infinite range from minVal to the type max + inline static MinMax<T> ge(const T& minVal); + + //- A semi-infinite range from type min to maxVal + inline static MinMax<T> le(const T& maxVal); + //- A 0-1 range corresponding to the pTraits zero, one inline static MinMax<T> zero_one(); diff --git a/src/OpenFOAM/primitives/ranges/MinMax/MinMaxI.H b/src/OpenFOAM/primitives/ranges/MinMax/MinMaxI.H index afdf34916d4..d6ef1ab38e1 100644 --- a/src/OpenFOAM/primitives/ranges/MinMax/MinMaxI.H +++ b/src/OpenFOAM/primitives/ranges/MinMax/MinMaxI.H @@ -25,6 +25,20 @@ License // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // +template<class T> +inline Foam::MinMax<T> Foam::MinMax<T>::ge(const T& minVal) +{ + return MinMax<T>(minVal, pTraits<T>::max); +} + + +template<class T> +inline Foam::MinMax<T> Foam::MinMax<T>::le(const T& maxVal) +{ + return MinMax<T>(pTraits<T>::min, maxVal); +} + + template<class T> inline Foam::MinMax<T> Foam::MinMax<T>::zero_one() { diff --git a/src/OpenFOAM/primitives/ranges/scalarRange/scalarRange.C b/src/OpenFOAM/primitives/ranges/scalarRange/scalarRange.C index 221101fcf03..0786ed5ce73 100644 --- a/src/OpenFOAM/primitives/ranges/scalarRange/scalarRange.C +++ b/src/OpenFOAM/primitives/ranges/scalarRange/scalarRange.C @@ -36,8 +36,8 @@ const Foam::scalarRange Foam::scalarRange::null; const Foam::scalarRange Foam::scalarRange::always ( scalarRange::ALWAYS, - -Foam::GREAT, - Foam::GREAT + -GREAT, + GREAT ); @@ -158,21 +158,21 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const scalarRange& range) switch (range.type_) { case scalarRange::EQ: - os << range.min_; + os << range.min(); break; case scalarRange::GE: case scalarRange::GT: - os << range.min_ << ":Inf"; + os << range.min() << ":Inf"; break; case scalarRange::LE: case scalarRange::LT: - os << "-Inf:" << range.max_; + os << "-Inf:" << range.max(); break; case scalarRange::GE_LE: - os << range.min_ << ':' << range.max_; + os << range.min() << ':' << range.max(); break; case scalarRange::ALWAYS: diff --git a/src/OpenFOAM/primitives/ranges/scalarRange/scalarRange.H b/src/OpenFOAM/primitives/ranges/scalarRange/scalarRange.H index 973f446de2d..f71c97cf493 100644 --- a/src/OpenFOAM/primitives/ranges/scalarRange/scalarRange.H +++ b/src/OpenFOAM/primitives/ranges/scalarRange/scalarRange.H @@ -34,6 +34,7 @@ Description used to define an empty (inverse) range. SeeAlso + Foam::MinMax Foam::predicates::scalars SourceFiles @@ -154,18 +155,27 @@ public: static scalarRange parse(const std::string& str); - //- Construct a greater-than-equals bound + //- Construct a greater-equals bound inline static scalarRange ge(const scalar minVal) noexcept; //- Construct a greater-than bound inline static scalarRange gt(const scalar minVal) noexcept; - //- Construct a less-than-equals bound + //- Construct a greater-equals zero bound + inline static scalarRange ge0() noexcept; + + //- Construct a greater-than zero bound + inline static scalarRange gt0() noexcept; + + //- Construct a less-equals bound inline static scalarRange le(const scalar maxVal) noexcept; //- Construct a less-than bound inline static scalarRange lt(const scalar maxVal) noexcept; + //- Construct a greater-equals 0, less-equals 1 bound + inline static scalarRange zero_one() noexcept; + // Member Functions @@ -192,13 +202,13 @@ public: inline scalar value() const; //- True if the value matches the condition. - inline bool match(const scalar& value) const; + inline bool match(const scalar& val) const; // Member Operators //- Identical to match(), for use as a predicate. - inline bool operator()(const scalar& value) const; + inline bool operator()(const scalar& val) const; inline bool operator==(const scalarRange& rhs) const noexcept; inline bool operator!=(const scalarRange& rhs) const noexcept; diff --git a/src/OpenFOAM/primitives/ranges/scalarRange/scalarRangeI.H b/src/OpenFOAM/primitives/ranges/scalarRange/scalarRangeI.H index 7de2ee93b76..42081f16272 100644 --- a/src/OpenFOAM/primitives/ranges/scalarRange/scalarRangeI.H +++ b/src/OpenFOAM/primitives/ranges/scalarRange/scalarRangeI.H @@ -40,7 +40,7 @@ inline Foam::scalarRange::scalarRange inline Foam::scalarRange::scalarRange() noexcept : - scalarRange(scalarRange::NONE, Foam::GREAT, -Foam::GREAT) + scalarRange(scalarRange::NONE, GREAT, -GREAT) {} @@ -62,7 +62,7 @@ inline Foam::scalarRange::scalarRange { clear(); // Inverted - explicitly mark as such } - else if (minVal == maxVal) + else if (equal(minVal, maxVal)) { type_ = EQ; } @@ -71,24 +71,42 @@ inline Foam::scalarRange::scalarRange inline Foam::scalarRange Foam::scalarRange::ge(const scalar minVal) noexcept { - return scalarRange(GE, minVal, Foam::VGREAT); + return scalarRange(scalarRange::GE, minVal, GREAT); } inline Foam::scalarRange Foam::scalarRange::gt(const scalar minVal) noexcept { - return scalarRange(GT, minVal, Foam::VGREAT); + return scalarRange(scalarRange::GT, minVal, GREAT); +} + + +inline Foam::scalarRange Foam::scalarRange::ge0() noexcept +{ + return scalarRange(scalarRange::GE, 0, GREAT); +} + + +inline Foam::scalarRange Foam::scalarRange::gt0() noexcept +{ + return scalarRange(scalarRange::GT, 0, GREAT); } inline Foam::scalarRange Foam::scalarRange::le(const scalar maxVal) noexcept { - return scalarRange(LE, -Foam::VGREAT, maxVal); + return scalarRange(scalarRange::LE, -GREAT, maxVal); } inline Foam::scalarRange Foam::scalarRange::lt(const scalar maxVal) noexcept { - return scalarRange(LT, -Foam::VGREAT, maxVal); + return scalarRange(scalarRange::LT, -GREAT, maxVal); +} + + +inline Foam::scalarRange Foam::scalarRange::zero_one() noexcept +{ + return scalarRange(scalarRange::GE_LE, 0, 1); } @@ -96,8 +114,8 @@ inline Foam::scalarRange Foam::scalarRange::lt(const scalar maxVal) noexcept inline void Foam::scalarRange::clear() noexcept { - min_ = Foam::GREAT; - max_ = -Foam::GREAT; + min_ = GREAT; + max_ = -GREAT; type_ = scalarRange::NONE; } @@ -136,16 +154,16 @@ inline Foam::scalar Foam::scalarRange::value() const { switch (type_) { - case EQ: // For equals, min and max are identical - case GE: - case GT: + case scalarRange::EQ: // For equals, min and max are identical + case scalarRange::GE: + case scalarRange::GT: return min_; - case LE: - case LT: + case scalarRange::LE: + case scalarRange::LT: return max_; - case GE_LE: + case scalarRange::GE_LE: // Multiply before adding to avoid possible overflow return (0.5 * min_) + (0.5 * max_); @@ -155,16 +173,16 @@ inline Foam::scalar Foam::scalarRange::value() const } -inline bool Foam::scalarRange::match(const scalar& value) const +inline bool Foam::scalarRange::match(const scalar& val) const { switch (type_) { - case EQ: return equal(value, min_); - case GE: return (value >= min_); - case GT: return (value > min_); - case LE: return (value <= max_); - case LT: return (value < max_); - case GE_LE: return (value >= min_ && value <= max_); + case EQ: return equal(val, min_); + case GE: return (val >= min_); + case GT: return (val > min_); + case LE: return (val <= max_); + case LT: return (val < max_); + case GE_LE: return (val >= min_ && val <= max_); case ALWAYS: return true; default: return false; } @@ -173,9 +191,9 @@ inline bool Foam::scalarRange::match(const scalar& value) const // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // -inline bool Foam::scalarRange::operator()(const scalar& value) const +inline bool Foam::scalarRange::operator()(const scalar& val) const { - return match(value); + return match(val); } diff --git a/src/OpenFOAM/primitives/ranges/scalarRange/scalarRanges.H b/src/OpenFOAM/primitives/ranges/scalarRange/scalarRanges.H index 1de90bb0f5d..d94795b4308 100644 --- a/src/OpenFOAM/primitives/ranges/scalarRange/scalarRanges.H +++ b/src/OpenFOAM/primitives/ranges/scalarRange/scalarRanges.H @@ -67,7 +67,11 @@ public: //- Construct by parsing string for scalar ranges // The individual items are space, comma or semicolon delimited. // Optionally report when any range failed to parse - inline scalarRanges(const std::string& str, bool verbose = true); + inline explicit scalarRanges + ( + const std::string& str, + bool verbose = true + ); // Static Constructors -- GitLab