1
0
Fork 0
mirror of https://github.com/bolero-MURAKAMI/Sprout synced 2025-08-03 12:49:50 +00:00

fix recursion depth: find_first_of, adjacent_find

This commit is contained in:
bolero-MURAKAMI 2012-12-11 12:59:36 +09:00
parent 54400ea7d0
commit b5bdde21c4
10 changed files with 455 additions and 29 deletions

View file

@ -7,16 +7,80 @@
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
namespace sprout {
// Copyright (C) 2011 RiSK (sscrisk)
namespace detail {
template<typename RandomAccessIterator>
inline SPROUT_CONSTEXPR RandomAccessIterator
adjacent_find_impl_ra_1(RandomAccessIterator found, RandomAccessIterator last) {
return NS_SSCRISK_CEL_OR_SPROUT::distance(found, last) == 1 ? last
: found
;
}
template<typename RandomAccessIterator, typename BinaryPredicate>
inline SPROUT_CONSTEXPR RandomAccessIterator
adjacent_find_impl_ra(
RandomAccessIterator first, RandomAccessIterator last, BinaryPredicate pred,
typename std::iterator_traits<RandomAccessIterator>::difference_type pivot, RandomAccessIterator found
)
{
return found != first ? found
: pivot == 0 ? (pred(*first, *last) ? first : last)
: sprout::detail::adjacent_find_impl_ra(
sprout::next(first, pivot), last, pred,
(NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) - pivot) / 2,
sprout::detail::adjacent_find_impl_ra(
first, sprout::next(first, pivot), pred,
pivot / 2,
first
)
)
;
}
template<typename RandomAccessIterator, typename BinaryPredicate>
inline SPROUT_CONSTEXPR RandomAccessIterator
adjacent_find(
RandomAccessIterator first, RandomAccessIterator last, BinaryPredicate pred,
std::random_access_iterator_tag*
)
{
return first == last || NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) == 1 ? last
: adjacent_find_impl_ra_1(
sprout::detail::adjacent_find_impl_ra(
first, sprout::next(first, NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) - 1), pred,
(NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) - 1) / 2, first
),
last
)
;
}
// Copyright (C) 2011 RiSK (sscrisk)
template<typename ForwardIterator, typename BinaryPredicate>
inline SPROUT_CONSTEXPR ForwardIterator
adjacent_find_impl(ForwardIterator first, ForwardIterator next, ForwardIterator last, BinaryPredicate pred) {
return next == last ? last
: pred(*first, *next) ? first
: sprout::detail::adjacent_find_impl(next, sprout::next(next), last, pred)
;
}
template<typename ForwardIterator, typename BinaryPredicate>
inline SPROUT_CONSTEXPR ForwardIterator
adjacent_find(
ForwardIterator first, ForwardIterator last, BinaryPredicate pred,
void*
)
{
return first == last ? last
: sprout::detail::adjacent_find_impl(first, sprout::next(first), last, pred)
;
}
} //namespace detail
// 25.2.8 Adjacent find
template<typename ForwardIterator, typename BinaryPredicate>
inline SPROUT_CONSTEXPR ForwardIterator
adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate pred) {
return first == last || sprout::next(first) == last ? last
: pred(*first, *(sprout::next(first))) ? first
: sprout::adjacent_find(sprout::next(first), last, pred)
;
typedef typename std::iterator_traits<ForwardIterator>::iterator_category* category;
return sprout::detail::adjacent_find(first, last, pred, category());
}
template<typename ForwardIterator>

View file

@ -35,7 +35,7 @@ namespace sprout {
std::random_access_iterator_tag*
)
{
return first == last ? first
return first == last ? last
: sprout::detail::find_impl_ra(first, last, value, NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) / 2, first)
;
}

View file

