xref: /aosp_15_r20/external/cronet/third_party/libc++/src/test/std/containers/views/views.span/span.elem/at.pass.cpp (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 
9 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
10 
11 // <span>
12 
13 // constexpr reference at(size_type idx) const; // since C++26
14 
15 #include <array>
16 #include <cassert>
17 #include <concepts>
18 #include <limits>
19 #include <span>
20 #include <stdexcept>
21 #include <string>
22 #include <tuple>
23 #include <utility>
24 #include <vector>
25 
26 #include "test_macros.h"
27 
28 template <typename ReferenceT>
testSpanAt(auto && anySpan,int index,int expectedValue)29 constexpr void testSpanAt(auto&& anySpan, int index, int expectedValue) {
30   // non-const
31   {
32     std::same_as<ReferenceT> decltype(auto) elem = anySpan.at(index);
33     assert(elem == expectedValue);
34   }
35 
36   // const
37   {
38     std::same_as<ReferenceT> decltype(auto) elem = std::as_const(anySpan).at(index);
39     assert(elem == expectedValue);
40   }
41 }
42 
test()43 constexpr bool test() {
44   // With static extent
45   {
46     std::array arr{0, 1, 2, 3, 4, 5, 9084};
47     std::span arrSpan{arr};
48 
49     assert(std::dynamic_extent != arrSpan.extent);
50 
51     using ReferenceT = typename decltype(arrSpan)::reference;
52 
53     testSpanAt<ReferenceT>(arrSpan, 0, 0);
54     testSpanAt<ReferenceT>(arrSpan, 1, 1);
55     testSpanAt<ReferenceT>(arrSpan, 6, 9084);
56   }
57 
58   // With dynamic extent
59   {
60     std::vector vec{0, 1, 2, 3, 4, 5, 9084};
61     std::span vecSpan{vec};
62 
63     assert(std::dynamic_extent == vecSpan.extent);
64 
65     using ReferenceT = typename decltype(vecSpan)::reference;
66 
67     testSpanAt<ReferenceT>(vecSpan, 0, 0);
68     testSpanAt<ReferenceT>(vecSpan, 1, 1);
69     testSpanAt<ReferenceT>(vecSpan, 6, 9084);
70   }
71 
72   return true;
73 }
74 
test_exceptions()75 void test_exceptions() {
76 #ifndef TEST_HAS_NO_EXCEPTIONS
77   using namespace std::string_literals;
78 
79   // With static extent
80   {
81     std::array arr{0, 1, 2, 3, 4, 5, 9084, std::numeric_limits<int>::max()};
82     const std::span arrSpan{arr};
83 
84     try {
85       using SizeT = typename decltype(arrSpan)::size_type;
86       std::ignore = arrSpan.at(std::numeric_limits<SizeT>::max());
87       assert(false);
88     } catch ([[maybe_unused]] const std::out_of_range& e) {
89       // pass
90       LIBCPP_ASSERT(e.what() == "span"s);
91     } catch (...) {
92       assert(false);
93     }
94 
95     try {
96       std::ignore = arrSpan.at(arr.size());
97       assert(false);
98     } catch ([[maybe_unused]] const std::out_of_range& e) {
99       // pass
100       LIBCPP_ASSERT(e.what() == "span"s);
101     } catch (...) {
102       assert(false);
103     }
104 
105     try {
106       std::ignore = arrSpan.at(arr.size() - 1);
107       // pass
108       assert(arrSpan.at(arr.size() - 1) == std::numeric_limits<int>::max());
109     } catch (...) {
110       assert(false);
111     }
112   }
113 
114   {
115     std::array<int, 0> arr{};
116     const std::span arrSpan{arr};
117 
118     try {
119       std::ignore = arrSpan.at(0);
120       assert(false);
121     } catch ([[maybe_unused]] const std::out_of_range& e) {
122       // pass
123       LIBCPP_ASSERT(e.what() == "span"s);
124     } catch (...) {
125       assert(false);
126     }
127   }
128 
129   // With dynamic extent
130 
131   {
132     std::vector vec{0, 1, 2, 3, 4, 5, 9084, std::numeric_limits<int>::max()};
133     const std::span vecSpan{vec};
134 
135     try {
136       using SizeT = typename decltype(vecSpan)::size_type;
137       std::ignore = vecSpan.at(std::numeric_limits<SizeT>::max());
138       assert(false);
139     } catch ([[maybe_unused]] const std::out_of_range& e) {
140       // pass
141       LIBCPP_ASSERT(e.what() == "span"s);
142     } catch (...) {
143       assert(false);
144     }
145 
146     try {
147       std::ignore = vecSpan.at(vec.size());
148       assert(false);
149     } catch (const std::out_of_range& e) {
150       // pass
151       LIBCPP_ASSERT(e.what() == "span"s);
152     } catch (...) {
153       assert(false);
154     }
155 
156     try {
157       std::ignore = vecSpan.at(vec.size() - 1);
158       assert(vecSpan.at(vec.size() - 1) == std::numeric_limits<int>::max());
159     } catch (...) {
160       assert(false);
161     }
162   }
163 
164   {
165     std::vector<int> vec{};
166     const std::span vecSpan{vec};
167 
168     try {
169       std::ignore = vecSpan.at(0);
170       assert(false);
171     } catch ([[maybe_unused]] const std::out_of_range& e) {
172       // pass
173       LIBCPP_ASSERT(e.what() == "span"s);
174     } catch (...) {
175       assert(false);
176     }
177   }
178 #endif // TEST_HAS_NO_EXCEPTIONS
179 }
180 
main(int,char **)181 int main(int, char**) {
182   test();
183   static_assert(test());
184 
185   test_exceptions();
186 
187   return 0;
188 }
189