Arcane  4.2.2.0
Developer documentation
Loading...
Searching...
No Matches
TestArray.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7#include <gtest/gtest.h>
8
9#include "arccore/collections/Array.h"
10#include "arccore/collections/IMemoryAllocator.h"
11
12#include "arccore/base/FatalErrorException.h"
13#include "arccore/base/Iterator.h"
14
15#include "TestArrayCommon.h"
16
17#include <iostream>
18
19using namespace Arccore;
20using namespace TestArccore;
21
22namespace
23{
24void _testArraySwap(bool use_own_swap)
25{
26 std::cout << "** TestArraySwap is_own=" << use_own_swap << "\n";
27
28 String c1_name = "TestC1";
30 c1.setDebugName(c1_name);
31 IntSubClass* x1 = c1.data();
32 std::cout << "** C1_this = " << &c1 << "\n";
33 std::cout << "** C1_BASE = " << x1 << "\n";
35 IntSubClass* x2 = c2.data();
36 std::cout << "** C2_this = " << &c2 << "\n";
37 std::cout << "** C2_BASE = " << x2 << "\n";
38
39 ASSERT_EQ(c1.debugName(), c1_name);
40 ASSERT_EQ(c2.debugName(), String{});
41
42 if (use_own_swap) {
43 swap(c1, c2);
44 }
45 else
46 std::swap(c1, c2);
47
48 ASSERT_EQ(c2.debugName(), c1_name);
49 ASSERT_EQ(c1.debugName(), String{});
50
51 IntSubClass* after_x1 = c1.data();
52 IntSubClass* after_x2 = c2.data();
53 std::cout << "** C1_BASE_AFTER = " << after_x1 << " size=" << c1.size() << "\n";
54 std::cout << "** C2_BASE_AFTER = " << after_x2 << " size=" << c2.size() << "\n";
55
56 ASSERT_TRUE(x1 == after_x2) << "Bad value after swap [1]";
57 ASSERT_TRUE(x2 == after_x1) << "Bad value after swap [2]";
58}
59} // namespace
60
61TEST(Array, Swap1)
62{
63 _testArraySwap(true);
64}
65
66TEST(Array, Swap2)
67{
68 _testArraySwap(false);
69}
70
71/*---------------------------------------------------------------------------*/
72/*---------------------------------------------------------------------------*/
73
74namespace
75{
76template <typename ArrayType>
77void _testArrayAssign()
78{
79 using namespace Arccore;
80 using value_type = ArrayType::value_type;
81 // Test assign(count, val)
82 {
83 ArrayType a;
84 a.assign(5l, value_type(42));
85 ASSERT_EQ(a.size(), 5);
86 for (Int32 i = 0; i < 5; ++i)
87 ASSERT_EQ(a[i], 42);
88
89 // Test assign with count = 0
90 a.assign(0l, value_type(99));
91 ASSERT_EQ(a.size(), 0);
92
93 // Test assign overwriting existing data
94 a.assign(3l, value_type(1));
95 a.assign(2l, value_type(7));
96 ASSERT_EQ(a.size(), 2);
97 ASSERT_EQ(a[0], 7);
98 ASSERT_EQ(a[1], 7);
99 }
100
101 // Test assign(InputIterator first, InputIterator last)
102 {
103 ArrayType a;
104 std::vector<Int32> src = { 1, 2, 3, 4, 5 };
105 a.assign(src.begin(), src.end());
106 ASSERT_EQ(a.size(), 5);
107 for (Int32 i = 0; i < 5; ++i)
108 ASSERT_EQ(a[i], i + 1);
109
110 // Test with empty range
111 ArrayType a2;
112 std::vector<Int32> empty;
113 a2.assign(empty.begin(), empty.end());
114 ASSERT_EQ(a2.size(), 0);
115
116 // Test with array iterators
117 ArrayType a3;
118 ArrayType src_array = { 10, 20, 30 };
119 a3.assign(src_array.begin(), src_array.end());
120 ASSERT_EQ(a3.size(), 3);
121 ASSERT_EQ(a3[0], 10);
122 ASSERT_EQ(a3[1], 20);
123 ASSERT_EQ(a3[2], 30);
124
125 // Test with initializer_list (via vector)
126 ArrayType a4;
127 std::vector<Int32> il_src = { 100, 200 };
128 a4.assign(il_src.begin(), il_src.end());
129 ASSERT_EQ(a4.size(), 2);
130 ASSERT_EQ(a4[0], 100);
131 ASSERT_EQ(a4[1], 200);
132 }
133}
134
135template <typename ArrayType>
136void _testArrayErase()
137{
138 using namespace Arccore;
139 using value_type = ArrayType::value_type;
140
141 // Test erase(const_iterator pos) - single element
142 {
143 ArrayType a = { 1, 2, 3, 4, 5 };
144
145 // Erase first element
146 auto it = a.erase(a.begin());
147 ASSERT_EQ(a.size(), 4);
148 ASSERT_EQ(a[0], 2);
149 ASSERT_EQ(a[1], 3);
150 ASSERT_EQ(a[2], 4);
151 ASSERT_EQ(a[3], 5);
152 ASSERT_EQ(*it, 2); // Returned iterator points to next element
153
154 // Erase middle element
155 a = { 1, 2, 3, 4, 5 };
156 it = a.erase(a.begin() + 2); // Erase '3'
157 ASSERT_EQ(a.size(), 4);
158 ASSERT_EQ(a[0], 1);
159 ASSERT_EQ(a[1], 2);
160 ASSERT_EQ(a[2], 4);
161 ASSERT_EQ(a[3], 5);
162 ASSERT_EQ(*it, 4);
163
164 // Erase last element
165 a = { 1, 2, 3, 4, 5 };
166 it = a.erase(a.end() - 1); // Erase '5'
167 ASSERT_EQ(a.size(), 4);
168 ASSERT_EQ(a[0], 1);
169 ASSERT_EQ(a[1], 2);
170 ASSERT_EQ(a[2], 3);
171 ASSERT_EQ(a[3], 4);
172 ASSERT_EQ(it, a.end()); // Returned iterator is end()
173 }
174
175 // Test erase(const_iterator first, const_iterator last) - range
176 {
177 // Erase from beginning
178 ArrayType a = { 1, 2, 3, 4, 5 };
179 auto it = a.erase(a.begin(), a.begin() + 2); // Erase [1, 2]
180 ASSERT_EQ(a.size(), 3);
181 ASSERT_EQ(a[0], 3);
182 ASSERT_EQ(a[1], 4);
183 ASSERT_EQ(a[2], 5);
184 ASSERT_EQ(*it, 3);
185
186 // Erase from middle
187 a = { 1, 2, 3, 4, 5 };
188 it = a.erase(a.begin() + 1, a.begin() + 3); // Erase [2, 3]
189 ASSERT_EQ(a.size(), 3);
190 ASSERT_EQ(a[0], 1);
191 ASSERT_EQ(a[1], 4);
192 ASSERT_EQ(a[2], 5);
193 ASSERT_EQ(*it, 4);
194
195 // Erase to end
196 a = { 1, 2, 3, 4, 5 };
197 it = a.erase(a.begin() + 2, a.end()); // Erase [3, 4, 5]
198 ASSERT_EQ(a.size(), 2);
199 ASSERT_EQ(a[0], 1);
200 ASSERT_EQ(a[1], 2);
201 ASSERT_EQ(it, a.end());
202
203 // Erase full range
204 a = { 1, 2, 3, 4, 5 };
205 it = a.erase(a.begin(), a.end());
206 ASSERT_EQ(a.size(), 0);
207 ASSERT_EQ(it, a.end());
208
209 // Erase empty range (first == last)
210 a = { 1, 2, 3, 4, 5 };
211 it = a.erase(a.begin() + 2, a.begin() + 2);
212 ASSERT_EQ(a.size(), 5);
213 ASSERT_EQ(*it, 3); // Points to element at position 2
214 }
215
216 // Test with const_iterator (const array)
217 {
218 const UniqueArray<value_type> ca = { 1, 2, 3, 4, 5 };
219 ArrayType a = ca;
220
221 // erase with const_iterator position
222 auto it = a.erase(a.cbegin() + 1); // Erase '2'
223 ASSERT_EQ(a.size(), 4);
224 ASSERT_EQ(a[0], 1);
225 ASSERT_EQ(a[1], 3);
226 ASSERT_EQ(*it, 3);
227
228 // erase with const_iterator range
229 a = ca;
230 it = a.erase(a.cbegin() + 1, a.cbegin() + 3); // Erase [2, 3]
231 ASSERT_EQ(a.size(), 3);
232 ASSERT_EQ(a[0], 1);
233 ASSERT_EQ(a[1], 4);
234 ASSERT_EQ(*it, 4);
235 }
236}
237
238template <typename ArrayType>
239void _testArrayPopBack()
240{
241 using namespace Arccore;
242
243 ArrayType a = {1, 2, 3, 4, 5};
244 a.pop_back();
245 ASSERT_EQ(a.size(), 4);
246 ASSERT_EQ(a[3], 4);
247
248 a.pop_back();
249 ASSERT_EQ(a.size(), 3);
250 ASSERT_EQ(a[2], 3);
251
252 // Pop until empty
253 while (!a.empty())
254 a.pop_back();
255 ASSERT_EQ(a.size(), 0);
256}
257
258template <typename ArrayType>
259void _testArrayEmplaceBack()
260{
261 using namespace Arccore;
262 using value_type = ArrayType::value_type;
263 // Test with simple type
264 if constexpr(std::is_same_v<Int32,value_type>){
265 ArrayType a;
266 a.emplace_back(42);
267 ASSERT_EQ(a.size(), 1);
268 ASSERT_EQ(a[0], 42);
269
270 a.emplace_back(100);
271 ASSERT_EQ(a.size(), 2);
272 ASSERT_EQ(a[1], 100);
273 }
274
275 // Test with non-POD type (IntSubClass)
276 if constexpr(std::is_same_v<IntSubClass,value_type>){
277 ArrayType a;
278 a.emplace_back(IntSubClass(10));
279 ASSERT_EQ(a.size(), 1);
280 ASSERT_EQ(a[0].value(), 10);
281
282 a.emplace_back(IntSubClass(20));
283 ASSERT_EQ(a.size(), 2);
284 ASSERT_EQ(a[1].value(), 20);
285 }
286}
287
288template <typename ArrayType>
289void _testArrayEdgeCases()
290{
291 using namespace Arccore;
292 using value_type = ArrayType::value_type;
293
294 // Test on empty array
295 {
296 ArrayType a;
297 ASSERT_EQ(a.size(), 0);
298 // assign on empty
299 a.assign(3l, value_type(7));
300 ASSERT_EQ(a.size(), 3);
301 // pop_back on empty should not crash (but is undefined behavior in STL)
302 // We don't test pop_back on empty as it's undefined
303 }
304
305 // Test on single element array
306 {
307 ArrayType a = { 42 };
308 ASSERT_EQ(a.size(), 1);
309
310 // erase single element
311 auto it = a.erase(a.begin());
312 ASSERT_EQ(a.size(), 0);
313 ASSERT_EQ(it, a.end());
314
315 // assign on single element
316 a.assign(1l, value_type(99));
317 ASSERT_EQ(a.size(), 1);
318 ASSERT_EQ(a[0], 99);
319
320 // pop_back on single element
321 a.pop_back();
322 ASSERT_EQ(a.size(), 0);
323
324 // emplace_back on single element
325 a.emplace_back(123);
326 ASSERT_EQ(a.size(), 1);
327 ASSERT_EQ(a[0], 123);
328 }
329
330 // Test assign with self-assignment-like scenario
331 {
332 ArrayType a = { 1, 2, 3 };
333 auto begin = a.begin();
334 auto end = a.end();
335 a.assign(begin, end); // Should work but be a no-op effectively
336 ASSERT_EQ(a.size(), 3);
337 ASSERT_EQ(a[0], 1);
338 ASSERT_EQ(a[1], 2);
339 ASSERT_EQ(a[2], 3);
340 }
341}
342
343} // namespace
344
345TEST(Array, Assign)
346{
347 _testArrayAssign<UniqueArray<Int32>>();
348 _testArrayAssign<SharedArray<Int32>>();
349 _testArrayAssign<UniqueArray<IntSubClass>>();
350 _testArrayAssign<SharedArray<IntSubClass>>();
351}
352
353TEST(Array, Erase)
354{
355 _testArrayErase<UniqueArray<Int32>>();
356 _testArrayErase<SharedArray<Int32>>();
357 _testArrayErase<UniqueArray<IntSubClass>>();
358 _testArrayErase<SharedArray<IntSubClass>>();
359}
360
361TEST(Array, PopBack)
362{
363 _testArrayPopBack<UniqueArray<Int32>>();
364 _testArrayPopBack<SharedArray<Int32>>();
365 _testArrayPopBack<UniqueArray<IntSubClass>>();
366 _testArrayPopBack<SharedArray<IntSubClass>>();
367}
368
369TEST(Array, EmplaceBack)
370{
371 _testArrayEmplaceBack<UniqueArray<Int32>>();
372 _testArrayEmplaceBack<SharedArray<Int32>>();
373 _testArrayEmplaceBack<UniqueArray<IntSubClass>>();
374 _testArrayEmplaceBack<SharedArray<IntSubClass>>();
375}
376
377TEST(Array, EdgeCases)
378{
379 _testArrayEdgeCases<UniqueArray<Int32>>();
380 _testArrayEdgeCases<SharedArray<Int32>>();
381 _testArrayEdgeCases<UniqueArray<IntSubClass>>();
382 _testArrayEdgeCases<SharedArray<IntSubClass>>();
383}
384
385/*---------------------------------------------------------------------------*/
386/*---------------------------------------------------------------------------*/
387
388Integer IntPtrSubClass::count = 0;
389
390/*---------------------------------------------------------------------------*/
391/*---------------------------------------------------------------------------*/
392
393template <typename Container, typename SubClass>
395{
396 public:
397
398 void test()
399 {
400 {
401 Container c;
402 c.add(SubClass(1));
403 c.add(SubClass(2));
404 c.add(SubClass(3));
405 ARCCORE_UT_CHECK((c.size() == 3), "Bad size (3)");
406 ARCCORE_UT_CHECK((c[0] == 1), "Bad value [0]");
407 ARCCORE_UT_CHECK((c[1] == 2), "Bad value [1]");
408 ARCCORE_UT_CHECK((c[2] == 3), "Bad value [2]");
409 c.resize(0);
410 ARCCORE_UT_CHECK((c.size() == 0), "Bad size (0)");
411 c.resize(5);
412 ARCCORE_UT_CHECK((c.size() == 5), "Bad size");
413 c.add(SubClass(6));
414 ARCCORE_UT_CHECK((c.size() == 6), "Bad size");
415 ARCCORE_UT_CHECK((c[5] == 6), "Bad value [5]");
416 c.shrink();
417 ASSERT_EQ(c.size(), c.capacity()) << "Bad capacity (test 1)";
418 c.resize(12);
419 c.shrink();
420 ASSERT_EQ(c.size(), c.capacity()) << "Bad capacity (test 2)";
421 }
422 {
423 Container c;
424 c.shrink();
425 ASSERT_EQ(c.capacity(), 0) << "Bad capacity (test 3)";
426 }
427 {
428 Container c;
429 Integer nb = 20;
430 for (Integer i = 0; i < nb; ++i)
431 c.add(SubClass(i));
432 c.reserve(nb * 2);
433 Int64 current_capacity = c.capacity();
434 ASSERT_EQ(current_capacity, (nb * 2)) << "Bad capacity (test 4)";
435 c.shrink(c.capacity() + 5);
436 ASSERT_EQ(c.capacity(), current_capacity) << "Bad capacity (test 5)";
437 c.shrink(32);
438 ASSERT_EQ(c.capacity(), 32) << "Bad capacity (test 6)";
439 c.shrink();
440 ASSERT_EQ(c.capacity(), c.size()) << "Bad capacity (test 7)";
441 }
442 {
444 Integer nb = 1000000;
445 uc.resize(1000);
446 for (Container& c : uc) {
447 c.reserve(nb);
448 c.shrink_to_fit();
449 }
450 }
451 {
452 Container c;
453 for (Integer i = 0; i < 50; ++i)
454 c.add(SubClass(i + 2));
455 {
456 Container c2 = c;
457 for (Integer i = 50; i < 100; ++i) {
458 c2.add(SubClass(i + 2));
459 }
460 Container c4 = c2;
461 Container c3;
462 c3.add(5);
463 c3.add(6);
464 c3.add(7);
465 c3 = c2;
466 for (Integer i = 100; i < 150; ++i) {
467 c4.add(SubClass(i + 2));
468 }
469 }
470 ARCCORE_UT_CHECK((c.size() == 150), "Bad size (150)");
471 c.reserve(300);
472 ARCCORE_UT_CHECK((c.capacity() == 300), "Bad capacity (300)");
473 for (Integer i = 0; i < 50; ++i) {
474 c.remove(i);
475 }
476 ARCCORE_UT_CHECK((c.size() == 100), "Bad size (100)");
477 for (Integer i = 0; i < 50; ++i) {
478 //cout << "** VAL: " << i << " c=" << c[i] << " expected=" << ((i*2)+3) << '\n';
479 ARCCORE_UT_CHECK((c[i] == ((i * 2) + 3)), "Bad value");
480 }
481 for (Integer i = 50; i < 100; ++i) {
482 //cout << "** VAL: " << i << " c=" << c[i] << " expected=" << (i+52) << '\n';
483 ARCCORE_UT_CHECK((c[i] == (i + 52)), "Bad value");
484 }
485 }
486 }
487};
488
489namespace
490{
491void _testArrayNewInternal()
492{
493 using namespace Arccore;
494 std::cout << "** TEST VECTOR NEW\n";
495
496 std::cout << "** wanted_size = " << AlignedMemoryAllocator3::simdAlignment() << "\n";
497 //if (impl_size!=wanted_size)
498 //ARCCORE_FATAL("Bad sizeof(ArrayImplBase) v={0} expected={1}",impl_size,wanted_size);
499 {
501 rvt.test();
502 }
503 std::cout << "** TEST VECTOR NEW 2\n";
504 {
506 rvt.test();
507 std::cout << "** COUNT = " << IntPtrSubClass::count << "\n";
508 }
509 std::cout << "** TEST VECTOR NEW 3\n";
510 {
512 rvt.test();
513 std::cout << "** COUNT = " << IntPtrSubClass::count << "\n";
514 }
515 {
517 c.add(5);
518 c.add(7);
520 c2.add(3);
521 ARCCORE_UT_CHECK((c2.size() == 3), "Bad value [3]");
522 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
523 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
524 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
525 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
526 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
527 ARCCORE_UT_CHECK((c2[2] == 3), "Bad value [7]");
528 }
529 {
531 c.add(5);
532 c.add(7);
534 c2.add(3);
535 ARCCORE_UT_CHECK((c2.size() == 3), "Bad value [3]");
536 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
537 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
538 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
539 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
540 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
541 ARCCORE_UT_CHECK((c2[2] == 3), "Bad value [7]");
542 }
543 {
544 UniqueArray<IntSubClass> c{ 5, 7 };
546 c2.add(3);
547 ARCCORE_UT_CHECK((c2.size() == 3), "Bad value [3]");
548 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
549 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
550 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
551 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
552 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
553 ARCCORE_UT_CHECK((c2[2] == 3), "Bad value [7]");
554 }
555 {
556 UniqueArray<IntSubClass> c{ 5, 7 };
557 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
558 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
559 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
560 }
561 {
562 SharedArray<IntSubClass> c{ 5, 7 };
563 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
564 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
565 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
566 }
567 {
568 PrintableMemoryAllocator allocator;
569 UniqueArray<IntSubClass> c(&allocator);
570 UniqueArray<IntSubClass> cx(&allocator, 5);
571 ARCCORE_UT_CHECK((cx.size() == 5), "Bad value [5]");
572 c.add(5);
573 c.add(7);
575 c2.add(3);
576 ARCCORE_UT_CHECK((c2.size() == 3), "Bad value [3]");
577 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
578 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
579 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
580 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
581 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
582 ARCCORE_UT_CHECK((c2[2] == 3), "Bad value [7]");
583 for (Integer i = 0; i < 50; ++i)
584 c.add(i + 3);
585 c.resize(24);
586 c.reserve(70);
587 }
588 {
590 c2.add(3);
591 c2.add(5);
593 ASSERT_EQ(c22.size(), 33);
594 c22 = c2;
595 {
597 c.add(5);
598 c.add(7);
599 c2 = c;
602 c2.resize(125);
603 ASSERT_EQ(c2.size(), c3.size());
604 ASSERT_EQ(c2.size(), c4.size());
605 c3.resize(459);
606 ASSERT_EQ(c2.size(), c3.size());
607 ASSERT_EQ(c2.size(), c4.size());
608 c4.resize(932);
609 c.resize(32);
610 }
611 c2.add(3);
612 ARCCORE_UT_CHECK((c2.size() == 33), "Bad value [3]");
613 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
614 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
615 ARCCORE_UT_CHECK((c2[32] == 3), "Bad value [7]");
616 c2.resize(1293);
617 ASSERT_EQ(c2.size(), 1293);
618 ASSERT_EQ(c22.size(), 2);
619
620 {
621 SharedArray<IntSubClass> values1 = { -7, 3, 4 };
622 ASSERT_EQ(values1.size(), 3);
623 ASSERT_EQ(values1[0], -7);
624 ASSERT_EQ(values1[1], 3);
625 ASSERT_EQ(values1[2], 4);
626 values1 = { 2, -1, 9, 13 };
627 ASSERT_EQ(values1.size(), 4);
628 ASSERT_EQ(values1[0], 2);
629 ASSERT_EQ(values1[1], -1);
630 ASSERT_EQ(values1[2], 9);
631 ASSERT_EQ(values1[3], 13);
632 SharedArray<IntSubClass> values2 = values1;
633 ASSERT_EQ(values2, values1);
634
635 values1 = {};
636 ASSERT_EQ(values1.size(), 0);
637 ASSERT_EQ(values2.size(), 0);
638 }
639 }
640 {
641 UniqueArray<Int32> values1 = { 2, 5 };
642 UniqueArray<Int32> values2 = { 4, 9, 7 };
643 // Copy the values of values2 to the end of values1.
644 std::copy(std::begin(values2), std::end(values2), std::back_inserter(values1));
645 std::cout << "** VALUES1 = " << values1 << "\n";
646 ARCCORE_UT_CHECK((values1.size() == 5), "BI: Bad size");
647 ARCCORE_UT_CHECK((values1[0] == 2), "BI: Bad value [0]");
648 ARCCORE_UT_CHECK((values1[1] == 5), "BI: Bad value [1]");
649 ARCCORE_UT_CHECK((values1[2] == 4), "BI: Bad value [2]");
650 ARCCORE_UT_CHECK((values1[3] == 9), "BI: Bad value [3]");
651 ARCCORE_UT_CHECK((values1[4] == 7), "BI: Bad value [4]");
652
654 vx.add(IntPtrSubClass(5));
655 UniqueArray<IntPtrSubClass>::iterator i = std::begin(vx);
657 std::cout << "V=" << i->m_v << " " << ci->m_v << '\n';
658
659 values1 = { -7, 3 };
660 ASSERT_EQ(values1.size(), 2);
661 ASSERT_EQ(values1[0], -7);
662 ASSERT_EQ(values1[1], 3);
663
664 values1 = {};
665 ASSERT_EQ(values1.size(), 0);
666 }
667 {
668 UniqueArray<Int32> values1;
669 UniqueArray<Int32> values2 = { 4, 9, 7, 6, 3 };
670 // Copy the values of values2 to the end of values1.
671 values1.copy(values2);
672 std::cout << "** VALUES1 = " << values1 << "\n";
673 ARCCORE_UT_CHECK((values1.size() == 5), "BI: Bad size");
674 ARCCORE_UT_CHECK((values1[0] == 4), "BI2: Bad value [0]");
675 ARCCORE_UT_CHECK((values1[1] == 9), "BI2: Bad value [1]");
676 ARCCORE_UT_CHECK((values1[2] == 7), "BI2: Bad value [2]");
677 ARCCORE_UT_CHECK((values1[3] == 6), "BI2: Bad value [3]");
678 ARCCORE_UT_CHECK((values1[4] == 3), "BI2: Bad value [4]");
679
681 vx.add(IntPtrSubClass(5));
682 UniqueArray<IntPtrSubClass>::iterator i = std::begin(vx);
684 std::cout << "V=" << i->m_v << " " << ci->m_v << '\n';
685 }
686 {
688 vx.add(IntPtrSubClass(5));
691 std::cout << "V=" << i->m_v << " " << ci->m_v << '\n';
694 std::cout << "V=" << cicvx->m_v << '\n';
695 }
696 {
698 vx.add(IntPtrSubClass(5));
699 UniqueArray<IntPtrSubClass>::iterator i = std::begin(vx);
700 UniqueArray<IntPtrSubClass>::iterator iend = std::end(vx);
702 std::cout << "V=" << i->m_v << " " << ci->m_v << " " << (iend - i) << '\n';
704 UniqueArray<IntPtrSubClass>::const_iterator cicvx = std::begin(cvx);
705 std::cout << "V=" << cicvx->m_v << '\n';
706 std::copy(std::begin(vx), std::end(vx), std::begin(vx));
707 }
708 {
709 UniqueArray<Int32> values = { 4, 9, 7 };
710 for (typename ArrayView<Int32>::const_iter i(values.view()); i(); ++i) {
711 std::cout << *i << '\n';
712 }
713 for (typename ConstArrayView<Int32>::const_iter i(values.view()); i(); ++i) {
714 std::cout << *i << '\n';
715 }
716 for (auto i : values.range()) {
717 std::cout << i << '\n';
718 }
719 for (auto i : values.constView().range()) {
720 std::cout << i << '\n';
721 }
722
723 {
724 auto r1 = std::make_reverse_iterator(values.end());
725 auto r2 = std::make_reverse_iterator(values.begin());
726 for (; r1 != r2; ++r1) {
727 std::cout << "RVALUE = " << *r1 << '\n';
728 }
729 }
730 {
731 auto r1 = values.rbegin();
732 ASSERT_EQ((*r1), 7);
733 ++r1;
734 ASSERT_EQ((*r1), 9);
735 ++r1;
736 ASSERT_EQ((*r1), 4);
737 ++r1;
738 ASSERT_TRUE((r1 == values.rend()));
739 }
740 {
743 c2.add(IntSubClassNoPod{ 3 });
744 ARCCORE_UT_CHECK((c2.size() == 3), "Bad value [3]");
745 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
746 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
747 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
748 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
749 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
750 ARCCORE_UT_CHECK((c2[2] == 3), "Bad value [7]");
751 c = c2.span();
752 SmallSpan<const IntSubClassNoPod> c2_small_span = c2;
753 ASSERT_EQ(c.constSpan(), c2.constSpan());
754 ASSERT_EQ(c.constSmallSpan(), c2_small_span);
755 ASSERT_EQ(c.smallSpan(), c2.smallSpan());
756 }
757 }
758}
759} // namespace
760
761/*---------------------------------------------------------------------------*/
762/*---------------------------------------------------------------------------*/
763
764TEST(Array, Misc)
765{
766 try {
767 _testArrayNewInternal();
768 }
769 catch (const Exception& ex) {
770 std::cerr << "Exception ex=" << ex << "\n";
771 throw;
772 }
773}
774
775/*---------------------------------------------------------------------------*/
776/*---------------------------------------------------------------------------*/
777
778namespace
779{
780void _Add(Array<Real>& v, Integer new_size)
781{
782 v.resize(new_size);
783}
784} // namespace
785
786/*---------------------------------------------------------------------------*/
787/*---------------------------------------------------------------------------*/
788
789TEST(Array, Misc2)
790{
791 using namespace Arccore;
792 {
794 v.resize(3);
795 v[0] = 1.2;
796 v.at(1) = -1.3;
797 v[2] = 7.6;
798 ASSERT_EQ(v[0], 1.2);
799 ASSERT_EQ(v[1], -1.3);
800 ASSERT_EQ(v.at(2), 7.6);
801
802 v.add(4.3);
803 for (Real x : v) {
804 std::cout << " Value: " << x << '\n';
805 }
806 v.printInfos(std::cout);
807 }
808 {
810 v.add(4.3);
811 v.add(5.3);
812 v.add(4.6);
813 v.printInfos(std::cout);
814 v.add(14.3);
815 v.add(25.3);
816 v.add(34.6);
817 v.printInfos(std::cout);
818 v.resize(4);
819 v.printInfos(std::cout);
820 v.add(12.2);
821 v.add(2.4);
822 v.add(3.4);
823 v.add(3.6);
824 v.printInfos(std::cout);
825 for (Integer i = 0, is = v.size(); i < is; ++i) {
826 std::cout << " Value: " << v[i] << '\n';
827 }
828 }
829 {
831 v.reserve(5);
832 for (int i = 0; i < 10; ++i)
833 v.add((Real)i);
834 for (Integer i = 0, is = v.size(); i < is; ++i) {
835 std::cout << " Value: " << v[i] << '\n';
836 }
837 }
838 {
840 v.reserve(175);
841 for (int i = 0; i < 27500; ++i) {
842 Real z = (Real)i;
843 v.add(z * z);
844 }
845 for (int i = 0; i < 5000; ++i) {
846 v.remove(i * 2);
847 }
848 v.reserve(150);
849 for (int i = 0; i < 27500; ++i) {
850 Real z = (Real)i;
851 v.add(z * z);
852 }
853 std::cout << " ValueSize= " << v.size() << " values=" << v << '\n';
854 }
855 for (Integer i = 0; i < 100; ++i) {
857 _Add(v, 500000);
858 _Add(v, 1000000);
859 _Add(v, 0);
860 _Add(v, 100000);
861 _Add(v, 0);
862 _Add(v, 0);
863 _Add(v, 230000);
864 std::cout << " Size: " << v.size() << '\n';
865 ASSERT_EQ(v.size(), 230000);
866 }
867}
868
869/*---------------------------------------------------------------------------*/
870/*---------------------------------------------------------------------------*/
871
872TEST(Array, SubViews)
873{
874 using namespace Arccore;
875
876 {
877 // Test Array::subView() and Array::subConstView()
879 v.resize(23);
880 for (Int32 i = 0, n = v.size(); i < n; ++i)
881 v[i] = (i + 1);
882
883 auto sub_view1 = v.subView(50, 5);
884 ASSERT_EQ(sub_view1.data(), nullptr);
885 ASSERT_EQ(sub_view1.size(), 0);
886
887 auto sub_view2 = v.subView(2, 8);
888 ASSERT_EQ(sub_view2.size(), 8);
889 for (Int32 i = 0, n = sub_view2.size(); i < n; ++i)
890 ASSERT_EQ(sub_view2[i], v[2 + i]);
891
892 auto sub_view3 = v.subView(20, 8);
893 ASSERT_EQ(sub_view3.size(), 3);
894 for (Int32 i = 0, n = sub_view3.size(); i < n; ++i)
895 ASSERT_EQ(sub_view3[i], v[20 + i]);
896
897 auto sub_const_view1 = v.subConstView(50, 5);
898 ASSERT_EQ(sub_const_view1.data(), nullptr);
899 ASSERT_EQ(sub_const_view1.size(), 0);
900
901 auto sub_const_view2 = v.subConstView(2, 8);
902 ASSERT_EQ(sub_const_view2.size(), 8);
903 for (Int32 i = 0, n = sub_const_view2.size(); i < n; ++i)
904 ASSERT_EQ(sub_const_view2[i], v[2 + i]);
905
906 auto sub_const_view3 = v.subConstView(20, 8);
907 ASSERT_EQ(sub_const_view3.size(), 3);
908 for (Int32 i = 0, n = sub_const_view3.size(); i < n; ++i)
909 ASSERT_EQ(sub_const_view3[i], v[20 + i]);
910 }
911}
912
913/*---------------------------------------------------------------------------*/
914/*---------------------------------------------------------------------------*/
915
916class NoCopyData
917{
918 public:
919
920 NoCopyData(const NoCopyData& x) = delete;
921};
922
923template <typename DataType>
925: public Arccore::Array<DataType>
926{
927 public:
928
929 using BaseClass = Arccore::Array<DataType>;
930};
931
932/*---------------------------------------------------------------------------*/
933/*---------------------------------------------------------------------------*/
934
935TEST(Array, Misc3)
936{
937 using namespace Arccore;
938
939 {
941 const Int32 ref_value1 = 12;
942 const Int32 ref_value2 = 7;
943
944 c.resize(9, IntSubClassNoPod(ref_value1));
945 std::cout << "C1=" << c << "\n";
946 for (IntSubClassNoPod x : c)
947 ASSERT_EQ(x, ref_value1);
948
949 c.resize(21, IntSubClassNoPod(ref_value2));
950 ASSERT_EQ(c.size(), 21);
951 std::cout << "C2=" << c << "\n";
952
953 // Resize without initializing. The values for elements
954 // from 9 to 18 must be \a ref_value2
955 c.resizeNoInit(18);
956 std::cout << "C4=" << c << "\n";
957 for (Int32 i = 9, s = c.size(); i < s; ++i)
958 ASSERT_EQ(c[i], ref_value2);
959 for (Int32 i = 9, s = c.size(); i < s; ++i)
960 new (c.data() + i) IntSubClassNoPod(i + 2);
961 for (Int32 i = 9, s = c.size(); i < s; ++i)
962 ASSERT_EQ(c[i], (i + 2));
963 }
964 {
966 c2.resizeNoInit(25);
967 }
968}
969
970/*---------------------------------------------------------------------------*/
971/*---------------------------------------------------------------------------*/
972
973template <typename ArrayType>
975{
976 public:
977
978 static void doTestBase()
979 {
980 using namespace Arccore;
981
983 PrintableMemoryAllocator printable_allocator2;
984 IMemoryAllocator* allocator2 = &printable_allocator2;
985
986 {
987 std::cout << "Array a\n";
988 ArrayType a(allocator1);
989 ASSERT_EQ(a.allocator(), allocator1);
990 a.add(27);
991 a.add(38);
992 a.add(13);
993 a.add(-5);
994
995 std::cout << "Array b\n";
996 ArrayType b(allocator2);
997 ASSERT_EQ(b.capacity(), 0);
998 ASSERT_EQ(b.size(), 0);
999 ASSERT_EQ(b.allocator(), allocator2);
1000
1001 b = a;
1002 ASSERT_EQ(b.size(), a.size());
1003 ASSERT_EQ(b.allocator(), a.allocator());
1004
1005 std::cout << "Array c\n";
1006 ArrayType c(a.clone());
1007 ASSERT_EQ(c.allocator(), a.allocator());
1008 ASSERT_EQ(c.size(), a.size());
1009 ASSERT_EQ(c.constSpan(), a.constSpan());
1010
1011 std::cout << "Array d\n";
1012 ArrayType d(allocator2, a);
1013 ASSERT_EQ(d.allocator(), allocator2);
1014 ASSERT_EQ(d.size(), a.size());
1015 ASSERT_EQ(d.constSpan(), a.constSpan());
1016
1017 std::cout << "Array e\n";
1018 ArrayType e(allocator2, 25);
1019 ASSERT_EQ(e.allocator(), allocator2);
1020 ASSERT_EQ(e.size(), 25);
1021
1022 ArrayType f(allocator2);
1023 f = e;
1024 ASSERT_EQ(f.allocator(), e.allocator());
1025 ASSERT_EQ(f.size(), e.size());
1026
1027 f = f;
1028 ASSERT_EQ(f.allocator(), e.allocator());
1029 ASSERT_EQ(f.size(), e.size());
1030 }
1031 }
1032};
1033
1034TEST(UniqueArray, AllocatorBase)
1035{
1036 AllocatorTest<UniqueArray<Int32>>::doTestBase();
1037}
1038
1039TEST(SharedArray, AllocatorBase)
1040{
1041 AllocatorTest<SharedArray<Int32>>::doTestBase();
1042}
1043
1044/*---------------------------------------------------------------------------*/
1045/*---------------------------------------------------------------------------*/
1046
1048{
1049 using namespace Arccore;
1050 std::cout << "Sizeof(MemoryAllocationOptions)=" << sizeof(MemoryAllocationOptions) << "\n";
1051 std::cout << "Sizeof(ArrayMetaData)=" << sizeof(ArrayMetaData) << "\n";
1052 std::cout << "Sizeof(UniqueArray<Int32>)=" << sizeof(UniqueArray<Int32>) << "\n";
1053 std::cout << "Sizeof(SharedArray<Int32>)=" << sizeof(SharedArray<Int32>) << "\n";
1054
1055 PrintableMemoryAllocator printable_allocator;
1056 PrintableMemoryAllocator printable_allocator2;
1059 {
1060 std::cout << "Array a1\n";
1061 UniqueArray<Int32> a1(allocator2);
1062 ASSERT_EQ(a1.allocator(), allocator2);
1063 ASSERT_EQ(a1.size(), 0);
1064 ASSERT_EQ(a1.capacity(), 0);
1065 ASSERT_EQ(a1.data(), nullptr);
1066
1067 std::cout << "Array a2\n";
1068 UniqueArray<Int32> a2(a1);
1069 ASSERT_EQ(a1.allocator(), a2.allocator());
1070 ASSERT_EQ(a2.capacity(), 0);
1071 ASSERT_EQ(a2.data(), nullptr);
1072 a1.reserve(3);
1073 a1.add(5);
1074 a1.add(7);
1075 a1.add(12);
1076 a1.add(3);
1077 a1.add(1);
1078 ASSERT_EQ(a1.size(), 5);
1079
1080 std::cout << "Array a3\n";
1081 UniqueArray<Int32> a3(allocator1);
1082 a3.add(4);
1083 a3.add(6);
1084 a3.add(2);
1085 ASSERT_EQ(a3.size(), 3);
1086 a3 = a1;
1087 ASSERT_EQ(a3.allocator(), a1.allocator());
1088 ASSERT_EQ(a3.size(), a1.size());
1089 ASSERT_EQ(a3.constSpan(), a1.constSpan());
1090
1091 std::cout << "Array a4\n";
1092 UniqueArray<Int32> a4(allocator1);
1093 a4.add(4);
1094 a4.add(6);
1095 a4.add(2);
1096 ASSERT_EQ(a4.size(), 3);
1097 a4 = a1.span();
1098 ASSERT_EQ(a4.allocator(), allocator1);
1099
1100 a4 = UniqueArray<Int32>(&printable_allocator2);
1101
1102 UniqueArray<Int32> array[2];
1103 IMemoryAllocator* allocator3 = allocator1;
1104 for (Integer i = 0; i < 2; ++i) {
1105 array[i] = UniqueArray<Int32>(allocator3);
1106 }
1107 ASSERT_EQ(array[0].allocator(), allocator3);
1108 ASSERT_EQ(array[1].allocator(), allocator3);
1109 }
1110}
1111
1112/*---------------------------------------------------------------------------*/
1113/*---------------------------------------------------------------------------*/
1114
1116{
1117 using namespace Arccore;
1118 std::cout << "Sizeof(MemoryAllocationOptions)=" << sizeof(MemoryAllocationOptions) << "\n";
1119 std::cout << "Sizeof(ArrayMetaData)=" << sizeof(ArrayMetaData) << "\n";
1120 std::cout << "Sizeof(UniqueArray<Int32>)=" << sizeof(UniqueArray<Int32>) << "\n";
1121 std::cout << "Sizeof(SharedArray<Int32>)=" << sizeof(SharedArray<Int32>) << "\n";
1122
1123 PrintableMemoryAllocator printable_allocator;
1124 PrintableMemoryAllocator printable_allocator2;
1127 {
1128 std::cout << "Array a1\n";
1129 SharedArray<Int32> a1(allocator2);
1130 ASSERT_EQ(a1.allocator(), allocator2);
1131 ASSERT_EQ(a1.size(), 0);
1132 ASSERT_EQ(a1.capacity(), 0);
1133 ASSERT_EQ(a1.data(), nullptr);
1134
1135 std::cout << "Array a2\n";
1136 SharedArray<Int32> a2(a1);
1137 ASSERT_EQ(a1.allocator(), a2.allocator());
1138 ASSERT_EQ(a2.capacity(), 0);
1139 ASSERT_EQ(a2.data(), nullptr);
1140 a1.reserve(3);
1141 a1.add(5);
1142 a1.add(7);
1143 a1.add(12);
1144 a1.add(3);
1145 a1.add(1);
1146 ASSERT_EQ(a1.size(), 5);
1147
1148 std::cout << "Array a3\n";
1150 a3.add(4);
1151 a3.add(6);
1152 a3.add(2);
1153 ASSERT_EQ(a3.size(), 3);
1154 a3 = a1;
1155 ASSERT_EQ(a3.allocator(), a1.allocator());
1156 ASSERT_EQ(a3.size(), a1.size());
1157 ASSERT_EQ(a3.constSpan(), a1.constSpan());
1158
1159 std::cout << "Array a4\n";
1160 SharedArray<Int32> a4(allocator1, 2);
1161 ASSERT_EQ(a4.size(), 2);
1162 a4.add(4);
1163 a4.add(6);
1164 a4.add(2);
1165 ASSERT_EQ(a4.size(), 5);
1166 ASSERT_EQ(a4[2], 4);
1167 ASSERT_EQ(a4[3], 6);
1168 ASSERT_EQ(a4[4], 2);
1169
1170 a4 = a1.span();
1171 ASSERT_EQ(a4.allocator(), allocator1);
1172
1173 a4 = SharedArray<Int32>(&printable_allocator2);
1174
1175 SharedArray<Int32> array[2];
1176 IMemoryAllocator* allocator3 = allocator1;
1177 for (Integer i = 0; i < 2; ++i) {
1178 array[i] = SharedArray<Int32>(allocator3);
1179 }
1180 ASSERT_EQ(array[0].allocator(), allocator3);
1181 ASSERT_EQ(array[1].allocator(), allocator3);
1182 }
1183}
1184
1193: public IMemoryAllocator3
1194{
1195 public:
1196
1197 bool hasRealloc(MemoryAllocationArgs args) const override
1198 {
1199 _checkValid(args);
1200 return m_default_allocator.hasRealloc(args);
1201 }
1202 AllocatedMemoryInfo allocate(MemoryAllocationArgs args, Int64 new_size) override
1203 {
1204 _checkValid(args);
1205 return m_default_allocator.allocate(args, new_size);
1206 }
1207 AllocatedMemoryInfo reallocate(MemoryAllocationArgs args, AllocatedMemoryInfo current_ptr, Int64 new_size) override
1208 {
1209 _checkValid(args);
1210 return m_default_allocator.reallocate(args, current_ptr, new_size);
1211 }
1212 void deallocate(MemoryAllocationArgs args, AllocatedMemoryInfo ptr) override
1213 {
1214 _checkValid(args);
1215 m_default_allocator.deallocate(args, ptr);
1216 }
1217 Int64 adjustedCapacity(MemoryAllocationArgs args, Int64 wanted_capacity, Int64 element_size) const override
1218 {
1219 _checkValid(args);
1220 return m_default_allocator.adjustedCapacity(args, wanted_capacity, element_size);
1221 }
1222 size_t guaranteedAlignment(MemoryAllocationArgs args) const override
1223 {
1224 _checkValid(args);
1225 return m_default_allocator.guaranteedAlignment(args);
1226 }
1227
1228 void notifyMemoryArgsChanged(MemoryAllocationArgs old_args, MemoryAllocationArgs new_args, AllocatedMemoryInfo ptr) override
1229 {
1230 // This method is only called once so we test the expected values directly
1231 ASSERT_EQ(old_args.memoryLocationHint(), eMemoryLocationHint::None);
1232 ASSERT_EQ(new_args.memoryLocationHint(), eMemoryLocationHint::MainlyHost);
1233 ASSERT_EQ(ptr.size(), 8);
1234 m_default_allocator.notifyMemoryArgsChanged(old_args, new_args, ptr);
1235 }
1236
1237 private:
1238
1239 DefaultMemoryAllocator3 m_default_allocator;
1240
1241 private:
1242
1243 static void _checkValid(MemoryAllocationArgs args)
1244 {
1245 bool v1 = args.memoryLocationHint() == eMemoryLocationHint::None;
1246 bool v2 = args.memoryLocationHint() == eMemoryLocationHint::MainlyHost;
1247 bool v3 = args.memoryLocationHint() == eMemoryLocationHint::HostAndDeviceMostlyRead;
1248 bool is_valid = v1 || v2 || v3;
1249 ASSERT_TRUE(is_valid);
1250 }
1251};
1252
1253#define ASSERT_SAME_ARRAY_INFOS(a, b) \
1254 ASSERT_EQ(a.allocationOptions(), b.allocationOptions()); \
1255 ASSERT_EQ(a.size(), b.size()); \
1256 ASSERT_EQ(a.capacity(), b.capacity())
1257
1258TEST(Array, AllocatorV2)
1259{
1260 using namespace Arccore;
1261 TesterMemoryAllocatorV3 testerv2_allocator;
1262 TesterMemoryAllocatorV3 testerv2_allocator2;
1263 MemoryAllocationOptions allocate_options1(&testerv2_allocator, eMemoryLocationHint::HostAndDeviceMostlyRead);
1264 MemoryAllocationOptions allocate_options2(&testerv2_allocator, eMemoryLocationHint::None, 0);
1265 {
1266 MemoryAllocationOptions opt3(&testerv2_allocator);
1267 opt3.setMemoryLocationHint(eMemoryLocationHint::HostAndDeviceMostlyRead);
1268 ASSERT_EQ(opt3, allocate_options1);
1269 }
1270 {
1271 std::cout << "Array a1\n";
1272 UniqueArray<Int32> a1(allocate_options2);
1273 ASSERT_EQ(a1.allocationOptions(), allocate_options2);
1274 ASSERT_EQ(a1.size(), 0);
1275 ASSERT_EQ(a1.capacity(), 0);
1276 ASSERT_EQ(a1.data(), nullptr);
1277
1278 std::cout << "Array a2\n";
1279 UniqueArray<Int32> a2(a1);
1280 ASSERT_SAME_ARRAY_INFOS(a2, a1);
1281 ASSERT_EQ(a2.data(), nullptr);
1282 a1.reserve(3);
1283 a1.add(5);
1284 a1.add(7);
1285 a1.add(12);
1286 a1.add(3);
1287 a1.add(1);
1288 ASSERT_EQ(a1.size(), 5);
1289 a2.add(9);
1290 a2.add(17);
1291 // To test notifyMemoryArgsChanged()
1292 a2.setMemoryLocationHint(eMemoryLocationHint::MainlyHost);
1293
1294 std::cout << "Array a3\n";
1295 UniqueArray<Int32> a3(allocate_options1);
1296 a3.add(4);
1297 a3.add(6);
1298 a3.add(2);
1299 ASSERT_EQ(a3.size(), 3);
1300 a3 = a1;
1301 ASSERT_EQ(a3.allocator(), a1.allocator());
1302 ASSERT_EQ(a3.size(), a1.size());
1303 ASSERT_EQ(a3.constSpan(), a1.constSpan());
1304
1305 std::cout << "Array a4\n";
1306 UniqueArray<Int32> a4(allocate_options1);
1307 a4.add(4);
1308 a4.add(6);
1309 a4.add(2);
1310 ASSERT_EQ(a4.size(), 3);
1311 a4 = a1.span();
1312 ASSERT_EQ(a4.allocationOptions(), allocate_options1);
1313
1314 a4 = UniqueArray<Int32>(&testerv2_allocator2);
1315
1316 UniqueArray<Int32> array[2];
1317 MemoryAllocationOptions allocator3 = allocate_options1;
1318 for (Integer i = 0; i < 2; ++i) {
1319 array[i] = UniqueArray<Int32>(allocator3);
1320 }
1321 ASSERT_EQ(array[0].allocationOptions(), allocator3);
1322 ASSERT_EQ(array[1].allocationOptions(), allocator3);
1323 }
1324}
1325
1326/*---------------------------------------------------------------------------*/
1327/*---------------------------------------------------------------------------*/
1328
1329TEST(Array, DebugInfo)
1330{
1331 using namespace Arccore;
1332 DefaultMemoryAllocator3 m_default_allocator;
1333 MemoryAllocationOptions allocate_options2(&m_default_allocator, eMemoryLocationHint::None, 0);
1334
1335 String a1_name("Array1");
1336 String sa1_name("SharedArray1");
1338 {
1339 std::cout << "Array a1\n";
1340 UniqueArray<Int32> a1(allocate_options2);
1341 a1.setDebugName(a1_name);
1342 ASSERT_EQ(a1.allocationOptions(), allocate_options2);
1343 ASSERT_EQ(a1.size(), 0);
1344 ASSERT_EQ(a1.capacity(), 0);
1345 ASSERT_EQ(a1.data(), nullptr);
1346 ASSERT_EQ(a1.debugName(), a1_name);
1347
1348 std::cout << "SharedArray sa1\n";
1349 SharedArray<Int32> sa1(allocate_options2);
1350 sa1.setDebugName(sa1_name);
1351 ASSERT_EQ(sa1.allocationOptions(), allocate_options2);
1352 ASSERT_EQ(sa1.size(), 0);
1353 ASSERT_EQ(sa1.capacity(), 0);
1354 ASSERT_EQ(sa1.data(), nullptr);
1355 ASSERT_EQ(sa1.debugName(), sa1_name);
1356
1357 ASSERT_EQ(a1.debugName(), a1_name);
1358
1359 std::cout << "Array a2\n";
1360 UniqueArray<Int32> a2(a1);
1361 ASSERT_SAME_ARRAY_INFOS(a2, a1);
1362 ASSERT_EQ(a2.data(), nullptr);
1363 ASSERT_EQ(a2.debugName(), a1_name);
1364 a1.reserve(3);
1365 a1.add(5);
1366 a1.add(7);
1367 a1.add(12);
1368 a1.add(3);
1369 a1.add(1);
1370 ASSERT_EQ(a1.size(), 5);
1371 a2.add(9);
1372 a2.add(17);
1373 ASSERT_EQ(a2.debugName(), a1_name);
1374 ASSERT_EQ(a2.size(), 2);
1375
1376 a3 = a2;
1377 }
1378 ASSERT_EQ(a3.debugName(), a1_name);
1379 ASSERT_EQ(a3.size(), 2);
1380}
1381
1382/*---------------------------------------------------------------------------*/
1383/*---------------------------------------------------------------------------*/
1384
1385TEST(Collections, Memory)
1386{
1387 using namespace Arccore;
1388 std::cout << eHostDeviceMemoryLocation::Unknown << " "
1393
1394 std::cout << eMemoryResource::Unknown << " "
1395 << eMemoryResource::Host << " "
1397 << eMemoryResource::Device << " "
1399
1404}
1405
1406/*---------------------------------------------------------------------------*/
1407/*---------------------------------------------------------------------------*/
1408
1409namespace Arcane
1410{
1411// Explicitly instantiates array classes to ensure
1412// that all methods work
1413template class UniqueArray<IntSubClass>;
1414template class SharedArray<IntSubClass>;
1415template class Array<IntSubClass>;
1416template class AbstractArray<IntSubClass>;
1417} // namespace Arcane
#define ASSERT_TRUE(condition)
Checks that condition is true.
Definition Assertion.h:128
String debugName() const
Debug name (null if no name specified).
Abstract base class for a vector.
void _internalSetHostDeviceMemoryLocation(eHostDeviceMemoryLocation location)
Sets the physical location of the memory region.
Integer size() const
Number of elements in the vector.
ArrayIterator< pointer > iterator
Type of the iterator over an array element.
eHostDeviceMemoryLocation hostDeviceMemoryLocation() const
Sets the physical location of the memory region.
ArrayIterator< const_pointer > const_iterator
Type of the constant iterator over an array element.
static constexpr Integer simdAlignment()
Alignment for structures using vectorization.
static AlignedMemoryAllocator * Simd()
Allocator guaranteeing alignment to use vectorization on the target platform.
Information about an allocated memory region.
Int64 size() const
Size in bytes of the used memory region. (-1) if unknown.
Array Metadata.
ConstIterT< ArrayView< T > > const_iter
Type of a constant iterator over the entire array.
Base class for 1D data vectors.
SmallSpan< const T > smallSpan() const
Immutable view of this array.
reverse_iterator rbegin()
Reverse iterator over the first element of the array.
T & at(Int64 i)
Element at index i. Always checks for overflows.
void resizeNoInit(Int64 s)
Resizes without initializing new values.
Span< const T > span() const
Immutable view of this array.
iterator erase(const_iterator pos)
Removes the element at pos.
void resize(Int64 s)
Changes the number of elements in the array to s.
ConstArrayView< T > subConstView(Int64 abegin, Int32 asize) const
Sub-view starting from element abegin and containing asize elements.
void copy(Span< const T > rhs)
Copies the values from rhs into the instance.
SmallSpan< const T > constSmallSpan() const
Immutable view of this array.
iterator begin()
Iterator over the first element of the array.
void add(ConstReferenceType val)
Adds element val to the end of the array.
ConstArrayView< T > constView() const
Constant view of this array.
ArrayRange< pointer > range()
Iteration range from the first to the last element.
void remove(Int64 index)
Removes the entity at index index.
Span< const T > constSpan() const
Constant view of this array.
void reserve(Int64 new_capacity)
Reserves memory for new_capacity elements.
reverse_iterator rend()
Reverse iterator over the first element after the end of the array.
ArrayView< T > subView(Int64 abegin, Integer asize)
Sub-view starting from element abegin and containing asize elements.
iterator end()
Iterator over the first element after the end of the array.
ArrayView< T > view() const
Mutable view of this array.
ConstIterT< ConstArrayView< T > > const_iter
Type of a constant iterator over the entire array.
Class containing information to specialize allocations.
Memory allocator via malloc/realloc/free with listing output.
1D vector of data with reference semantics.
SharedArray< T > clone() const
Clones the array.
View of an array of elements of type T.
Definition Span.h:803
1D data vector with value semantics (STL style).
Allocator for testing arguments.
Concept for allocating, resizing and freeing memory block.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
void swap(UniqueArray2< T > &v1, UniqueArray2< T > &v2)
Swaps the values of v1 and v2.
Int32 Integer
Type representing an integer.
@ MainlyHost
Indicates that the data will primarily be used on the CPU.
@ HostAndDeviceMostlyRead
Indicates that the data will be used both on the accelerator and on the CPU and will not be frequentl...
@ ManagedMemoryDevice
The memory is managed memory on the accelerator.
@ Host
The memory is on the host.
@ ManagedMemoryHost
The memory is managed memory on the host.
@ Device
The memory is on the accelerator.
@ HostPinned
Allocates on the host.
@ Unknown
Unknown or uninitialized value.
@ Host
Allocates on the host.
@ UnifiedMemory
Allocates using unified memory.
@ Device
Allocates on the device.
Namespace of Arccore.