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 } 228