xref: /llvm-project/libcxx/test/std/containers/views/views.span/span.cons/stdarray.pass.cpp (revision 355e0ce3c5366bd0b564a25e4b6675353da3c53e)
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 // UNSUPPORTED: c++03, c++11, c++14, c++17
9 
10 // <span>
11 
12 // template<size_t N>
13 //     constexpr span(array<value_type, N>& arr) noexcept;
14 // template<size_t N>
15 //     constexpr span(const array<value_type, N>& arr) noexcept;
16 //
17 // Remarks: These constructors shall not participate in overload resolution unless:
18 //   - extent == dynamic_extent || N == extent is true, and
19 //   - remove_pointer_t<decltype(data(arr))>(*)[] is convertible to ElementType(*)[].
20 //
21 
22 
23 #include <span>
24 #include <array>
25 #include <cassert>
26 #include <string>
27 
28 #include "test_macros.h"
29 
checkCV()30 void checkCV()
31 {
32     std::array<int, 3> arr  = {1,2,3};
33 //  STL says these are not cromulent
34 //  std::array<const int,3> carr = {4,5,6};
35 //  std::array<volatile int, 3> varr = {7,8,9};
36 //  std::array<const volatile int, 3> cvarr = {1,3,5};
37 
38 //  Types the same (dynamic sized)
39     {
40     std::span<               int> s1{  arr};    // a span<               int> pointing at int.
41     }
42 
43 //  Types the same (static sized)
44     {
45     std::span<               int,3> s1{  arr};  // a span<               int> pointing at int.
46     }
47 
48 
49 //  types different (dynamic sized)
50     {
51     std::span<const          int> s1{ arr};     // a span<const          int> pointing at int.
52     std::span<      volatile int> s2{ arr};     // a span<      volatile int> pointing at int.
53     std::span<      volatile int> s3{ arr};     // a span<      volatile int> pointing at const int.
54     std::span<const volatile int> s4{ arr};     // a span<const volatile int> pointing at int.
55     }
56 
57 //  types different (static sized)
58     {
59     std::span<const          int,3> s1{ arr};   // a span<const          int> pointing at int.
60     std::span<      volatile int,3> s2{ arr};   // a span<      volatile int> pointing at int.
61     std::span<      volatile int,3> s3{ arr};   // a span<      volatile int> pointing at const int.
62     std::span<const volatile int,3> s4{ arr};   // a span<const volatile int> pointing at int.
63     }
64 }
65 
66 template <typename T, typename U>
testConstructorArray()67 constexpr bool testConstructorArray() {
68   std::array<U, 2> val = {U(), U()};
69   ASSERT_NOEXCEPT(std::span<T>{val});
70   ASSERT_NOEXCEPT(std::span<T, 2>{val});
71   std::span<T> s1{val};
72   std::span<T, 2> s2{val};
73   return s1.data() == &val[0] && s1.size() == 2 && s2.data() == &val[0] &&
74          s2.size() == 2;
75 }
76 
77 template <typename T, typename U>
testConstructorConstArray()78 constexpr bool testConstructorConstArray() {
79   const std::array<U, 2> val = {U(), U()};
80   ASSERT_NOEXCEPT(std::span<const T>{val});
81   ASSERT_NOEXCEPT(std::span<const T, 2>{val});
82   std::span<const T> s1{val};
83   std::span<const T, 2> s2{val};
84   return s1.data() == &val[0] && s1.size() == 2 && s2.data() == &val[0] &&
85          s2.size() == 2;
86 }
87 
88 template <typename T>
testConstructors()89 constexpr bool testConstructors() {
90   static_assert(testConstructorArray<T, T>(), "");
91   static_assert(testConstructorArray<const T, const T>(), "");
92   static_assert(testConstructorArray<const T, T>(), "");
93   static_assert(testConstructorConstArray<T, T>(), "");
94   static_assert(testConstructorConstArray<const T, const T>(), "");
95   static_assert(testConstructorConstArray<const T, T>(), "");
96 
97   return testConstructorArray<T, T>() &&
98          testConstructorArray<const T, const T>() &&
99          testConstructorArray<const T, T>() &&
100          testConstructorConstArray<T, T>() &&
101          testConstructorConstArray<const T, const T>() &&
102          testConstructorConstArray<const T, T>();
103 }
104 
105 struct A{};
106 
main(int,char **)107 int main(int, char**)
108 {
109     assert(testConstructors<int>());
110     assert(testConstructors<long>());
111     assert(testConstructors<double>());
112     assert(testConstructors<A>());
113 
114     assert(testConstructors<int*>());
115     assert(testConstructors<const int*>());
116 
117     checkCV();
118 
119     return 0;
120 }
121