Skip to content

Commit

Permalink
LWG3101 - span's Container constructors need another constraint. Revi…
Browse files Browse the repository at this point in the history
…ewed as https://reviews.llvm.org/D57058.

llvm-svn: 354805
  • Loading branch information
mclow committed Feb 25, 2019
1 parent a20bd27 commit 310b75e
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 64 deletions.
14 changes: 0 additions & 14 deletions libcxx/include/span
Expand Up @@ -225,20 +225,6 @@ public:
_LIBCPP_INLINE_VISIBILITY constexpr span( array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {}
_LIBCPP_INLINE_VISIBILITY constexpr span(const array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {}

template <class _Container>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span( _Container& __c,
enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr)
: __data{_VSTD::data(__c)}
{ _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (container)"); }

template <class _Container>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span(const _Container& __c,
enable_if_t<__is_span_compatible_container<const _Container, _Tp>::value, nullptr_t> = nullptr)
: __data{_VSTD::data(__c)}
{ _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (const container)"); }

template <class _OtherElementType>
inline _LIBCPP_INLINE_VISIBILITY
constexpr span(const span<_OtherElementType, _Extent>& __other,
Expand Down
27 changes: 5 additions & 22 deletions libcxx/test/std/containers/views/span.cons/container.fail.cpp
Expand Up @@ -16,6 +16,7 @@
// constexpr span(const Container& cont);
//
// Remarks: These constructors shall not participate in overload resolution unless:
// — extent == dynamic_extent,
// — Container is not a specialization of span,
// — Container is not a specialization of array,
// — is_array_v<Container> is false,
Expand Down Expand Up @@ -69,37 +70,28 @@ int main(int, char**)
// Making non-const spans from const sources (a temporary binds to `const &`)
{
std::span<int> s1{IsAContainer<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span<int, 0> s2{IsAContainer<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
std::span<int> s3{std::vector<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
std::span<int, 0> s4{std::vector<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
}

// Missing size and/or data
{
std::span<const int> s1{NotAContainerNoData<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
std::span<const int, 0> s2{NotAContainerNoData<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 0>'}}
std::span<const int> s3{NotAContainerNoSize<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
std::span<const int, 0> s4{NotAContainerNoSize<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 0>'}}
std::span<const int> s5{NotAContainerPrivate<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
std::span<const int, 0> s6{NotAContainerPrivate<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 0>'}}

// Again with the standard containers
std::span<const int> s11{std::deque<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
std::span<const int, 0> s12{std::deque<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 0>'}}
std::span<const int> s13{std::list<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
std::span<const int, 0> s14{std::list<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 0>'}}
std::span<const int> s15{std::forward_list<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
std::span<const int, 0> s16{std::forward_list<int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 0>'}}
}

// Not the same type
{
IsAContainer<int> c;
std::span<float> s1{c}; // expected-error {{no matching constructor for initialization of 'std::span<float>'}}
std::span<float, 0> s2{c}; // expected-error {{no matching constructor for initialization of 'std::span<float, 0>'}}
}

// CV wrong (dynamically sized)
// CV wrong
{
IsAContainer<const int> c;
IsAContainer<const volatile int> cv;
Expand All @@ -114,19 +106,10 @@ int main(int, char**)
std::span< volatile int> s7{cv}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int>'}}
}

// CV wrong (statically sized)
// statically sized
{
IsAContainer<const int> c;
IsAContainer<const volatile int> cv;
IsAContainer< volatile int> v;

std::span< int,1> s1{c}; // expected-error {{no matching constructor for initialization of 'std::span<int, 1>'}}
std::span< int,1> s2{v}; // expected-error {{no matching constructor for initialization of 'std::span<int, 1>'}}
std::span< int,1> s3{cv}; // expected-error {{no matching constructor for initialization of 'std::span<int, 1>'}}
std::span<const int,1> s4{v}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 1>'}}
std::span<const int,1> s5{cv}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 1>'}}
std::span< volatile int,1> s6{c}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int, 1>'}}
std::span< volatile int,1> s7{cv}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int, 1>'}}
IsAContainer<int> c;
std::span<int,1> s1{c}; // expected-error {{no matching constructor for initialization of 'std::span<int, 1>'}}
}


Expand Down
33 changes: 5 additions & 28 deletions libcxx/test/std/containers/views/span.cons/container.pass.cpp
Expand Up @@ -16,6 +16,7 @@
// constexpr span(const Container& cont);
//
// Remarks: These constructors shall not participate in overload resolution unless:
// — extent == dynamic_extent,
// — Container is not a specialization of span,
// — Container is not a specialization of array,
// — is_array_v<Container> is false,
Expand Down Expand Up @@ -48,42 +49,25 @@ void checkCV()
{
std::vector<int> v = {1,2,3};

// Types the same (dynamic sized)
// Types the same
{
std::span< int> s1{v}; // a span< int> pointing at int.
}

// Types the same (static sized)
{
std::span< int,3> s1{v}; // a span< int> pointing at int.
}

// types different (dynamic sized)
// types different
{
std::span<const int> s1{v}; // a span<const int> pointing at int.
std::span< volatile int> s2{v}; // a span< volatile int> pointing at int.
std::span< volatile int> s3{v}; // a span< volatile int> pointing at const int.
std::span<const volatile int> s4{v}; // a span<const volatile int> pointing at int.
}

// types different (static sized)
{
std::span<const int,3> s1{v}; // a span<const int> pointing at int.
std::span< volatile int,3> s2{v}; // a span< volatile int> pointing at int.
std::span< volatile int,3> s3{v}; // a span< volatile int> pointing at const int.
std::span<const volatile int,3> s4{v}; // a span<const volatile int> pointing at int.
}

// Constructing a const view from a temporary
{
std::span<const int> s1{IsAContainer<int>()};
std::span<const int, 0> s2{IsAContainer<int>()};
std::span<const int> s3{std::vector<int>()};
std::span<const int, 0> s4{std::vector<int>()};
(void) s1;
(void) s2;
(void) s3;
(void) s4;
}
}

Expand All @@ -92,11 +76,8 @@ template <typename T>
constexpr bool testConstexprSpan()
{
constexpr IsAContainer<const T> val{};
std::span<const T> s1{val};
std::span<const T, 1> s2{val};
return
s1.data() == val.getV() && s1.size() == 1
&& s2.data() == val.getV() && s2.size() == 1;
std::span<const T> s1{val};
return s1.data() == val.getV() && s1.size() == 1;
}


Expand All @@ -107,12 +88,8 @@ void testRuntimeSpan()
const IsAContainer<T> cVal;
std::span<T> s1{val};
std::span<const T> s2{cVal};
std::span<T, 1> s3{val};
std::span<const T, 1> s4{cVal};
assert(s1.data() == val.getV() && s1.size() == 1);
assert(s2.data() == cVal.getV() && s2.size() == 1);
assert(s3.data() == val.getV() && s3.size() == 1);
assert(s4.data() == cVal.getV() && s4.size() == 1);
}

struct A{};
Expand Down

0 comments on commit 310b75e

Please sign in to comment.