aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorAnna Gringauze <annagrin@microsoft.com>2018-03-15 12:14:29 -0700
committerGitHub <noreply@github.com>2018-03-15 12:14:29 -0700
commitc6bf25a5f6463047a59df3cc5b6fd18c8766c6a8 (patch)
tree1941990c47e23be54c56f56675c4616a76836987 /include
parentc9e423d7cf2afb88672e31f55e4b30c53be7aae3 (diff)
downloadplatform_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/span105
-rw-r--r--include/gsl/string_span3
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(); }