mirror of
https://github.com/bolero-MURAKAMI/Sprout
synced 2025-02-04 21:33:56 +00:00
add C++14 constexpr nth_element
This commit is contained in:
parent
0fa551beed
commit
20cd8402b7
3 changed files with 354 additions and 171 deletions
182
sprout/algorithm/cxx14/detail/sort_tool.hpp
Normal file
182
sprout/algorithm/cxx14/detail/sort_tool.hpp
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
/*=============================================================================
|
||||||
|
Copyright (c) 2011-2014 Bolero MURAKAMI
|
||||||
|
https://github.com/bolero-MURAKAMI/Sprout
|
||||||
|
|
||||||
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
=============================================================================*/
|
||||||
|
#ifndef SPROUT_ALGORITHM_CXX14_DETAIL_SORT_TOOL_HPP
|
||||||
|
#define SPROUT_ALGORITHM_CXX14_DETAIL_SORT_TOOL_HPP
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/algorithm/min_element.hpp>
|
||||||
|
#include <sprout/utility/swap.hpp>
|
||||||
|
#include <sprout/utility/move.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace detail {
|
||||||
|
template<typename Compare, typename ForwardIterator>
|
||||||
|
inline SPROUT_CXX14_CONSTEXPR unsigned
|
||||||
|
sort3(ForwardIterator x, ForwardIterator y, ForwardIterator z, Compare comp) {
|
||||||
|
unsigned r = 0;
|
||||||
|
if (!comp(*y, *x)) {
|
||||||
|
if (!comp(*z, *y))
|
||||||
|
return r;
|
||||||
|
sprout::swap(*y, *z);
|
||||||
|
r = 1;
|
||||||
|
if (comp(*y, *x)) {
|
||||||
|
sprout::swap(*x, *y);
|
||||||
|
r = 2;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
if (comp(*z, *y)) {
|
||||||
|
sprout::swap(*x, *z);
|
||||||
|
r = 1;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
sprout::swap(*x, *y);
|
||||||
|
r = 1;
|
||||||
|
if (comp(*z, *y)) {
|
||||||
|
sprout::swap(*y, *z);
|
||||||
|
r = 2;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
template<typename Compare, typename ForwardIterator>
|
||||||
|
inline SPROUT_CXX14_CONSTEXPR unsigned
|
||||||
|
sort4(ForwardIterator x1, ForwardIterator x2, ForwardIterator x3, ForwardIterator x4, Compare comp) {
|
||||||
|
unsigned r = sprout::detail::sort3<Compare>(x1, x2, x3, comp);
|
||||||
|
if (comp(*x4, *x3)) {
|
||||||
|
sprout::swap(*x3, *x4);
|
||||||
|
++r;
|
||||||
|
if (comp(*x3, *x2)) {
|
||||||
|
sprout::swap(*x2, *x3);
|
||||||
|
++r;
|
||||||
|
if (comp(*x2, *x1)) {
|
||||||
|
sprout::swap(*x1, *x2);
|
||||||
|
++r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
template<typename Compare, typename ForwardIterator>
|
||||||
|
inline SPROUT_CXX14_CONSTEXPR unsigned
|
||||||
|
sort5(ForwardIterator x1, ForwardIterator x2, ForwardIterator x3, ForwardIterator x4, ForwardIterator x5, Compare comp) {
|
||||||
|
unsigned r = sprout::detail::sort4<Compare>(x1, x2, x3, x4, comp);
|
||||||
|
if (comp(*x5, *x4)) {
|
||||||
|
sprout::swap(*x4, *x5);
|
||||||
|
++r;
|
||||||
|
if (comp(*x4, *x3)) {
|
||||||
|
sprout::swap(*x3, *x4);
|
||||||
|
++r;
|
||||||
|
if (comp(*x3, *x2)) {
|
||||||
|
sprout::swap(*x2, *x3);
|
||||||
|
++r;
|
||||||
|
if (comp(*x2, *x1)) {
|
||||||
|
sprout::swap(*x1, *x2);
|
||||||
|
++r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
template<typename Compare, typename BirdirectionalIterator>
|
||||||
|
inline SPROUT_CXX14_CONSTEXPR void
|
||||||
|
selection_sort(BirdirectionalIterator first, BirdirectionalIterator last, Compare comp) {
|
||||||
|
BirdirectionalIterator lm1 = last;
|
||||||
|
for (--lm1; first != lm1; ++first) {
|
||||||
|
BirdirectionalIterator i = sprout::min_element(first, last, comp);
|
||||||
|
if (i != first) {
|
||||||
|
sprout::swap(*first, *i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<typename Compare, typename BirdirectionalIterator>
|
||||||
|
inline SPROUT_CXX14_CONSTEXPR void
|
||||||
|
insertion_sort(BirdirectionalIterator first, BirdirectionalIterator last, Compare comp) {
|
||||||
|
typedef typename std::iterator_traits<BirdirectionalIterator>::value_type value_type;
|
||||||
|
if (first != last) {
|
||||||
|
BirdirectionalIterator i = first;
|
||||||
|
for (++i; i != last; ++i) {
|
||||||
|
BirdirectionalIterator j = i;
|
||||||
|
value_type t(sprout::move(*j));
|
||||||
|
for (BirdirectionalIterator k = i; k != first && comp(t, *--k); --j) {
|
||||||
|
*j = sprout::move(*k);
|
||||||
|
}
|
||||||
|
*j = sprout::move(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<typename Compare, typename RandomAccessIterator>
|
||||||
|
inline SPROUT_CXX14_CONSTEXPR void
|
||||||
|
insertion_sort_3(RandomAccessIterator first, RandomAccessIterator last, Compare comp) {
|
||||||
|
typedef typename std::iterator_traits<RandomAccessIterator>::value_type value_type;
|
||||||
|
RandomAccessIterator j = first + 2;
|
||||||
|
sprout::detail::sort3<Compare>(first, first + 1, j, comp);
|
||||||
|
for (RandomAccessIterator i = j + 1; i != last; ++i) {
|
||||||
|
if (comp(*i, *j)) {
|
||||||
|
value_type t(sprout::move(*i));
|
||||||
|
RandomAccessIterator k = j;
|
||||||
|
j = i;
|
||||||
|
do {
|
||||||
|
*j = sprout::move(*k);
|
||||||
|
j = k;
|
||||||
|
} while (j != first && comp(t, *--k));
|
||||||
|
*j = sprout::move(t);
|
||||||
|
}
|
||||||
|
j = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<typename Compare, typename RandomAccessIterator>
|
||||||
|
inline SPROUT_CXX14_CONSTEXPR bool
|
||||||
|
insertion_sort_incomplete(RandomAccessIterator first, RandomAccessIterator last, Compare comp) {
|
||||||
|
switch (last - first) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
return true;
|
||||||
|
case 2:
|
||||||
|
if (comp(*--last, *first)) {
|
||||||
|
sprout::swap(*first, *last);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
case 3:
|
||||||
|
sprout::detail::sort3<Compare>(first, first + 1, --last, comp);
|
||||||
|
return true;
|
||||||
|
case 4:
|
||||||
|
sprout::detail::sort4<Compare>(first, first + 1, first + 2, --last, comp);
|
||||||
|
return true;
|
||||||
|
case 5:
|
||||||
|
sprout::detail::sort5<Compare>(first, first + 1, first + 2, first + 3, --last, comp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
typedef typename std::iterator_traits<RandomAccessIterator>::value_type value_type;
|
||||||
|
RandomAccessIterator j = first+2;
|
||||||
|
sprout::detail::sort3<Compare>(first, first + 1, j, comp);
|
||||||
|
unsigned const limit = 8;
|
||||||
|
unsigned count = 0;
|
||||||
|
for (RandomAccessIterator i = j + 1; i != last; ++i) {
|
||||||
|
if (comp(*i, *j)) {
|
||||||
|
value_type t(sprout::move(*i));
|
||||||
|
RandomAccessIterator k = j;
|
||||||
|
j = i;
|
||||||
|
do {
|
||||||
|
*j = sprout::move(*k);
|
||||||
|
j = k;
|
||||||
|
} while (j != first && comp(t, *--k));
|
||||||
|
*j = sprout::move(t);
|
||||||
|
if (++count == limit) {
|
||||||
|
return ++i == last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
j = i;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_ALGORITHM_CXX14_DETAIL_SORT_TOOL_HPP
|
|
@ -8,20 +8,178 @@
|
||||||
#ifndef SPROUT_ALGORITHM_CXX14_NTH_ELEMENT_HPP
|
#ifndef SPROUT_ALGORITHM_CXX14_NTH_ELEMENT_HPP
|
||||||
#define SPROUT_ALGORITHM_CXX14_NTH_ELEMENT_HPP
|
#define SPROUT_ALGORITHM_CXX14_NTH_ELEMENT_HPP
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
#include <type_traits>
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/algorithm/cxx14/detail/sort_tool.hpp>
|
||||||
|
#include <sprout/utility/swap.hpp>
|
||||||
|
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
|
namespace detail {
|
||||||
|
template<typename Compare, typename RandomAccessIterator>
|
||||||
|
inline SPROUT_CXX14_CONSTEXPR void
|
||||||
|
nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp) {
|
||||||
|
typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_type;
|
||||||
|
difference_type const limit = 7;
|
||||||
|
while (true) {
|
||||||
|
if (nth == last) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
difference_type len = last - first;
|
||||||
|
switch (len) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
return;
|
||||||
|
case 2:
|
||||||
|
if (comp(*--last, *first)) {
|
||||||
|
sprout::swap(*first, *last);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
RandomAccessIterator m = first;
|
||||||
|
sprout::detail::sort3<Compare>(first, ++m, --last, comp);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (len <= limit) {
|
||||||
|
sprout::detail::selection_sort<Compare>(first, last, comp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RandomAccessIterator m = first + len / 2;
|
||||||
|
RandomAccessIterator lm1 = last;
|
||||||
|
unsigned n_swaps = sprout::detail::sort3<Compare>(first, m, --lm1, comp);
|
||||||
|
RandomAccessIterator i = first;
|
||||||
|
RandomAccessIterator j = lm1;
|
||||||
|
if (!comp(*i, *m)) {
|
||||||
|
bool restart_flag = false;
|
||||||
|
while (true) {
|
||||||
|
if (i == --j) {
|
||||||
|
++i;
|
||||||
|
j = last;
|
||||||
|
if (!comp(*first, *--j)) {
|
||||||
|
while (true) {
|
||||||
|
if (i == j) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (comp(*first, *i)) {
|
||||||
|
sprout::swap(*i, *j);
|
||||||
|
++n_swaps;
|
||||||
|
++i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == j) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (true) {
|
||||||
|
while (!comp(*first, *i)) {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
while (comp(*first, *--j))
|
||||||
|
;
|
||||||
|
if (i >= j) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sprout::swap(*i, *j);
|
||||||
|
++n_swaps;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
if (nth < i) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
first = i;
|
||||||
|
restart_flag = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (comp(*j, *m)) {
|
||||||
|
sprout::swap(*i, *j);
|
||||||
|
++n_swaps;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (restart_flag) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
if (i < j) {
|
||||||
|
while (true) {
|
||||||
|
while (comp(*i, *m)) {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
while (!comp(*--j, *m))
|
||||||
|
;
|
||||||
|
if (i >= j) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sprout::swap(*i, *j);
|
||||||
|
++n_swaps;
|
||||||
|
if (m == i) {
|
||||||
|
m = j;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i != m && comp(*m, *i)) {
|
||||||
|
sprout::swap(*i, *m);
|
||||||
|
++n_swaps;
|
||||||
|
}
|
||||||
|
if (nth == i) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
if (n_swaps == 0) {
|
||||||
|
if (nth < i) {
|
||||||
|
j = m = first;
|
||||||
|
while (++j != i) {
|
||||||
|
if (comp(*j, *m)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m = j;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
j = m = i;
|
||||||
|
while (++j != last) {
|
||||||
|
if (comp(*j, *m)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m = j;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (false);
|
||||||
|
if (nth < i) {
|
||||||
|
last = i;
|
||||||
|
} else {
|
||||||
|
first = ++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace detail
|
||||||
//
|
//
|
||||||
// 25.4.2 Nth element
|
// 25.4.2 Nth element
|
||||||
//
|
//
|
||||||
// !!! TODO: implementation
|
|
||||||
template<typename RandomAccessIterator>
|
|
||||||
inline SPROUT_CXX14_CONSTEXPR void
|
|
||||||
nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last);
|
|
||||||
|
|
||||||
template<typename RandomAccessIterator, typename Compare>
|
template<typename RandomAccessIterator, typename Compare>
|
||||||
inline SPROUT_CXX14_CONSTEXPR void
|
inline SPROUT_CXX14_CONSTEXPR void
|
||||||
nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp);
|
nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp) {
|
||||||
|
typedef typename std::add_lvalue_reference<Compare>::type compare_ref;
|
||||||
|
sprout::detail::nth_element<compare_ref>(first, nth, last, comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename RandomAccessIterator>
|
||||||
|
inline SPROUT_CXX14_CONSTEXPR void
|
||||||
|
nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last) {
|
||||||
|
sprout::nth_element(
|
||||||
|
first, nth, last,
|
||||||
|
NS_SSCRISK_CEL_OR_SPROUT::less<typename std::iterator_traits<RandomAccessIterator>::value_type>()
|
||||||
|
);
|
||||||
|
}
|
||||||
} // namespace sprout
|
} // namespace sprout
|
||||||
|
|
||||||
#endif // #ifndef SPROUT_ALGORITHM_CXX14_NTH_ELEMENT_HPP
|
#endif // #ifndef SPROUT_ALGORITHM_CXX14_NTH_ELEMENT_HPP
|
||||||
|
|
|
@ -9,176 +9,16 @@
|
||||||
#define SPROUT_ALGORITHM_CXX14_SORT_HPP
|
#define SPROUT_ALGORITHM_CXX14_SORT_HPP
|
||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <type_traits>
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
#include <sprout/algorithm/min_element.hpp>
|
#include <sprout/algorithm/cxx14/detail/sort_tool.hpp>
|
||||||
#include <sprout/functional/less.hpp>
|
|
||||||
#include <sprout/type_traits/integral_constant.hpp>
|
|
||||||
#include <sprout/type_traits/std_type_traits.hpp>
|
#include <sprout/type_traits/std_type_traits.hpp>
|
||||||
#include <sprout/utility/swap.hpp>
|
#include <sprout/utility/swap.hpp>
|
||||||
#include <sprout/utility/move.hpp>
|
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
|
||||||
|
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename Compare, typename ForwardIterator>
|
|
||||||
inline SPROUT_CXX14_CONSTEXPR unsigned
|
|
||||||
sort3(ForwardIterator x, ForwardIterator y, ForwardIterator z, Compare comp) {
|
|
||||||
unsigned r = 0;
|
|
||||||
if (!comp(*y, *x)) {
|
|
||||||
if (!comp(*z, *y))
|
|
||||||
return r;
|
|
||||||
sprout::swap(*y, *z);
|
|
||||||
r = 1;
|
|
||||||
if (comp(*y, *x)) {
|
|
||||||
sprout::swap(*x, *y);
|
|
||||||
r = 2;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
if (comp(*z, *y)) {
|
|
||||||
sprout::swap(*x, *z);
|
|
||||||
r = 1;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
sprout::swap(*x, *y);
|
|
||||||
r = 1;
|
|
||||||
if (comp(*z, *y)) {
|
|
||||||
sprout::swap(*y, *z);
|
|
||||||
r = 2;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
template<typename Compare, typename ForwardIterator>
|
|
||||||
inline SPROUT_CXX14_CONSTEXPR unsigned
|
|
||||||
sort4(ForwardIterator x1, ForwardIterator x2, ForwardIterator x3, ForwardIterator x4, Compare comp) {
|
|
||||||
unsigned r = sprout::detail::sort3<Compare>(x1, x2, x3, comp);
|
|
||||||
if (comp(*x4, *x3)) {
|
|
||||||
sprout::swap(*x3, *x4);
|
|
||||||
++r;
|
|
||||||
if (comp(*x3, *x2)) {
|
|
||||||
sprout::swap(*x2, *x3);
|
|
||||||
++r;
|
|
||||||
if (comp(*x2, *x1)) {
|
|
||||||
sprout::swap(*x1, *x2);
|
|
||||||
++r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
template<typename Compare, typename ForwardIterator>
|
|
||||||
inline SPROUT_CXX14_CONSTEXPR unsigned
|
|
||||||
sort5(ForwardIterator x1, ForwardIterator x2, ForwardIterator x3, ForwardIterator x4, ForwardIterator x5, Compare comp) {
|
|
||||||
unsigned r = sprout::detail::sort4<Compare>(x1, x2, x3, x4, comp);
|
|
||||||
if (comp(*x5, *x4)) {
|
|
||||||
sprout::swap(*x4, *x5);
|
|
||||||
++r;
|
|
||||||
if (comp(*x4, *x3)) {
|
|
||||||
sprout::swap(*x3, *x4);
|
|
||||||
++r;
|
|
||||||
if (comp(*x3, *x2)) {
|
|
||||||
sprout::swap(*x2, *x3);
|
|
||||||
++r;
|
|
||||||
if (comp(*x2, *x1)) {
|
|
||||||
sprout::swap(*x1, *x2);
|
|
||||||
++r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
template<typename Compare, typename BirdirectionalIterator>
|
|
||||||
inline SPROUT_CXX14_CONSTEXPR void
|
|
||||||
selection_sort(BirdirectionalIterator first, BirdirectionalIterator last, Compare comp) {
|
|
||||||
BirdirectionalIterator lm1 = last;
|
|
||||||
for (--lm1; first != lm1; ++first) {
|
|
||||||
BirdirectionalIterator i = sprout::min_element(first, last, comp);
|
|
||||||
if (i != first) {
|
|
||||||
sprout::swap(*first, *i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
template<typename Compare, typename BirdirectionalIterator>
|
|
||||||
inline SPROUT_CXX14_CONSTEXPR void
|
|
||||||
insertion_sort(BirdirectionalIterator first, BirdirectionalIterator last, Compare comp) {
|
|
||||||
typedef typename std::iterator_traits<BirdirectionalIterator>::value_type value_type;
|
|
||||||
if (first != last) {
|
|
||||||
BirdirectionalIterator i = first;
|
|
||||||
for (++i; i != last; ++i) {
|
|
||||||
BirdirectionalIterator j = i;
|
|
||||||
value_type t(sprout::move(*j));
|
|
||||||
for (BirdirectionalIterator k = i; k != first && comp(t, *--k); --j) {
|
|
||||||
*j = sprout::move(*k);
|
|
||||||
}
|
|
||||||
*j = sprout::move(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
template<typename Compare, typename RandomAccessIterator>
|
|
||||||
inline SPROUT_CXX14_CONSTEXPR void
|
|
||||||
insertion_sort_3(RandomAccessIterator first, RandomAccessIterator last, Compare comp) {
|
|
||||||
typedef typename std::iterator_traits<RandomAccessIterator>::value_type value_type;
|
|
||||||
RandomAccessIterator j = first + 2;
|
|
||||||
sprout::detail::sort3<Compare>(first, first + 1, j, comp);
|
|
||||||
for (RandomAccessIterator i = j + 1; i != last; ++i) {
|
|
||||||
if (comp(*i, *j)) {
|
|
||||||
value_type t(sprout::move(*i));
|
|
||||||
RandomAccessIterator k = j;
|
|
||||||
j = i;
|
|
||||||
do {
|
|
||||||
*j = sprout::move(*k);
|
|
||||||
j = k;
|
|
||||||
} while (j != first && comp(t, *--k));
|
|
||||||
*j = sprout::move(t);
|
|
||||||
}
|
|
||||||
j = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
template<typename Compare, typename RandomAccessIterator>
|
|
||||||
inline SPROUT_CXX14_CONSTEXPR bool
|
|
||||||
insertion_sort_incomplete(RandomAccessIterator first, RandomAccessIterator last, Compare comp) {
|
|
||||||
switch (last - first) {
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
return true;
|
|
||||||
case 2:
|
|
||||||
if (comp(*--last, *first)) {
|
|
||||||
sprout::swap(*first, *last);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
case 3:
|
|
||||||
sprout::detail::sort3<Compare>(first, first + 1, --last, comp);
|
|
||||||
return true;
|
|
||||||
case 4:
|
|
||||||
sprout::detail::sort4<Compare>(first, first + 1, first + 2, --last, comp);
|
|
||||||
return true;
|
|
||||||
case 5:
|
|
||||||
sprout::detail::sort5<Compare>(first, first + 1, first + 2, first + 3, --last, comp);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
typedef typename std::iterator_traits<RandomAccessIterator>::value_type value_type;
|
|
||||||
RandomAccessIterator j = first+2;
|
|
||||||
sprout::detail::sort3<Compare>(first, first + 1, j, comp);
|
|
||||||
unsigned const limit = 8;
|
|
||||||
unsigned count = 0;
|
|
||||||
for (RandomAccessIterator i = j + 1; i != last; ++i) {
|
|
||||||
if (comp(*i, *j)) {
|
|
||||||
value_type t(sprout::move(*i));
|
|
||||||
RandomAccessIterator k = j;
|
|
||||||
j = i;
|
|
||||||
do {
|
|
||||||
*j = sprout::move(*k);
|
|
||||||
j = k;
|
|
||||||
} while (j != first && comp(t, *--k));
|
|
||||||
*j = sprout::move(t);
|
|
||||||
if (++count == limit) {
|
|
||||||
return ++i == last;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
j = i;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
template<typename Compare, typename RandomAccessIterator>
|
template<typename Compare, typename RandomAccessIterator>
|
||||||
SPROUT_CXX14_CONSTEXPR void
|
SPROUT_CXX14_CONSTEXPR void
|
||||||
sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
|
sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
|
||||||
|
@ -349,7 +189,10 @@ namespace sprout {
|
||||||
template<typename RandomAccessIterator>
|
template<typename RandomAccessIterator>
|
||||||
inline SPROUT_CXX14_CONSTEXPR void
|
inline SPROUT_CXX14_CONSTEXPR void
|
||||||
sort(RandomAccessIterator first, RandomAccessIterator last) {
|
sort(RandomAccessIterator first, RandomAccessIterator last) {
|
||||||
sprout::sort(first, last, sprout::less<typename std::iterator_traits<RandomAccessIterator>::value_type>());
|
sprout::sort(
|
||||||
|
first, last,
|
||||||
|
NS_SSCRISK_CEL_OR_SPROUT::less<typename std::iterator_traits<RandomAccessIterator>::value_type>()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} // namespace sprout
|
} // namespace sprout
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue