Home | History | Annotate | Download | only in span.cons
      1 // -*- C++ -*-
      2 //===------------------------------ span ---------------------------------===//
      3 //
      4 //                     The LLVM Compiler Infrastructure
      5 //
      6 // This file is dual licensed under the MIT and the University of Illinois Open
      7 // Source Licenses. See LICENSE.TXT for details.
      8 //
      9 //===---------------------------------------------------------------------===//
     10 // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
     11 
     12 // <span>
     13 
     14 //  template<class Container>
     15 //     constexpr span(Container& cont);
     16 //   template<class Container>
     17 //     constexpr span(const Container& cont);
     18 //
     19 // Remarks: These constructors shall not participate in overload resolution unless:
     20 //    Container is not a specialization of span,
     21 //    Container is not a specialization of array,
     22 //    is_array_v<Container> is false,
     23 //    data(cont) and size(cont) are both well-formed, and
     24 //    remove_pointer_t<decltype(data(cont))>(*)[] is convertible to ElementType(*)[].
     25 //
     26 
     27 
     28 #include <span>
     29 #include <cassert>
     30 #include <list>
     31 #include <forward_list>
     32 #include <deque>
     33 
     34 #include "test_macros.h"
     35 
     36 //  Look ma - I'm a container!
     37 template <typename T>
     38 struct IsAContainer {
     39     constexpr IsAContainer() : v_{} {}
     40     constexpr size_t size() const {return 1;}
     41     constexpr       T *data() {return &v_;}
     42     constexpr const T *data() const {return &v_;}
     43 
     44     constexpr const T *getV() const {return &v_;} // for checking
     45     T v_;
     46 };
     47 
     48 template <typename T>
     49 struct NotAContainerNoData {
     50     size_t size() const {return 0;}
     51 };
     52 
     53 template <typename T>
     54 struct NotAContainerNoSize {
     55     const T *data() const {return nullptr;}
     56 };
     57 
     58 template <typename T>
     59 struct NotAContainerPrivate {
     60 private:
     61     size_t size() const {return 0;}
     62     const T *data() const {return nullptr;}
     63 };
     64 
     65 
     66 int main ()
     67 {
     68 
     69 //  Missing size and/or data
     70     {
     71     std::span<int>    s1{IsAContainer<int>()};          // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
     72     std::span<int, 0> s2{IsAContainer<int>()};          // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
     73     std::span<int>    s3{NotAContainerNoData<int>()};   // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
     74     std::span<int, 0> s4{NotAContainerNoData<int>()};   // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
     75     std::span<int>    s5{NotAContainerNoSize<int>()};   // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
     76     std::span<int, 0> s6{NotAContainerNoSize<int>()};   // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
     77     std::span<int>    s7{NotAContainerPrivate<int>()};  // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
     78     std::span<int, 0> s8{NotAContainerPrivate<int>()};  // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
     79 
     80 //  Again with the standard containers
     81     std::span<int>    s11{std::deque<int>()};           // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
     82     std::span<int, 0> s12{std::deque<int>()};           // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
     83     std::span<int>    s13{std::list<int>()};            // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
     84     std::span<int, 0> s14{std::list<int>()};            // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
     85     std::span<int>    s15{std::forward_list<int>()};    // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
     86     std::span<int, 0> s16{std::forward_list<int>()};    // expected-error {{no matching constructor for initialization of 'std::span<int, 0>'}}
     87     }
     88 
     89 //  Not the same type
     90     {
     91     std::span<float>    s1{IsAContainer<int>()};   // expected-error {{no matching constructor for initialization of 'std::span<float>'}}
     92     std::span<float, 0> s2{IsAContainer<int>()};   // expected-error {{no matching constructor for initialization of 'std::span<float, 0>'}}
     93     }
     94 
     95 //  CV wrong (dynamically sized)
     96     {
     97     std::span<               int> s1{IsAContainer<const          int>()};   // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
     98     std::span<               int> s2{IsAContainer<      volatile int>()};   // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
     99     std::span<               int> s3{IsAContainer<const volatile int>()};   // expected-error {{no matching constructor for initialization of 'std::span<int>'}}
    100     std::span<const          int> s4{IsAContainer<      volatile int>()};   // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
    101     std::span<const          int> s5{IsAContainer<const volatile int>()};   // expected-error {{no matching constructor for initialization of 'std::span<const int>'}}
    102     std::span<      volatile int> s6{IsAContainer<const          int>()};   // expected-error {{no matching constructor for initialization of 'std::span<volatile int>'}}
    103     std::span<      volatile int> s7{IsAContainer<const volatile int>()};   // expected-error {{no matching constructor for initialization of 'std::span<volatile int>'}}
    104     }
    105 
    106 //  CV wrong (statically sized)
    107     {
    108     std::span<               int,1> s1{IsAContainer<const          int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 1>'}}
    109     std::span<               int,1> s2{IsAContainer<      volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 1>'}}
    110     std::span<               int,1> s3{IsAContainer<const volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<int, 1>'}}
    111     std::span<const          int,1> s4{IsAContainer<      volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 1>'}}
    112     std::span<const          int,1> s5{IsAContainer<const volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<const int, 1>'}}
    113     std::span<      volatile int,1> s6{IsAContainer<const          int>()}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int, 1>'}}
    114     std::span<      volatile int,1> s7{IsAContainer<const volatile int>()}; // expected-error {{no matching constructor for initialization of 'std::span<volatile int, 1>'}}
    115     }
    116 
    117 }
    118