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