Iros
 
Loading...
Searching...
No Matches
binary_search.h
Go to the documentation of this file.
1#pragma once
2
5
6namespace di::container {
7namespace detail {
9 template<concepts::ForwardIterator It, concepts::SentinelFor<It> Sent, typename T,
10 typename Proj = function::Identity,
11 concepts::IndirectStrictWeakOrder<T const*, meta::Projected<It, Proj>> Comp = function::Compare>
12 constexpr auto operator()(It first, Sent last, T const& needle, Comp comp = {}, Proj proj = {}) const
14 auto const distance = container::distance(first, last);
15 return binary_search_with_size(util::move(first), needle, util::ref(comp), util::ref(proj), distance);
16 }
17
18 template<concepts::ForwardContainer Con, typename T, typename Proj = function::Identity,
21 constexpr auto operator()(Con&& container, T const& needle, Comp comp = {}, Proj proj = {}) const
24 return binary_search_with_size(container::begin(container), needle, util::ref(comp), util::ref(proj),
25 distance);
26 }
27
28 private:
29 template<typename It, typename T, typename Proj, typename Comp,
30 typename SSizeType = meta::IteratorSSizeType<It>>
31 constexpr static auto binary_search_with_size(It first, T const& needle, Comp comp, Proj proj,
32 meta::TypeIdentity<SSizeType> n) -> InFoundResult<It> {
33 while (n != 0) {
34 SSizeType left_length = n >> 1;
35 auto* mid = container::next(first, left_length);
36 auto result = function::invoke(comp, needle, function::invoke(proj, *mid));
37 if (result == 0) {
38 // found the needle, return true.
39 return { util::move(mid), true };
40 }
41 if (result > 0) {
42 // needle is greater than every element in the range [first, mid].
43 n -= left_length + 1;
44 first = ++mid;
45 } else {
46 // needle is less than every element in the range [mid, last).
47 n = left_length;
48 }
49 }
50
51 return { util::move(first), false };
52 }
53 };
54}
55
57}
58
59namespace di {
61}
Definition forward_container.h:8
Definition indirect_strict_weak_order.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 distance
Definition distance.h:44
constexpr auto binary_search
Definition binary_search.h:56
constexpr auto begin
Definition begin.h:44
constexpr auto invoke
Definition invoke.h:100
Type< TypeConstant< T > > TypeIdentity
This is a helper template to prevent C++ from deducing the type of template argument.
Definition core.h:32
Conditional< concepts::BorrowedContainer< Con >, ContainerIterator< Con >, container::Dangling > BorrowedIterator
Definition borrowed_iterator.h:11
decltype(container::iterator_ssize_type(types::in_place_type< meta::RemoveCVRef< T > >)) IteratorSSizeType
Definition iterator_ssize_type.h:8
constexpr auto ref
Definition reference_wrapper.h:98
Definition zstring_parser.h:9
constexpr auto proj
Definition proj.h:59
Definition in_found_result.h:8
constexpr auto operator()(Con &&container, T const &needle, Comp comp={}, Proj proj={}) const -> InFoundResult< meta::BorrowedIterator< Con > >
Definition binary_search.h:21
constexpr auto operator()(It first, Sent last, T const &needle, Comp comp={}, Proj proj={}) const -> InFoundResult< It >
Definition binary_search.h:12
Definition compare.h:8
Definition identity.h:7