10 #if __cplusplus >= 201703L
133 #include <type_traits>
135 #define _SYCL_SPAN_TEMPLATE_VIS
136 #define _SYCL_SPAN_INLINE_VISIBILITY inline
142 using byte =
unsigned char;
146 #if defined(__SYCL_DEVICE_ONLY__)
147 #define _SYCL_SPAN_ASSERT(x, m) ((void)0)
149 #define _SYCL_SPAN_ASSERT(x, m) assert(((x) && m))
153 template <
typename _Tp,
size_t _Extent = dynamic_extent>
class span;
155 template <
class _Tp>
struct __is_span_impl :
public std::false_type {};
157 template <
class _Tp,
size_t _Extent>
158 struct __is_span_impl<span<_Tp, _Extent>> :
public std::true_type {};
161 struct __is_span :
public __is_span_impl<std::remove_cv_t<_Tp>> {};
163 template <
class _Tp>
struct __is_std_array_impl :
public std::false_type {};
165 template <
class _Tp,
size_t _Sz>
166 struct __is_std_array_impl<
std::array<_Tp, _Sz>> :
public std::true_type {};
169 struct __is_std_array :
public __is_std_array_impl<std::remove_cv_t<_Tp>> {};
171 template <
class _Tp,
class _ElementType,
class =
void>
172 struct __is_span_compatible_container :
public std::false_type {};
174 template <
class _Tp,
class _ElementType>
175 struct __is_span_compatible_container<
179 typename std::enable_if<!__is_span<_Tp>::value, std::nullptr_t>::type,
181 typename std::enable_if<!__is_std_array<_Tp>::value,
182 std::nullptr_t>::type,
184 typename std::enable_if<!std::is_array_v<_Tp>, std::nullptr_t>::type,
186 decltype(data(std::declval<_Tp>())),
187 decltype(size(std::declval<_Tp>())),
190 typename std::enable_if<
191 std::is_convertible_v<std::remove_pointer_t<decltype(
192 data(std::declval<_Tp &>()))> (*)[],
194 std::nullptr_t>::type>> :
public std::true_type {};
196 template <
typename _Tp,
size_t _Extent>
class _SYCL_SPAN_TEMPLATE_VIS span {
199 using element_type = _Tp;
200 using value_type = std::remove_cv_t<_Tp>;
201 using size_type = size_t;
202 using difference_type = ptrdiff_t;
203 using pointer = _Tp *;
204 using const_pointer =
const _Tp *;
205 using reference = _Tp &;
206 using const_reference =
const _Tp &;
207 using iterator = pointer;
208 using rev_iterator = std::reverse_iterator<pointer>;
210 static constexpr size_type extent = _Extent;
213 template <
size_t _Sz = _Extent,
214 std::enable_if_t<_Sz == 0, std::nullptr_t> =
nullptr>
215 _SYCL_SPAN_INLINE_VISIBILITY constexpr span() noexcept : __data{
nullptr} {}
217 constexpr span(
const span &) noexcept =
default;
218 constexpr span &operator=(
const span &) noexcept =
default;
220 _SYCL_SPAN_INLINE_VISIBILITY constexpr
explicit span(pointer __ptr,
224 _SYCL_SPAN_ASSERT(_Extent == __count,
225 "size mismatch in span's constructor (ptr, len)");
227 _SYCL_SPAN_INLINE_VISIBILITY constexpr
explicit span(pointer __f, pointer __l)
231 "size mismatch in span's constructor (ptr, ptr)");
234 template <
class _OtherElementType,
237 std::nullptr_t> =
nullptr>
238 _SYCL_SPAN_INLINE_VISIBILITY constexpr span(
239 std::array<_OtherElementType, _Extent> &__arr) noexcept
240 : __data{__arr.data()} {}
243 class _OtherElementType,
246 std::nullptr_t> =
nullptr>
247 _SYCL_SPAN_INLINE_VISIBILITY constexpr span(
248 const std::array<_OtherElementType, _Extent> &__arr) noexcept
249 : __data{__arr.data()} {}
251 template <
class _Container>
252 _SYCL_SPAN_INLINE_VISIBILITY constexpr
explicit span(
255 std::nullptr_t> =
nullptr)
256 : __data{std::data(__c)} {
257 _SYCL_SPAN_ASSERT(_Extent == std::size(__c),
258 "size mismatch in span's constructor (range)");
261 template <
class _Container>
262 _SYCL_SPAN_INLINE_VISIBILITY constexpr
explicit span(
263 const _Container &__c,
265 __is_span_compatible_container<const _Container, _Tp>::value,
266 std::nullptr_t> =
nullptr)
267 : __data{std::data(__c)} {
268 _SYCL_SPAN_ASSERT(_Extent == std::size(__c),
269 "size mismatch in span's constructor (range)");
272 template <
class _OtherElementType>
273 _SYCL_SPAN_INLINE_VISIBILITY constexpr span(
274 const span<_OtherElementType, _Extent> &__other,
276 std::is_convertible_v<_OtherElementType (*)[], element_type (*)[]>,
277 std::nullptr_t> =
nullptr)
278 : __data{__other.data()} {}
282 template <
size_t _Count>
283 _SYCL_SPAN_INLINE_VISIBILITY constexpr span<element_type, _Count>
284 first() const noexcept {
285 static_assert(_Count <= _Extent,
"Count out of range in span::first()");
286 return span<element_type, _Count>{data(), _Count};
289 template <
size_t _Count>
290 _SYCL_SPAN_INLINE_VISIBILITY constexpr span<element_type, _Count> last() const
292 static_assert(_Count <= _Extent,
"Count out of range in span::last()");
293 return span<element_type, _Count>{data() + size() - _Count, _Count};
296 _SYCL_SPAN_INLINE_VISIBILITY
297 constexpr span<element_type, dynamic_extent> first(size_type __count)
const
299 _SYCL_SPAN_ASSERT(__count <= size(),
300 "Count out of range in span::first(count)");
301 return {data(), __count};
304 _SYCL_SPAN_INLINE_VISIBILITY
305 constexpr span<element_type, dynamic_extent> last(size_type __count)
const
307 _SYCL_SPAN_ASSERT(__count <= size(),
308 "Count out of range in span::last(count)");
309 return {data() + size() - __count, __count};
312 template <
size_t _Offset,
size_t _Count = dynamic_extent>
313 _SYCL_SPAN_INLINE_VISIBILITY constexpr
auto subspan() const noexcept
314 -> span<element_type,
316 static_assert(_Offset <= _Extent,
"Offset out of range in span::subspan()");
317 static_assert(_Count ==
dynamic_extent || _Count <= _Extent - _Offset,
318 "Offset + count out of range in span::subspan()");
323 return _ReturnType{data() + _Offset,
327 _SYCL_SPAN_INLINE_VISIBILITY
328 constexpr span<element_type, dynamic_extent>
329 subspan(size_type __offset, size_type __count =
dynamic_extent)
const
331 _SYCL_SPAN_ASSERT(__offset <= size(),
332 "Offset out of range in span::subspan(offset, count)");
334 "Count out of range in span::subspan(offset, count)");
336 return {data() + __offset, size() - __offset};
338 __count <= size() - __offset,
339 "Offset + count out of range in span::subspan(offset, count)");
340 return {data() + __offset, __count};
343 _SYCL_SPAN_INLINE_VISIBILITY constexpr size_type size() const noexcept {
346 _SYCL_SPAN_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept {
347 return _Extent *
sizeof(element_type);
349 _SYCL_SPAN_INLINE_VISIBILITY constexpr
bool empty() const noexcept {
353 _SYCL_SPAN_INLINE_VISIBILITY constexpr reference
354 operator[](size_type __idx)
const noexcept {
355 _SYCL_SPAN_ASSERT(__idx < size(),
"span<T,N>[] index out of bounds");
356 return __data[__idx];
359 _SYCL_SPAN_INLINE_VISIBILITY constexpr reference front() const noexcept {
360 _SYCL_SPAN_ASSERT(!empty(),
"span<T, N>::front() on empty span");
364 _SYCL_SPAN_INLINE_VISIBILITY constexpr reference back() const noexcept {
365 _SYCL_SPAN_ASSERT(!empty(),
"span<T, N>::back() on empty span");
366 return __data[size() - 1];
369 _SYCL_SPAN_INLINE_VISIBILITY constexpr pointer data() const noexcept {
374 _SYCL_SPAN_INLINE_VISIBILITY constexpr iterator begin() const noexcept {
375 return iterator(data());
377 _SYCL_SPAN_INLINE_VISIBILITY constexpr iterator end() const noexcept {
378 return iterator(data() + size());
380 _SYCL_SPAN_INLINE_VISIBILITY constexpr rev_iterator rbegin() const noexcept {
381 return rev_iterator(end());
383 _SYCL_SPAN_INLINE_VISIBILITY constexpr rev_iterator rend() const noexcept {
384 return rev_iterator(begin());
387 _SYCL_SPAN_INLINE_VISIBILITY span<
const byte, _Extent *
sizeof(element_type)>
388 __as_bytes() const noexcept {
389 return span<
const byte, _Extent *
sizeof(element_type)>{
390 reinterpret_cast<const byte *
>(data()), size_bytes()};
393 _SYCL_SPAN_INLINE_VISIBILITY span<
byte, _Extent *
sizeof(element_type)>
394 __as_writable_bytes() const noexcept {
395 return span<
byte, _Extent *
sizeof(element_type)>{
396 reinterpret_cast<byte *
>(data()), size_bytes()};
403 template <
typename _Tp>
408 using element_type = _Tp;
409 using value_type = std::remove_cv_t<_Tp>;
410 using size_type = size_t;
411 using difference_type = ptrdiff_t;
412 using pointer = _Tp *;
413 using const_pointer =
const _Tp *;
414 using reference = _Tp &;
415 using const_reference =
const _Tp &;
416 using iterator = pointer;
417 using rev_iterator = std::reverse_iterator<pointer>;
422 _SYCL_SPAN_INLINE_VISIBILITY constexpr span() noexcept
423 : __data{
nullptr}, __size{0} {}
425 constexpr span(
const span &) noexcept =
default;
426 constexpr span &operator=(
const span &) noexcept =
default;
428 _SYCL_SPAN_INLINE_VISIBILITY constexpr span(pointer __ptr, size_type __count)
429 : __data{__ptr}, __size{__count} {}
430 _SYCL_SPAN_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l)
431 : __data{__f}, __size{
static_cast<size_t>(
std::distance(__f, __l))} {}
433 template <
size_t _Sz>
434 _SYCL_SPAN_INLINE_VISIBILITY constexpr span(
435 element_type (&__arr)[_Sz]) noexcept
436 : __data{__arr}, __size{_Sz} {}
438 template <
class _OtherElementType,
size_t _Sz,
441 std::nullptr_t> =
nullptr>
442 _SYCL_SPAN_INLINE_VISIBILITY constexpr span(
443 std::array<_OtherElementType, _Sz> &__arr) noexcept
444 : __data{__arr.data()}, __size{_Sz} {}
447 class _OtherElementType,
size_t _Sz,
450 std::nullptr_t> =
nullptr>
451 _SYCL_SPAN_INLINE_VISIBILITY constexpr span(
452 const std::array<_OtherElementType, _Sz> &__arr) noexcept
453 : __data{__arr.data()}, __size{_Sz} {}
455 template <
class _Container>
456 _SYCL_SPAN_INLINE_VISIBILITY constexpr span(
459 std::nullptr_t> =
nullptr)
460 : __data{std::data(__c)}, __size{(size_type)std::size(__c)} {}
462 template <
class _Container>
463 _SYCL_SPAN_INLINE_VISIBILITY constexpr span(
464 const _Container &__c,
466 __is_span_compatible_container<const _Container, _Tp>::value,
467 std::nullptr_t> =
nullptr)
468 : __data{std::data(__c)}, __size{(size_type)std::size(__c)} {}
470 template <
class _OtherElementType,
size_t _OtherExtent>
471 _SYCL_SPAN_INLINE_VISIBILITY constexpr span(
472 const span<_OtherElementType, _OtherExtent> &__other,
474 std::is_convertible_v<_OtherElementType (*)[], element_type (*)[]>,
475 std::nullptr_t> =
nullptr) noexcept
476 : __data{__other.data()}, __size{__other.size()} {}
480 template <
size_t _Count>
481 _SYCL_SPAN_INLINE_VISIBILITY constexpr span<element_type, _Count>
482 first() const noexcept {
483 _SYCL_SPAN_ASSERT(_Count <= size(),
"Count out of range in span::first()");
484 return span<element_type, _Count>{data(), _Count};
487 template <
size_t _Count>
488 _SYCL_SPAN_INLINE_VISIBILITY constexpr span<element_type, _Count> last() const
490 _SYCL_SPAN_ASSERT(_Count <= size(),
"Count out of range in span::last()");
491 return span<element_type, _Count>{data() + size() - _Count, _Count};
494 _SYCL_SPAN_INLINE_VISIBILITY
495 constexpr span<element_type, dynamic_extent> first(size_type __count)
const
497 _SYCL_SPAN_ASSERT(__count <= size(),
498 "Count out of range in span::first(count)");
499 return {data(), __count};
502 _SYCL_SPAN_INLINE_VISIBILITY
503 constexpr span<element_type, dynamic_extent> last(size_type __count)
const
505 _SYCL_SPAN_ASSERT(__count <= size(),
506 "Count out of range in span::last(count)");
507 return {data() + size() - __count, __count};
510 template <
size_t _Offset,
size_t _Count = dynamic_extent>
511 _SYCL_SPAN_INLINE_VISIBILITY constexpr span<element_type, _Count>
512 subspan() const noexcept {
513 _SYCL_SPAN_ASSERT(_Offset <= size(),
514 "Offset out of range in span::subspan()");
515 _SYCL_SPAN_ASSERT(_Count ==
dynamic_extent || _Count <= size() - _Offset,
516 "Offset + count out of range in span::subspan()");
517 return span<element_type, _Count>{
518 data() + _Offset, _Count ==
dynamic_extent ? size() - _Offset : _Count};
521 constexpr span<element_type, dynamic_extent> _SYCL_SPAN_INLINE_VISIBILITY
522 subspan(size_type __offset, size_type __count =
dynamic_extent)
const
524 _SYCL_SPAN_ASSERT(__offset <= size(),
525 "Offset out of range in span::subspan(offset, count)");
527 "count out of range in span::subspan(offset, count)");
529 return {data() + __offset, size() - __offset};
531 __count <= size() - __offset,
532 "Offset + count out of range in span::subspan(offset, count)");
533 return {data() + __offset, __count};
536 _SYCL_SPAN_INLINE_VISIBILITY constexpr size_type size() const noexcept {
539 _SYCL_SPAN_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept {
540 return __size *
sizeof(element_type);
542 _SYCL_SPAN_INLINE_VISIBILITY constexpr
bool empty() const noexcept {
546 _SYCL_SPAN_INLINE_VISIBILITY constexpr reference
547 operator[](size_type __idx)
const noexcept {
548 _SYCL_SPAN_ASSERT(__idx < size(),
"span<T>[] index out of bounds");
549 return __data[__idx];
552 _SYCL_SPAN_INLINE_VISIBILITY constexpr reference front() const noexcept {
553 _SYCL_SPAN_ASSERT(!empty(),
"span<T>[].front() on empty span");
557 _SYCL_SPAN_INLINE_VISIBILITY constexpr reference back() const noexcept {
558 _SYCL_SPAN_ASSERT(!empty(),
"span<T>[].back() on empty span");
559 return __data[size() - 1];
562 _SYCL_SPAN_INLINE_VISIBILITY constexpr pointer data() const noexcept {
567 _SYCL_SPAN_INLINE_VISIBILITY constexpr iterator begin() const noexcept {
568 return iterator(data());
570 _SYCL_SPAN_INLINE_VISIBILITY constexpr iterator end() const noexcept {
571 return iterator(data() + size());
573 _SYCL_SPAN_INLINE_VISIBILITY constexpr rev_iterator rbegin() const noexcept {
574 return rev_iterator(end());
576 _SYCL_SPAN_INLINE_VISIBILITY constexpr rev_iterator rend() const noexcept {
577 return rev_iterator(begin());
580 _SYCL_SPAN_INLINE_VISIBILITY span<const byte, dynamic_extent>
581 __as_bytes() const noexcept {
582 return {
reinterpret_cast<const byte *
>(data()), size_bytes()};
585 _SYCL_SPAN_INLINE_VISIBILITY span<byte, dynamic_extent>
586 __as_writable_bytes() const noexcept {
587 return {
reinterpret_cast<byte *
>(data()), size_bytes()};
596 template <
class _Tp,
size_t _Extent>
597 _SYCL_SPAN_INLINE_VISIBILITY
auto as_bytes(span<_Tp, _Extent> __s) noexcept
598 -> decltype(__s.__as_bytes()) {
599 return __s.__as_bytes();
602 template <
class _Tp,
size_t _Extent>
603 _SYCL_SPAN_INLINE_VISIBILITY
auto
604 as_writable_bytes(span<_Tp, _Extent> __s) noexcept
605 -> std::enable_if_t<!std::is_const_v<_Tp>,
606 decltype(__s.__as_writable_bytes())> {
607 return __s.__as_writable_bytes();
614 template <
class _Tp,
size_t _Sz>
615 span(_Tp (&)[_Sz]) -> span<_Tp, dynamic_extent>;
617 template <
class _Tp,
size_t _Sz> span(std::array<_Tp, _Sz> &)->span<_Tp, _Sz>;
619 template <
class _Tp,
size_t _Sz>
620 span(
const std::array<_Tp, _Sz> &)->span<
const _Tp, _Sz>;
622 template <
class _Container>
623 span(_Container &)->span<
typename _Container::value_type>;
625 template <
class _Container>
626 span(
const _Container &)->span<
const typename _Container::value_type>;
633 #endif // __cplusplus >= 201703L