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
// Optionally with an alternative start index, so that (map[i] == i+start)
labelList identity(const label len, label start=0);
//- Find first occurence of given element and return index,
// return -1 if not found. Linear search.
//- Linear search to find the first occurence of the given element.
// \return The index found or return -1 if not found.
// \deprecated prefer UList find/found methods (deprecated Oct 2017)
template<class ListType>
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>
labelList findIndices
(
......@@ -360,20 +360,44 @@ labelList findIndices
label start=0
);
//- Find index of max element (and larger than given element).
// return -1 if not found. Linear search.
//- Linear search for the index of the max element.
//
// \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>
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).
// return -1 if not found. Linear search.
//- Linear search for the index of the min element.
//
// \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>
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,
// return -1 if not found. Binary search.
//- Binary search to find the index of the last element in a sorted list
//- 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>
label findSortedIndex
(
......@@ -383,25 +407,53 @@ label findSortedIndex
);
//- Find last element < given value in sorted list and return index,
// return -1 if not found. Binary search.
template<class ListType, class BinaryPredicate>
//- Binary search to find the index of the last element in a sorted list
//- that is less than value.
//
// 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
(
const ListType& input,
typename ListType::const_reference val,
const T& val,
const label start,
const BinaryPredicate& pred
const ComparePredicate& comp
);
//- Find last element < given value in sorted list and return index,
// return -1 if not found. Binary search.
template<class ListType>
//- Binary search to find the index of the last element in a sorted list
//- that is less than value.
//
// 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
(
const ListType& input,
typename ListType::const_reference val,
const T& val,
const label start=0
);
......@@ -416,7 +468,8 @@ template<class ListType>
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.
template<class ListType>
ListType rotateList(const ListType& list, const label n);
......
......@@ -672,48 +672,54 @@ Foam::labelList Foam::findIndices
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();
if (start >= len)
if (start < 0 || start >= len)
{
return -1;
}
label idx = start;
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>
Foam::label Foam::findMin(const ListType& input, const label start)
Foam::label Foam::findMin
(
const ListType& input,
label start
)
{
const label len = input.size();
if (start >= len)
if (start < 0 || start >= len)
{
return -1;
}
label idx = start;
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
label low = start;
label high = input.size() - 1;
if (start >= input.size())
if (start < 0 || start >= input.size())
{
return -1;
}
......@@ -755,19 +761,19 @@ Foam::label Foam::findSortedIndex
}
template<class ListType, class BinaryPredicate>
template<class ListType, class T, class ComparePredicate>
Foam::label Foam::findLower
(
const ListType& input,
typename ListType::const_reference val,
const T& val,
const label start,
const BinaryPredicate& pred
const ComparePredicate& comp
)
{
label low = start;
label high = input.size() - 1;
if (start >= input.size())
if (start < 0 || start >= input.size())
{
return -1;
}
......@@ -776,7 +782,7 @@ Foam::label Foam::findLower
{
const label mid = (low + high)/2;
if (pred(input[mid], val))
if (comp(input[mid], val))
{
low = mid;
}
......@@ -786,11 +792,11 @@ Foam::label Foam::findLower
}
}
if (pred(input[high], val))
if (comp(input[high], val))
{
return high;
}
else if (pred(input[low], val))
else if (comp(input[low], val))
{
return low;
}
......@@ -801,11 +807,11 @@ Foam::label Foam::findLower
}
template<class ListType>
template<class ListType, class T>
Foam::label Foam::findLower
(
const ListType& input,
typename ListType::const_reference val,
const T& val,
const label start
)
{
......@@ -814,7 +820,7 @@ Foam::label Foam::findLower
input,
val,
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