10 typename Vec::value_type;
28template<
class T,
size_t N = std::dynamic_extent>
class Span :
public std::span<T, N> {
30 using Base = std::span<T, N>;
35 explicit(N != std::dynamic_extent)
constexpr Span(std::initializer_list<T> init) noexcept
36 :
Base(
const_cast<T*
>(std::begin(init)), std::ranges::distance(init)) {}
37 constexpr Span(std::span<T, N> span) noexcept
39 template<Vectorlike Vec>
requires(std::is_same_v<typename Vec::value_type, T>)
40 explicit(N != std::dynamic_extent)
constexpr Span(Vec& vec)
41 :
Base(const_cast<T*>(vec.data()), vec.size()) {}
42 template<Vectorlike Vec>
requires(std::is_same_v<std::add_const_t<typename Vec::value_type>, std::add_const_t<T>>)
43 explicit(N != std::dynamic_extent)
constexpr Span(
const Vec& vec)
44 :
Base(const_cast<T*>(vec.data()), vec.size()) {}
45 constexpr explicit Span(
typename Base::pointer p)
47 static_assert(N != std::dynamic_extent);
55 return Base::subspan(i, n);
59 template<
size_t i,
size_t n = std::dynamic_extent>
60 constexpr Span<T, n != std::dynamic_extent ? n : (N != std::dynamic_extent ? N - i : std::dynamic_extent)>
70 return n != std::dynamic_extent ?
subspan(Base::size() - i - n, n) :
subspan(0, Base::size() - i);
74 template<
size_t i,
size_t n = std::dynamic_extent>
75 constexpr Span<T, n != std::dynamic_extent ? n : (N != std::dynamic_extent ? N - i : std::dynamic_extent)>
77 if constexpr (n != std::dynamic_extent)
78 return Span<T, n>(Base::data() + Base::size() - i - n);
79 else if constexpr (N != std::dynamic_extent)
87static_assert(std::ranges::contiguous_range<Span<int>>);
107template<
class T,
size_t N>
struct tuple_size<
mim::Span<T, N>> : std::integral_constant<size_t, N> {};
109template<
size_t I,
class T,
size_t N>
struct tuple_element<I,
mim::Span<T, N>> {
113template<
size_t I,
class T,
size_t N>
constexpr decltype(
auto)
get(
mim::Span<T, N> span) {
return (span[I]); }
This is a thin wrapper for std::span<T, N> with the following additional features:
constexpr Span< T, std::dynamic_extent > rsubspan(size_t i, size_t n=std::dynamic_extent) const
constexpr Span< T, n !=std::dynamic_extent ? n :(N !=std::dynamic_extent ? N - i :std::dynamic_extent)> subspan() const
E.g.: If span points to 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, then the result will point to 2,...
constexpr Span< T, n !=std::dynamic_extent ? n :(N !=std::dynamic_extent ? N - i :std::dynamic_extent)> rsubspan() const
span.rsubspan(3, 5) removes the last 3 elements and while picking 5 elements onwards from there.
constexpr Span< T, std::dynamic_extent > subspan(size_t i, size_t n=std::dynamic_extent) const
constexpr Span(typename Base::pointer p)
constexpr Span(std::span< T, N > span) noexcept
Something which behaves like std::vector or std::array.
Span(I, E) -> Span< std::remove_reference_t< std::iter_reference_t< I > > >
typename mim::Span< T, N >::reference type
constexpr decltype(auto) get(mim::Span< T, N > span)