From 75228465fe33cc3a23984b81b840de441707a0ac Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Wed, 12 Dec 2012 01:47:14 +0900 Subject: [PATCH] fix recursion depth: count, count_if, mismatch, equal, is_permutation --- libs/algorithm/test/count.cpp | 56 +++++++++++++++ libs/algorithm/test/count_if.cpp | 56 +++++++++++++++ libs/algorithm/test/equal.cpp | 95 ++++++++++++++++++++++++++ libs/algorithm/test/is_permutation.cpp | 95 ++++++++++++++++++++++++++ libs/algorithm/test/mismatch.cpp | 95 ++++++++++++++++++++++++++ libs/algorithm/test/non_modifying.cpp | 10 +++ sprout/algorithm/count.hpp | 56 +++++++++++++-- sprout/algorithm/count_if.hpp | 56 +++++++++++++-- sprout/algorithm/equal.hpp | 75 ++++++++++++++++---- sprout/algorithm/find_end.hpp | 20 +----- sprout/algorithm/find_first_of.hpp | 7 +- sprout/algorithm/is_permutation.hpp | 89 +++++++++++++++--------- sprout/algorithm/mismatch.hpp | 92 +++++++++++++++++++++---- sprout/detail/pow.hpp | 1 + 14 files changed, 716 insertions(+), 87 deletions(-) create mode 100644 libs/algorithm/test/count.cpp create mode 100644 libs/algorithm/test/count_if.cpp create mode 100644 libs/algorithm/test/equal.cpp create mode 100644 libs/algorithm/test/is_permutation.cpp create mode 100644 libs/algorithm/test/mismatch.cpp diff --git a/libs/algorithm/test/count.cpp b/libs/algorithm/test/count.cpp new file mode 100644 index 00000000..7db9b1a3 --- /dev/null +++ b/libs/algorithm/test/count.cpp @@ -0,0 +1,56 @@ +#ifndef SPROUT_LIBS_ALGORITHM_TEST_COUNT_CPP +#define SPROUT_LIBS_ALGORITHM_TEST_COUNT_CPP + +#include +#include +#include +#include + +namespace testspr { + static void algorithm_count_test() { + using namespace sprout; + { + SPROUT_STATIC_CONSTEXPR auto arr1 = array{{1, 2, 3, 5, 5, 5, 5, 8, 9, 10}}; + + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::count( + sprout::begin(arr1), + sprout::end(arr1), + 5 + ); + TESTSPR_BOTH_ASSERT(result == 4); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::count( + sprout::begin(arr1), + sprout::end(arr1), + 11 + ); + TESTSPR_BOTH_ASSERT(result == 0); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::count( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + 5 + ); + TESTSPR_BOTH_ASSERT(result == 2); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::count( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + 11 + ); + TESTSPR_BOTH_ASSERT(result == 0); + } + } + } +} // namespace testspr + +#ifndef TESTSPR_CPP_INCLUDE +# define TESTSPR_TEST_FUNCTION testspr::algorithm_count_test +# include +#endif + +#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_COUNT_CPP diff --git a/libs/algorithm/test/count_if.cpp b/libs/algorithm/test/count_if.cpp new file mode 100644 index 00000000..ac61bfbf --- /dev/null +++ b/libs/algorithm/test/count_if.cpp @@ -0,0 +1,56 @@ +#ifndef SPROUT_LIBS_ALGORITHM_TEST_COUNT_IF_CPP +#define SPROUT_LIBS_ALGORITHM_TEST_COUNT_IF_CPP + +#include +#include +#include +#include + +namespace testspr { + static void algorithm_count_if_test() { + using namespace sprout; + { + SPROUT_STATIC_CONSTEXPR auto arr1 = array{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}; + + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::count_if( + sprout::begin(arr1), + sprout::end(arr1), + testspr::is_odd() + ); + TESTSPR_BOTH_ASSERT(result == 5); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::count_if( + sprout::begin(arr1), + sprout::end(arr1), + testspr::less_than(8) + ); + TESTSPR_BOTH_ASSERT(result == 7); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::count_if( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + testspr::is_odd() + ); + TESTSPR_BOTH_ASSERT(result == 3); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::count_if( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + testspr::less_than(8) + ); + TESTSPR_BOTH_ASSERT(result == 5); + } + } + } +} // namespace testspr + +#ifndef TESTSPR_CPP_INCLUDE +# define TESTSPR_TEST_FUNCTION testspr::algorithm_count_if_test +# include +#endif + +#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_COUNT_IF_CPP diff --git a/libs/algorithm/test/equal.cpp b/libs/algorithm/test/equal.cpp new file mode 100644 index 00000000..40f3a7c6 --- /dev/null +++ b/libs/algorithm/test/equal.cpp @@ -0,0 +1,95 @@ +#ifndef SPROUT_LIBS_ALGORITHM_TEST_EQUAL_CPP +#define SPROUT_LIBS_ALGORITHM_TEST_EQUAL_CPP + +#include +#include +#include +#include + +namespace testspr { + static void algorithm_equal_test() { + using namespace sprout; + { + SPROUT_STATIC_CONSTEXPR auto arr1 = array{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}; + SPROUT_STATIC_CONSTEXPR auto arr2 = array{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}; + SPROUT_STATIC_CONSTEXPR auto arr3 = array{{1, 2, 3, 4, 5, 6, 7, 10, 9, 8}}; + + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::equal( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr2) + ); + TESTSPR_BOTH_ASSERT(result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::equal( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr3) + ); + TESTSPR_BOTH_ASSERT(!result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::equal( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + sprout::begin(arr2) + ); + TESTSPR_BOTH_ASSERT(result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::equal( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + sprout::begin(arr3) + ); + TESTSPR_BOTH_ASSERT(result); + } + + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::equal( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr2), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::equal( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr3), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(!result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::equal( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + sprout::begin(arr2), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::equal( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + sprout::begin(arr3), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(result); + } + } + } +} // namespace testspr + +#ifndef TESTSPR_CPP_INCLUDE +# define TESTSPR_TEST_FUNCTION testspr::algorithm_equal_test +# include +#endif + +#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_EQUAL_CPP diff --git a/libs/algorithm/test/is_permutation.cpp b/libs/algorithm/test/is_permutation.cpp new file mode 100644 index 00000000..02c57d25 --- /dev/null +++ b/libs/algorithm/test/is_permutation.cpp @@ -0,0 +1,95 @@ +#ifndef SPROUT_LIBS_ALGORITHM_TEST_IS_PERMUTATION_CPP +#define SPROUT_LIBS_ALGORITHM_TEST_IS_PERMUTATION_CPP + +#include +#include +#include +#include + +namespace testspr { + static void algorithm_is_permutation_test() { + using namespace sprout; + { + SPROUT_STATIC_CONSTEXPR auto arr1 = array{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}; + SPROUT_STATIC_CONSTEXPR auto arr2 = array{{10, 9, 8, 1, 2, 3, 4, 5, 6, 7}}; + SPROUT_STATIC_CONSTEXPR auto arr3 = array{{5, 4, 3, 2, 1, 11, 10, 9, 8, 7}}; + + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::is_permutation( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr2) + ); + TESTSPR_BOTH_ASSERT(result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::is_permutation( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr3) + ); + TESTSPR_BOTH_ASSERT(!result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::is_permutation( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + sprout::begin(arr2) + ); + TESTSPR_BOTH_ASSERT(!result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::is_permutation( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + sprout::begin(arr3) + ); + TESTSPR_BOTH_ASSERT(result); + } + + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::is_permutation( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr2), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::is_permutation( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr3), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(!result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::is_permutation( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + sprout::begin(arr2), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(!result); + } + { + SPROUT_STATIC_CONSTEXPR auto result = sprout::is_permutation( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + sprout::begin(arr3), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(result); + } + } + } +} // namespace testspr + +#ifndef TESTSPR_CPP_INCLUDE +# define TESTSPR_TEST_FUNCTION testspr::algorithm_is_permutation_test +# include +#endif + +#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_IS_PERMUTATION_CPP diff --git a/libs/algorithm/test/mismatch.cpp b/libs/algorithm/test/mismatch.cpp new file mode 100644 index 00000000..07fef740 --- /dev/null +++ b/libs/algorithm/test/mismatch.cpp @@ -0,0 +1,95 @@ +#ifndef SPROUT_LIBS_ALGORITHM_TEST_MISMATCH_CPP +#define SPROUT_LIBS_ALGORITHM_TEST_MISMATCH_CPP + +#include +#include +#include +#include + +namespace testspr { + static void algorithm_mismatch_test() { + using namespace sprout; + { + SPROUT_STATIC_CONSTEXPR auto arr1 = array{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}; + SPROUT_STATIC_CONSTEXPR auto arr2 = array{{1, 2, 3, 4, 5, 6, 7, 10, 9, 8}}; + SPROUT_STATIC_CONSTEXPR auto arr3 = array{{10, 9, 8, 1, 2, 3, 4, 5, 6, 7}}; + + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr2) + ); + TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1) + 7); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr3) + ); + TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1)); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + sprout::begin(arr2) + ); + TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1) + 5); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + sprout::begin(arr3) + ); + TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1)); + } + + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr2), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1) + 7); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + sprout::begin(arr1), + sprout::end(arr1), + sprout::begin(arr3), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1)); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + sprout::begin(arr2), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1) + 5); + } + { + SPROUT_STATIC_CONSTEXPR auto found = sprout::mismatch( + sprout::begin(arr1), + sprout::begin(arr1) + 5, + sprout::begin(arr3), + testspr::equal_to() + ); + TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1)); + } + } + } +} // namespace testspr + +#ifndef TESTSPR_CPP_INCLUDE +# define TESTSPR_TEST_FUNCTION testspr::algorithm_mismatch_test +# include +#endif + +#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_MISMATCH_CPP diff --git a/libs/algorithm/test/non_modifying.cpp b/libs/algorithm/test/non_modifying.cpp index 3d68cf03..51435d14 100644 --- a/libs/algorithm/test/non_modifying.cpp +++ b/libs/algorithm/test/non_modifying.cpp @@ -16,6 +16,11 @@ #include "./find_end.cpp" #include "./find_first_of.cpp" #include "./adjacent_find.cpp" +#include "./count.cpp" +#include "./count_if.cpp" +#include "./mismatch.cpp" +#include "./equal.cpp" +#include "./is_permutation.cpp" #ifdef TESTSPR_CPP_INCLUDE_DISABLE_SPROUT_LIBS_ALGORITHM_TEST_NON_MODIFYIING_CPP # undef TESTSPR_CPP_INCLUDE @@ -33,6 +38,11 @@ namespace testspr { testspr::algorithm_find_end_test(); testspr::algorithm_find_first_of_test(); testspr::algorithm_adjacent_find_test(); + testspr::algorithm_count_test(); + testspr::algorithm_count_if_test(); + testspr::algorithm_mismatch_test(); + testspr::algorithm_equal_test(); + testspr::algorithm_is_permutation_test(); } } // namespace testspr diff --git a/sprout/algorithm/count.hpp b/sprout/algorithm/count.hpp index c5cacdef..2a2ba6e2 100644 --- a/sprout/algorithm/count.hpp +++ b/sprout/algorithm/count.hpp @@ -4,17 +4,65 @@ #include #include #include +#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT namespace sprout { - // Copyright (C) 2011 RiSK (sscrisk) + namespace detail { + template + inline SPROUT_CONSTEXPR typename std::iterator_traits::difference_type + count_impl_ra( + RandomAccessIterator first, RandomAccessIterator last, T const& value, + typename std::iterator_traits::difference_type pivot + ) + { + return pivot == 0 ? (*first == value ? 1 : 0) + : sprout::detail::count_impl_ra( + first, sprout::next(first, pivot), value, + pivot / 2 + ) + + sprout::detail::count_impl_ra( + sprout::next(first, pivot), last, value, + (NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) - pivot) / 2 + ) + ; + } + template + inline SPROUT_CONSTEXPR typename std::iterator_traits::difference_type + count( + RandomAccessIterator first, RandomAccessIterator last, T const& value, + std::random_access_iterator_tag* + ) + { + return first == last ? 0 + : sprout::detail::count_impl_ra(first, last, value, NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) / 2) + ; + } + + // Copyright (C) 2011 RiSK (sscrisk) + template + inline SPROUT_CONSTEXPR typename std::iterator_traits::difference_type + count_impl(InputIterator first, InputIterator last, T const& value) { + return first == last ? 0 + : (*first == value ? 1 : 0) + sprout::detail::count_impl(sprout::next(first), last, value) + ; + } + template + inline SPROUT_CONSTEXPR typename std::iterator_traits::difference_type + count( + InputIterator first, InputIterator last, T const& value, + void* + ) + { + return sprout::detail::count_impl(first, last, value); + } + } //namespace detail // 25.2.9 Count template inline SPROUT_CONSTEXPR typename std::iterator_traits::difference_type count(InputIterator first, InputIterator last, T const& value) { - return first == last ? 0 - : (*first == value ? 1 : 0) + sprout::count(sprout::next(first), last, value) - ; + typedef typename std::iterator_traits::iterator_category* category; + return sprout::detail::count(first, last, value, category()); } } // namespace sprout diff --git a/sprout/algorithm/count_if.hpp b/sprout/algorithm/count_if.hpp index 01aaf721..e49f9b77 100644 --- a/sprout/algorithm/count_if.hpp +++ b/sprout/algorithm/count_if.hpp @@ -4,17 +4,65 @@ #include #include #include +#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT namespace sprout { - // Copyright (C) 2011 RiSK (sscrisk) + namespace detail { + template + inline SPROUT_CONSTEXPR typename std::iterator_traits::difference_type + count_if_impl_ra( + RandomAccessIterator first, RandomAccessIterator last, Predicate pred, + typename std::iterator_traits::difference_type pivot + ) + { + return pivot == 0 ? (pred(*first) ? 1 : 0) + : sprout::detail::count_if_impl_ra( + first, sprout::next(first, pivot), pred, + pivot / 2 + ) + + sprout::detail::count_if_impl_ra( + sprout::next(first, pivot), last, pred, + (NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) - pivot) / 2 + ) + ; + } + template + inline SPROUT_CONSTEXPR typename std::iterator_traits::difference_type + count_if( + RandomAccessIterator first, RandomAccessIterator last, Predicate pred, + std::random_access_iterator_tag* + ) + { + return first == last ? 0 + : sprout::detail::count_if_impl_ra(first, last, pred, NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) / 2) + ; + } + + // Copyright (C) 2011 RiSK (sscrisk) + template + inline SPROUT_CONSTEXPR typename std::iterator_traits::difference_type + count_if_impl(InputIterator first, InputIterator last, Predicate pred) { + return first == last ? 0 + : (pred(*first) ? 1 : 0) + sprout::detail::count_if_impl(sprout::next(first), last, pred) + ; + } + template + inline SPROUT_CONSTEXPR typename std::iterator_traits::difference_type + count_if( + InputIterator first, InputIterator last, Predicate pred, + void* + ) + { + return sprout::detail::count_if_impl(first, last, pred); + } + } //namespace detail // 25.2.9 Count template inline SPROUT_CONSTEXPR typename std::iterator_traits::difference_type count_if(InputIterator first, InputIterator last, Predicate pred) { - return first == last ? 0 - : (pred(*first) ? 1 : 0) + sprout::count_if(sprout::next(first), last, pred) - ; + typedef typename std::iterator_traits::iterator_category* category; + return sprout::detail::count_if(first, last, pred, category()); } } // namespace sprout diff --git a/sprout/algorithm/equal.hpp b/sprout/algorithm/equal.hpp index 2b98ff57..daabd085 100644 --- a/sprout/algorithm/equal.hpp +++ b/sprout/algorithm/equal.hpp @@ -1,27 +1,78 @@ #ifndef SPROUT_ALGORITHM_EQUAL_HPP #define SPROUT_ALGORITHM_EQUAL_HPP +#include #include #include +#include +#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT namespace sprout { - // Copyright (C) 2011 RiSK (sscrisk) + namespace detail { + template + inline SPROUT_CONSTEXPR bool + equal_impl_ra( + RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, BinaryPredicate pred, + typename std::iterator_traits::difference_type pivot + ) + { + return pivot == 0 ? pred(*first1, *first2) + : sprout::detail::equal_impl_ra( + first1, sprout::next(first1, pivot), first2, pred, + pivot / 2 + ) + && sprout::detail::equal_impl_ra( + sprout::next(first1, pivot), last1, sprout::next(first2, pivot), pred, + (NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1) - pivot) / 2 + ) + ; + } + template + inline SPROUT_CONSTEXPR bool + equal( + RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, BinaryPredicate pred, + std::random_access_iterator_tag* + ) + { + return first1 == last1 ? true + : sprout::detail::equal_impl_ra( + first1, last1, first2, pred, + NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1) / 2 + ) + ; + } + + // Copyright (C) 2011 RiSK (sscrisk) + template + inline SPROUT_CONSTEXPR bool + equal_impl(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred) { + return first1 == last1 ? true + : pred(*first1, *first2) && sprout::detail::equal_impl(sprout::next(first1), last1, sprout::next(first2), pred) + ; + } + template + inline SPROUT_CONSTEXPR bool + equal( + InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred, + void* + ) + { + return sprout::detail::equal_impl(first1, last1, first2, pred); + } + } //namespace detail // 25.2.11 Equal - template - inline SPROUT_CONSTEXPR bool - equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2) { - return first1 == last1 ? true - : *first1 == *first2 && sprout::equal(sprout::next(first1), last1, sprout::next(first2)) - ; - } - template inline SPROUT_CONSTEXPR bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred) { - return first1 == last1 ? true - : pred(*first1, *first2) && sprout::equal(sprout::next(first1), last1, sprout::next(first2), pred) - ; + typedef typename sprout::common_iterator_category::type* category; + return sprout::detail::equal(first1, last1, first2, pred, category()); + } + + template + inline SPROUT_CONSTEXPR bool + equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2) { + return sprout::equal(first1, last1, first2, sprout::equal_to<>()); } } // namespace sprout diff --git a/sprout/algorithm/find_end.hpp b/sprout/algorithm/find_end.hpp index 962e9dff..87e03b2c 100644 --- a/sprout/algorithm/find_end.hpp +++ b/sprout/algorithm/find_end.hpp @@ -4,25 +4,9 @@ #include #include #include +#include namespace sprout { - namespace detail { - // Copyright (C) 2011 RiSK (sscrisk) - - template - struct iter_equal_to { - public: - SPROUT_CONSTEXPR bool - operator()( - typename std::iterator_traits::value_type const& x, - typename std::iterator_traits::value_type const& y - ) const - { - return x == y; - } - }; - } // namespace detail - namespace detail { template inline SPROUT_CONSTEXPR ForwardIterator1 @@ -81,7 +65,7 @@ namespace sprout { return sprout::find_end( first1, last1, first2, last2, - sprout::detail::iter_equal_to() + sprout::equal_to<>() ); } } // namespace sprout diff --git a/sprout/algorithm/find_first_of.hpp b/sprout/algorithm/find_first_of.hpp index 5ae371ab..2ddd934f 100644 --- a/sprout/algorithm/find_first_of.hpp +++ b/sprout/algorithm/find_first_of.hpp @@ -5,8 +5,9 @@ #include #include #include +#include +#include #include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT -#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT namespace sprout { namespace detail { @@ -20,7 +21,7 @@ namespace sprout { ) { return found != first1 ? found - : pivot == 0 ? sprout::find_if(first2, last2, NS_SSCRISK_CEL_OR_SPROUT::bind2nd(pred, *first1)) != last2 ? first1 : last1 + : pivot == 0 ? sprout::find_if(first2, last2, sprout::bind2nd(pred, *first1)) != last2 ? first1 : last1 : sprout::detail::find_first_of_impl_ra( sprout::next(first1, pivot), last1, first2, last2, pred, (NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1) - pivot) / 2, @@ -58,7 +59,7 @@ namespace sprout { BinaryPredicate pred ) { - return first1 == last1 || sprout::find_if(first2, last2, NS_SSCRISK_CEL_OR_SPROUT::bind2nd(pred, *first1)) != last2 ? first1 + return first1 == last1 || sprout::find_if(first2, last2, sprout::bind2nd(pred, *first1)) != last2 ? first1 : sprout::detail::find_first_of_impl(sprout::next(first1), last1, first2, last2, pred) ; } diff --git a/sprout/algorithm/is_permutation.hpp b/sprout/algorithm/is_permutation.hpp index 37866193..0eba4f5b 100644 --- a/sprout/algorithm/is_permutation.hpp +++ b/sprout/algorithm/is_permutation.hpp @@ -1,65 +1,92 @@ #ifndef SPROUT_ALGORITHM_IS_PERMUTATION_HPP #define SPROUT_ALGORITHM_IS_PERMUTATION_HPP +#include #include #include -#include +#include +#include #include #include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT -#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT namespace sprout { - // Copyright (C) 2011 RiSK (sscrisk) - namespace detail { - template + template inline SPROUT_CONSTEXPR bool - is_permutation_impl( - ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator1 first1_ + is_permutation_impl_ra( + RandomAccessIterator1 first1, RandomAccessIterator1 last1, + RandomAccessIterator2 first2, RandomAccessIterator2 last2, + BinaryPredicate pred, + typename std::iterator_traits::difference_type pivot ) { - return first1_ == last1 ? true - : sprout::count(first1, last1, *first1_) - == sprout::count(first2, sprout::next(first2, NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1)), *first1_) - && sprout::detail::is_permutation_impl(first1, last1, first2, sprout::next(first1_)) - ? true - : false + return pivot == 0 ? sprout::count_if(first1, last1, sprout::bind2nd(pred, *first1)) + <= sprout::count_if(first2, last2, sprout::bind2nd(pred, *first1)) + : sprout::detail::is_permutation_impl_ra( + first1, last1, first2, last2, + pred, pivot / 2 + ) + && sprout::detail::is_permutation_impl_ra( + sprout::next(first1, pivot), last1, first2, last2, + pred, (NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1) - pivot) / 2 + ) + ; + } + template + inline SPROUT_CONSTEXPR bool + is_permutation( + RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, BinaryPredicate pred, + std::random_access_iterator_tag* + ) + { + return first1 == last1 ? true + : sprout::detail::is_permutation_impl_ra( + first1, last1, first2, sprout::next(first2, NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1)), + pred, NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1) / 2 + ) ; } + // Copyright (C) 2011 RiSK (sscrisk) template inline SPROUT_CONSTEXPR bool is_permutation_impl( ForwardIterator1 first1, ForwardIterator1 last1, - ForwardIterator2 first2, ForwardIterator1 first1_, + ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred ) { - return first1_ == last1 ? true - : sprout::count_if(first1, last1, NS_SSCRISK_CEL_OR_SPROUT::bind2nd(pred, *first1_)) - == sprout::count_if( - first2, sprout::next(first2, NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1)), - NS_SSCRISK_CEL_OR_SPROUT::bind2nd(pred, *first1_) - ) - && sprout::detail::is_permutation_impl(first1, last1, first2, sprout::next(first1_), pred) - ? true - : false + return first1 == last1 ? true + : sprout::count_if(first1, last1, sprout::bind2nd(pred, *first1)) + <= sprout::count_if(first2, last2, sprout::bind2nd(pred, *first1)) + && sprout::detail::is_permutation_impl(sprout::next(first1), last1, first2, last2, pred) ; } + template + inline SPROUT_CONSTEXPR bool + is_permutation( + ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, BinaryPredicate pred, + void* + ) + { + return sprout::detail::is_permutation_impl( + first1, last1, first2, sprout::next(first2, NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1)), pred + ); + } } // namespace detail // 25.2.12 Is permutation - template - inline SPROUT_CONSTEXPR bool - is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2) { - return sprout::detail::is_permutation_impl(first1, last1, first2, first1); - } - template inline SPROUT_CONSTEXPR bool is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, BinaryPredicate pred) { - return sprout::detail::is_permutation_impl(first1, last1, first2, first1, pred); + typedef typename sprout::common_iterator_category::type* category; + return sprout::detail::is_permutation(first1, last1, first2, pred, category()); + } + + template + inline SPROUT_CONSTEXPR bool + is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2) { + return sprout::is_permutation(first1, last1, first2, sprout::equal_to<>()); } } // namespace sprout diff --git a/sprout/algorithm/mismatch.hpp b/sprout/algorithm/mismatch.hpp index 888cbf4e..8ba6c148 100644 --- a/sprout/algorithm/mismatch.hpp +++ b/sprout/algorithm/mismatch.hpp @@ -1,30 +1,92 @@ #ifndef SPROUT_ALGORITHM_MISMATCH_HPP #define SPROUT_ALGORITHM_MISMATCH_HPP +#include #include -#include #include +#include +#include +#include +#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT namespace sprout { - // Copyright (C) 2011 RiSK (sscrisk) + namespace detail { + template + inline SPROUT_CONSTEXPR sprout::pair + mismatch_impl_ra_1(RandomAccessIterator1 first1, RandomAccessIterator2 first2, RandomAccessIterator1 found) { + return sprout::pair{ + found, sprout::next(first2, NS_SSCRISK_CEL_OR_SPROUT::distance(first1, found)) + }; + } + template + inline SPROUT_CONSTEXPR RandomAccessIterator1 + mismatch_impl_ra( + RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, BinaryPredicate pred, + typename std::iterator_traits::difference_type pivot, RandomAccessIterator1 found + ) + { + return found != first1 ? found + : pivot == 0 ? (!pred(*first1, *first2) ? first1 : last1) + : sprout::detail::mismatch_impl_ra( + sprout::next(first1, pivot), last1, sprout::next(first2, pivot), pred, + (NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1) - pivot) / 2, + sprout::detail::mismatch_impl_ra( + first1, sprout::next(first1, pivot), first2, pred, + pivot / 2, + first1 + ) + ) + ; + } + template + inline SPROUT_CONSTEXPR sprout::pair + mismatch( + RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, BinaryPredicate pred, + std::random_access_iterator_tag* + ) + { + return first1 == last1 ? sprout::pair{first1, first2} + : sprout::detail::mismatch_impl_ra_1( + first1, first2, + sprout::detail::mismatch_impl_ra( + first1, last1, first2, pred, + NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1) / 2, first1 + ) + ) + ; + } + + // Copyright (C) 2011 RiSK (sscrisk) + template + inline SPROUT_CONSTEXPR sprout::pair + mismatch_impl(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred) { + return first1 == last1 || !pred(*first1, *first2) + ? sprout::pair{first1, first2} + : sprout::detail::mismatch_impl(sprout::next(first1), last1, sprout::next(first2)) + ; + } + template + inline SPROUT_CONSTEXPR sprout::pair + mismatch( + InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred, + void* + ) + { + return sprout::detail::mismatch_impl(first1, last1, first2, pred); + } + } //namespace detail // 25.2.10 Mismatch - template - inline SPROUT_CONSTEXPR sprout::pair - mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2) { - return first1 == last1 || !(*first1 == *first2) - ? sprout::pair{first1, first2} - : sprout::mismatch(sprout::next(first1), last1, sprout::next(first2)) - ; - } - template inline SPROUT_CONSTEXPR sprout::pair mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred) { - return first1 == last1 || !pred(*first1, *first2) - ? sprout::pair{first1, first2} - : sprout::mismatch(sprout::next(first1), last1, sprout::next(first2)) - ; + typedef typename sprout::common_iterator_category::type* category; + return sprout::detail::mismatch(first1, last1, first2, pred, category()); + } + template + inline SPROUT_CONSTEXPR sprout::pair + mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2) { + return sprout::mismatch(first1, last1, first2, sprout::equal_to<>()); } } // namespace sprout diff --git a/sprout/detail/pow.hpp b/sprout/detail/pow.hpp index 020209cd..41a90e8d 100644 --- a/sprout/detail/pow.hpp +++ b/sprout/detail/pow.hpp @@ -1,5 +1,6 @@ #ifndef SPROUT_DETAIL_POW_HPP #define SPROUT_DETAIL_POW_HPP + #include namespace sprout {