From 4bf4b89af4ed0b7bebda904e149b3d7c5517b405 Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@esi-group.com> Date: Tue, 13 Nov 2018 14:12:53 +0100 Subject: [PATCH] ENH: support scalar predicates and lists of scalar predicates (#1056) --- applications/test/scalarPredicates/Make/files | 3 + .../test/scalarPredicates/Make/options | 1 + .../scalarPredicates/Test-scalarPredicates.C | 158 ++++++++ src/OpenFOAM/Make/files | 2 + .../predicates/scalar/scalarPredicates.C | 332 +++++++++++++++++ .../predicates/scalar/scalarPredicates.H | 341 ++++++++++++++++++ .../predicates/scalar/scalarPredicatesI.H | 161 +++++++++ 7 files changed, 998 insertions(+) create mode 100644 applications/test/scalarPredicates/Make/files create mode 100644 applications/test/scalarPredicates/Make/options create mode 100644 applications/test/scalarPredicates/Test-scalarPredicates.C create mode 100644 src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.C create mode 100644 src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.H create mode 100644 src/OpenFOAM/primitives/predicates/scalar/scalarPredicatesI.H diff --git a/applications/test/scalarPredicates/Make/files b/applications/test/scalarPredicates/Make/files new file mode 100644 index 00000000000..4fa35a46879 --- /dev/null +++ b/applications/test/scalarPredicates/Make/files @@ -0,0 +1,3 @@ +Test-scalarPredicates.C + +EXE = $(FOAM_USER_APPBIN)/Test-scalarPredicates diff --git a/applications/test/scalarPredicates/Make/options b/applications/test/scalarPredicates/Make/options new file mode 100644 index 00000000000..9d6f459ad89 --- /dev/null +++ b/applications/test/scalarPredicates/Make/options @@ -0,0 +1 @@ +/**/ diff --git a/applications/test/scalarPredicates/Test-scalarPredicates.C b/applications/test/scalarPredicates/Test-scalarPredicates.C new file mode 100644 index 00000000000..22338e91746 --- /dev/null +++ b/applications/test/scalarPredicates/Test-scalarPredicates.C @@ -0,0 +1,158 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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-scalarPredicates + +Description + Simple tests using predicates for scalars + +\*---------------------------------------------------------------------------*/ + +#include "IOstreams.H" +#include "labelList.H" +#include "scalarList.H" +#include "scalarPredicates.H" +#include "FlatOutput.H" +#include "Tuple2.H" +#include "StringStream.H" + +using namespace Foam; + + +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; + + for (const scalar& value : values) + { + if (accept.match(value)) + { + Info<< "matched: " << value << " at " + << flatOutput(accept.matching(value)) << nl; + } + } + + labelList matches = accept.matching(values); + Info<< "values matched at positions: " << flatOutput(matches) << nl; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: + +int main(int argc, char *argv[]) +{ + scalarList values + ({ + -10, + 10, + 0, + 3.145, + 1000.56, + 1e5, + }); + + + Info<< nl << "From a mixed list of entries" << nl; + { + predicates::scalars + accept + ({ + predicates::scalars::lessOp(10), + predicates::scalars::greaterOp(100), + predicates::scalars::orOp + ( + predicates::scalars::lessOp(-5), + predicates::scalars::greaterOp(100) + ), + predicates::scalars::orOp + ( + [](const scalar& val){ return val < 5; }, + predicates::scalars::greaterOp(100) + ), + + [](const scalar& val){ return val < -8; }, + + // Rather wordy, word normally not be called manually + predicates::scalars::operation("le", -9), + }); + + doTest(values, accept); + } + + + Info<< nl << "Construct from list input" << nl; + { + List<Tuple2<word, scalar>> entries + ({ + {"less", 10}, + {"greater", 100}, + // Not possible > ((less -5) or (greater 100)) + {"less", -8}, + {"le", -9}, + }); + + predicates::scalars accept(entries); + + doTest(values, accept); + } + + Info<< nl << "Construct from initializer_list input" << nl; + { + predicates::scalars accept + ({ + {"less", 10}, + {"greater", 100}, + // Not possible > ((less -5) or (greater 100)) + {"less", -8}, + {"le", -9}, + }); + + doTest(values, accept); + } + + Info<< nl << "Construct from Istream" << nl; + { + IStringStream is("((less 10) (greater 100) (less -8) (le -9))"); + predicates::scalars accept(is); + + doTest(values, accept); + + // change some location + accept[0] = predicates::scalars::greaterOp(1000); + + Info<< nl << "Reset some values" << nl; + doTest(values, accept); + } + + + Info<< "\nEnd\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index 7af81c16549..90ba8622095 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -123,6 +123,8 @@ $(strings)/parsing/parsing.C ops = primitives/ops $(ops)/flipOp.C +primitives/predicates/scalar/scalarPredicates.C + primitives/hashes/Hasher/Hasher.C sha1 = primitives/hashes/SHA1 diff --git a/src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.C b/src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.C new file mode 100644 index 00000000000..921efb7509c --- /dev/null +++ b/src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.C @@ -0,0 +1,332 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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/>. + +\*---------------------------------------------------------------------------*/ + +#include "scalarPredicates.H" +#include "HashSet.H" +#include "FlatOutput.H" +#include "Tuple2.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +const Foam::Enum +< + Foam::predicates::scalars::opType +> +Foam::predicates::scalars::opNames +({ + { opType::EQUAL, "eq" }, + { opType::EQUAL, "equal" }, + { opType::NOT_EQUAL, "neq" }, + { opType::NOT_EQUAL, "notEqual" }, + { opType::LESS, "lt" }, + { opType::LESS, "less" }, + { opType::LESS_EQ, "le" }, + { opType::LESS_EQ, "lessEq" }, + { opType::GREATER, "gt" }, + { opType::GREATER, "greater" }, + { opType::GREATER_EQ, "ge" }, + { opType::GREATER_EQ, "greaterEq" }, +}); + + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +std::function<bool(Foam::scalar)> Foam::predicates::scalars::operation +( + const enum predicates::scalars::opType op, + const Foam::scalar opVal, + const Foam::scalar tol +) +{ + switch (op) + { + case opType::EQUAL: + return equalOp(opVal, tol); + break; + case opType::NOT_EQUAL: + return notEqualOp(opVal, tol); + break; + case opType::LESS: + return lessOp(opVal); + break; + case opType::LESS_EQ: + return lessEqOp(opVal); + break; + case opType::GREATER: + return greaterOp(opVal); + break; + case opType::GREATER_EQ: + return greaterEqOp(opVal); + break; + case opType::ALWAYS: + return trueOp(); + break; + default: + break; + } + + return falseOp(); +} + + +// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // + +namespace Foam +{ + // Check for bad/unknown operations + template<class Container, class Get0> + static bool hasBadEntries + ( + const Container& entries, + const Get0& get0 + ) + { + for (const auto& entry : entries) + { + if (!Foam::predicates::scalars::opNames.found(get0(entry))) + { + return true; + } + } + + return false; + } + + + // Print bad/unknown operations + template<class Error, class Container, class Get0, class Get1> + static Error& printBadEntries + ( + Error& err, + const Container& entries, + const Get0& get0, + const Get1& get1 + ) + { + labelHashSet badIndices; + + label idx = 0; + + for (const auto& entry : entries) + { + if (!Foam::predicates::scalars::opNames.found(get0(entry))) + { + badIndices.insert(idx); + } + ++idx; + } + + err + << "Entries with unknown operations:" << nl + << idx << nl + << '(' << nl; + + idx = 0; + for (const auto& entry : entries) + { + const bool bad = badIndices.found(idx); + ++idx; + + if (bad) + { + err << ">>> "; + } + else + { + err << " "; + } + err << '(' << get0(entry) << ' ' << get1(entry) << ')'; + + if (bad) + { + err << " <<<"; + } + err << nl; + } + + err << ')' << nl; + + return err; + } + +} // End namespace Foam + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::predicates::scalars::scalars +( + std::initializer_list<std::pair<word, scalar>> entries +) +: + List<unary>(entries.size()) +{ + // Access + const auto get0 = + [](const std::pair<word,scalar>& entry) { return entry.first; }; + const auto get1 = + [](const std::pair<word,scalar>& entry) { return entry.second; }; + + // Check for bad/unknown operations + if (hasBadEntries(entries, get0)) + { + printBadEntries(FatalErrorInFunction, entries, get0, get1) + << exit(FatalError); + } + + // Appears to be good + auto& list = *this; + label idx = 0; + for (const auto& entry : entries) + { + list[idx] = predicates::scalars::operation(entry); + ++idx; + } +} + + +Foam::predicates::scalars::scalars +( + const UList<Tuple2<word, scalar>>& entries +) +: + List<unary>(entries.size()) +{ + // Access + const auto get0 = + [](const Tuple2<word,scalar>& entry) { return entry.first(); }; + const auto get1 = + [](const Tuple2<word,scalar>& entry) { return entry.second(); }; + + // Check for bad/unknown operations + if (hasBadEntries(entries, get0)) + { + printBadEntries(FatalErrorInFunction, entries, get0, get1) + << exit(FatalError); + } + + // Appears to be good + auto& list = *this; + label idx = 0; + for (const auto& entry : entries) + { + list[idx] = predicates::scalars::operation(entry); + ++idx; + } +} + + +Foam::predicates::scalars::scalars(Istream& is) +: + List<unary>() +{ + is >> *this; +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::label Foam::predicates::scalars::find +( + const scalar& value, + const label start +) const +{ + const label len = this->size(); + + if (start >= 0 && len) + { + // auto iter = this->cbegin(); + + for (label i = start; i < len; ++i) + { + if ((*this)[i](value)) + { + return i; + } + } + } + + return -1; +} + + +Foam::label Foam::predicates::scalars::rfind +( + const scalar& value, + const label pos +) const +{ + const label len1 = (this->size()-1); + + // pos == -1 has same meaning as std::string::npos - search from end + for (label i = ((pos >= 0 && pos < len1) ? pos : len1); i >= 0; --i) + { + if ((*this)[i](value)) + { + return i; + } + } + + return -1; +} + + +// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // + +Foam::Istream& Foam::operator>>(Istream& is, Foam::predicates::scalars& list) +{ + // Read tuples + List<Tuple2<word, scalar>> entries(is); + + // Access + const auto get0 = + [](const Tuple2<word,scalar>& entry) { return entry.first(); }; + const auto get1 = + [](const Tuple2<word,scalar>& entry) { return entry.second(); }; + + + // Check for bad/unknown operations + if (hasBadEntries(entries, get0)) + { + printBadEntries(FatalIOErrorInFunction(is), entries, get0, get1) + << exit(FatalIOError); + } + + // Appears to be good + list.resize(entries.size()); + + label idx = 0; + for (const Tuple2<word, scalar>& entry : entries) + { + list[idx] = predicates::scalars::operation(entry); + ++idx; + } + + return is; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.H b/src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.H new file mode 100644 index 00000000000..fbb57cc5593 --- /dev/null +++ b/src/OpenFOAM/primitives/predicates/scalar/scalarPredicates.H @@ -0,0 +1,341 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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/>. + +Class + Foam::predicates::scalars + +Description + A list of unary predicates (tests) on scalars. + Includes a number of standard comparison predicates + (eg, "less", "greater", ...) + +Note + This class is still subject to larger changes (2018-11) as it matures. + +SourceFiles + scalarPredicates.C + scalarPredicatesI.H + +\*---------------------------------------------------------------------------*/ + +#ifndef scalarPredicates_H +#define scalarPredicates_H + +#include "scalar.H" +#include "predicates.H" +#include "Enum.H" +#include "List.H" +#include "Tuple2.H" +#include <functional> + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace predicates +{ + +/*---------------------------------------------------------------------------*\ + Class scalars Declaration +\*---------------------------------------------------------------------------*/ + +class scalars +: + public List<std::function<bool(Foam::scalar)>> +{ +public: + + // Public types + + //- The unary function type for testing a scalar + typedef std::function<bool(Foam::scalar)> unary; + + //- Enumerations for some standard comparison predicates + enum opType + { + EQUAL, //!< "eq", "equal" + NOT_EQUAL, //!< "neq", "notEqual" + LESS, //!< "lt", "less" + LESS_EQ, //!< "le", "lessEq" + GREATER, //!< "gt", "greater" + GREATER_EQ, //!< "ge", "greaterEq" + ALWAYS, //!< Always matches + NEVER, //!< Never matches + }; + + //- Names for the opType enumeration. + static const Enum<opType> opNames; + + + // Standard comparison methods + + //- Compare for equality, with specified tolerance (non-negative) + static unary equalOp + ( + const scalar opVal, + const scalar tol = VSMALL + ) + { + return [=](const scalar val) + { + return (Foam::mag(opVal - val) <= tol); + }; + } + + + //- Compare for inequality, with specified tolerance (non-negative) + static unary notEqualOp + ( + const scalar opVal, + const scalar tol = VSMALL + ) + { + return [=](const scalar val) + { + return (Foam::mag(opVal - val) > tol); + }; + } + + + //- Test if value is 'less' than prescribed + static unary lessOp(const scalar opVal) + { + return std::bind + ( + std::less<scalar>(), std::placeholders::_1, opVal + ); + } + + + //- Test if value is 'less_equal' to prescribed + static unary lessEqOp(const scalar opVal) + { + return std::bind + ( + std::less_equal<scalar>(), std::placeholders::_1, opVal + ); + } + + + //- Test if value is 'greater' than prescribed + //- Compare scalar values for inequality + static unary greaterOp(const scalar opVal) + { + return std::bind + ( + std::greater<scalar>(), std::placeholders::_1, opVal + ); + } + + + //- Test if value is 'greater_equal' to prescribed + static unary greaterEqOp(const scalar opVal) + { + return std::bind + ( + std::greater_equal<scalar>(), std::placeholders::_1, opVal + ); + } + + + // Special purpose comparison methods + + //- Predicate that always returns true + static unary trueOp() + { + return [](const scalar) { return true; }; + } + + //- Predicate that always returns false + static unary falseOp() + { + return [](const scalar) { return false; }; + } + + + // Combining operations + + //- Combine unary tests as an AND operation + static unary andOp(const unary& test1, const unary& test2) + { + return [=](const scalar value) + { + return (test1(value) && test2(value)); + }; + } + + //- Combine unary tests as an OR operation + static unary orOp(const unary& test1, const unary& test2) + { + return [=](const scalar value) + { + return (test1(value) || test2(value)); + }; + } + + + // Factory for standard comparison methods + + //- Standard comparison method by type + static unary operation + ( + const opType op, + const scalar opVal, + const scalar tol = VSMALL + ); + + //- Standard comparison method by name + inline static unary operation + ( + const word& opName, + const scalar opVal, + const scalar tol = VSMALL + ); + + //- Standard comparison method by (name, value) + inline static unary operation + ( + const Tuple2<word, scalar>& op, + const scalar tol = VSMALL + ); + + //- Standard comparison method by (name, value) + inline static unary operation + ( + const std::pair<word, scalar>& op, + const scalar tol = VSMALL + ); + + + // Constructors + + //- Inherit constructors from List of unary functions + using List<unary>::List; + + //- Construct from an initializer list of (opName opValue) tuples + explicit scalars(std::initializer_list<std::pair<word, scalar>> entries); + + //- Copy construct from a list of (opName opValue) tuples + explicit scalars(const UList<Tuple2<word, scalar>>& entries); + + //- Construct from Istream, from list of (opName opValue) tuples + explicit scalars(Istream& is); + + + //- Destructor + ~scalars() = default; + + + // Member Functions + + // Search + + //- Index of the first match for the value. + // When start is specified, any occurrences before start are ignored. + // Linear search. + // \return position in list or -1 if not found. + label find(const scalar& value, const label start=0) const; + + //- Index of the last match for the value. + // When pos is specified, any occurrences after pos are ignored. + // Linear search. + // \return position in list or -1 if not found. + label rfind(const scalar& value, const label pos=-1) const; + + //- True if the value matches any in the list. + // When start is specified, any occurences before start are ignored. + // Linear search. + // \return true if found. + inline bool found(const scalar& value, const label start=0) const; + + //- Match any condition in the list. + // + // \return True if the value matches any condition in the list. + inline bool match(const scalar& value) const; + + //- Match any condition in the list. + // + // \return True if the value matches any condition in the list. + inline bool matchAny(const scalar& value) const; + + //- Match all conditions in the list. + // + // \return True if the value matches all conditions in the list. + inline bool matchAll(const scalar& value) const; + + //- Extract list indices for all matches. + // + // \return The locations (indices) in the input list where match() + // is true + inline labelList matching(const scalar& value) const; + + //- Extract list indices for all matches. + // + // \param input A list of scalar inputs to test + // \param invert invert the matching logic + // \return The locations (indices) in the input list where match() + // is true + inline labelList matching + ( + const UList<scalar>& input, + const bool invert=false + ) const; + + + // Member Operators + + //- Identical to found(), match(), for use as a predicate. + inline bool operator()(const scalar& value) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace predicates + + +// IOstream Operators + +//- Suppressed write +Ostream& operator<<(Ostream& os, const predicates::scalars& list) +{ + return os; +} + +//- Read list of (opName opValue) tuple +Istream& operator>>(Istream& is, predicates::scalars& list); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "scalarPredicatesI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/primitives/predicates/scalar/scalarPredicatesI.H b/src/OpenFOAM/primitives/predicates/scalar/scalarPredicatesI.H new file mode 100644 index 00000000000..9074fa2891d --- /dev/null +++ b/src/OpenFOAM/primitives/predicates/scalar/scalarPredicatesI.H @@ -0,0 +1,161 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +inline Foam::predicates::scalars::unary Foam::predicates::scalars::operation +( + const word& opName, + const scalar opVal, + const scalar tol +) +{ + return operation(opNames[opName], opVal, tol); +} + + +inline Foam::predicates::scalars::unary Foam::predicates::scalars::operation +( + const Tuple2<word, scalar>& op, + const scalar tol +) +{ + return operation(opNames[op.first()], op.second(), tol); +} + + +inline Foam::predicates::scalars::unary Foam::predicates::scalars::operation +( + const std::pair<word, scalar>& op, + const scalar tol +) +{ + return operation(opNames[op.first], op.second, tol); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +inline bool Foam::predicates::scalars::found +( + const scalar& value, + const label start +) const +{ + return (this->find(value, start) >= 0); +} + + +inline bool Foam::predicates::scalars::match(const scalar& value) const +{ + return this->matchAny(value); +} + + +inline bool Foam::predicates::scalars::matchAny(const scalar& value) const +{ + for (const unary& test : *this) + { + if (test(value)) + { + return true; + } + } + + return false; +} + + +inline bool Foam::predicates::scalars::matchAll(const scalar& value) const +{ + for (const unary& test : *this) + { + if (!test(value)) + { + return false; + } + } + + return (!this->empty()); +} + + +inline Foam::labelList Foam::predicates::scalars::matching +( + const scalar& value +) const +{ + labelList indices(this->size()); + + label i = 0, count = 0; + for (const unary& test : *this) + { + if (test(value)) + { + indices[count] = i; + ++count; + } + ++i; + } + indices.resize(count); + + return indices; +} + + +inline Foam::labelList Foam::predicates::scalars::matching +( + const UList<scalar>& input, + const bool invert +) const +{ + const label len = input.size(); + + labelList indices(len); + + label count = 0; + for (label i=0; i < len; ++i) + { + if (match(input[i]) ? !invert : invert) + { + indices[count] = i; + ++count; + } + } + indices.resize(count); + + return indices; +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +inline bool Foam::predicates::scalars::operator()(const scalar& value) const +{ + return this->found(value); +} + + +// ************************************************************************* // -- GitLab