Iros
 
Loading...
Searching...
No Matches
partition_point.h
Go to the documentation of this file.
1#pragma once
2
6
7namespace di::container {
8namespace detail {
10 template<concepts::ForwardIterator It, concepts::SentinelFor<It> Sent, typename Proj = function::Identity,
11 concepts::IndirectUnaryPredicate<meta::Projected<It, Proj>> Pred>
12 constexpr auto operator()(It first, Sent last, Pred pred, Proj proj = {}) const -> It {
13 auto const n = container::distance(first, last);
14 return partition_point_with_size(util::move(first), util::ref(pred), util::ref(proj), n);
15 }
16
17 template<concepts::ForwardContainer Con, typename Proj = function::Identity,
19 constexpr auto operator()(Con&& container, Pred pred, Proj proj = {}) const -> meta::BorrowedIterator<Con> {
20 return partition_point_with_size(container::begin(container), util::ref(pred), util::ref(proj),
22 }
23
24 private:
25 template<typename It, typename Pred, typename Proj, typename SSizeType>
26 constexpr static auto partition_point_with_size(It first, Pred pred, Proj proj, SSizeType n) -> It {
27 // Perform binary search for the partition point, knowing the size of the container.
28 // If the mid point cannot be the partition point, advance first past the just
29 // checked point, otherwise decrease the length.
30 while (n > 0) {
31 auto const mid_length = static_cast<SSizeType>(n / 2);
32 auto mid = container::next(first, mid_length);
33 if (function::invoke(pred, function::invoke(proj, *mid))) {
34 // Mid is before the partition point.
35 // Skip the range denoted by [first, mid].
36 first = util::move(++mid);
37 n -= mid_length + 1;
38 } else {
39 // Mid is the partition point or past it.
40 // Skip the trailing range denoted by [mid, last].
41 n = mid_length;
42 }
43 }
44 return first;
45 }
46 };
47}
48
50}
51
52namespace di {
54}
Definition forward_container.h:8
Definition indirect_unary_predicate.h:12
Definition sequence.h:13
constexpr auto first(concepts::detail::ConstantVector auto &vector, size_t count)
Definition vector_first.h:13
Definition sequence.h:12
constexpr auto next
Definition next.h:35
constexpr auto partition_point
Definition partition_point.h:49
constexpr auto distance
Definition distance.h:44
constexpr auto begin
Definition begin.h:44
constexpr auto invoke
Definition invoke.h:100
Conditional< concepts::BorrowedContainer< Con >, ContainerIterator< Con >, container::Dangling > BorrowedIterator
Definition borrowed_iterator.h:11
constexpr auto ref
Definition reference_wrapper.h:98
Definition zstring_parser.h:9
constexpr auto proj
Definition proj.h:59
Definition partition_point.h:9
constexpr auto operator()(Con &&container, Pred pred, Proj proj={}) const -> meta::BorrowedIterator< Con >
Definition partition_point.h:19
constexpr auto operator()(It first, Sent last, Pred pred, Proj proj={}) const -> It
Definition partition_point.h:12
Definition identity.h:7