Iros
 
Loading...
Searching...
No Matches
unique_copy.h
Go to the documentation of this file.
1#pragma once
2
8
9namespace di::container {
10namespace detail {
12 template<concepts::InputIterator It, concepts::SentinelFor<It> Sent, concepts::WeaklyIncrementable Out,
13 typename Proj = function::Identity,
14 concepts::IndirectEquivalenceRelation<meta::Projected<It, Proj>> Comp = function::Equal>
20 constexpr auto operator()(It first, Sent last, Out out, Comp comp = {}, Proj proj = {}) const
22 if (first == last) {
23 return { util::move(first), util::move(out) };
24 }
25
26 if constexpr (concepts::InputIterator<Out> &&
27 concepts::SameAs<meta::IteratorValue<It>, meta::IteratorValue<Out>>) {
28 // Since out is an InputIterator, we can read the value's written to Out to check for equality.
29
30 *out = *first;
31 for (++first; first != last; ++first) {
32 if (!function::invoke(comp, function::invoke(proj, *out), function::invoke(proj, *first))) {
33 *out = *first;
34 ++out;
35 }
36 }
37 ++out;
38 } else if constexpr (concepts::ForwardIterator<It>) {
39 // Since first is an input iterator, and we are performing a copy, we can
40 // read the previous value from first.
41
42 *out = *first;
43 ++out;
44 auto prev = first;
45 for (++first; first != last; ++first) {
47 prev = first;
48 *out = *first;
49 ++out;
50 }
51 }
52 } else {
53 // Store the previous value directly, on the stack.
54
56 *out = prev;
57 ++out;
58 for (++first; first != last; ++first) {
60 prev = *first;
61 *out = prev;
62 ++out;
63 }
64 }
65 }
66
67 return { util::move(first), util::move(out) };
68 }
69
70 template<concepts::InputContainer Con, concepts::WeaklyIncrementable Out, typename Proj = function::Identity,
71 concepts::IndirectEquivalenceRelation<meta::Projected<meta::ContainerIterator<Con>, Proj>> Comp =
72 function::Equal>
73 requires(concepts::IndirectlyCopyable<meta::ContainerIterator<Con>, Out> &&
74 (concepts::ForwardIterator<meta::ContainerIterator<Con>> ||
75 (concepts::InputIterator<Out> &&
76 concepts::SameAs<meta::ContainerValue<Con>, meta::ContainerValue<Out>>) ||
77 concepts::IndirectlyCopyableStorable<meta::ContainerIterator<Con>, Out>) )
78 constexpr auto operator()(Con&& container, Out out, Comp comp = {}, Proj proj = {}) const
80 return (*this)(container::begin(container), container::end(container), util::move(out), util::ref(comp),
82 }
83 };
84}
85
86constexpr inline auto unique_copy = detail::UniqueCopyFunction {};
87}
88
89namespace di {
91}
Definition forward_iterator.h:10
Definition indirectly_copyable_storable.h:10
Definition indirectly_copyable.h:9
Definition input_iterator.h:9
Definition core.h:114
Definition sequence.h:13
constexpr auto last(concepts::detail::ConstantVector auto &vector, size_t count)
Definition vector_last.h:13
constexpr auto first(concepts::detail::ConstantVector auto &vector, size_t count)
Definition vector_first.h:13
Definition sequence.h:12
constexpr auto prev
Definition prev.h:28
constexpr auto unique_copy
Definition unique_copy.h:86
constexpr auto end
Definition end.h:47
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
meta::Type< decltype(container::iterator_value(types::in_place_type< meta::RemoveCVRef< T > >))> IteratorValue
Definition iterator_value.h:8
IteratorValue< ContainerIterator< T > > ContainerValue
Definition container_value.h:8
constexpr auto ref
Definition reference_wrapper.h:98
Definition zstring_parser.h:9
constexpr auto proj
Definition proj.h:59
Definition in_out_result.h:8