diff options
author | Anna Gringauze <annagrin@microsoft.com> | 2018-03-15 12:14:29 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-15 12:14:29 -0700 |
commit | c6bf25a5f6463047a59df3cc5b6fd18c8766c6a8 (patch) | |
tree | 1941990c47e23be54c56f56675c4616a76836987 /include | |
parent | c9e423d7cf2afb88672e31f55e4b30c53be7aae3 (diff) | |
download | platform_external_Microsoft-GSL-c6bf25a5f6463047a59df3cc5b6fd18c8766c6a8.tar.gz platform_external_Microsoft-GSL-c6bf25a5f6463047a59df3cc5b6fd18c8766c6a8.tar.bz2 platform_external_Microsoft-GSL-c6bf25a5f6463047a59df3cc5b6fd18c8766c6a8.zip |
simplified constructors and removed GSL_NOEXCEPT in span (#639)
- simplified storage constructors to reduce branching
- eliminated null check for constructor from array
- removed GSL_NOEXCEPT in span
Diffstat (limited to 'include')
-rw-r--r-- | include/gsl/span | 105 | ||||
-rw-r--r-- | include/gsl/string_span | 3 |
2 files changed, 59 insertions, 49 deletions
diff --git a/include/gsl/span b/include/gsl/span index 622c031..6dd1c1f 100644 --- a/include/gsl/span +++ b/include/gsl/span @@ -58,8 +58,6 @@ #endif // _MSC_VER -#define GSL_NOEXCEPT noexcept - namespace gsl { @@ -136,13 +134,13 @@ namespace details span_iterator() = default; - constexpr span_iterator(const Span* span, typename Span::index_type idx) GSL_NOEXCEPT + constexpr span_iterator(const Span* span, typename Span::index_type idx) noexcept : span_(span), index_(idx) {} friend span_iterator<Span, true>; template<bool B, std::enable_if_t<!B && IsConst>* = nullptr> - constexpr span_iterator(const span_iterator<Span, B>& other) GSL_NOEXCEPT + constexpr span_iterator(const span_iterator<Span, B>& other) noexcept : span_iterator(other.span_, other.index_) { } @@ -220,37 +218,37 @@ namespace details } constexpr friend bool operator==(span_iterator lhs, - span_iterator rhs) GSL_NOEXCEPT + span_iterator rhs) noexcept { return lhs.span_ == rhs.span_ && lhs.index_ == rhs.index_; } constexpr friend bool operator!=(span_iterator lhs, - span_iterator rhs) GSL_NOEXCEPT + span_iterator rhs) noexcept { return !(lhs == rhs); } constexpr friend bool operator<(span_iterator lhs, - span_iterator rhs) GSL_NOEXCEPT + span_iterator rhs) noexcept { return lhs.index_ < rhs.index_; } constexpr friend bool operator<=(span_iterator lhs, - span_iterator rhs) GSL_NOEXCEPT + span_iterator rhs) noexcept { return !(rhs < lhs); } constexpr friend bool operator>(span_iterator lhs, - span_iterator rhs) GSL_NOEXCEPT + span_iterator rhs) noexcept { return rhs < lhs; } constexpr friend bool operator>=(span_iterator lhs, - span_iterator rhs) GSL_NOEXCEPT + span_iterator rhs) noexcept { return !(rhs > lhs); } @@ -284,7 +282,7 @@ namespace details static_assert(Ext >= 0, "A fixed-size span must be >= 0 in size."); - constexpr extent_type() GSL_NOEXCEPT {} + constexpr extent_type() noexcept {} template <index_type Other> constexpr extent_type(extent_type<Other> ext) @@ -296,7 +294,7 @@ namespace details constexpr extent_type(index_type size) { Expects(size == Ext); } - constexpr index_type size() const GSL_NOEXCEPT { return Ext; } + constexpr index_type size() const noexcept { return Ext; } }; template <> @@ -312,7 +310,7 @@ namespace details explicit constexpr extent_type(index_type size) : size_(size) { Expects(size >= 0); } - constexpr index_type size() const GSL_NOEXCEPT { return size_; } + constexpr index_type size() const noexcept { return size_; } private: index_type size_; @@ -355,7 +353,7 @@ public: // "Dependent" is needed to make "std::enable_if_t<Dependent || Extent <= 0>" SFINAE, // since "std::enable_if_t<Extent <= 0>" is ill-formed when Extent is greater than 0. class = std::enable_if_t<(Dependent || Extent <= 0)>> - constexpr span() GSL_NOEXCEPT : storage_(nullptr, details::extent_type<0>()) + constexpr span() noexcept : storage_(nullptr, details::extent_type<0>()) { } @@ -367,19 +365,19 @@ public: } template <std::size_t N> - constexpr span(element_type (&arr)[N]) GSL_NOEXCEPT - : storage_(&arr[0], details::extent_type<N>()) + constexpr span(element_type (&arr)[N]) noexcept + : storage_(KnownNotNull{&arr[0]}, details::extent_type<N>()) { } template <std::size_t N, class ArrayElementType = std::remove_const_t<element_type>> - constexpr span(std::array<ArrayElementType, N>& arr) GSL_NOEXCEPT + constexpr span(std::array<ArrayElementType, N>& arr) noexcept : storage_(&arr[0], details::extent_type<N>()) { } template <std::size_t N> - constexpr span(const std::array<std::remove_const_t<element_type>, N>& arr) GSL_NOEXCEPT + constexpr span(const std::array<std::remove_const_t<element_type>, N>& arr) noexcept : storage_(&arr[0], details::extent_type<N>()) { } @@ -406,7 +404,7 @@ public: { } - constexpr span(const span& other) GSL_NOEXCEPT = default; + constexpr span(const span& other) noexcept = default; template < class OtherElementType, std::ptrdiff_t OtherExtent, @@ -418,8 +416,8 @@ public: { } - ~span() GSL_NOEXCEPT = default; - constexpr span& operator=(const span& other) GSL_NOEXCEPT = default; + ~span() noexcept = default; + constexpr span& operator=(const span& other) noexcept = default; // [span.sub], span subviews template <std::ptrdiff_t Count> @@ -464,12 +462,12 @@ public: // [span.obs], span observers - constexpr index_type size() const GSL_NOEXCEPT { return storage_.size(); } - constexpr index_type size_bytes() const GSL_NOEXCEPT + constexpr index_type size() const noexcept { return storage_.size(); } + constexpr index_type size_bytes() const noexcept { return size() * narrow_cast<index_type>(sizeof(element_type)); } - constexpr bool empty() const GSL_NOEXCEPT { return size() == 0; } + constexpr bool empty() const noexcept { return size() == 0; } // [span.elem], span element access constexpr reference operator[](index_type idx) const @@ -480,22 +478,29 @@ public: constexpr reference at(index_type idx) const { return this->operator[](idx); } constexpr reference operator()(index_type idx) const { return this->operator[](idx); } - constexpr pointer data() const GSL_NOEXCEPT { return storage_.data(); } + constexpr pointer data() const noexcept { return storage_.data(); } // [span.iter], span iterator support - constexpr iterator begin() const GSL_NOEXCEPT { return {this, 0}; } - constexpr iterator end() const GSL_NOEXCEPT { return {this, size()}; } + constexpr iterator begin() const noexcept { return {this, 0}; } + constexpr iterator end() const noexcept { return {this, size()}; } - constexpr const_iterator cbegin() const GSL_NOEXCEPT { return {this, 0}; } - constexpr const_iterator cend() const GSL_NOEXCEPT { return {this, size()}; } + constexpr const_iterator cbegin() const noexcept { return {this, 0}; } + constexpr const_iterator cend() const noexcept { return {this, size()}; } - constexpr reverse_iterator rbegin() const GSL_NOEXCEPT { return reverse_iterator{end()}; } - constexpr reverse_iterator rend() const GSL_NOEXCEPT { return reverse_iterator{begin()}; } + constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator{end()}; } + constexpr reverse_iterator rend() const noexcept { return reverse_iterator{begin()}; } - constexpr const_reverse_iterator crbegin() const GSL_NOEXCEPT { return const_reverse_iterator{cend()}; } - constexpr const_reverse_iterator crend() const GSL_NOEXCEPT { return const_reverse_iterator{cbegin()}; } + constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator{cend()}; } + constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator{cbegin()}; } private: + + // Needed to remove unnecessary null check in subspans + struct KnownNotNull + { + pointer p; + }; + // this implementation detail class lets us take advantage of the // empty base class optimization to pay for only storage of a single // pointer in the case of fixed-size spans @@ -503,16 +508,23 @@ private: class storage_type : public ExtentType { public: + // KnownNotNull parameter is needed to remove unnecessary null check + // in subspans and constructors from arrays + template <class OtherExtentType> + constexpr storage_type(KnownNotNull data, OtherExtentType ext) : ExtentType(ext), data_(data.p) + { + Expects(ExtentType::size() >= 0); + } + - // checked parameter is needed to remove unnecessary null check in subspans template <class OtherExtentType> - constexpr storage_type(pointer data, OtherExtentType ext, bool checked = false) : ExtentType(ext), data_(data) + constexpr storage_type(pointer data, OtherExtentType ext) : ExtentType(ext), data_(data) { - Expects(((checked || !data) && ExtentType::size() == 0) || - ((checked || data) && ExtentType::size() >= 0)); + Expects(ExtentType::size() >= 0); + Expects(data || ExtentType::size() == 0); } - constexpr pointer data() const GSL_NOEXCEPT { return data_; } + constexpr pointer data() const noexcept { return data_; } private: pointer data_; @@ -520,8 +532,9 @@ private: storage_type<details::extent_type<Extent>> storage_; - // The rest is needed to remove unnecessary null check in subspans - constexpr span(pointer ptr, index_type count, bool checked) : storage_(ptr, count, checked) {} + // The rest is needed to remove unnecessary null check + // in subspans and constructors from arrays + constexpr span(KnownNotNull ptr, index_type count) : storage_(ptr, count) {} template <std::ptrdiff_t CallerExtent> class subspan_selector {}; @@ -542,11 +555,11 @@ private: Expects(offset >= 0 && size() - offset >= 0); if (count == dynamic_extent) { - return { data() + offset, size() - offset, true }; + return { KnownNotNull{ data() + offset }, size() - offset }; } Expects(count >= 0 && size() - offset >= count); - return { data() + offset, count, true }; + return { KnownNotNull{ data() + offset }, count }; } }; @@ -625,7 +638,7 @@ namespace details // [span.objectrep], views of object representation template <class ElementType, std::ptrdiff_t Extent> span<const byte, details::calculate_byte_size<ElementType, Extent>::value> -as_bytes(span<ElementType, Extent> s) GSL_NOEXCEPT +as_bytes(span<ElementType, Extent> s) noexcept { return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()}; } @@ -633,7 +646,7 @@ as_bytes(span<ElementType, Extent> s) GSL_NOEXCEPT template <class ElementType, std::ptrdiff_t Extent, class = std::enable_if_t<!std::is_const<ElementType>::value>> span<byte, details::calculate_byte_size<ElementType, Extent>::value> -as_writeable_bytes(span<ElementType, Extent> s) GSL_NOEXCEPT +as_writeable_bytes(span<ElementType, Extent> s) noexcept { return {reinterpret_cast<byte*>(s.data()), s.size_bytes()}; } @@ -654,7 +667,7 @@ constexpr span<ElementType> make_span(ElementType* firstElem, ElementType* lastE } template <class ElementType, std::size_t N> -constexpr span<ElementType, N> make_span(ElementType (&arr)[N]) GSL_NOEXCEPT +constexpr span<ElementType, N> make_span(ElementType (&arr)[N]) noexcept { return span<ElementType, N>(arr); } @@ -693,8 +706,6 @@ constexpr ElementType& at(span<ElementType, Extent> s, index i) } // namespace gsl -#undef GSL_NOEXCEPT - #ifdef _MSC_VER #if _MSC_VER < 1910 #undef constexpr diff --git a/include/gsl/string_span b/include/gsl/string_span index e4b186f..0bb98d2 100644 --- a/include/gsl/string_span +++ b/include/gsl/string_span @@ -417,9 +417,8 @@ public: constexpr string_span_type as_string_span() const GSL_NOEXCEPT { auto sz = span_.size(); - return span_.first(sz <= 0 ? 0 : sz - 1); + return { span_.data(), sz > 1 ? sz - 1 : 0 }; } - constexpr string_span_type ensure_z() const GSL_NOEXCEPT { return gsl::ensure_z(span_); } constexpr const_zstring_type assume_z() const GSL_NOEXCEPT { return span_.data(); } |