155 using ElementType =
typename SpanType::element_type;
158 using iterator_category = std::random_access_iterator_tag;
159 using value_type =
typename SpanType::value_type;
160 using difference_type = detail::ptrdiff_t;
162 using reference =
typename std::conditional<
163 IsConst,
const ElementType, ElementType>::type&;
164 using pointer =
typename std::add_pointer<reference>::type;
169 const SpanType* _span,
170 typename SpanType::index_type _idx) __span_noexcept :
171 span_(_span), index_(_idx) {}
174 template <bool B, typename std::enable_if<!B && IsConst>::type* =
nullptr>
180 SPAN_CHECK(index_ < span_->size());
181 return *(span_->data() + index_);
188 SPAN_CHECK(index_ != span_->size());
189 return span_->data() + index_;
193 SPAN_CHECK(index_ != span_->size());
205 SPAN_CHECK(index_ != 0 && index_ <= span_->size());
222 SPAN_CHECK((index_ + n) <= span_->size());
228 SPAN_CHECK(span_ == rhs.span_);
229 return index_ - rhs.index_;
244 return _lhs.span_ == _rhs.span_ && _lhs.index_ == _rhs.index_;
249 return !(_lhs == _rhs);
254 return _lhs.index_ < _rhs.index_;
259 return !(_rhs < _lhs);
269 return !(_rhs > _lhs);
273 const SpanType *span_ {
nullptr };
274 typename SpanType::index_type index_ { 0 };
426 using element_type = T;
427 using value_type =
typename std::remove_cv<T>::type;
428 using index_type = std::size_t;
429 using difference_type = detail::ptrdiff_t;
431 using reference = T&;
435 using reverse_iterator = std::reverse_iterator<iterator>;
436 using const_reverse_iterator =
const std::reverse_iterator<const_iterator>;
439 constexpr Span() __span_noexcept =
default;
442 size_(_count), data_(_ptr) {
443 SPAN_CHECK(!(Extent != dynamic_extent && _count != Extent));
444 SPAN_CHECK(_ptr || _count == 0);
448 size_(_last - _first), data_(_first) {
449 SPAN_CHECK(data_ || size_ == 0);
452 template <std::
size_t N>
454 __span_noexcept : size_(N), data_(&arr[0]) {}
456 template <
class Container,
457 class =
typename std::enable_if<
458 !std::is_const<element_type>::value &&
460 std::is_convertible<typename Container::pointer, pointer>::value &&
461 std::is_convertible<
typename Container::pointer,
462 decltype(std::declval<Container>().data())>::value>::type>
463 Span(Container& _cont) :
464 size_(_cont.size()), data_(_cont.data()) {
468 template <
class Container,
469 class =
typename std::enable_if<
470 std::is_const<element_type>::value &&
472 std::is_convertible<typename Container::pointer, pointer>::value &&
473 std::is_convertible<
typename Container::pointer,
474 decltype(std::declval<Container>().data())>::value>::type>
475 Span(
const Container& _cont) : size_(_cont.size()),
476 data_(_cont.data()) {
480 template <
class U, std::size_t OtherExtent,
481 class =
typename std::enable_if<
485 __span_noexcept : size_(_other.size()), data_(_other.data()) {}
488 __span_noexcept : size_(_other.size()), data_(_other.data()) {}
491 size_ = _other.size();
492 data_ = _other.data();
503 return {
this, size()};
511 return {
this, size()};
514 constexpr reverse_iterator rbegin()
const __span_noexcept {
515 return reverse_iterator{end()};
518 constexpr reverse_iterator rend()
const __span_noexcept {
519 return reverse_iterator{begin()};
522 XGBOOST_DEVICE constexpr const_reverse_iterator crbegin()
const __span_noexcept {
523 return const_reverse_iterator{cend()};
526 XGBOOST_DEVICE constexpr const_reverse_iterator crend()
const __span_noexcept {
527 return const_reverse_iterator{cbegin()};
537 return (*
this)[size() - 1];
541 SPAN_LT(_idx, size());
546 return this->operator[](_idx);
554 XGBOOST_DEVICE constexpr index_type size()
const __span_noexcept {
557 XGBOOST_DEVICE constexpr index_type size_bytes()
const __span_noexcept {
558 return size() *
sizeof(T);
566 template <std::
size_t Count>
568 SPAN_CHECK(Count <= size());
569 return {data(), Count};
573 std::size_t _count)
const {
574 SPAN_CHECK(_count <= size());
575 return {data(), _count};
578 template <std::
size_t Count>
580 SPAN_CHECK(Count <= size());
581 return {data() + size() - Count, Count};
585 std::size_t _count)
const {
586 SPAN_CHECK(_count <= size());
587 return subspan(size() - _count, _count);
594 template <std::size_t Offset,
595 std::size_t Count = dynamic_extent>
598 detail::ExtentValue<Extent, Offset, Count>::value> {
599 SPAN_CHECK((Count == dynamic_extent) ?
600 (Offset <= size()) : (Offset + Count <= size()));
601 return {data() + Offset, Count == dynamic_extent ? size() - Offset : Count};
606 index_type _count = dynamic_extent)
const {
607 SPAN_CHECK((_count == dynamic_extent) ?
608 (_offset <= size()) : (_offset + _count <= size()));
609 return {data() + _offset, _count ==
610 dynamic_extent ? size() - _offset : _count};
614 index_type size_ { 0 };
615 pointer data_ {
nullptr };
679 using value_type =
typename std::iterator_traits<It>::value_type;
680 using index_type = std::size_t;
691 : it_{span.data()}, size_{span.size()} {}
693 [[nodiscard]]
XGBOOST_DEVICE index_type size()
const noexcept {
return size_; }
694 [[nodiscard]]
XGBOOST_DEVICE decltype(
auto)
operator[](index_type i)
const {
return it_[i]; }
695 [[nodiscard]]
XGBOOST_DEVICE decltype(
auto)
operator[](index_type i) {
return it_[i]; }
696 [[nodiscard]]
XGBOOST_DEVICE bool empty()
const noexcept {
return size() == 0; }
697 [[nodiscard]]
XGBOOST_DEVICE It data()
const noexcept {
return it_; }
699 index_type _offset, index_type _count = dynamic_extent)
const {
700 SPAN_CHECK((_count == dynamic_extent) ? (_offset <= size()) : (_offset + _count <= size()));
701 return {data() + _offset, _count == dynamic_extent ? size() - _offset : _count};
703 [[nodiscard]]
XGBOOST_DEVICE constexpr iterator begin()
const noexcept {
706 [[nodiscard]]
XGBOOST_DEVICE constexpr iterator end()
const noexcept {
707 return {
this, size()};