sparrow 0.6.0
Loading...
Searching...
No Matches
buffer_view.hpp
Go to the documentation of this file.
1// Copyright 2024 Man Group Operations Limited
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16
19
20namespace sparrow
21{
22 /*
23 * Non-owning view of a contiguous sequence of objects of type T.
24 *
25 * Although this class looks very similar to std::span, it provides
26 * methods that are missing in C++20 std::span (like cbegin / cend),
27 * and additional std::vector-like APIs.
28 */
29 template <class T>
31 {
32 public:
33
35 using value_type = T;
36 using reference = T&;
37 using const_reference = const T&;
38 using pointer = T*;
39 using const_pointer = const T*;
40 using size_type = std::size_t;
41 using difference_type = std::ptrdiff_t;
42
45 using reverse_iterator = std::reverse_iterator<iterator>;
46 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
47
48 buffer_view() = default;
50 requires(!std::is_const_v<T>);
51 template <class U>
52 requires std::same_as<std::remove_const_t<T>, U>
53 explicit buffer_view(const buffer<U>& buffer);
55
56 template <class It, class End>
57 requires std::contiguous_iterator<It> && std::sentinel_for<End, It>
58 && std::same_as<std::remove_const_t<std::iter_value_t<It>>, std::remove_const_t<T>>
59 buffer_view(It first, End last);
60
61 [[nodiscard]] bool empty() const noexcept;
62 [[nodiscard]] size_type size() const noexcept;
63 [[nodiscard]] size_type max_size() const noexcept;
64
65 reference operator[](size_type);
66 const_reference operator[](size_type) const;
67
69 const_reference front() const;
70
72 const_reference back() const;
73
74 template <class U = T>
75 U* data() noexcept;
76
77 template <class U = T>
78 const U* data() const noexcept;
79
81 iterator end();
82
83 const_iterator begin() const;
84 const_iterator end() const;
85 const_iterator cbegin() const;
86 const_iterator cend() const;
87
90
95
96 void swap(buffer_view& rhs) noexcept;
97
98 buffer_view subrange(size_type pos, size_type count) const;
101
102 explicit operator buffer<std::remove_const_t<T>>() const;
103
104 private:
105
106 pointer p_data = nullptr;
107 size_type m_size = 0u;
108 };
109
110 template <class T>
111 bool operator==(const buffer_view<T>& lhs, const buffer_view<T>& rhs);
112
113 /******************************
114 * buffer_view implementation *
115 ******************************/
116
117 template <class T>
119 requires(!std::is_const_v<T>)
120 : p_data(buffer.data())
121 , m_size(buffer.size())
122 {
123 }
124
125 template <class T>
126 template <class U>
127 requires std::same_as<std::remove_const_t<T>, U>
129 : p_data(buffer.data())
130 , m_size(buffer.size())
131 {
132 }
133
134 template <class T>
136 : p_data(p)
137 , m_size(n)
138 {
139 SPARROW_ASSERT_TRUE(p != nullptr || n == 0u);
140 }
141
142 template <class T>
143 template <class It, class End>
144 requires std::contiguous_iterator<It> && std::sentinel_for<End, It>
145 && std::same_as<std::remove_const_t<std::iter_value_t<It>>, std::remove_const_t<T>>
146 buffer_view<T>::buffer_view(It first, End last)
147 : p_data(std::to_address(first))
148 , m_size(static_cast<size_type>(std::distance(first, last)))
149 {
150 SPARROW_ASSERT_TRUE(first <= last);
151 }
152
153 template <class T>
154 bool buffer_view<T>::empty() const noexcept
155 {
156 return size() == size_type(0);
157 }
158
159 template <class T>
160 auto buffer_view<T>::size() const noexcept -> size_type
161 {
162 return m_size;
163 }
164
165 template <class T>
166 auto buffer_view<T>::max_size() const noexcept -> size_type
167 {
168 return size();
169 }
170
171 template <class T>
173 {
174 SPARROW_ASSERT_TRUE(pos < size());
175 return data()[pos];
176 }
177
178 template <class T>
180 {
181 SPARROW_ASSERT_TRUE(pos < size());
182 return data()[pos];
183 }
184
185 template <class T>
187 {
189 return data()[0];
190 }
191
192 template <class T>
194 {
196 return data()[0];
197 }
198
199 template <class T>
201 {
203 return data()[m_size - 1];
204 }
205
206 template <class T>
208 {
210 return data()[m_size - 1];
211 }
212
213 template <class T>
214 template <class U>
216 {
217#if defined(__GNUC__)
218# pragma GCC diagnostic push
219# pragma GCC diagnostic ignored "-Wcast-align"
220#endif
221 return reinterpret_cast<U*>(p_data);
222#if defined(__GNUC__)
223# pragma GCC diagnostic pop
224#endif
225 }
226
227 template <class T>
228 template <class U>
229 const U* buffer_view<T>::data() const noexcept
230 {
231#if defined(__GNUC__)
232# pragma GCC diagnostic push
233# pragma GCC diagnostic ignored "-Wcast-align"
234#endif
235 return reinterpret_cast<const U*>(p_data);
236#if defined(__GNUC__)
237# pragma GCC diagnostic pop
238#endif
239 }
240
241 template <class T>
243 {
244 return iterator(p_data);
245 }
246
247 template <class T>
249 {
250 return iterator(p_data + m_size);
251 }
252
253 template <class T>
255 {
256 return cbegin();
257 }
258
259 template <class T>
261 {
262 return cend();
263 }
264
265 template <class T>
267 {
268 return const_iterator(p_data);
269 }
270
271 template <class T>
273 {
274 return const_iterator(p_data + m_size);
275 }
276
277 template <class T>
279 {
280 return reverse_iterator(end());
281 }
282
283 template <class T>
285 {
286 return reverse_iterator(begin());
287 }
288
289 template <class T>
291 {
292 return crbegin();
293 }
294
295 template <class T>
297 {
298 return crend();
299 }
300
301 template <class T>
306
307 template <class T>
312
313 template <class T>
315 {
316 std::swap(p_data, rhs.p_data);
317 std::swap(m_size, rhs.m_size);
318 }
319
320 template <class T>
322 {
323 SPARROW_ASSERT_TRUE(pos <= size());
324 SPARROW_ASSERT_TRUE(count <= size() - pos);
325 return buffer_view<T>(p_data + pos, count);
326 }
327
328 template <class T>
330 {
331 SPARROW_ASSERT_TRUE(pos <= size());
332 return buffer_view<T>(p_data + pos, size() - pos);
333 }
334
335 template <class T>
337 {
338 SPARROW_ASSERT_TRUE(first >= begin() && last <= end());
339 return buffer_view<T>(first, last);
340 }
341
342 template <class T>
344 {
345 return {p_data, p_data + m_size};
346 }
347
348 template <class T>
349 bool operator==(const buffer_view<T>& lhs, const buffer_view<T>& rhs)
350 {
351 return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
352 }
353}
const_iterator cend() const
bool empty() const noexcept
pointer_iterator< pointer > iterator
U * data() noexcept
const_reverse_iterator crend() const
std::ptrdiff_t difference_type
pointer_iterator< const_pointer > const_iterator
reverse_iterator rbegin()
reference operator[](size_type)
buffer_view subrange(size_type pos, size_type count) const
const_iterator cbegin() const
std::reverse_iterator< iterator > reverse_iterator
size_type max_size() const noexcept
buffer_view< T > self_type
void swap(buffer_view &rhs) noexcept
reverse_iterator rend()
const_reverse_iterator crbegin() const
std::reverse_iterator< const_iterator > const_reverse_iterator
size_type size() const noexcept
Object that owns a piece of contiguous memory.
Definition buffer.hpp:109
#define SPARROW_ASSERT_TRUE(expr__)
SPARROW_API bool operator==(const array &lhs, const array &rhs)
Compares the content of two arrays.