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 Count>
13 // constexpr span<element_type, Count> first() const;
14 //
15 // constexpr span<element_type, dynamic_extent> first(size_type count) const;
16 //
17 // Requires: Count <= size().
18
19
20 #include <span>
21 #include <cassert>
22 #include <algorithm>
23 #include <string>
24
25 #include "test_macros.h"
26
27 template <typename Span, size_t Count>
testConstexprSpan(Span sp)28 constexpr bool testConstexprSpan(Span sp)
29 {
30 LIBCPP_ASSERT((noexcept(sp.template first<Count>())));
31 LIBCPP_ASSERT((noexcept(sp.first(Count))));
32 auto s1 = sp.template first<Count>();
33 auto s2 = sp.first(Count);
34 using S1 = decltype(s1);
35 using S2 = decltype(s2);
36 ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
37 ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
38 static_assert(S1::extent == Count, "");
39 static_assert(S2::extent == std::dynamic_extent, "");
40 return
41 s1.data() == s2.data()
42 && s1.size() == s2.size()
43 && std::equal(s1.begin(), s1.end(), sp.begin());
44 }
45
46
47 template <typename Span, size_t Count>
testRuntimeSpan(Span sp)48 void testRuntimeSpan(Span sp)
49 {
50 LIBCPP_ASSERT((noexcept(sp.template first<Count>())));
51 LIBCPP_ASSERT((noexcept(sp.first(Count))));
52 auto s1 = sp.template first<Count>();
53 auto s2 = sp.first(Count);
54 using S1 = decltype(s1);
55 using S2 = decltype(s2);
56 ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
57 ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
58 static_assert(S1::extent == Count, "");
59 static_assert(S2::extent == std::dynamic_extent, "");
60 assert(s1.data() == s2.data());
61 assert(s1.size() == s2.size());
62 assert(std::equal(s1.begin(), s1.end(), sp.begin()));
63 }
64
65
66 constexpr int carr1[] = {1,2,3,4};
67 int arr[] = {5,6,7};
68 std::string sarr [] = { "ABC", "DEF", "GHI", "JKL", "MNO"};
69
main(int,char **)70 int main(int, char**)
71 {
72 {
73 using Sp = std::span<const int>;
74 static_assert(testConstexprSpan<Sp, 0>(Sp{}), "");
75
76 static_assert(testConstexprSpan<Sp, 0>(Sp{carr1}), "");
77 static_assert(testConstexprSpan<Sp, 1>(Sp{carr1}), "");
78 static_assert(testConstexprSpan<Sp, 2>(Sp{carr1}), "");
79 static_assert(testConstexprSpan<Sp, 3>(Sp{carr1}), "");
80 static_assert(testConstexprSpan<Sp, 4>(Sp{carr1}), "");
81 }
82
83 {
84 using Sp = std::span<const int, 4>;
85
86 static_assert(testConstexprSpan<Sp, 0>(Sp{carr1}), "");
87 static_assert(testConstexprSpan<Sp, 1>(Sp{carr1}), "");
88 static_assert(testConstexprSpan<Sp, 2>(Sp{carr1}), "");
89 static_assert(testConstexprSpan<Sp, 3>(Sp{carr1}), "");
90 static_assert(testConstexprSpan<Sp, 4>(Sp{carr1}), "");
91 }
92
93 {
94 using Sp = std::span<int>;
95 testRuntimeSpan<Sp, 0>(Sp{});
96
97 testRuntimeSpan<Sp, 0>(Sp{arr});
98 testRuntimeSpan<Sp, 1>(Sp{arr});
99 testRuntimeSpan<Sp, 2>(Sp{arr});
100 testRuntimeSpan<Sp, 3>(Sp{arr});
101 }
102
103 {
104 using Sp = std::span<int, 3>;
105
106 testRuntimeSpan<Sp, 0>(Sp{arr});
107 testRuntimeSpan<Sp, 1>(Sp{arr});
108 testRuntimeSpan<Sp, 2>(Sp{arr});
109 testRuntimeSpan<Sp, 3>(Sp{arr});
110 }
111
112 {
113 using Sp = std::span<std::string>;
114 testConstexprSpan<Sp, 0>(Sp{});
115
116 testRuntimeSpan<Sp, 0>(Sp{sarr});
117 testRuntimeSpan<Sp, 1>(Sp{sarr});
118 testRuntimeSpan<Sp, 2>(Sp{sarr});
119 testRuntimeSpan<Sp, 3>(Sp{sarr});
120 testRuntimeSpan<Sp, 4>(Sp{sarr});
121 testRuntimeSpan<Sp, 5>(Sp{sarr});
122 }
123
124 {
125 using Sp = std::span<std::string, 5>;
126
127 testRuntimeSpan<Sp, 0>(Sp{sarr});
128 testRuntimeSpan<Sp, 1>(Sp{sarr});
129 testRuntimeSpan<Sp, 2>(Sp{sarr});
130 testRuntimeSpan<Sp, 3>(Sp{sarr});
131 testRuntimeSpan<Sp, 4>(Sp{sarr});
132 testRuntimeSpan<Sp, 5>(Sp{sarr});
133 }
134
135 return 0;
136 }
137