CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
Span.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2020 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
10#if __has_include(<span>)
11# include <span>
12# if defined(__cpp_lib_span)
13# define CE_HAS_STD_SPAN 1
14# endif
15#endif
16
17#if !defined(CE_HAS_STD_SPAN)
18/*
19This is an implementation of C++20's std::span
20http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4820.pdf
21*/
22
23// Copyright Tristan Brindle 2018.
24// Distributed under the Boost Software License, Version 1.0.
25// (See accompanying file ../../LICENSE_1_0.txt or copy at
26// https://www.boost.org/LICENSE_1_0.txt)
27
28# ifndef TCB_SPAN_HPP_INCLUDED
29# define TCB_SPAN_HPP_INCLUDED
30
31# include <array>
32# include <cstddef>
33# include <cstdint>
34# include <type_traits>
35
36# ifndef TCB_SPAN_NO_EXCEPTIONS
37// Attempt to discover whether we're being compiled with exception support
38# if !(defined(__cpp_exceptions) || defined(__EXCEPTIONS) || \
39 defined(_CPPUNWIND))
40# define TCB_SPAN_NO_EXCEPTIONS
41# endif
42# endif
43
44# ifndef TCB_SPAN_NO_EXCEPTIONS
45
46# include <cstdio>
47# include <stdexcept>
48
49# endif
50
51// Various feature test macros
52
53# ifndef TCB_SPAN_NAMESPACE_NAME
54# define TCB_SPAN_NAMESPACE_NAME tcb
55# endif
56
57# if __cplusplus >= 201703L || \
58 (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
59# define TCB_SPAN_HAVE_CPP17
60# endif
61
62# if __cplusplus >= 201402L || \
63 (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
64# define TCB_SPAN_HAVE_CPP14
65# endif
66
68
69// Establish default contract checking behavior
70# if !defined(TCB_SPAN_THROW_ON_CONTRACT_VIOLATION) && \
71 !defined(TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION) && \
72 !defined(TCB_SPAN_NO_CONTRACT_CHECKING)
73# if defined(NDEBUG) || !defined(TCB_SPAN_HAVE_CPP14)
74# define TCB_SPAN_NO_CONTRACT_CHECKING
75# else
76# define TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION
77# endif
78# endif
79
80# if defined(TCB_SPAN_THROW_ON_CONTRACT_VIOLATION)
81 struct contract_violation_error : std::logic_error {
82 explicit contract_violation_error(const char* msg)
83 : std::logic_error(msg) {}
84 };
85
86 inline void contract_violation(const char* msg) {
87 throw contract_violation_error(msg);
88 }
89
90# elif defined(TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION)
91 [[noreturn]] inline void contract_violation(const char* /*unused*/) {
92 std::terminate();
93 }
94# endif
95
96# if !defined(TCB_SPAN_NO_CONTRACT_CHECKING)
97# define TCB_SPAN_STRINGIFY(cond) # cond
98# define TCB_SPAN_EXPECT(cond) \
99 cond ? (void)0 \
100 : contract_violation( \
101 "Expected " TCB_SPAN_STRINGIFY(cond))
102# else
103# define TCB_SPAN_EXPECT(cond)
104# endif
105
106# if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_inline_variables)
107# define TCB_SPAN_INLINE_VAR inline
108# else
109# define TCB_SPAN_INLINE_VAR
110# endif
111
112# if defined(TCB_SPAN_HAVE_CPP14) || \
113 (defined(__cpp_constexpr) && __cpp_constexpr >= 201304)
114# define TCB_SPAN_HAVE_CPP14_CONSTEXPR
115# endif
116
117# if defined(TCB_SPAN_HAVE_CPP14_CONSTEXPR)
118# define TCB_SPAN_CONSTEXPR14 constexpr
119# else
120# define TCB_SPAN_CONSTEXPR14
121# endif
122
123# if defined(TCB_SPAN_HAVE_CPP14_CONSTEXPR) && \
124 (!defined(_MSC_VER) || _MSC_VER > 1900)
125# define TCB_SPAN_CONSTEXPR_ASSIGN constexpr
126# else
127# define TCB_SPAN_CONSTEXPR_ASSIGN
128# endif
129
130# if defined(TCB_SPAN_NO_CONTRACT_CHECKING)
131# define TCB_SPAN_CONSTEXPR11 constexpr
132# else
133# define TCB_SPAN_CONSTEXPR11 TCB_SPAN_CONSTEXPR14
134# endif
135
136# if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_deduction_guides)
137# define TCB_SPAN_HAVE_DEDUCTION_GUIDES
138# endif
139
140# if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_byte)
141# define TCB_SPAN_HAVE_STD_BYTE
142# endif
143
144# if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_array_constexpr)
145# define TCB_SPAN_HAVE_CONSTEXPR_STD_ARRAY_ETC
146# endif
147
148# if defined(TCB_SPAN_HAVE_CONSTEXPR_STD_ARRAY_ETC)
149# define TCB_SPAN_ARRAY_CONSTEXPR constexpr
150# else
151# define TCB_SPAN_ARRAY_CONSTEXPR
152# endif
153
154# ifdef TCB_SPAN_HAVE_STD_BYTE
155 using byte = std::byte;
156# else
157 using byte = unsigned char;
158# endif
159
160# if defined(TCB_SPAN_HAVE_CPP17)
161# define TCB_SPAN_NODISCARD [[nodiscard]]
162# else
163# define TCB_SPAN_NODISCARD
164# endif
165
166 TCB_SPAN_INLINE_VAR constexpr std::size_t dynamic_extent = SIZE_MAX;
167
168 template<typename ElementType, std::size_t Extent = dynamic_extent>
169 class span;
170
171 namespace detail {
172
173 template<typename E, std::size_t S>
174 struct span_storage {
175 constexpr span_storage() noexcept = default;
176
177 constexpr span_storage(E* ptr, std::size_t /*unused*/) noexcept
178 : ptr(ptr) {}
179
180 E* ptr = nullptr;
181 static constexpr std::size_t size = S;
182 };
183
184 template<typename E>
185 struct span_storage<E, dynamic_extent> {
186 constexpr span_storage() noexcept = default;
187
188 constexpr span_storage(E* ptr, std::size_t size) noexcept
189 : ptr(ptr), size(size) {}
190
191 E* ptr = nullptr;
192 std::size_t size = 0;
193 };
194
195// Reimplementation of C++17 std::size() and std::data()
196# if defined(TCB_SPAN_HAVE_CPP17) || \
197 defined(__cpp_lib_nonmember_container_access)
198 using std::data;
199 using std::size;
200# else
201 template<class C>
202 constexpr auto size(const C& c) -> decltype(c.size()) {
203 return c.size();
204 }
205
206 template<class T, std::size_t N>
207 constexpr std::size_t size(const T (&)[N]) noexcept {
208 return N;
209 }
210
211 template<class C>
212 constexpr auto data(C& c) -> decltype(c.data()) {
213 return c.data();
214 }
215
216 template<class C>
217 constexpr auto data(const C& c) -> decltype(c.data()) {
218 return c.data();
219 }
220
221 template<class T, std::size_t N>
222 constexpr T* data(T (&array)[N]) noexcept {
223 return array;
224 }
225
226 template<class E>
227 constexpr const E* data(std::initializer_list<E> il) noexcept {
228 return il.begin();
229 }
230# endif // TCB_SPAN_HAVE_CPP17
231
232# if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_void_t)
233 using std::void_t;
234# else
235 template<typename...>
236 using void_t = void;
237# endif
238
239 template<typename T>
240 using uncvref_t = typename std::remove_cv<
241 typename std::remove_reference<T>::type>::type;
242
243 template<typename>
244 struct is_span : std::false_type {};
245
246 template<typename T, std::size_t S>
247 struct is_span<span<T, S>> : std::true_type {};
248
249 template<typename>
250 struct is_std_array : std::false_type {};
251
252 template<typename T, std::size_t N>
253 struct is_std_array<std::array<T, N>> : std::true_type {};
254
255 template<typename, typename = void>
256 struct has_size_and_data : std::false_type {};
257
258 template<typename T>
259 struct has_size_and_data<
260 T, void_t<decltype(detail::size(std::declval<T>())),
261 decltype(detail::data(std::declval<T>()))>>
262 : std::true_type {};
263
264 template<typename C, typename U = uncvref_t<C>>
265 struct is_container {
266 static constexpr bool value =
267 !is_span<U>::value && !is_std_array<U>::value &&
268 !std::is_array<U>::value && has_size_and_data<C>::value;
269 };
270
271 template<typename T>
272 using remove_pointer_t = typename std::remove_pointer<T>::type;
273
274 template<typename, typename, typename = void>
275 struct is_container_element_type_compatible : std::false_type {};
276
277 template<typename T, typename E>
278 struct is_container_element_type_compatible<
279 T, E, void_t<decltype(detail::data(std::declval<T>()))>>
280 : std::is_convertible<
281 remove_pointer_t<decltype(
282 detail::data(std::declval<T>()))> (*)[],
283 E (*)[]> {};
284
285 template<typename, typename = size_t>
286 struct is_complete : std::false_type {};
287
288 template<typename T>
289 struct is_complete<T, decltype(sizeof(T))> : std::true_type {};
290
291 } // namespace detail
292
293 template<typename ElementType, std::size_t Extent>
294 class span {
295 static_assert(
296 std::is_object<ElementType>::value,
297 "A span's ElementType must be an object type (not a "
298 "reference type or void)");
299 static_assert(
300 detail::is_complete<ElementType>::value,
301 "A span's ElementType must be a complete type (not a forward "
302 "declaration)");
303 static_assert(
304 !std::is_abstract<ElementType>::value,
305 "A span's ElementType cannot be an abstract class type");
306
307 using storage_type = detail::span_storage<ElementType, Extent>;
308
309 public:
310 // constants and types
311 using element_type = ElementType;
312 using value_type = typename std::remove_cv<ElementType>::type;
313 using index_type = std::size_t;
314 using difference_type = std::ptrdiff_t;
315 using pointer = element_type*;
316 using const_pointer = const element_type*;
317 using reference = element_type&;
318 using iterator = pointer;
319 using const_iterator = const_pointer;
320 using reverse_iterator = std::reverse_iterator<iterator>;
321 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
322
323 static constexpr index_type extent = Extent;
324
325 // [span.cons], span constructors, copy, assignment, and destructor
326 template<
327 std::size_t E = Extent,
328 typename std::enable_if<
329 (E == dynamic_extent || E <= 0), int>::type = 0>
330 constexpr span() noexcept {}
331
332 TCB_SPAN_CONSTEXPR11 span(pointer ptr, index_type count)
333 : storage_(ptr, count) {
334 TCB_SPAN_EXPECT(extent == dynamic_extent || count == extent);
335 }
336
337 TCB_SPAN_CONSTEXPR11 span(pointer first_elem, pointer last_elem)
338 : storage_(first_elem, last_elem - first_elem) {
340 extent == dynamic_extent ||
341 last_elem - first_elem ==
342 static_cast<std::ptrdiff_t>(extent));
343 }
344
345 template<
346 std::size_t N, std::size_t E = Extent,
347 typename std::enable_if<
348 (E == dynamic_extent || N == E) &&
349 detail::is_container_element_type_compatible<
350 element_type (&)[N],
351 ElementType>::value,
352 int>::type = 0>
353 constexpr span(element_type (&arr)[N]) noexcept : storage_(arr, N) {} // NOLINT
354
355 template<
356 std::size_t N, std::size_t E = Extent,
357 typename std::enable_if<
358 (E == dynamic_extent || N == E) &&
359 detail::is_container_element_type_compatible<
360 std::array<value_type, N>&,
361 ElementType>::value,
362 int>::type = 0>
363 TCB_SPAN_ARRAY_CONSTEXPR span(std::array<value_type, N>& arr) noexcept // NOLINT
364 : storage_(arr.data(), N) {}
365
366 template<
367 std::size_t N, std::size_t E = Extent,
368 typename std::enable_if<
369 (E == dynamic_extent || N == E) &&
370 detail::is_container_element_type_compatible<
371 const std::array<value_type, N>&,
372 ElementType>::value,
373 int>::type = 0>
374 TCB_SPAN_ARRAY_CONSTEXPR span( // NOLINT
375 const std::array<value_type, N>& arr) noexcept
376 : storage_(arr.data(), N) {}
377
378 template<
379 typename Container, std::size_t E = Extent,
380 typename std::enable_if<
381 E == dynamic_extent &&
382 detail::is_container<Container>::value &&
383 detail::is_container_element_type_compatible<
384 Container&, ElementType>::value,
385 int>::type = 0>
386 constexpr span(Container& cont) // NOLINT
387 : storage_(detail::data(cont), detail::size(cont)) {}
388
389 template<
390 typename Container, std::size_t E = Extent,
391 typename std::enable_if<
392 E == dynamic_extent &&
393 detail::is_container<Container>::value &&
394 detail::is_container_element_type_compatible<
395 const Container&, ElementType>::value,
396 int>::type = 0>
397 constexpr span(const Container& cont) // NOLINT
398 : storage_(detail::data(cont), detail::size(cont)) {}
399
400 constexpr span(const span& other) noexcept = default;
401
402 template<
403 typename OtherElementType, std::size_t OtherExtent,
404 typename std::enable_if<
405 (Extent == OtherExtent || Extent == dynamic_extent) &&
406 std::is_convertible<
407 OtherElementType (*)[],
408 ElementType (*)[]>::value,
409 int>::type = 0>
410 constexpr span( // NOLINT
411 const span<OtherElementType, OtherExtent>& other) noexcept
412 : storage_(other.data(), other.size()) {}
413
414 ~span() noexcept = default;
415
416 TCB_SPAN_CONSTEXPR_ASSIGN span& operator=(const span& other) noexcept =
417 default;
418
419 // [span.sub], span subviews
420 template<std::size_t Count>
421 TCB_SPAN_CONSTEXPR11 span<element_type, Count> first() const {
422 TCB_SPAN_EXPECT(Count <= size());
423 return {data(), Count};
424 }
425
426 template<std::size_t Count>
427 TCB_SPAN_CONSTEXPR11 span<element_type, Count> last() const {
428 TCB_SPAN_EXPECT(Count <= size());
429 return {data() + (size() - Count), Count};
430 }
431
432 template<std::size_t Offset, std::size_t Count = dynamic_extent>
433 using subspan_return_t =
434 span<ElementType,
436 ? Count
437 : (Extent != dynamic_extent ? Extent - Offset
438 : dynamic_extent)>;
439
440 template<std::size_t Offset, std::size_t Count = dynamic_extent>
441 TCB_SPAN_CONSTEXPR11 subspan_return_t<Offset, Count> subspan() const {
443 Offset <= size() &&
444 (Count == dynamic_extent || Offset + Count <= size()));
445 return {data() + Offset,
446 Count != dynamic_extent ? Count : size() - Offset};
447 }
448
449 [[nodiscard]] TCB_SPAN_CONSTEXPR11 span<element_type, dynamic_extent> first(
450 index_type count) const {
451 TCB_SPAN_EXPECT(count <= size());
452 return {data(), count};
453 }
454
455 [[nodiscard]] TCB_SPAN_CONSTEXPR11 span<element_type, dynamic_extent> last(
456 index_type count) const {
457 TCB_SPAN_EXPECT(count <= size());
458 return {data() + (size() - count), count};
459 }
460
461 [[nodiscard]] TCB_SPAN_CONSTEXPR11 span<element_type, dynamic_extent> subspan(
462 index_type offset, index_type count = dynamic_extent) const {
464 offset <= size() &&
465 (count == dynamic_extent || offset + count <= size()));
466 return {data() + offset,
467 count == dynamic_extent ? size() - offset : count};
468 }
469
470 // [span.obs], span observers
471 [[nodiscard]] constexpr index_type size() const noexcept { return storage_.size; }
472
473 [[nodiscard]] constexpr index_type size_bytes() const noexcept {
474 return size() * sizeof(element_type);
475 }
476
477 TCB_SPAN_NODISCARD constexpr bool empty() const noexcept {
478 return size() == 0;
479 }
480
481 // [span.elem], span element access
482 TCB_SPAN_CONSTEXPR11 reference operator[](index_type idx) const {
483 TCB_SPAN_EXPECT(idx < size());
484 return *(data() + idx);
485 }
486
487 [[nodiscard]] TCB_SPAN_CONSTEXPR11 reference front() const {
488 TCB_SPAN_EXPECT(!empty());
489 return *data();
490 }
491
492 [[nodiscard]] TCB_SPAN_CONSTEXPR11 reference back() const {
493 TCB_SPAN_EXPECT(!empty());
494 return *(data() + (size() - 1));
495 }
496
497 [[nodiscard]] constexpr pointer data() const noexcept { return storage_.ptr; }
498
499 // [span.iterators], span iterator support
500 [[nodiscard]] constexpr iterator begin() const noexcept { return data(); }
501
502 [[nodiscard]] constexpr iterator end() const noexcept { return data() + size(); }
503
504 [[nodiscard]] constexpr const_iterator cbegin() const noexcept { return begin(); }
505
506 [[nodiscard]] constexpr const_iterator cend() const noexcept { return end(); }
507
508 [[nodiscard]] TCB_SPAN_ARRAY_CONSTEXPR reverse_iterator rbegin() const noexcept {
509 return reverse_iterator(end());
510 }
511
512 [[nodiscard]] TCB_SPAN_ARRAY_CONSTEXPR reverse_iterator rend() const noexcept {
513 return reverse_iterator(begin());
514 }
515
516 [[nodiscard]] TCB_SPAN_ARRAY_CONSTEXPR const_reverse_iterator crbegin() const
517 noexcept {
518 return const_reverse_iterator(cend());
519 }
520
521 [[nodiscard]] TCB_SPAN_ARRAY_CONSTEXPR const_reverse_iterator crend() const noexcept {
522 return const_reverse_iterator(cbegin());
523 }
524
525 friend constexpr iterator begin(span s) noexcept { return s.begin(); }
526
527 friend constexpr iterator end(span s) noexcept { return s.end(); }
528
529 private:
530 storage_type storage_{};
531 };
532
533# ifdef TCB_SPAN_HAVE_DEDUCTION_GUIDES
534
535 /* Deduction Guides */
536 template<class T, size_t N>
537 span(T (&)[N])->span<T, N>;
538
539 template<class T, size_t N>
540 span(std::array<T, N>&)->span<T, N>;
541
542 template<class T, size_t N>
543 span(const std::array<T, N>&)->span<const T, N>;
544
545 template<class Container>
546 span(Container&)->span<typename Container::value_type>;
547
548 template<class Container>
549 span(const Container&)->span<const typename Container::value_type>;
550
551# endif // TCB_HAVE_DEDUCTION_GUIDES
552
553 template<typename ElementType, std::size_t Extent>
554 constexpr span<ElementType, Extent> make_span(
555 span<ElementType, Extent> s) noexcept {
556 return s;
557 }
558
559 template<typename T, std::size_t N>
560 constexpr span<T, N> make_span(T (&arr)[N]) noexcept {
561 return {arr};
562 }
563
564 template<typename T, std::size_t N>
566 std::array<T, N>& arr) noexcept {
567 return {arr};
568 }
569
570 template<typename T, std::size_t N>
572 const std::array<T, N>& arr) noexcept {
573 return {arr};
574 }
575
576 template<typename Container>
577 constexpr span<typename Container::value_type> make_span(Container& cont) {
578 return {cont};
579 }
580
581 template<typename Container>
582 constexpr span<const typename Container::value_type> make_span(
583 const Container& cont) {
584 return {cont};
585 }
586
587 /* Comparison operators */
588 // Implementation note: the implementations of == and < are equivalent to
589 // 4-legged std::equal and std::lexicographical_compare respectively
590
591 template<typename T, std::size_t X, typename U, std::size_t Y>
592 TCB_SPAN_CONSTEXPR14 bool operator==(span<T, X> lhs, span<U, Y> rhs) {
593 if(lhs.size() != rhs.size()) {
594 return false;
595 }
596
597 for(std::size_t i = 0; i < lhs.size(); i++) {
598 if(lhs[i] != rhs[i]) {
599 return false;
600 }
601 }
602
603 return true;
604 }
605
606 template<typename T, std::size_t X, typename U, std::size_t Y>
607 TCB_SPAN_CONSTEXPR14 bool operator!=(span<T, X> lhs, span<U, Y> rhs) {
608 return !(lhs == rhs);
609 }
610
611 template<typename T, std::size_t X, typename U, std::size_t Y>
612 TCB_SPAN_CONSTEXPR14 bool operator<(span<T, X> lhs, span<U, Y> rhs) {
613 // No std::min to avoid dragging in <algorithm>
614 const std::size_t size =
615 lhs.size() < rhs.size() ? lhs.size() : rhs.size();
616
617 for(std::size_t i = 0; i < size; i++) {
618 if(lhs[i] < rhs[i]) {
619 return true;
620 }
621 if(lhs[i] > rhs[i]) {
622 return false;
623 }
624 }
625 return lhs.size() < rhs.size();
626 }
627
628 template<typename T, std::size_t X, typename U, std::size_t Y>
629 TCB_SPAN_CONSTEXPR14 bool operator<=(span<T, X> lhs, span<U, Y> rhs) {
630 return !(rhs < lhs);
631 }
632
633 template<typename T, std::size_t X, typename U, std::size_t Y>
634 TCB_SPAN_CONSTEXPR14 bool operator>(span<T, X> lhs, span<U, Y> rhs) {
635 return rhs < lhs;
636 }
637
638 template<typename T, std::size_t X, typename U, std::size_t Y>
639 TCB_SPAN_CONSTEXPR14 bool operator>=(span<T, X> lhs, span<U, Y> rhs) {
640 return !(lhs < rhs);
641 }
642
643 template<typename ElementType, std::size_t Extent>
644 span<const byte,
645 ((Extent == dynamic_extent) ? dynamic_extent
646 : sizeof(ElementType) * Extent)>
647 as_bytes(span<ElementType, Extent> s) noexcept {
648 return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()};
649 }
650
651 template<
652 class ElementType, size_t Extent,
653 typename std::enable_if<
654 !std::is_const<ElementType>::value, int>::type = 0>
655 span<byte, ((Extent == dynamic_extent) ? dynamic_extent
656 : sizeof(ElementType) * Extent)>
657 as_writable_bytes(span<ElementType, Extent> s) noexcept {
658 return {reinterpret_cast<byte*>(s.data()), s.size_bytes()};
659 }
660
661 template<std::size_t N, typename E, std::size_t S>
662 constexpr auto get(span<E, S> s) -> decltype(s[N]) {
663 return s[N];
664 }
665
666} // namespace TCB_SPAN_NAMESPACE_NAME
667
668namespace std {
669
670 template<typename ElementType, size_t Extent>
671 class tuple_size<TCB_SPAN_NAMESPACE_NAME::span<ElementType, Extent>>
672 : public integral_constant<size_t, Extent> {};
673
674 template<typename ElementType>
675 class tuple_size<TCB_SPAN_NAMESPACE_NAME::span<
676 ElementType, TCB_SPAN_NAMESPACE_NAME::dynamic_extent>>; // not
677 // defined
678
679 template<size_t I, typename ElementType, size_t Extent>
680 class tuple_element<I, TCB_SPAN_NAMESPACE_NAME::span<ElementType, Extent>> {
681 public:
682 static_assert(
683 Extent != TCB_SPAN_NAMESPACE_NAME::dynamic_extent && I < Extent,
684 "");
685 using type = ElementType;
686 };
687
688} // end namespace std
689
690# endif // TCB_SPAN_HPP_INCLUDED
691#endif
692
693#if defined(CE_HAS_STD_SPAN)
694# define CE_SPAN_NS std
695#else
696# define CE_SPAN_NS tcb
697#endif
698
699namespace CeresEngine {
706 // size.
707 template<typename T, std::size_t Extent = CE_SPAN_NS::dynamic_extent>
708 using Span = CE_SPAN_NS::span<T, Extent>;
709}
710
711#undef CE_HAS_STD_SPAN
712#undef CE_SPAN_NS
#define TCB_SPAN_EXPECT(cond)
Definition Span.hpp:103
#define TCB_SPAN_CONSTEXPR14
Definition Span.hpp:120
#define TCB_SPAN_INLINE_VAR
Definition Span.hpp:109
#define TCB_SPAN_NODISCARD
Definition Span.hpp:163
#define TCB_SPAN_NAMESPACE_NAME
Definition Span.hpp:54
#define TCB_SPAN_ARRAY_CONSTEXPR
Definition Span.hpp:151
#define TCB_SPAN_CONSTEXPR_ASSIGN
Definition Span.hpp:127
#define TCB_SPAN_CONSTEXPR11
Definition Span.hpp:131
constexpr size_t Count
Interface type alias.
Definition Count.hpp:20
Iterator< Generator > end(const Generator &) noexcept
Returns a dummy end iterator.
Definition Iterator.hpp:82
Iterator< Generator > begin(Generator &generator) noexcept
Will return an iterator to the generator.
Definition Iterator.hpp:79
void void_t
Definition FlatHashMap.hpp:144
Definition Application.hpp:19
constexpr CountAlgorithmFunctor count
Returns the number of elements matching an element.
Definition Count.hpp:82
tcb ::span< T, Extent > Span
Span describes an object that can refer to a contiguous sequence of objects with the first element of...
Definition Span.hpp:708
Definition Span.hpp:668
span< byte,((Extent==dynamic_extent) ? dynamic_extent :sizeof(ElementType) *Extent)> as_writable_bytes(span< ElementType, Extent > s) noexcept
Definition Span.hpp:657
unsigned char byte
Definition Span.hpp:157
constexpr auto get(span< E, S > s) -> decltype(s[N])
Definition Span.hpp:662
span< const byte,((Extent==dynamic_extent) ? dynamic_extent :sizeof(ElementType) *Extent)> as_bytes(span< ElementType, Extent > s) noexcept
Definition Span.hpp:647
constexpr std::size_t dynamic_extent
Definition Span.hpp:166
constexpr span< ElementType, Extent > make_span(span< ElementType, Extent > s) noexcept
Definition Span.hpp:554