From edc41403f6a781e08e0cd710bc0195ddf443f707 Mon Sep 17 00:00:00 2001 From: Mitsuru Kariya Date: Wed, 8 Apr 2015 00:24:12 +0900 Subject: [PATCH] fix rotate_copy --- libs/algorithm/test/rotate.cpp | 20 ++--- libs/algorithm/test/rotate_copy.cpp | 118 +++++++++++++++++++++---- sprout/algorithm/fixed/rotate_copy.hpp | 12 +-- 3 files changed, 119 insertions(+), 31 deletions(-) diff --git a/libs/algorithm/test/rotate.cpp b/libs/algorithm/test/rotate.cpp index d4181fba..65a5d550 100644 --- a/libs/algorithm/test/rotate.cpp +++ b/libs/algorithm/test/rotate.cpp @@ -24,21 +24,21 @@ namespace testspr { { SPROUT_STATIC_CONSTEXPR auto rotated = sprout::rotate( arr1, - sprout::begin(arr1) + 5 + sprout::begin(arr1) + 4 ); TESTSPR_BOTH_ASSERT(testspr::equal( rotated, - array{{6, 7, 8, 9, 10, 1, 2, 3, 4, 5}} + array{{5, 6, 7, 8, 9, 10, 1, 2, 3, 4}} )); } { SPROUT_STATIC_CONSTEXPR auto rotated = sprout::fit::rotate( arr1, - sprout::begin(arr1) + 5 + sprout::begin(arr1) + 4 ); TESTSPR_BOTH_ASSERT(testspr::equal( rotated, - array{{6, 7, 8, 9, 10, 1, 2, 3, 4, 5}} + array{{5, 6, 7, 8, 9, 10, 1, 2, 3, 4}} )); } // rotate @@ -46,29 +46,29 @@ namespace testspr { { SPROUT_STATIC_CONSTEXPR auto rotated = sprout::rotate( sprout::sub(arr1, 2, 8), - sprout::begin(arr1) + 5 + sprout::begin(arr1) + 4 ); TESTSPR_BOTH_ASSERT(testspr::equal( rotated, - array{{6, 7, 8, 3, 4, 5}} + array{{5, 6, 7, 8, 3, 4}} )); TESTSPR_BOTH_ASSERT(testspr::equal( sprout::get_internal(rotated), - array{{1, 2, 6, 7, 8, 3, 4, 5, 9, 10}} + array{{1, 2, 5, 6, 7, 8, 3, 4, 9, 10}} )); } { SPROUT_STATIC_CONSTEXPR auto rotated = sprout::fit::rotate( sprout::sub(arr1, 2, 8), - sprout::begin(arr1) + 5 + sprout::begin(arr1) + 4 ); TESTSPR_BOTH_ASSERT(testspr::equal( rotated, - array{{6, 7, 8, 3, 4, 5}} + array{{5, 6, 7, 8, 3, 4}} )); TESTSPR_BOTH_ASSERT(testspr::equal( sprout::get_internal(rotated), - array{{1, 2, 6, 7, 8, 3, 4, 5, 9, 10}} + array{{1, 2, 5, 6, 7, 8, 3, 4, 9, 10}} )); } } diff --git a/libs/algorithm/test/rotate_copy.cpp b/libs/algorithm/test/rotate_copy.cpp index 77224c07..0236ab81 100644 --- a/libs/algorithm/test/rotate_copy.cpp +++ b/libs/algorithm/test/rotate_copy.cpp @@ -26,25 +26,25 @@ namespace testspr { { SPROUT_STATIC_CONSTEXPR auto rotated = sprout::rotate_copy( sprout::begin(arr1) + 2, - sprout::begin(arr1) + 5, + sprout::begin(arr1) + 4, sprout::begin(arr1) + 8, arr2 ); TESTSPR_BOTH_ASSERT(testspr::equal( rotated, - array{{6, 7, 8, 3, 4, 5, 0, 0, 0, 0}} + array{{5, 6, 7, 8, 3, 4, 0, 0, 0, 0}} )); } { SPROUT_STATIC_CONSTEXPR auto rotated = sprout::fit::rotate_copy( sprout::begin(arr1) + 2, - sprout::begin(arr1) + 5, + sprout::begin(arr1) + 4, sprout::begin(arr1) + 8, arr2 ); TESTSPR_BOTH_ASSERT(testspr::equal( rotated, - array{{6, 7, 8, 3, 4, 5}} + array{{5, 6, 7, 8, 3, 4}} )); } // rotate in range [2 .. 8) @@ -52,25 +52,25 @@ namespace testspr { { SPROUT_STATIC_CONSTEXPR auto rotated = sprout::rotate_copy( sprout::begin(arr1) + 2, - sprout::begin(arr1) + 5, - sprout::begin(arr1) + 8, + sprout::begin(arr1) + 4, + sprout::begin(arr1) + 7, arr3 ); TESTSPR_BOTH_ASSERT(testspr::equal( rotated, - array{{6, 7, 8, 3}} + array{{5, 6, 7, 3}} )); } { SPROUT_STATIC_CONSTEXPR auto rotated = sprout::fit::rotate_copy( sprout::begin(arr1) + 2, - sprout::begin(arr1) + 5, - sprout::begin(arr1) + 8, + sprout::begin(arr1) + 4, + sprout::begin(arr1) + 7, arr3 ); TESTSPR_BOTH_ASSERT(testspr::equal( rotated, - array{{6, 7, 8, 3}} + array{{5, 6, 7, 3}} )); } // rotate in range [2 .. 8) @@ -78,33 +78,119 @@ namespace testspr { { SPROUT_STATIC_CONSTEXPR auto rotated = sprout::rotate_copy( sprout::begin(arr1) + 2, - sprout::begin(arr1) + 5, + sprout::begin(arr1) + 4, sprout::begin(arr1) + 8, sprout::sub(arr2, 2, 8) ); TESTSPR_BOTH_ASSERT(testspr::equal( rotated, - array{{6, 7, 8, 3, 4, 5}} + array{{5, 6, 7, 8, 3, 4}} )); TESTSPR_BOTH_ASSERT(testspr::equal( sprout::get_internal(rotated), - array{{0, 0, 6, 7, 8, 3, 4, 5, 0, 0}} + array{{0, 0, 5, 6, 7, 8, 3, 4, 0, 0}} )); } { SPROUT_STATIC_CONSTEXPR auto rotated = sprout::fit::rotate_copy( sprout::begin(arr1) + 2, - sprout::begin(arr1) + 5, + sprout::begin(arr1) + 4, sprout::begin(arr1) + 8, sprout::sub(arr2, 2, 8) ); TESTSPR_BOTH_ASSERT(testspr::equal( rotated, - array{{6, 7, 8, 3, 4, 5}} + array{{5, 6, 7, 8, 3, 4}} )); TESTSPR_BOTH_ASSERT(testspr::equal( sprout::get_internal(rotated), - array{{0, 0, 6, 7, 8, 3, 4, 5, 0, 0}} + array{{0, 0, 5, 6, 7, 8, 3, 4, 0, 0}} + )); + } + + // rotate in range [2 .. 8) + { + SPROUT_STATIC_CONSTEXPR auto rotated = sprout::rotate_copy( + testspr::reduct_forward(sprout::begin(arr1) + 2), + testspr::reduct_forward(sprout::begin(arr1) + 4), + testspr::reduct_forward(sprout::begin(arr1) + 8), + arr2 + ); + TESTSPR_BOTH_ASSERT(testspr::equal( + rotated, + array{{5, 6, 7, 8, 3, 4, 0, 0, 0, 0}} + )); + } + { + SPROUT_STATIC_CONSTEXPR auto rotated = sprout::fit::rotate_copy( + testspr::reduct_forward(sprout::begin(arr1) + 2), + testspr::reduct_forward(sprout::begin(arr1) + 4), + testspr::reduct_forward(sprout::begin(arr1) + 8), + arr2 + ); + TESTSPR_BOTH_ASSERT(testspr::equal( + rotated, + array{{5, 6, 7, 8, 3, 4}} + )); + } + // rotate in range [2 .. 8) + // overrun from output range + { + SPROUT_STATIC_CONSTEXPR auto rotated = sprout::rotate_copy( + testspr::reduct_forward(sprout::begin(arr1) + 2), + testspr::reduct_forward(sprout::begin(arr1) + 4), + testspr::reduct_forward(sprout::begin(arr1) + 7), + arr3 + ); + TESTSPR_BOTH_ASSERT(testspr::equal( + rotated, + array{{5, 6, 7, 3}} + )); + } + { + SPROUT_STATIC_CONSTEXPR auto rotated = sprout::fit::rotate_copy( + testspr::reduct_forward(sprout::begin(arr1) + 2), + testspr::reduct_forward(sprout::begin(arr1) + 4), + testspr::reduct_forward(sprout::begin(arr1) + 7), + arr3 + ); + TESTSPR_BOTH_ASSERT(testspr::equal( + rotated, + array{{5, 6, 7, 3}} + )); + } + // rotate in range [2 .. 8) + // to sub range + { + SPROUT_STATIC_CONSTEXPR auto rotated = sprout::rotate_copy( + testspr::reduct_forward(sprout::begin(arr1) + 2), + testspr::reduct_forward(sprout::begin(arr1) + 4), + testspr::reduct_forward(sprout::begin(arr1) + 8), + sprout::sub(arr2, 2, 8) + ); + TESTSPR_BOTH_ASSERT(testspr::equal( + rotated, + array{{5, 6, 7, 8, 3, 4}} + )); + TESTSPR_BOTH_ASSERT(testspr::equal( + sprout::get_internal(rotated), + array{{0, 0, 5, 6, 7, 8, 3, 4, 0, 0}} + )); + } + { + SPROUT_STATIC_CONSTEXPR auto rotated = sprout::fit::rotate_copy( + testspr::reduct_forward(sprout::begin(arr1) + 2), + testspr::reduct_forward(sprout::begin(arr1) + 4), + testspr::reduct_forward(sprout::begin(arr1) + 8), + sprout::sub(arr2, 2, 8) + ); + TESTSPR_BOTH_ASSERT(testspr::equal( + rotated, + array{{5, 6, 7, 8, 3, 4}} + )); + TESTSPR_BOTH_ASSERT(testspr::equal( + sprout::get_internal(rotated), + array{{0, 0, 5, 6, 7, 8, 3, 4, 0, 0}} )); } } diff --git a/sprout/algorithm/fixed/rotate_copy.hpp b/sprout/algorithm/fixed/rotate_copy.hpp index 395fcd78..3b149e9a 100644 --- a/sprout/algorithm/fixed/rotate_copy.hpp +++ b/sprout/algorithm/fixed/rotate_copy.hpp @@ -29,7 +29,8 @@ namespace sprout { template inline SPROUT_CONSTEXPR typename sprout::fixed::results::algorithm::type rotate_copy_impl_ra( - RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, + RandomAccessIterator first, RandomAccessIterator middle, + typename sprout::container_traits::size_type last_half_size, Result const& result, sprout::index_tuple, typename sprout::container_traits::difference_type offset, @@ -41,9 +42,9 @@ namespace sprout { result, sprout::size(result), (Indexes >= offset && Indexes < offset + size && Indexes < offset + input_size - ? (Indexes < offset + sprout::distance(middle, last) + ? (Indexes < offset + last_half_size ? middle[Indexes - offset] - : first[(Indexes - offset) - sprout::distance(first, middle)] + : first[(Indexes - offset) - last_half_size] ) : *sprout::next(sprout::internal_begin(result), Indexes) )... @@ -58,7 +59,8 @@ namespace sprout { ) { return sprout::fixed::detail::rotate_copy_impl_ra( - first, middle, last, + first, middle, + sprout::distance(middle, last), result, sprout::container_indexes::make(), sprout::internal_begin_offset(result), @@ -138,7 +140,7 @@ namespace sprout { std::forward_iterator_tag* ) { - return sprout::fixed::detail::rotate_copy_impl(first, middle, last, result, sprout::size(result)); + return sprout::fixed::detail::rotate_copy_impl(first, middle, middle, last, result, sprout::size(result)); } template