Commit 3a8b4999 authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: add ListOps find/found accepting a unary predicate (#1182)

- can also be used for other purposes.
  Eg,

      if (ListOps::found(list, matcher))
      {
         ...
      }

  vs.

      if (!findStrings(matcher, list).empty())
      {
         ...
      }
parent 4cbea59c
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2019 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -32,6 +32,8 @@ Description
#include "List.H"
#include "SubList.H"
#include "ListOps.H"
#include "labelField.H"
#include "MinMax.H"
#include "face.H"
using namespace Foam;
......@@ -113,22 +115,40 @@ int main(int argc, char *argv[])
Info<< nl << "Test lambda predicates:" << nl << endl;
List<label> test6(identity(11));
// shift range for general testing
std::for_each(test6.begin(), test6.end(), [](label& x){ x -= 4; });
List<label> test6(identity(11, -4));
Info<< "Subset of non-zero, even values: "
<< subsetList
// Add multiplier for mpore interesting testing
std::for_each(test6.begin(), test6.end(), [](label& x){ x *= 3; });
// Randomize the list
std::random_shuffle(test6.begin(), test6.end());
Info<< "randomized input list: " << flatOutput(test6) << nl;
const auto evenNonZero = [](const label& x){ return x && !(x % 2); };
Info<< "location of first even/non-zero: "
<< ListOps::find(test6, evenNonZero) << nl;
Info<< "find > 12 && divisible by 5 : "
<< ListOps::find
(
test6,
[](const label& x){ return x && !(x % 2); }
) << nl
<< endl;
[](const label& x) { return x > 12 && !(x % 5); }
) << nl;
test6.append(identity(13));
Info<< "Found >= 8 : "
<< ListOps::found(test6, labelMinMax(8, labelMax)) << nl;
// Randomize the list
std::random_shuffle(test6.begin(), test6.end());
Info<< "Found >= 25 : "
<< ListOps::found(test6, labelMinMax(25, labelMax)) << nl;
Info<< "Subset of non-zero, even values: "
<< subsetList(test6, evenNonZero) << nl
<< endl;
test6.append(identity(13, 12));
Info<< "Randomized: " << flatOutput(test6) << endl;
inplaceUniqueSort(test6);
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2019 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -26,6 +26,7 @@ Description
\*---------------------------------------------------------------------------*/
#include "stringListOps.H"
#include "ListOps.H"
#include "FlatOutput.H"
#include "IOstreams.H"
#include "StringStream.H"
......@@ -57,10 +58,18 @@ int main(int argc, char *argv[])
labelList matches = findStrings(regExp(".*ee.*"), strLst);
Info<< "matches found for regexp .*ee.* :" << nl << matches << nl;
forAll(matches, i)
{
Info<< " -> " << strLst[matches[i]] << nl;
}
Info<< "Match found using ListOps = "
<< ListOps::found(strLst, regExp(".*ee.*")) << nl;
Info<< "First index = "
<< ListOps::find(strLst, regExp(".*ee.*")) << nl;
Info<< endl;
matches = findStrings(reLst, strLst);
......
......@@ -582,6 +582,32 @@ struct greater
};
//- Find index of the first occurrence that satisfies the predicate.
// When start is specified, any occurrences before start are ignored.
// Linear search.
// \return position in list or -1 if not found.
template<class ListType, class UnaryPredicate>
label find
(
const ListType& input,
const UnaryPredicate& pred,
const label start=0
);
//- True if there is a value in the list that satisfies the predicate.
// When start is specified, any occurences before start are ignored.
// Linear search.
// \return true if found.
template<class ListType, class UnaryPredicate>
bool found
(
const ListType& input,
const UnaryPredicate& pred,
const label start=0
);
//- Set various locations of the list with a specified value.
//
// \param list the list to modify
......
......@@ -1097,6 +1097,43 @@ void Foam::ListOps::uniqueEqOp<T>::operator()
}
template<class ListType, class UnaryPredicate>
Foam::label Foam::ListOps::find
(
const ListType& input,
const UnaryPredicate& pred,
const label start
)
{
const label len = input.size();
if (start >= 0)
{
for (label i = start; i < len; ++i)
{
if (pred(input[i]))
{
return i;
}
}
}
return -1;
}
template<class ListType, class UnaryPredicate>
bool Foam::ListOps::found
(
const ListType& input,
const UnaryPredicate& pred,
const label start
)
{
return (ListOps::find(input, pred, start) >= 0);
}
template<class T>
void Foam::ListOps::setValue
(
......
......@@ -111,6 +111,7 @@ namespace Foam
template<class T> class MinMax;
// Common min/max types
typedef MinMax<label> labelMinMax;
typedef MinMax<scalar> scalarMinMax;
......
......@@ -425,7 +425,7 @@ Foam::label Foam::voxelMeshSearch::findCell(const point& p) const
label nei = mesh_.faceNeighbour()[facei];
nextCell = (own == celli ? nei : own);
if (findIndex(track_, nextCell, startOfTrack) != -1)
if (track_.found(nextCell, startOfTrack))
{
return celli;
}
......@@ -438,7 +438,7 @@ Foam::label Foam::voxelMeshSearch::findCell(const point& p) const
{
return nextCell;
}
else if (findIndex(track_, nextCell, startOfTrack) != -1)
else if (track_.found(nextCell, startOfTrack))
{
return -1; // point is really out
}
......
......@@ -26,8 +26,8 @@ License
#include "sampledSets.H"
#include "volFields.H"
#include "IOobjectList.H"
#include "stringListOps.H"
#include "UIndirectList.H"
#include "ListOps.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
......@@ -69,7 +69,7 @@ Foam::label Foam::sampledSets::classifyFields()
// Detect missing fields
forAll(fieldSelection_, i)
{
if (findStrings(fieldSelection_[i], allFields).empty())
if (!ListOps::found(allFields, fieldSelection_[i]))
{
missed.append(i);
}
......
......@@ -25,8 +25,8 @@ License
#include "sampledSurfaces.H"
#include "IOobjectList.H"
#include "stringListOps.H"
#include "UIndirectList.H"
#include "ListOps.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
......@@ -57,7 +57,7 @@ Foam::label Foam::sampledSurfaces::classifyFields()
// Detect missing fields
forAll(fieldSelection_, i)
{
if (findStrings(fieldSelection_[i], allFields).empty())
if (!ListOps::found(allFields, fieldSelection_[i]))
{
missed.append(i);
}
......
......@@ -641,7 +641,7 @@ void Foam::isoSurfaceTopo::generateTriPoints
forAll(f1, fp)
{
oppositeI = f1[fp];
if (findIndex(f0, oppositeI) == -1)
if (!f0.found(oppositeI))
{
break;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment