21 #ifndef FUB_CORE_SPAN_HPP
22 #define FUB_CORE_SPAN_HPP
30 #include <type_traits>
39 template <
typename T>
struct is_std_array : std::false_type {};
40 template <
typename T, std::
size_t N>
41 struct is_std_array<std::array<T, N>> : std::true_type {};
44 template <
typename T>
using data_t = decltype(std::declval<T>().data());
45 template <
typename T>
using element_type_ = std::remove_pointer_t<data_t<T>>;
46 template <
typename T>
using array_type_t = element_type_<T> (*)[];
49 template <
typename T, std::ptrdiff_t N>
class span;
56 template <
typename T>
struct is_span : std::false_type {};
60 template <
typename T, std::ptrdiff_t N>
81 template <
typename T, std::ptrdiff_t N = dynamic_extent>
class span {
83 static_assert(N > 0,
"span's extent needs to be non-negative.");
97 static constexpr std::size_t
sextent =
static_cast<std::size_t
>(N);
157 template <
typename ValueType, std::size_t
Extent,
158 typename = std::enable_if_t<Extent == extent>,
159 typename = std::enable_if_t<std::is_convertible<
161 constexpr
span(
const std::array<ValueType, Extent>& arr) noexcept
174 template <
typename ValueType, std::size_t
Extent,
175 typename = std::enable_if_t<Extent == extent>,
176 typename = std::enable_if_t<std::is_convertible<
178 constexpr
span(std::array<ValueType, Extent>& arr) noexcept
198 template <
typename Container>
200 template <
typename Container,
201 typename = std::enable_if_t<!std::is_array<Container>::value>,
202 typename = std::enable_if_t<
203 !detail::is_std_array<std::remove_const_t<Container>>::value>,
204 typename = std::enable_if_t<!is_span<Container>::value>,
205 typename = std::enable_if_t<std::is_convertible<
206 detected_t<detail::array_type_t, Container&>,
209 constexpr
span(Container& container)
231 template <
typename Container>
235 typename = std::enable_if_t<!std::is_array<Container>::value>,
236 typename = std::enable_if_t<!detail::is_std_array<Container>::value>,
237 typename = std::enable_if_t<!is_span<Container>::value>,
238 typename = std::enable_if_t<std::is_convertible<
242 constexpr
span(
const Container& container)
258 template <
typename S, std::ptrdiff_t M>
261 typename S, std::ptrdiff_t M,
262 typename = std::enable_if_t<std::is_convertible<
264 typename = std::enable_if_t<extent == M>>
272 typename = std::enable_if_t<std::is_convertible<
293 template <ptrdiff_t Count,
294 typename = std::enable_if_t<(0 <= Count && Count <= extent)>>
318 template <ptrdiff_t Count,
319 typename = std::enable_if_t<(0 <= Count && Count <= extent)>>
346 typename = std::enable_if_t<(0 <= Offset && Offset <= extent)>,
348 (0 <= Count && Count + Offset <= extent))>>
350 #ifndef __cpp_if_constexpr
351 struct if_constexpr_t_ {
382 (0 <= count && count + offset <=
size()));
398 return sizeof(T) *
extent;
404 constexpr
bool empty() const noexcept {
return false; }
512 constexpr
span() noexcept = default;
555 template <
typename Container>
557 template <
typename Container,
558 typename = std::enable_if_t<!std::is_array<Container>::value>,
559 typename = std::enable_if_t<!is_span<Container>::value>,
560 typename = std::enable_if_t<
561 std::is_convertible<detected_t<detail::array_type_t, Container>,
562 element_type (*)[]>::value>>
564 constexpr
span(Container& container)
565 : pointer_{container.data()} {
580 template <
typename Container>
582 template <
typename Container,
583 typename = std::enable_if_t<!std::is_array<Container>::value>,
584 typename = std::enable_if_t<!is_span<Container>::value>,
585 typename = std::enable_if_t<
586 std::is_convertible<detected_t<detail::array_type_t, Container>,
587 element_type (*)[]>::value>>
589 constexpr
span(
const Container& container)
590 : pointer_{container.data()} {
602 template <
typename S>
606 typename = std::enable_if_t<std::is_convertible<
610 : pointer_{s.data()} {
628 constexpr std::ptrdiff_t
size_bytes() const noexcept {
return 0; }
633 constexpr
bool empty() const noexcept {
return true; }
657 constexpr
iterator end() const noexcept {
return begin() + size(); }
763 template <std::
size_t M>
777 typename = std::enable_if_t<!std::is_array<Container>::value>,
779 std::enable_if_t<!is_span<std::remove_const_t<Container>>::value>,
780 typename = std::enable_if_t<
781 std::is_convertible<detected_t<detail::array_type_t, Container&>,
783 constexpr
span(Container& container) noexcept
785 container.size())} {}
795 typename = std::enable_if_t<std::is_convertible<S (*)[], T (*)[]>::value>>
797 :
pointer_{s.data()}, size_{s.size()} {}
810 template <ptrdiff_t Count,
typename = std::enable_if_t<0 <= Count>>
811 constexpr span<element_type, Count> first() const {
812 FUB_ASSERT(Count <= size());
813 return {po
inter_, Count};
823 constexpr span<element_type> first(index_type count) const {
824 FUB_ASSERT(0 <= count && count <= size());
825 return {po
inter_, count};
835 template <ptrdiff_t Count,
typename = std::enable_if_t<0 <= Count>>
836 constexpr span<element_type, Count> last() const {
837 FUB_ASSERT(Count <= size());
838 return {po
inter_ + (size() - Count), Count};
848 constexpr span<element_type> last(index_type count) const {
849 FUB_ASSERT(0 <= count && count <= size());
850 return {po
inter_ + (extent - count), count};
861 template <ptrdiff_t Offset, ptrdiff_t Count = dynamic_extent,
862 typename = std::enable_if_t<0 <= Offset>>
863 constexpr span<element_type, Count> subspan() const {
864 FUB_ASSERT(Offset <= size());
865 FUB_ASSERT(Count == dynamic_extent ||
866 (0 <= Count && Count + Offset <= size()));
867 return {po
inter_ + Offset,
868 Count == dynamic_extent ? size() - Offset : Count};
880 constexpr span<element_type>
881 subspan(index_type offset, index_type count = dynamic_extent) const {
882 FUB_ASSERT(0 <= offset && offset <= size());
883 FUB_ASSERT(count == dynamic_extent ||
884 (0 <= count && count + offset <= size()));
885 return {po
inter_ + offset,
886 count == dynamic_extent ? size() - offset : count};
894 constexpr index_type size() const noexcept { return size_; }
899 constexpr index_type size_
bytes() const noexcept { return sizeof(T) * size_; }
904 constexpr
bool empty() const noexcept { return size_ == 0; }
911 constexpr po
inter data() const noexcept { return po
inter_; }
916 constexpr reference operator[](index_type n) const { return po
inter_[n]; }
921 constexpr reference operator()(index_type n) const { return po
inter_[n]; }
928 constexpr iterator begin() const noexcept { return po
inter_; }
933 constexpr const_iterator cbegin() const noexcept { return po
inter_; }
938 constexpr iterator end() const noexcept { return po
inter_ + size_; }
943 constexpr const_iterator cend() const noexcept { return po
inter_ + size_; }
948 constexpr reverse_iterator rbegin() const noexcept {
949 return reverse_iterator(end());
955 constexpr const_reverse_iterator crbegin() const noexcept {
956 return const_reverse_iterator(cend());
962 constexpr reverse_iterator rend() const noexcept {
963 return reverse_iterator(begin());
970 constexpr const_reverse_iterator crend() const noexcept {
971 return const_reverse_iterator(cbegin());
975 po
inter po
inter_{
nullptr};
981 template <
class T,
typename I>
span(T*, I)->span<T>;
983 template <
class T,
size_t N>
984 span(T (&)[N])->span<T,
static_cast<std::ptrdiff_t
>(N)>;
986 template <
class T,
size_t N>
987 span(std::array<T, N>&)->span<T,
static_cast<std::ptrdiff_t
>(N)>;
989 template <
class T,
size_t N>
990 span(
const std::array<T, N>&)->span<
const T,
static_cast<std::ptrdiff_t
>(N)>;
992 template <
class Container>
993 span(Container&)->span<
typename Container::value_type>;
995 template <
class Container>
996 span(
const Container&)->span<
const typename Container::value_type>;
1000 template <
class T,
size_t N>
1005 template <
class T,
size_t N>
1011 template <
class T,
size_t N>
1017 template <
class Container>
1022 template <
class Container>
1032 template <
typename T, std::ptrdiff_t N>
1034 :
public std::integral_constant<std::size_t, static_cast<std::size_t>(N)> {
#define FUB_ASSERT(x)
Definition: assert.hpp:39
A span is a view over a contiguous sequence of objects, the storage of which is owned by some other o...
Definition: span.hpp:489
constexpr std::ptrdiff_t size_bytes() const noexcept
Returns the number of bytes which are spanned by this span.
Definition: span.hpp:628
constexpr const_reverse_iterator crbegin() const noexcept
Returns a const reverse iterator pointing to the last element of the span.
Definition: span.hpp:674
constexpr span(pointer first, pointer last)
Constructs a span from two pointers.
Definition: span.hpp:542
constexpr span() noexcept=default
Constructs an empty span.
constexpr const_iterator cend() const noexcept
Returns a const iterator pointing one after the last element of the span.
Definition: span.hpp:662
T & reference
Definition: span.hpp:493
constexpr span(const span< S, 0 > &s) noexcept
Implicit conversion from other span types.
Definition: span.hpp:609
constexpr reverse_iterator rbegin() const noexcept
Returns a reverse iterator pointing to the last element of the span.
Definition: span.hpp:667
constexpr span(const span &s) noexcept=default
Defaulted copy constructor to trivially copy the class member variables.
constexpr iterator end() const noexcept
Returns an iterator pointing one after the last element of the span.
Definition: span.hpp:657
pointer iterator
Definition: span.hpp:497
std::ptrdiff_t index_type
Definition: span.hpp:495
constexpr bool empty() const noexcept
Returns true if size() == 0.
Definition: span.hpp:633
constexpr pointer data() const noexcept
Returns the underlying pointer.
Definition: span.hpp:640
std::remove_cv_t< T > value_type
Definition: span.hpp:494
T element_type
Definition: span.hpp:491
constexpr iterator begin() const noexcept
Returns an iterator pointing to the first element of the span.
Definition: span.hpp:647
std::ptrdiff_t difference_type
Definition: span.hpp:496
std::add_const_t< T > * const_iterator
Definition: span.hpp:498
constexpr span(Container &container)
Implicit conversion operator from a mutable container.
Definition: span.hpp:564
T * pointer
Definition: span.hpp:492
constexpr span(const Container &container)
Implicit conversion operator from a constant container.
Definition: span.hpp:589
constexpr reverse_iterator rend() const noexcept
Returns a reverse iterator pointing to the first element of the span.
Definition: span.hpp:681
constexpr const_reverse_iterator crend() const noexcept
Returns a const reverse iterator pointing to the first element of the span.
Definition: span.hpp:689
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: span.hpp:500
constexpr index_type size() const noexcept
Returns the number of elements in the span.
Definition: span.hpp:623
std::reverse_iterator< iterator > reverse_iterator
Definition: span.hpp:499
constexpr const_iterator cbegin() const noexcept
Returns a const iterator pointing to the first element of the span.
Definition: span.hpp:652
std::reverse_iterator< iterator > reverse_iterator
Definition: span.hpp:715
constexpr span(Container &container) noexcept
Implicit conversion from mutable Container-like types.
Definition: span.hpp:783
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: span.hpp:716
std::ptrdiff_t difference_type
Definition: span.hpp:712
constexpr span(pointer p, index_type size) noexcept
Constructs a span from a pointer + size pair.
Definition: span.hpp:742
constexpr span(pointer first, pointer last) noexcept
Constructs a span from two pointers.
Definition: span.hpp:754
constexpr span(element_type(&arr)[M]) noexcept
Implicit conversion from a built-in C-style array.
Definition: span.hpp:764
std::remove_cv_t< T > value_type
Definition: span.hpp:710
T * pointer
Definition: span.hpp:708
std::ptrdiff_t index_type
Definition: span.hpp:711
T element_type
Definition: span.hpp:707
std::add_const_t< T > * const_iterator
Definition: span.hpp:714
constexpr span(const span &s) noexcept=default
T & reference
Definition: span.hpp:709
pointer iterator
Definition: span.hpp:713
constexpr span()=default
Constructs an empty span of size 0.
constexpr span(const span< S, OtherExtents > &s) noexcept
Implicit conversion from other span types.
Definition: span.hpp:796
A span is a view over a contiguous sequence of objects, the storage of which is owned by some other o...
Definition: span.hpp:81
constexpr const_reverse_iterator crbegin() const noexcept
Returns a const reverse iterator pointing to the last element of the span.
Definition: span.hpp:455
constexpr span< element_type > subspan(index_type offset, index_type count=dynamic_extent) const
Returns a subspan viewing count many elements from offset offset.
Definition: span.hpp:379
pointer pointer_
Returns an iterator pointing to the first element of the span.
Definition: span.hpp:475
constexpr auto subspan() const
Returns a subspan viewing Count many elements from offset Offset.
Definition: span.hpp:349
constexpr reverse_iterator rbegin() const noexcept
Returns a reverse iterator pointing to the last element of the span.
Definition: span.hpp:448
constexpr span(pointer first, pointer last)
Constructs a span from two pointers.
Definition: span.hpp:134
static constexpr std::size_t sextent
Definition: span.hpp:97
std::ptrdiff_t index_type
Definition: span.hpp:89
T & reference
Definition: span.hpp:87
constexpr reference operator()(index_type n) const
Accesses the n-th element of the spanned array.
Definition: span.hpp:421
static constexpr index_type extent
Definition: span.hpp:96
constexpr index_type size() const noexcept
Returns the number of elements in the span.
Definition: span.hpp:392
constexpr index_type size_bytes() const noexcept
Returns the number of bytes which are spanned by this span.
Definition: span.hpp:397
std::add_const_t< T > * const_iterator
Definition: span.hpp:92
constexpr span(std::array< ValueType, Extent > &arr) noexcept
Implicit conversion from mutable std::arrays.
Definition: span.hpp:178
constexpr reverse_iterator rend() const noexcept
Returns a reverse iterator pointing to the first element of the span.
Definition: span.hpp:462
std::ptrdiff_t difference_type
Definition: span.hpp:90
constexpr const_iterator cend() const noexcept
Returns a const iterator pointing one after the last element of the span.
Definition: span.hpp:443
pointer iterator
Definition: span.hpp:91
T * pointer
Definition: span.hpp:86
constexpr span(const span &s) noexcept=default
Defaulted copy constructor to trivially copy the class member variables.
constexpr iterator begin() const noexcept
Returns an iterator pointing to the first element of the span.
Definition: span.hpp:428
constexpr reference operator[](index_type n) const
Accesses the n-th element of the spanned array.
Definition: span.hpp:416
constexpr span< element_type, Count > last() const
Returns a span of the last Count-many elements of this span.
Definition: span.hpp:320
constexpr iterator end() const noexcept
Returns an iterator pointing one after the last element of the span.
Definition: span.hpp:438
constexpr span(const Container &container)
Implicit conversion operator from a constant container.
Definition: span.hpp:242
constexpr const_iterator cbegin() const noexcept
Returns a const iterator pointing to the first element of the span.
Definition: span.hpp:433
constexpr span(const std::array< ValueType, Extent > &arr) noexcept
Implicit conversion from const std::arrays.
Definition: span.hpp:161
std::reverse_iterator< iterator > reverse_iterator
Definition: span.hpp:93
constexpr span(const span< S, M > &s) noexcept
Implicit conversion from other span types.
Definition: span.hpp:266
constexpr span(const span< S > &s)
Constructs a span from a pointer and size pair.
Definition: span.hpp:274
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: span.hpp:94
constexpr bool empty() const noexcept
Returns true if size() == 0.
Definition: span.hpp:404
constexpr span< element_type > last(index_type count) const
Returns a span of the last count-many elements of this span.
Definition: span.hpp:331
constexpr span(pointer p, [[maybe_unused]] index_type size)
Constructs a span from a pointer and size pair.
Definition: span.hpp:115
constexpr const_reverse_iterator crend() const noexcept
Returns a const reverse iterator pointing to the first element of the span.
Definition: span.hpp:470
std::remove_cv_t< T > value_type
Definition: span.hpp:88
constexpr span< element_type, Count > first() const
Returns a span of the first Count-many elements of this span.
Definition: span.hpp:295
constexpr span(Container &container)
Implicit conversion operator from a mutable container.
Definition: span.hpp:209
T element_type
Definition: span.hpp:85
constexpr span< element_type > first(index_type count) const
Returns a span of the first count-many elements of this span.
Definition: span.hpp:306
constexpr span(element_type(&arr)[sextent]) noexcept
Implicit conversion from a built-in C-style array.
Definition: span.hpp:144
constexpr pointer data() const noexcept
Returns the underlying pointer.
Definition: span.hpp:411
detail::detected_t< Op, Args... > detected_t
Returns the type of Op<Args...> or nonesuch
Definition: type_traits.hpp:97
The fub namespace.
Definition: AnyBoundaryCondition.hpp:31
span(T *, I) -> span< T >
auto make_span(T(&array)[N]) -> span< T, static_cast< std::ptrdiff_t >(N)>
Definition: span.hpp:1001
std::ptrdiff_t Extent(const PatchDataView< T, R, L > &pdv)
Definition: StateRow.hpp:127
static constexpr std::ptrdiff_t dynamic_extent
This is a magic value to denote runtime-known extents.
Definition: dynamic_extent.hpp:28
static constexpr bool is_span_v
Returns true if the specified T is a span<S, N> for some type S and integer N.
Definition: span.hpp:65
Returns true if the specified T is a span<S, N> for some type S and integer N.
Definition: span.hpp:56
This file adds basic type traits utilities which are not yet implemented in all standard libraries.