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 <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/index_tuple.hpp>
#include <sprout/fixed_container/traits.hpp> #include <sprout/fixed_container/traits.hpp>
#include <sprout/fixed_container/functions.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 <sprout/algorithm/fixed/result_of.hpp>
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT_DETAIL #include <sprout/detail/container_complate.hpp>
namespace sprout { namespace sprout {
namespace fixed { namespace fixed {
namespace detail { 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> template<typename Container, typename Compare, typename... Args>
SPROUT_CONSTEXPR inline typename std::enable_if< SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm<Container>::type stable_sort_impl_restart(
sizeof...(Indexes) != 0 && sizeof...(SortedIndexes) != 0,
typename sprout::fixed::result_of::algorithm<Container>::type
>::type stable_sort_impl_4(
Container const& cont, Container const& cont,
Compare comp, Compare comp,
sprout::index_tuple<I1, Indexes...>, typename sprout::fixed_container_traits<Container>::size_type size,
sprout::index_tuple<I2, SortedIndexes...>, typename sprout::fixed_container_traits<Container>::value_type const& prev_value,
sprout::index_tuple<NextIndexes...>, Args const&... args
sprout::index_tuple<PreIndexes...>,
sprout::index_tuple<PostIndexes...>
); );
template<typename Container, std::ptrdiff_t... Indexes> template<typename Container, typename Compare, typename... Args>
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>
SPROUT_CONSTEXPR inline typename std::enable_if< 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 typename sprout::fixed::result_of::algorithm<Container>::type
>::type stable_sort_impl_4( >::type stable_sort_impl_synonym(
Container const& cont, Container const& cont,
Compare comp, Compare comp,
sprout::index_tuple<I1, Indexes...>, typename sprout::fixed_container_traits<Container>::size_type size,
sprout::index_tuple<I2, SortedIndexes...>, typename sprout::fixed_container_traits<Container>::const_iterator first,
sprout::index_tuple<NextIndexes...>, typename sprout::fixed_container_traits<Container>::const_iterator last,
sprout::index_tuple<PreIndexes...>, typename sprout::fixed_container_traits<Container>::value_type const& value,
sprout::index_tuple<PostIndexes...> 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)) return sprout::remake_clone<Container, Container>(cont, sprout::size(cont), args...);
? 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...>()) 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> template<typename Container, typename Compare, typename... Args>
SPROUT_CONSTEXPR inline typename std::enable_if< SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm<Container>::type stable_sort_impl_restart_1(
sizeof...(Indexes) == 0 && sizeof...(SortedIndexes) != 0,
typename sprout::fixed::result_of::algorithm<Container>::type
>::type stable_sort_impl_4(
Container const& cont, Container const& cont,
Compare comp, Compare comp,
sprout::index_tuple<I1, Indexes...>, typename sprout::fixed_container_traits<Container>::size_type size,
sprout::index_tuple<I2, SortedIndexes...>, typename sprout::fixed_container_traits<Container>::const_iterator first,
sprout::index_tuple<NextIndexes...>, typename sprout::fixed_container_traits<Container>::const_iterator last,
sprout::index_tuple<PreIndexes...>, typename sprout::fixed_container_traits<Container>::value_type const& value,
sprout::index_tuple<PostIndexes...> 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)) return first != last
? stable_sort_impl_finish(cont, sprout::index_tuple<PreIndexes..., NextIndexes..., I1, I2, SortedIndexes..., PostIndexes...>()) ? comp(prev_value, *first)
: 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...>()) ? 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> template<typename Container, typename Compare, typename... Args>
SPROUT_CONSTEXPR inline typename std::enable_if< SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm<Container>::type stable_sort_impl_restart(
sizeof...(Indexes) != 0 && sizeof...(SortedIndexes) == 0,
typename sprout::fixed::result_of::algorithm<Container>::type
>::type stable_sort_impl_4(
Container const& cont, Container const& cont,
Compare comp, Compare comp,
sprout::index_tuple<I1, Indexes...>, typename sprout::fixed_container_traits<Container>::size_type size,
sprout::index_tuple<I2, SortedIndexes...>, typename sprout::fixed_container_traits<Container>::value_type const& prev_value,
sprout::index_tuple<NextIndexes...>, Args const&... args
sprout::index_tuple<PreIndexes...>,
sprout::index_tuple<PostIndexes...>
) )
{ {
return comp(*sprout::next(sprout::fixed_begin(cont), I1), *sprout::next(sprout::fixed_begin(cont), I2)) return sizeof...(Args) < size
? 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...>()) ? sprout::fixed::detail::stable_sort_impl_restart_1(
: 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...>()) 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> template<typename Container, typename Compare>
SPROUT_CONSTEXPR inline typename std::enable_if< SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm<Container>::type stable_sort_impl_1(
sizeof...(Indexes) != 0 && sizeof...(SortedIndexes) != 0,
typename sprout::fixed::result_of::algorithm<Container>::type
>::type stable_sort_impl_4(
Container const& cont, Container const& cont,
Compare comp, Compare comp,
sprout::index_tuple<I1, Indexes...>, typename sprout::fixed_container_traits<Container>::size_type size,
sprout::index_tuple<I2, SortedIndexes...>, typename sprout::fixed_container_traits<Container>::const_iterator first,
sprout::index_tuple<NextIndexes...>, typename sprout::fixed_container_traits<Container>::const_iterator last,
sprout::index_tuple<PreIndexes...>, typename sprout::fixed_container_traits<Container>::value_type const& value,
sprout::index_tuple<PostIndexes...> 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)) return first != last
? 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...>()) ? comp(*first, value)
: 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...>()) ? 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> template<typename Container, typename Compare>
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>
SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm<Container>::type stable_sort_impl( SPROUT_CONSTEXPR inline typename sprout::fixed::result_of::algorithm<Container>::type stable_sort_impl(
Container const& cont, Container const& cont,
Compare comp, 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> template<typename Container, typename Compare>
SPROUT_CONSTEXPR inline typename std::enable_if< SPROUT_CONSTEXPR inline typename std::enable_if<
@ -221,7 +171,7 @@ namespace sprout {
return sprout::fixed::detail::stable_sort_impl( return sprout::fixed::detail::stable_sort_impl(
cont, cont,
comp, comp,
typename sprout::index_range<0, sprout::fixed_container_traits<Container>::fixed_size>::type() sprout::size(cont)
); );
} }
template<typename Container> template<typename Container>
@ -245,7 +195,7 @@ namespace sprout {
return sprout::fixed::detail::stable_sort_impl( return sprout::fixed::detail::stable_sort_impl(
cont, cont,
NS_SSCRISK_CEL_OR_SPROUT_DETAIL::less<typename sprout::fixed_container_traits<Container>::value_type>(), 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 } // namespace detail