fix rexursion depth: is_pertitioned, partition_point, is_sorted, is_sorted_until

This commit is contained in:
bolero-MURAKAMI 2012-12-15 17:41:20 +09:00
parent d6914ddd72
commit eea1c2bbc1
12 changed files with 410 additions and 50 deletions

View file

@ -4,6 +4,7 @@
#include <iterator>
#include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp>
#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
namespace sprout {

View file

@ -6,9 +6,17 @@
#include <sprout/algorithm/search.hpp>
#include <sprout/functional/equal_to.hpp>
#include <sprout/detail/algorithm/search_one.hpp>
#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT
namespace sprout {
namespace detail {
template<typename RandomAccessIterator1>
inline SPROUT_CONSTEXPR RandomAccessIterator1
find_end_impl_ra_1(RandomAccessIterator1 first1, RandomAccessIterator1 result, RandomAccessIterator1 searched) {
return searched == first1 ? searched
: result
;
}
template<typename RandomAccessIterator1, typename ForwardIterator2, typename BinaryPredicate>
inline SPROUT_CONSTEXPR RandomAccessIterator1
find_end_impl_ra(
@ -19,16 +27,21 @@ namespace sprout {
RandomAccessIterator1 searched
)
{
return searched < first1 ? sprout::detail::find_end_impl_ra(
sprout::next(first1, pivot), last1, first2, last2, pred,
(NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1) - pivot) / 2, last1_, searched,
sprout::detail::find_end_impl_ra(
first1, sprout::next(first1, pivot), first2, last2, pred,
pivot / 2, last1_, searched,
first1
return searched == last1_ ? result
: searched < first1 ? pivot == 0
? sprout::detail::find_end_impl_ra_1(
first1, searched,
sprout::detail::search_one(first1, last1_, first2, last2, pred)
)
: sprout::detail::find_end_impl_ra(
sprout::next(first1, pivot), last1, first2, last2, pred,
(NS_SSCRISK_CEL_OR_SPROUT::distance(first1, last1) - pivot) / 2, last1_, searched,
sprout::detail::find_end_impl_ra(
first1, sprout::next(first1, pivot), first2, last2, pred,
pivot / 2, last1_, searched,
first1
)
)
)
: searched == last1_ ? result
: pivot == 0 ? sprout::detail::search_one(first1, last1_, first2, last2, pred)
: sprout::detail::find_end_impl_ra(
sprout::next(first1, pivot), last1, first2, last2, pred,

View file

@ -2,28 +2,20 @@
#define SPROUT_ALGORITHM_IS_PARTITIONED_HPP
#include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/algorithm/none_of.hpp>
#include <sprout/algorithm/find_if_not.hpp>
namespace sprout {
// Copyright (C) 2011 RiSK (sscrisk)
namespace detail {
template<typename InputIterator, typename Predicate>
inline SPROUT_CONSTEXPR bool
is_partitioned_impl(InputIterator first, InputIterator last, Predicate pred, bool cond = true) {
return first == last ? true
: cond ? sprout::detail::is_partitioned_impl(sprout::next(first), last, pred, pred(*first))
: pred(*first) ? false
: sprout::detail::is_partitioned_impl(sprout::next(first), last, pred, false)
;
}
} // namespace detail
// 25.3.13 Partitions
//
// recursion depth:
// [first, last) is RandomAccessIterator -> O(log N)
// otherwise -> O(N)
//
template<typename InputIterator, typename Predicate>
inline SPROUT_CONSTEXPR bool
is_partitioned(InputIterator first, InputIterator last, Predicate pred) {
return sprout::detail::is_partitioned_impl(first, last, pred);
return sprout::none_of(sprout::find_if_not(first, last, pred), last, pred);
}
} // namespace sprout

View file

@ -1,23 +1,75 @@
#ifndef SPROUT_ALGORITHM_IS_SORTED_HPP
#define SPROUT_ALGORITHM_IS_SORTED_HPP
#include <iterator>
#include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp>
#include <sprout/algorithm/is_sorted_until.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 RandomAccessIterator, typename Compare>
inline SPROUT_CONSTEXPR bool
is_sorted_impl_ra(
RandomAccessIterator first, RandomAccessIterator last, Compare comp,
typename std::iterator_traits<RandomAccessIterator>::difference_type pivot
)
{
return pivot == 0 ? !comp(*last, *first)
: sprout::detail::is_sorted_impl_ra(
first, sprout::next(first, pivot), comp,
pivot / 2
)
&& sprout::detail::is_sorted_impl_ra(
sprout::next(first, pivot), last, comp,
(NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) - pivot) / 2
)
;
}
template<typename RandomAccessIterator, typename Compare>
inline SPROUT_CONSTEXPR bool
is_sorted(
RandomAccessIterator first, RandomAccessIterator last, Compare comp,
std::random_access_iterator_tag*
)
{
return first == last || NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) == 1 ? true
: sprout::detail::is_sorted_impl_ra(
first, sprout::next(first, NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) - 1), comp,
(NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) - 1) / 2
)
;
}
// Copyright (C) 2011 RiSK (sscrisk)
template<typename ForwardIterator, typename Compare>
inline SPROUT_CONSTEXPR bool
is_sorted(
ForwardIterator first, ForwardIterator last, Compare comp,
void*
)
{
return sprout::is_sorted_until(first, last, comp) == last;
}
} //namespace detail
// 25.4.1.5 is_sorted
template<typename ForwardIterator>
inline SPROUT_CONSTEXPR bool
is_sorted(ForwardIterator first, ForwardIterator last) {
return sprout::is_sorted_until(first, last) == last;
}
template<typename ForwardIterator, typename Compare>
inline SPROUT_CONSTEXPR bool
is_sorted(ForwardIterator first, ForwardIterator last, Compare comp) {
return sprout::is_sorted_until(first, last, comp) == last;
typedef typename std::iterator_traits<ForwardIterator>::iterator_category* category;
return sprout::detail::is_sorted(first, last, comp, category());
}
template<typename ForwardIterator>
inline SPROUT_CONSTEXPR bool
is_sorted(ForwardIterator first, ForwardIterator last) {
return sprout::is_sorted(
first, last,
NS_SSCRISK_CEL_OR_SPROUT::less<typename std::iterator_traits<ForwardIterator>::value_type>()
);
}
} // namespace sprout

