xref: /llvm-project/libcxx/test/std/containers/views/views.span/span.cons/copy.pass.cpp (revision 99696b35bc8a0054e0b0c1a26e8dd5049fa8c41b)
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
10 
11 // <span>
12 
13 //  constexpr span(const span& other) noexcept = default;
14 
15 #include <span>
16 #include <cassert>
17 #include <string>
18 #include <utility>
19 
20 #include "test_macros.h"
21 
22 template <class T>
23 constexpr void test() {
24   ASSERT_NOEXCEPT(std::span<T>(std::declval<std::span<T> const&>()));
25   ASSERT_NOEXCEPT(std::span<T>{std::declval<std::span<T> const&>()});
26 
27   // dynamic_extent
28   {
29     std::span<T> x;
30     std::span<T> copy(x);
31     assert(copy.data() == x.data());
32     assert(copy.size() == x.size());
33   }
34   {
35     T array[3] = {};
36     std::span<T> x(array, 3);
37     std::span<T> copy(x);
38     assert(copy.data() == array);
39     assert(copy.size() == 3);
40   }
41   {
42     T array[3] = {};
43     std::span<T> x(array, 2);
44     std::span<T> copy(x);
45     assert(copy.data() == array);
46     assert(copy.size() == 2);
47   }
48 
49   // static extent
50   {
51     std::span<T, 0> x;
52     std::span<T, 0> copy(x);
53     assert(copy.data() == x.data());
54     assert(copy.size() == x.size());
55   }
56   {
57     T array[3] = {};
58     std::span<T, 3> x(array);
59     std::span<T, 3> copy(x);
60     assert(copy.data() == array);
61     assert(copy.size() == 3);
62   }
63   {
64     T array[2] = {};
65     std::span<T, 2> x(array);
66     std::span<T, 2> copy(x);
67     assert(copy.data() == array);
68     assert(copy.size() == 2);
69   }
70 }
71 
72 struct Foo {};
73 
74 constexpr bool test_all() {
75   test<int>();
76   test<const int>();
77   test<volatile int>();
78   test<const volatile int>();
79 
80   test<long>();
81   test<const long>();
82   test<volatile long>();
83   test<const volatile long>();
84 
85   test<double>();
86   test<const double>();
87   test<volatile double>();
88   test<const volatile double>();
89 
90   // Note: Can't test non-fundamental types with volatile because we require `T*` to be indirectly_readable,
91   //       which isn't the case when T is volatile.
92   test<Foo>();
93   test<const Foo>();
94 
95   test<std::string>();
96   test<const std::string>();
97 
98   // Regression test for https://github.com/llvm/llvm-project/issues/104496
99   {
100     struct Incomplete;
101     std::span<Incomplete> x;
102     std::span<Incomplete> copy(x);
103     assert(copy.data() == x.data());
104     assert(copy.size() == x.size());
105   }
106 
107   return true;
108 }
109 
110 int main(int, char**) {
111   test_all();
112   static_assert(test_all());
113 
114   return 0;
115 }
116