sparrow ..
Loading...
Searching...
No Matches
u8_buffer.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
17#include <ranges>
18#include <type_traits>
19
24
25namespace sparrow
26{
27
28 namespace detail
29 {
35 template <class T>
36 class holder
37 {
38 public:
39
40 using inner_type = T;
41
48 template <class... Args>
49 constexpr holder(Args&&... args) noexcept
50 : value(std::forward<Args>(args)...)
51 {
52 }
53
55
61 [[nodiscard]] constexpr T extract_storage() && noexcept
62 {
63 return std::move(value);
64 }
65
71 [[nodiscard]] constexpr const T& storage() const noexcept
72 {
73 return value;
74 }
75
81 [[nodiscard]] constexpr T& storage() noexcept
82 {
83 return value;
84 }
85
91 constexpr void assign(T&& other)
92 {
93 value = std::move(other);
94 }
95 };
96 }
97
104 template <class T>
105 class u8_buffer : private detail::holder<buffer<std::uint8_t>>,
106 public buffer_adaptor<T, buffer<std::uint8_t>&>
107 {
108 public:
109
113 using default_allocator_type = std::allocator<std::uint8_t>;
114
120 constexpr u8_buffer(u8_buffer&& other) noexcept;
121
127 constexpr u8_buffer(const u8_buffer& other);
128
132 u8_buffer& operator=(u8_buffer&& other) = delete;
133
137 u8_buffer& operator=(u8_buffer& other) = delete;
138
142 ~u8_buffer() = default;
148 constexpr explicit u8_buffer(std::size_t n);
149
156 constexpr u8_buffer(std::size_t n, const T& val);
157
166 template <std::ranges::input_range R>
167 requires(
168 !std::same_as<u8_buffer<T>, std::decay_t<R>>
169 && std::convertible_to<std::ranges::range_value_t<R>, T>
170 )
171 constexpr explicit u8_buffer(R&& range);
172
178 constexpr u8_buffer(std::initializer_list<T> ilist);
179
191 template <allocator A = default_allocator_type>
192 constexpr u8_buffer(T* data_ptr, std::size_t count, const A& a = A());
193 };
194
195 template <class T>
196 constexpr u8_buffer<T>::u8_buffer(u8_buffer&& other) noexcept
197 : holder_type(std::move(other).extract_storage())
199 {
200 }
201
202 template <class T>
203 constexpr u8_buffer<T>::u8_buffer(const u8_buffer& other)
204 : holder_type(other.storage())
206 {
207 }
208
209 template <class T>
210 constexpr u8_buffer<T>::u8_buffer(std::size_t n)
211 : holder_type{n * sizeof(T)}
213 {
214 }
215
216 template <class T>
217 constexpr u8_buffer<T>::u8_buffer(std::size_t n, const T& val)
218 : u8_buffer(n)
219 {
220 std::fill(this->begin(), this->end(), val);
221 }
222
223 template <class T>
224 template <std::ranges::input_range R>
225 requires(
226 !std::same_as<u8_buffer<T>, std::decay_t<R>> && std::convertible_to<std::ranges::range_value_t<R>, T>
227 )
228 constexpr u8_buffer<T>::u8_buffer(R&& range)
229 : u8_buffer(range_size(range))
230 {
231 sparrow::ranges::copy(range, this->begin());
232 }
233
234 template <class T>
235 constexpr u8_buffer<T>::u8_buffer(std::initializer_list<T> ilist)
236 : u8_buffer(ilist.size())
237 {
238 std::copy(ilist.begin(), ilist.end(), this->begin());
239 }
240
241 template <class T>
242 template <allocator A>
243 constexpr u8_buffer<T>::u8_buffer(T* data_ptr, std::size_t count, const A& a)
244 : holder_type{reinterpret_cast<uint8_t*>(data_ptr), count * sizeof(T), a}
246 {
247 }
248}
constexpr size_type size() const noexcept(!SPARROW_CONTRACTS_THROW_ON_FAILURE)
A holder class that wraps a value and provides storage management.
Definition u8_buffer.hpp:37
constexpr void assign(T &&other)
Assigns a new value to the storage.
Definition u8_buffer.hpp:91
constexpr T extract_storage() &&noexcept
Extracts the storage by moving the wrapped value.
Definition u8_buffer.hpp:61
constexpr T & storage() noexcept
Gets a reference to the storage.
Definition u8_buffer.hpp:81
constexpr holder(Args &&... args) noexcept
Constructs a holder with the given arguments forwarded to the wrapped value.
Definition u8_buffer.hpp:49
constexpr const T & storage() const noexcept
Gets a constant reference to the storage.
Definition u8_buffer.hpp:71
buffer_adaptor< IT, buffer< std::uint8_t > & > buffer_adaptor_type
u8_buffer & operator=(u8_buffer &&other)=delete
Move assignment operator (deleted).
constexpr u8_buffer(std::size_t n)
Constructs a buffer with n uninitialized elements.
constexpr u8_buffer(std::initializer_list< T > ilist)
Constructs a buffer with the elements of the initializer list ilist.
u8_buffer & operator=(u8_buffer &other)=delete
Copy assignment operator (deleted).
constexpr buffer< std::uint8_t > extract_storage() &&noexcept
Extracts the storage by moving the wrapped value.
Definition u8_buffer.hpp:61
detail::holder< buffer< std::uint8_t > > holder_type
constexpr u8_buffer(const u8_buffer &other)
Copy constructor.
constexpr u8_buffer(T *data_ptr, std::size_t count, const A &a=A())
Constructs a buffer by taking ownership of the storage pointed to by data_ptr.
constexpr u8_buffer(R &&range)
Constructs a buffer with the elements of the range range.
constexpr u8_buffer(std::size_t n, const T &val)
Constructs a buffer with n elements, each initialized to val.
std::allocator< std::uint8_t > default_allocator_type
~u8_buffer()=default
Destructor.
constexpr u8_buffer(u8_buffer &&other) noexcept
Move constructor.
constexpr std::ranges::copy_result< std::ranges::borrowed_iterator_t< R >, O > copy(R &&r, O result)
Definition ranges.hpp:117
constexpr std::size_t range_size(R &&r)
Definition ranges.hpp:32