mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +00:00
fix rexursion depth: is_pertitioned, partition_point, is_sorted, is_sorted_until
This commit is contained in:
parent
d6914ddd72
commit
eea1c2bbc1
12 changed files with 410 additions and 50 deletions
56
libs/algorithm/test/is_partitioned.cpp
Normal file
56
libs/algorithm/test/is_partitioned.cpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
#ifndef SPROUT_LIBS_ALGORITHM_TEST_IS_PERTITIONED_CPP
|
||||
#define SPROUT_LIBS_ALGORITHM_TEST_IS_PERTITIONED_CPP
|
||||
|
||||
#include <sprout/algorithm/is_partitioned.hpp>
|
||||
#include <sprout/array.hpp>
|
||||
#include <sprout/container.hpp>
|
||||
#include <testspr/tools.hpp>
|
||||
|
||||
namespace testspr {
|
||||
static void algorithm_is_partitioned_test() {
|
||||
using namespace sprout;
|
||||
{
|
||||
SPROUT_STATIC_CONSTEXPR auto arr1 = array<int, 10>{{1, 3, 5, 7, 9, 2, 4, 6, 8, 10}};
|
||||
|
||||
{
|
||||
SPROUT_STATIC_CONSTEXPR auto result = sprout::is_partitioned(
|
||||
sprout::begin(arr1),
|
||||
sprout::end(arr1),
|
||||
testspr::is_odd<int>()
|
||||
);
|
||||
TESTSPR_BOTH_ASSERT(result);
|
||||
}
|
||||
{
|
||||
SPROUT_STATIC_CONSTEXPR auto result = sprout::is_partitioned(
|
||||
sprout::begin(arr1),
|
||||
sprout::end(arr1),
|
||||
testspr::less_than<int>(6)
|
||||
);
|
||||
TESTSPR_BOTH_ASSERT(!result);
|
||||
}
|
||||
{
|
||||
SPROUT_STATIC_CONSTEXPR auto result = sprout::is_partitioned(
|
||||
sprout::begin(arr1),
|
||||
sprout::begin(arr1) + 5,
|
||||
testspr::is_odd<int>()
|
||||
);
|
||||
TESTSPR_BOTH_ASSERT(result);
|
||||
}
|
||||
{
|
||||
SPROUT_STATIC_CONSTEXPR auto result = sprout::is_partitioned(
|
||||
sprout::begin(arr1),
|
||||
sprout::begin(arr1) + 5,
|
||||
testspr::less_than<int>(6)
|
||||
);
|
||||
TESTSPR_BOTH_ASSERT(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace testspr
|
||||
|
||||
#ifndef TESTSPR_CPP_INCLUDE
|
||||
# define TESTSPR_TEST_FUNCTION testspr::algorithm_is_partitioned_test
|
||||
# include <testspr/include_main.hpp>
|
||||
#endif
|
||||
|
||||
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_IS_PERTITIONED_CPP
|
54
libs/algorithm/test/is_sorted.cpp
Normal file
54
libs/algorithm/test/is_sorted.cpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
#ifndef SPROUT_LIBS_ALGORITHM_TEST_IS_SORTED_CPP
|
||||
#define SPROUT_LIBS_ALGORITHM_TEST_IS_SORTED_CPP
|
||||
|
||||
#include <sprout/algorithm/is_sorted.hpp>
|
||||
#include <sprout/array.hpp>
|
||||
#include <sprout/container.hpp>
|
||||
#include <testspr/tools.hpp>
|
||||
|
||||
namespace testspr {
|
||||
static void algorithm_is_sorted_test() {
|
||||
using namespace sprout;
|
||||
{
|
||||
SPROUT_STATIC_CONSTEXPR auto arr1 = array<int, 10>{{1, 3, 5, 7, 9, 2, 4, 6, 8, 10}};
|
||||
|
||||
{
|
||||
SPROUT_STATIC_CONSTEXPR auto result = sprout::is_sorted(
|
||||
sprout::begin(arr1),
|
||||
sprout::end(arr1)
|
||||
);
|
||||
TESTSPR_BOTH_ASSERT(!result);
|
||||
}
|
||||
{
|
||||
SPROUT_STATIC_CONSTEXPR auto result = sprout::is_sorted(
|
||||
sprout::begin(arr1),
|
||||
sprout::begin(arr1) + 5
|
||||
);
|
||||
TESTSPR_BOTH_ASSERT(result);
|
||||
}
|
||||
{
|
||||
SPROUT_STATIC_CONSTEXPR auto result = sprout::is_sorted(
|
||||
sprout::begin(arr1),
|
||||
sprout::end(arr1),
|
||||
testspr::less<int>()
|
||||
);
|
||||
TESTSPR_BOTH_ASSERT(!result);
|
||||
}
|
||||
{
|
||||
SPROUT_STATIC_CONSTEXPR auto result = sprout::is_sorted(
|
||||
sprout::begin(arr1),
|
||||
sprout::begin(arr1) + 5,
|
||||
testspr::less<int>()
|
||||
);
|
||||
TESTSPR_BOTH_ASSERT(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace testspr
|
||||
|
||||
#ifndef TESTSPR_CPP_INCLUDE
|
||||
# define TESTSPR_TEST_FUNCTION testspr::algorithm_is_sorted_test
|
||||
# include <testspr/include_main.hpp>
|
||||
#endif
|
||||
|
||||
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_IS_SORTED_CPP
|
54
libs/algorithm/test/is_sorted_until.cpp
Normal file
54
libs/algorithm/test/is_sorted_until.cpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
#ifndef SPROUT_LIBS_ALGORITHM_TEST_IS_SORTED_UNTIL_CPP
|
||||
#define SPROUT_LIBS_ALGORITHM_TEST_IS_SORTED_UNTIL_CPP
|
||||
|
||||
#include <sprout/algorithm/is_sorted_until.hpp>
|
||||
#include <sprout/array.hpp>
|
||||
#include <sprout/container.hpp>
|
||||
#include <testspr/tools.hpp>
|
||||
|
||||
namespace testspr {
|
||||
static void algorithm_is_sorted_until_test() {
|
||||
using namespace sprout;
|
||||
{
|
||||
SPROUT_STATIC_CONSTEXPR auto arr1 = array<int, 10>{{1, 3, 5, 7, 9, 2, 4, 6, 8, 10}};
|
||||
|
||||
{
|
||||
SPROUT_STATIC_CONSTEXPR auto found = sprout::is_sorted_until(
|
||||
sprout::begin(arr1),
|
||||
sprout::end(arr1)
|
||||
);
|
||||
TESTSPR_BOTH_ASSERT(found == sprout::begin(arr1) + 5);
|
||||
}
|
||||
{
|
||||
SPROUT_STATIC_CONSTEXPR auto found = sprout::is_sorted_until(
|
||||
sprout::begin(arr1),
|
||||
sprout::begin(arr1) + 5
|
||||
);
|
||||
TESTSPR_BOTH_ASSERT(found == sprout::begin(arr1) + 5);
|
||||
}
|
||||
{
|
||||
SPROUT_STATIC_CONSTEXPR auto found = sprout::is_sorted_until(
|
||||
sprout::begin(arr1),
|
||||
sprout::end(arr1),
|
||||
testspr::less<int>()
|
||||
);
|
||||
TESTSPR_BOTH_ASSERT(found == sprout::begin(arr1) + 5);
|
||||
}
|
||||
{
|
||||
SPROUT_STATIC_CONSTEXPR auto found = sprout::is_sorted_until(
|
||||
sprout::begin(arr1),
|
||||
sprout::begin(arr1) + 5,
|
||||
testspr::less<int>()
|
||||
);
|
||||
TESTSPR_BOTH_ASSERT(found == sprout::begin(arr1) + 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace testspr
|
||||
|
||||
#ifndef TESTSPR_CPP_INCLUDE
|
||||
# define TESTSPR_TEST_FUNCTION testspr::algorithm_is_sorted_until_test
|
||||
# include <testspr/include_main.hpp>
|
||||
#endif
|
||||
|
||||
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_IS_SORTED_UNTIL_CPP
|
|
@ -23,6 +23,10 @@
|
|||
#include "./is_permutation.cpp"
|
||||
#include "./search.cpp"
|
||||
#include "./search_n.cpp"
|
||||
#include "./is_partitioned.cpp"
|
||||
#include "./partition_point.cpp"
|
||||
#include "./is_sorted.cpp"
|
||||
#include "./is_sorted_until.cpp"
|
||||
|
||||
#ifdef TESTSPR_CPP_INCLUDE_DISABLE_SPROUT_LIBS_ALGORITHM_TEST_NON_MODIFYIING_CPP
|
||||
# undef TESTSPR_CPP_INCLUDE
|
||||
|
@ -47,6 +51,10 @@ namespace testspr {
|
|||
testspr::algorithm_is_permutation_test();
|
||||
testspr::algorithm_search_test();
|
||||
testspr::algorithm_search_n_test();
|
||||
testspr::algorithm_is_partitioned_test();
|
||||
testspr::algorithm_partition_point_test();
|
||||
testspr::algorithm_is_sorted_test();
|
||||
testspr::algorithm_is_sorted_until_test();
|
||||
}
|
||||
} // namespace testspr
|
||||
|
||||
|
|
40
libs/algorithm/test/partition_point.cpp
Normal file
40
libs/algorithm/test/partition_point.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
#ifndef SPROUT_LIBS_ALGORITHM_TEST_PERTITION_POINT_CPP
|
||||
#define SPROUT_LIBS_ALGORITHM_TEST_PERTITION_POINT_CPP
|
||||
|
||||
#include <sprout/algorithm/partition_point.hpp>
|
||||
#include <sprout/array.hpp>
|
||||
#include <sprout/container.hpp>
|
||||
#include <testspr/tools.hpp>
|
||||
|
||||
namespace testspr {
|
||||
static void algorithm_partition_point_test() {
|
||||
using namespace sprout;
|
||||
{
|
||||
SPROUT_STATIC_CONSTEXPR auto arr1 = array<int, 10>{{1, 3, 5, 7, 9, 2, 4, 6, 8, 10}};
|
||||
|
||||
{
|
||||
SPROUT_STATIC_CONSTEXPR auto found = sprout::partition_point(
|
||||
sprout::begin(arr1),
|
||||
sprout::end(arr1),
|
||||
testspr::is_odd<int>()
|
||||
);
|
||||
TESTSPR_BOTH_ASSERT(found == sprout::begin(arr1) + 5);
|
||||
}
|
||||
{
|
||||
SPROUT_STATIC_CONSTEXPR auto found = sprout::partition_point(
|
||||
sprout::begin(arr1),
|
||||
sprout::begin(arr1) + 5,
|
||||
testspr::is_odd<int>()
|
||||
);
|
||||
TESTSPR_BOTH_ASSERT(found == sprout::begin(arr1) + 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace testspr
|
||||
|
||||
#ifndef TESTSPR_CPP_INCLUDE
|
||||
# define TESTSPR_TEST_FUNCTION testspr::algorithm_partition_point_test
|
||||
# include <testspr/include_main.hpp>
|
||||
#endif
|
||||
|
||||
#endif // #ifndef SPROUT_LIBS_ALGORITHM_TEST_PERTITION_POINT_CPP
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define SPROUT_ITERATOR_DISTANCE_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/next.hpp>
|
||||
#include <sprout/adl/not_found.hpp>
|
||||
|
@ -12,14 +13,34 @@ namespace sprout_adl {
|
|||
|
||||
namespace sprout {
|
||||
namespace iterator_detail {
|
||||
template<typename RandomAccessIterator>
|
||||
inline SPROUT_CONSTEXPR typename std::enable_if<
|
||||
!std::is_pointer<RandomAccessIterator>::value,
|
||||
typename std::iterator_traits<RandomAccessIterator>::difference_type
|
||||
>::type
|
||||
iterator_distance(RandomAccessIterator first, RandomAccessIterator last, std::random_access_iterator_tag*) {
|
||||
return last - first;
|
||||
}
|
||||
|
||||
// Copyright (C) 2011 RiSK (sscrisk)
|
||||
template<typename InputIterator>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||
iterator_distance_impl(InputIterator first, InputIterator last) {
|
||||
return first == last ? 0
|
||||
: 1 + sprout::iterator_detail::iterator_distance_impl(sprout::next(first), last)
|
||||
;
|
||||
}
|
||||
template<typename InputIterator>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||
iterator_distance(InputIterator first, InputIterator last, void*) {
|
||||
return sprout::iterator_detail::iterator_distance_impl(first, last);
|
||||
}
|
||||
|
||||
template<typename InputIterator>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||
iterator_distance(InputIterator first, InputIterator last) {
|
||||
return first == last ? 0
|
||||
: 1 + sprout::iterator_detail::iterator_distance(sprout::next(first), last)
|
||||
;
|
||||
typedef typename std::iterator_traits<InputIterator>::iterator_category* category;
|
||||
return sprout::iterator_detail::iterator_distance(first, last, category());
|
||||
}
|
||||
} // namespace iterator_detail
|
||||
} // namespace sprout
|
||||
|
@ -38,6 +59,11 @@ namespace sprout {
|
|||
//
|
||||
// distance
|
||||
//
|
||||
// effect:
|
||||
// ADL callable iterator_distance(first, last) -> iterator_distance(first, last)
|
||||
// [first, last) is RandomAccessIterator && not Pointer -> last - first
|
||||
// otherwise -> linearly count: first to last
|
||||
//
|
||||
template<typename InputIterator>
|
||||
inline SPROUT_CONSTEXPR typename std::iterator_traits<InputIterator>::difference_type
|
||||
distance(InputIterator first, InputIterator last) {
|
||||
|
|
Loading…
Reference in a new issue