aligator  0.10.0
A primal-dual augmented Lagrangian-type solver for nonlinear trajectory optimization.
Loading...
Searching...
No Matches
span.hpp
Go to the documentation of this file.
1/*
2Copyright 2019-2023 Glen Joseph Fernandes
3(glenjofe@gmail.com)
4
5Distributed under the Boost Software License, Version 1.0.
6(http://www.boost.org/LICENSE_1_0.txt)
7*/
8#ifndef BOOST_CORE_SPAN_HPP
9#define BOOST_CORE_SPAN_HPP
10
11#include "data.hpp"
12#include <array>
13#include <iterator>
14#include <type_traits>
15
16namespace boost {
17
18constexpr std::size_t dynamic_extent = static_cast<std::size_t>(-1);
19
20template<class T, std::size_t E = dynamic_extent>
21class span;
22
23namespace detail {
24
25template<class U, class T>
27 static constexpr bool value = std::is_convertible<U(*)[], T(*)[]>::value;
28};
29
30template<std::size_t E, std::size_t N>
32 static constexpr bool value = E == boost::dynamic_extent || E == N;
33};
34
35template<class T, std::size_t E, class U, std::size_t N>
40
41template<class T>
42using span_uncvref = typename std::remove_cv<typename
43 std::remove_reference<T>::type>::type;
44
45template<class>
47 static constexpr bool value = false;
48};
49
50template<class T, std::size_t E>
51struct span_is_span<boost::span<T, E> > {
52 static constexpr bool value = true;
53};
54
55template<class T>
57 static constexpr bool value = false;
58};
59
60template<class T, std::size_t N>
61struct span_is_array<std::array<T, N> > {
62 static constexpr bool value = true;
63};
64
65template<class T>
66using span_ptr = decltype(boost::data(std::declval<T&>()));
67
68template<class, class = void>
69struct span_data { };
70
71template<class T>
72struct span_data<T,
73 typename std::enable_if<std::is_pointer<span_ptr<T> >::value>::type> {
74 typedef typename std::remove_pointer<span_ptr<T> >::type type;
75};
76
77template<class, class, class = void>
79 static constexpr bool value = false;
80};
81
82template<class R, class T>
83struct span_has_data<R, T, typename std::enable_if<span_convertible<typename
84 span_data<R>::type, T>::value>::type> {
85 static constexpr bool value = true;
86};
87
88template<class, class = void>
90 static constexpr bool value = false;
91};
92
93template<class R>
94struct span_has_size<R, typename
95 std::enable_if<std::is_convertible<decltype(std::declval<R&>().size()),
96 std::size_t>::value>::type> {
97 static constexpr bool value = true;
98};
99
100template<class R, class T>
102 static constexpr bool value = (std::is_const<T>::value ||
103 std::is_lvalue_reference<R>::value) &&
106 !std::is_array<span_uncvref<R> >::value &&
109};
110
111template<std::size_t E, std::size_t N>
113 static constexpr bool value = E == boost::dynamic_extent ||
115};
116
117template<class T, std::size_t E, class U, std::size_t N>
122
123template<std::size_t E, std::size_t O>
124struct span_sub {
125 static constexpr std::size_t value = E == boost::dynamic_extent ?
126 boost::dynamic_extent : E - O;
127};
128
129template<class T, std::size_t E>
131 constexpr span_store(T* p_, std::size_t) noexcept
132 : p(p_) { }
133 static constexpr std::size_t n = E;
134 T* p;
135};
136
137template<class T>
139 constexpr span_store(T* p_, std::size_t n_) noexcept
140 : p(p_)
141 , n(n_) { }
142 T* p;
143 std::size_t n;
144};
145
146template<class T, std::size_t E>
148 static constexpr std::size_t value = sizeof(T) * E;
149};
150
151template<class T>
153 static constexpr std::size_t value = boost::dynamic_extent;
154};
155
156} /* detail */
157
158template<class T, std::size_t E>
159class span {
160public:
161 typedef T element_type;
162 typedef typename std::remove_cv<T>::type value_type;
163 typedef std::size_t size_type;
164 typedef std::ptrdiff_t difference_type;
165 typedef T* pointer;
166 typedef const T* const_pointer;
167 typedef T& reference;
168 typedef const T& const_reference;
169 typedef T* iterator;
170 typedef const T* const_iterator;
171 typedef std::reverse_iterator<T*> reverse_iterator;
172 typedef std::reverse_iterator<const T*> const_reverse_iterator;
173
174 static constexpr std::size_t extent = E;
175
176 template<std::size_t N = E,
177 typename std::enable_if<N == dynamic_extent || N == 0, int>::type = 0>
178 constexpr span() noexcept
179 : s_(0, 0) { }
180
181 template<class I,
182 typename std::enable_if<E == dynamic_extent &&
184 constexpr span(I* f, size_type c)
185 : s_(f, c) { }
186
187 template<class I,
188 typename std::enable_if<E != dynamic_extent &&
190 explicit constexpr span(I* f, size_type c)
191 : s_(f, c) { }
192
193 template<class I, class L,
194 typename std::enable_if<E == dynamic_extent &&
196 constexpr span(I* f, L* l)
197 : s_(f, l - f) { }
198
199 template<class I, class L,
200 typename std::enable_if<E != dynamic_extent &&
202 explicit constexpr span(I* f, L* l)
203 : s_(f, l - f) { }
204
205 template<std::size_t N,
206 typename std::enable_if<detail::span_capacity<E, N>::value,
207 int>::type = 0>
208 constexpr span(typename std::enable_if<true, T>::type (&a)[N]) noexcept
209 : s_(a, N) { }
210
211 template<class U, std::size_t N,
212 typename std::enable_if<detail::span_compatible<T, E, U, N>::value,
213 int>::type = 0>
214 constexpr span(std::array<U, N>& a) noexcept
215 : s_(a.data(), N) { }
216
217 template<class U, std::size_t N,
218 typename std::enable_if<detail::span_compatible<T, E, const U,
219 N>::value, int>::type = 0>
220 constexpr span(const std::array<U, N>& a) noexcept
221 : s_(a.data(), N) { }
222
223 template<class R,
224 typename std::enable_if<E == dynamic_extent &&
226 constexpr span(R&& r) noexcept(noexcept(boost::data(r)) &&
227 noexcept(r.size()))
228 : s_(boost::data(r), r.size()) { }
229
230 template<class R,
231 typename std::enable_if<E != dynamic_extent &&
233 explicit constexpr span(R&& r) noexcept(noexcept(boost::data(r)) &&
234 noexcept(r.size()))
235 : s_(boost::data(r), r.size()) { }
236
237 template<class U, std::size_t N,
238 typename std::enable_if<detail::span_implicit<E, N>::value &&
240 constexpr span(const span<U, N>& s) noexcept
241 : s_(s.data(), s.size()) { }
242
243 template<class U, std::size_t N,
244 typename std::enable_if<!detail::span_implicit<E, N>::value &&
246 explicit constexpr span(const span<U, N>& s) noexcept
247 : s_(s.data(), s.size()) { }
248
249 template<std::size_t C>
250 constexpr span<T, C> first() const {
251 static_assert(C <= E, "Count <= Extent");
252 return span<T, C>(s_.p, C);
253 }
254
255 template<std::size_t C>
256 constexpr span<T, C> last() const {
257 static_assert(C <= E, "Count <= Extent");
258 return span<T, C>(s_.p + (s_.n - C), C);
259 }
260
261 template<std::size_t O, std::size_t C = dynamic_extent>
262 constexpr typename std::enable_if<C == dynamic_extent,
264 static_assert(O <= E, "Offset <= Extent");
265 return span<T, detail::span_sub<E, O>::value>(s_.p + O, s_.n - O);
266 }
267
268 template<std::size_t O, std::size_t C = dynamic_extent>
269 constexpr typename std::enable_if<C != dynamic_extent,
270 span<T, C> >::type subspan() const {
271 static_assert(O <= E && C <= E - O,
272 "Offset <= Extent && Count <= Extent - Offset");
273 return span<T, C>(s_.p + O, C);
274 }
275
277 return span<T, dynamic_extent>(s_.p, c);
278 }
279
281 return span<T, dynamic_extent>(s_.p + (s_.n - c), c);
282 }
283
285 size_type c = dynamic_extent) const {
286 return span<T, dynamic_extent>(s_.p + o,
287 c == dynamic_extent ? s_.n - o : c);
288 }
289
290 constexpr size_type size() const noexcept {
291 return s_.n;
292 }
293
294 constexpr size_type size_bytes() const noexcept {
295 return s_.n * sizeof(T);
296 }
297
298 constexpr bool empty() const noexcept {
299 return s_.n == 0;
300 }
301
302 constexpr reference operator[](size_type i) const {
303 return s_.p[i];
304 }
305
306 constexpr reference front() const {
307 return *s_.p;
308 }
309
310 constexpr reference back() const {
311 return s_.p[s_.n - 1];
312 }
313
314 constexpr pointer data() const noexcept {
315 return s_.p;
316 }
317
318 constexpr iterator begin() const noexcept {
319 return s_.p;
320 }
321
322 constexpr iterator end() const noexcept {
323 return s_.p + s_.n;
324 }
325
326 constexpr reverse_iterator rbegin() const noexcept {
327 return reverse_iterator(s_.p + s_.n);
328 }
329
330 constexpr reverse_iterator rend() const noexcept {
331 return reverse_iterator(s_.p);
332 }
333
334 constexpr const_iterator cbegin() const noexcept {
335 return s_.p;
336 }
337
338 constexpr const_iterator cend() const noexcept {
339 return s_.p + s_.n;
340 }
341
342 constexpr const_reverse_iterator crbegin() const noexcept {
343 return const_reverse_iterator(s_.p + s_.n);
344 }
345
346 constexpr const_reverse_iterator crend() const noexcept {
347 return const_reverse_iterator(s_.p);
348 }
349
350private:
352};
353
354template<class T, std::size_t E>
355constexpr std::size_t span<T, E>::extent;
356
357#ifdef __cpp_deduction_guides
358template<class I, class L>
359span(I*, L) -> span<I>;
360
361template<class T, std::size_t N>
362span(T(&)[N]) -> span<T, N>;
363
364template<class T, std::size_t N>
365span(std::array<T, N>&) -> span<T, N>;
366
367template<class T, std::size_t N>
368span(const std::array<T, N>&) -> span<const T, N>;
369
370template<class R>
371span(R&&) -> span<typename detail::span_data<R>::type>;
372
373template<class T, std::size_t E>
374span(span<T, E>) -> span<T, E>;
375#endif
376
377#ifdef __cpp_lib_byte
378template<class T, std::size_t E>
379inline span<const std::byte, detail::span_bytes<T, E>::value>
380as_bytes(span<T, E> s) noexcept
381{
382 return span<const std::byte, detail::span_bytes<T,
383 E>::value>(reinterpret_cast<const std::byte*>(s.data()),
384 s.size_bytes());
385}
386
387template<class T, std::size_t E>
388inline typename std::enable_if<!std::is_const<T>::value,
389 span<std::byte, detail::span_bytes<T, E>::value> >::type
390as_writable_bytes(span<T, E> s) noexcept
391{
392 return span<std::byte, detail::span_bytes<T,
393 E>::value>(reinterpret_cast<std::byte*>(s.data()), s.size_bytes());
394}
395#endif
396
397} /* boost */
398
399#endif
std::size_t size_type
Definition span.hpp:163
constexpr reverse_iterator rbegin() const noexcept
Definition span.hpp:326
std::remove_cv< T >::type value_type
Definition span.hpp:162
constexpr reference operator[](size_type i) const
Definition span.hpp:302
constexpr iterator end() const noexcept
Definition span.hpp:322
std::reverse_iterator< const T * > const_reverse_iterator
Definition span.hpp:172
const T * const_iterator
Definition span.hpp:170
constexpr std::enable_if< C!=dynamic_extent, span< T, C > >::type subspan() const
Definition span.hpp:270
constexpr const_reverse_iterator crbegin() const noexcept
Definition span.hpp:342
T & reference
Definition span.hpp:167
constexpr std::enable_if< C==dynamic_extent, span< T, detail::span_sub< E, O >::value > >::type subspan() const
Definition span.hpp:263
constexpr span< T, dynamic_extent > last(size_type c) const
Definition span.hpp:280
constexpr span(std::array< U, N > &a) noexcept
Definition span.hpp:214
constexpr span(R &&r) noexcept(noexcept(boost::data(r)) &&noexcept(r.size()))
Definition span.hpp:226
T * iterator
Definition span.hpp:169
T element_type
Definition span.hpp:161
constexpr span(typename std::enable_if< true, T >::type(&a)[N]) noexcept
Definition span.hpp:208
constexpr const_reverse_iterator crend() const noexcept
Definition span.hpp:346
constexpr const_iterator cbegin() const noexcept
Definition span.hpp:334
constexpr bool empty() const noexcept
Definition span.hpp:298
constexpr pointer data() const noexcept
Definition span.hpp:314
std::ptrdiff_t difference_type
Definition span.hpp:164
std::reverse_iterator< T * > reverse_iterator
Definition span.hpp:171
constexpr size_type size_bytes() const noexcept
Definition span.hpp:294
T * pointer
Definition span.hpp:165
constexpr span< T, C > first() const
Definition span.hpp:250
constexpr span() noexcept
Definition span.hpp:178
const T * const_pointer
Definition span.hpp:166
constexpr iterator begin() const noexcept
Definition span.hpp:318
static constexpr std::size_t extent
Definition span.hpp:174
constexpr const_iterator cend() const noexcept
Definition span.hpp:338
constexpr span(const span< U, N > &s) noexcept
Definition span.hpp:240
constexpr reference front() const
Definition span.hpp:306
constexpr span< T, C > last() const
Definition span.hpp:256
constexpr span< T, dynamic_extent > first(size_type c) const
Definition span.hpp:276
constexpr reference back() const
Definition span.hpp:310
constexpr reverse_iterator rend() const noexcept
Definition span.hpp:330
constexpr span< T, dynamic_extent > subspan(size_type o, size_type c=dynamic_extent) const
Definition span.hpp:284
constexpr size_type size() const noexcept
Definition span.hpp:290
constexpr span(I *f, size_type c)
Definition span.hpp:184
const T & const_reference
Definition span.hpp:168
constexpr span(const std::array< U, N > &a) noexcept
Definition span.hpp:220
constexpr span(I *f, L *l)
Definition span.hpp:196
decltype(boost::data(std::declval< T & >())) span_ptr
Definition span.hpp:66
typename std::remove_cv< typename std::remove_reference< T >::type >::type span_uncvref
Definition span.hpp:42
Definition data.hpp:14
constexpr std::size_t dynamic_extent
Definition span.hpp:18
constexpr auto data(C &c) noexcept(noexcept(c.data())) -> decltype(c.data())
Definition data.hpp:18
static constexpr std::size_t value
Definition span.hpp:148
static constexpr bool value
Definition span.hpp:32
static constexpr bool value
Definition span.hpp:37
static constexpr bool value
Definition span.hpp:27
static constexpr bool value
Definition span.hpp:119
static constexpr bool value
Definition span.hpp:79
static constexpr bool value
Definition span.hpp:90
static constexpr bool value
Definition span.hpp:113
static constexpr bool value
Definition span.hpp:57
static constexpr bool value
Definition span.hpp:102
static constexpr bool value
Definition span.hpp:47
constexpr span_store(T *p_, std::size_t n_) noexcept
Definition span.hpp:139
constexpr span_store(T *p_, std::size_t) noexcept
Definition span.hpp:131
static constexpr std::size_t n
Definition span.hpp:133
static constexpr std::size_t value
Definition span.hpp:125