fix recursion depth: count, count_if, mismatch, equal, is_permutation

This commit is contained in:
bolero-MURAKAMI 2012-12-12 01:47:14 +09:00
parent b5bdde21c4
commit 75228465fe
14 changed files with 716 additions and 87 deletions

View file

@ -0,0 +1,56 @@
#ifndef SPROUT_LIBS_ALGORITHM_TEST_COUNT_CPP
#define SPROUT_LIBS_ALGORITHM_TEST_COUNT_CPP
#include <sprout/algorithm/count.hpp>
#include <sprout/array.hpp>
#include <sprout/container.hpp>
#include <testspr/tools.hpp>
namespace testspr {
static void algorithm_count_test() {
using namespace sprout;
{
SPROUT_STATIC_CONSTEXPR auto arr1 = array<int, 10>{{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 <testspr/include_main.hpp>
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_COUNT_CPP

View file

@ -0,0 +1,56 @@
#ifndef SPROUT_LIBS_ALGORITHM_TEST_COUNT_IF_CPP
#define SPROUT_LIBS_ALGORITHM_TEST_COUNT_IF_CPP
#include <sprout/algorithm/count_if.hpp>
#include <sprout/array.hpp>
#include <sprout/container.hpp>
#include <testspr/tools.hpp>
namespace testspr {
static void algorithm_count_if_test() {
using namespace sprout;
{
SPROUT_STATIC_CONSTEXPR auto arr1 = array<int, 10>{{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<int>()
);
TESTSPR_BOTH_ASSERT(result == 5);
}
{
SPROUT_STATIC_CONSTEXPR auto result = sprout::count_if(
sprout::begin(arr1),
sprout::end(arr1),
testspr::less_than<int>(8)
);
TESTSPR_BOTH_ASSERT(result == 7);
}
{
SPROUT_STATIC_CONSTEXPR auto result = sprout::count_if(
sprout::begin(arr1),
sprout::begin(arr1) + 5,
testspr::is_odd<int>()
);
TESTSPR_BOTH_ASSERT(result == 3);
}
{
SPROUT_STATIC_CONSTEXPR auto result = sprout::count_if(
sprout::begin(arr1),
sprout::begin(arr1) + 5,
testspr::less_than<int>(8)
);
TESTSPR_BOTH_ASSERT(result == 5);
}
}
}
} // namespace testspr
#ifndef TESTSPR_CPP_INCLUDE
# define TESTSPR_TEST_FUNCTION testspr::algorithm_count_if_test
# include <testspr/include_main.hpp>
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_COUNT_IF_CPP

View file

@ -0,0 +1,95 @@
#ifndef SPROUT_LIBS_ALGORITHM_TEST_EQUAL_CPP
#define SPROUT_LIBS_ALGORITHM_TEST_EQUAL_CPP
#include <sprout/algorithm/equal.hpp>
#include <sprout/array.hpp>
#include <sprout/container.hpp>
#include <testspr/tools.hpp>
namespace testspr {
static void algorithm_equal_test() {
using namespace sprout;
{
SPROUT_STATIC_CONSTEXPR auto arr1 = array<int, 10>{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}};
SPROUT_STATIC_CONSTEXPR auto arr2 = array<int, 10>{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}};
SPROUT_STATIC_CONSTEXPR auto arr3 = array<int, 10>{{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<int>()
);
TESTSPR_BOTH_ASSERT(result);
}
{
SPROUT_STATIC_CONSTEXPR auto result = sprout::equal(
sprout::begin(arr1),
sprout::end(arr1),
sprout::begin(arr3),
testspr::equal_to<int>()
);
TESTSPR_BOTH_ASSERT(!result);
}
{
SPROUT_STATIC_CONSTEXPR auto result = sprout::equal(
sprout::begin(arr1),
sprout::begin(arr1) + 5,
sprout::begin(arr2),
testspr::equal_to<int>()
);
TESTSPR_BOTH_ASSERT(result);
}
{
SPROUT_STATIC_CONSTEXPR auto result = sprout::equal(
sprout::begin(arr1),
sprout::begin(arr1) + 5,
sprout::begin(arr3),
testspr::equal_to<int>()
);
TESTSPR_BOTH_ASSERT(result);
}
}
}
} // namespace testspr
#ifndef TESTSPR_CPP_INCLUDE
# define TESTSPR_TEST_FUNCTION testspr::algorithm_equal_test
# include <testspr/include_main.hpp>
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_EQUAL_CPP

View file

@ -0,0 +1,95 @@
#ifndef SPROUT_LIBS_ALGORITHM_TEST_IS_PERMUTATION_CPP
#define SPROUT_LIBS_ALGORITHM_TEST_IS_PERMUTATION_CPP
#include <sprout/algorithm/is_permutation.hpp>
#include <sprout/array.hpp>
#include <sprout/container.hpp>
#include <testspr/tools.hpp>
namespace testspr {
static void algorithm_is_permutation_test() {
using namespace sprout;
{
SPROUT_STATIC_CONSTEXPR auto arr1 = array<int, 10>{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}};
SPROUT_STATIC_CONSTEXPR auto arr2 = array<int, 10>{{10, 9, 8, 1, 2, 3, 4, 5, 6, 7}};
SPROUT_STATIC_CONSTEXPR auto arr3 = array<int, 10>{{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<int>()
);
TESTSPR_BOTH_ASSERT(result);
}
{
SPROUT_STATIC_CONSTEXPR auto result = sprout::is_permutation(
sprout::begin(arr1),
sprout::end(arr1),
sprout::begin(arr3),
testspr::equal_to<int>()
);
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<int>()
);
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<int>()
);
TESTSPR_BOTH_ASSERT(result);
}
}
}
} // namespace testspr
#ifndef TESTSPR_CPP_INCLUDE
# define TESTSPR_TEST_FUNCTION testspr::algorithm_is_permutation_test
# include <testspr/include_main.hpp>
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_IS_PERMUTATION_CPP

