Iros
 
Loading...
Searching...
No Matches
cache_last_view.h
Go to the documentation of this file.
1#pragma once
2
17#include "di/meta/core.h"
18#include "di/meta/language.h"
19#include "di/meta/operations.h"
20#include "di/util/addressof.h"
22
23namespace di::container {
24namespace detail {
25 template<typename T>
26 constexpr auto as_lvalue(T&& value) -> T& {
27 return value;
28 }
29}
30
31template<concepts::InputContainer Con>
32class CacheLastView : public ViewInterface<CacheLastView<Con>> {
33private:
34 using Reference = meta::ContainerReference<Con>;
37
39
40 class Iterator
41 : public IteratorBase<Iterator, InputIteratorTag, meta::ContainerValue<Con>, meta::ContainerSSizeType<Con>> {
42 private:
43 friend class CacheLastView;
44
45 constexpr explicit Iterator(CacheLastView& parent)
46 : m_parent(di::addressof(parent)), m_iterator(di::begin(parent.m_container)) {}
47
48 public:
49 Iterator(Iterator&&) = default;
50 auto operator=(Iterator&&) -> Iterator& = default;
51
52 constexpr auto base() const& -> It const& { return m_iterator; }
53 constexpr auto base() && -> It { return di::move(m_iterator); }
54
55 constexpr auto operator*() const -> Reference& {
56 if constexpr (concepts::Reference<Reference>) {
57 if (!m_parent->m_last_value) {
58 m_parent->m_last_value = di::addressof(detail::as_lvalue(*m_iterator));
59 }
60 return **m_parent->m_last_value;
61 } else {
62 if (!m_parent->m_last_value) {
63 m_parent->m_last_value.emplace_deref(m_iterator);
64 }
65 return *m_parent->m_last_value;
66 }
67 }
68
69 constexpr void advance_one() {
70 ++m_iterator;
71 m_parent->m_last_value.reset();
72 }
73
74 private:
75 constexpr friend auto tag_invoke(di::Tag<iterator_move>, Iterator const& self) -> meta::ContainerRValue<Con> {
76 return iterator_move(self.m_iterator);
77 }
78
79 constexpr friend void tag_invoke(di::Tag<iterator_swap>, Iterator& a, Iterator& b)
81 {
82 iterator_swap(a.m_iterator, b.m_iterator);
83 }
84
85 CacheLastView* m_parent;
86 It m_iterator;
87 };
88
89 class Sentinel : public SentinelBase<Sentinel> {
90 private:
91 friend class CacheLastView;
92
93 constexpr explicit Sentinel(CacheLastView& parent) : m_sentinel(di::end(parent.m_container)) {}
94
95 public:
96 Sentinel() = default;
97
98 constexpr auto base() const -> Sent { return m_sentinel; }
99
100 constexpr auto equals(Iterator const& it) const -> bool { return m_sentinel == it.base(); }
101
102 private:
103 Sent m_sentinel {};
104 };
105
106public:
109 = default;
110
111 constexpr explicit CacheLastView(Con container) : m_container { di::move(container) } {}
112
113 constexpr auto base() const& -> Con
114 requires(concepts::CopyConstructible<Con>)
115 {
116 return m_container;
117 }
118 constexpr auto base() && -> Con { return di::move(m_container); }
119
120 constexpr auto begin() { return Iterator(*this); }
121
122 constexpr auto end() { return Sentinel(*this); }
123
124 constexpr auto size()
126 {
127 return m_container.size();
128 }
129 constexpr auto size() const
130 requires(concepts::SizedContainer<Con const>)
131 {
132 return m_container.size();
133 }
134
135private:
136 Con m_container {};
138};
139}
constexpr auto end()
Definition cache_last_view.h:122
constexpr auto size() const
Definition cache_last_view.h:129
constexpr CacheLastView(Con container)
Definition cache_last_view.h:111
constexpr auto size()
Definition cache_last_view.h:124
constexpr auto base() &&-> Con
Definition cache_last_view.h:118
constexpr auto begin()
Definition cache_last_view.h:120
constexpr auto base() const &-> Con requires(concepts::CopyConstructible< Con >)
Definition cache_last_view.h:113
Definition sentinel_base.h:13
Definition view_interface.h:26
Definition non_propagating_cache.h:9
constexpr auto emplace_deref(I const &it) -> T &requires(
Definition non_propagating_cache.h:36
Definition operations.h:27
Definition indirectly_swappable.h:7
Definition language.h:50
Definition sized_container.h:8
Definition any_storable.h:9
Definition sequence.h:13
constexpr auto as_lvalue(T &&value) -> T &
Definition cache_last_view.h:26
Definition sequence.h:12
constexpr auto iterator_move
Definition iterator_move.h:56
constexpr auto move
Definition move.h:38
constexpr auto iterator_swap
Definition iterator_swap.h:49
IteratorRValue< ContainerIterator< T > > ContainerRValue
Definition container_rvalue.h:8
detail::ConditionalHelper< value, T, U >::Type Conditional
Definition core.h:88
decltype(container::end(util::declval< T & >())) ContainerSentinel
Definition container_sentinel.h:8
IteratorReference< ContainerIterator< T > > ContainerReference
Definition container_reference.h:8
Type< detail::AddPointerHelper< T > > AddPointer
This is a helper template which will convert reference types into their corresponding pointer type,...
Definition language.h:427
decltype(container::begin(util::declval< T & >())) ContainerIterator
Definition container_iterator.h:8
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
Definition zstring_parser.h:9
constexpr tag_invoke_detail::TagInvokeFn tag_invoke
Definition tag_invoke.h:22
constexpr auto end
Definition end.h:47
constexpr auto begin
Definition begin.h:44
Definition iterator_base.h:14