@ -6,9 +6,9 @@
#include <sprout/algorithm/search.hpp>
namespace sprout {
// Copyright (C) 2011 RiSK (sscrisk)
namespace detail {
// Copyright (C) 2011 RiSK (sscrisk)
template<typename Iterator1, typename Iterator2>
struct iter_equal_to {
public:
@ -23,6 +23,41 @@ namespace sprout {
};
} // namespace detail
namespace detail {
template<typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR ForwardIterator1
find_end_impl(
ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate pred,
ForwardIterator1 result
)
{
return first1 == last1 ? result
: sprout::detail::find_end_impl(
sprout::search(sprout::next(first1), last1, first2, last2, pred), last1, first2, last2, pred,
first1
)
;
}
template<typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR ForwardIterator1
find_end(
ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate pred,
void*
)
{
return first2 == last2 ? last1
: sprout::detail::find_end_impl(
sprout::search(first1, last1, first2, last2, pred), last1, first2, last2, pred,
last1
)
;
}
} // namespace detail
// 25.2.6 Find end
template<typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR ForwardIterator1
@ -32,12 +67,8 @@ namespace sprout {
BinaryPredicate pred
)
{
return first1 == last1 || first2 == last2 ? last1
: sprout::search(first1, last1, first2, last2, pred) == first1
&& sprout::search(sprout::next(first1), last1, first2, last2, pred) == last1
? first1
: sprout::find_end(sprout::next(first1), last1, first2, last2, pred)
;
typedef typename std::iterator_traits<ForwardIterator1>::iterator_category* category;
return sprout::detail::find_end(first1, last1, first2, last2, pred, category());
}
template<typename ForwardIterator1, typename ForwardIterator2>

View file

@ -1,37 +1,101 @@
#ifndef SPROUT_ALGORITHM_FIND_FIRST_OF_HPP
#define SPROUT_ALGORITHM_FIND_FIRST_OF_HPP
#include <iterator>
#include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/functional/equal_to.hpp>
#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
namespace sprout {
// Copyright (C) 2011 RiSK (sscrisk)
namespace detail {
template<typename RandomAccessIterator1, typename ForwardIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR RandomAccessIterator1
find_first_of_impl_ra(
RandomAccessIterator1 first1, RandomAccessIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate pred,
typename std::iterator_traits<RandomAccessIterator1>::difference_type pivot, RandomAccessIterator1 found
)
{
return found != first1 ? found
: pivot == 0 ? sprout::find_if(first2, last2, NS_SSCRISK_CEL_OR_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,
sprout::detail::find_first_of_impl_ra(
first1, sprout::next(first1, pivot), first2, last2, pred,
pivot / 2,
first1
)
)
;
}
template<typename RandomAccessIterator1, typename ForwardIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR RandomAccessIterator1
find_first_of(
RandomAccessIterator1 first1, RandomAccessIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate pred,
std::random_access_iterator_tag*
)
{
return first1 == last1 ? last1
: sprout::detail::find_first_of_impl_ra(
first1, last1, first2, last2,
pred, NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1) / 2, first1
)
;
}
// Copyright (C) 2011 RiSK (sscrisk)
template<typename InputIterator1, typename ForwardIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR InputIterator1
find_first_of_impl(
InputIterator1 first1, InputIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate pred
)
{
return first1 == last1 || sprout::find_if(first2, last2, NS_SSCRISK_CEL_OR_SPROUT::bind2nd(pred, *first1)) != last2 ? first1
: sprout::detail::find_first_of_impl(sprout::next(first1), last1, first2, last2, pred)
;
}
template<typename InputIterator1, typename ForwardIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR InputIterator1
find_first_of(
InputIterator1 first1, InputIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate pred,
void*
)
{
return sprout::detail::find_first_of_impl(first1, last1, first2, last2, pred);
}
} //namespace detail
// 25.2.7 Find first
template<typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR ForwardIterator1
template<typename InputIterator1, typename ForwardIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR InputIterator1
find_first_of(
ForwardIterator1 first1, ForwardIterator1 last1,
InputIterator1 first1, InputIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate pred
)
{
return first1 == last1 || sprout::find_if(first2, last2, NS_SSCRISK_CEL_OR_SPROUT::bind2nd(pred, *first1)) != last2 ? first1
: sprout::find_first_of(sprout::next(first1), last1, first2, last2, pred)
;
typedef typename std::iterator_traits<InputIterator1>::iterator_category* category;
return sprout::detail::find_first_of(first1, last1, first2, last2, pred, category());
}
template<typename ForwardIterator1, typename ForwardIterator2>
inline SPROUT_CONSTEXPR ForwardIterator1
template<typename InputIterator1, typename ForwardIterator2>
inline SPROUT_CONSTEXPR InputIterator1
find_first_of(
ForwardIterator1 first1, ForwardIterator1 last1,
InputIterator1 first1, InputIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2
)
{
return first1 == last1 || sprout::find(first2, last2, *first1) != last2 ? first1
: sprout::find_first_of(sprout::next(first1), last1, first2, last2)
;
return sprout::find_first_of(first1, last1, first2, last2, sprout::equal_to<>());
}
} // namespace sprout

View file

@ -35,7 +35,7 @@ namespace sprout {
std::random_access_iterator_tag*
)
{
return first == last ? first
return first == last ? last
: sprout::detail::find_if_impl_ra(first, last, pred, NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) / 2, first)
;
}

View file

@ -35,7 +35,7 @@ namespace sprout {
std::random_access_iterator_tag*
)
{
return first == last ? first
return first == last ? last
: sprout::detail::find_if_not_impl_ra(first, last, pred, NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) / 2, first)
;
}