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