From d3929c59a07a0bd1137601cf2866ffd6dd68d795 Mon Sep 17 00:00:00 2001 From: Neil MacIntosh Date: Wed, 24 Feb 2016 16:11:33 -0800 Subject: [PATCH] Began reimplementation of span. Basic constructors. --- include/gsl_util.h | 1 + include/span.h | 132 ++++++++++++++++++++++++++++++++++++++++--- tests/span_tests.cpp | 2 +- 3 files changed, 126 insertions(+), 9 deletions(-) diff --git a/include/gsl_util.h b/include/gsl_util.h index 316f2a1..508672c 100644 --- a/include/gsl_util.h +++ b/include/gsl_util.h @@ -106,6 +106,7 @@ inline T narrow(U u) T t = narrow_cast(u); if (static_cast(t) != u) throw narrowing_error(); +#pragma warning(suppress:4127) // suppress warning from MSVC compiler about constant in if-test if (!details::is_same_signedness::value && ((t < T{}) != (u < U{}))) throw narrowing_error(); return t; diff --git a/include/span.h b/include/span.h index 7df4964..b8c1196 100644 --- a/include/span.h +++ b/include/span.h @@ -21,16 +21,9 @@ #include "gsl_assert.h" #include "gsl_util.h" -#include #include -#include -#include -#include -#include -#include #include -#include -#include +#include #include #include #include @@ -79,6 +72,129 @@ namespace gsl { +// [views.constants], constants +constexpr const std::ptrdiff_t dynamic_extent = -1; + + +// [span], class template span +template +class span { +public: + // constants and types + using element_type = ElementType; + using index_type = std::ptrdiff_t; + using pointer = element_type*; + using reference = element_type&; +#if 0 // TODO + using iterator = /*implementation-defined */; + using const_iterator = /* implementation-defined */; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; +#endif + constexpr static const index_type extent = Extent; + + // [span.cons], span constructors, copy, assignment, and destructor + constexpr span() noexcept : data_(nullptr), size_(0) + { static_assert(extent == dynamic_extent || extent == 0, "Cannot default initialize a fixed-length span."); } + constexpr span(nullptr_t) noexcept : span() {} + constexpr span(pointer ptr, index_type count) : data_(ptr), size_(count) + { Expects((!ptr && count == 0) || (ptr && count >= 0)); } +#if 0 // TODO + constexpr span(pointer firstElem, pointer lastElem); + template + constexpr span(element_type(&arr)[N]); + template + constexpr span(array, N>& arr); + template + constexpr span(const array, N>& arr); + template + constexpr span(Container& cont); + template + span(const Container&&) = delete; + constexpr span(const span& other) noexcept = default; + constexpr span(span&& other) noexcept = default; + template + constexpr span(const span& other); + template + constexpr span(span&& other); + ~span() noexcept = default; + constexpr span& operator=(const span& other) noexcept = default; + constexpr span& operator=(span&& other) noexcept = default; + + // [span.sub], span subviews + template + constexpr span first() const; + template + constexpr span last() const; + template + constexpr span subspan() const; + constexpr span first(index_type count) const; + constexpr span last(index_type count) const; + constexpr span subspan(index_type offset, index_type count = dynamic_extent) const; +#endif + // [span.obs], span observers + constexpr index_type length() const noexcept { return size(); } + constexpr index_type size() const noexcept { return size_; } + constexpr index_type length_bytes() const noexcept { return size_bytes(); } + constexpr index_type size_bytes() const noexcept { return size() * sizeof(element_type); } + constexpr bool empty() const noexcept { return size() == 0; } + +#if 0 // TODO + // [span.elem], span element access + constexpr reference operator[](index_type idx) const; + constexpr reference operator()(index_type idx) const; +#endif + constexpr pointer data() const noexcept { return data_; } +#if 0 // TODO + // [span.iter], span iterator support + iterator begin() const noexcept; + iterator end() const noexcept; + + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; + + reverse_iterator rbegin() const noexcept; + reverse_iterator rend() const noexcept; + + const_reverse_iterator crbegin() const noexcept; + const_reverse_iterator crend() const noexcept; +#endif +private: + pointer data_; + index_type size_; +}; + + +#if 0 // TODO +// [span.comparison], span comparison operators +template +constexpr bool operator==(const span& l, const span& r) const noexcept; + +template +constexpr bool operator!=(const span& l, const span& r) const noexcept; + +template +constexpr bool operator<(const span& l, const span& r) const noexcept; + +template +constexpr bool operator<=(const span& l, const span& r) const noexcept; + +template +constexpr bool operator>(const span& l, const span& r) const noexcept; + +template +constexpr bool operator>=(const span& l, const span& r) const noexcept; +#endif + + +#if 0 // TODO +// [span.objectrep], views of object representation +template +constexpr span as_bytes(span s) noexcept; + +template +constexpr span as_writeable_bytes(span) noexcept; +#endif } // namespace gsl diff --git a/tests/span_tests.cpp b/tests/span_tests.cpp index 83eec0e..233ab00 100644 --- a/tests/span_tests.cpp +++ b/tests/span_tests.cpp @@ -39,7 +39,6 @@ struct DerivedClass : BaseClass SUITE(span_tests) { -#if 0 TEST(default_constructor) { { @@ -116,6 +115,7 @@ SUITE(span_tests) } } +#if 0 TEST(from_nullptr_length_constructor) { {