diff options
author | Anna Gringauze <annagrin@microsoft.com> | 2018-05-22 18:07:49 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-22 18:07:49 -0700 |
commit | 51ae678d080c4b9b97419c1ca716b2c464d72741 (patch) | |
tree | 7e35cabcd9b0183cdd79768a1408d8ce5344207e /include | |
parent | 2be3b00faf46e56845029611a179ea1d3546b309 (diff) | |
download | platform_external_Microsoft-GSL-51ae678d080c4b9b97419c1ca716b2c464d72741.tar.gz platform_external_Microsoft-GSL-51ae678d080c4b9b97419c1ca716b2c464d72741.tar.bz2 platform_external_Microsoft-GSL-51ae678d080c4b9b97419c1ca716b2c464d72741.zip |
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:
https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_git/msvc/commit/ca77129308c775f422ecef0c01ad460f75c462ad
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
Diffstat (limited to 'include')
-rw-r--r-- | include/gsl/span | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/include/gsl/span b/include/gsl/span index f5f1332..dd2d053 100644 --- a/include/gsl/span +++ b/include/gsl/span @@ -258,6 +258,44 @@ namespace details 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: const Span* span_ = nullptr; std::ptrdiff_t index_ = 0; |