Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[span] Make span standard_layout #877

Merged
merged 10 commits into from
Jun 24, 2020
69 changes: 32 additions & 37 deletions stl/inc/span
Original file line number Diff line number Diff line change
Expand Up @@ -234,12 +234,9 @@ struct _Span_extent_type {

constexpr explicit _Span_extent_type(size_t, const pointer _Data) noexcept : _Mydata{_Data} {}
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved

_NODISCARD constexpr size_t size() const noexcept {
return _Extent;
}

protected:
pointer _Mydata{nullptr};
static constexpr size_t _Mysize = _Extent;
};

template <class _Ty>
Expand All @@ -249,15 +246,11 @@ struct _Span_extent_type<_Ty, dynamic_extent> {
constexpr _Span_extent_type() noexcept = default;

constexpr explicit _Span_extent_type(const size_t _Size, const pointer _Data) noexcept
: _Mysize(_Size), _Mydata{_Data} {}

_NODISCARD constexpr size_t size() const noexcept {
return _Mysize;
}
: _Mydata{_Data}, _Mysize{_Size} {}

protected:
size_t _Mysize{0};
pointer _Mydata{nullptr};
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
size_t _Mysize{0};
};

template <class _Ty, size_t _Size>
Expand Down Expand Up @@ -356,6 +349,10 @@ inline constexpr bool _Is_span_compatible_range = conjunction_v<
// CLASS TEMPLATE span
template <class _Ty, size_t _Extent = dynamic_extent>
class span : public _Span_extent_type<_Ty, _Extent> {
miscco marked this conversation as resolved.
Show resolved Hide resolved
using _Mybase = _Span_extent_type<_Ty, _Extent>;
using _Mybase::_Mydata;
using _Mybase::_Mysize;

public:
using element_type = _Ty;
using value_type = remove_cv_t<_Ty>;
Expand Down Expand Up @@ -529,7 +526,7 @@ public:
}
#if _CONTAINER_DEBUG_LEVEL > 0
else {
_STL_VERIFY(_Count <= size(), "Count out of range in span::first()");
_STL_VERIFY(_Count <= _Mysize, "Count out of range in span::first()");
}
#endif // _CONTAINER_DEBUG_LEVEL > 0
return span<element_type, _Count>{_Mydata, _Count};
Expand All @@ -538,7 +535,7 @@ public:
_NODISCARD constexpr auto first(const size_type _Count) const noexcept
/* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(_Count <= size(), "Count out of range in span::first(count)");
_STL_VERIFY(_Count <= _Mysize, "Count out of range in span::first(count)");
#endif // _CONTAINER_DEBUG_LEVEL > 0
return span<element_type, dynamic_extent>{_Mydata, _Count};
}
Expand All @@ -550,17 +547,17 @@ public:
}
#if _CONTAINER_DEBUG_LEVEL > 0
else {
_STL_VERIFY(_Count <= size(), "Count out of range in span::last()");
_STL_VERIFY(_Count <= _Mysize, "Count out of range in span::last()");
}
#endif // _CONTAINER_DEBUG_LEVEL > 0
return span<element_type, _Count>{_Mydata + (size() - _Count), _Count};
return span<element_type, _Count>{_Mydata + (_Mysize - _Count), _Count};
}

_NODISCARD constexpr auto last(const size_type _Count) const noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(_Count <= size(), "Count out of range in span::last(count)");
_STL_VERIFY(_Count <= _Mysize, "Count out of range in span::last(count)");
#endif // _CONTAINER_DEBUG_LEVEL > 0
return span<element_type, dynamic_extent>{_Mydata + (size() - _Count), _Count};
return span<element_type, dynamic_extent>{_Mydata + (_Mysize - _Count), _Count};
}

template <size_t _Offset, size_t _Count = dynamic_extent>
Expand All @@ -572,64 +569,66 @@ public:
}
#if _CONTAINER_DEBUG_LEVEL > 0
else {
_STL_VERIFY(_Offset <= size(), "Offset out of range in span::subspan()");
_STL_VERIFY(_Offset <= _Mysize, "Offset out of range in span::subspan()");

if constexpr (_Count != dynamic_extent) {
_STL_VERIFY(_Count <= size() - _Offset, "Count out of range in span::subspan()");
_STL_VERIFY(_Count <= _Mysize - _Offset, "Count out of range in span::subspan()");
}
}
#endif // _CONTAINER_DEBUG_LEVEL > 0
using _ReturnType = span<element_type,
_Count != dynamic_extent ? _Count : (_Extent != dynamic_extent ? _Extent - _Offset : dynamic_extent)>;
return _ReturnType{_Mydata + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
return _ReturnType{_Mydata + _Offset, _Count == dynamic_extent ? _Mysize - _Offset : _Count};
}

_NODISCARD constexpr auto subspan(const size_type _Offset, const size_type _Count = dynamic_extent) const noexcept
/* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(_Offset <= size(), "Offset out of range in span::subspan(offset, count)");
_STL_VERIFY(_Count == dynamic_extent || _Count <= size() - _Offset,
_STL_VERIFY(_Offset <= _Mysize, "Offset out of range in span::subspan(offset, count)");
_STL_VERIFY(_Count == dynamic_extent || _Count <= _Mysize - _Offset,
"Count out of range in span::subspan(offset, count)");
#endif // _CONTAINER_DEBUG_LEVEL > 0
using _ReturnType = span<element_type, dynamic_extent>;
return _ReturnType{_Mydata + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
return _ReturnType{_Mydata + _Offset, _Count == dynamic_extent ? _Mysize - _Offset : _Count};
}

// [span.obs] Observers
using _Span_extent_type<_Ty, _Extent>::size;
_NODISCARD constexpr size_t size() const noexcept {
return _Mysize;
}

_NODISCARD constexpr size_type size_bytes() const noexcept {
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(size() <= dynamic_extent / sizeof(element_type),
_STL_VERIFY(_Mysize <= dynamic_extent / sizeof(element_type),
"size of span in bytes exceeds std::numeric_limits<size_t>::max()");
#endif // _CONTAINER_DEBUG_LEVEL > 0
return size() * sizeof(element_type);
return _Mysize * sizeof(element_type);
}

_NODISCARD constexpr bool empty() const noexcept {
return size() == 0;
return _Mysize == 0;
}

// [span.elem] Element access
_NODISCARD constexpr reference operator[](const size_type _Off) const noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(_Off < size(), "span index out of range");
_STL_VERIFY(_Off < _Mysize, "span index out of range");
#endif // _CONTAINER_DEBUG_LEVEL > 0
return _Mydata[_Off];
}

_NODISCARD constexpr reference front() const noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(size() > 0, "front of empty span");
_STL_VERIFY(_Mysize > 0, "front of empty span");
miscco marked this conversation as resolved.
Show resolved Hide resolved
#endif // _CONTAINER_DEBUG_LEVEL > 0
return _Mydata[0];
}

_NODISCARD constexpr reference back() const noexcept /* strengthened */ {
#if _CONTAINER_DEBUG_LEVEL > 0
_STL_VERIFY(size() > 0, "back of empty span");
_STL_VERIFY(_Mysize > 0, "back of empty span");
#endif // _CONTAINER_DEBUG_LEVEL > 0
return _Mydata[size() - 1];
return _Mydata[_Mysize - 1];
}

