151 span<T, N>, (N == dynamic_extent ? finite : static_cast<cardinality>(N))>
152 ,
public detail::span_extent<N>
154 CPP_assert(std::is_object<T>::value);
156 using element_type = T;
158 using index_type = detail::span_index_t;
159 using difference_type = index_type;
161 using reference = T &;
162 using iterator = T *;
165 static constexpr index_type extent = N;
167 constexpr span()
noexcept =
default;
168 constexpr span(pointer ptr, index_type cnt) noexcept
169 : detail::span_extent<N>{(RANGES_EXPECT(cnt >= 0), cnt)}
170 , data_{(RANGES_EXPECT(0 == cnt || ptr !=
nullptr), ptr)}
172 template<
typename =
void>
174 constexpr span(pointer first, pointer last) noexcept
175 :
span{first, last - first}
178 template(
typename Rng)(
179 requires (!same_as<
span, uncvref_t<Rng>>) AND
180 span_compatible_range<Rng, T> AND
181 span_dynamic_conversion<Rng, N>)
182 constexpr span(Rng && rng)
noexcept(
noexcept(ranges::data(rng),
184 :
span{ranges::data(rng), detail::narrow_cast<index_type>(ranges::size(rng))}
187 template(
typename Rng)(
188 requires (!same_as<
span, uncvref_t<Rng>>) AND
189 span_compatible_range<Rng, T> AND
190 span_static_conversion<Rng, N>)
191 constexpr span(Rng && rng)
noexcept(
noexcept(ranges::data(rng)))
192 :
span{ranges::data(rng), N}
195 template<index_type Count>
198 static_assert(Count >= 0,
"Count of elements to extract cannot be negative.");
200 N == dynamic_extent || Count <= N,
201 "Count of elements to extract must be less than the static span extent.");
202 return RANGES_EXPECT(Count <= size()),
203 RANGES_EXPECT(Count == 0 || data_ !=
nullptr),
206 constexpr span<T> first(index_type cnt)
const noexcept
208 return RANGES_EXPECT(cnt >= 0 && cnt <= size()),
209 RANGES_EXPECT(cnt == 0 || data_ !=
nullptr),
span<T>{data_, cnt};
212 template<index_type Count>
215 static_assert(Count >= 0,
"Count of elements to extract cannot be negative.");
217 N == dynamic_extent || Count <= N,
218 "Count of elements to extract must be less than the static span extent.");
219 return RANGES_EXPECT(Count <= size()),
220 RANGES_EXPECT((Count == 0 && size() == 0) || data_ !=
nullptr),
223 constexpr span<T> last(index_type cnt)
const noexcept
225 return RANGES_EXPECT(cnt >= 0 && cnt <= size()),
226 RANGES_EXPECT((cnt == 0 && size() == 0) || data_ !=
nullptr),
227 span<T>{data_ + size() - cnt, cnt};
230 template<index_type Offset, index_type Count>
231 constexpr span<T, detail::subspan_extent(N, Offset, Count)> subspan()
const
234 static_assert(Offset >= 0,
235 "Offset of first element to extract cannot be negative.");
236 static_assert(Count >= dynamic_extent,
237 "Count of elements to extract cannot be negative.");
239 N == dynamic_extent ||
240 N >= Offset + (Count == dynamic_extent ? 0 : Count),
241 "Sequence of elements to extract must be within the static span extent.");
242 return RANGES_EXPECT(size() >=
243 Offset + (Count == dynamic_extent ? 0 : Count)),
244 RANGES_EXPECT((Offset == 0 && Count <= 0) || data_ !=
nullptr),
245 span<T, detail::subspan_extent(N, Offset, Count)>{
246 data_ + Offset, Count == dynamic_extent ? size() - Offset : Count};
248 template<index_type Offset>
249 constexpr span<T, (N >= Offset ? N - Offset : dynamic_extent)> subspan()
const
252 static_assert(Offset >= 0,
253 "Offset of first element to extract cannot be negative.");
254 static_assert(N == dynamic_extent || N >= Offset,
255 "Offset of first element to extract must be within the static "
257 return RANGES_EXPECT(size() >= Offset),
258 RANGES_EXPECT((Offset == 0 && size() == 0) || data_ !=
nullptr),
260 N >= Offset ? N - Offset
261 : dynamic_extent > {data_ + Offset, size() - Offset};
265 return RANGES_EXPECT(offset >= 0), RANGES_EXPECT(size() >= offset),
266 RANGES_EXPECT((offset == 0 && size() == 0) || data_ !=
nullptr),
272 return RANGES_EXPECT(offset >= 0), RANGES_EXPECT(cnt >= 0),
273 RANGES_EXPECT(size() >= offset + cnt),
274 RANGES_EXPECT((offset == 0 && cnt == 0) || data_ !=
nullptr),
278 constexpr pointer data()
const noexcept
282 using detail::span_extent<N>::size;
283 constexpr index_type size_bytes()
const noexcept
285 return detail::byte_size<T>(size());
287 constexpr bool empty()
const noexcept
292 constexpr reference operator[](index_type idx)
const noexcept
294 return RANGES_EXPECT(idx >= 0), RANGES_EXPECT(idx < size()),
295 RANGES_EXPECT(data_), data_[idx];
298 constexpr iterator begin()
const noexcept
300 return RANGES_EXPECT(!size() || data_), data_;
302 constexpr iterator end()
const noexcept
304 return RANGES_EXPECT(!size() || data_), data_ + size();
315 template(
typename U, index_type M)(
316 requires equality_comparable_with<T, U>)
317 bool operator==(
span<U, M> const & that)
const
319 RANGES_EXPECT(!size() || data());
320 RANGES_EXPECT(!that.size() || that.data());
321 return ranges::equal(*
this, that);
323 template(
typename U, index_type M)(
324 requires equality_comparable_with<T, U>)
325 bool operator!=(
span<U, M> const & that)
const
327 return !(*
this == that);
330 template(
typename U, index_type M)(
331 requires totally_ordered_with<T, U>)
334 RANGES_EXPECT(!size() || data());
335 RANGES_EXPECT(!that.size() || that.data());
336 return ranges::lexicographical_compare(*
this, that);
338 template(
typename U, index_type M)(
339 requires totally_ordered_with<T, U>)
344 template(
typename U, index_type M)(
345 requires totally_ordered_with<T, U>)
346 bool operator<=(
span<U, M> const & that)
const
348 return !(that < *
this);
350 template(
typename U, index_type M)(
351 requires totally_ordered_with<T, U>)
352 bool operator>=(
span<U, M> const & that)
const
354 return !(*
this < that);