mirror of
https://github.com/bolero-MURAKAMI/Sprout
synced 2025-08-03 12:49:50 +00:00
fix recursion depth O(logN): some algorithms
This commit is contained in:
parent
28697ee7a8
commit
5019f6aa96
162 changed files with 3600 additions and 1659 deletions
|
@ -2,45 +2,68 @@
|
|||
#define SPROUT_DETAIL_ALGORITHM_COUNT_N_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/iterator/type_traits/is_iterator.hpp>
|
||||
#include <sprout/utility/pair.hpp>
|
||||
#include <sprout/algorithm/count.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
template<typename InputIterator, typename Size, typename T>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||
template<typename RandomAccessIterator, typename T>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sprout::is_constant_distance_iterator<RandomAccessIterator>::value,
|
||||
typename std::iterator_traits<RandomAccessIterator>::difference_type
|
||||
>::type
|
||||
count_n(
|
||||
InputIterator first, Size n, T const& value,
|
||||
RandomAccessIterator first, typename std::iterator_traits<RandomAccessIterator>::difference_type n, T const& value,
|
||||
std::random_access_iterator_tag*
|
||||
)
|
||||
{
|
||||
return sprout::count(first, sprout::next(first, n), value);
|
||||
}
|
||||
|
||||
template<typename InputIterator, typename Size, typename T>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||
count_n_impl(InputIterator first, Size n, T const& value) {
|
||||
return n == 0 ? 0
|
||||
: (*first == value ? 1 : 0) + sprout::detail::count_n_impl(sprout::next(first), n - 1, value)
|
||||
template<typename InputIterator, typename T>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<InputIterator, typename std::iterator_traits<InputIterator>::difference_type>
|
||||
count_n_impl(
|
||||
sprout::pair<InputIterator, typename std::iterator_traits<InputIterator>::difference_type> const& current,
|
||||
T const& value, typename std::iterator_traits<InputIterator>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::pair<InputIterator, typename std::iterator_traits<InputIterator>::difference_type> type;
|
||||
return n == 1 ? type(sprout::next(current.first), current.second + (*current.first == value ? 1 : 0))
|
||||
: sprout::detail::count_n_impl(
|
||||
sprout::detail::count_n_impl(
|
||||
current,
|
||||
value, n / 2
|
||||
),
|
||||
value, n - n / 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename InputIterator, typename Size, typename T>
|
||||
template<typename InputIterator, typename T>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||
count_n(
|
||||
InputIterator first, Size n, T const& value,
|
||||
InputIterator first, typename std::iterator_traits<InputIterator>::difference_type n, T const& value,
|
||||
void*
|
||||
)
|
||||
{
|
||||
return sprout::detail::count_n_impl(first, n, value);
|
||||
typedef sprout::pair<InputIterator, typename std::iterator_traits<InputIterator>::difference_type> type;
|
||||
return n == 0 ? 0
|
||||
: sprout::detail::count_n_impl(type(first, 0), value, n).second
|
||||
;
|
||||
}
|
||||
|
||||
//
|
||||
// count_n
|
||||
//
|
||||
template<typename InputIterator, typename Size, typename T>
|
||||
// recursion depth:
|
||||
// O(log N)
|
||||
//
|
||||
template<typename InputIterator, typename T>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||
count_n(InputIterator first, Size n, T const& value) {
|
||||
count_n(InputIterator first, typename std::iterator_traits<InputIterator>::difference_type n, T const& value) {
|
||||
typedef typename std::iterator_traits<InputIterator>::iterator_category* category;
|
||||
return sprout::detail::count_n(first, n, value, category());
|
||||
}
|
||||
|
|
|
@ -2,45 +2,68 @@
|
|||
#define SPROUT_DETAIL_ALGORITHM_COUNT_N_IF_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/iterator/type_traits/is_iterator.hpp>
|
||||
#include <sprout/utility/pair.hpp>
|
||||
#include <sprout/algorithm/count_if.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
template<typename InputIterator, typename Size, typename Predicate>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||
template<typename RandomAccessIterator, typename Predicate>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sprout::is_constant_distance_iterator<RandomAccessIterator>::pred,
|
||||
typename std::iterator_traits<RandomAccessIterator>::difference_type
|
||||
>::type
|
||||
count_n_if(
|
||||
InputIterator first, Size n, Predicate pred,
|
||||
RandomAccessIterator first, typename std::iterator_traits<RandomAccessIterator>::difference_type n, Predicate pred,
|
||||
std::random_access_iterator_tag*
|
||||
)
|
||||
{
|
||||
return sprout::count_if(first, sprout::next(first, n), pred);
|
||||
return sprout::count(first, sprout::next(first, n), pred);
|
||||
}
|
||||
|
||||
template<typename InputIterator, typename Size, typename Predicate>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||
count_n_if_impl(InputIterator first, Size n, Predicate pred) {
|
||||
return n == 0 ? 0
|
||||
: (pred(*first) ? 1 : 0) + sprout::detail::count_n_if(sprout::next(first), n - 1, pred)
|
||||
template<typename InputIterator, typename Predicate>
|
||||
inline SPROUT_CONSTEXPR sprout::pair<InputIterator, typename std::iterator_traits<InputIterator>::difference_type>
|
||||
count_n_if_impl(
|
||||
sprout::pair<InputIterator, typename std::iterator_traits<InputIterator>::difference_type> const& current,
|
||||
Predicate pred, typename std::iterator_traits<InputIterator>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::pair<InputIterator, typename std::iterator_traits<InputIterator>::difference_type> type;
|
||||
return n == 1 ? type(sprout::next(current.first), current.second + (pred(*current.first) ? 1 : 0))
|
||||
: sprout::detail::count_n_if_impl(
|
||||
sprout::detail::count_n_if_impl(
|
||||
current,
|
||||
pred, n / 2
|
||||
),
|
||||
pred, n - n / 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename InputIterator, typename Size, typename Predicate>
|
||||
template<typename InputIterator, typename Predicate>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||
count_n_if(
|
||||
InputIterator first, Size n, Predicate pred,
|
||||
InputIterator first, typename std::iterator_traits<InputIterator>::difference_type n, Predicate pred,
|
||||
void*
|
||||
)
|
||||
{
|
||||
return sprout::detail::count_n_if_impl(first, n, pred);
|
||||
typedef sprout::pair<InputIterator, typename std::iterator_traits<InputIterator>::difference_type> type;
|
||||
return n == 0 ? 0
|
||||
: sprout::detail::count_n_if_impl(type(first, 0), pred, n).second
|
||||
;
|
||||
}
|
||||
|
||||
//
|
||||
// count_n_if
|
||||
//
|
||||
template<typename InputIterator, typename Size, typename Predicate>
|
||||
// recursion depth:
|
||||
// O(log N)
|
||||
//
|
||||
template<typename InputIterator, typename Predicate>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||
count_n_if(InputIterator first, Size n, Predicate pred) {
|
||||
count_n_if(InputIterator first, typename std::iterator_traits<InputIterator>::difference_type n, Predicate pred) {
|
||||
typedef typename std::iterator_traits<InputIterator>::iterator_category* category;
|
||||
return sprout::detail::count_n_if(first, n, pred, category());
|
||||
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
#include <iterator>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT
|
||||
#include <sprout/iterator/type_traits/is_iterator.hpp>
|
||||
#include <sprout/tuple/tuple.hpp>
|
||||
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
|
||||
|
||||
namespace sprout {
|
||||
|
@ -23,52 +24,89 @@ namespace sprout {
|
|||
)
|
||||
+ sprout::detail::overlap_count_impl_ra(
|
||||
sprout::next(first, pivot), last, pred,
|
||||
(NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) - pivot) / 2
|
||||
(sprout::distance(first, last) - pivot) / 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename RandomAccessIterator, typename BinaryPredicate>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<RandomAccessIterator>::difference_type
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sprout::is_constant_distance_iterator<RandomAccessIterator>::value,
|
||||
typename std::iterator_traits<RandomAccessIterator>::difference_type
|
||||
>::type
|
||||
overlap_count(
|
||||
RandomAccessIterator first, RandomAccessIterator last, BinaryPredicate pred,
|
||||
std::random_access_iterator_tag*
|
||||
)
|
||||
{
|
||||
return first == last || NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) == 1 ? 0
|
||||
return first == last || sprout::distance(first, last) == 1 ? 0
|
||||
: sprout::detail::overlap_count_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, sprout::next(first, sprout::distance(first, last) - 1), pred,
|
||||
(sprout::distance(first, last) - 1) / 2
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
template<typename InputIterator, typename BinaryPredicate>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||
overlap_count_impl(
|
||||
InputIterator first, InputIterator last, BinaryPredicate pred,
|
||||
typename std::iterator_traits<InputIterator>::value_type const& value
|
||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<InputIterator, typename std::iterator_traits<InputIterator>::value_type, typename std::iterator_traits<InputIterator>::difference_type>
|
||||
overlap_count_impl_1(
|
||||
sprout::tuples::tuple<InputIterator, typename std::iterator_traits<InputIterator>::value_type, typename std::iterator_traits<InputIterator>::difference_type> const& current,
|
||||
InputIterator last, BinaryPredicate pred, typename std::iterator_traits<InputIterator>::difference_type n
|
||||
)
|
||||
{
|
||||
return first == last ? 0
|
||||
: pred(*first, value) ? 1 + sprout::detail::overlap_count_impl(sprout::next(first), last, pred, value)
|
||||
: sprout::detail::overlap_count_impl(sprout::next(first), last, pred, *first)
|
||||
typedef sprout::tuples::tuple<InputIterator, typename std::iterator_traits<InputIterator>::value_type, typename std::iterator_traits<InputIterator>::difference_type> type;
|
||||
return sprout::tuples::get<0>(current) == last ? current
|
||||
: n == 1 ? type(
|
||||
sprout::next(sprout::tuples::get<0>(current)), *sprout::tuples::get<0>(current),
|
||||
sprout::tuples::get<2>(current) + (pred(*sprout::tuples::get<0>(current), sprout::tuples::get<1>(current)) ? 1 : 0)
|
||||
)
|
||||
: sprout::detail::overlap_count_impl_1(
|
||||
sprout::detail::overlap_count_impl_1(
|
||||
current,
|
||||
last, pred, n / 2
|
||||
),
|
||||
last, pred, n - n / 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename InputIterator, typename BinaryPredicate>
|
||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<InputIterator, typename std::iterator_traits<InputIterator>::value_type, typename std::iterator_traits<InputIterator>::difference_type>
|
||||
overlap_count_impl(
|
||||
sprout::tuples::tuple<InputIterator, typename std::iterator_traits<InputIterator>::value_type, typename std::iterator_traits<InputIterator>::difference_type> const& current,
|
||||
InputIterator last, BinaryPredicate pred, typename std::iterator_traits<InputIterator>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::tuples::tuple<InputIterator, typename std::iterator_traits<InputIterator>::value_type, typename std::iterator_traits<InputIterator>::difference_type> type;
|
||||
return sprout::tuples::get<0>(current) == last ? current
|
||||
: sprout::detail::overlap_count_impl(
|
||||
sprout::detail::overlap_count_impl_1(
|
||||
current,
|
||||
last, pred, n
|
||||
),
|
||||
last, pred, n * 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename InputIterator, typename BinaryPredicate>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||
overlap_count_impl(
|
||||
overlap_count(
|
||||
InputIterator first, InputIterator last, BinaryPredicate pred,
|
||||
void*
|
||||
)
|
||||
{
|
||||
typedef sprout::tuples::tuple<InputIterator, typename std::iterator_traits<InputIterator>::value_type, typename std::iterator_traits<InputIterator>::difference_type> type;
|
||||
return first == last ? 0
|
||||
: sprout::detail::overlap_count_impl(sprout::next(first), last, pred, *first)
|
||||
: sprout::tuples::get<2>(
|
||||
sprout::detail::overlap_count_impl(type(sprout::next(first), *first, 0), last, pred, 1)
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
//
|
||||
// overlap_count
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log N)
|
||||
//
|
||||
template<typename InputIterator, typename BinaryPredicate>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||
overlap_count(InputIterator first, InputIterator last, BinaryPredicate pred) {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include <sprout/iterator/type_traits/common.hpp>
|
||||
#include <sprout/functional/equal_to.hpp>
|
||||
#include <sprout/algorithm/mismatch.hpp>
|
||||
#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT
|
||||
#include <sprout/tuple/tuple.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
|
@ -17,12 +17,7 @@ namespace sprout {
|
|||
RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, RandomAccessIterator2 last2, BinaryPredicate pred
|
||||
)
|
||||
{
|
||||
return sprout::detail::mismatch_impl_ra(
|
||||
first1, last1, first2, pred,
|
||||
NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1) / 2, first1
|
||||
)
|
||||
== last1
|
||||
? first1
|
||||
return sprout::mismatch(first1, last1, first2, pred).first == last1 ? first1
|
||||
: last1
|
||||
;
|
||||
}
|
||||
|
@ -33,25 +28,57 @@ namespace sprout {
|
|||
std::random_access_iterator_tag*
|
||||
)
|
||||
{
|
||||
return NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1) < NS_SSCRISK_CEL_OR_SPROUT::distance(first2, last2) ? last1
|
||||
return sprout::distance(first1, last1) < sprout::distance(first2, last2) ? last1
|
||||
: first1 == last1 ? first1
|
||||
: sprout::detail::search_one_impl_ra(
|
||||
first1, sprout::next(first1, NS_SSCRISK_CEL_OR_SPROUT::distance(first2, last2)), first2, last2, pred
|
||||
first1, sprout::next(first1, sprout::distance(first2, last2)), first2, last2, pred
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
template<typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate>
|
||||
inline SPROUT_CONSTEXPR ForwardIterator1
|
||||
search_one_impl(
|
||||
ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred,
|
||||
ForwardIterator1 first1_
|
||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<ForwardIterator1, ForwardIterator2, bool>
|
||||
search_one_impl_1(
|
||||
sprout::tuples::tuple<ForwardIterator1, ForwardIterator2, bool> const& current,
|
||||
ForwardIterator1 last1, ForwardIterator2 last2, BinaryPredicate pred,
|
||||
ForwardIterator1 first1_, typename std::iterator_traits<ForwardIterator1>::difference_type n
|
||||
)
|
||||
{
|
||||
return first2 == last2 ? first1_
|
||||
: first1 == last1 ? last1
|
||||
: !pred(*first1, *first2) ? first1
|
||||
: sprout::detail::search_one_impl(sprout::next(first1), last1, sprout::next(first2), last2, pred, first1_)
|
||||
typedef sprout::tuples::tuple<ForwardIterator1, ForwardIterator2, bool> type;
|
||||
return sprout::tuples::get<2>(current) ? current
|
||||
: sprout::tuples::get<1>(current) == last2 ? type(first1_, last2, true)
|
||||
: sprout::tuples::get<0>(current) == last1 ? type(last1, last2, true)
|
||||
: n == 1 ? !pred(*sprout::tuples::get<0>(current), *sprout::tuples::get<1>(current))
|
||||
? type(sprout::next(sprout::tuples::get<0>(current)), last2, true)
|
||||
: type(sprout::next(sprout::tuples::get<0>(current)), sprout::next(sprout::tuples::get<1>(current)), false)
|
||||
: sprout::detail::search_one_impl_1(
|
||||
sprout::detail::search_one_impl_1(
|
||||
current,
|
||||
last1, last2, pred, first1_, n / 2
|
||||
),
|
||||
last1, last2, pred, first1_, n - n / 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate>
|
||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<ForwardIterator1, ForwardIterator2, bool>
|
||||
search_one_impl(
|
||||
sprout::tuples::tuple<ForwardIterator1, ForwardIterator2, bool> const& current,
|
||||
ForwardIterator1 last1, ForwardIterator2 last2, BinaryPredicate pred,
|
||||
ForwardIterator1 first1_, typename std::iterator_traits<ForwardIterator1>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::tuples::tuple<ForwardIterator1, ForwardIterator2, bool> type;
|
||||
return sprout::tuples::get<2>(current) ? current
|
||||
: sprout::tuples::get<1>(current) == last2 ? type(first1_, last2, true)
|
||||
: sprout::tuples::get<0>(current) == last1 ? type(last1, last2, true)
|
||||
: sprout::detail::search_one_impl(
|
||||
sprout::detail::search_one_impl_1(
|
||||
current,
|
||||
last1, last2, pred, first1_, n
|
||||
),
|
||||
last1, last2, pred, first1_, n * 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate>
|
||||
|
@ -61,12 +88,18 @@ namespace sprout {
|
|||
void*
|
||||
)
|
||||
{
|
||||
return sprout::detail::search_one_impl(first1, last1, first2, last2, pred, first1);
|
||||
typedef sprout::tuples::tuple<ForwardIterator1, ForwardIterator2, bool> type;
|
||||
return sprout::tuples::get<0>(
|
||||
sprout::detail::search_one_impl(type(first1, first2, false), last1, last2, pred, first1, 1)
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// search_one
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log (N1+N2))
|
||||
//
|
||||
template<typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate>
|
||||
inline SPROUT_CONSTEXPR ForwardIterator1
|
||||
search_one(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred) {
|
||||
|
|
|
@ -4,13 +4,68 @@
|
|||
#include <iterator>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/iterator/type_traits/is_iterator.hpp>
|
||||
#include <sprout/iterator/type_traits/common.hpp>
|
||||
#include <sprout/tuple/tuple.hpp>
|
||||
#include <sprout/functional/less.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
template<typename InputIterator1, typename InputIterator2, typename Compare>
|
||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<InputIterator1, InputIterator2, typename std::iterator_traits<InputIterator1>::difference_type>
|
||||
set_overlap_count_impl_1(
|
||||
sprout::tuples::tuple<InputIterator1, InputIterator2, typename std::iterator_traits<InputIterator1>::difference_type> const& current,
|
||||
InputIterator1 last1, InputIterator2 last2, Compare comp, typename std::iterator_traits<InputIterator1>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::tuples::tuple<InputIterator1, InputIterator2, typename std::iterator_traits<InputIterator1>::difference_type> type;
|
||||
return sprout::tuples::get<0>(current) == last1 || sprout::tuples::get<1>(current) == last2 ? current
|
||||
: n == 1 ? comp(*sprout::tuples::get<0>(current), *sprout::tuples::get<1>(current)) ? type(
|
||||
sprout::next(sprout::tuples::get<0>(current)), sprout::tuples::get<1>(current),
|
||||
sprout::tuples::get<2>(current)
|
||||
)
|
||||
: comp(*sprout::tuples::get<1>(current), *sprout::tuples::get<0>(current)) ? type(
|
||||
sprout::tuples::get<0>(current), sprout::next(sprout::tuples::get<1>(current)),
|
||||
sprout::tuples::get<2>(current)
|
||||
)
|
||||
: type(
|
||||
sprout::next(sprout::tuples::get<0>(current)), sprout::next(sprout::tuples::get<1>(current)),
|
||||
sprout::tuples::get<2>(current) + 1
|
||||
)
|
||||
: sprout::detail::set_overlap_count_impl_1(
|
||||
sprout::detail::set_overlap_count_impl_1(
|
||||
current,
|
||||
last1, last2, comp, n / 2
|
||||
),
|
||||
last1, last2, comp, n - n / 2
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename InputIterator1, typename InputIterator2, typename Compare>
|
||||
inline SPROUT_CONSTEXPR sprout::tuples::tuple<InputIterator1, InputIterator2, typename std::iterator_traits<InputIterator1>::difference_type>
|
||||
set_overlap_count_impl(
|
||||
sprout::tuples::tuple<InputIterator1, InputIterator2, typename std::iterator_traits<InputIterator1>::difference_type> const& current,
|
||||
InputIterator1 last1, InputIterator2 last2, Compare comp, typename std::iterator_traits<InputIterator1>::difference_type n
|
||||
)
|
||||
{
|
||||
typedef sprout::tuples::tuple<InputIterator1, InputIterator2, typename std::iterator_traits<InputIterator1>::difference_type> type;
|
||||
return sprout::tuples::get<0>(current) == last1 || sprout::tuples::get<1>(current) == last2 ? current
|
||||
: sprout::detail::set_overlap_count_impl(
|
||||
sprout::detail::set_overlap_count_impl_1(
|
||||
current,
|
||||
last1, last2, comp, n
|
||||
),
|
||||
last1, last2, comp, n * 2
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
//
|
||||
// set_overlap_count
|
||||
//
|
||||
// recursion depth:
|
||||
// O(log N)
|
||||
//
|
||||
template<typename InputIterator1, typename InputIterator2, typename Compare>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator1>::difference_type
|
||||
set_overlap_count(
|
||||
|
@ -19,14 +74,10 @@ namespace sprout {
|
|||
Compare comp
|
||||
)
|
||||
{
|
||||
return first1 != last1 && first2 != last2
|
||||
? comp(*first1, *first2)
|
||||
? sprout::detail::set_overlap_count(sprout::next(first1), last1, first2, last2, comp)
|
||||
: comp(*first2, *first1)
|
||||
? sprout::detail::set_overlap_count(first1, last1, sprout::next(first2), last2, comp)
|
||||
: 1 + sprout::detail::set_overlap_count(sprout::next(first1), last1, sprout::next(first2), last2, comp)
|
||||
: 0
|
||||
;
|
||||
typedef sprout::tuples::tuple<InputIterator1, InputIterator2, typename std::iterator_traits<InputIterator1>::difference_type> type;
|
||||
return sprout::tuples::get<2>(
|
||||
sprout::detail::set_overlap_count_impl(type(first1, first2, 0), last1, last2, comp, 1)
|
||||
);
|
||||
}
|
||||
|
||||
template<typename InputIterator1, typename InputIterator2>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue