]>
Commit | Line | Data |
---|---|---|
f427ee49 A |
1 | // |
2 | // Tests for | |
3 | // bounded_array_ref<T, TrappingPolicy> slice(size_t n, size_t m) const; | |
4 | // | |
5 | ||
6 | #include <libkern/c++/bounded_array_ref.h> | |
7 | #include "test_policy.h" | |
8 | #include <cstddef> | |
9 | #include <cstdint> | |
10 | #include <darwintest.h> | |
11 | #include <darwintest_utils.h> | |
12 | #include <limits> | |
13 | ||
14 | struct T { int i; }; | |
15 | ||
16 | template <typename T> | |
17 | using tracking_bounded_array_ref = libkern::bounded_array_ref<T, tracking_policy>; | |
18 | ||
19 | template <typename T> | |
20 | static void | |
21 | tests() | |
22 | { | |
23 | T array[5] = {T{0}, T{1}, T{2}, T{3}, T{4}}; | |
24 | ||
25 | // Slices starting at 0 | |
26 | { | |
27 | test_bounded_array_ref<T> view(array); | |
28 | test_bounded_array_ref<T> slice = view.slice(0, 0); | |
29 | CHECK(slice.size() == 0); | |
30 | } | |
31 | { | |
32 | test_bounded_array_ref<T> view(array); | |
33 | test_bounded_array_ref<T> slice = view.slice(0, 1); | |
34 | CHECK(slice.size() == 1); | |
35 | CHECK(&slice[0] == &array[0]); | |
36 | } | |
37 | { | |
38 | test_bounded_array_ref<T> view(array); | |
39 | test_bounded_array_ref<T> slice = view.slice(0, 2); | |
40 | CHECK(slice.size() == 2); | |
41 | CHECK(&slice[0] == &array[0]); | |
42 | CHECK(&slice[1] == &array[1]); | |
43 | } | |
44 | { | |
45 | test_bounded_array_ref<T> view(array); | |
46 | test_bounded_array_ref<T> slice = view.slice(0, 5); | |
47 | CHECK(slice.size() == 5); | |
48 | CHECK(&slice[0] == &array[0]); | |
49 | CHECK(&slice[1] == &array[1]); | |
50 | CHECK(&slice[2] == &array[2]); | |
51 | CHECK(&slice[3] == &array[3]); | |
52 | CHECK(&slice[4] == &array[4]); | |
53 | } | |
54 | { | |
55 | tracking_bounded_array_ref<T> view(array); | |
56 | tracking_policy::reset(); | |
57 | tracking_bounded_array_ref<T> slice = view.slice(0, 6); | |
58 | CHECK(tracking_policy::did_trap); | |
59 | CHECK(tracking_policy::message == "bounded_array_ref: invalid slice provided, the indices are of bounds for the bounded_array_ref"); | |
60 | } | |
61 | ||
62 | // Slices starting at 1 (near the beginning) | |
63 | { | |
64 | test_bounded_array_ref<T> view(array); | |
65 | test_bounded_array_ref<T> slice = view.slice(1, 0); | |
66 | CHECK(slice.size() == 0); | |
67 | } | |
68 | { | |
69 | test_bounded_array_ref<T> view(array); | |
70 | test_bounded_array_ref<T> slice = view.slice(1, 3); | |
71 | CHECK(slice.size() == 3); | |
72 | CHECK(&slice[0] == &array[1]); | |
73 | CHECK(&slice[1] == &array[2]); | |
74 | CHECK(&slice[2] == &array[3]); | |
75 | } | |
76 | { | |
77 | test_bounded_array_ref<T> view(array); | |
78 | test_bounded_array_ref<T> slice = view.slice(1, 4); | |
79 | CHECK(slice.size() == 4); | |
80 | CHECK(&slice[0] == &array[1]); | |
81 | CHECK(&slice[1] == &array[2]); | |
82 | CHECK(&slice[2] == &array[3]); | |
83 | CHECK(&slice[3] == &array[4]); | |
84 | } | |
85 | { | |
86 | tracking_bounded_array_ref<T> view(array); | |
87 | tracking_policy::reset(); | |
88 | tracking_bounded_array_ref<T> slice = view.slice(1, 5); | |
89 | CHECK(tracking_policy::did_trap); | |
90 | } | |
91 | { | |
92 | tracking_bounded_array_ref<T> view(array); | |
93 | tracking_policy::reset(); | |
94 | tracking_bounded_array_ref<T> slice = view.slice(1, 10); | |
95 | CHECK(tracking_policy::did_trap); | |
96 | } | |
97 | ||
98 | // Slices starting at 3 (in the middle) | |
99 | { | |
100 | test_bounded_array_ref<T> view(array); | |
101 | test_bounded_array_ref<T> slice = view.slice(3, 0); | |
102 | CHECK(slice.size() == 0); | |
103 | } | |
104 | { | |
105 | test_bounded_array_ref<T> view(array); | |
106 | test_bounded_array_ref<T> slice = view.slice(3, 2); | |
107 | CHECK(slice.size() == 2); | |
108 | CHECK(&slice[0] == &array[3]); | |
109 | CHECK(&slice[1] == &array[4]); | |
110 | } | |
111 | { | |
112 | tracking_bounded_array_ref<T> view(array); | |
113 | tracking_policy::reset(); | |
114 | tracking_bounded_array_ref<T> slice = view.slice(3, 3); | |
115 | CHECK(tracking_policy::did_trap); | |
116 | } | |
117 | { | |
118 | tracking_bounded_array_ref<T> view(array); | |
119 | tracking_policy::reset(); | |
120 | tracking_bounded_array_ref<T> slice = view.slice(3, 100); | |
121 | CHECK(tracking_policy::did_trap); | |
122 | } | |
123 | ||
124 | // Slices starting at 4 (near the end) | |
125 | { | |
126 | test_bounded_array_ref<T> view(array); | |
127 | test_bounded_array_ref<T> slice = view.slice(4, 0); | |
128 | CHECK(slice.size() == 0); | |
129 | } | |
130 | { | |
131 | test_bounded_array_ref<T> view(array); | |
132 | test_bounded_array_ref<T> slice = view.slice(4, 1); | |
133 | CHECK(slice.size() == 1); | |
134 | CHECK(&slice[0] == &array[4]); | |
135 | } | |
136 | { | |
137 | tracking_bounded_array_ref<T> view(array); | |
138 | tracking_policy::reset(); | |
139 | tracking_bounded_array_ref<T> slice = view.slice(4, 2); | |
140 | CHECK(tracking_policy::did_trap); | |
141 | } | |
142 | ||
143 | // Slices starting at the end | |
144 | { | |
145 | test_bounded_array_ref<T> view(array); | |
146 | test_bounded_array_ref<T> slice = view.slice(5, 0); | |
147 | CHECK(slice.size() == 0); | |
148 | } | |
149 | { | |
150 | tracking_bounded_array_ref<T> view(array); | |
151 | tracking_policy::reset(); | |
152 | tracking_bounded_array_ref<T> slice = view.slice(5, 1); | |
153 | CHECK(tracking_policy::did_trap); | |
154 | } | |
155 | { | |
156 | tracking_bounded_array_ref<T> view(array); | |
157 | tracking_policy::reset(); | |
158 | tracking_bounded_array_ref<T> slice = view.slice(5, 10); | |
159 | CHECK(tracking_policy::did_trap); | |
160 | } | |
161 | ||
162 | // Slices starting after the end | |
163 | { | |
164 | tracking_bounded_array_ref<T> view(array); | |
165 | tracking_policy::reset(); | |
166 | tracking_bounded_array_ref<T> slice = view.slice(6, 0); | |
167 | CHECK(tracking_policy::did_trap); | |
168 | } | |
169 | { | |
170 | tracking_bounded_array_ref<T> view(array); | |
171 | tracking_policy::reset(); | |
172 | tracking_bounded_array_ref<T> slice = view.slice(6, 1); | |
173 | CHECK(tracking_policy::did_trap); | |
174 | } | |
175 | { | |
176 | tracking_bounded_array_ref<T> view(array); | |
177 | tracking_policy::reset(); | |
178 | tracking_bounded_array_ref<T> slice = view.slice(8, 10); | |
179 | CHECK(tracking_policy::did_trap); | |
180 | } | |
181 | ||
182 | // Slices overflowing a uint32_t | |
183 | { | |
184 | std::uint32_t n = std::numeric_limits<std::uint32_t>::max() / 2 + 1; | |
185 | std::uint32_t m = std::numeric_limits<std::uint32_t>::max() / 2 + 1; | |
186 | tracking_bounded_array_ref<T> view(array); | |
187 | tracking_policy::reset(); | |
188 | tracking_bounded_array_ref<T> slice = view.slice(n, m); | |
189 | CHECK(tracking_policy::did_trap); | |
190 | CHECK(tracking_policy::message == "bounded_array_ref: n + m is larger than the size of any bounded_array_ref"); | |
191 | } | |
192 | ||
193 | // Check the documented range equivalent | |
194 | { | |
195 | test_bounded_array_ref<T> view(array); | |
196 | test_bounded_array_ref<T> slice = view.slice(3, 2); | |
197 | CHECK(slice.begin() == view.begin() + 3); | |
198 | CHECK(slice.end() == view.begin() + 3 + 2); | |
199 | } | |
200 | ||
201 | // Chaining calls to slice() | |
202 | { | |
203 | test_bounded_array_ref<T> view(array); | |
204 | test_bounded_array_ref<T> slice = view.slice(1, 4).slice(2, 2); | |
205 | CHECK(slice.size() == 2); | |
206 | CHECK(&slice[0] == &array[3]); | |
207 | CHECK(&slice[1] == &array[4]); | |
208 | } | |
209 | ||
210 | // Slicing an empty view | |
211 | { | |
212 | test_bounded_array_ref<T> view; | |
213 | test_bounded_array_ref<T> slice = view.slice(0, 0); | |
214 | CHECK(slice.size() == 0); | |
215 | } | |
216 | { | |
217 | tracking_bounded_array_ref<T> view; | |
218 | tracking_policy::reset(); | |
219 | tracking_bounded_array_ref<T> slice = view.slice(0, 1); | |
220 | CHECK(tracking_policy::did_trap); | |
221 | } | |
222 | } | |
223 | ||
224 | T_DECL(slice, "bounded_array_ref.slice") { | |
225 | tests<T>(); | |
226 | tests<T const>(); | |
227 | } |