View file

@ -0,0 +1,95 @@
#ifndef SPROUT_LIBS_ALGORITHM_TEST_MISMATCH_CPP
#define SPROUT_LIBS_ALGORITHM_TEST_MISMATCH_CPP
#include <sprout/algorithm/mismatch.hpp>
#include <sprout/array.hpp>
#include <sprout/container.hpp>
#include <testspr/tools.hpp>
namespace testspr {
static void algorithm_mismatch_test() {
using namespace sprout;
{
SPROUT_STATIC_CONSTEXPR auto arr1 = array<int, 10>{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}};
SPROUT_STATIC_CONSTEXPR auto arr2 = array<int, 10>{{1, 2, 3, 4, 5, 6, 7, 10, 9, 8}};
SPROUT_STATIC_CONSTEXPR auto arr3 = array<int, 10>{{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<int>()
);
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<int>()
);
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<int>()
);
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<int>()
);
TESTSPR_BOTH_ASSERT(found.first == sprout::begin(arr1));
}
}
}
} // namespace testspr
#ifndef TESTSPR_CPP_INCLUDE
# define TESTSPR_TEST_FUNCTION testspr::algorithm_mismatch_test
# include <testspr/include_main.hpp>
#endif
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_MISMATCH_CPP

View file

@ -16,6 +16,11 @@
#include "./find_end.cpp" #include "./find_end.cpp"
#include "./find_first_of.cpp" #include "./find_first_of.cpp"
#include "./adjacent_find.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 #ifdef TESTSPR_CPP_INCLUDE_DISABLE_SPROUT_LIBS_ALGORITHM_TEST_NON_MODIFYIING_CPP
# undef TESTSPR_CPP_INCLUDE # undef TESTSPR_CPP_INCLUDE
@ -33,6 +38,11 @@ namespace testspr {
testspr::algorithm_find_end_test(); testspr::algorithm_find_end_test();
testspr::algorithm_find_first_of_test(); testspr::algorithm_find_first_of_test();
testspr::algorithm_adjacent_find_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 } // namespace testspr

View file

