mirror of
https://github.com/microsoft/GSL.git
synced 2024-11-03 17:56:43 -05:00
span_iterator: converting constructor isn't a copy constructor (#511)
Fixes #510. * Constrain the converting constructor to not participate in overload resolution when IsConst is true, so that it is never a copy constructor. * Use Default Member Initializers for span_iterator's data members so that the default constructor can be explicitly defaulted. * Declare all members of span_iterator GSL_NOEXCEPT: they only throw when contract violations throw. * Don't use & in operator-> since evil types may overload it.
This commit is contained in:
parent
1f82596e1d
commit
39902b6ec0
@ -141,36 +141,34 @@ namespace details
|
|||||||
using reference = std::conditional_t<IsConst, const element_type_, element_type_>&;
|
using reference = std::conditional_t<IsConst, const element_type_, element_type_>&;
|
||||||
using pointer = std::add_pointer_t<reference>;
|
using pointer = std::add_pointer_t<reference>;
|
||||||
|
|
||||||
constexpr span_iterator() GSL_NOEXCEPT : span_iterator(nullptr, 0) {}
|
span_iterator() = default;
|
||||||
|
|
||||||
constexpr span_iterator(const Span* span, typename Span::index_type index)
|
constexpr span_iterator(const Span* span, typename Span::index_type index)
|
||||||
: span_(span), index_(index)
|
: span_(span), index_(index) GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
Expects(span == nullptr || (index_ >= 0 && index <= span_->length()));
|
Expects(span == nullptr || (index_ >= 0 && index <= span_->length()));
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class span_iterator<Span, true>;
|
friend span_iterator<Span, true>;
|
||||||
constexpr span_iterator(const span_iterator<Span, false>& other) GSL_NOEXCEPT
|
template<bool B, std::enable_if_t<!B && IsConst>* = nullptr>
|
||||||
|
constexpr span_iterator(const span_iterator<Span, B>& other) GSL_NOEXCEPT
|
||||||
: span_iterator(other.span_, other.index_)
|
: span_iterator(other.span_, other.index_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr span_iterator<Span, IsConst>&
|
constexpr reference operator*() const GSL_NOEXCEPT
|
||||||
operator=(const span_iterator<Span, IsConst>&) GSL_NOEXCEPT = default;
|
|
||||||
|
|
||||||
constexpr reference operator*() const
|
|
||||||
{
|
{
|
||||||
Expects(span_);
|
Expects(span_);
|
||||||
return (*span_)[index_];
|
return (*span_)[index_];
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr pointer operator->() const
|
constexpr pointer operator->() const GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
Expects(span_);
|
Expects(span_ && index_ >= 0 && index_ < span_->length());
|
||||||
return &((*span_)[index_]);
|
return span_->data() + index_;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr span_iterator& operator++()
|
constexpr span_iterator& operator++() GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
Expects(span_ && index_ >= 0 && index_ < span_->length());
|
Expects(span_ && index_ >= 0 && index_ < span_->length());
|
||||||
++index_;
|
++index_;
|
||||||
@ -184,7 +182,7 @@ namespace details
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr span_iterator& operator--()
|
constexpr span_iterator& operator--() GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
Expects(span_ && index_ > 0 && index_ <= span_->length());
|
Expects(span_ && index_ > 0 && index_ <= span_->length());
|
||||||
--index_;
|
--index_;
|
||||||
@ -204,7 +202,7 @@ namespace details
|
|||||||
return ret += n;
|
return ret += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr span_iterator& operator+=(difference_type n)
|
constexpr span_iterator& operator+=(difference_type n) GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
Expects(span_ && (index_ + n) >= 0 && (index_ + n) <= span_->length());
|
Expects(span_ && (index_ + n) >= 0 && (index_ + n) <= span_->length());
|
||||||
index_ += n;
|
index_ += n;
|
||||||
@ -219,7 +217,7 @@ namespace details
|
|||||||
|
|
||||||
constexpr span_iterator& operator-=(difference_type n) GSL_NOEXCEPT { return *this += -n; }
|
constexpr span_iterator& operator-=(difference_type n) GSL_NOEXCEPT { return *this += -n; }
|
||||||
|
|
||||||
constexpr difference_type operator-(const span_iterator& rhs) const
|
constexpr difference_type operator-(const span_iterator& rhs) const GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
Expects(span_ == rhs.span_);
|
Expects(span_ == rhs.span_);
|
||||||
return index_ - rhs.index_;
|
return index_ - rhs.index_;
|
||||||
@ -242,7 +240,8 @@ namespace details
|
|||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr friend bool operator<(const span_iterator& lhs, const span_iterator& rhs)
|
constexpr friend bool operator<(const span_iterator& lhs,
|
||||||
|
const span_iterator& rhs) GSL_NOEXCEPT
|
||||||
{
|
{
|
||||||
Expects(lhs.span_ == rhs.span_);
|
Expects(lhs.span_ == rhs.span_);
|
||||||
return lhs.index_ < rhs.index_;
|
return lhs.index_ < rhs.index_;
|
||||||
@ -266,15 +265,9 @@ namespace details
|
|||||||
return !(rhs > lhs);
|
return !(rhs > lhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(span_iterator& rhs) GSL_NOEXCEPT
|
|
||||||
{
|
|
||||||
std::swap(index_, rhs.index_);
|
|
||||||
std::swap(span_, rhs.span_);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const Span* span_;
|
const Span* span_ = nullptr;
|
||||||
std::ptrdiff_t index_;
|
std::ptrdiff_t index_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Span, bool IsConst>
|
template <class Span, bool IsConst>
|
||||||
|
Loading…
Reference in New Issue
Block a user