libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

span.pass.cpp (5121B)


      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 OtherElementType, ptrdiff_t OtherExtent>
     15 //    constexpr span(const span<OtherElementType, OtherExtent>& s) noexcept;
     16 //
     17 //  Remarks: This constructor shall not participate in overload resolution unless:
     18 //      Extent == dynamic_extent || Extent == OtherExtent is true, and
     19 //      OtherElementType(*)[] is convertible to ElementType(*)[].
     20 
     21 
     22 #include <span>
     23 #include <cassert>
     24 #include <string>
     25 
     26 #include "test_macros.h"
     27 
     28 void checkCV()
     29 {
     30     std::span<               int>   sp;
     31 //  std::span<const          int>  csp;
     32     std::span<      volatile int>  vsp;
     33 //  std::span<const volatile int> cvsp;
     34 
     35     std::span<               int, 0>   sp0;
     36 //  std::span<const          int, 0>  csp0;
     37     std::span<      volatile int, 0>  vsp0;
     38 //  std::span<const volatile int, 0> cvsp0;
     39 
     40 //  dynamic -> dynamic
     41     {
     42         std::span<const          int> s1{  sp}; // a span<const          int> pointing at int.
     43         std::span<      volatile int> s2{  sp}; // a span<      volatile int> pointing at int.
     44         std::span<const volatile int> s3{  sp}; // a span<const volatile int> pointing at int.
     45         std::span<const volatile int> s4{ vsp}; // a span<const volatile int> pointing at volatile int.
     46         assert(s1.size() + s2.size() + s3.size() + s4.size() == 0);
     47     }
     48 
     49 //  static -> static
     50     {
     51         std::span<const          int, 0> s1{  sp0}; // a span<const          int> pointing at int.
     52         std::span<      volatile int, 0> s2{  sp0}; // a span<      volatile int> pointing at int.
     53         std::span<const volatile int, 0> s3{  sp0}; // a span<const volatile int> pointing at int.
     54         std::span<const volatile int, 0> s4{ vsp0}; // a span<const volatile int> pointing at volatile int.
     55         assert(s1.size() + s2.size() + s3.size() + s4.size() == 0);
     56     }
     57 
     58 //  static -> dynamic
     59     {
     60         std::span<const          int> s1{  sp0};    // a span<const          int> pointing at int.
     61         std::span<      volatile int> s2{  sp0};    // a span<      volatile int> pointing at int.
     62         std::span<const volatile int> s3{  sp0};    // a span<const volatile int> pointing at int.
     63         std::span<const volatile int> s4{ vsp0};    // a span<const volatile int> pointing at volatile int.
     64         assert(s1.size() + s2.size() + s3.size() + s4.size() == 0);
     65     }
     66 
     67 //  dynamic -> static
     68     {
     69         std::span<const          int, 0> s1{  sp};  // a span<const          int> pointing at int.
     70         std::span<      volatile int, 0> s2{  sp};  // a span<      volatile int> pointing at int.
     71         std::span<const volatile int, 0> s3{  sp};  // a span<const volatile int> pointing at int.
     72         std::span<const volatile int, 0> s4{ vsp};  // a span<const volatile int> pointing at volatile int.
     73         assert(s1.size() + s2.size() + s3.size() + s4.size() == 0);
     74     }
     75 }
     76 
     77 
     78 template <typename T>
     79 constexpr bool testConstexprSpan()
     80 {
     81     std::span<T>    s0{};
     82     std::span<T, 0> s1(s0); // dynamic -> static
     83     std::span<T>    s2(s1); // static -> dynamic
     84     ASSERT_NOEXCEPT(std::span<T>   {s0});
     85     ASSERT_NOEXCEPT(std::span<T, 0>{s1});
     86     ASSERT_NOEXCEPT(std::span<T>   {s1});
     87     ASSERT_NOEXCEPT(std::span<T, 0>{s0});
     88 
     89     return
     90         s1.data() == nullptr && s1.size() == 0
     91     &&  s2.data() == nullptr && s2.size() == 0;
     92 }
     93 
     94 
     95 template <typename T>
     96 void testRuntimeSpan()
     97 {
     98     std::span<T>    s0{};
     99     std::span<T, 0> s1(s0); // dynamic -> static
    100     std::span<T>    s2(s1); // static -> dynamic
    101     ASSERT_NOEXCEPT(std::span<T>   {s0});
    102     ASSERT_NOEXCEPT(std::span<T, 0>{s1});
    103     ASSERT_NOEXCEPT(std::span<T>   {s1});
    104     ASSERT_NOEXCEPT(std::span<T, 0>{s0});
    105 
    106     assert(s1.data() == nullptr && s1.size() == 0);
    107     assert(s2.data() == nullptr && s2.size() == 0);
    108 }
    109 
    110 
    111 template <typename Dest, typename Src>
    112 bool testConversionSpan()
    113 {
    114     static_assert(std::is_convertible_v<Src(*)[], Dest(*)[]>, "Bad input types to 'testConversionSpan");
    115     std::span<Src>    s0d{};
    116     std::span<Src>    s0s{};
    117     std::span<Dest, 0> s1(s0d); // dynamic -> static
    118     std::span<Dest>    s2(s0s); // static -> dynamic
    119         s1.data() == nullptr && s1.size() == 0
    120     &&  s2.data() == nullptr && s2.size() == 0;
    121 }
    122 
    123 struct A{};
    124 
    125 int main ()
    126 {
    127     static_assert(testConstexprSpan<int>(),    "");
    128     static_assert(testConstexprSpan<long>(),   "");
    129     static_assert(testConstexprSpan<double>(), "");
    130     static_assert(testConstexprSpan<A>(),      "");
    131 
    132     testRuntimeSpan<int>();
    133     testRuntimeSpan<long>();
    134     testRuntimeSpan<double>();
    135     testRuntimeSpan<std::string>();
    136     testRuntimeSpan<A>();
    137 
    138 //  TODO: Add some conversion tests here that aren't "X --> const X"
    139 //  assert((testConversionSpan<unsigned char, char>()));
    140 
    141     checkCV();
    142 }