@ -4,17 +4,65 @@
#include <iterator> #include <iterator>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT
namespace sprout { namespace sprout {
// Copyright (C) 2011 RiSK (sscrisk) namespace detail {
template<typename RandomAccessIterator, typename T>
inline SPROUT_CONSTEXPR typename std::iterator_traits<RandomAccessIterator>::difference_type
count_impl_ra(
RandomAccessIterator first, RandomAccessIterator last, T const& value,
typename std::iterator_traits<RandomAccessIterator>::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<typename RandomAccessIterator, typename T>
inline SPROUT_CONSTEXPR typename std::iterator_traits<RandomAccessIterator>::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<typename InputIterator, typename T>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::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<typename InputIterator, typename T>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::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 // 25.2.9 Count
template<typename InputIterator, typename T> template<typename InputIterator, typename T>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
count(InputIterator first, InputIterator last, T const& value) { count(InputIterator first, InputIterator last, T const& value) {
return first == last ? 0 typedef typename std::iterator_traits<InputIterator>::iterator_category* category;
: (*first == value ? 1 : 0) + sprout::count(sprout::next(first), last, value) return sprout::detail::count(first, last, value, category());
;
} }
} // namespace sprout } // namespace sprout

View file

@ -4,17 +4,65 @@
#include <iterator> #include <iterator>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT
namespace sprout { namespace sprout {
// Copyright (C) 2011 RiSK (sscrisk) namespace detail {
template<typename RandomAccessIterator, typename Predicate>
inline SPROUT_CONSTEXPR typename std::iterator_traits<RandomAccessIterator>::difference_type
count_if_impl_ra(
RandomAccessIterator first, RandomAccessIterator last, Predicate pred,
typename std::iterator_traits<RandomAccessIterator>::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<typename RandomAccessIterator, typename Predicate>
inline SPROUT_CONSTEXPR typename std::iterator_traits<RandomAccessIterator>::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<typename InputIterator, typename Predicate>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::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<typename InputIterator, typename Predicate>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::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 // 25.2.9 Count
template<typename InputIterator, typename Predicate> template<typename InputIterator, typename Predicate>
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
count_if(InputIterator first, InputIterator last, Predicate pred) { count_if(InputIterator first, InputIterator last, Predicate pred) {
return first == last ? 0 typedef typename std::iterator_traits<InputIterator>::iterator_category* category;
: (pred(*first) ? 1 : 0) + sprout::count_if(sprout::next(first), last, pred) return sprout::detail::count_if(first, last, pred, category());
;
} }
} // namespace sprout } // namespace sprout

View file

@ -1,27 +1,78 @@
#ifndef SPROUT_ALGORITHM_EQUAL_HPP #ifndef SPROUT_ALGORITHM_EQUAL_HPP
#define SPROUT_ALGORITHM_EQUAL_HPP #define SPROUT_ALGORITHM_EQUAL_HPP
#include <iterator>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/functional/equal_to.hpp>
#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT
namespace sprout { namespace sprout {
// Copyright (C) 2011 RiSK (sscrisk) namespace detail {
template<typename RandomAccessIterator1, typename RandomAccessIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR bool
equal_impl_ra(
RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, BinaryPredicate pred,
typename std::iterator_traits<RandomAccessIterator1>::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<typename RandomAccessIterator1, typename RandomAccessIterator2, typename BinaryPredicate>
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<typename InputIterator1, typename InputIterator2, typename BinaryPredicate>
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<typename InputIterator1, typename InputIterator2, typename BinaryPredicate>
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 // 25.2.11 Equal
template<typename InputIterator1, typename InputIterator2>
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<typename InputIterator1, typename InputIterator2, typename BinaryPredicate> template<typename InputIterator1, typename InputIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR bool inline SPROUT_CONSTEXPR bool
equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred) { equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred) {
return first1 == last1 ? true typedef typename sprout::common_iterator_category<InputIterator1, InputIterator2>::type* category;
: pred(*first1, *first2) && sprout::equal(sprout::next(first1), last1, sprout::next(first2), pred) return sprout::detail::equal(first1, last1, first2, pred, category());
; }
template<typename InputIterator1, typename InputIterator2>
inline SPROUT_CONSTEXPR bool
equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2) {
return sprout::equal(first1, last1, first2, sprout::equal_to<>());
} }
} // namespace sprout } // namespace sprout

View file

@ -4,25 +4,9 @@
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/algorithm/search.hpp> #include <sprout/algorithm/search.hpp>
#include <sprout/functional/equal_to.hpp>
namespace sprout { namespace sprout {
namespace detail {
// Copyright (C) 2011 RiSK (sscrisk)
template<typename Iterator1, typename Iterator2>
struct iter_equal_to {
public:
SPROUT_CONSTEXPR bool
operator()(
typename std::iterator_traits<Iterator1>::value_type const& x,
typename std::iterator_traits<Iterator2>::value_type const& y
) const
{
return x == y;
}
};
} // namespace detail
namespace detail { namespace detail {
template<typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate> template<typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR ForwardIterator1 inline SPROUT_CONSTEXPR ForwardIterator1
@ -81,7 +65,7 @@ namespace sprout {
return sprout::find_end( return sprout::find_end(
first1, last1, first1, last1,
first2, last2, first2, last2,
sprout::detail::iter_equal_to<ForwardIterator1, ForwardIterator2>() sprout::equal_to<>()
); );
} }
} // namespace sprout } // namespace sprout

View file

@ -5,8 +5,9 @@
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/functional/equal_to.hpp> #include <sprout/functional/equal_to.hpp>
#include <sprout/functional/bind2nd.hpp>
#include <sprout/algorithm/find_if.hpp>
#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT #include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
namespace sprout { namespace sprout {
namespace detail { namespace detail {
@ -20,7 +21,7 @@ namespace sprout {
) )
{ {
return found != first1 ? found 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::detail::find_first_of_impl_ra(
sprout::next(first1, pivot), last1, first2, last2, pred, sprout::next(first1, pivot), last1, first2, last2, pred,
(NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1) - pivot) / 2, (NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1) - pivot) / 2,
@ -58,7 +59,7 @@ namespace sprout {
BinaryPredicate pred 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) : sprout::detail::find_first_of_impl(sprout::next(first1), last1, first2, last2, pred)
; ;
} }

View file

@ -1,65 +1,92 @@
#ifndef SPROUT_ALGORITHM_IS_PERMUTATION_HPP #ifndef SPROUT_ALGORITHM_IS_PERMUTATION_HPP
#define SPROUT_ALGORITHM_IS_PERMUTATION_HPP #define SPROUT_ALGORITHM_IS_PERMUTATION_HPP
#include <iterator>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/algorithm/count.hpp> #include <sprout/functional/equal_to.hpp>
#include <sprout/functional/bind2nd.hpp>
#include <sprout/algorithm/count_if.hpp> #include <sprout/algorithm/count_if.hpp>
#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT #include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
namespace sprout { namespace sprout {
// Copyright (C) 2011 RiSK (sscrisk)
namespace detail { namespace detail {
template<typename ForwardIterator1, typename ForwardIterator2> template<typename RandomAccessIterator1, typename RandomAccessIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR bool inline SPROUT_CONSTEXPR bool
is_permutation_impl( is_permutation_impl_ra(
ForwardIterator1 first1, ForwardIterator1 last1, RandomAccessIterator1 first1, RandomAccessIterator1 last1,
ForwardIterator2 first2, ForwardIterator1 first1_ RandomAccessIterator2 first2, RandomAccessIterator2 last2,
BinaryPredicate pred,
typename std::iterator_traits<RandomAccessIterator1>::difference_type pivot
) )
{ {
return first1_ == last1 ? true return pivot == 0 ? sprout::count_if(first1, last1, sprout::bind2nd(pred, *first1))
: sprout::count(first1, last1, *first1_) <= sprout::count_if(first2, last2, sprout::bind2nd(pred, *first1))
== sprout::count(first2, sprout::next(first2, NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1)), *first1_) : sprout::detail::is_permutation_impl_ra(
&& sprout::detail::is_permutation_impl(first1, last1, first2, sprout::next(first1_)) first1, last1, first2, last2,
? true pred, pivot / 2
: false )
&& 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<typename RandomAccessIterator1, typename RandomAccessIterator2, typename BinaryPredicate>
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<typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate> template<typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR bool inline SPROUT_CONSTEXPR bool
is_permutation_impl( is_permutation_impl(
ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator1 first1_, ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate pred BinaryPredicate pred
) )
{ {
return first1_ == last1 ? true return first1 == last1 ? true
: sprout::count_if(first1, last1, NS_SSCRISK_CEL_OR_SPROUT::bind2nd(pred, *first1_)) : sprout::count_if(first1, last1, sprout::bind2nd(pred, *first1))
== sprout::count_if( <= sprout::count_if(first2, last2, sprout::bind2nd(pred, *first1))
first2, sprout::next(first2, NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1)), && sprout::detail::is_permutation_impl(sprout::next(first1), last1, first2, last2, pred)
NS_SSCRISK_CEL_OR_SPROUT::bind2nd(pred, *first1_)
)
&& sprout::detail::is_permutation_impl(first1, last1, first2, sprout::next(first1_), pred)
? true
: false
; ;
} }
template<typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate>
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 } // namespace detail
// 25.2.12 Is permutation // 25.2.12 Is permutation
template<typename ForwardIterator1, typename ForwardIterator2>
inline SPROUT_CONSTEXPR bool
is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2) {
return sprout::detail::is_permutation_impl(first1, last1, first2, first1);
}
template<typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate> template<typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR bool inline SPROUT_CONSTEXPR bool
is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, BinaryPredicate pred) { 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<ForwardIterator1, ForwardIterator2>::type* category;
return sprout::detail::is_permutation(first1, last1, first2, pred, category());
}
template<typename ForwardIterator1, typename ForwardIterator2>
inline SPROUT_CONSTEXPR bool
is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2) {
return sprout::is_permutation(first1, last1, first2, sprout::equal_to<>());
} }
} // namespace sprout } // namespace sprout

View file

@ -1,30 +1,92 @@
#ifndef SPROUT_ALGORITHM_MISMATCH_HPP #ifndef SPROUT_ALGORITHM_MISMATCH_HPP
#define SPROUT_ALGORITHM_MISMATCH_HPP #define SPROUT_ALGORITHM_MISMATCH_HPP
#include <iterator>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/utility/pair.hpp> #include <sprout/utility/pair.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/iterator/type_traits/common.hpp>
#include <sprout/functional/equal_to.hpp>
#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT
namespace sprout { namespace sprout {
// Copyright (C) 2011 RiSK (sscrisk) namespace detail {
template<typename RandomAccessIterator1, typename RandomAccessIterator2>
inline SPROUT_CONSTEXPR sprout::pair<RandomAccessIterator1, RandomAccessIterator2>
mismatch_impl_ra_1(RandomAccessIterator1 first1, RandomAccessIterator2 first2, RandomAccessIterator1 found) {
return sprout::pair<RandomAccessIterator1, RandomAccessIterator2>{
found, sprout::next(first2, NS_SSCRISK_CEL_OR_SPROUT::distance(first1, found))
};
}
template<typename RandomAccessIterator1, typename RandomAccessIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR RandomAccessIterator1
mismatch_impl_ra(
RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, BinaryPredicate pred,
typename std::iterator_traits<RandomAccessIterator1>::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<typename RandomAccessIterator1, typename RandomAccessIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR sprout::pair<RandomAccessIterator1, RandomAccessIterator2>
mismatch(
RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, BinaryPredicate pred,
std::random_access_iterator_tag*
)
{
return first1 == last1 ? sprout::pair<RandomAccessIterator1, RandomAccessIterator2>{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<typename InputIterator1, typename InputIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR sprout::pair<InputIterator1, InputIterator2>
mismatch_impl(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred) {
return first1 == last1 || !pred(*first1, *first2)
? sprout::pair<InputIterator1, InputIterator2>{first1, first2}
: sprout::detail::mismatch_impl(sprout::next(first1), last1, sprout::next(first2))
;
}
template<typename InputIterator1, typename InputIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR sprout::pair<InputIterator1, InputIterator2>
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 // 25.2.10 Mismatch
template<typename InputIterator1, typename InputIterator2>
inline SPROUT_CONSTEXPR sprout::pair<InputIterator1, InputIterator2>
mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2) {
return first1 == last1 || !(*first1 == *first2)
? sprout::pair<InputIterator1, InputIterator2>{first1, first2}
: sprout::mismatch(sprout::next(first1), last1, sprout::next(first2))
;
}
template<typename InputIterator1, typename InputIterator2, typename BinaryPredicate> template<typename InputIterator1, typename InputIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR sprout::pair<InputIterator1, InputIterator2> inline SPROUT_CONSTEXPR sprout::pair<InputIterator1, InputIterator2>
mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred) { mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred) {
return first1 == last1 || !pred(*first1, *first2) typedef typename sprout::common_iterator_category<InputIterator1, InputIterator2>::type* category;
? sprout::pair<InputIterator1, InputIterator2>{first1, first2} return sprout::detail::mismatch(first1, last1, first2, pred, category());
: sprout::mismatch(sprout::next(first1), last1, sprout::next(first2)) }
; template<typename InputIterator1, typename InputIterator2>
inline SPROUT_CONSTEXPR sprout::pair<InputIterator1, InputIterator2>
mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2) {
return sprout::mismatch(first1, last1, first2, sprout::equal_to<>());
} }
} // namespace sprout } // namespace sprout

View file

@ -1,5 +1,6 @@
#ifndef SPROUT_DETAIL_POW_HPP #ifndef SPROUT_DETAIL_POW_HPP
#define SPROUT_DETAIL_POW_HPP #define SPROUT_DETAIL_POW_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
namespace sprout { namespace sprout {