_NODISCARD constexpr pointer data() const noexcept {
Expand All @@ -639,14 +638,14 @@ public:
// [span.iterators] Iterator support
_NODISCARD constexpr iterator begin() const noexcept {
#if _ITERATOR_DEBUG_LEVEL >= 1
return {_Mydata, _Mydata, _Mydata + size()};
return {_Mydata, _Mydata, _Mydata + _Mysize};
#else // ^^^ _ITERATOR_DEBUG_LEVEL >= 1 ^^^ // vvv _ITERATOR_DEBUG_LEVEL == 0 vvv
return {_Mydata};
#endif // _ITERATOR_DEBUG_LEVEL
}

_NODISCARD constexpr iterator end() const noexcept {
const auto _End = _Mydata + size();
const auto _End = _Mydata + _Mysize;
#if _ITERATOR_DEBUG_LEVEL >= 1
return {_End, _Mydata, _End};
#else // ^^^ _ITERATOR_DEBUG_LEVEL >= 1 ^^^ // vvv _ITERATOR_DEBUG_LEVEL == 0 vvv
Expand All @@ -667,12 +666,8 @@ public:
}

_NODISCARD constexpr pointer _Unchecked_end() const noexcept {
return _Mydata + size();
return _Mydata + _Mysize;
}

private:
using _Mybase = _Span_extent_type<_Ty, _Extent>;
using _Mybase::_Mydata;
};

// DEDUCTION GUIDES
Expand Down