Iros
 
Loading...
Searching...
No Matches
split_view.h
Go to the documentation of this file.
1#pragma once
2
9#include "di/function/equal.h"
10#include "di/util/move.h"
12
13namespace di::container {
14template<concepts::ForwardContainer View, concepts::ForwardContainer Pattern>
15requires(
16 concepts::View<View> && concepts::View<Pattern> &&
17 concepts::IndirectlyComparable<meta::ContainerIterator<View>, meta::ContainerIterator<Pattern>, function::Equal>)
18class SplitView : public ViewInterface<SplitView<View, Pattern>> {
19private:
20 friend struct Sentinel;
21 friend struct Iterator;
22
24
25 struct Iterator : public IteratorBase<Iterator, ForwardIteratorTag, Value, meta::ContainerSSizeType<View>> {
26 public:
27 Iterator() = default;
28
29 constexpr Iterator(SplitView& parent, meta::ContainerIterator<View> base, Value next)
30 : m_parent(util::addressof(parent)), m_base(util::move(base)), m_next(util::move(next)) {}
31
32 constexpr auto base() const { return m_base; }
33
34 constexpr auto operator*() const -> Value {
36 }
37
38 constexpr void advance_one() {
39 m_base = container::begin(m_next);
40 if (m_base != container::end(m_parent->m_base)) {
41 m_base = container::end(m_next);
42 if (m_base == container::end(m_parent->m_base)) {
43 m_trailing_empty = true;
44 m_next = container::reconstruct(in_place_type<View>, m_base, m_base);
45 } else {
46 m_next = m_parent->find_next(m_base);
47 }
48 } else {
49 m_trailing_empty = false;
50 }
51 }
52
53 private:
54 friend struct Sentinel;
55
56 constexpr friend auto operator==(Iterator const& a, Iterator const& b) -> bool {
57 return a.m_base == b.m_base && a.m_trailing_empty == b.m_trailing_empty;
58 }
59
60 SplitView* m_parent { nullptr };
61 meta::ContainerIterator<View> m_base;
62 Value m_next;
63 bool m_trailing_empty { false };
64 };
65
66 struct Sentinel {
67 public:
68 Sentinel() = default;
69
70 constexpr explicit Sentinel(SplitView& parent) : m_base(container::end(parent.m_base)) {}
71
72 private:
73 constexpr friend auto operator==(Iterator const& a, Sentinel const& b) -> bool {
74 return a.m_base == b.m_base && !a.m_trailing_empty;
75 }
76
77 meta::ContainerSentinel<View> m_base;
78 };
79
80public:
83 = default;
84
85 constexpr SplitView(View base, Pattern pattern) : m_base(util::move(base)), m_pattern(util::move(pattern)) {}
86
87 template<concepts::InputContainer Con>
91 : m_base(view::all(util::forward<Con>(container))), m_pattern(SingleView { util::move(value) }) {}
92
93 constexpr auto base() const& -> View
94 requires(concepts::CopyConstructible<View>)
95 {
96 return m_base;
97 }
98 constexpr auto base() && -> View { return util::move(m_base); }
99
100 constexpr auto begin() -> Iterator {
101 if (!m_cached_begin) {
102 m_cached_begin = this->find_next(container::begin(m_base));
103 }
104 return { *this, container::begin(m_base), *m_cached_begin };
105 }
106
107 constexpr auto end() {
108 if constexpr (concepts::CommonContainer<View>) {
109 return Iterator { *this, container::end(m_base),
111 container::end(m_base)) };
112 } else {
113 return Sentinel { *this };
114 }
115 }
116
117private:
118 constexpr auto find_next(meta::ContainerIterator<View> it) -> Value {
119 auto [start, end] = container::search(container::View(it, container::end(m_base)), m_pattern);
120 if (start != container::end(m_base) && container::empty(m_pattern)) {
121 ++start;
122 ++end;
123 }
124 return container::reconstruct(in_place_type<View>, util::move(start), util::move(end));
125 }
126
127 View m_base;
128 Pattern m_pattern;
129 Optional<Value> m_cached_begin;
130};
131
132template<typename Con, typename Pattern>
134
135template<concepts::InputContainer Con>
137}
Definition single_view.h:15
Definition split_view.h:18
constexpr SplitView(Con &&container, meta::ContainerValue< Con > value)
Definition split_view.h:90
constexpr SplitView(View base, Pattern pattern)
Definition split_view.h:85
constexpr auto end()
Definition split_view.h:107
constexpr auto begin() -> Iterator
Definition split_view.h:100
constexpr auto base() &&-> View
Definition split_view.h:98
constexpr auto base() const &-> View requires(concepts::CopyConstructible< View >)
Definition split_view.h:93
Definition view_interface.h:26
Definition view.h:35
Definition common_container.h:10
Definition operations.h:11
Definition operations.h:27
constexpr auto operator==(Duration< Rep1, Period1 > const &a, Duration< Rep2, Period2 > const &b) -> bool
Definition duration.h:108
Definition any_storable.h:9
Definition adjacent.h:8
Definition sequence.h:12
constexpr auto next
Definition next.h:35
constexpr auto empty
Definition empty.h:45
constexpr auto reconstruct
Definition reconstruct.h:75
constexpr auto move
Definition move.h:38
constexpr auto search
Definition search.h:36
View(Iter, Sent) -> View< Iter, Sent >
constexpr auto end
Definition end.h:47
constexpr auto begin
Definition begin.h:44
SplitView(Con &&, Pattern &&) -> SplitView< meta::AsView< Con >, meta::AsView< Pattern > >
decltype(container::reconstruct(in_place_type< T >, util::declval< It >(), util::declval< Sent >())) Reconstructed
Definition reconstructed.h:11
decltype(container::view::all(util::declval< Con >())) AsView
Definition as_view.h:9
IteratorValue< ContainerIterator< T > > ContainerValue
Definition container_value.h:8
decltype(container::begin(util::declval< T & >())) ContainerIterator
Definition container_iterator.h:8
Definition vocab.h:96
constexpr auto in_place_type
Definition in_place_type.h:12
constexpr auto end
Definition end.h:47
Definition iterator_base.h:14