From c40094a532f932bc0ed7af2279161dc4bc72b85d Mon Sep 17 00:00:00 2001 From: Neil MacIntosh Date: Tue, 1 Mar 2016 12:11:41 -0800 Subject: [PATCH] Added from-container constructors. --- include/multi_span.h | 18 ++++++------- include/span.h | 50 +++++++++++++++++++++++++++++++------ include/string_span.h | 28 ++++++++++----------- tests/span_tests.cpp | 4 +-- tests/string_span_tests.cpp | 2 +- 5 files changed, 68 insertions(+), 34 deletions(-) diff --git a/include/multi_span.h b/include/multi_span.h index b070f29..5eb9109 100644 --- a/include/multi_span.h +++ b/include/multi_span.h @@ -1156,22 +1156,22 @@ namespace details }; template - struct is_span_oracle : std::false_type + struct is_multi_span_oracle : std::false_type { }; template - struct is_span_oracle> : std::true_type + struct is_multi_span_oracle> : std::true_type { }; template - struct is_span_oracle> : std::true_type + struct is_multi_span_oracle> : std::true_type { }; template - struct is_span : is_span_oracle> + struct is_multi_span : is_multi_span_oracle> { }; } @@ -1324,7 +1324,7 @@ public: // type-requirements: container must have .size(), operator[] which are value_type compatible template ::value && + !details::is_multi_span::value && std::is_convertible::value && std::is_same().size(), *std::declval().data())>, @@ -1338,7 +1338,7 @@ public: // prevent constructing from temporary containers template ::value && + !details::is_multi_span::value && std::is_convertible::value && std::is_same().size(), *std::declval().data())>, @@ -1595,7 +1595,7 @@ template as_span(SpanType s, Dimensions2... dims) { - static_assert(details::is_span::value, + static_assert(details::is_multi_span::value, "Variadic as_span() is for reshaping existing spans."); using BoundsType = typename multi_span::bounds_type; @@ -1718,7 +1718,7 @@ constexpr multi_span as_span(T* begin, T* end) template constexpr auto as_span(Cont& arr) -> std::enable_if_t< - !details::is_span>::value, + !details::is_multi_span>::value, multi_span, dynamic_range>> { Expects(arr.size() < PTRDIFF_MAX); @@ -1727,7 +1727,7 @@ constexpr auto as_span(Cont& arr) -> std::enable_if_t< template constexpr auto as_span(Cont&& arr) -> std::enable_if_t< - !details::is_span>::value, + !details::is_multi_span>::value, multi_span, dynamic_range>> = delete; // from basic_string which doesn't have nonconst .data() member like other contiguous containers diff --git a/include/span.h b/include/span.h index 2d95899..eab2659 100644 --- a/include/span.h +++ b/include/span.h @@ -72,12 +72,35 @@ namespace gsl { +template +class span; + + +namespace details +{ +template +struct is_span_oracle : std::false_type +{ +}; + +template +struct is_span_oracle> : std::true_type +{ +}; + +template +struct is_span : is_span_oracle> +{ +}; +} // namespace details + + // [views.constants], constants constexpr const std::ptrdiff_t dynamic_extent = -1; // [span], class template span -template +template class span { public: // constants and types @@ -122,11 +145,25 @@ public: : storage_(&arr[0], extent_type()) {} -#if 0 // TODO - template - constexpr span(Container& cont); - template + // NB: the SFINAE here uses .data() as a incomplete/imperfect proxy for the requirement + // on Container to be a contiguous sequence container. + template ::value && + std::is_convertible::value && + std::is_convertible().data())>::value> + > + constexpr span(Container& cont) : span(cont.data(), cont.size()) {} + + // NB: the SFINAE here uses .data() as an incomplete/imperfect proxy for the requirement + // on Container to be a contiguous sequence container. + template ::value && + std::is_convertible::value && + std::is_convertible().data())>::value> + > span(const Container&&) = delete; + +#if 0 // TODO constexpr span(const span& other) noexcept = default; constexpr span(span&& other) noexcept = default; template @@ -231,9 +268,6 @@ private: storage_type(pointer data, OtherExtentType ext) : ExtentType(ext), data_(data) {} - //storage_type(pointer data, ExtentType ext) - // : ExtentType(ext), data_(data) {} - constexpr inline pointer data() const noexcept { return data_; } diff --git a/include/string_span.h b/include/string_span.h index c58cef9..69c3a81 100644 --- a/include/string_span.h +++ b/include/string_span.h @@ -297,7 +297,7 @@ public: // from containers. Containers must have .size() and .data() function signatures template ::value + typename Dummy = std::enable_if_t::value && !details::is_basic_string_span::value && !(!std::is_const::value && std::is_const::value) // no converting const containers to non-const span && std::is_convertible::value @@ -309,7 +309,7 @@ public: // disallow creation from temporary containers and strings template ::value + typename Dummy = std::enable_if_t::value && !details::is_basic_string_span::value && std::is_convertible::value && std::is_same().size(), *std::declval().data())>, DataType>::value> @@ -640,7 +640,7 @@ bool operator==(const T& one, gsl::basic_string_span other) noexc template ::value + !gsl::details::is_multi_span::value && !gsl::details::is_basic_string_span::value && std::is_convertible::value && std::is_same().size(), *std::declval().data())>, DataType>::value> @@ -654,7 +654,7 @@ bool operator==(gsl::basic_string_span one, const T& other) noexc template ::value + !gsl::details::is_multi_span::value && !gsl::details::is_basic_string_span::value && std::is_convertible::value && std::is_same().size(), *std::declval().data())>, DataType>::value> @@ -694,7 +694,7 @@ bool operator!=(const T& one, gsl::basic_string_span other) noexc template ::value + !gsl::details::is_multi_span::value && !gsl::details::is_basic_string_span::value && std::is_convertible::value && std::is_same().size(), *std::declval().data())>, DataType>::value> @@ -707,7 +707,7 @@ bool operator!=(gsl::basic_string_span one, const T& other) noexc template ::value + !gsl::details::is_multi_span::value && !gsl::details::is_basic_string_span::value && std::is_convertible::value && std::is_same().size(), *std::declval().data())>, DataType>::value> @@ -748,7 +748,7 @@ bool operator<(const T& one, gsl::basic_string_span other) noexce template ::value + !gsl::details::is_multi_span::value && !gsl::details::is_basic_string_span::value && std::is_convertible::value && std::is_same().size(), *std::declval().data())>, DataType>::value> @@ -762,7 +762,7 @@ bool operator<(gsl::basic_string_span one, const T& other) noexce template ::value + !gsl::details::is_multi_span::value && !gsl::details::is_basic_string_span::value && std::is_convertible::value && std::is_same().size(), *std::declval().data())>, DataType>::value> @@ -802,7 +802,7 @@ bool operator<=(const T& one, gsl::basic_string_span other) noexc template ::value + !gsl::details::is_multi_span::value && !gsl::details::is_basic_string_span::value && std::is_convertible::value && std::is_same().size(), *std::declval().data())>, DataType>::value> @@ -815,7 +815,7 @@ bool operator<=(gsl::basic_string_span one, const T& other) noexc template ::value + !gsl::details::is_multi_span::value && !gsl::details::is_basic_string_span::value && std::is_convertible::value && std::is_same().size(), *std::declval().data())>, DataType>::value> @@ -854,7 +854,7 @@ bool operator>(const T& one, gsl::basic_string_span other) noexce template ::value + !gsl::details::is_multi_span::value && !gsl::details::is_basic_string_span::value && std::is_convertible::value && std::is_same().size(), *std::declval().data())>, DataType>::value> @@ -867,7 +867,7 @@ bool operator>(gsl::basic_string_span one, const T& other) noexce template ::value + !gsl::details::is_multi_span::value && !gsl::details::is_basic_string_span::value && std::is_convertible::value && std::is_same().size(), *std::declval().data())>, DataType>::value> @@ -906,7 +906,7 @@ bool operator>=(const T& one, gsl::basic_string_span other) noexc template ::value + !gsl::details::is_multi_span::value && !gsl::details::is_basic_string_span::value && std::is_convertible::value && std::is_same().size(), *std::declval().data())>, DataType>::value> @@ -919,7 +919,7 @@ bool operator>=(gsl::basic_string_span one, const T& other) noexc template ::value + !gsl::details::is_multi_span::value && !gsl::details::is_basic_string_span::value && std::is_convertible::value && std::is_same().size(), *std::declval().data())>, DataType>::value> diff --git a/tests/span_tests.cpp b/tests/span_tests.cpp index e13694c..e68493c 100644 --- a/tests/span_tests.cpp +++ b/tests/span_tests.cpp @@ -438,7 +438,7 @@ SUITE(span_tests) } #endif } -#if 0 + TEST(from_container_constructor) { std::vector v = {1, 2, 3}; @@ -512,7 +512,7 @@ SUITE(span_tests) #endif } } - +#if 0 TEST(from_convertible_span_constructor) { #ifdef CONFIRM_COMPILATION_ERRORS diff --git a/tests/string_span_tests.cpp b/tests/string_span_tests.cpp index cd301a0..6876253 100644 --- a/tests/string_span_tests.cpp +++ b/tests/string_span_tests.cpp @@ -46,7 +46,7 @@ SUITE(string_span_tests) TEST(TestConstructFromStdVector) { std::vector vec(5, 'h'); - string_span<> v = vec; + string_span<> v {vec}; CHECK(v.length() == static_cast::size_type>(vec.size())); }