mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-11-14 10:39:05 +00:00
sprout/algorithm/fixed/stable_sort.hpp 実装変更
This commit is contained in:
parent
f4aba3218c
commit
b8c536cce2
1 changed files with 105 additions and 155 deletions
|
@ -3,200 +3,150 @@
|
|||
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/index_tuple.hpp>
|
||||
#include <sprout/fixed_container/traits.hpp>
|
||||
#include <sprout/fixed_container/functions.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/algorithm/fixed/result_of.hpp>
|
||||
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT_DETAIL
|
||||
#include <sprout/detail/container_complate.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace fixed {
|
||||
namespace detail {
|
||||
template<typename Container, typename Compare, std::ptrdiff_t I1, std::ptrdiff_t... Indexes, std::ptrdiff_t I2, std::ptrdiff_t... SortedIndexes, std::ptrdiff_t... NextIndexes, std::ptrdiff_t... PreIndexes, std::ptrdiff_t... PostIndexes>
|
||||
SPROUT_CONSTEXPR inline typename std::enable_if<
|
||||
sizeof...(Indexes) != 0 && sizeof...(SortedIndexes) != 0,
|
||||
typename sprout::fixed::result_of::algorithm<Container>::type
|
||||
>::type stable_sort_impl_4(
|
||||
template<typename Container, typename Compare, typename... Args>
|
||||
SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm<Container>::type stable_sort_impl_restart(
|
||||
Container const& cont,
|
||||
Compare comp,
|
||||
sprout::index_tuple<I1, Indexes...>,
|
||||
sprout::index_tuple<I2, SortedIndexes...>,
|
||||
sprout::index_tuple<NextIndexes...>,
|
||||
sprout::index_tuple<PreIndexes...>,
|
||||
sprout::index_tuple<PostIndexes...>
|
||||
typename sprout::fixed_container_traits<Container>::size_type size,
|
||||
typename sprout::fixed_container_traits<Container>::value_type const& prev_value,
|
||||
Args const&... args
|
||||
);
|
||||
template<typename Container, std::ptrdiff_t... Indexes>
|
||||
SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm<Container>::type stable_sort_impl_finish(
|
||||
Container const& cont,
|
||||
sprout::index_tuple<Indexes...>
|
||||
)
|
||||
{
|
||||
return sprout::remake_clone<Container, Container>(cont, sprout::size(cont), (*sprout::next(sprout::fixed_begin(cont), Indexes))...);
|
||||
}
|
||||
template<typename Container, typename Compare, std::ptrdiff_t I1, std::ptrdiff_t... Indexes, std::ptrdiff_t I2, std::ptrdiff_t... SortedIndexes, std::ptrdiff_t... NextIndexes, std::ptrdiff_t... PreIndexes, std::ptrdiff_t... PostIndexes>
|
||||
template<typename Container, typename Compare, typename... Args>
|
||||
SPROUT_CONSTEXPR inline typename std::enable_if<
|
||||
sizeof...(Indexes) == 0 && sizeof...(SortedIndexes) == 0,
|
||||
sprout::fixed_container_traits<Container>::fixed_size == sizeof...(Args),
|
||||
typename sprout::fixed::result_of::algorithm<Container>::type
|
||||
>::type stable_sort_impl_4(
|
||||
>::type stable_sort_impl_synonym(
|
||||
Container const& cont,
|
||||
Compare comp,
|
||||
sprout::index_tuple<I1, Indexes...>,
|
||||
sprout::index_tuple<I2, SortedIndexes...>,
|
||||
sprout::index_tuple<NextIndexes...>,
|
||||
sprout::index_tuple<PreIndexes...>,
|
||||
sprout::index_tuple<PostIndexes...>
|
||||
typename sprout::fixed_container_traits<Container>::size_type size,
|
||||
typename sprout::fixed_container_traits<Container>::const_iterator first,
|
||||
typename sprout::fixed_container_traits<Container>::const_iterator last,
|
||||
typename sprout::fixed_container_traits<Container>::value_type const& value,
|
||||
typename sprout::fixed_container_traits<Container>::size_type count,
|
||||
Args const&... args
|
||||
)
|
||||
{
|
||||
return comp(*sprout::next(sprout::fixed_begin(cont), I1), *sprout::next(sprout::fixed_begin(cont), I2))
|
||||
? stable_sort_impl_finish(cont, sprout::index_tuple<PreIndexes..., NextIndexes..., I1, I2, SortedIndexes..., PostIndexes...>())
|
||||
: stable_sort_impl_finish(cont, sprout::index_tuple<PreIndexes..., NextIndexes..., I2, I1, SortedIndexes..., PostIndexes...>())
|
||||
return sprout::remake_clone<Container, Container>(cont, sprout::size(cont), args...);
|
||||
}
|
||||
template<typename Container, typename Compare, typename... Args>
|
||||
SPROUT_CONSTEXPR inline typename std::enable_if<
|
||||
sprout::fixed_container_traits<Container>::fixed_size != sizeof...(Args),
|
||||
typename sprout::fixed::result_of::algorithm<Container>::type
|
||||
>::type stable_sort_impl_synonym(
|
||||
Container const& cont,
|
||||
Compare comp,
|
||||
typename sprout::fixed_container_traits<Container>::size_type size,
|
||||
typename sprout::fixed_container_traits<Container>::const_iterator first,
|
||||
typename sprout::fixed_container_traits<Container>::const_iterator last,
|
||||
typename sprout::fixed_container_traits<Container>::value_type const& value,
|
||||
typename sprout::fixed_container_traits<Container>::size_type count,
|
||||
Args const&... args
|
||||
)
|
||||
{
|
||||
return first != last && count != 0
|
||||
? !comp(*first, value) && !comp(value, *first)
|
||||
? sprout::fixed::detail::stable_sort_impl_synonym(cont, comp, size, sprout::next(first), last, value, count - 1, args..., *first)
|
||||
: sprout::fixed::detail::stable_sort_impl_synonym(cont, comp, size, sprout::next(first), last, value, count, args...)
|
||||
: sprout::fixed::detail::stable_sort_impl_restart(cont, comp, size, value, args...)
|
||||
;
|
||||
}
|
||||
template<typename Container, typename Compare, std::ptrdiff_t I1, std::ptrdiff_t... Indexes, std::ptrdiff_t I2, std::ptrdiff_t... SortedIndexes, std::ptrdiff_t... NextIndexes, std::ptrdiff_t... PreIndexes, std::ptrdiff_t... PostIndexes>
|
||||
SPROUT_CONSTEXPR inline typename std::enable_if<
|
||||
sizeof...(Indexes) == 0 && sizeof...(SortedIndexes) != 0,
|
||||
typename sprout::fixed::result_of::algorithm<Container>::type
|
||||
>::type stable_sort_impl_4(
|
||||
template<typename Container, typename Compare, typename... Args>
|
||||
SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm<Container>::type stable_sort_impl_restart_1(
|
||||
Container const& cont,
|
||||
Compare comp,
|
||||
sprout::index_tuple<I1, Indexes...>,
|
||||
sprout::index_tuple<I2, SortedIndexes...>,
|
||||
sprout::index_tuple<NextIndexes...>,
|
||||
sprout::index_tuple<PreIndexes...>,
|
||||
sprout::index_tuple<PostIndexes...>
|
||||
typename sprout::fixed_container_traits<Container>::size_type size,
|
||||
typename sprout::fixed_container_traits<Container>::const_iterator first,
|
||||
typename sprout::fixed_container_traits<Container>::const_iterator last,
|
||||
typename sprout::fixed_container_traits<Container>::value_type const& value,
|
||||
typename sprout::fixed_container_traits<Container>::size_type count,
|
||||
typename sprout::fixed_container_traits<Container>::const_iterator current,
|
||||
typename sprout::fixed_container_traits<Container>::value_type const& prev_value,
|
||||
Args const&... args
|
||||
)
|
||||
{
|
||||
return comp(*sprout::next(sprout::fixed_begin(cont), I1), *sprout::next(sprout::fixed_begin(cont), I2))
|
||||
? stable_sort_impl_finish(cont, sprout::index_tuple<PreIndexes..., NextIndexes..., I1, I2, SortedIndexes..., PostIndexes...>())
|
||||
: stable_sort_impl_4(cont, comp, sprout::index_tuple<I1>(), sprout::index_tuple<SortedIndexes...>(), sprout::index_tuple<NextIndexes..., I2>(), sprout::index_tuple<PreIndexes...>(), sprout::index_tuple<PostIndexes...>())
|
||||
return first != last
|
||||
? comp(prev_value, *first)
|
||||
? count == 0 || comp(*first, value)
|
||||
? sprout::fixed::detail::stable_sort_impl_restart_1(cont, comp, size, sprout::next(first), last, *first, 1, first, prev_value, args...)
|
||||
: comp(value, *first)
|
||||
? sprout::fixed::detail::stable_sort_impl_restart_1(cont, comp, size, sprout::next(first), last, value, count, current, prev_value, args...)
|
||||
: sprout::fixed::detail::stable_sort_impl_restart_1(cont, comp, size, sprout::next(first), last, value, count + 1, current, prev_value, args...)
|
||||
: sprout::fixed::detail::stable_sort_impl_restart_1(cont, comp, size, sprout::next(first), last, value, count, current, prev_value, args...)
|
||||
: sprout::fixed::detail::stable_sort_impl_synonym(cont, comp, size, sprout::next(current), last, value, count - 1, args..., value)
|
||||
;
|
||||
}
|
||||
template<typename Container, typename Compare, std::ptrdiff_t I1, std::ptrdiff_t... Indexes, std::ptrdiff_t I2, std::ptrdiff_t... SortedIndexes, std::ptrdiff_t... NextIndexes, std::ptrdiff_t... PreIndexes, std::ptrdiff_t... PostIndexes>
|
||||
SPROUT_CONSTEXPR inline typename std::enable_if<
|
||||
sizeof...(Indexes) != 0 && sizeof...(SortedIndexes) == 0,
|
||||
typename sprout::fixed::result_of::algorithm<Container>::type
|
||||
>::type stable_sort_impl_4(
|
||||
template<typename Container, typename Compare, typename... Args>
|
||||
SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm<Container>::type stable_sort_impl_restart(
|
||||
Container const& cont,
|
||||
Compare comp,
|
||||
sprout::index_tuple<I1, Indexes...>,
|
||||
sprout::index_tuple<I2, SortedIndexes...>,
|
||||
sprout::index_tuple<NextIndexes...>,
|
||||
sprout::index_tuple<PreIndexes...>,
|
||||
sprout::index_tuple<PostIndexes...>
|
||||
typename sprout::fixed_container_traits<Container>::size_type size,
|
||||
typename sprout::fixed_container_traits<Container>::value_type const& prev_value,
|
||||
Args const&... args
|
||||
)
|
||||
{
|
||||
return comp(*sprout::next(sprout::fixed_begin(cont), I1), *sprout::next(sprout::fixed_begin(cont), I2))
|
||||
? stable_sort_impl_4(cont, comp, sprout::index_tuple<Indexes...>(), sprout::index_tuple<NextIndexes..., I1, I2, SortedIndexes...>(), sprout::index_tuple<>(), sprout::index_tuple<PreIndexes...>(), sprout::index_tuple<PostIndexes...>())
|
||||
: stable_sort_impl_4(cont, comp, sprout::index_tuple<Indexes...>(), sprout::index_tuple<NextIndexes..., I2, I1, SortedIndexes...>(), sprout::index_tuple<>(), sprout::index_tuple<PreIndexes...>(), sprout::index_tuple<PostIndexes...>())
|
||||
return sizeof...(Args) < size
|
||||
? sprout::fixed::detail::stable_sort_impl_restart_1(
|
||||
cont,
|
||||
comp,
|
||||
size,
|
||||
sprout::begin(cont),
|
||||
sprout::end(cont),
|
||||
*sprout::begin(cont),
|
||||
0,
|
||||
sprout::begin(cont),
|
||||
prev_value,
|
||||
args...
|
||||
)
|
||||
: sprout::detail::container_complate(cont, args...)
|
||||
;
|
||||
}
|
||||
template<typename Container, typename Compare, std::ptrdiff_t I1, std::ptrdiff_t... Indexes, std::ptrdiff_t I2, std::ptrdiff_t... SortedIndexes, std::ptrdiff_t... NextIndexes, std::ptrdiff_t... PreIndexes, std::ptrdiff_t... PostIndexes>
|
||||
SPROUT_CONSTEXPR inline typename std::enable_if<
|
||||
sizeof...(Indexes) != 0 && sizeof...(SortedIndexes) != 0,
|
||||
typename sprout::fixed::result_of::algorithm<Container>::type
|
||||
>::type stable_sort_impl_4(
|
||||
template<typename Container, typename Compare>
|
||||
SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm<Container>::type stable_sort_impl_1(
|
||||
Container const& cont,
|
||||
Compare comp,
|
||||
sprout::index_tuple<I1, Indexes...>,
|
||||
sprout::index_tuple<I2, SortedIndexes...>,
|
||||
sprout::index_tuple<NextIndexes...>,
|
||||
sprout::index_tuple<PreIndexes...>,
|
||||
sprout::index_tuple<PostIndexes...>
|
||||
typename sprout::fixed_container_traits<Container>::size_type size,
|
||||
typename sprout::fixed_container_traits<Container>::const_iterator first,
|
||||
typename sprout::fixed_container_traits<Container>::const_iterator last,
|
||||
typename sprout::fixed_container_traits<Container>::value_type const& value,
|
||||
typename sprout::fixed_container_traits<Container>::size_type count,
|
||||
typename sprout::fixed_container_traits<Container>::const_iterator current
|
||||
)
|
||||
{
|
||||
return comp(*sprout::next(sprout::fixed_begin(cont), I1), *sprout::next(sprout::fixed_begin(cont), I2))
|
||||
? stable_sort_impl_4(cont, comp, sprout::index_tuple<Indexes...>(), sprout::index_tuple<NextIndexes..., I1, I2, SortedIndexes...>(), sprout::index_tuple<>(), sprout::index_tuple<PreIndexes...>(), sprout::index_tuple<PostIndexes...>())
|
||||
: stable_sort_impl_4(cont, comp, sprout::index_tuple<I1, Indexes...>(), sprout::index_tuple<SortedIndexes...>(), sprout::index_tuple<NextIndexes..., I2>(), sprout::index_tuple<PreIndexes...>(), sprout::index_tuple<PostIndexes...>())
|
||||
return first != last
|
||||
? comp(*first, value)
|
||||
? sprout::fixed::detail::stable_sort_impl_1(cont, comp, size, sprout::next(first), last, *first, 1, first)
|
||||
: comp(value, *first)
|
||||
? sprout::fixed::detail::stable_sort_impl_1(cont, comp, size, sprout::next(first), last, value, count, current)
|
||||
: sprout::fixed::detail::stable_sort_impl_1(cont, comp, size, sprout::next(first), last, value, count + 1, current)
|
||||
: sprout::fixed::detail::stable_sort_impl_synonym(cont, comp, size, sprout::next(current), last, value, count - 1, value)
|
||||
;
|
||||
}
|
||||
template<typename Container, typename Compare, std::ptrdiff_t I, std::ptrdiff_t... Indexes, std::ptrdiff_t... PreIndexes, std::ptrdiff_t... PostIndexes>
|
||||
SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm<Container>::type stable_sort_impl_3(
|
||||
Container const& cont,
|
||||
Compare comp,
|
||||
sprout::index_tuple<I, Indexes...>,
|
||||
sprout::index_tuple<PreIndexes...>,
|
||||
sprout::index_tuple<PostIndexes...>
|
||||
)
|
||||
{
|
||||
return stable_sort_impl_4(cont, comp, sprout::index_tuple<Indexes...>(), sprout::index_tuple<I>(), sprout::index_tuple<>(), sprout::index_tuple<PreIndexes...>(), sprout::index_tuple<PostIndexes...>());
|
||||
}
|
||||
template<typename Container, typename Compare, std::ptrdiff_t... Indexes, std::ptrdiff_t... PreIndexes, std::ptrdiff_t... PostIndexes>
|
||||
SPROUT_CONSTEXPR inline typename std::enable_if<
|
||||
(sizeof...(Indexes) <= 1),
|
||||
typename sprout::fixed::result_of::algorithm<Container>::type
|
||||
>::type stable_sort_impl_2(
|
||||
Container const& cont,
|
||||
Compare comp,
|
||||
sprout::index_tuple<Indexes...>,
|
||||
sprout::index_tuple<PreIndexes...>,
|
||||
sprout::index_tuple<PostIndexes...>
|
||||
)
|
||||
{
|
||||
return stable_sort_impl_finish(cont, sprout::index_tuple<PreIndexes..., Indexes..., PostIndexes...>());
|
||||
}
|
||||
template<typename Container, typename Compare, std::ptrdiff_t... Indexes, std::ptrdiff_t... PreIndexes, std::ptrdiff_t... PostIndexes>
|
||||
SPROUT_CONSTEXPR inline typename std::enable_if<
|
||||
(sizeof...(Indexes) > 1),
|
||||
typename sprout::fixed::result_of::algorithm<Container>::type
|
||||
>::type stable_sort_impl_2(
|
||||
Container const& cont,
|
||||
Compare comp,
|
||||
sprout::index_tuple<Indexes...>,
|
||||
sprout::index_tuple<PreIndexes...>,
|
||||
sprout::index_tuple<PostIndexes...>
|
||||
)
|
||||
{
|
||||
return stable_sort_impl_3(cont, comp, sprout::index_tuple<Indexes...>(), sprout::index_tuple<PreIndexes...>(), sprout::index_tuple<PostIndexes...>());
|
||||
}
|
||||
template<typename Container, typename Compare, std::ptrdiff_t I, std::ptrdiff_t... Indexes, std::ptrdiff_t... RangeIndexes, std::ptrdiff_t... PreIndexes, std::ptrdiff_t... PostIndexes>
|
||||
SPROUT_CONSTEXPR inline typename std::enable_if<
|
||||
sizeof...(Indexes) == 0,
|
||||
typename sprout::fixed::result_of::algorithm<Container>::type
|
||||
>::type stable_sort_impl_1(
|
||||
Container const& cont,
|
||||
Compare comp,
|
||||
sprout::index_tuple<I, Indexes...>,
|
||||
sprout::index_tuple<RangeIndexes...>,
|
||||
sprout::index_tuple<PreIndexes...>,
|
||||
sprout::index_tuple<PostIndexes...>
|
||||
)
|
||||
{
|
||||
return I < sprout::fixed_begin_offset(cont)
|
||||
? stable_sort_impl_2(cont, comp, sprout::index_tuple<RangeIndexes...>(), sprout::index_tuple<PreIndexes..., I>(), sprout::index_tuple<PostIndexes...>())
|
||||
: I >= sprout::fixed_end_offset(cont)
|
||||
? stable_sort_impl_2(cont, comp, sprout::index_tuple<RangeIndexes...>(), sprout::index_tuple<PreIndexes...>(), sprout::index_tuple<PostIndexes..., I>())
|
||||
: stable_sort_impl_2(cont, comp, sprout::index_tuple<RangeIndexes..., I>(), sprout::index_tuple<PreIndexes...>(), sprout::index_tuple<PostIndexes...>())
|
||||
;
|
||||
}
|
||||
template<typename Container, typename Compare, std::ptrdiff_t I, std::ptrdiff_t... Indexes, std::ptrdiff_t... RangeIndexes, std::ptrdiff_t... PreIndexes, std::ptrdiff_t... PostIndexes>
|
||||
SPROUT_CONSTEXPR inline typename std::enable_if<
|
||||
sizeof...(Indexes) != 0,
|
||||
typename sprout::fixed::result_of::algorithm<Container>::type
|
||||
>::type stable_sort_impl_1(
|
||||
Container const& cont,
|
||||
Compare comp,
|
||||
sprout::index_tuple<I, Indexes...>,
|
||||
sprout::index_tuple<RangeIndexes...>,
|
||||
sprout::index_tuple<PreIndexes...>,
|
||||
sprout::index_tuple<PostIndexes...>
|
||||
)
|
||||
{
|
||||
return I < sprout::fixed_begin_offset(cont)
|
||||
? stable_sort_impl_1(cont, comp, sprout::index_tuple<Indexes...>(), sprout::index_tuple<RangeIndexes...>(), sprout::index_tuple<PreIndexes..., I>(), sprout::index_tuple<PostIndexes...>())
|
||||
: I >= sprout::fixed_end_offset(cont)
|
||||
? stable_sort_impl_1(cont, comp, sprout::index_tuple<Indexes...>(), sprout::index_tuple<RangeIndexes...>(), sprout::index_tuple<PreIndexes...>(), sprout::index_tuple<PostIndexes..., I>())
|
||||
: stable_sort_impl_1(cont, comp, sprout::index_tuple<Indexes...>(), sprout::index_tuple<RangeIndexes..., I>(), sprout::index_tuple<PreIndexes...>(), sprout::index_tuple<PostIndexes...>())
|
||||
;
|
||||
}
|
||||
template<typename Container, typename Compare, std::ptrdiff_t... Indexes>
|
||||
template<typename Container, typename Compare>
|
||||
SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm<Container>::type stable_sort_impl(
|
||||
Container const& cont,
|
||||
Compare comp,
|
||||
sprout::index_tuple<Indexes...>
|
||||
typename sprout::fixed_container_traits<Container>::size_type size
|
||||
)
|
||||
{
|
||||
return stable_sort_impl_1(cont, comp, sprout::index_tuple<Indexes...>(), sprout::index_tuple<>(), sprout::index_tuple<>(), sprout::index_tuple<>());
|
||||
return sprout::fixed::detail::stable_sort_impl_1(
|
||||
cont,
|
||||
comp,
|
||||
size,
|
||||
sprout::next(sprout::begin(cont)),
|
||||
sprout::end(cont),
|
||||
*sprout::begin(cont),
|
||||
1,
|
||||
sprout::begin(cont)
|
||||
);
|
||||
}
|
||||
template<typename Container, typename Compare>
|
||||
SPROUT_CONSTEXPR inline typename std::enable_if<
|
||||
|
@ -221,7 +171,7 @@ namespace sprout {
|
|||
return sprout::fixed::detail::stable_sort_impl(
|
||||
cont,
|
||||
comp,
|
||||
typename sprout::index_range<0, sprout::fixed_container_traits<Container>::fixed_size>::type()
|
||||
sprout::size(cont)
|
||||
);
|
||||
}
|
||||
template<typename Container>
|
||||
|
@ -245,7 +195,7 @@ namespace sprout {
|
|||
return sprout::fixed::detail::stable_sort_impl(
|
||||
cont,
|
||||
NS_SSCRISK_CEL_OR_SPROUT_DETAIL::less<typename sprout::fixed_container_traits<Container>::value_type>(),
|
||||
typename sprout::index_range<0, sprout::fixed_container_traits<Container>::fixed_size>::type()
|
||||
sprout::size(cont)
|
||||
);
|
||||
}
|
||||
} // namespace detail
|
||||
|
|
Loading…
Reference in a new issue