OGS
ContainerTools.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#pragma once
5
6#include <memory>
7#include <type_traits>
8
9namespace BaseLib
10{
11namespace detail
12{
13
14template <typename Element>
16
17template <typename Element>
19{
20 using value_type = Element;
21 using difference_type = std::ptrdiff_t;
22
24
26 std::size_t n,
28 view) noexcept
29 : n_{n}, view_{view}
30 {
31 }
32
34 {
35 ++n_;
36 return *this;
37 }
39 {
40 auto copy{*this};
41 operator++();
42 return copy;
43 }
44
46 {
47 --n_;
48 return *this;
49 }
51 {
52 auto copy{*this};
53 operator--();
54 return copy;
55 }
56
58 difference_type const increment) noexcept
59 {
60 n_ += increment;
61 return *this;
62 }
64 difference_type const decrement) noexcept
65 {
66 n_ -= decrement;
67 return *this;
68 }
69
72 difference_type const increment) noexcept
73 {
74 iterator.n_ += increment;
75 return iterator;
76 }
77
79 difference_type const increment,
81 {
82 iterator.n_ += increment;
83 return iterator;
84 }
85
87 PolymorphicRandomAccessContainerViewIterator const other) const noexcept
88 {
89 assert(view_ == other.view_);
90 return n_ - other.n_;
91 }
92
95 difference_type const decrement) noexcept
96 {
97 iterator.n_ -= decrement;
98 return iterator;
99 }
100
101 [[nodiscard]] Element& operator*() const { return (*view_)[n_]; }
102 [[nodiscard]] Element& operator[](difference_type n) const
103 {
104 return (*view_)[n_ + n];
105 }
106
108 PolymorphicRandomAccessContainerViewIterator const&) const = default;
109
110private:
111 std::size_t n_ = 0;
113 nullptr;
114};
115
116template <typename Element>
118{
120 const noexcept
121 {
122 return {0, this};
123 }
125 const noexcept
126 {
127 return {size(), this};
128 }
129
130 [[nodiscard]] virtual std::size_t size() const noexcept = 0;
131
132 [[nodiscard]] virtual Element& operator[](std::size_t) const = 0;
133
135};
136
137template <typename Element, typename Container>
140{
141 explicit CovariantRandomAccessContainerView(Container& container)
142 : container_{container}
143 {
144 }
145
146 Element& operator[](std::size_t index) const override
147 {
148 if constexpr (requires {
149 typename Container::value_type::element_type;
150 })
151 {
152 static_assert(
153 std::derived_from<typename Container::value_type::element_type,
154 Element>);
155
156 return *container_[index];
157 }
158 else
159 {
160 static_assert(
161 std::derived_from<typename Container::value_type, Element>);
162
163 // this restriction is necessary because of the constness
164 // propagation of std::vector.
165 static_assert(
166 (!std::is_const_v<Container>) || std::is_const_v<Element>,
167 "If the element type is non-const, the container must be "
168 "non-const, too.");
169
170 return container_[index];
171 }
172 }
173
174 std::size_t size() const noexcept override { return container_.size(); }
175
176private:
177 Container& container_;
178};
179} // namespace detail
180
210template <typename Element>
212{
217
218 template <typename Container>
219 explicit(false)
220 // cppcheck-suppress noExplicitConstructor
221 PolymorphicRandomAccessContainerView(Container& container)
222 : impl_{std::make_unique<
224 container)}
225 {
226 }
227
228 template <typename Container>
229 explicit(false)
230 // cppcheck-suppress noExplicitConstructor
231 PolymorphicRandomAccessContainerView(Container const& container)
232 : impl_{std::make_unique<
234 Container const>>(
235 container)}
236 {
237 }
238
243
245 begin() const noexcept
246 {
247 return impl_->begin();
248 }
250 end() const noexcept
251 {
252 return impl_->end();
253 }
254
255 [[nodiscard]] std::size_t size() const noexcept { return impl_->size(); }
256
257 [[nodiscard]] Element& operator[](std::size_t n) const
258 {
259 return (*impl_)[n];
260 }
261
262private:
263 std::unique_ptr<
266};
267} // 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