OGLplus  (0.59.0) a C++ wrapper for rendering APIs

span.hpp
Go to the documentation of this file.
1 
9 #ifndef EAGINE_MEMORY_SPAN_HPP
10 #define EAGINE_MEMORY_SPAN_HPP
11 
12 #include "../anything.hpp"
13 #include "../assert.hpp"
14 #include "../compare.hpp"
15 #include "../extract.hpp"
16 #include "../int_constant.hpp"
17 #include "../type_identity.hpp"
18 #include "../types.hpp"
19 #include "address.hpp"
20 #include <cstring>
21 #include <initializer_list>
22 #include <iterator>
23 #include <type_traits>
24 
25 namespace eagine {
26 namespace memory {
27 //------------------------------------------------------------------------------
28 // rebind_pointer
29 //------------------------------------------------------------------------------
30 template <typename Ptr, typename U>
31 struct rebind_pointer;
32 //------------------------------------------------------------------------------
33 template <typename Ptr, typename U>
34 using rebind_pointer_t = typename rebind_pointer<Ptr, U>::type;
35 //------------------------------------------------------------------------------
36 template <typename T, typename U>
37 struct rebind_pointer<T*, U> : type_identity<U*> {};
38 //------------------------------------------------------------------------------
39 // has_span_size_member
40 //------------------------------------------------------------------------------
41 struct _has_span_size_member_base {
42  template <typename X, typename S = decltype(std::declval<X>().size())>
43 
44  static auto _detect(X*) -> bool_constant<std::is_integral_v<S>>;
45  static auto _detect(...) -> std::false_type;
46 };
47 //------------------------------------------------------------------------------
50 template <typename T>
52  : public decltype(
53  _has_span_size_member_base::_detect(static_cast<T*>(nullptr))) {};
54 //------------------------------------------------------------------------------
57 template <typename T>
59 //------------------------------------------------------------------------------
60 // has_span_data_member
61 //------------------------------------------------------------------------------
62 template <typename Elem>
63 struct _has_span_data_member_base {
64  template <
65  typename X,
66  typename P = decltype(std::declval<X>().data()),
67  typename PT = typename std::pointer_traits<P>::element_type>
68  static auto _detect(X*) -> std::is_convertible<PT, Elem>;
69 
70  static auto _detect(...) -> std::false_type;
71 };
72 //------------------------------------------------------------------------------
75 template <typename T, typename E>
77  : public decltype(
78  _has_span_data_member_base<E>::_detect(static_cast<T*>(nullptr))) {};
79 //------------------------------------------------------------------------------
82 template <typename T, typename E = anything>
84 //------------------------------------------------------------------------------
85 // basic_span
86 //------------------------------------------------------------------------------
98 template <
99  typename ValueType,
100  typename Pointer = ValueType*,
101  typename SizeType = span_size_t>
102 class basic_span {
103 public:
105  using value_type = ValueType;
106 
108  using size_type = SizeType;
109 
112 
114  using pointer = Pointer;
115 
117  using iterator = Pointer;
118 
120  using const_iterator = Pointer;
121 
123  using reverse_iterator = std::reverse_iterator<iterator>;
124 
126  constexpr basic_span(pointer addr, size_type len) noexcept
127  : _addr{addr}
128  , _size{len} {}
129 
131  constexpr basic_span(address_type addr, size_type len) noexcept
132  : _addr{static_cast<Pointer>(addr)}
133  , _size{len} {}
134 
136  constexpr basic_span(pointer b, pointer e) noexcept
137  : _addr{b}
138  , _size{b <= e ? e - b : 0} {}
139 
141  constexpr basic_span(address_type ba, address_type be) noexcept
142  : _addr{static_cast<Pointer>(ba)}
143  , _size{limit_cast<size_type>(
144  ba <= be ? (be - ba) / sizeof(value_type) : 0)} {}
145 
146  template <typename T, typename P, typename S>
147  using enable_if_convertible = std::enable_if_t<
148  std::is_convertible_v<T, ValueType> &&
149  std::is_convertible_v<P, Pointer> && std::is_convertible_v<S, SizeType>>;
150 
151  template <typename T, typename P, typename S>
152  using enable_if_different = std::enable_if_t<
153  !std::is_same_v<T, ValueType> || !std::is_same_v<P, Pointer> ||
154  !std::is_same_v<S, SizeType>>;
155 
159  constexpr basic_span() noexcept = default;
160 
162  constexpr basic_span(const basic_span&) noexcept = default;
163 
165  constexpr basic_span(basic_span&&) noexcept = default;
166 
168  auto operator=(const basic_span&) noexcept -> basic_span& = default;
169 
171  auto operator=(basic_span&&) noexcept -> basic_span& = default;
172  ~basic_span() noexcept = default;
173 
175  template <
176  typename T,
177  typename P,
178  typename S,
179  typename = enable_if_convertible<T, P, S>,
180  typename = enable_if_different<T, P, S>>
181  constexpr basic_span(basic_span<T, P, S> that) noexcept
182  : _addr{static_cast<Pointer>(that.data())}
183  , _size{limit_cast<SizeType>(that.size())} {}
184 
186  template <
187  typename T,
188  typename P,
189  typename S,
190  typename = enable_if_convertible<T, P, S>,
191  typename = enable_if_different<T, P, S>>
192  auto operator=(basic_span<T, P, S> that) noexcept -> auto& {
193  _addr = static_cast<Pointer>(that.data());
194  _size = limit_cast<SizeType>(that.size());
195  return *this;
196  }
197 
200  auto reset() noexcept -> auto& {
201  return *this = {};
202  }
203 
205  auto reset(pointer addr, size_type length) noexcept -> auto& {
206  return *this = basic_span(addr, length);
207  }
208 
210  auto reset(address_type addr, size_type length) noexcept -> auto& {
211  return *this = basic_span(addr, length);
212  }
213 
215  auto reset(pointer b, pointer e) noexcept -> auto& {
216  return *this = basic_span(b, e);
217  }
218 
222  explicit constexpr operator bool() const noexcept {
223  return size() != 0;
224  }
225 
228  constexpr auto is_empty() const noexcept -> bool {
229  return size() == 0;
230  }
231 
235  constexpr auto empty() const noexcept -> bool {
236  return size() == 0;
237  }
238 
240  constexpr auto is_zero_terminated() const noexcept -> bool {
241  return size() < 0;
242  }
243 
246  constexpr auto size() const noexcept -> size_type {
247  return EAGINE_LIKELY(_size >= 0) ? _size : -_size;
248  }
249 
254  constexpr auto data() const noexcept -> pointer {
255  return _addr;
256  }
257 
259  constexpr auto begin() const noexcept -> iterator {
260  return _addr;
261  }
262 
264  constexpr auto end() const noexcept -> iterator {
265  return begin() + size();
266  }
267 
269  constexpr auto rbegin() const noexcept {
270  return reverse_iterator{end()};
271  }
272 
274  constexpr auto rend() const noexcept {
275  return reverse_iterator{begin()};
276  }
277 
279  constexpr auto addr() const noexcept -> address_type {
280  return as_address(begin());
281  }
282 
284  constexpr auto begin_addr() const noexcept -> address_type {
285  return as_address(begin());
286  }
287 
289  constexpr auto end_addr() const noexcept -> address_type {
290  return as_address(end());
291  }
292 
294  template <typename X>
295  auto is_aligned_as() const noexcept -> bool {
296  return addr().template is_aligned_as<X>();
297  }
298 
301  auto encloses(const_address a) const noexcept -> bool {
302  return (addr() <= a) && (a <= end_addr());
303  }
304 
308  template <typename Ts, typename Ps, typename Ss>
309  auto contains(basic_span<Ts, Ps, Ss> that) const noexcept -> bool {
310  return (addr() <= that.addr()) && (that.end_addr() <= end_addr());
311  }
312 
316  template <typename Ts, typename Ps, typename Ss>
317  auto overlaps(const basic_span<Ts, Ps, Ss>& that) const noexcept -> bool {
318  return encloses(that.addr()) || encloses(that.end_addr()) ||
319  that.encloses(addr()) || that.encloses(end_addr());
320  }
321 
324  constexpr auto ref(size_type index) const noexcept
325  -> std::add_const_t<value_type>& {
326  return EAGINE_CONSTEXPR_ASSERT(index < size(), _addr[index]);
327  }
328 
331  auto ref(size_type index) noexcept -> value_type& {
332  return EAGINE_CONSTEXPR_ASSERT(index < size(), _addr[index]);
333  }
334 
338  auto front() const noexcept -> const value_type& {
339  return EAGINE_CONSTEXPR_ASSERT(0 < size(), _addr[0]);
340  }
341 
345  auto front() noexcept -> value_type& {
346  return EAGINE_CONSTEXPR_ASSERT(0 < size(), _addr[0]);
347  }
348 
352  auto back() const noexcept -> const value_type& {
353  return EAGINE_CONSTEXPR_ASSERT(0 < size(), _addr[size() - 1]);
354  }
355 
359  auto back() noexcept -> value_type& {
360  return EAGINE_CONSTEXPR_ASSERT(0 < size(), _addr[size() - 1]);
361  }
362 
365  template <typename Int>
366  constexpr auto element(Int index) const noexcept
367  -> std::enable_if_t<std::is_integral_v<Int>, std::add_const_t<value_type>&> {
368  return ref(span_size(index));
369  }
370 
373  template <typename Int>
374  auto element(Int index) noexcept
375  -> std::enable_if_t<std::is_integral_v<Int>, value_type&> {
376  return ref(span_size(index));
377  }
378 
381  template <typename Int>
382  auto operator[](Int index) noexcept
383  -> std::enable_if_t<std::is_integral_v<Int>, value_type&> {
384  return element(index);
385  }
386 
389  template <typename Int>
390  constexpr auto operator[](Int index) const noexcept
391  -> std::enable_if_t<std::is_integral_v<Int>, std::add_const_t<value_type>&> {
392  return element(index);
393  }
394 
395 private:
396  pointer _addr{nullptr};
397  // if _size is negative it indicates that the span is terminated
398  // by a zero value. if such case the span length is calculated by
399  // getting the absolute value of _size.
400  size_type _size{0};
401 };
402 //------------------------------------------------------------------------------
406 template <typename T, typename P, typename S>
407 static constexpr auto absolute(basic_span<T, P, S> spn) noexcept
409  return {spn};
410 }
411 //------------------------------------------------------------------------------
414 template <typename T, typename S = span_size_t>
416 //------------------------------------------------------------------------------
419 template <typename T>
420 using span_if_mutable = std::enable_if_t<!std::is_const_v<T>, span<T>>;
421 //------------------------------------------------------------------------------
424 template <typename T>
426 //------------------------------------------------------------------------------
429 template <typename T>
430 static constexpr auto view_one(const T& value) noexcept -> const_span<T> {
431  return {std::addressof(value), span_size(1)};
432 }
433 //------------------------------------------------------------------------------
436 template <typename T>
437 static constexpr auto cover_one(T& value) noexcept -> span_if_mutable<T> {
438  return {std::addressof(value), span_size(1)};
439 }
440 //------------------------------------------------------------------------------
443 template <typename T>
444 static constexpr auto view_one(const T* pointer) noexcept -> const_span<T> {
445  return {pointer, span_size(1)};
446 }
447 //------------------------------------------------------------------------------
450 template <typename T>
451 static constexpr auto cover_one(T* pointer) noexcept -> span_if_mutable<T> {
452  return {pointer, span_size(1)};
453 }
454 //------------------------------------------------------------------------------
457 template <typename T, typename S>
458 static constexpr auto view(T* addr, S size) noexcept -> const_span<T> {
459  return {addr, span_size(size)};
460 }
461 //------------------------------------------------------------------------------
464 template <typename T, typename S>
465 static constexpr auto cover(T* addr, S size) noexcept -> span_if_mutable<T> {
466  return {addr, span_size(size)};
467 }
468 //------------------------------------------------------------------------------
471 template <typename T, typename S>
472 static constexpr auto view(const_address addr, S size) noexcept
473  -> const_span<T> {
474  return {addr, span_size(size)};
475 }
476 //------------------------------------------------------------------------------
479 template <typename T, typename S>
480 static constexpr auto cover(address addr, S size) noexcept
481  -> span_if_mutable<T> {
482  return {addr, span_size(size)};
483 }
484 //------------------------------------------------------------------------------
487 template <typename T, std::size_t N>
488 static constexpr auto view(const T (&array)[N]) noexcept -> const_span<T> {
489  return view(static_cast<const T*>(array), N);
490 }
491 //------------------------------------------------------------------------------
494 template <typename T, std::size_t N>
495 static constexpr auto cover(T (&array)[N]) noexcept -> span_if_mutable<T> {
496  return cover(static_cast<T*>(array), N);
497 }
498 //------------------------------------------------------------------------------
501 template <typename T>
502 static constexpr auto view(std::initializer_list<T> il) noexcept
503  -> const_span<T> {
504  return view(il.begin(), il.size());
505 }
506 //------------------------------------------------------------------------------
509 template <
510  typename C,
511  typename =
512  std::enable_if_t<has_span_data_member_v<C> && has_span_size_member_v<C>>>
513 static constexpr auto view(const C& container) noexcept {
514  return view(container.data(), container.size());
515 }
516 //------------------------------------------------------------------------------
519 template <
520  typename C,
521  typename =
522  std::enable_if_t<has_span_data_member_v<C> && has_span_size_member_v<C>>>
523 static constexpr auto cover(C& container) noexcept {
524  return cover(container.data(), container.size());
525 }
526 //------------------------------------------------------------------------------
527 // accomodate
528 //------------------------------------------------------------------------------
529 static constexpr auto can_accomodate_between(
530  const_address bgn,
531  const_address end,
532  span_size_t size) noexcept -> bool {
533  return (end - bgn) >= size;
534 }
535 //------------------------------------------------------------------------------
538 template <typename T, typename B, typename P, typename S>
539 static constexpr auto can_accomodate(
541  span_size_t count,
542  type_identity<T> tid = {}) noexcept {
543  return can_accomodate_between(
544  align_up(blk.begin_addr(), span_align_of(tid), span_align_of(tid)),
545  align_down(blk.end_addr(), span_align_of(tid), span_align_of(tid)),
546  count * span_size_of(tid));
547 }
548 //------------------------------------------------------------------------------
551 template <typename T, typename B, typename P, typename S>
552 static constexpr auto
554  return can_accomodate(blk, 1, tid);
555 }
556 //------------------------------------------------------------------------------
561 template <typename T, typename B, typename P, typename S>
562 static constexpr auto
564  -> basic_span<std::add_const_t<T>, rebind_pointer_t<P, T>, S> {
565  return {
566  align_up_to(blk.begin_addr(), tid), align_down_to(blk.end_addr(), tid)};
567 }
568 //------------------------------------------------------------------------------
569 // extract
570 //------------------------------------------------------------------------------
574 template <typename T, typename P, typename S>
575 static constexpr auto extract(basic_span<T, P, S> spn) noexcept -> T& {
576  return EAGINE_CONSTEXPR_ASSERT(spn.size() >= 1, spn.front());
577 }
578 //------------------------------------------------------------------------------
581 template <typename T, typename P, typename S>
582 static constexpr auto extract_or(basic_span<T, P, S> spn, T& fallback) noexcept
583  -> T& {
584  return (spn.size() >= 1) ? spn.front() : fallback;
585 }
586 //------------------------------------------------------------------------------
589 template <typename T, typename P, typename S, typename F>
590 static constexpr auto extract_or(basic_span<T, P, S> spn, F&& fallback)
591  -> std::enable_if_t<std::is_convertible_v<F, T>, T> {
592  return (spn.size() >= 1) ? spn.front() : T{std::forward<F>(fallback)};
593 }
594 //------------------------------------------------------------------------------
595 } // namespace memory
596 //------------------------------------------------------------------------------
597 template <
598  typename Tl,
599  typename Tr,
600  typename Pl,
601  typename Pr,
602  typename Sl,
603  typename Sr>
604 struct equal_cmp<memory::basic_span<Tl, Pl, Sl>, memory::basic_span<Tr, Pr, Sr>> {
605 
606  static auto check(
607  memory::basic_span<Tl, Pl, Sl> l,
608  memory::basic_span<Tr, Pr, Sr> r) noexcept -> bool {
609  if(are_equal(l.size(), r.size())) {
610  if constexpr(
611  std::is_same_v<std::remove_const_t<Tl>, std::remove_const_t<Tr>> &&
612  std::is_integral_v<std::remove_const_t<Tl>>) {
613  return 0 ==
614  std::memcmp(
615  l.data(), r.data(), sizeof(Tl) * std_size(l.size()));
616  } else {
617  const auto n = span_size(l.size());
618  for(span_size_t i = 0; i < n; ++i) {
619  if(!are_equal(l[i], r[i])) {
620  return false;
621  }
622  }
623  return true;
624  }
625  }
626  return false;
627  }
628 };
629 //------------------------------------------------------------------------------
630 } // namespace eagine
631 
632 #endif // EAGINE_MEMORY_SPAN_HPP
constexpr auto rbegin() const noexcept
Returns a reverse interator to the end of the span.
Definition: span.hpp:269
constexpr auto empty() const noexcept -> bool
Indicates that the span is empty.
Definition: span.hpp:235
static constexpr auto align_up_to(basic_address< std::is_const_v< T >> addr, type_identity< T >={}, span_size_t align=span_align_of< T >(), span_size_t max=span_size_of< T >()) noexcept
Aligns a memory address up to the required alignment of type T.
Definition: address.hpp:320
Class for handling memory addresses as integer values.
Definition: address.hpp:23
std::ptrdiff_t span_size_t
Signed span size type used by eagine.
Definition: types.hpp:36
static constexpr auto span_size(T v) noexcept
Converts argument to span size type.
Definition: types.hpp:59
auto operator[](Int index) noexcept -> std::enable_if_t< std::is_integral_v< Int >, value_type & >
Array subscript operator.
Definition: span.hpp:382
Common code is placed in this namespace.
Definition: eagine.hpp:21
static constexpr auto as_address(T *addr) noexcept
Casts a pointer to basic_address.
Definition: address.hpp:208
const gl_types::ubyte_type * pointer
The pointer type.
Definition: span.hpp:114
auto reset(address_type addr, size_type length) noexcept -> auto &
Resets this span with a new memory address and length.
Definition: span.hpp:210
static constexpr auto extract(api_result_value< Result, api_result_validity::never > &) noexcept -> Result &
Overload of extract for api_result_value.
Definition: c_api_wrap.hpp:270
constexpr basic_span(pointer addr, size_type len) noexcept
Construction from pointer and length.
Definition: span.hpp:126
std::enable_if_t<!std::is_const_v< T >, span< T > > span_if_mutable
Alias for span<T> if T is mutable type. Ill defined otherwise.
Definition: span.hpp:420
static constexpr auto can_accomodate(basic_span< B, P, S > blk, type_identity< T > tid={}) noexcept
Indicates if the specified memory block can accomodate one element of T.
Definition: span.hpp:553
constexpr auto begin() const noexcept -> iterator
Returns an interator to the start of the span.
Definition: span.hpp:259
constexpr auto addr() const noexcept -> address_type
Returns the memory address of the start of the span.
Definition: span.hpp:279
auto front() noexcept -> value_type &
Returns a reference to value at the front of the span.
Definition: span.hpp:345
constexpr auto data() const noexcept -> pointer
Returns a pointer to the start of the span.
Definition: span.hpp:254
constexpr auto end() const noexcept -> iterator
Returns a iterator past the end of the span.
Definition: span.hpp:264
auto back() noexcept -> value_type &
Returns a const reference to value at the back of the span.
Definition: span.hpp:359
auto ref(size_type index) noexcept -> value_type &
Returns a reference to value at the specified index.
Definition: span.hpp:331
constexpr basic_span() noexcept=default
Default constructor. Constructs an empty span.
constexpr basic_span(pointer b, pointer e) noexcept
Construction from a pair of pointers.
Definition: span.hpp:136
static constexpr auto cover_one(T *pointer) noexcept -> span_if_mutable< T >
Creates a single-element mutable span from the specified pointer.
Definition: span.hpp:451
constexpr bool has_span_size_member_v
Trait indicating if type T has x.size() member function.
Definition: span.hpp:58
auto reset(pointer addr, size_type length) noexcept -> auto &
Resets this span with a new pointer and length.
Definition: span.hpp:205
static constexpr auto view_one(const T *pointer) noexcept -> const_span< T >
Creates a single-const-element view from the specified pointer.
Definition: span.hpp:444
auto reset() noexcept -> auto &
Resets this span.
Definition: span.hpp:200
span_size_t size_type
The element count type.
Definition: span.hpp:108
auto contains(basic_span< Ts, Ps, Ss > that) const noexcept -> bool
Indicates if this span encloses another span.
Definition: span.hpp:309
static constexpr auto std_size(T v) noexcept
Converts argument to std size type.
Definition: types.hpp:52
constexpr auto is_empty() const noexcept -> bool
Indicates that the span is empty.
Definition: span.hpp:228
static constexpr auto view(const C &container) noexcept
Creates a const view over a compatible contiguous container.
Definition: span.hpp:513
constexpr auto rend() const noexcept
Returns a reverse interator past the begin of the span.
Definition: span.hpp:274
constexpr auto element(Int index) const noexcept -> std::enable_if_t< std::is_integral_v< Int >, std::add_const_t< value_type > & >
Returns a const reference to value at the specified index.
Definition: span.hpp:366
std::reverse_iterator< iterator > reverse_iterator
The reverse iterator type.
Definition: span.hpp:123
Non-owning view of a contiguous range of memory with ValueType elements.
Definition: flatten_fwd.hpp:16
constexpr auto operator[](Int index) const noexcept -> std::enable_if_t< std::is_integral_v< Int >, std::add_const_t< value_type > & >
Array subscript operator.
Definition: span.hpp:390
static constexpr auto align_up(basic_address< IsConst > addr, span_size_t align, span_size_t max) noexcept -> basic_address< IsConst >
Aligns a memory address up to the specified alignment.
Definition: address.hpp:266
basic_address< true > const_address
Type alias for const memory address values.
Definition: address.hpp:199
static constexpr auto span_align_of(type_identity< T >={}) noexcept
Returns the byte alignment of type T as span_size_t.
Definition: types.hpp:66
static constexpr auto span_size_of(type_identity< T >={}) noexcept
Returns the byte size of type T as span_size_t.
Definition: types.hpp:73
constexpr auto is_zero_terminated() const noexcept -> bool
Indicates that the span is terminated with value T(0) if applicable.
Definition: span.hpp:240
auto is_aligned_as() const noexcept -> bool
Checks if the start of the span is aligned as the alignment of X.
Definition: span.hpp:295
auto reset(pointer b, pointer e) noexcept -> auto &
Resets this span with a pair or pointers.
Definition: span.hpp:215
auto encloses(const_address a) const noexcept -> bool
Indicates if this span encloses the specified address.
Definition: span.hpp:301
constexpr auto ref(size_type index) const noexcept -> std::add_const_t< value_type > &
Returns a const reference to value at the specified index.
Definition: span.hpp:324
static constexpr auto align_down(basic_address< IsConst > addr, span_size_t align, span_size_t max) noexcept -> basic_address< IsConst >
Aligns a memory address down to the specified alignment.
Definition: address.hpp:292
static constexpr auto accomodate(basic_span< B, P, S > blk, type_identity< T > tid={}) noexcept -> basic_span< std::add_const_t< T >, rebind_pointer_t< P, T >, S >
Returns a span, rebinding the element type (typically from basic_block).
Definition: span.hpp:563
constexpr auto begin_addr() const noexcept -> address_type
Returns the memory address of the start of the span.
Definition: span.hpp:284
constexpr basic_span(address_type addr, size_type len) noexcept
Construction from memory address and length.
Definition: span.hpp:131
static constexpr auto align_down_to(basic_address< std::is_const_v< T >> addr, type_identity< T >={}, span_size_t align=span_align_of< T >(), span_size_t max=span_size_of< T >()) noexcept
Aligns a memory address down to the required alignment of type T.
Definition: address.hpp:337
constexpr auto size() const noexcept -> size_type
Returns the number of elements in the span.
Definition: span.hpp:246
Helper class detecting if type T has x.size() member function.
Definition: span.hpp:51
constexpr bool has_span_data_member_v
Trait indicating if type T has x.size() member function.
Definition: span.hpp:83
const gl_types::ubyte_type value_type
The element value type.
Definition: span.hpp:105
static constexpr auto cover(C &container) noexcept
Creates a mutable span covering a compatible contiguous container.
Definition: span.hpp:523
Template type used mostly for function type-tag dispatching.
Definition: type_identity.hpp:19
constexpr basic_span(address_type ba, address_type be) noexcept
Construction from a pair of memory addresses.
Definition: span.hpp:141
const gl_types::ubyte_type * iterator
The iterator type.
Definition: span.hpp:117
constexpr auto end_addr() const noexcept -> address_type
Returns the memory address past the end of the span.
Definition: span.hpp:289
auto operator=(basic_span< T, P, S > that) noexcept -> auto &
Converting copy assignment from span of compatible elements.
Definition: span.hpp:192
static constexpr auto extract_or(basic_span< T, P, S > spn, T &fallback) noexcept -> T &
Overload of extract_or for spans. Returns the first element,.
Definition: span.hpp:582
Helper class detecting if type T has x.data() member function.
Definition: span.hpp:76
const gl_types::ubyte_type * const_iterator
The const iterator type.
Definition: span.hpp:120
auto front() const noexcept -> const value_type &
Returns a const reference to value at the front of the span.
Definition: span.hpp:338
auto overlaps(const basic_span< Ts, Ps, Ss > &that) const noexcept -> bool
Indicates if this span overlaps with another span.
Definition: span.hpp:317
static constexpr auto absolute(basic_span< T, P, S > spn) noexcept -> basic_span< T, T *, S >
Converts argument to span using a native pointer type.
Definition: span.hpp:407
auto back() const noexcept -> const value_type &
Returns a const reference to value at the back of the span.
Definition: span.hpp:352
auto element(Int index) noexcept -> std::enable_if_t< std::is_integral_v< Int >, value_type & >
Returns a reference to value at the specified index.
Definition: span.hpp:374

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).