OGS
ContainerTools.h
Go to the documentation of this file.
1
11#pragma once
12
13#include <memory>
14#include <type_traits>
15
16namespace BaseLib
17{
18namespace detail
19{
20
21template <typename Element>
23
24template <typename Element>
26{
27 using value_type = Element;
28 using difference_type = std::ptrdiff_t;
29
31
33 std::size_t n,
35 view) noexcept
36 : n_{n}, view_{view}
37 {
38 }
39
41 {
42 ++n_;
43 return *this;
44 }
46 {
47 auto copy{*this};
48 operator++();
49 return copy;
50 }
51
53 {
54 --n_;
55 return *this;
56 }
58 {
59 auto copy{*this};
60 operator--();
61 return copy;
62 }
63
65 difference_type const increment) noexcept
66 {
67 n_ += increment;
68 return *this;
69 }
71 difference_type const decrement) noexcept
72 {
73 n_ -= decrement;
74 return *this;
75 }
76
79 difference_type const increment) noexcept
80 {
81 iterator.n_ += increment;
82 return iterator;
83 }
84
86 difference_type const increment,
88 {
89 iterator.n_ += increment;
90 return iterator;
91 }
92
94 PolymorphicRandomAccessContainerViewIterator const other) const noexcept
95 {
96 assert(view_ == other.view_);
97 return n_ - other.n_;
98 }
99
102 difference_type const decrement) noexcept
103 {
104 iterator.n_ -= decrement;
105 return iterator;
106 }
107
108 [[nodiscard]] Element& operator*() const { return (*view_)[n_]; }
109 [[nodiscard]] Element& operator[](difference_type n) const
110 {
111 return (*view_)[n_ + n];
112 }
113
115 PolymorphicRandomAccessContainerViewIterator const&) const = default;
116
117private:
118 std::size_t n_ = 0;
120 nullptr;
121};
122
123template <typename Element>
125{
127 const noexcept
128 {
129 return {0, this};
130 }
132 const noexcept
133 {
134 return {size(), this};
135 }
136
137 [[nodiscard]] virtual std::size_t size() const noexcept = 0;
138
139 [[nodiscard]] virtual Element& operator[](std::size_t) const = 0;
140
142};
143
144template <typename Element, typename Container>
147{
148 explicit CovariantRandomAccessContainerView(Container& container)
149 : container_{container}
150 {
151 }
152
153 Element& operator[](std::size_t index) const override
154 {
155 if constexpr (requires {
156 typename Container::value_type::element_type;
157 })
158 {
159 static_assert(
160 std::derived_from<typename Container::value_type::element_type,
161 Element>);
162
163 return *container_[index];
164 }
165 else
166 {
167 static_assert(
168 std::derived_from<typename Container::value_type, Element>);
169
170 // this restriction is necessary because of the constness
171 // propagation of std::vector.
172 static_assert(
173 (!std::is_const_v<Container>) || std::is_const_v<Element>,
174 "If the element type is non-const, the container must be "
175 "non-const, too.");
176
177 return container_[index];
178 }
179 }
180
181 std::size_t size() const noexcept override { return container_.size(); }
182
183private:
184 Container& container_;
185};
186} // namespace detail
187
217template <typename Element>
219{
224
225 template <typename Container>
226 explicit(false)
227 // cppcheck-suppress noExplicitConstructor
228 PolymorphicRandomAccessContainerView(Container& container)
229 : impl_{std::make_unique<
231 container)}
232 {
233 }
234
235 template <typename Container>
236 explicit(false)
237 // cppcheck-suppress noExplicitConstructor
238 PolymorphicRandomAccessContainerView(Container const& container)
239 : impl_{std::make_unique<
241 Container const>>(
242 container)}
243 {
244 }
245
250
252 begin() const noexcept
253 {
254 return impl_->begin();
255 }
257 end() const noexcept
258 {
259 return impl_->end();
260 }
261
262 [[nodiscard]] std::size_t size() const noexcept { return impl_->size(); }
263
264 [[nodiscard]] Element& operator[](std::size_t n) const
265 {
266 return (*impl_)[n];
267 }
268
269private:
270 std::unique_ptr<
273};
274} // namespace BaseLib
detail::PolymorphicRandomAccessContainerViewIterator< Element > end() const noexcept
detail::PolymorphicRandomAccessContainerViewIterator< Element > begin() const noexcept
PolymorphicRandomAccessContainerView(PolymorphicRandomAccessContainerView const &)=delete
Element & operator[](std::size_t n) const
PolymorphicRandomAccessContainerView(PolymorphicRandomAccessContainerView &&)=default
PolymorphicRandomAccessContainerView & operator=(PolymorphicRandomAccessContainerView &&)=default
std::unique_ptr< detail::PolymorphicRandomAccessContainerViewInterface< Element > > impl_
PolymorphicRandomAccessContainerView & operator=(PolymorphicRandomAccessContainerView const &)=delete
Element & operator[](std::size_t index) const override
std::size_t size() const noexcept override
PolymorphicRandomAccessContainerViewIterator< Element > end() const noexcept
PolymorphicRandomAccessContainerViewIterator< Element > begin() const noexcept
PolymorphicRandomAccessContainerViewIterator & operator+=(difference_type const increment) noexcept
friend PolymorphicRandomAccessContainerViewIterator operator+(PolymorphicRandomAccessContainerViewIterator iterator, difference_type const increment) noexcept
PolymorphicRandomAccessContainerViewIterator(std::size_t n, PolymorphicRandomAccessContainerViewInterface< Element > const *const view) noexcept
friend PolymorphicRandomAccessContainerViewIterator operator-(PolymorphicRandomAccessContainerViewIterator iterator, difference_type const decrement) noexcept
PolymorphicRandomAccessContainerViewIterator & operator++() noexcept
difference_type operator-(PolymorphicRandomAccessContainerViewIterator const other) const noexcept
PolymorphicRandomAccessContainerViewInterface< Element > const * view_
PolymorphicRandomAccessContainerViewIterator operator++(int) noexcept
auto operator<=>(PolymorphicRandomAccessContainerViewIterator const &) const =default
PolymorphicRandomAccessContainerViewIterator operator--(int) noexcept
PolymorphicRandomAccessContainerViewIterator & operator-=(difference_type const decrement) noexcept
friend PolymorphicRandomAccessContainerViewIterator operator+(difference_type const increment, PolymorphicRandomAccessContainerViewIterator iterator) noexcept
PolymorphicRandomAccessContainerViewIterator & operator--() noexcept