sparrow 0.3.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 }
140
141 template <class T>
142 template <class It, class End>
143 requires std::contiguous_iterator<It> && std::sentinel_for<End, It>
144 && std::same_as<std::remove_const_t<std::iter_value_t<It>>, std::remove_const_t<T>>
145 buffer_view<T>::buffer_view(It first, End last)
146 : p_data(std::to_address(first))
147 , m_size(static_cast<size_type>(std::distance(first, last)))
148 {
149 SPARROW_ASSERT_TRUE(first <= last);
150 }
151
152 template <class T>
153 bool buffer_view<T>::empty() const noexcept
154 {
155 return size() == size_type(0);
156 }
157
158 template <class T>
159 auto buffer_view<T>::size() const noexcept -> size_type
160 {
161 return m_size;
162 }
163
164 template <class T>
165 auto buffer_view<T>::max_size() const noexcept -> size_type
166 {
167 return size();
168 }
169
170 template <class T>
172 {
173 SPARROW_ASSERT_TRUE(pos < size());
174 return data()[pos];
175 }
176
177 template <class T>
179 {
180 SPARROW_ASSERT_TRUE(pos < size());
181 return data()[pos];
182 }
183
184 template <class T>
186 {
188 return data()[0];
189 }
190
191 template <class T>
193 {
195 return data()[0];
196 }
197
198 template <class T>
200 {
202 return data()[m_size - 1];
203 }
204
205 template <class T>
207 {
209 return data()[m_size - 1];
210 }
211
212 template <class T>
213 template <class U>
215 {
216#if defined(__GNUC__)
217# pragma GCC diagnostic push
218# pragma GCC diagnostic ignored "-Wcast-align"
219#endif
220 return reinterpret_cast<U*>(p_data);
221#if defined(__GNUC__)
222# pragma GCC diagnostic pop
223#endif
224 }
225
226 template <class T>
227 template <class U>
228 const U* buffer_view<T>::data() const noexcept
229 {
230#if defined(__GNUC__)
231# pragma GCC diagnostic push
232# pragma GCC diagnostic ignored "-Wcast-align"
233#endif
234 return reinterpret_cast<const U*>(p_data);
235#if defined(__GNUC__)
236# pragma GCC diagnostic pop
237#endif
238 }
239
240 template <class T>
242 {
243 return iterator(p_data);
244 }
245
246 template <class T>
248 {
249 return iterator(p_data + m_size);
250 }
251
252 template <class T>
254 {
255 return cbegin();
256 }
257
258 template <class T>
260 {
261 return cend();
262 }
263
264 template <class T>
266 {
267 return const_iterator(p_data);
268 }
269
270 template <class T>
272 {
273 return const_iterator(p_data + m_size);
274 }
275
276 template <class T>
278 {
279 return reverse_iterator(end());
280 }
281
282 template <class T>
284 {
285 return reverse_iterator(begin());
286 }
287
288 template <class T>
290 {
291 return crbegin();
292 }
293
294 template <class T>
296 {
297 return crend();
298 }
299
300 template <class T>
305
306 template <class T>
311
312 template <class T>
314 {
315 std::swap(p_data, rhs.p_data);
316 std::swap(m_size, rhs.m_size);
317 }
318
319 template <class T>
321 {
322 SPARROW_ASSERT_TRUE(pos <= size());
323 SPARROW_ASSERT_TRUE(count <= size() - pos);
324 return buffer_view<T>(p_data + pos, count);
325 }
326
327 template <class T>
329 {
330 SPARROW_ASSERT_TRUE(pos <= size());
331 return buffer_view<T>(p_data + pos, size() - pos);
332 }
333
334 template <class T>
336 {
337 SPARROW_ASSERT_TRUE(first >= begin() && last <= end());
338 return buffer_view<T>(first, last);
339 }
340
341 template <class T>
343 {
344 return {p_data, p_data + m_size};
345 }
346
347 template <class T>
348 bool operator==(const buffer_view<T>& lhs, const buffer_view<T>& rhs)
349 {
350 return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
351 }
352}
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.