From dce6fff6a45d7cdc3dbc43a49a4679cc398fee54 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Thu, 16 May 2013 15:13:49 +0900 Subject: [PATCH] add mismatch algorithm: robust version (N3607) --- libs/algorithm/test/mismatch.cpp | 284 ++++++++++++++++++ sprout/algorithm/lexicographical_compare.hpp | 4 +- sprout/algorithm/mismatch.hpp | 137 ++++++++- .../tristate_lexicographical_compare.hpp | 6 +- 4 files changed, 424 insertions(+), 7 deletions(-) diff --git a/libs/algorithm/test/mismatch.cpp b/libs/algorithm/test/mismatch.cpp index 16e660c9..131918c5 100644 --- a/libs/algorithm/test/mismatch.cpp +++ b/libs/algorithm/test/mismatch.cpp @@ -21,6 +21,7 @@ namespace testspr { sprout::begin(arr2) ); TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1) + 7); + TESTSPR_BOTH_ASSERT(found.second == sprout::begin(arr2) + 7); } { SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( @@ -29,6 +30,7 @@ namespace testspr { sprout::begin(arr3) ); TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second == sprout::begin(arr2)); } { SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( @@ -37,6 +39,7 @@ namespace testspr { sprout::begin(arr2) ); TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1) + 5); + TESTSPR_BOTH_ASSERT(found.second == sprout::begin(arr2) + 5); } { SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( @@ -45,6 +48,7 @@ namespace testspr { sprout::begin(arr3) ); TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second == sprout::begin(arr2)); } { @@ -55,6 +59,7 @@ namespace testspr { testspr::equal_to() ); TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1) + 7); + TESTSPR_BOTH_ASSERT(found.second == sprout::begin(arr2) + 7); } { SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( @@ -64,6 +69,7 @@ namespace testspr { testspr::equal_to() ); TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second == sprout::begin(arr2)); } { SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( @@ -73,6 +79,7 @@ namespace testspr { testspr::equal_to() ); TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1) + 5); + TESTSPR_BOTH_ASSERT(found.second == sprout::begin(arr2) + 5); } { SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( @@ -82,6 +89,7 @@ namespace testspr { testspr::equal_to() ); TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second == sprout::begin(arr2)); } { @@ -91,6 +99,7 @@ namespace testspr { testspr::reduct_input(sprout::begin(arr2)) ); TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1) + 7); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2) + 7); } { SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( @@ -99,6 +108,7 @@ namespace testspr { testspr::reduct_input(sprout::begin(arr3)) ); TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2)); } { SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( @@ -107,6 +117,7 @@ namespace testspr { testspr::reduct_input(sprout::begin(arr2)) ); TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1) + 5); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2) + 5); } { SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( @@ -115,6 +126,7 @@ namespace testspr { testspr::reduct_input(sprout::begin(arr3)) ); TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2)); } { @@ -125,6 +137,7 @@ namespace testspr { testspr::equal_to() ); TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1) + 7); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2) + 7); } { SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( @@ -134,6 +147,7 @@ namespace testspr { testspr::equal_to() ); TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2)); } { SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( @@ -143,6 +157,7 @@ namespace testspr { testspr::equal_to() ); TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1) + 5); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2) + 5); } { SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( @@ -152,6 +167,7 @@ namespace testspr { testspr::equal_to() ); TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2)); } #if defined(__clang__) @@ -162,6 +178,7 @@ namespace testspr { testspr::reduct_random_access(sprout::begin(arr2)) ); TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1) + 7); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2) + 7); } { SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( @@ -170,6 +187,7 @@ namespace testspr { testspr::reduct_random_access(sprout::begin(arr3)) ); TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2)); } { SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( @@ -178,6 +196,7 @@ namespace testspr { testspr::reduct_random_access(sprout::begin(arr2)) ); TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1) + 5); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2) + 5); } { SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( @@ -186,6 +205,7 @@ namespace testspr { testspr::reduct_random_access(sprout::begin(arr3)) ); TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2)); } { @@ -196,6 +216,7 @@ namespace testspr { testspr::equal_to() ); TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1) + 7); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2) + 7); } { SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( @@ -205,6 +226,7 @@ namespace testspr { testspr::equal_to() ); TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2)); } { SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( @@ -214,6 +236,7 @@ namespace testspr { testspr::equal_to() ); TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1) + 5); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2) + 5); } { SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( @@ -223,6 +246,267 @@ namespace testspr { testspr::equal_to() ); TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2)); + } +#endif + + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr2), + sprout::end(arr2) + ); + TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1) + 7); + TESTSPR_BOTH_ASSERT(found.second == sprout::begin(arr2) + 7); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr3), + sprout::end(arr2) + ); + TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second == sprout::begin(arr2)); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr2), + sprout::begin(arr2) + 5 + ); + TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1) + 5); + TESTSPR_BOTH_ASSERT(found.second == sprout::begin(arr2) + 5); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr3), + sprout::begin(arr2) + 5 + ); + TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second == sprout::begin(arr2)); + } + + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr2), + sprout::end(arr2), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1) + 7); + TESTSPR_BOTH_ASSERT(found.second == sprout::begin(arr2) + 7); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr3), + sprout::end(arr2), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second == sprout::begin(arr2)); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr2), + sprout::begin(arr2) + 5, + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1) + 5); + TESTSPR_BOTH_ASSERT(found.second == sprout::begin(arr2) + 5); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr3), + sprout::begin(arr2) + 5, + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second == sprout::begin(arr2)); + } + + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + testspr::reduct_input(sprout::begin(arr1)), + testspr::reduct_input(sprout::end(arr1)), + testspr::reduct_input(sprout::begin(arr2)), + testspr::reduct_input(sprout::end(arr2)) + ); + TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1) + 7); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2) + 7); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + testspr::reduct_input(sprout::begin(arr1)), + testspr::reduct_input(sprout::end(arr1)), + testspr::reduct_input(sprout::begin(arr3)), + testspr::reduct_input(sprout::end(arr2)) + ); + TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2)); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + testspr::reduct_input(sprout::begin(arr1)), + testspr::reduct_input(sprout::end(arr1)), + testspr::reduct_input(sprout::begin(arr2)), + testspr::reduct_input(sprout::begin(arr2) + 5) + ); + TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1) + 5); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2) + 5); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + testspr::reduct_input(sprout::begin(arr1)), + testspr::reduct_input(sprout::end(arr1)), + testspr::reduct_input(sprout::begin(arr3)), + testspr::reduct_input(sprout::begin(arr2) + 5) + ); + TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2)); + } + + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + testspr::reduct_input(sprout::begin(arr1)), + testspr::reduct_input(sprout::end(arr1)), + testspr::reduct_input(sprout::begin(arr2)), + testspr::reduct_input(sprout::end(arr2)), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1) + 7); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2) + 7); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + testspr::reduct_input(sprout::begin(arr1)), + testspr::reduct_input(sprout::end(arr1)), + testspr::reduct_input(sprout::begin(arr3)), + testspr::reduct_input(sprout::end(arr2)), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2)); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + testspr::reduct_input(sprout::begin(arr1)), + testspr::reduct_input(sprout::end(arr1)), + testspr::reduct_input(sprout::begin(arr2)), + testspr::reduct_input(sprout::begin(arr2) + 5), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1) + 5); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2) + 5); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + testspr::reduct_input(sprout::begin(arr1)), + testspr::reduct_input(sprout::end(arr1)), + testspr::reduct_input(sprout::begin(arr3)), + testspr::reduct_input(sprout::begin(arr2) + 5), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2)); + } + +#if defined(__clang__) + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + testspr::reduct_random_access(sprout::begin(arr1)), + testspr::reduct_random_access(sprout::end(arr1)), + testspr::reduct_random_access(sprout::begin(arr2)), + testspr::reduct_random_access(sprout::end(arr2)) + ); + TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1) + 7); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2) + 7); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + testspr::reduct_random_access(sprout::begin(arr1)), + testspr::reduct_random_access(sprout::end(arr1)), + testspr::reduct_random_access(sprout::begin(arr3)), + testspr::reduct_random_access(sprout::end(arr2)) + ); + TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2)); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + testspr::reduct_random_access(sprout::begin(arr1)), + testspr::reduct_random_access(sprout::end(arr1)), + testspr::reduct_random_access(sprout::begin(arr2)), + testspr::reduct_random_access(sprout::begin(arr2) + 5) + ); + TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1) + 5); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2) + 5); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + testspr::reduct_random_access(sprout::begin(arr1)), + testspr::reduct_random_access(sprout::end(arr1)), + testspr::reduct_random_access(sprout::begin(arr3)), + testspr::reduct_random_access(sprout::begin(arr2) + 5) + ); + TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2)); + } + + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + testspr::reduct_random_access(sprout::begin(arr1)), + testspr::reduct_random_access(sprout::end(arr1)), + testspr::reduct_random_access(sprout::begin(arr2)), + testspr::reduct_random_access(sprout::end(arr2)), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1) + 7); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2) + 7); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + testspr::reduct_random_access(sprout::begin(arr1)), + testspr::reduct_random_access(sprout::end(arr1)), + testspr::reduct_random_access(sprout::begin(arr3)), + testspr::reduct_random_access(sprout::end(arr2)), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2)); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + testspr::reduct_random_access(sprout::begin(arr1)), + testspr::reduct_random_access(sprout::end(arr1)), + testspr::reduct_random_access(sprout::begin(arr2)), + testspr::reduct_random_access(sprout::begin(arr2) + 5), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1) + 5); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2) + 5); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + testspr::reduct_random_access(sprout::begin(arr1)), + testspr::reduct_random_access(sprout::end(arr1)), + testspr::reduct_random_access(sprout::begin(arr3)), + testspr::reduct_random_access(sprout::begin(arr2) + 5), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(found.first.base() == sprout::begin(arr1)); + TESTSPR_BOTH_ASSERT(found.second.base() == sprout::begin(arr2)); } #endif } diff --git a/sprout/algorithm/lexicographical_compare.hpp b/sprout/algorithm/lexicographical_compare.hpp index 37eeb11b..d2f8c4cc 100644 --- a/sprout/algorithm/lexicographical_compare.hpp +++ b/sprout/algorithm/lexicographical_compare.hpp @@ -8,8 +8,8 @@ #include #include #include -#include #include +#include HDR_ALGORITHM_MIN_MAX_SSCRISK_CEL_OR_SPROUT namespace sprout { namespace detail { @@ -76,7 +76,7 @@ namespace sprout { : first1 == last1 ? true : sprout::detail::lexicographical_compare_impl_ra( first1, last1, first2, last2, comp, - sprout::min(sprout::distance(first1, last1), sprout::distance(first2, last2)) + NS_SSCRISK_CEL_OR_SPROUT::min(sprout::distance(first1, last1), sprout::distance(first2, last2)) ) ; } diff --git a/sprout/algorithm/mismatch.hpp b/sprout/algorithm/mismatch.hpp index f510acd6..02b42aa2 100644 --- a/sprout/algorithm/mismatch.hpp +++ b/sprout/algorithm/mismatch.hpp @@ -10,16 +10,18 @@ #include #include #include +#include HDR_ALGORITHM_MIN_MAX_SSCRISK_CEL_OR_SPROUT namespace sprout { namespace detail { template inline SPROUT_CONSTEXPR sprout::pair - mismatch_impl_ra_1(RandomAccessIterator1 first1, RandomAccessIterator2 first2, RandomAccessIterator1 found) { + mismatch_impl_check(RandomAccessIterator1 first1, RandomAccessIterator2 first2, RandomAccessIterator1 found) { return sprout::pair{ found, sprout::next(first2, sprout::distance(first1, found)) }; } + template inline SPROUT_CONSTEXPR RandomAccessIterator1 mismatch_impl_ra( @@ -51,7 +53,7 @@ namespace sprout { ) { return first1 == last1 ? sprout::pair{first1, first2} - : sprout::detail::mismatch_impl_ra_1( + : sprout::detail::mismatch_impl_check( first1, first2, sprout::detail::mismatch_impl_ra( first1, last1, first2, pred, @@ -137,6 +139,137 @@ namespace sprout { mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2) { return sprout::mismatch(first1, last1, first2, sprout::equal_to<>()); } + + namespace detail { + template + inline SPROUT_CONSTEXPR RandomAccessIterator1 + mismatch2_impl_ra_1( + RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, RandomAccessIterator2 last2, BinaryPredicate pred, + typename std::iterator_traits::difference_type pivot, RandomAccessIterator1 found + ) + { + return found != first1 ? found + : pivot == 0 ? (!pred(*first1, *first2) ? first1 : last1) + : sprout::detail::mismatch2_impl_ra_1( + sprout::next(first1, pivot), last1, sprout::next(first2, pivot), last2, pred, + (sprout::distance(first1, last1) - pivot) / 2, + sprout::detail::mismatch2_impl_ra_1( + first1, sprout::next(first1, pivot), first2, sprout::next(first2, pivot), pred, + pivot / 2, + first1 + ) + ) + ; + } + template + inline SPROUT_CONSTEXPR RandomAccessIterator1 + mismatch2_impl_ra( + RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, RandomAccessIterator2 last2, BinaryPredicate pred, + typename std::iterator_traits::difference_type size + ) + { + return sprout::detail::mismatch2_impl_ra_1( + first1, sprout::next(first1, size), first2, sprout::next(first2, size), pred, + size / 2, first1 + ); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::is_constant_distance_iterator::value && sprout::is_constant_distance_iterator::value, + sprout::pair + >::type + mismatch( + RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, RandomAccessIterator2 last2, BinaryPredicate pred, + std::random_access_iterator_tag* + ) + { + return first1 == last1 || first2 == last2 ? sprout::pair{first1, first2} + : sprout::detail::mismatch_impl_check( + first1, first2, + sprout::detail::mismatch2_impl_ra( + first1, last1, first2, last2, pred, + NS_SSCRISK_CEL_OR_SPROUT::min(sprout::distance(first1, last1), sprout::distance(first2, last2)) + ) + ) + ; + } + + template + inline SPROUT_CONSTEXPR sprout::pair + mismatch2_impl_check(sprout::tuples::tuple const& current) { + return sprout::pair( + sprout::tuples::get<0>(current), + sprout::tuples::get<1>(current) + ); + } + template + inline SPROUT_CONSTEXPR sprout::tuples::tuple + mismatch2_impl_1( + sprout::tuples::tuple const& current, + InputIterator1 last1, InputIterator2 last2, BinaryPredicate pred, typename std::iterator_traits::difference_type n + ) + { + typedef sprout::tuples::tuple type; + return sprout::tuples::get<2>(current) || sprout::tuples::get<0>(current) == last1 || sprout::tuples::get<1>(current) == last2 ? current + : n == 1 ? !pred(*sprout::tuples::get<0>(current), *sprout::tuples::get<1>(current)) + ? type(sprout::tuples::get<0>(current), sprout::tuples::get<1>(current), true) + : type(sprout::next(sprout::tuples::get<0>(current)), sprout::next(sprout::tuples::get<1>(current)), false) + : sprout::detail::mismatch2_impl_1( + sprout::detail::mismatch2_impl_1( + current, + last1, last2, pred, n / 2 + ), + last1, last2, pred, n - n / 2 + ) + ; + } + template + inline SPROUT_CONSTEXPR sprout::tuples::tuple + mismatch2_impl( + sprout::tuples::tuple const& current, + InputIterator1 last1, InputIterator2 last2, BinaryPredicate pred, typename std::iterator_traits::difference_type n + ) + { + return sprout::tuples::get<2>(current) || sprout::tuples::get<0>(current) == last1 || sprout::tuples::get<1>(current) == last2 ? current + : sprout::detail::mismatch2_impl( + sprout::detail::mismatch2_impl_1( + current, + last1, last2, pred, n + ), + last1, last2, pred, n * 2 + ) + ; + } + template + inline SPROUT_CONSTEXPR sprout::pair + mismatch( + InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred, + std::input_iterator_tag* + ) + { + typedef sprout::tuples::tuple type; + return sprout::detail::mismatch2_impl_check( + sprout::detail::mismatch2_impl(type(first1, first2, false), last1, last2, pred, 1) + ); + } + } // namespace detail + + // 25.2.10 Mismatch + // + // recursion depth: + // O(log N) + // + template + inline SPROUT_CONSTEXPR sprout::pair + mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred) { + typedef typename sprout::common_iterator_category::type* category; + return sprout::detail::mismatch(first1, last1, first2, last2, pred, category()); + } + template + inline SPROUT_CONSTEXPR sprout::pair + mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2) { + return sprout::mismatch(first1, last1, first2, last2, sprout::equal_to<>()); + } } // namespace sprout #endif // #ifndef SPROUT_ALGORITHM_MISMATCH_HPP diff --git a/sprout/algorithm/tristate_lexicographical_compare.hpp b/sprout/algorithm/tristate_lexicographical_compare.hpp index 1b4f5cc1..06749540 100644 --- a/sprout/algorithm/tristate_lexicographical_compare.hpp +++ b/sprout/algorithm/tristate_lexicographical_compare.hpp @@ -8,8 +8,8 @@ #include #include #include -#include #include +#include HDR_ALGORITHM_MIN_MAX_SSCRISK_CEL_OR_SPROUT namespace sprout { namespace detail { @@ -79,7 +79,7 @@ namespace sprout { : first1 == last1 ? -1 : sprout::detail::tristate_lexicographical_compare_impl_ra( first1, last1, first2, last2, comp, - sprout::min(sprout::distance(first1, last1), sprout::distance(first2, last2)) + NS_SSCRISK_CEL_OR_SPROUT::min(sprout::distance(first1, last1), sprout::distance(first2, last2)) ) ; } @@ -243,7 +243,7 @@ namespace sprout { : first1 == last1 || (!comp(*first1, delim1) && !comp(delim1, *first1)) ? -1 : sprout::detail::tristate_lexicographical_compare_2_impl_ra( first1, last1, delim1, first2, last2, delim2, comp, - sprout::min(sprout::distance(first1, last1), sprout::distance(first2, last2)) + NS_SSCRISK_CEL_OR_SPROUT::min(sprout::distance(first1, last1), sprout::distance(first2, last2)) ) ; }