mirror of
https://github.com/microsoft/GSL.git
synced 2024-11-03 17:56:43 -05:00
Add usage for check-and-unwrap of MS STL iterators (#687)
* Add usage for check-and-unwrap of MS STL iterators
This is Billy ONeal's PR #682 with a typo fixed.
See corresponding change here:
ca77129308
That change officially exposes the STL's range checking machinery,
available in MSVC++ "15.8"+
This change augments GSL span::iterator to call into that newly exposed
machinery.
_Verify_range(cit, cit)
Requests that the iterator type check that the parameters form a valid
[First, Last) range iterator pair. This replaces _DEBUG_RANGE and
supporting machinery. The standard library provides a version for
pointers under _IDL != 0; otherwise they are normally provided via
hidden friend functions. Note that declaring some of these hidden
friends for "wrapper" iterators like move_iterator and reverse_iterator
triggers VSO#610735.
cit._Verify_offset(difference_type _Off)
For random-access iterators, performs any asserts that would be
performed by i += _Off; except with possibly a better error message and
without moving the iterator.
cit._Unwrapped()
Returns an "unchecked" or "unwrapped" iterator which has previously been
validated. The iterator may have been validated by a call to
_Verify_range or _Verify_offset (above), or by seeking a checked
iterator to a "high water mark" point.
it._Seek_to(cit) / it._Seek_to(return value from _Unwrapped())
Moves the position of the checked iterator it to the position of the
unchecked iterator supplied. Generally not intended to perform range
checks.
* Fixed build break in VS2015
* fixed constexpr build break when using VS2015
This commit is contained in:
parent
2be3b00faf
commit
51ae678d08
@ -258,6 +258,44 @@ namespace details
|
|||||||
return !(rhs > lhs);
|
return !(rhs > lhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// MSVC++ iterator debugging support; allows STL algorithms in 15.8+
|
||||||
|
// to unwrap span_iterator to a pointer type after a range check in STL
|
||||||
|
// algorithm calls
|
||||||
|
friend constexpr void _Verify_range(span_iterator lhs,
|
||||||
|
span_iterator rhs) noexcept
|
||||||
|
{ // test that [lhs, rhs) forms a valid range inside an STL algorithm
|
||||||
|
Expects(lhs.span_ == rhs.span_ // range spans have to match
|
||||||
|
&& lhs.index_ <= rhs.index_); // range must not be transposed
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void _Verify_offset(const difference_type n) const noexcept
|
||||||
|
{ // test that the iterator *this + n is a valid range in an STL
|
||||||
|
// algorithm call
|
||||||
|
Expects((index_ + n) >= 0 && (index_ + n) <= span_->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr pointer _Unwrapped() const noexcept
|
||||||
|
{ // after seeking *this to a high water mark, or using one of the
|
||||||
|
// _Verify_xxx functions above, unwrap this span_iterator to a raw
|
||||||
|
// pointer
|
||||||
|
return span_->data() + index_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell the STL that span_iterator should not be unwrapped if it can't
|
||||||
|
// validate in advance, even in release / optimized builds:
|
||||||
|
#if defined(GSL_USE_STATIC_CONSTEXPR_WORKAROUND)
|
||||||
|
static constexpr const bool _Unwrap_when_unverified = false;
|
||||||
|
#else
|
||||||
|
static constexpr bool _Unwrap_when_unverified = false;
|
||||||
|
#endif
|
||||||
|
constexpr void _Seek_to(const pointer p) noexcept
|
||||||
|
{ // adjust the position of *this to previously verified location p
|
||||||
|
// after _Unwrapped
|
||||||
|
index_ = p - span_->data();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const Span* span_ = nullptr;
|
const Span* span_ = nullptr;
|
||||||
std::ptrdiff_t index_ = 0;
|
std::ptrdiff_t index_ = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user