xref: /llvm-project/libcxx/test/std/containers/views/views.span/span.sub/last.pass.cpp (revision fb855eb941b6d740cc6560297d0b4d3201dcaf9f)
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