sprout/algorithm/fixed/stable_sort.hpp 実装変更

This commit is contained in:
bolero-MURAKAMI 2011-10-28 00:16:46 +09:00
parent f4aba3218c
commit b8c536cce2

View file

@ -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/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