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