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.