| 281 | |
| 282 | template <int elements_per_inner_array, int inline_elements> |
| 283 | static void TestArrayOfArrays(int n) { |
| 284 | SCOPED_TRACE(n); |
| 285 | SCOPED_TRACE(inline_elements); |
| 286 | SCOPED_TRACE(elements_per_inner_array); |
| 287 | ConstructionTester::constructions = 0; |
| 288 | ConstructionTester::destructions = 0; |
| 289 | { |
| 290 | using InnerArray = ConstructionTester[elements_per_inner_array]; |
| 291 | // Heap-allocate the FixedArray to avoid blowing the stack frame. |
| 292 | auto array_ptr = std::unique_ptr< |
| 293 | ceres::internal::FixedArray<InnerArray, inline_elements>>( |
| 294 | new ceres::internal::FixedArray<InnerArray, inline_elements>(n)); |
| 295 | auto& array = *array_ptr; |
| 296 | |
| 297 | ASSERT_EQ(array.size(), n); |
| 298 | ASSERT_EQ(array.memsize(), |
| 299 | sizeof(ConstructionTester) * elements_per_inner_array * n); |
| 300 | ASSERT_EQ(array.begin() + n, array.end()); |
| 301 | |
| 302 | // Check that all elements were constructed |
| 303 | for (int i = 0; i < n; i++) { |
| 304 | for (int j = 0; j < elements_per_inner_array; j++) { |
| 305 | (array[i])[j].CheckConstructed(); |
| 306 | } |
| 307 | } |
| 308 | // Check that no other elements were constructed |
| 309 | ASSERT_EQ(ConstructionTester::constructions, n * elements_per_inner_array); |
| 310 | |
| 311 | // Test operator[] |
| 312 | for (int i = 0; i < n; i++) { |
| 313 | for (int j = 0; j < elements_per_inner_array; j++) { |
| 314 | (array[i])[j].set(i * elements_per_inner_array + j); |
| 315 | } |
| 316 | } |
| 317 | for (int i = 0; i < n; i++) { |
| 318 | for (int j = 0; j < elements_per_inner_array; j++) { |
| 319 | ASSERT_EQ((array[i])[j].get(), i * elements_per_inner_array + j); |
| 320 | ASSERT_EQ((array.data()[i])[j].get(), i * elements_per_inner_array + j); |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | // Test data() |
| 325 | for (int i = 0; i < n; i++) { |
| 326 | for (int j = 0; j < elements_per_inner_array; j++) { |
| 327 | (array.data()[i])[j].set((i + 1) * elements_per_inner_array + j); |
| 328 | } |
| 329 | } |
| 330 | for (int i = 0; i < n; i++) { |
| 331 | for (int j = 0; j < elements_per_inner_array; j++) { |
| 332 | ASSERT_EQ((array[i])[j].get(), (i + 1) * elements_per_inner_array + j); |
| 333 | ASSERT_EQ((array.data()[i])[j].get(), |
| 334 | (i + 1) * elements_per_inner_array + j); |
| 335 | } |
| 336 | } |
| 337 | } // Close scope containing 'array'. |
| 338 | |
| 339 | // Check that all constructed elements were destructed. |
| 340 | EXPECT_EQ(ConstructionTester::constructions, |