sparrow 2.2.1
C++20 idiomatic APIs for the Apache Arrow Columnar Format
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
21
22namespace sparrow
23{
24 template <class T>
25 class buffer_view;
26
27 namespace copy_tracker
28 {
29 template <typename T>
31 std::string key()
32 {
33 return "buffer_view<" + std::string(typeid(typename T::value_type).name()) + ">";
34 }
35 }
36
37 /*
38 * Non-owning view of a contiguous sequence of objects of type T.
39 *
40 * Although this class looks very similar to std::span, it provides
41 * methods that are missing in C++20 std::span (like cbegin / cend),
42 * and additional std::vector-like APIs.
43 */
44 template <class T>
46 {
47 public:
48
50 using value_type = T;
51 using reference = T&;
52 using const_reference = const T&;
53 using pointer = T*;
54 using const_pointer = const T*;
55 using size_type = std::size_t;
56 using difference_type = std::ptrdiff_t;
57
58 using is_buffer_view = std::true_type;
59
62 using reverse_iterator = std::reverse_iterator<iterator>;
63 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
64
65 constexpr buffer_view() = default;
66 constexpr buffer_view(const buffer_view&);
67 constexpr buffer_view(buffer_view&&) noexcept = default;
68 constexpr buffer_view& operator=(const buffer_view&);
69 constexpr buffer_view& operator=(buffer_view&&) noexcept = default;
70 constexpr explicit buffer_view(buffer<T>& buffer)
71 requires(!std::is_const_v<T>);
72 template <class U>
73 requires std::same_as<std::remove_const_t<T>, U>
74 constexpr explicit buffer_view(const buffer<U>& buffer);
75 constexpr buffer_view(pointer p, size_type n);
76
77 template <class It, class End>
78 requires std::contiguous_iterator<It> && std::sentinel_for<End, It>
79 && std::same_as<std::remove_const_t<std::iter_value_t<It>>, std::remove_const_t<T>>
80 constexpr buffer_view(It first, End last);
81
82 [[nodiscard]] constexpr bool empty() const noexcept;
83 [[nodiscard]] constexpr size_type size() const noexcept;
84 [[nodiscard]] constexpr size_type max_size() const noexcept;
85
86 constexpr reference operator[](size_type);
87 constexpr const_reference operator[](size_type) const;
88
89 constexpr reference front();
90 constexpr const_reference front() const;
91
92 constexpr reference back();
93 constexpr const_reference back() const;
94
95 template <class U = T>
96 constexpr U* data() noexcept;
97
98 template <class U = T>
99 constexpr const U* data() const noexcept;
100
101 constexpr iterator begin();
102 constexpr iterator end();
103
104 constexpr const_iterator begin() const;
105 constexpr const_iterator end() const;
106 constexpr const_iterator cbegin() const;
107 constexpr const_iterator cend() const;
108
109 constexpr reverse_iterator rbegin();
110 constexpr reverse_iterator rend();
111
112 constexpr const_reverse_iterator rbegin() const;
113 constexpr const_reverse_iterator rend() const;
114 constexpr const_reverse_iterator crbegin() const;
115 constexpr const_reverse_iterator crend() const;
116
117 constexpr void swap(buffer_view& rhs) noexcept;
118
119 constexpr buffer_view subrange(size_type pos, size_type count) const;
120 constexpr buffer_view subrange(size_type pos) const;
121 constexpr buffer_view subrange(const_iterator first, const_iterator last) const;
122
123 constexpr operator buffer<std::remove_const_t<T>>() const;
124
125 private:
126
127 pointer p_data = nullptr;
128 size_type m_size = 0u;
129 };
130
131 template <class T>
132 bool operator==(const buffer_view<T>& lhs, const buffer_view<T>& rhs);
133
134 /******************************
135 * buffer_view implementation *
136 ******************************/
137
138 template <class T>
139 constexpr buffer_view<T>::buffer_view(const buffer_view& other)
140 : p_data(other.p_data)
141 , m_size(other.m_size)
142 {
144 }
145
146 template <class T>
148 {
149 if (this != &other)
150 {
151 p_data = other.p_data;
152 m_size = other.m_size;
154 }
155 return *this;
156 }
157
158 template <class T>
160 requires(!std::is_const_v<T>)
161 : p_data(buffer.data())
162 , m_size(buffer.size())
163 {
164 }
165
166 template <class T>
167 template <class U>
168 requires std::same_as<std::remove_const_t<T>, U>
170 : p_data(buffer.data())
171 , m_size(buffer.size())
172 {
173 }
174
175 template <class T>
177 : p_data(p)
178 , m_size(n)
179 {
180 SPARROW_ASSERT_TRUE(p != nullptr || n == 0u);
181 }
182
183 template <class T>
184 template <class It, class End>
185 requires std::contiguous_iterator<It> && std::sentinel_for<End, It>
186 && std::same_as<std::remove_const_t<std::iter_value_t<It>>, std::remove_const_t<T>>
187 constexpr buffer_view<T>::buffer_view(It first, End last)
188 : p_data(std::to_address(first))
189 , m_size(static_cast<size_type>(std::distance(first, last)))
190 {
191 SPARROW_ASSERT_TRUE(first <= last);
192 }
193
194 template <class T>
195 constexpr bool buffer_view<T>::empty() const noexcept
196 {
197 return size() == size_type(0);
198 }
199
200 template <class T>
201 constexpr auto buffer_view<T>::size() const noexcept -> size_type
202 {
203 return m_size;
204 }
205
206 template <class T>
207 constexpr auto buffer_view<T>::max_size() const noexcept -> size_type
208 {
209 return size();
210 }
211
212 template <class T>
214 {
215 SPARROW_ASSERT_TRUE(pos < size());
216 return data()[pos];
217 }
218
219 template <class T>
221 {
222 SPARROW_ASSERT_TRUE(pos < size());
223 return data()[pos];
224 }
225
226 template <class T>
228 {
230 return data()[0];
231 }
232
233 template <class T>
234 constexpr auto buffer_view<T>::front() const -> const_reference
235 {
237 return data()[0];
238 }
239
240 template <class T>
241 constexpr auto buffer_view<T>::back() -> reference
242 {
244 return data()[m_size - 1];
245 }
246
247 template <class T>
248 constexpr auto buffer_view<T>::back() const -> const_reference
249 {
251 return data()[m_size - 1];
252 }
253
254 template <class T>
255 template <class U>
256 constexpr U* buffer_view<T>::data() noexcept
257 {
258#if defined(__GNUC__)
259# pragma GCC diagnostic push
260# pragma GCC diagnostic ignored "-Wcast-align"
261#endif
262 return reinterpret_cast<U*>(p_data);
263#if defined(__GNUC__)
264# pragma GCC diagnostic pop
265#endif
266 }
267
268 template <class T>
269 template <class U>
270 constexpr const U* buffer_view<T>::data() const noexcept
271 {
272#if defined(__GNUC__)
273# pragma GCC diagnostic push
274# pragma GCC diagnostic ignored "-Wcast-align"
275#endif
276 return reinterpret_cast<const U*>(p_data);
277#if defined(__GNUC__)
278# pragma GCC diagnostic pop
279#endif
280 }
281
282 template <class T>
283 constexpr auto buffer_view<T>::begin() -> iterator
284 {
285 return iterator(p_data);
286 }
287
288 template <class T>
289 constexpr auto buffer_view<T>::end() -> iterator
290 {
291 return iterator(p_data + m_size);
292 }
293
294 template <class T>
295 constexpr auto buffer_view<T>::begin() const -> const_iterator
296 {
297 return cbegin();
298 }
299
300 template <class T>
301 constexpr auto buffer_view<T>::end() const -> const_iterator
302 {
303 return cend();
304 }
305
306 template <class T>
307 constexpr auto buffer_view<T>::cbegin() const -> const_iterator
308 {
309 return const_iterator(p_data);
310 }
311
312 template <class T>
313 constexpr auto buffer_view<T>::cend() const -> const_iterator
314 {
315 return const_iterator(p_data + m_size);
316 }
317
318 template <class T>
320 {
321 return reverse_iterator(end());
322 }
323
324 template <class T>
326 {
327 return reverse_iterator(begin());
328 }
329
330 template <class T>
332 {
333 return crbegin();
334 }
335
336 template <class T>
338 {
339 return crend();
340 }
341
342 template <class T>
344 {
346 }
347
348 template <class T>
350 {
352 }
353
354 template <class T>
355 constexpr void buffer_view<T>::swap(buffer_view<T>& rhs) noexcept
356 {
357 std::swap(p_data, rhs.p_data);
358 std::swap(m_size, rhs.m_size);
359 }
360
361 template <class T>
363 {
364 SPARROW_ASSERT_TRUE(pos <= size());
365 SPARROW_ASSERT_TRUE(count <= size() - pos);
366 return buffer_view<T>(p_data + pos, count);
367 }
368
369 template <class T>
371 {
372 SPARROW_ASSERT_TRUE(pos <= size());
373 return buffer_view<T>(p_data + pos, size() - pos);
374 }
375
376 template <class T>
378 {
379 SPARROW_ASSERT_TRUE(first >= begin() && last <= end());
380 return buffer_view<T>(first, last);
381 }
382
383 template <class T>
385 {
386 if (!p_data)
387 {
389 }
390 else
391 {
393 cbegin(),
394 cend(),
395 typename buffer<std::remove_const_t<T>>::default_allocator{}
396 );
397 }
398 }
399
400 template <class T>
401 bool operator==(const buffer_view<T>& lhs, const buffer_view<T>& rhs)
402 {
403 return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
404 }
405}
constexpr bool empty() const noexcept
constexpr iterator end()
constexpr reverse_iterator rend()
constexpr U * data() noexcept
pointer_iterator< pointer > iterator
constexpr const_iterator cbegin() const
constexpr buffer_view subrange(size_type pos, size_type count) const
std::ptrdiff_t difference_type
pointer_iterator< const_pointer > const_iterator
constexpr buffer_view & operator=(const buffer_view &)
constexpr size_type max_size() const noexcept
constexpr reference back()
constexpr reference operator[](size_type)
constexpr size_type size() const noexcept
constexpr const_iterator cend() const
constexpr buffer_view(buffer_view &&) noexcept=default
constexpr reference front()
constexpr iterator begin()
constexpr reverse_iterator rbegin()
std::reverse_iterator< iterator > reverse_iterator
buffer_view< T > self_type
constexpr buffer_view()=default
constexpr const_reverse_iterator crend() const
constexpr void swap(buffer_view &rhs) noexcept
constexpr const_reverse_iterator crbegin() const
std::reverse_iterator< const_iterator > const_reverse_iterator
Object that owns a piece of contiguous memory.
Definition buffer.hpp:131
#define SPARROW_ASSERT_TRUE(expr__)
SPARROW_API void increase(const std::string &key)
std::string key()
Definition buffer.hpp:49
constexpr bool is_type_instance_of_v
Variable template for convenient access to is_type_instance_of.
Definition mp_utils.hpp:102
SPARROW_API bool operator==(const array &lhs, const array &rhs)
Compares the content of two arrays.
Extensions to the C++ standard library.