ENH: additional BitOps::toc, BitOps::sortedToc

- for obtaining set entries from a boolList

- BitOps::select to mirror bitSet constructor but returning a boolList

- BitOps::set/unset for boolList

ENH: construct bitSet from a labelRange

- useful, for example, when marking up patch slices

ENH: ListOps methods

- ListOps::count_if to mirror std::count_if but with list indexing.
- ListOps::find_if to mirror std::find_if but with list indexing.

ENH: UPtrList::test() method.

- includes bounds checks, which means it can be used in more places
  (eg, even if the storage is empty).
This commit is contained in:
Mark Olesen
2022-04-12 17:36:00 +02:00
parent 7399dbfee8
commit b59a5b1188
12 changed files with 332 additions and 98 deletions

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2012-2013 OpenFOAM Foundation Copyright (C) 2012-2013 OpenFOAM Foundation
Copyright (C) 2019-2021 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -131,20 +131,20 @@ int main(int argc, char *argv[])
const auto evenNonZero = [](const label& x){ return x && !(x % 2); }; const auto evenNonZero = [](const label& x){ return x && !(x % 2); };
Info<< "location of first even/non-zero: " Info<< "location of first even/non-zero: "
<< ListOps::find(test6, evenNonZero) << nl; << ListOps::find_if(test6, evenNonZero) << nl;
Info<< "find > 12 && divisible by 5 : " Info<< "find > 12 && divisible by 5 : "
<< ListOps::find << ListOps::find_if
( (
test6, test6,
[](const label& x) { return x > 12 && !(x % 5); } [](const label& x) { return x > 12 && !(x % 5); }
) << nl; ) << nl;
Info<< "Found >= 8 : " Info<< "Found >= 8 : "
<< ListOps::found(test6, labelMinMax(8, labelMax)) << nl; << ListOps::found_if(test6, labelMinMax(8, labelMax)) << nl;
Info<< "Found >= 25 : " Info<< "Found >= 25 : "
<< ListOps::found(test6, labelMinMax(25, labelMax)) << nl; << ListOps::found_if(test6, labelMinMax(25, labelMax)) << nl;
Info<< "Subset of non-zero, even values: " Info<< "Subset of non-zero, even values: "

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018-2020 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -30,9 +30,32 @@ License
#include "HashSet.H" #include "HashSet.H"
#include "List.H" #include "List.H"
#include "labelRange.H" #include "labelRange.H"
#include <algorithm>
// * * * * * * * * * * * * * * * * * BitOps * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * BitOps * * * * * * * * * * * * * * * * //
// See bitSet::setMany for original implementation
void Foam::BitOps::set(List<bool>& bools, const labelUList& locations)
{
// Check the max expected value first
const auto max = std::max_element(locations.begin(), locations.end());
const label len = (max != locations.end() ? (1 + *max) : 0);
if (len > bools.size())
{
bools.resize(len, false);
}
for (label i : locations)
{
if (i >= 0)
{
bools[i] = true;
}
}
}
// See bitSet::set(labelRange) for original implementation // See bitSet::set(labelRange) for original implementation
void Foam::BitOps::set(List<bool>& bools, const labelRange& range) void Foam::BitOps::set(List<bool>& bools, const labelRange& range)
{ {
@ -45,28 +68,17 @@ void Foam::BitOps::set(List<bool>& bools, const labelRange& range)
return; return;
} }
// Range finishes at or beyond the right side. // Check maximum extent of the range.
// - zero fill any gaps that we might create. // The after() method is the exclusive end-value,
// - flood-fill the rest, which now corresponds to the full range. // which corresponds to our potential new length.
// // - resize now to avoid allocations within the loop
// NB: use labelRange after() for the exclusive end-value, which
// corresponds to our new set size.
if (slice.after() >= bools.size()) if (slice.after() >= bools.size())
{ {
label i = bools.size(); bools.resize(slice.after(), false);
bools.resize(slice.after(), true);
// Backfill with false
while (i < slice.start())
{
bools.unset(i);
++i;
}
return;
} }
for (label i = slice.first(); i <= slice.last(); ++i) for (const label i : slice)
{ {
bools.set(i); bools.set(i);
} }
@ -79,7 +91,7 @@ void Foam::BitOps::set(labelHashSet& hashset, const labelRange& range)
labelRange slice(range); labelRange slice(range);
slice.adjust(); // No negative start, size adjusted accordingly slice.adjust(); // No negative start, size adjusted accordingly
for (label i = slice.first(); i <= slice.last(); ++i) for (const label i : slice)
{ {
hashset.set(i); hashset.set(i);
} }
@ -92,10 +104,19 @@ void Foam::BitOps::set(bitSet& bitset, const labelRange& range)
} }
void Foam::BitOps::unset(List<bool>& bools, const labelUList& locations)
{
for (const label i : locations)
{
bools.unset(i);
}
}
// See bitSet::unset(labelRange) for original implementation // See bitSet::unset(labelRange) for original implementation
void Foam::BitOps::unset(List<bool>& bools, const labelRange& range) void Foam::BitOps::unset(List<bool>& bools, const labelRange& range)
{ {
for (label i = range.first(); i <= range.last(); ++i) for (const label i : range)
{ {
bools.unset(i); bools.unset(i);
} }
@ -104,7 +125,7 @@ void Foam::BitOps::unset(List<bool>& bools, const labelRange& range)
void Foam::BitOps::unset(labelHashSet& hashset, const labelRange& range) void Foam::BitOps::unset(labelHashSet& hashset, const labelRange& range)
{ {
for (label i = range.first(); i <= range.last(); ++i) for (const label i : range)
{ {
hashset.unset(i); hashset.unset(i);
} }
@ -117,6 +138,74 @@ void Foam::BitOps::unset(bitSet& bitset, const labelRange& range)
} }
Foam::List<bool> Foam::BitOps::select
(
const label n,
const labelUList& locations
)
{
List<bool> bools(n, false);
BitOps::set(bools, locations);
return bools;
}
Foam::List<bool> Foam::BitOps::select(const labelUList& locations)
{
List<bool> bools;
BitOps::set(bools, locations);
return bools;
}
// Note: code is like ListOps findIndices() and/or bitSet toc()
Foam::List<Foam::label> Foam::BitOps::toc(const UList<bool>& bools)
{
const label len = bools.size();
// Pass 1: count occurrences
label count = 0;
for (const bool b : bools)
{
if (b) ++count;
}
labelList indices(count);
// Pass 2: fill content
if (count)
{
const label total(count);
count = 0;
for (label i = 0; i < len; ++i)
{
if (bools[i])
{
indices[count] = i;
if (++count == total) // Terminate early
{
break;
}
}
}
}
return indices;
}
Foam::List<Foam::label> Foam::BitOps::sortedToc(const UList<bool>& bools)
{
return BitOps::toc(bools);
}
// * * * * * * * * * * * * * * * * BitSetOps * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * BitSetOps * * * * * * * * * * * * * * * * //
Foam::bitSet Foam::BitSetOps::create Foam::bitSet Foam::BitSetOps::create

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018-2020 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -27,7 +27,8 @@ Namespace
Foam::BitOps Foam::BitOps
Description Description
Various bit-wise operations, etc. Various bit-wise operations and adaptor methods for containers
that are somewhat similar to bitSet (eg, boolList, labelHashSet).
The population count uses the Hamming weight The population count uses the Hamming weight
(http://en.wikipedia.org/wiki/Hamming_weight). (http://en.wikipedia.org/wiki/Hamming_weight).
@ -42,8 +43,8 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef BitOps_H #ifndef Foam_BitOps_H
#define BitOps_H #define Foam_BitOps_H
#include "label.H" #include "label.H"
#include "UList.H" #include "UList.H"
@ -83,24 +84,30 @@ inline unsigned int count(const UList<bool>& bools, const bool val=true)
// For compatibility with bitSet::all() // For compatibility with bitSet::all()
inline bool all(const UList<bool>& bools) inline bool all(const UList<bool>& bools)
{ {
return std::all_of(bools.begin(), bools.end(), [](bool b){return b;}); return std::all_of(bools.begin(), bools.end(), identityOp());
} }
//- True if any entries are 'true'. //- True if any entries are 'true'.
// For compatibility with bitSet::any() // For compatibility with bitSet::any()
inline bool any(const UList<bool>& bools) inline bool any(const UList<bool>& bools)
{ {
return std::any_of(bools.begin(), bools.end(), [](bool b){return b;}); return std::any_of(bools.begin(), bools.end(), identityOp());
} }
//- True if no entries are 'true'. //- True if no entries are 'true'.
// For compatibility with bitSet::none() // For compatibility with bitSet::none()
inline bool none(const UList<bool>& bools) inline bool none(const UList<bool>& bools)
{ {
return std::none_of(bools.begin(), bools.end(), [](bool b){return b;}); return std::none_of(bools.begin(), bools.end(), identityOp());
} }
//- Set the listed locations (assign 'true').
// Does auto-vivify for non-existent entries.
//
// For compatibility with bitSet::set(labelUList)
void set(List<bool>& bools, const labelUList& locations);
//- Set the specified range 'on' in a boolList. //- Set the specified range 'on' in a boolList.
// For compatibility with bitSet::set(labelRange) // For compatibility with bitSet::set(labelRange)
void set(List<bool>& bools, const labelRange& range); void set(List<bool>& bools, const labelRange& range);
@ -113,6 +120,12 @@ void set(labelHashSet& hashset, const labelRange& range);
void set(bitSet& bitset, const labelRange& range); void set(bitSet& bitset, const labelRange& range);
//- Unset the listed locations (assign 'false').
// No auto-vivify non-existent entries.
//
// For compatibility with bitSet::set(labelUList)
void unset(List<bool>& bools, const labelUList& locations);
//- Unset the specified range 'on' in a boolList. //- Unset the specified range 'on' in a boolList.
// For compatibility with bitSet::unset(labelRange) // For compatibility with bitSet::unset(labelRange)
void unset(List<bool>& bools, const labelRange& range); void unset(List<bool>& bools, const labelRange& range);
@ -125,6 +138,34 @@ void unset(labelHashSet& hashset, const labelRange& range);
void unset(bitSet& bitset, const labelRange& range); void unset(bitSet& bitset, const labelRange& range);
//- Construct a selection list of bools (all false) with the given pre-size,
//- subsequently add specified locations as true,
//- auto-vivify entries if needed.
// Similar to bitSet construction from locations
//
// \return a List of bools
List<bool> select(const label n, const labelUList& locations);
//- Construct an auto-sized selection list of bools (all false),
//- and populate the specified locations as true.
// Similar to bitSet construction from locations
//
// \return a List of bools
List<bool> select(const labelUList& locations);
//- Return the (sorted) values corresponding to 'true' entries.
// Similar to bitSet::toc()
//
// \return a List of labels
List<label> toc(const UList<bool>& bools);
//- Return the (sorted) values corresponding to 'true' entries.
// Similar to bitSet::sortedToc() and labelHashSet::sortedToc()
//
// \return a List of labels
List<label> sortedToc(const UList<bool>& bools);
//- Count arbitrary number of bits (of an integral type) //- Count arbitrary number of bits (of an integral type)
template<class UIntType> template<class UIntType>
inline unsigned int bit_count(UIntType x) inline unsigned int bit_count(UIntType x)
@ -254,7 +295,7 @@ namespace BitSetOps
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Create a bitSet with length n with the specified \a on locations. //- Create a bitSet with length n with the specified \a on locations.
// The resulting bitSet is guaranteed to have exactly the specified length, // The resulting bitSet is guaranteed to have \b exactly the specified length,
// any values or positions larger than n-1 are silently ignored. // any values or positions larger than n-1 are silently ignored.
// //
// \param n the size of the output bitSet // \param n the size of the output bitSet
@ -271,7 +312,7 @@ bitSet create
//- Create a bitSet with length n with the specified \a on locations. //- Create a bitSet with length n with the specified \a on locations.
// The resulting bitSet is guaranteed to have exactly the specified length, // The resulting bitSet is guaranteed to have \b exactly the specified length,
// any values or positions larger than n-1 are silently ignored. // any values or positions larger than n-1 are silently ignored.
// //
// \param n the size of the output bitSet // \param n the size of the output bitSet
@ -290,7 +331,7 @@ bitSet create
//- Create a bitSet with length n with the specified \a on locations //- Create a bitSet with length n with the specified \a on locations
//- when the list values are equal to the select value. //- when the list values are equal to the select value.
// //
// The resulting bitSet is guaranteed to have exactly the specified length, // The resulting bitSet is guaranteed to have \b exactly the specified length,
// any values or positions larger than n-1 are silently ignored. // any values or positions larger than n-1 are silently ignored.
// //
// \param n the size of the output bitSet // \param n the size of the output bitSet

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -323,6 +323,20 @@ Foam::bitSet::bitSet(const bitSet& bitset, const labelRange& range)
} }
Foam::bitSet::bitSet(const label n, const labelRange& range)
:
bitSet(n)
{
this->set(range);
}
Foam::bitSet::bitSet(const labelRange& range)
{
this->set(range);
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::bitSet::assign(const UList<bool>& bools) void Foam::bitSet::assign(const UList<bool>& bools)
@ -384,6 +398,7 @@ void Foam::bitSet::set(const labelRange& range)
// corresponds to our new set size. // corresponds to our new set size.
if (slice.after() >= size()) if (slice.after() >= size())
{ {
reserve(slice.after());
resize(slice.start(), false); resize(slice.start(), false);
resize(slice.after(), true); resize(slice.after(), true);
return; return;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018-2021 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -43,8 +43,8 @@ See also
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef bitSet_H #ifndef Foam_bitSet_H
#define bitSet_H #define Foam_bitSet_H
#include "className.H" #include "className.H"
#include "PackedList.H" #include "PackedList.H"
@ -135,7 +135,7 @@ public:
// Constructors // Constructors
//- Default construct an empty, zero-sized set //- Default construct an empty, zero-sized bitSet
inline bitSet() noexcept; inline bitSet() noexcept;
//- Construct from Istream //- Construct from Istream
@ -153,10 +153,12 @@ public:
//- Move construct //- Move construct
inline bitSet(bitSet&& bitset); inline bitSet(bitSet&& bitset);
//- Copy construct a subset //- Construct a new bitSet by extracting the specified (unique)
//- locations of an existing bitSet.
bitSet(const bitSet& bitset, const labelUList& addr); bitSet(const bitSet& bitset, const labelUList& addr);
//- Copy construct a subset //- Construct a new set by extracting the specified (unique)
//- locations of an existing bitSet.
template<class Addr> template<class Addr>
bitSet bitSet
( (
@ -164,18 +166,26 @@ public:
const IndirectListBase<label, Addr>& addr const IndirectListBase<label, Addr>& addr
); );
//- Copy construct a subset range //- Construct a new bitSet by extracting the specified range
//- locations of an existing bitSet.
bitSet(const bitSet& bitset, const labelRange& range); bitSet(const bitSet& bitset, const labelRange& range);
//- Construct from a list of bools //- Construct from a list of bools
inline explicit bitSet(const UList<bool>& bools); inline explicit bitSet(const UList<bool>& bools);
//- Construct with given size with all bits set to 0, //- Construct with given pre-size (filled with 0),
//- subsequently add specified locations as 1. //- subsequently add specified locations as 1,
//- auto-vivify entries if needed.
explicit bitSet(const label n, const labelRange& range);
//- Construct with given pre-size (filled with 0),
//- subsequently add specified locations as 1,
//- auto-vivify entries if needed.
inline bitSet(const label n, const labelUList& locations); inline bitSet(const label n, const labelUList& locations);
//- Construct with given size with all bits set to 0, //- Construct with given pre-size (filled with 0),
//- subsequently add specified locations as 1. //- subsequently add specified locations as 1,
//- auto-vivify entries if needed.
template<class Addr> template<class Addr>
bitSet bitSet
( (
@ -183,26 +193,32 @@ public:
const IndirectListBase<label, Addr>& locations const IndirectListBase<label, Addr>& locations
); );
//- Construct with given size with all bits set to 0, //- Construct with given pre-size (filled with 0),
//- subsequently add specified locations as 1. //- subsequently add specified locations as 1,
//- auto-vivify entries if needed.
template<unsigned N> template<unsigned N>
bitSet(const label n, const FixedList<label, N>& locations); bitSet(const label n, const FixedList<label, N>& locations);
//- Construct with given size with all bits set to 0, //- Construct with given pre-size (filled with 0),
//- subsequently add specified locations as 1. //- subsequently add specified locations as 1,
//- auto-vivify entries if needed.
inline bitSet(const label n, std::initializer_list<label> locations); inline bitSet(const label n, std::initializer_list<label> locations);
//- Construct with automatic sizing (filled with 0), //- Construct with automatic sizing (filled with 0),
//- and populate with specified locations as 1. //- and set the specified locations as 1.
explicit bitSet(const labelRange& range);
//- Construct with automatic sizing (filled with 0),
//- and set the specified locations as 1.
inline explicit bitSet(const labelUList& locations); inline explicit bitSet(const labelUList& locations);
//- Construct with automatic sizing (filled with 0), //- Construct with automatic sizing (filled with 0),
//- and populate with specified locations as 1. //- and set the specified locations as 1.
template<class Addr> template<class Addr>
inline explicit bitSet(const IndirectListBase<label, Addr>& locations); inline explicit bitSet(const IndirectListBase<label, Addr>& locations);
//- Construct with automatic sizing (filled with 0), //- Construct with automatic sizing (filled with 0),
//- and populate with specified locations as 1. //- and set the specified locations as 1.
template<unsigned N> template<unsigned N>
explicit bitSet(const FixedList<label, N>& locations); explicit bitSet(const FixedList<label, N>& locations);
@ -216,7 +232,7 @@ public:
//- True if all bits in this bitset are set or if the set is \b empty. //- True if all bits in this bitset are set or if the set is \b empty.
// Returning true for an empty set may not seem intuitive, but // Returning true for an empty set may not seem intuitive, but
// conforms to how boost has defined things. // conforms with boost definitions and std::all_of behaviour.
// \note Method name compatibility with boost::dynamic_bitset // \note Method name compatibility with boost::dynamic_bitset
inline bool all() const; inline bool all() const;
@ -388,26 +404,26 @@ public:
inline bitSet& extend(const bitSet& other); inline bitSet& extend(const bitSet& other);
//- Set the locations listed by the iterator range, //- Set the locations listed by the iterator range,
// auto-vivify entries if needed. //- auto-vivify entries if needed.
// //
// \return number of locations changed // \return number of locations changed
template<class InputIter> template<class InputIter>
label setMany(InputIter first, InputIter last); label setMany(InputIter first, InputIter last);
//- Set the listed locations to true. //- Set the listed locations to 1.
// Does auto-vivify for non-existent entries. // Does auto-vivify for non-existent entries.
// //
// \return number of locations changed // \return number of locations changed
inline label set(const labelUList& locations); inline label set(const labelUList& locations);
//- Set the listed locations to true. //- Set the listed locations to 1.
// Does auto-vivify for non-existent entries. // Does auto-vivify for non-existent entries.
// //
// \return number of locations changed // \return number of locations changed
template<class Addr> template<class Addr>
inline label set(const IndirectListBase<label, Addr>& locations); inline label set(const IndirectListBase<label, Addr>& locations);
//- Set the listed locations to true. //- Set the listed locations to 1.
// Does auto-vivify for non-existent entries. // Does auto-vivify for non-existent entries.
// //
// \return number of locations changed // \return number of locations changed

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2017-2020 OpenCFD Ltd. Copyright (C) 2017-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -42,8 +42,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef ListOps_H #ifndef Foam_ListOps_H
#define ListOps_H #define Foam_ListOps_H
#include "FlatOutput.H" #include "FlatOutput.H"
#include "labelPair.H" #include "labelPair.H"
@ -628,18 +628,44 @@ struct greater
// Optionally with an alternative start index, so that (map[i] == i+start) // Optionally with an alternative start index, so that (map[i] == i+start)
void identity(labelUList& map, label start=0); void identity(labelUList& map, label start=0);
//- Count the number of matching entries.
// When start is specified, any occurrences before start are ignored.
// Linear search.
// Like std::count_if but works with list indexing
template<class ListType, class UnaryPredicate>
label count_if
(
const ListType& input,
const UnaryPredicate& pred,
const label start=0
);
//- Find index of the first occurrence that satisfies the predicate. //- Find index of the first occurrence that satisfies the predicate.
// When start is specified, any occurrences before start are ignored. // When start is specified, any occurrences before start are ignored.
// Linear search. // Linear search.
// Like std::find_if but works with list indexing.
// \return position in list or -1 if not found. // \return position in list or -1 if not found.
template<class ListType, class UnaryPredicate> template<class ListType, class UnaryPredicate>
label find_if
(
const ListType& input,
const UnaryPredicate& pred,
const label start=0
);
//- Same as ListOps::find_if
template<class ListType, class UnaryPredicate>
label find label find
( (
const ListType& input, const ListType& input,
const UnaryPredicate& pred, const UnaryPredicate& pred,
const label start=0 const label start=0
); )
{
return ListOps::find_if(input, pred, start);
}
//- True if there is a value in the list that satisfies the predicate. //- True if there is a value in the list that satisfies the predicate.
@ -647,7 +673,7 @@ label find
// Linear search. // Linear search.
// \return true if found. // \return true if found.
template<class ListType, class UnaryPredicate> template<class ListType, class UnaryPredicate>
bool found bool found_if
( (
const ListType& input, const ListType& input,
const UnaryPredicate& pred, const UnaryPredicate& pred,
@ -655,6 +681,19 @@ bool found
); );
//- Same as found_if
template<class ListType, class UnaryPredicate>
bool found
(
const ListType& input,
const UnaryPredicate& pred,
const label start=0
)
{
return ListOps::found_if(input, pred, start);
}
//- Linear search to find all occurences of given element. //- Linear search to find all occurences of given element.
template<class ListType, class UnaryPredicate> template<class ListType, class UnaryPredicate>
labelList findIndices labelList findIndices

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2015-2021 OpenCFD Ltd. Copyright (C) 2015-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -1127,7 +1127,34 @@ void Foam::ListOps::uniqueEqOp<T>::operator()
template<class ListType, class UnaryPredicate> template<class ListType, class UnaryPredicate>
Foam::label Foam::ListOps::find Foam::label Foam::ListOps::count_if
(
const ListType& input,
const UnaryPredicate& pred,
const label start
)
{
label num = 0;
const label len = input.size();
if (start >= 0)
{
for (label i = start; i < len; ++i)
{
if (pred(input[i]))
{
++num;
}
}
}
return num;
}
template<class ListType, class UnaryPredicate>
Foam::label Foam::ListOps::find_if
( (
const ListType& input, const ListType& input,
const UnaryPredicate& pred, const UnaryPredicate& pred,
@ -1152,14 +1179,14 @@ Foam::label Foam::ListOps::find
template<class ListType, class UnaryPredicate> template<class ListType, class UnaryPredicate>
bool Foam::ListOps::found bool Foam::ListOps::found_if
( (
const ListType& input, const ListType& input,
const UnaryPredicate& pred, const UnaryPredicate& pred,
const label start const label start
) )
{ {
return (ListOps::find(input, pred, start) >= 0); return (ListOps::find_if(input, pred, start) >= 0);
} }
@ -1173,7 +1200,7 @@ Foam::labelList Foam::ListOps::findIndices
{ {
const label len = input.size(); const label len = input.size();
// Pass 1: count occurrences // Pass 1: count occurrences where pred is true. ie, count_if()
label count = 0; label count = 0;
if (start >= 0) if (start >= 0)

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018-2021 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -38,8 +38,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef PtrDynList_H #ifndef Foam_PtrDynList_H
#define PtrDynList_H #define Foam_PtrDynList_H
#include "PtrList.H" #include "PtrList.H"
#include <type_traits> #include <type_traits>
@ -103,13 +103,14 @@ public:
inline label capacity() const noexcept; inline label capacity() const noexcept;
//- Return const pointer to element (can be nullptr), //- Return const pointer to element (can be nullptr),
// with bounds checking. //- with bounds checking.
inline const T* get(const label i) const; // The return value can be tested as a bool.
const T* get(const label i) const { return this->test(i); }
//- Return const pointer to element (if set) or nullptr, //- Return const pointer to element (if set) or nullptr,
// with bounds checking. //- with bounds checking.
// The return value can be tested as a bool. // The return value can be tested as a bool.
const T* set(const label i) const { return this->get(i); } const T* set(const label i) const { return this->test(i); }
// Sizing // Sizing

View File

@ -90,13 +90,6 @@ inline Foam::label Foam::PtrDynList<T, SizeMin>::capacity() const noexcept
} }
template<class T, int SizeMin>
inline const T* Foam::PtrDynList<T, SizeMin>::get(const label i) const
{
return (i >= 0 && i < PtrList<T>::size()) ? PtrList<T>::get(i) : nullptr;
}
template<class T, int SizeMin> template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::reserve(const label len) inline void Foam::PtrDynList<T, SizeMin>::reserve(const label len)
{ {

View File

@ -43,8 +43,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef PtrList_H #ifndef Foam_PtrList_H
#define PtrList_H #define Foam_PtrList_H
#include "UPtrList.H" #include "UPtrList.H"
#include "SLPtrListFwd.H" #include "SLPtrListFwd.H"
@ -134,8 +134,8 @@ public:
// Access // Access
//- Return const pointer to element (can be nullptr), //- Return const pointer to element (can be nullptr),
// without bounds checking - same as get(). //- without bounds checking - same as get().
// The return value can also be tested as a bool. // The return value can be tested as a bool.
const T* set(const label i) const { return this->get(i); } const T* set(const label i) const { return this->get(i); }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2021 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -47,8 +47,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef UPtrList_H #ifndef Foam_UPtrList_H
#define UPtrList_H #define Foam_UPtrList_H
#include "PtrListDetail.H" #include "PtrListDetail.H"
#include <iterator> #include <iterator>
@ -132,7 +132,7 @@ public:
// the values (not the addresses) within the original list. // the values (not the addresses) within the original list.
explicit UPtrList(PtrList<T>& list); explicit UPtrList(PtrList<T>& list);
//- Construct from UList of pointers //- Construct from UList of pointers (shallow copy)
inline explicit UPtrList(const UList<T*>& list); inline explicit UPtrList(const UList<T*>& list);
//- Construct from UList, taking the address of each list element //- Construct from UList, taking the address of each list element
@ -163,17 +163,23 @@ public:
//- Return reference to the last element of the list //- Return reference to the last element of the list
inline const T& last() const; inline const T& last() const;
//- Return const pointer to element (can be nullptr),
//- or nullptr for out-of-range access (ie, \em with bounds checking).
// The return value can be tested as a bool.
inline const T* test(const label i) const;
//- Return pointer to element (can be nullptr), //- Return pointer to element (can be nullptr),
//- without bounds checking. //- \em without bounds checking.
// The return value can be tested as a bool.
inline T* get(const label i); inline T* get(const label i);
//- Return const pointer to element (can be nullptr), //- Return const pointer to element (can be nullptr),
//- without bounds checking. //- \em without bounds checking.
inline const T* get(const label i) const; inline const T* get(const label i) const;
//- Return const pointer to element (can be nullptr), //- Return const pointer to element (can be nullptr),
//- without bounds checking - same as get(). //- \em without bounds checking - same as get().
// The return value can also be tested as a bool. // The return value can be tested as a bool.
const T* set(const label i) const { return this->get(i); } const T* set(const label i) const { return this->get(i); }

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2021 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -116,6 +116,13 @@ inline bool Foam::UPtrList<T>::empty() const noexcept
} }
template<class T>
inline const T* Foam::UPtrList<T>::test(const label i) const
{
return (i >= 0 && i < ptrs_.size()) ? ptrs_[i] : nullptr;
}
template<class T> template<class T>
inline T* Foam::UPtrList<T>::get(const label i) inline T* Foam::UPtrList<T>::get(const label i)
{ {