sparrow 0.9.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
43 using is_buffer_view = std::true_type;
44
47 using reverse_iterator = std::reverse_iterator<iterator>;
48 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
49
50 buffer_view() = default;
52 requires(!std::is_const_v<T>);
53 template <class U>
54 requires std::same_as<std::remove_const_t<T>, U>
55 explicit buffer_view(const buffer<U>& buffer);
57
58 template <class It, class End>
59 requires std::contiguous_iterator<It> && std::sentinel_for<End, It>
60 && std::same_as<std::remove_const_t<std::iter_value_t<It>>, std::remove_const_t<T>>
61 buffer_view(It first, End last);
62
63 [[nodiscard]] bool empty() const noexcept;
64 [[nodiscard]] size_type size() const noexcept;
65 [[nodiscard]] size_type max_size() const noexcept;
66
67 reference operator[](size_type);
68 const_reference operator[](size_type) const;
69
71 const_reference front() const;
72
74 const_reference back() const;
75
76 template <class U = T>
77 U* data() noexcept;
78
79 template <class U = T>
80 const U* data() const noexcept;
81
83 iterator end();
84
85 const_iterator begin() const;
86 const_iterator end() const;
87 const_iterator cbegin() const;
88 const_iterator cend() const;
89
92
97
98 void swap(buffer_view& rhs) noexcept;
99
100 buffer_view subrange(size_type pos, size_type count) const;
101 buffer_view subrange(size_type pos) const;
103
104 operator buffer<std::remove_const_t<T>>() const;
105
106 private:
107
108 pointer p_data = nullptr;
109 size_type m_size = 0u;
110 };
111
112 template <class T>
113 bool operator==(const buffer_view<T>& lhs, const buffer_view<T>& rhs);
114
115 /******************************
116 * buffer_view implementation *
117 ******************************/
118
119 template <class T>
121 requires(!std::is_const_v<T>)
122 : p_data(buffer.data())
123 , m_size(buffer.size())
124 {
125 }
126
127 template <class T>
128 template <class U>
129 requires std::same_as<std::remove_const_t<T>, U>
131 : p_data(buffer.data())
132 , m_size(buffer.size())
133 {
134 }
135
136 template <class T>
138 : p_data(p)
139 , m_size(n)
140 {
141 SPARROW_ASSERT_TRUE(p != nullptr || n == 0u);
142 }
143
144 template <class T>
145 template <class It, class End>
146 requires std::contiguous_iterator<It> && std::sentinel_for<End, It>
147 && std::same_as<std::remove_const_t<std::iter_value_t<It>>, std::remove_const_t<T>>
148 buffer_view<T>::buffer_view(It first, End last)
149 : p_data(std::to_address(first))
150 , m_size(static_cast<size_type>(std::distance(first, last)))
151 {
152 SPARROW_ASSERT_TRUE(first <= last);
153 }
154
155 template <class T>
156 bool buffer_view<T>::empty() const noexcept
157 {
158 return size() == size_type(0);
159 }
160
161 template <class T>
162 auto buffer_view<T>::size() const noexcept -> size_type
163 {
164 return m_size;
165 }
166
167 template <class T>
168 auto buffer_view<T>::max_size() const noexcept -> size_type
169 {
170 return size();
171 }
172
173 template <class T>
175 {
176 SPARROW_ASSERT_TRUE(pos < size());
177 return data()[pos];
178 }
179
180 template <class T>
182 {
183 SPARROW_ASSERT_TRUE(pos < size());
184 return data()[pos];
185 }
186
187 template <class T>
189 {
191 return data()[0];
192 }
193
194 template <class T>
196 {
198 return data()[0];
199 }
200
201 template <class T>
203 {
205 return data()[m_size - 1];
206 }
207
208 template <class T>
210 {
212 return data()[m_size - 1];
213 }
214
215 template <class T>
216 template <class U>
218 {
219#if defined(__GNUC__)
220# pragma GCC diagnostic push
221# pragma GCC diagnostic ignored "-Wcast-align"
222#endif
223 return reinterpret_cast<U*>(p_data);
224#if defined(__GNUC__)
225# pragma GCC diagnostic pop
226#endif
227 }
228
229 template <class T>
230 template <class U>
231 const U* buffer_view<T>::data() const noexcept
232 {
233#if defined(__GNUC__)
234# pragma GCC diagnostic push
235# pragma GCC diagnostic ignored "-Wcast-align"
236#endif
237 return reinterpret_cast<const U*>(p_data);
238#if defined(__GNUC__)
239# pragma GCC diagnostic pop
240#endif
241 }
242
243 template <class T>
245 {
246 return iterator(p_data);
247 }
248
249 template <class T>
251 {
252 return iterator(p_data + m_size);
253 }
254
255 template <class T>
257 {
258 return cbegin();
259 }
260
261 template <class T>
263 {
264 return cend();
265 }
266
267 template <class T>
269 {
270 return const_iterator(p_data);
271 }
272
273 template <class T>
275 {
276 return const_iterator(p_data + m_size);
277 }
278
279 template <class T>
281 {
282 return reverse_iterator(end());
283 }
284
285 template <class T>
287 {
288 return reverse_iterator(begin());
289 }
290
291 template <class T>
293 {
294 return crbegin();
295 }
296
297 template <class T>
299 {
300 return crend();
301 }
302
303 template <class T>
308
309 template <class T>
314
315 template <class T>
317 {
318 std::swap(p_data, rhs.p_data);
319 std::swap(m_size, rhs.m_size);
320 }
321
322 template <class T>
324 {
325 SPARROW_ASSERT_TRUE(pos <= size());
326 SPARROW_ASSERT_TRUE(count <= size() - pos);
327 return buffer_view<T>(p_data + pos, count);
328 }
329
330 template <class T>
332 {
333 SPARROW_ASSERT_TRUE(pos <= size());
334 return buffer_view<T>(p_data + pos, size() - pos);
335 }
336
337 template <class T>
339 {
340 SPARROW_ASSERT_TRUE(first >= begin() && last <= end());
341 return buffer_view<T>(first, last);
342 }
343
344 template <class T>
346 {
347 if (!p_data)
348 {
350 }
351 else
352 {
354 }
355 }
356
357 template <class T>
358 bool operator==(const buffer_view<T>& lhs, const buffer_view<T>& rhs)
359 {
360 return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
361 }
362}
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:112
#define SPARROW_ASSERT_TRUE(expr__)
SPARROW_API bool operator==(const array &lhs, const array &rhs)
Compares the content of two arrays.