Changes from review of algorithm.h on development branch (#1340)

* Add missing constexpr in algorithm.h

* Fix call of nth_element

2nd argument (nth) was missing

* Replace partition point with O(log(N)) algorithm

The C++ standard defines O(log(N)) calls of predicate as the
complexity of partition_point(). The old algorithm was linear.

* Use predicate in calculation of is_permutation consistently

In case of predicate not equal_to, the calculation previously
returned wron results

* Omit swap in selection_sort if iterators are equal

* Use difference_type in rotate_general() instead of int

* Typo fix in algorithm.h

* Simplifications in algorithm.h

Application of plain refactoring by keeping semantics

* Guard against past-end iterator in etl::rotate()

And fix scope of rotate_right_by_one for etl::rotate()

* Support empty ranges in selection_sort

* Add tests for swap_ranges

* Add tests for binary_search

* Add tests for find_end

* Add tests for accumulate

* Add tests for move_s

* Added tests for is_heap and sort_heap

* Remove early exit for empty input

* Add adjacent_find

* Add unique

* Add unique_copy

* Add merge

* Add inplace_merge

* Add partial_sort

* Add partial_sort_copy
This commit is contained in:
Roland Reichwein 2026-03-10 21:39:13 +01:00 committed by GitHub
parent 521df8ee19
commit 4a8c167a31
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 2735 additions and 169 deletions

View File

@ -507,6 +507,7 @@ namespace etl
//***************************************************************************
template <typename TIterator, typename T, typename Compare>
ETL_NODISCARD
ETL_CONSTEXPR14
bool binary_search(TIterator first, TIterator last, const T& value, Compare compare)
{
first = etl::lower_bound(first, last, value, compare);
@ -516,6 +517,7 @@ namespace etl
template <typename TIterator, typename T>
ETL_NODISCARD
ETL_CONSTEXPR14
bool binary_search(TIterator first, TIterator last, const T& value)
{
typedef etl::less<typename etl::iterator_traits<TIterator>::value_type> compare;
@ -949,7 +951,7 @@ namespace etl
{
// Push Heap Helper
template <typename TIterator, typename TDistance, typename TValue, typename TCompare>
void push_heap(TIterator first, TDistance value_index, TDistance top_index, TValue value, TCompare compare)
ETL_CONSTEXPR14 void push_heap(TIterator first, TDistance value_index, TDistance top_index, TValue value, TCompare compare)
{
TDistance parent = (value_index - 1) / 2;
@ -965,7 +967,7 @@ namespace etl
// Adjust Heap Helper
template <typename TIterator, typename TDistance, typename TValue, typename TCompare>
void adjust_heap(TIterator first, TDistance value_index, TDistance length, TValue value, TCompare compare)
ETL_CONSTEXPR14 void adjust_heap(TIterator first, TDistance value_index, TDistance length, TValue value, TCompare compare)
{
TDistance top_index = value_index;
TDistance child2nd = (2 * value_index) + 2;
@ -993,7 +995,7 @@ namespace etl
// Is Heap Helper
template <typename TIterator, typename TDistance, typename TCompare>
bool is_heap(const TIterator first, const TDistance n, TCompare compare)
ETL_CONSTEXPR14 bool is_heap(const TIterator first, const TDistance n, TCompare compare)
{
TDistance parent = 0;
@ -1016,6 +1018,7 @@ namespace etl
// Pop Heap
template <typename TIterator, typename TCompare>
ETL_CONSTEXPR14
void pop_heap(TIterator first, TIterator last, TCompare compare)
{
typedef typename etl::iterator_traits<TIterator>::value_type value_t;
@ -1029,6 +1032,7 @@ namespace etl
// Pop Heap
template <typename TIterator>
ETL_CONSTEXPR14
void pop_heap(TIterator first, TIterator last)
{
typedef etl::less<typename etl::iterator_traits<TIterator>::value_type> compare;
@ -1038,6 +1042,7 @@ namespace etl
// Push Heap
template <typename TIterator, typename TCompare>
ETL_CONSTEXPR14
void push_heap(TIterator first, TIterator last, TCompare compare)
{
typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
@ -1048,6 +1053,7 @@ namespace etl
// Push Heap
template <typename TIterator>
ETL_CONSTEXPR14
void push_heap(TIterator first, TIterator last)
{
typedef etl::less<typename etl::iterator_traits<TIterator>::value_type> compare;
@ -1057,6 +1063,7 @@ namespace etl
// Make Heap
template <typename TIterator, typename TCompare>
ETL_CONSTEXPR14
void make_heap(TIterator first, TIterator last, TCompare compare)
{
typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
@ -1084,6 +1091,7 @@ namespace etl
// Make Heap
template <typename TIterator>
ETL_CONSTEXPR14
void make_heap(TIterator first, TIterator last)
{
typedef etl::less<typename etl::iterator_traits<TIterator>::value_type> compare;
@ -1094,6 +1102,7 @@ namespace etl
// Is Heap
template <typename TIterator>
ETL_NODISCARD
ETL_CONSTEXPR14
bool is_heap(TIterator first, TIterator last)
{
typedef etl::less<typename etl::iterator_traits<TIterator>::value_type> compare;
@ -1104,6 +1113,7 @@ namespace etl
// Is Heap
template <typename TIterator, typename TCompare>
ETL_NODISCARD
ETL_CONSTEXPR14
bool is_heap(TIterator first, TIterator last, TCompare compare)
{
return private_heap::is_heap(first, last - first, compare);
@ -1111,6 +1121,7 @@ namespace etl
// Sort Heap
template <typename TIterator>
ETL_CONSTEXPR14
void sort_heap(TIterator first, TIterator last)
{
while (first != last)
@ -1122,6 +1133,7 @@ namespace etl
// Sort Heap
template <typename TIterator, typename TCompare>
ETL_CONSTEXPR14
void sort_heap(TIterator first, TIterator last, TCompare compare)
{
while (first != last)
@ -1131,6 +1143,119 @@ namespace etl
}
}
//***************************************************************************
/// partial_sort
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/partial_sort"></a>
//***************************************************************************
template <typename TIterator, typename TCompare>
ETL_CONSTEXPR14
void partial_sort(TIterator first, TIterator middle, TIterator last, TCompare compare)
{
if (first == middle)
{
return;
}
typedef typename etl::iterator_traits<TIterator>::value_type value_t;
typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
etl::make_heap(first, middle, compare);
for (TIterator i = middle; i != last; ++i)
{
if (compare(*i, *first))
{
value_t value = ETL_MOVE(*i);
*i = ETL_MOVE(*first);
private_heap::adjust_heap(first, difference_t(0), difference_t(middle - first), ETL_MOVE(value), compare);
}
}
etl::sort_heap(first, middle, compare);
}
//***************************************************************************
/// partial_sort
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/partial_sort"></a>
//***************************************************************************
template <typename TIterator>
ETL_CONSTEXPR14
void partial_sort(TIterator first, TIterator middle, TIterator last)
{
typedef etl::less<typename etl::iterator_traits<TIterator>::value_type> compare;
etl::partial_sort(first, middle, last, compare());
}
//***************************************************************************
/// partial_sort_copy
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/partial_sort_copy"></a>
//***************************************************************************
template <typename TInputIterator, typename TRandomAccessIterator, typename TCompare>
ETL_CONSTEXPR14
TRandomAccessIterator partial_sort_copy(TInputIterator first,
TInputIterator last,
TRandomAccessIterator d_first,
TRandomAccessIterator d_last,
TCompare compare)
{
typedef typename etl::iterator_traits<TRandomAccessIterator>::value_type value_t;
typedef typename etl::iterator_traits<TRandomAccessIterator>::difference_type difference_t;
TRandomAccessIterator result = d_first;
// Fill the destination range
while ((first != last) && (result != d_last))
{
*result = *first;
++result;
++first;
}
if (result == d_first)
{
return result;
}
// Build a max-heap over the destination range
etl::make_heap(d_first, result, compare);
// Process remaining input elements
for (TInputIterator i = first; i != last; ++i)
{
if (compare(*i, *d_first))
{
value_t value = *i;
private_heap::adjust_heap(d_first, difference_t(0), difference_t(result - d_first), ETL_MOVE(value), compare);
}
}
etl::sort_heap(d_first, result, compare);
return result;
}
//***************************************************************************
/// partial_sort_copy
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/partial_sort_copy"></a>
//***************************************************************************
template <typename TInputIterator, typename TRandomAccessIterator>
ETL_CONSTEXPR14
TRandomAccessIterator partial_sort_copy(TInputIterator first,
TInputIterator last,
TRandomAccessIterator d_first,
TRandomAccessIterator d_last)
{
typedef etl::less<typename etl::iterator_traits<TRandomAccessIterator>::value_type> compare;
return etl::partial_sort_copy(first, last, d_first, d_last, compare());
}
//***************************************************************************
// Search
//***************************************************************************
@ -1185,7 +1310,6 @@ namespace etl
//***************************************************************************
namespace private_algorithm
{
#if ETL_USING_CPP11
//*********************************
// For random access iterators
template <typename TIterator>
@ -1204,21 +1328,21 @@ namespace etl
}
typedef typename etl::iterator_traits<TIterator>::value_type value_type;
typedef typename etl::iterator_traits<TIterator>::difference_type difference_type;
int n = last - first;
int m = middle - first;
int gcd_nm = (n == 0 || m == 0) ? n + m : etl::gcd(n, m);
difference_type n = last - first;
difference_type m = middle - first;
difference_type gcd_nm = (n == 0 || m == 0) ? n + m : etl::gcd(n, m);
TIterator result = first + (last - middle);
for (int i = 0; i < gcd_nm; i++)
for (difference_type i = 0; i < gcd_nm; i++)
{
value_type temp = ETL_MOVE(*(first + i));
int j = i;
difference_type j = i;
while (true)
{
int k = j + m;
difference_type k = j + m;
if (k >= n)
{
@ -1239,61 +1363,6 @@ namespace etl
return result;
}
#else
//*********************************
// For random access iterators
template <typename TIterator>
ETL_CONSTEXPR14
typename etl::enable_if<etl::is_random_access_iterator<TIterator>::value, TIterator>::type
rotate_general(TIterator first, TIterator middle, TIterator last)
{
if (first == middle)
{
return last;
}
if (middle == last)
{
return first;
}
typedef typename etl::iterator_traits<TIterator>::value_type value_type;
int n = last - first;
int m = middle - first;
int gcd_nm = (n == 0 || m == 0) ? n + m : etl::gcd(n, m);
TIterator result = first + (last - middle);
for (int i = 0; i < gcd_nm; i++)
{
value_type temp = *(first + i);
int j = i;
while (true)
{
int k = j + m;
if (k >= n)
{
k = k - n;
}
if (k == i)
{
break;
}
*(first + j) = *(first + k);
j = k;
}
*(first + j) = temp;
}
return result;
}
#endif
//*********************************
// For bidirectional iterators
@ -1410,26 +1479,29 @@ namespace etl
ETL_CONSTEXPR14
TIterator rotate(TIterator first, TIterator middle, TIterator last)
{
if (first == middle)
{
return last;
}
if (middle == last)
{
return first;
}
if (etl::next(first) == middle)
{
return private_algorithm::rotate_left_by_one(first, last);
}
#if ETL_USING_CPP20
if (etl::next(middle) == last)
{
#if ETL_USING_CPP20
if ETL_IF_CONSTEXPR(etl::is_forward_iterator<TIterator>::value)
{
return private_algorithm::rotate_general(first, middle, last);
}
else
if ETL_IF_CONSTEXPR(etl::is_bidirectional_iterator_concept<TIterator>::value)
{
return private_algorithm::rotate_right_by_one(first, last);
}
#else
return private_algorithm::rotate_general(first, middle, last);
#endif
}
#endif
return private_algorithm::rotate_general(first, middle, last);
}
@ -1661,35 +1733,6 @@ namespace etl
return compare(b, a) ? ETL_OR_STD::pair<const T&, const T&>(b, a) : ETL_OR_STD::pair<const T&, const T&>(a, b);
}
//***************************************************************************
/// is_sorted_until
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/is_sorted_until"></a>
//***************************************************************************
template <typename TIterator>
ETL_NODISCARD
ETL_CONSTEXPR14
TIterator is_sorted_until(TIterator begin,
TIterator end)
{
if (begin != end)
{
TIterator next = begin;
while (++next != end)
{
if (*next < *begin)
{
return next;
}
++begin;
}
}
return end;
}
//***************************************************************************
/// is_sorted_until
///\ingroup algorithm
@ -1720,6 +1763,22 @@ namespace etl
return end;
}
//***************************************************************************
/// is_sorted_until
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/is_sorted_until"></a>
//***************************************************************************
template <typename TIterator>
ETL_NODISCARD
ETL_CONSTEXPR14
TIterator is_sorted_until(TIterator begin,
TIterator end)
{
typedef etl::less<typename etl::iterator_traits<TIterator>::value_type> compare;
return etl::is_sorted_until(begin, end, compare());
}
//***************************************************************************
/// is_sorted
///\ingroup algorithm
@ -1788,22 +1847,9 @@ namespace etl
TIterator is_unique_sorted_until(TIterator begin,
TIterator end)
{
if (begin != end)
{
TIterator next = begin;
typedef etl::less<typename etl::iterator_traits<TIterator>::value_type> compare;
while (++next != end)
{
if (!(*begin < *next))
{
return next;
}
++begin;
}
}
return end;
return etl::is_unique_sorted_until(begin, end, compare());
}
//***************************************************************************
@ -1858,6 +1904,51 @@ namespace etl
return end;
}
//***************************************************************************
/// adjacent_find
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/adjacent_find"></a>
//***************************************************************************
template <typename TIterator, typename TBinaryPredicate>
ETL_NODISCARD
ETL_CONSTEXPR14
TIterator adjacent_find(TIterator first, TIterator last, TBinaryPredicate predicate)
{
if (first != last)
{
TIterator next = first;
++next;
while (next != last)
{
if (predicate(*first, *next))
{
return first;
}
++first;
++next;
}
}
return last;
}
//***************************************************************************
/// adjacent_find
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/adjacent_find"></a>
//***************************************************************************
template <typename TIterator>
ETL_NODISCARD
ETL_CONSTEXPR14
TIterator adjacent_find(TIterator first, TIterator last)
{
typedef etl::equal_to<typename etl::iterator_traits<TIterator>::value_type> predicate;
return etl::adjacent_find(first, last, predicate());
}
//***************************************************************************
/// is_permutation
///\ingroup algorithm
@ -1916,9 +2007,9 @@ namespace etl
{
if (i == etl::find_if(begin1, i, etl::bind1st(predicate, *i)))
{
size_t n = etl::count(begin2, end2, *i);
size_t n = etl::count_if(begin2, end2, etl::bind1st(predicate, *i));
if (n == 0 || size_t(etl::count(i, end1, *i)) != n)
if (n == 0 || size_t(etl::count_if(i, end1, etl::bind1st(predicate, *i))) != n)
{
return false;
}
@ -1942,18 +2033,20 @@ namespace etl
TIterator2 begin2,
TIterator2 end2)
{
if (begin1 != end1)
if (etl::distance(begin1, end1) != etl::distance(begin2, end2))
{
for (TIterator1 i = begin1; i != end1; ++i)
{
if (i == etl::find(begin1, i, *i))
{
size_t n = etl::count(begin2, end2, *i);
return false;
}
if (n == 0 || size_t(etl::count(i, end1, *i)) != n)
{
return false;
}
for (TIterator1 i = begin1; i != end1; ++i)
{
if (i == etl::find(begin1, i, *i))
{
size_t n = etl::count(begin2, end2, *i);
if (n == 0 || size_t(etl::count(i, end1, *i)) != n)
{
return false;
}
}
}
@ -1968,24 +2061,27 @@ namespace etl
//***************************************************************************
template <typename TIterator1, typename TIterator2, typename TBinaryPredicate>
ETL_NODISCARD
ETL_CONSTEXPR14
bool is_permutation(TIterator1 begin1,
TIterator1 end1,
TIterator2 begin2,
TIterator2 end2,
TBinaryPredicate predicate)
{
if (begin1 != end1)
if (etl::distance(begin1, end1) != etl::distance(begin2, end2))
{
for (TIterator1 i = begin1; i != end1; ++i)
{
if (i == etl::find_if(begin1, i, etl::bind1st(predicate, *i)))
{
size_t n = etl::count(begin2, end2, *i);
return false;
}
if (n == 0 || size_t(etl::count(i, end1, *i)) != n)
{
return false;
}
for (TIterator1 i = begin1; i != end1; ++i)
{
if (i == etl::find_if(begin1, i, etl::bind1st(predicate, *i)))
{
size_t n = etl::count_if(begin2, end2, etl::bind1st(predicate, *i));
if (n == 0 || size_t(etl::count_if(i, end1, etl::bind1st(predicate, *i))) != n)
{
return false;
}
}
}
@ -2040,14 +2136,22 @@ namespace etl
TIterator end,
TUnaryPredicate predicate)
{
while (begin != end)
{
if (!predicate(*begin))
{
return begin;
}
typedef typename etl::iterator_traits<TIterator>::difference_type difference_t;
++begin;
// binary search on a partitioned range
for (difference_t length = etl::distance(begin, end); 0 < length; )
{
difference_t half = length / 2;
TIterator middle = etl::next(begin, half);
if (predicate(*middle))
{
begin = etl::next(middle);
length -= (half + 1);
}
else
{
length = half;
}
}
return begin;
@ -2364,6 +2468,253 @@ namespace etl
return first;
}
//***************************************************************************
/// unique
/// see https://en.cppreference.com/w/cpp/algorithm/unique
///\ingroup algorithm
//***************************************************************************
template <typename TIterator>
ETL_CONSTEXPR14
TIterator unique(TIterator first, TIterator last)
{
if (first == last)
{
return last;
}
TIterator result = first;
while (++first != last)
{
if (!(*result == *first) && (++result != first))
{
*result = ETL_MOVE(*first);
}
}
return ++result;
}
//***************************************************************************
/// unique
/// see https://en.cppreference.com/w/cpp/algorithm/unique
/// predicate overload to determine equality.
///\ingroup algorithm
//***************************************************************************
template <typename TIterator, typename TBinaryPredicate>
ETL_CONSTEXPR14
TIterator unique(TIterator first, TIterator last, TBinaryPredicate predicate)
{
if (first == last)
{
return last;
}
TIterator result = first;
while (++first != last)
{
if (!predicate(*result, *first) && (++result != first))
{
*result = ETL_MOVE(*first);
}
}
return ++result;
}
//***************************************************************************
/// unique_copy
/// see https://en.cppreference.com/w/cpp/algorithm/unique_copy
///\ingroup algorithm
//***************************************************************************
template <typename TInputIterator, typename TOutputIterator>
ETL_CONSTEXPR14
TOutputIterator unique_copy(TInputIterator first,
TInputIterator last,
TOutputIterator d_first)
{
if (first == last)
{
return d_first;
}
typename etl::iterator_traits<TInputIterator>::value_type prev = *first;
*d_first = prev;
while (++first != last)
{
if (!(prev == *first))
{
prev = *first;
*(++d_first) = prev;
}
}
return ++d_first;
}
//***************************************************************************
/// unique_copy
/// see https://en.cppreference.com/w/cpp/algorithm/unique_copy
/// predicate overload to determine equality.
///\ingroup algorithm
//***************************************************************************
template <typename TInputIterator, typename TOutputIterator, typename TBinaryPredicate>
ETL_CONSTEXPR14
TOutputIterator unique_copy(TInputIterator first,
TInputIterator last,
TOutputIterator d_first,
TBinaryPredicate predicate)
{
if (first == last)
{
return d_first;
}
typename etl::iterator_traits<TInputIterator>::value_type prev = *first;
*d_first = prev;
while (++first != last)
{
if (!predicate(prev, *first))
{
prev = *first;
*(++d_first) = prev;
}
}
return ++d_first;
}
//***************************************************************************
/// merge
/// Merges two sorted ranges into one sorted range.
/// see https://en.cppreference.com/w/cpp/algorithm/merge
///\ingroup algorithm
//***************************************************************************
template <typename TInputIterator1, typename TInputIterator2, typename TOutputIterator, typename TCompare>
ETL_CONSTEXPR14
TOutputIterator merge(TInputIterator1 first1, TInputIterator1 last1,
TInputIterator2 first2, TInputIterator2 last2,
TOutputIterator d_first,
TCompare compare)
{
while ((first1 != last1) && (first2 != last2))
{
if (compare(*first2, *first1))
{
*d_first = *first2;
++first2;
}
else
{
*d_first = *first1;
++first1;
}
++d_first;
}
d_first = etl::copy(first1, last1, d_first);
d_first = etl::copy(first2, last2, d_first);
return d_first;
}
//***************************************************************************
/// merge
/// Merges two sorted ranges into one sorted range.
/// Uses operator< for comparison.
/// see https://en.cppreference.com/w/cpp/algorithm/merge
///\ingroup algorithm
//***************************************************************************
template <typename TInputIterator1, typename TInputIterator2, typename TOutputIterator>
ETL_CONSTEXPR14
TOutputIterator merge(TInputIterator1 first1, TInputIterator1 last1,
TInputIterator2 first2, TInputIterator2 last2,
TOutputIterator d_first)
{
typedef etl::less<typename etl::iterator_traits<TInputIterator1>::value_type> compare;
return etl::merge(first1, last1, first2, last2, d_first, compare());
}
//***************************************************************************
/// inplace_merge
/// Merges two consecutive sorted ranges [first, middle) and [middle, last)
/// into one sorted range [first, last) in-place.
/// Uses an iterative rotate-based algorithm that requires no additional
/// memory, no recursion and no explicit stack, making it safe for deeply
/// embedded targets with constrained stack sizes.
/// Complexity: O(N log N) comparisons, O(N log N) element moves.
/// see https://en.cppreference.com/w/cpp/algorithm/inplace_merge
///\ingroup algorithm
//***************************************************************************
template <typename TBidirectionalIterator, typename TCompare>
void inplace_merge(TBidirectionalIterator first,
TBidirectionalIterator middle,
TBidirectionalIterator last,
TCompare compare)
{
typedef typename etl::iterator_traits<TBidirectionalIterator>::difference_type difference_type;
difference_type len1 = etl::distance(first, middle);
difference_type len2 = etl::distance(middle, last);
while ((len1 != 0) && (len2 != 0))
{
// Find where the first element of the right half belongs in the left half.
// All elements in [first, cut1) are <= *middle, so they are already in place.
TBidirectionalIterator cut1 = etl::upper_bound(first, middle, *middle, compare);
difference_type prefix = etl::distance(first, cut1);
len1 -= prefix;
// If the entire left half is <= *middle, we are done.
if (len1 == 0)
{
return;
}
// Advance first past the already-placed prefix.
first = cut1;
// Find where the first element of the (remaining) left half belongs in
// the right half. All elements in [middle, cut2) are < *first, so they
// need to be moved before *first.
TBidirectionalIterator cut2 = etl::lower_bound(middle, last, *first, compare);
difference_type run = etl::distance(middle, cut2);
len2 -= run;
// Rotate the block [first, middle, cut2) so that [middle, cut2) moves
// before [first, middle). After the rotate the elements from
// [middle, cut2) (length = run) now occupy [first, first + run) and
// are in their final position.
etl::rotate(first, middle, cut2);
// Advance past the block we just placed.
etl::advance(first, run);
middle = cut2;
}
}
//***************************************************************************
/// inplace_merge
/// Merges two consecutive sorted ranges [first, middle) and [middle, last)
/// into one sorted range [first, last) in-place.
/// Uses operator< for comparison.
/// see https://en.cppreference.com/w/cpp/algorithm/inplace_merge
///\ingroup algorithm
//***************************************************************************
template <typename TBidirectionalIterator>
void inplace_merge(TBidirectionalIterator first,
TBidirectionalIterator middle,
TBidirectionalIterator last)
{
typedef etl::less<typename etl::iterator_traits<TBidirectionalIterator>::value_type> compare;
etl::inplace_merge(first, middle, last, compare());
}
}
//*****************************************************************************
@ -3160,6 +3511,11 @@ namespace etl
ETL_CONSTEXPR20
void selection_sort(TIterator first, TIterator last, TCompare compare)
{
if (first == last)
{
return;
}
TIterator min;
const TIterator ilast = private_algorithm::get_before_last(first, last);
const TIterator jlast = last;
@ -3180,7 +3536,10 @@ namespace etl
}
using ETL_OR_STD::swap; // Allow ADL
swap(*i, *min);
if (min != i)
{
swap(*i, *min);
}
}
}
@ -3204,11 +3563,7 @@ namespace etl
ETL_CONSTEXPR14
void heap_sort(TIterator first, TIterator last, TCompare compare)
{
if (!etl::is_heap(first, last, compare))
{
etl::make_heap(first, last, compare);
}
etl::make_heap(first, last, compare);
etl::sort_heap(first, last, compare);
}
@ -3220,11 +3575,7 @@ namespace etl
ETL_CONSTEXPR14
void heap_sort(TIterator first, TIterator last)
{
if (!etl::is_heap(first, last))
{
etl::make_heap(first, last);
}
etl::make_heap(first, last);
etl::sort_heap(first, last);
}
@ -3268,7 +3619,7 @@ namespace etl
#endif
//***************************************************************************
/// Returns the maximum value.
/// Returns the minimum value.
//***************************************************************************
#if ETL_USING_CPP11
template <typename T>
@ -3464,14 +3815,7 @@ namespace etl
{
typedef typename etl::iterator_traits<TIterator>::value_type value_type;
TIterator pivot = last; // Maybe find a better pivot choice?
value_type pivot_value = *pivot;
// Swap the pivot with the last, if necessary.
if (pivot != last)
{
swap(*pivot, *last);
}
value_type pivot_value = ETL_MOVE(*last);
TIterator i = first;
@ -3570,7 +3914,7 @@ namespace etl
{
typedef etl::less<typename etl::iterator_traits<TIterator>::value_type> compare_t;
nth_element(first, last, compare_t());
nth_element(first, nth, last, compare_t());
}
#endif
}

File diff suppressed because it is too large Load Diff