Commit 32565b4b authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: make findLower more flexible (issue #960)

- a second template parameter for the comparison value type instead of
  ListType::const_reference allows more generic comparison predicates.
parent a1345b7e
...@@ -336,8 +336,8 @@ List<OutputIntListType> invertManyToMany ...@@ -336,8 +336,8 @@ List<OutputIntListType> invertManyToMany
// Optionally with an alternative start index, so that (map[i] == i+start) // Optionally with an alternative start index, so that (map[i] == i+start)
labelList identity(const label len, label start=0); labelList identity(const label len, label start=0);
//- Find first occurence of given element and return index, //- Linear search to find the first occurence of the given element.
// return -1 if not found. Linear search. // \return The index found or return -1 if not found.
// \deprecated prefer UList find/found methods (deprecated Oct 2017) // \deprecated prefer UList find/found methods (deprecated Oct 2017)
template<class ListType> template<class ListType>
label findIndex label findIndex
...@@ -351,7 +351,7 @@ label findIndex ...@@ -351,7 +351,7 @@ label findIndex
} }
//- Find all occurences of given element. Linear search. //- Linear search to find all occurences of given element.
template<class ListType> template<class ListType>
labelList findIndices labelList findIndices
( (
...@@ -360,20 +360,44 @@ labelList findIndices ...@@ -360,20 +360,44 @@ labelList findIndices
label start=0 label start=0
); );
//- Find index of max element (and larger than given element). //- Linear search for the index of the max element.
// return -1 if not found. Linear search. //
// \tparam ListType The input list type
//
// \param input The list to search
// \param start The start index in the list (default: 0)
//
// \return The max index or -1 on error.
template<class ListType> template<class ListType>
label findMax(const ListType& input, const label start=0); label findMax(const ListType& input, label start=0);
//- Find index of min element (and less than given element). //- Linear search for the index of the min element.
// return -1 if not found. Linear search. //
// \tparam ListType The input list type
//
// \param input The list to search
// \param start The start index in the list (default: 0)
//
// \return The min index or -1 on error.
template<class ListType> template<class ListType>
label findMin(const ListType& input, const label start=0); label findMin(const ListType& input, label start=0);
//- Find first occurrence of given element in sorted list and return index, //- Binary search to find the index of the last element in a sorted list
// return -1 if not found. Binary search. //- that is less than value.
//
// Uses the global <code> < </code> operator and thus
// <code> (list[i] < val) </code> for the test.
//
// \tparam ListType The input list type
// \tparam T The value type (should normally be ListType::value_type)
//
// \param input The sorted list to search
// \param val The value for searching/comparing
// \param start The start index in the list (default: 0)
//
// \return The index found or -1 if not found.
template<class ListType> template<class ListType>
label findSortedIndex label findSortedIndex
( (
...@@ -383,25 +407,53 @@ label findSortedIndex ...@@ -383,25 +407,53 @@ label findSortedIndex
); );
//- Find last element < given value in sorted list and return index, //- Binary search to find the index of the last element in a sorted list
// return -1 if not found. Binary search. //- that is less than value.
template<class ListType, class BinaryPredicate> //
// Uses <code> lessOp<T>() </code> and thus
// <code> lessOp<T>(list[i], val) </code> for the test.
//
// \tparam ListType The input list type
// \tparam T The value type (is often the same as ListType::value_type)
// \tparam ComparePredicate The type of the comparison functor that
// returns true for sorting below.
//
// \param input The sorted list to search
// \param val The value for searching/comparing
// \param start The start index in the list
// \param comp The comparison functor for testing.
// Uses <code> comp(list[i], val) </code> for the test.
//
// \return The index found or -1 if not found.
template<class ListType, class T, class ComparePredicate>
label findLower label findLower
( (
const ListType& input, const ListType& input,
typename ListType::const_reference val, const T& val,
const label start, const label start,
const BinaryPredicate& pred const ComparePredicate& comp
); );
//- Find last element < given value in sorted list and return index, //- Binary search to find the index of the last element in a sorted list
// return -1 if not found. Binary search. //- that is less than value.
template<class ListType> //
// Uses <code> lessOp<T>() </code> and thus
// <code> lessOp<T>(list[i], val) </code> for the test.
//
// \tparam ListType The input list type
// \tparam T The value type (should normally be ListType::value_type)
//
// \param input The sorted list to search
// \param val The value for searching/comparing
// \param start The start index in the list (default: 0)
//
// \return The index found or -1 if not found.
template<class ListType, class T>
label findLower label findLower
( (
const ListType& input, const ListType& input,
typename ListType::const_reference val, const T& val,
const label start=0 const label start=0
); );
...@@ -416,7 +468,8 @@ template<class ListType> ...@@ -416,7 +468,8 @@ template<class ListType>
void inplaceReverseList(ListType& input); void inplaceReverseList(ListType& input);
//- Rotate a list by n places. If n is positive rotate clockwise/right/down. //- Rotate a list by n places.
// If n is positive rotate clockwise/right/down.
// If n is negative rotate anti-clockwise/left/up. // If n is negative rotate anti-clockwise/left/up.
template<class ListType> template<class ListType>
ListType rotateList(const ListType& list, const label n); ListType rotateList(const ListType& list, const label n);
......
...@@ -672,48 +672,54 @@ Foam::labelList Foam::findIndices ...@@ -672,48 +672,54 @@ Foam::labelList Foam::findIndices
template<class ListType> template<class ListType>
Foam::label Foam::findMax(const ListType& input, const label start) Foam::label Foam::findMax
(
const ListType& input,
label start
)
{ {
const label len = input.size(); const label len = input.size();
if (start >= len) if (start < 0 || start >= len)
{ {
return -1; return -1;
} }
label idx = start;
for (label i = start+1; i < len; ++i) for (label i = start+1; i < len; ++i)
{ {
if (input[idx] < input[i]) if (input[start] < input[i])
{ {
idx = i; start = i;
} }
} }
return idx; return start;
} }
template<class ListType> template<class ListType>
Foam::label Foam::findMin(const ListType& input, const label start) Foam::label Foam::findMin
(
const ListType& input,
label start
)
{ {
const label len = input.size(); const label len = input.size();
if (start >= len) if (start < 0 || start >= len)
{ {
return -1; return -1;
} }
label idx = start;
for (label i = start+1; i < len; ++i) for (label i = start+1; i < len; ++i)
{ {
if (input[i] < input[idx]) if (input[i] < input[start])
{ {
idx = i; start = i;
} }
} }
return idx; return start;
} }
...@@ -728,7 +734,7 @@ Foam::label Foam::findSortedIndex ...@@ -728,7 +734,7 @@ Foam::label Foam::findSortedIndex
label low = start; label low = start;
label high = input.size() - 1; label high = input.size() - 1;
if (start >= input.size()) if (start < 0 || start >= input.size())
{ {
return -1; return -1;
} }
...@@ -755,19 +761,19 @@ Foam::label Foam::findSortedIndex ...@@ -755,19 +761,19 @@ Foam::label Foam::findSortedIndex
} }
template<class ListType, class BinaryPredicate> template<class ListType, class T, class ComparePredicate>
Foam::label Foam::findLower Foam::label Foam::findLower
( (
const ListType& input, const ListType& input,
typename ListType::const_reference val, const T& val,
const label start, const label start,
const BinaryPredicate& pred const ComparePredicate& comp
) )
{ {
label low = start; label low = start;
label high = input.size() - 1; label high = input.size() - 1;
if (start >= input.size()) if (start < 0 || start >= input.size())
{ {
return -1; return -1;
} }
...@@ -776,7 +782,7 @@ Foam::label Foam::findLower ...@@ -776,7 +782,7 @@ Foam::label Foam::findLower
{ {
const label mid = (low + high)/2; const label mid = (low + high)/2;
if (pred(input[mid], val)) if (comp(input[mid], val))
{ {
low = mid; low = mid;
} }
...@@ -786,11 +792,11 @@ Foam::label Foam::findLower ...@@ -786,11 +792,11 @@ Foam::label Foam::findLower
} }
} }
if (pred(input[high], val)) if (comp(input[high], val))
{ {
return high; return high;
} }
else if (pred(input[low], val)) else if (comp(input[low], val))
{ {
return low; return low;
} }
...@@ -801,11 +807,11 @@ Foam::label Foam::findLower ...@@ -801,11 +807,11 @@ Foam::label Foam::findLower
} }
template<class ListType> template<class ListType, class T>
Foam::label Foam::findLower Foam::label Foam::findLower
( (
const ListType& input, const ListType& input,
typename ListType::const_reference val, const T& val,
const label start const label start
) )
{ {
...@@ -814,7 +820,7 @@ Foam::label Foam::findLower ...@@ -814,7 +820,7 @@ Foam::label Foam::findLower
input, input,
val, val,
start, start,
lessOp<typename ListType::value_type>() lessOp<T>()
); );
} }
......
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