mirror of
https://github.com/microsoft/GSL.git
synced 2024-11-03 17:56:43 -05:00
[span] Tell MSVC how to avoid range-checking (#664)
* [span] implement non-member + as a hidden friend Drive-by: remove garbage `operator-(difference_type, span_iterator)`. * [span] Use pointers for range-based-for on MSVC
This commit is contained in:
parent
5cbde3008a
commit
d6a2242d97
@ -191,6 +191,11 @@ namespace details
|
|||||||
return ret += n;
|
return ret += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend constexpr span_iterator operator+(difference_type n, span_iterator const& rhs)
|
||||||
|
{
|
||||||
|
return rhs + n;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr span_iterator& operator+=(difference_type n)
|
constexpr span_iterator& operator+=(difference_type n)
|
||||||
{
|
{
|
||||||
Expects((index_ + n) >= 0 && (index_ + n) <= span_->size());
|
Expects((index_ + n) >= 0 && (index_ + n) <= span_->size());
|
||||||
@ -258,22 +263,6 @@ namespace details
|
|||||||
std::ptrdiff_t index_ = 0;
|
std::ptrdiff_t index_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Span, bool IsConst>
|
|
||||||
constexpr span_iterator<Span, IsConst>
|
|
||||||
operator+(typename span_iterator<Span, IsConst>::difference_type n,
|
|
||||||
span_iterator<Span, IsConst> rhs)
|
|
||||||
{
|
|
||||||
return rhs + n;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Span, bool IsConst>
|
|
||||||
constexpr span_iterator<Span, IsConst>
|
|
||||||
operator-(typename span_iterator<Span, IsConst>::difference_type n,
|
|
||||||
span_iterator<Span, IsConst> rhs)
|
|
||||||
{
|
|
||||||
return rhs - n;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <std::ptrdiff_t Ext>
|
template <std::ptrdiff_t Ext>
|
||||||
class extent_type
|
class extent_type
|
||||||
{
|
{
|
||||||
@ -418,7 +407,7 @@ public:
|
|||||||
|
|
||||||
~span() noexcept = default;
|
~span() noexcept = default;
|
||||||
constexpr span& operator=(const span& other) noexcept = default;
|
constexpr span& operator=(const span& other) noexcept = default;
|
||||||
|
|
||||||
// [span.sub], span subviews
|
// [span.sub], span subviews
|
||||||
template <std::ptrdiff_t Count>
|
template <std::ptrdiff_t Count>
|
||||||
constexpr span<element_type, Count> first() const
|
constexpr span<element_type, Count> first() const
|
||||||
@ -493,10 +482,16 @@ public:
|
|||||||
constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator{cend()}; }
|
constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator{cend()}; }
|
||||||
constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator{cbegin()}; }
|
constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator{cbegin()}; }
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// Tell MSVC how to unwrap spans in range-based-for
|
||||||
|
constexpr pointer _Unchecked_begin() const noexcept { return data(); }
|
||||||
|
constexpr pointer _Unchecked_end() const noexcept { return data() + size(); }
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Needed to remove unnecessary null check in subspans
|
// Needed to remove unnecessary null check in subspans
|
||||||
struct KnownNotNull
|
struct KnownNotNull
|
||||||
{
|
{
|
||||||
pointer p;
|
pointer p;
|
||||||
};
|
};
|
||||||
@ -508,7 +503,7 @@ private:
|
|||||||
class storage_type : public ExtentType
|
class storage_type : public ExtentType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// KnownNotNull parameter is needed to remove unnecessary null check
|
// KnownNotNull parameter is needed to remove unnecessary null check
|
||||||
// in subspans and constructors from arrays
|
// in subspans and constructors from arrays
|
||||||
template <class OtherExtentType>
|
template <class OtherExtentType>
|
||||||
constexpr storage_type(KnownNotNull data, OtherExtentType ext) : ExtentType(ext), data_(data.p)
|
constexpr storage_type(KnownNotNull data, OtherExtentType ext) : ExtentType(ext), data_(data.p)
|
||||||
|
Loading…
Reference in New Issue
Block a user