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