View file

@ -1,29 +1,88 @@
#ifndef SPROUT_ALGORITHM_IS_SORTED_UNTIL_HPP
#define SPROUT_ALGORITHM_IS_SORTED_UNTIL_HPP
#include <iterator>
#include <sprout/config.hpp>
#include <sprout/iterator/operation.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 RandomAccessIterator, typename Compare>
inline SPROUT_CONSTEXPR RandomAccessIterator
is_sorted_until_impl_ra(
RandomAccessIterator first, RandomAccessIterator last, Compare comp,
typename std::iterator_traits<RandomAccessIterator>::difference_type pivot, RandomAccessIterator found
)
{
return found != first ? found
: pivot == 0 ? (comp(*last, *first) ? first : last)
: sprout::detail::is_sorted_until_impl_ra(
sprout::next(first, pivot), last, comp,
(NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) - pivot) / 2,
sprout::detail::is_sorted_until_impl_ra(
first, sprout::next(first, pivot), comp,
pivot / 2,
first
)
)
;
}
template<typename RandomAccessIterator, typename Compare>
inline SPROUT_CONSTEXPR RandomAccessIterator
is_sorted_until(
RandomAccessIterator first, RandomAccessIterator last, Compare comp,
std::random_access_iterator_tag*
)
{
return first == last || NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) == 1 ? last
: sprout::next(
sprout::detail::is_sorted_until_impl_ra(
first, sprout::next(first, NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) - 1), comp,
(NS_SSCRISK_CEL_OR_SPROUT::distance(first, last) - 1) / 2, first
)
)
;
}
// Copyright (C) 2011 RiSK (sscrisk)
template<typename ForwardIterator, typename Compare>
inline SPROUT_CONSTEXPR ForwardIterator
is_sorted_until_impl(ForwardIterator first, ForwardIterator next, ForwardIterator last, Compare comp) {
return next == last ? last
: comp(*next, *first) ? first
: sprout::detail::is_sorted_until_impl(next, sprout::next(next), last, comp)
;
}
template<typename ForwardIterator, typename Compare>
inline SPROUT_CONSTEXPR ForwardIterator
is_sorted_until(
ForwardIterator first, ForwardIterator last, Compare comp,
void*
)
{
return first == last ? last
: sprout::detail::is_sorted_until_impl(first, sprout::next(first), last, comp)
;
}
} //namespace detail
// 25.4.1.5 is_sorted
template<typename ForwardIterator>
inline SPROUT_CONSTEXPR ForwardIterator
is_sorted_until(ForwardIterator first, ForwardIterator last) {
return first == last || sprout::next(first) == last ? last
: *(sprout::next(first)) < *first ? sprout::next(first)
: sprout::is_sorted_until(sprout::next(first), last)
;
}
template<typename ForwardIterator, typename Compare>
inline SPROUT_CONSTEXPR ForwardIterator
is_sorted_until(ForwardIterator first, ForwardIterator last, Compare comp) {
return first == last || sprout::next(first) == last ? last
: comp(*(sprout::next(first)), *first) ? sprout::next(first)
: sprout::is_sorted_until(sprout::next(first), last)
;
typedef typename std::iterator_traits<ForwardIterator>::iterator_category* category;
return sprout::detail::is_sorted_until(first, last, comp, category());
}
template<typename ForwardIterator>
inline SPROUT_CONSTEXPR ForwardIterator
is_sorted_until(ForwardIterator first, ForwardIterator last) {
return sprout::is_sorted_until(
first, last,
NS_SSCRISK_CEL_OR_SPROUT::less<typename std::iterator_traits<ForwardIterator>::value_type>()
);
}
} // namespace sprout

View file

@ -26,6 +26,11 @@ namespace sprout {
} // namespace detail
// 25.3.13 Partitions
//
// recursion depth:
// [first, last) is RandomAccessIterator -> O(log N)
// otherwise -> O(N)
//
template<typename ForwardIterator, typename Predicate>
inline SPROUT_CONSTEXPR ForwardIterator
partition_point(ForwardIterator first, ForwardIterator last, Predicate pred) {