Arcane  4.2.3.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
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 // Teste 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 // Teste assign avec count = 0
90 a.assign(0l, value_type(99));
91 ASSERT_EQ(a.size(), 0);
92
93 // Teste assign en écrasant des données existantes
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 // Teste 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 // Teste avec une plage vide
111 ArrayType a2;
112 std::vector<Int32> empty;
113 a2.assign(empty.begin(), empty.end());
114 ASSERT_EQ(a2.size(), 0);
115
116 // Teste avec des itérateurs de tableau
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 // Teste avec 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 // Teste erase(const_iterator pos) - élément unique
142 {
143 ArrayType a = { 1, 2, 3, 4, 5 };
144
145 // Efface le premier élément
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); // L'itérateur retourné pointe sur l'élément suivant
153
154 // Efface l'élément du milieu
155 a = { 1, 2, 3, 4, 5 };
156 it = a.erase(a.begin() + 2); // Efface '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 // Efface le dernier élément
165 a = { 1, 2, 3, 4, 5 };
166 it = a.erase(a.end() - 1); // Efface '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()); // L'itérateur retourné est end()
173 }
174
175 // Teste erase(const_iterator first, const_iterator last) - plage
176 {
177 // Efface depuis le début
178 ArrayType a = { 1, 2, 3, 4, 5 };
179 auto it = a.erase(a.begin(), a.begin() + 2); // Efface [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 // Efface depuis le milieu
187 a = { 1, 2, 3, 4, 5 };
188 it = a.erase(a.begin() + 1, a.begin() + 3); // Efface [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 // Efface jusqu'à la fin
196 a = { 1, 2, 3, 4, 5 };
197 it = a.erase(a.begin() + 2, a.end()); // Efface [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 // Efface toute la plage
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 // Efface une plage vide (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); // Pointe sur l'élément à la position 2
214 }
215
216 // Teste avec const_iterator (tableau constant)
217 {
218 const UniqueArray<value_type> ca = { 1, 2, 3, 4, 5 };
219 ArrayType a = ca;
220
221 // erase avec une position const_iterator
222 auto it = a.erase(a.cbegin() + 1); // Efface '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 avec une plage const_iterator
229 a = ca;
230 it = a.erase(a.cbegin() + 1, a.cbegin() + 3); // Efface [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 // Dépile jusqu'à ce que le tableau soit vide
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 // Teste avec un type simple
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 // Teste avec un type non-POD (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 // Teste sur un tableau vide
295 {
296 ArrayType a;
297 ASSERT_EQ(a.size(), 0);
298 // assign sur un tableau vide
299 a.assign(3l, value_type(7));
300 ASSERT_EQ(a.size(), 3);
301 // pop_back sur un tableau vide ne doit pas planter (mais c'est un
302 // comportement indéfini dans la STL)
303 // On ne teste pas pop_back sur un tableau vide car c'est un comportement indéfini
304 }
305
306 // Teste sur un tableau d'un seul élément
307 {
308 ArrayType a = { 42 };
309 ASSERT_EQ(a.size(), 1);
310
311 // erase d'un élément unique
312 auto it = a.erase(a.begin());
313 ASSERT_EQ(a.size(), 0);
314 ASSERT_EQ(it, a.end());
315
316 // assign sur un seul élément
317 a.assign(1l, value_type(99));
318 ASSERT_EQ(a.size(), 1);
319 ASSERT_EQ(a[0], 99);
320
321 // pop_back sur un seul élément
322 a.pop_back();
323 ASSERT_EQ(a.size(), 0);
324
325 // emplace_back sur un seul élément
326 a.emplace_back(123);
327 ASSERT_EQ(a.size(), 1);
328 ASSERT_EQ(a[0], 123);
329 }
330
331 // Teste assign avec un scénario de type auto-assignation
332 {
333 ArrayType a = { 1, 2, 3 };
334 auto begin = a.begin();
335 auto end = a.end();
336 a.assign(begin, end); // Doit fonctionner mais être en pratique un no-op
337 ASSERT_EQ(a.size(), 3);
338 ASSERT_EQ(a[0], 1);
339 ASSERT_EQ(a[1], 2);
340 ASSERT_EQ(a[2], 3);
341 }
342}
343
344} // namespace
345
346TEST(Array, Assign)
347{
348 _testArrayAssign<UniqueArray<Int32>>();
349 _testArrayAssign<SharedArray<Int32>>();
350 _testArrayAssign<UniqueArray<IntSubClass>>();
351 _testArrayAssign<SharedArray<IntSubClass>>();
352}
353
354TEST(Array, Erase)
355{
356 _testArrayErase<UniqueArray<Int32>>();
357 _testArrayErase<SharedArray<Int32>>();
358 _testArrayErase<UniqueArray<IntSubClass>>();
359 _testArrayErase<SharedArray<IntSubClass>>();
360}
361
362TEST(Array, PopBack)
363{
364 _testArrayPopBack<UniqueArray<Int32>>();
365 _testArrayPopBack<SharedArray<Int32>>();
366 _testArrayPopBack<UniqueArray<IntSubClass>>();
367 _testArrayPopBack<SharedArray<IntSubClass>>();
368}
369
370TEST(Array, EmplaceBack)
371{
372 _testArrayEmplaceBack<UniqueArray<Int32>>();
373 _testArrayEmplaceBack<SharedArray<Int32>>();
374 _testArrayEmplaceBack<UniqueArray<IntSubClass>>();
375 _testArrayEmplaceBack<SharedArray<IntSubClass>>();
376}
377
378TEST(Array, EdgeCases)
379{
380 _testArrayEdgeCases<UniqueArray<Int32>>();
381 _testArrayEdgeCases<SharedArray<Int32>>();
382 _testArrayEdgeCases<UniqueArray<IntSubClass>>();
383 _testArrayEdgeCases<SharedArray<IntSubClass>>();
384}
385
386/*---------------------------------------------------------------------------*/
387/*---------------------------------------------------------------------------*/
388
389Integer IntPtrSubClass::count = 0;
390
391/*---------------------------------------------------------------------------*/
392/*---------------------------------------------------------------------------*/
393
394template <typename Container, typename SubClass>
396{
397 public:
398
399 void test()
400 {
401 {
402 Container c;
403 c.add(SubClass(1));
404 c.add(SubClass(2));
405 c.add(SubClass(3));
406 ARCCORE_UT_CHECK((c.size() == 3), "Bad size (3)");
407 ARCCORE_UT_CHECK((c[0] == 1), "Bad value [0]");
408 ARCCORE_UT_CHECK((c[1] == 2), "Bad value [1]");
409 ARCCORE_UT_CHECK((c[2] == 3), "Bad value [2]");
410 c.resize(0);
411 ARCCORE_UT_CHECK((c.size() == 0), "Bad size (0)");
412 c.resize(5);
413 ARCCORE_UT_CHECK((c.size() == 5), "Bad size");
414 c.add(SubClass(6));
415 ARCCORE_UT_CHECK((c.size() == 6), "Bad size");
416 ARCCORE_UT_CHECK((c[5] == 6), "Bad value [5]");
417 c.shrink();
418 ASSERT_EQ(c.size(), c.capacity()) << "Bad capacity (test 1)";
419 c.resize(12);
420 c.shrink();
421 ASSERT_EQ(c.size(), c.capacity()) << "Bad capacity (test 2)";
422 }
423 {
424 Container c;
425 c.shrink();
426 ASSERT_EQ(c.capacity(), 0) << "Bad capacity (test 3)";
427 }
428 {
429 Container c;
430 Integer nb = 20;
431 for (Integer i = 0; i < nb; ++i)
432 c.add(SubClass(i));
433 c.reserve(nb * 2);
434 Int64 current_capacity = c.capacity();
435 ASSERT_EQ(current_capacity, (nb * 2)) << "Bad capacity (test 4)";
436 c.shrink(c.capacity() + 5);
437 ASSERT_EQ(c.capacity(), current_capacity) << "Bad capacity (test 5)";
438 c.shrink(32);
439 ASSERT_EQ(c.capacity(), 32) << "Bad capacity (test 6)";
440 c.shrink();
441 ASSERT_EQ(c.capacity(), c.size()) << "Bad capacity (test 7)";
442 }
443 {
445 Integer nb = 1000000;
446 uc.resize(1000);
447 for (Container& c : uc) {
448 c.reserve(nb);
449 c.shrink_to_fit();
450 }
451 }
452 {
453 Container c;
454 for (Integer i = 0; i < 50; ++i)
455 c.add(SubClass(i + 2));
456 {
457 Container c2 = c;
458 for (Integer i = 50; i < 100; ++i) {
459 c2.add(SubClass(i + 2));
460 }
461 Container c4 = c2;
462 Container c3;
463 c3.add(5);
464 c3.add(6);
465 c3.add(7);
466 c3 = c2;
467 for (Integer i = 100; i < 150; ++i) {
468 c4.add(SubClass(i + 2));
469 }
470 }
471 ARCCORE_UT_CHECK((c.size() == 150), "Bad size (150)");
472 c.reserve(300);
473 ARCCORE_UT_CHECK((c.capacity() == 300), "Bad capacity (300)");
474 for (Integer i = 0; i < 50; ++i) {
475 c.remove(i);
476 }
477 ARCCORE_UT_CHECK((c.size() == 100), "Bad size (100)");
478 for (Integer i = 0; i < 50; ++i) {
479 //cout << "** VAL: " << i << " c=" << c[i] << " expected=" << ((i*2)+3) << '\n';
480 ARCCORE_UT_CHECK((c[i] == ((i * 2) + 3)), "Bad value");
481 }
482 for (Integer i = 50; i < 100; ++i) {
483 //cout << "** VAL: " << i << " c=" << c[i] << " expected=" << (i+52) << '\n';
484 ARCCORE_UT_CHECK((c[i] == (i + 52)), "Bad value");
485 }
486 }
487 }
488};
489
490namespace
491{
492void _testArrayNewInternal()
493{
494 using namespace Arccore;
495 std::cout << "** TEST VECTOR NEW\n";
496
497 std::cout << "** wanted_size = " << AlignedMemoryAllocator3::simdAlignment() << "\n";
498 //if (impl_size!=wanted_size)
499 //ARCCORE_FATAL("Bad sizeof(ArrayImplBase) v={0} expected={1}",impl_size,wanted_size);
500 {
502 rvt.test();
503 }
504 std::cout << "** TEST VECTOR NEW 2\n";
505 {
507 rvt.test();
508 std::cout << "** COUNT = " << IntPtrSubClass::count << "\n";
509 }
510 std::cout << "** TEST VECTOR NEW 3\n";
511 {
513 rvt.test();
514 std::cout << "** COUNT = " << IntPtrSubClass::count << "\n";
515 }
516 {
518 c.add(5);
519 c.add(7);
521 c2.add(3);
522 ARCCORE_UT_CHECK((c2.size() == 3), "Bad value [3]");
523 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
524 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
525 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
526 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
527 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
528 ARCCORE_UT_CHECK((c2[2] == 3), "Bad value [7]");
529 }
530 {
532 c.add(5);
533 c.add(7);
535 c2.add(3);
536 ARCCORE_UT_CHECK((c2.size() == 3), "Bad value [3]");
537 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
538 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
539 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
540 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
541 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
542 ARCCORE_UT_CHECK((c2[2] == 3), "Bad value [7]");
543 }
544 {
545 UniqueArray<IntSubClass> c{ 5, 7 };
547 c2.add(3);
548 ARCCORE_UT_CHECK((c2.size() == 3), "Bad value [3]");
549 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
550 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
551 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
552 }
553 {
554 UniqueArray<IntSubClass> c{ 5, 7 };
555 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
556 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
557 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
558 }
559 {
560 SharedArray<IntSubClass> c{ 5, 7 };
561 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
562 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
563 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
564 }
565 {
566 PrintableMemoryAllocator allocator;
567 UniqueArray<IntSubClass> c(&allocator);
568 UniqueArray<IntSubClass> cx(&allocator, 5);
569 ARCCORE_UT_CHECK((cx.size() == 5), "Bad value [5]");
570 c.add(5);
571 c.add(7);
573 c2.add(3);
574 ARCCORE_UT_CHECK((c2.size() == 3), "Bad value [3]");
575 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
576 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
577 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
578 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
579 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
580 ARCCORE_UT_CHECK((c2[2] == 3), "Bad value [7]");
581 for (Integer i = 0; i < 50; ++i)
582 c.add(i + 3);
583 c.resize(24);
584 c.reserve(70);
585 }
586 {
588 c2.add(3);
589 c2.add(5);
591 ASSERT_EQ(c22.size(), 33);
592 c22 = c2;
593 {
595 c.add(5);
596 c.add(7);
597 c2 = c;
600 c2.resize(125);
601 ASSERT_EQ(c2.size(), c3.size());
602 ASSERT_EQ(c2.size(), c4.size());
603 c3.resize(459);
604 ASSERT_EQ(c2.size(), c3.size());
605 ASSERT_EQ(c2.size(), c4.size());
606 c4.resize(932);
607 c.resize(32);
608 }
609 c2.add(3);
610 ARCCORE_UT_CHECK((c2.size() == 33), "Bad value [3]");
611 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
612 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
613 ARCCORE_UT_CHECK((c2[32] == 3), "Bad value [7]");
614 c2.resize(1293);
615 ASSERT_EQ(c2.size(), 1293);
616 ASSERT_EQ(c22.size(), 2);
617
618 {
619 SharedArray<IntSubClass> values1 = { -7, 3, 4 };
620 ASSERT_EQ(values1.size(), 3);
621 ASSERT_EQ(values1[0], -7);
622 ASSERT_EQ(values1[1], 3);
623 ASSERT_EQ(values1[2], 4);
624 values1 = { 2, -1, 9, 13 };
625 ASSERT_EQ(values1.size(), 4);
626 ASSERT_EQ(values1[0], 2);
627 ASSERT_EQ(values1[1], -1);
628 ASSERT_EQ(values1[2], 9);
629 ASSERT_EQ(values1[3], 13);
630 SharedArray<IntSubClass> values2 = values1;
631 ASSERT_EQ(values2, values1);
632
633 values1 = {};
634 ASSERT_EQ(values1.size(), 0);
635 ASSERT_EQ(values2.size(), 0);
636 }
637 }
638 {
639 UniqueArray<Int32> values1 = { 2, 5 };
640 UniqueArray<Int32> values2 = { 4, 9, 7 };
641 // Copie les valeurs de values2 à la fin de values1.
642 std::copy(std::begin(values2), std::end(values2), std::back_inserter(values1));
643 std::cout << "** VALUES1 = " << values1 << "\n";
644 ARCCORE_UT_CHECK((values1.size() == 5), "BI: Bad size");
645 ARCCORE_UT_CHECK((values1[0] == 2), "BI: Bad value [0]");
646 ARCCORE_UT_CHECK((values1[1] == 5), "BI: Bad value [1]");
647 ARCCORE_UT_CHECK((values1[2] == 4), "BI: Bad value [2]");
648 ARCCORE_UT_CHECK((values1[3] == 9), "BI: Bad value [3]");
649 ARCCORE_UT_CHECK((values1[4] == 7), "BI: Bad value [4]");
650
652 vx.add(IntPtrSubClass(5));
653 UniqueArray<IntPtrSubClass>::iterator i = std::begin(vx);
655 std::cout << "V=" << i->m_v << " " << ci->m_v << '\n';
656
657 values1 = { -7, 3 };
658 ASSERT_EQ(values1.size(), 2);
659 ASSERT_EQ(values1[0], -7);
660 ASSERT_EQ(values1[1], 3);
661
662 values1 = {};
663 ASSERT_EQ(values1.size(), 0);
664 }
665 {
666 UniqueArray<Int32> values1;
667 UniqueArray<Int32> values2 = { 4, 9, 7, 6, 3 };
668 // Copie les valeurs de values2 à la fin de values1.
669 values1.copy(values2);
670 std::cout << "** VALUES1 = " << values1 << "\n";
671 ARCCORE_UT_CHECK((values1.size() == 5), "BI: Bad size");
672 ARCCORE_UT_CHECK((values1[0] == 4), "BI2: Bad value [0]");
673 ARCCORE_UT_CHECK((values1[1] == 9), "BI2: Bad value [1]");
674 ARCCORE_UT_CHECK((values1[2] == 7), "BI2: Bad value [2]");
675 ARCCORE_UT_CHECK((values1[3] == 6), "BI2: Bad value [3]");
676 ARCCORE_UT_CHECK((values1[4] == 3), "BI2: Bad value [4]");
677
679 vx.add(IntPtrSubClass(5));
680 UniqueArray<IntPtrSubClass>::iterator i = std::begin(vx);
682 std::cout << "V=" << i->m_v << " " << ci->m_v << '\n';
683 }
684 {
686 vx.add(IntPtrSubClass(5));
689 std::cout << "V=" << i->m_v << " " << ci->m_v << '\n';
692 std::cout << "V=" << cicvx->m_v << '\n';
693 }
694 {
696 vx.add(IntPtrSubClass(5));
697 UniqueArray<IntPtrSubClass>::iterator i = std::begin(vx);
698 UniqueArray<IntPtrSubClass>::iterator iend = std::end(vx);
700 std::cout << "V=" << i->m_v << " " << ci->m_v << " " << (iend - i) << '\n';
702 UniqueArray<IntPtrSubClass>::const_iterator cicvx = std::begin(cvx);
703 std::cout << "V=" << cicvx->m_v << '\n';
704 std::copy(std::begin(vx), std::end(vx), std::begin(vx));
705 }
706 {
707 UniqueArray<Int32> values = { 4, 9, 7 };
708 for (typename ArrayView<Int32>::const_iter i(values.view()); i(); ++i) {
709 std::cout << *i << '\n';
710 }
711 for (typename ConstArrayView<Int32>::const_iter i(values.view()); i(); ++i) {
712 std::cout << *i << '\n';
713 }
714 for (auto i : values.range()) {
715 std::cout << i << '\n';
716 }
717 for (auto i : values.constView().range()) {
718 std::cout << i << '\n';
719 }
720
721 {
722 auto r1 = std::make_reverse_iterator(values.end());
723 auto r2 = std::make_reverse_iterator(values.begin());
724 for (; r1 != r2; ++r1) {
725 std::cout << "RVALUE = " << *r1 << '\n';
726 }
727 }
728 {
729 auto r1 = values.rbegin();
730 ASSERT_EQ((*r1), 7);
731 ++r1;
732 ASSERT_EQ((*r1), 9);
733 ++r1;
734 ASSERT_EQ((*r1), 4);
735 ++r1;
736 ASSERT_TRUE((r1 == values.rend()));
737 }
738 {
741 c2.add(IntSubClassNoPod{ 3 });
742 ARCCORE_UT_CHECK((c2.size() == 3), "Bad value [3]");
743 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
744 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
745 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
746 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
747 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
748 ARCCORE_UT_CHECK((c2[2] == 3), "Bad value [7]");
749 c = c2.span();
750 SmallSpan<const IntSubClassNoPod> c2_small_span = c2;
751 ASSERT_EQ(c.constSpan(), c2.constSpan());
752 ASSERT_EQ(c.constSmallSpan(), c2_small_span);
753 ASSERT_EQ(c.smallSpan(), c2.smallSpan());
754 }
755 }
756}
757} // namespace
758
759/*---------------------------------------------------------------------------*/
760/*---------------------------------------------------------------------------*/
761
762TEST(Array, Misc)
763{
764 try {
765 _testArrayNewInternal();
766 }
767 catch (const Exception& ex) {
768 std::cerr << "Exception ex=" << ex << "\n";
769 throw;
770 }
771}
772
773/*---------------------------------------------------------------------------*/
774/*---------------------------------------------------------------------------*/
775
776namespace
777{
778void _Add(Array<Real>& v, Integer new_size)
779{
780 v.resize(new_size);
781}
782} // namespace
783
784/*---------------------------------------------------------------------------*/
785/*---------------------------------------------------------------------------*/
786
787TEST(Array, Misc2)
788{
789 using namespace Arccore;
790 {
792 v.resize(3);
793 v[0] = 1.2;
794 v.at(1) = -1.3;
795 v[2] = 7.6;
796 ASSERT_EQ(v[0], 1.2);
797 ASSERT_EQ(v[1], -1.3);
798 ASSERT_EQ(v.at(2), 7.6);
799
800 v.add(4.3);
801 for (Real x : v) {
802 std::cout << " Value: " << x << '\n';
803 }
804 v.printInfos(std::cout);
805 }
806 {
808 v.add(4.3);
809 v.add(5.3);
810 v.add(4.6);
811 v.printInfos(std::cout);
812 v.add(14.3);
813 v.add(25.3);
814 v.add(34.6);
815 v.printInfos(std::cout);
816 v.resize(4);
817 v.printInfos(std::cout);
818 v.add(12.2);
819 v.add(2.4);
820 v.add(3.4);
821 v.add(3.6);
822 v.printInfos(std::cout);
823 for (Integer i = 0, is = v.size(); i < is; ++i) {
824 std::cout << " Value: " << v[i] << '\n';
825 }
826 }
827 {
829 v.reserve(5);
830 for (int i = 0; i < 10; ++i)
831 v.add((Real)i);
832 for (Integer i = 0, is = v.size(); i < is; ++i) {
833 std::cout << " Value: " << v[i] << '\n';
834 }
835 }
836 {
838 v.reserve(175);
839 for (int i = 0; i < 27500; ++i) {
840 Real z = (Real)i;
841 v.add(z * z);
842 }
843 for (int i = 0; i < 5000; ++i) {
844 v.remove(i * 2);
845 }
846 v.reserve(150);
847 for (int i = 0; i < 27500; ++i) {
848 Real z = (Real)i;
849 v.add(z * z);
850 }
851 std::cout << " ValueSize= " << v.size() << " values=" << v << '\n';
852 }
853 for (Integer i = 0; i < 100; ++i) {
855 _Add(v, 500000);
856 _Add(v, 1000000);
857 _Add(v, 0);
858 _Add(v, 100000);
859 _Add(v, 0);
860 _Add(v, 0);
861 _Add(v, 230000);
862 std::cout << " Size: " << v.size() << '\n';
863 ASSERT_EQ(v.size(), 230000);
864 }
865}
866
867/*---------------------------------------------------------------------------*/
868/*---------------------------------------------------------------------------*/
869
870TEST(Array, SubViews)
871{
872 using namespace Arccore;
873
874 {
875 // Test Array::subView() et Array::subConstView()
877 v.resize(23);
878 for (Int32 i = 0, n = v.size(); i < n; ++i)
879 v[i] = (i + 1);
880
881 auto sub_view1 = v.subView(50, 5);
882 ASSERT_EQ(sub_view1.data(), nullptr);
883 ASSERT_EQ(sub_view1.size(), 0);
884
885 auto sub_view2 = v.subView(2, 8);
886 ASSERT_EQ(sub_view2.size(), 8);
887 for (Int32 i = 0, n = sub_view2.size(); i < n; ++i)
888 ASSERT_EQ(sub_view2[i], v[2 + i]);
889
890 auto sub_view3 = v.subView(20, 8);
891 ASSERT_EQ(sub_view3.size(), 3);
892 for (Int32 i = 0, n = sub_view3.size(); i < n; ++i)
893 ASSERT_EQ(sub_view3[i], v[20 + i]);
894
895 auto sub_const_view1 = v.subConstView(50, 5);
896 ASSERT_EQ(sub_const_view1.data(), nullptr);
897 ASSERT_EQ(sub_const_view1.size(), 0);
898
899 auto sub_const_view2 = v.subConstView(2, 8);
900 ASSERT_EQ(sub_const_view2.size(), 8);
901 for (Int32 i = 0, n = sub_const_view2.size(); i < n; ++i)
902 ASSERT_EQ(sub_const_view2[i], v[2 + i]);
903
904 auto sub_const_view3 = v.subConstView(20, 8);
905 ASSERT_EQ(sub_const_view3.size(), 3);
906 for (Int32 i = 0, n = sub_const_view3.size(); i < n; ++i)
907 ASSERT_EQ(sub_const_view3[i], v[20 + i]);
908 }
909}
910
911/*---------------------------------------------------------------------------*/
912/*---------------------------------------------------------------------------*/
913
914class NoCopyData
915{
916 public:
917
918 NoCopyData(const NoCopyData& x) = delete;
919};
920
921template <typename DataType>
923: public Arccore::Array<DataType>
924{
925 public:
926
927 using BaseClass = Arccore::Array<DataType>;
928};
929
930/*---------------------------------------------------------------------------*/
931/*---------------------------------------------------------------------------*/
932
933TEST(Array, Misc3)
934{
935 using namespace Arccore;
936
937 {
939 const Int32 ref_value1 = 12;
940 const Int32 ref_value2 = 7;
941
942 c.resize(9, IntSubClassNoPod(ref_value1));
943 std::cout << "C1=" << c << "\n";
944 for (IntSubClassNoPod x : c)
945 ASSERT_EQ(x, ref_value1);
946
947 c.resize(21, IntSubClassNoPod(ref_value2));
948 ASSERT_EQ(c.size(), 21);
949 std::cout << "C2=" << c << "\n";
950
951 // Redimensionne sans initialiser. Les valeurs pour les éléments
952 // de 9 à 18 doivent valoir \a ref_value2
953 c.resizeNoInit(18);
954 std::cout << "C4=" << c << "\n";
955 for (Int32 i = 9, s = c.size(); i < s; ++i)
956 ASSERT_EQ(c[i], ref_value2);
957 for (Int32 i = 9, s = c.size(); i < s; ++i)
958 new (c.data() + i) IntSubClassNoPod(i + 2);
959 for (Int32 i = 9, s = c.size(); i < s; ++i)
960 ASSERT_EQ(c[i], (i + 2));
961 }
962 {
964 c2.resizeNoInit(25);
965 }
966}
967
968/*---------------------------------------------------------------------------*/
969/*---------------------------------------------------------------------------*/
970
971template <typename ArrayType>
973{
974 public:
975
976 static void doTestBase()
977 {
978 using namespace Arccore;
979
981 PrintableMemoryAllocator printable_allocator2;
982 IMemoryAllocator* allocator2 = &printable_allocator2;
983
984 {
985 std::cout << "Array a\n";
986 ArrayType a(allocator1);
987 ASSERT_EQ(a.allocator(), allocator1);
988 a.add(27);
989 a.add(38);
990 a.add(13);
991 a.add(-5);
992
993 std::cout << "Array b\n";
994 ArrayType b(allocator2);
995 ASSERT_EQ(b.capacity(), 0);
996 ASSERT_EQ(b.size(), 0);
997 ASSERT_EQ(b.allocator(), allocator2);
998
999 b = a;
1000 ASSERT_EQ(b.size(), a.size());
1001 ASSERT_EQ(b.allocator(), a.allocator());
1002
1003 std::cout << "Array c\n";
1004 ArrayType c(a.clone());
1005 ASSERT_EQ(c.allocator(), a.allocator());
1006 ASSERT_EQ(c.size(), a.size());
1007 ASSERT_EQ(c.constSpan(), a.constSpan());
1008
1009 std::cout << "Array d\n";
1010 ArrayType d(allocator2, a);
1011 ASSERT_EQ(d.allocator(), allocator2);
1012 ASSERT_EQ(d.size(), a.size());
1013 ASSERT_EQ(d.constSpan(), a.constSpan());
1014
1015 std::cout << "Array e\n";
1016 ArrayType e(allocator2, 25);
1017 ASSERT_EQ(e.allocator(), allocator2);
1018 ASSERT_EQ(e.size(), 25);
1019
1020 ArrayType f(allocator2);
1021 f = e;
1022 ASSERT_EQ(f.allocator(), e.allocator());
1023 ASSERT_EQ(f.size(), e.size());
1024
1025 f = f;
1026 ASSERT_EQ(f.allocator(), e.allocator());
1027 ASSERT_EQ(f.size(), e.size());
1028 }
1029 }
1030};
1031
1032TEST(UniqueArray, AllocatorBase)
1033{
1034 AllocatorTest<UniqueArray<Int32>>::doTestBase();
1035}
1036
1037TEST(SharedArray, AllocatorBase)
1038{
1039 AllocatorTest<SharedArray<Int32>>::doTestBase();
1040}
1041
1042/*---------------------------------------------------------------------------*/
1043/*---------------------------------------------------------------------------*/
1044
1046{
1047 using namespace Arccore;
1048 std::cout << "Sizeof(MemoryAllocationOptions)=" << sizeof(MemoryAllocationOptions) << "\n";
1049 std::cout << "Sizeof(ArrayMetaData)=" << sizeof(ArrayMetaData) << "\n";
1050 std::cout << "Sizeof(UniqueArray<Int32>)=" << sizeof(UniqueArray<Int32>) << "\n";
1051 std::cout << "Sizeof(SharedArray<Int32>)=" << sizeof(SharedArray<Int32>) << "\n";
1052
1053 PrintableMemoryAllocator printable_allocator;
1054 PrintableMemoryAllocator printable_allocator2;
1057 {
1058 std::cout << "Array a1\n";
1059 UniqueArray<Int32> a1(allocator2);
1060 ASSERT_EQ(a1.allocator(), allocator2);
1061 ASSERT_EQ(a1.size(), 0);
1062 ASSERT_EQ(a1.capacity(), 0);
1063 ASSERT_EQ(a1.data(), nullptr);
1064
1065 std::cout << "Array a2\n";
1066 UniqueArray<Int32> a2(a1);
1067 ASSERT_EQ(a1.allocator(), a2.allocator());
1068 ASSERT_EQ(a2.capacity(), 0);
1069 ASSERT_EQ(a2.data(), nullptr);
1070 a1.reserve(3);
1071 a1.add(5);
1072 a1.add(7);
1073 a1.add(12);
1074 a1.add(3);
1075 a1.add(1);
1076 ASSERT_EQ(a1.size(), 5);
1077
1078 std::cout << "Array a3\n";
1079 UniqueArray<Int32> a3(allocator1);
1080 a3.add(4);
1081 a3.add(6);
1082 a3.add(2);
1083 ASSERT_EQ(a3.size(), 3);
1084 a3 = a1;
1085 ASSERT_EQ(a3.allocator(), a1.allocator());
1086 ASSERT_EQ(a3.size(), a1.size());
1087 ASSERT_EQ(a3.constSpan(), a1.constSpan());
1088
1089 std::cout << "Array a4\n";
1090 UniqueArray<Int32> a4(allocator1);
1091 a4.add(4);
1092 a4.add(6);
1093 a4.add(2);
1094 ASSERT_EQ(a4.size(), 3);
1095 a4 = a1.span();
1096 ASSERT_EQ(a4.allocator(), allocator1);
1097
1098 a4 = UniqueArray<Int32>(&printable_allocator2);
1099
1100 UniqueArray<Int32> array[2];
1101 IMemoryAllocator* allocator3 = allocator1;
1102 for (Integer i = 0; i < 2; ++i) {
1103 array[i] = UniqueArray<Int32>(allocator3);
1104 }
1105 ASSERT_EQ(array[0].allocator(), allocator3);
1106 ASSERT_EQ(array[1].allocator(), allocator3);
1107 }
1108}
1109
1110/*---------------------------------------------------------------------------*/
1111/*---------------------------------------------------------------------------*/
1112
1114{
1115 using namespace Arccore;
1116 std::cout << "Sizeof(MemoryAllocationOptions)=" << sizeof(MemoryAllocationOptions) << "\n";
1117 std::cout << "Sizeof(ArrayMetaData)=" << sizeof(ArrayMetaData) << "\n";
1118 std::cout << "Sizeof(UniqueArray<Int32>)=" << sizeof(UniqueArray<Int32>) << "\n";
1119 std::cout << "Sizeof(SharedArray<Int32>)=" << sizeof(SharedArray<Int32>) << "\n";
1120
1121 PrintableMemoryAllocator printable_allocator;
1122 PrintableMemoryAllocator printable_allocator2;
1125 {
1126 std::cout << "Array a1\n";
1127 SharedArray<Int32> a1(allocator2);
1128 ASSERT_EQ(a1.allocator(), allocator2);
1129 ASSERT_EQ(a1.size(), 0);
1130 ASSERT_EQ(a1.capacity(), 0);
1131 ASSERT_EQ(a1.data(), nullptr);
1132
1133 std::cout << "Array a2\n";
1134 SharedArray<Int32> a2(a1);
1135 ASSERT_EQ(a1.allocator(), a2.allocator());
1136 ASSERT_EQ(a2.capacity(), 0);
1137 ASSERT_EQ(a2.data(), nullptr);
1138 a1.reserve(3);
1139 a1.add(5);
1140 a1.add(7);
1141 a1.add(12);
1142 a1.add(3);
1143 a1.add(1);
1144 ASSERT_EQ(a1.size(), 5);
1145
1146 std::cout << "Array a3\n";
1148 a3.add(4);
1149 a3.add(6);
1150 a3.add(2);
1151 ASSERT_EQ(a3.size(), 3);
1152 a3 = a1;
1153 ASSERT_EQ(a3.allocator(), a1.allocator());
1154 ASSERT_EQ(a3.size(), a1.size());
1155 ASSERT_EQ(a3.constSpan(), a1.constSpan());
1156
1157 std::cout << "Array a4\n";
1158 SharedArray<Int32> a4(allocator1, 2);
1159 ASSERT_EQ(a4.size(), 2);
1160 a4.add(4);
1161 a4.add(6);
1162 a4.add(2);
1163 ASSERT_EQ(a4.size(), 5);
1164 ASSERT_EQ(a4[2], 4);
1165 ASSERT_EQ(a4[3], 6);
1166 ASSERT_EQ(a4[4], 2);
1167
1168 a4 = a1.span();
1169 ASSERT_EQ(a4.allocator(), allocator1);
1170
1171 a4 = SharedArray<Int32>(&printable_allocator2);
1172
1173 SharedArray<Int32> array[2];
1174 IMemoryAllocator* allocator3 = allocator1;
1175 for (Integer i = 0; i < 2; ++i) {
1176 array[i] = SharedArray<Int32>(allocator3);
1177 }
1178 ASSERT_EQ(array[0].allocator(), allocator3);
1179 ASSERT_EQ(array[1].allocator(), allocator3);
1180 }
1181}
1182
1191: public IMemoryAllocator3
1192{
1193 public:
1194
1195 bool hasRealloc(MemoryAllocationArgs args) const override
1196 {
1197 _checkValid(args);
1198 return m_default_allocator.hasRealloc(args);
1199 }
1200 AllocatedMemoryInfo allocate(MemoryAllocationArgs args, Int64 new_size) override
1201 {
1202 _checkValid(args);
1203 return m_default_allocator.allocate(args, new_size);
1204 }
1205 AllocatedMemoryInfo reallocate(MemoryAllocationArgs args, AllocatedMemoryInfo current_ptr, Int64 new_size) override
1206 {
1207 _checkValid(args);
1208 return m_default_allocator.reallocate(args, current_ptr, new_size);
1209 }
1210 void deallocate(MemoryAllocationArgs args, AllocatedMemoryInfo ptr) override
1211 {
1212 _checkValid(args);
1213 m_default_allocator.deallocate(args, ptr);
1214 }
1215 Int64 adjustedCapacity(MemoryAllocationArgs args, Int64 wanted_capacity, Int64 element_size) const override
1216 {
1217 _checkValid(args);
1218 return m_default_allocator.adjustedCapacity(args, wanted_capacity, element_size);
1219 }
1220 size_t guaranteedAlignment(MemoryAllocationArgs args) const override
1221 {
1222 _checkValid(args);
1223 return m_default_allocator.guaranteedAlignment(args);
1224 }
1225
1226 void notifyMemoryArgsChanged(MemoryAllocationArgs old_args, MemoryAllocationArgs new_args, AllocatedMemoryInfo ptr) override
1227 {
1228 // Cette méthode n'est appelée qu'une seule fois donc on teste directement les valeurs attendues
1229 ASSERT_EQ(old_args.memoryLocationHint(), eMemoryLocationHint::None);
1230 ASSERT_EQ(new_args.memoryLocationHint(), eMemoryLocationHint::MainlyHost);
1231 ASSERT_EQ(ptr.size(), 8);
1232 m_default_allocator.notifyMemoryArgsChanged(old_args, new_args, ptr);
1233 }
1234
1235 private:
1236
1237 DefaultMemoryAllocator3 m_default_allocator;
1238
1239 private:
1240
1241 static void _checkValid(MemoryAllocationArgs args)
1242 {
1243 bool v1 = args.memoryLocationHint() == eMemoryLocationHint::None;
1244 bool v2 = args.memoryLocationHint() == eMemoryLocationHint::MainlyHost;
1245 bool v3 = args.memoryLocationHint() == eMemoryLocationHint::HostAndDeviceMostlyRead;
1246 bool is_valid = v1 || v2 || v3;
1247 ASSERT_TRUE(is_valid);
1248 }
1249};
1250
1251#define ASSERT_SAME_ARRAY_INFOS(a, b) \
1252 ASSERT_EQ(a.allocationOptions(), b.allocationOptions()); \
1253 ASSERT_EQ(a.size(), b.size()); \
1254 ASSERT_EQ(a.capacity(), b.capacity())
1255
1256TEST(Array, AllocatorV2)
1257{
1258 using namespace Arccore;
1259 TesterMemoryAllocatorV3 testerv2_allocator;
1260 TesterMemoryAllocatorV3 testerv2_allocator2;
1261 MemoryAllocationOptions allocate_options1(&testerv2_allocator, eMemoryLocationHint::HostAndDeviceMostlyRead);
1262 MemoryAllocationOptions allocate_options2(&testerv2_allocator, eMemoryLocationHint::None, 0);
1263 {
1264 MemoryAllocationOptions opt3(&testerv2_allocator);
1265 opt3.setMemoryLocationHint(eMemoryLocationHint::HostAndDeviceMostlyRead);
1266 ASSERT_EQ(opt3, allocate_options1);
1267 }
1268 {
1269 std::cout << "Array a1\n";
1270 UniqueArray<Int32> a1(allocate_options2);
1271 ASSERT_EQ(a1.allocationOptions(), allocate_options2);
1272 ASSERT_EQ(a1.size(), 0);
1273 ASSERT_EQ(a1.capacity(), 0);
1274 ASSERT_EQ(a1.data(), nullptr);
1275
1276 std::cout << "Array a2\n";
1277 UniqueArray<Int32> a2(a1);
1278 ASSERT_SAME_ARRAY_INFOS(a2, a1);
1279 ASSERT_EQ(a2.data(), nullptr);
1280 a1.reserve(3);
1281 a1.add(5);
1282 a1.add(7);
1283 a1.add(12);
1284 a1.add(3);
1285 a1.add(1);
1286 ASSERT_EQ(a1.size(), 5);
1287 a2.add(9);
1288 a2.add(17);
1289 // Pour tester notifyMemoryArgsChanged()
1290 a2.setMemoryLocationHint(eMemoryLocationHint::MainlyHost);
1291
1292 std::cout << "Array a3\n";
1293 UniqueArray<Int32> a3(allocate_options1);
1294 a3.add(4);
1295 a3.add(6);
1296 a3.add(2);
1297 ASSERT_EQ(a3.size(), 3);
1298 a3 = a1;
1299 ASSERT_EQ(a3.allocator(), a1.allocator());
1300 ASSERT_EQ(a3.size(), a1.size());
1301 ASSERT_EQ(a3.constSpan(), a1.constSpan());
1302
1303 std::cout << "Array a4\n";
1304 UniqueArray<Int32> a4(allocate_options1);
1305 a4.add(4);
1306 a4.add(6);
1307 a4.add(2);
1308 ASSERT_EQ(a4.size(), 3);
1309 a4 = a1.span();
1310 ASSERT_EQ(a4.allocationOptions(), allocate_options1);
1311
1312 a4 = UniqueArray<Int32>(&testerv2_allocator2);
1313
1314 UniqueArray<Int32> array[2];
1315 MemoryAllocationOptions allocator3 = allocate_options1;
1316 for (Integer i = 0; i < 2; ++i) {
1317 array[i] = UniqueArray<Int32>(allocator3);
1318 }
1319 ASSERT_EQ(array[0].allocationOptions(), allocator3);
1320 ASSERT_EQ(array[1].allocationOptions(), allocator3);
1321 }
1322}
1323
1324/*---------------------------------------------------------------------------*/
1325/*---------------------------------------------------------------------------*/
1326
1327TEST(Array, DebugInfo)
1328{
1329 using namespace Arccore;
1330 DefaultMemoryAllocator3 m_default_allocator;
1331 MemoryAllocationOptions allocate_options2(&m_default_allocator, eMemoryLocationHint::None, 0);
1332
1333 String a1_name("Array1");
1334 String sa1_name("SharedArray1");
1336 {
1337 std::cout << "Array a1\n";
1338 UniqueArray<Int32> a1(allocate_options2);
1339 a1.setDebugName(a1_name);
1340 ASSERT_EQ(a1.allocationOptions(), allocate_options2);
1341 ASSERT_EQ(a1.size(), 0);
1342 ASSERT_EQ(a1.capacity(), 0);
1343 ASSERT_EQ(a1.data(), nullptr);
1344 ASSERT_EQ(a1.debugName(), a1_name);
1345
1346 std::cout << "SharedArray sa1\n";
1347 SharedArray<Int32> sa1(allocate_options2);
1348 sa1.setDebugName(sa1_name);
1349 ASSERT_EQ(sa1.allocationOptions(), allocate_options2);
1350 ASSERT_EQ(sa1.size(), 0);
1351 ASSERT_EQ(sa1.capacity(), 0);
1352 ASSERT_EQ(sa1.data(), nullptr);
1353 ASSERT_EQ(sa1.debugName(), sa1_name);
1354
1355 ASSERT_EQ(a1.debugName(), a1_name);
1356
1357 std::cout << "Array a2\n";
1358 UniqueArray<Int32> a2(a1);
1359 ASSERT_SAME_ARRAY_INFOS(a2, a1);
1360 ASSERT_EQ(a2.data(), nullptr);
1361 ASSERT_EQ(a2.debugName(), a1_name);
1362 a1.reserve(3);
1363 a1.add(5);
1364 a1.add(7);
1365 a1.add(12);
1366 a1.add(3);
1367 a1.add(1);
1368 ASSERT_EQ(a1.size(), 5);
1369 a2.add(9);
1370 a2.add(17);
1371 ASSERT_EQ(a2.debugName(), a1_name);
1372 ASSERT_EQ(a2.size(), 2);
1373
1374 a3 = a2;
1375 }
1376 ASSERT_EQ(a3.debugName(), a1_name);
1377 ASSERT_EQ(a3.size(), 2);
1378}
1379
1380/*---------------------------------------------------------------------------*/
1381/*---------------------------------------------------------------------------*/
1382
1383TEST(Collections, Memory)
1384{
1385 using namespace Arccore;
1386 std::cout << eHostDeviceMemoryLocation::Unknown << " "
1391
1392 std::cout << eMemoryResource::Unknown << " "
1393 << eMemoryResource::Host << " "
1395 << eMemoryResource::Device << " "
1397
1402}
1403
1404/*---------------------------------------------------------------------------*/
1405/*---------------------------------------------------------------------------*/
1406
1407namespace Arcane
1408{
1409// Instancie explicitement les classes tableaux pour garantir
1410// que toutes les méthodes fonctionnent
1411template class UniqueArray<IntSubClass>;
1412template class SharedArray<IntSubClass>;
1413template class Array<IntSubClass>;
1414template class AbstractArray<IntSubClass>;
1415} // namespace Arcane
#define ASSERT_TRUE(condition)
Vérifie que condition est vrai.
Definition Assertion.h:125
String debugName() const
Nom de debug (nul si aucun nom spécifié).
Classe abstraite de base d'un vecteur.
void _internalSetHostDeviceMemoryLocation(eHostDeviceMemoryLocation location)
Positionne l'emplacement physique de la zone mémoire.
Integer size() const
Nombre d'éléments du vecteur.
ArrayIterator< pointer > iterator
Type de l'itérateur sur un élément du tableau.
eHostDeviceMemoryLocation hostDeviceMemoryLocation() const
Positionne l'emplacement physique de la zone mémoire.
ArrayIterator< const_pointer > const_iterator
Type de l'itérateur constant sur un élément du tableau.
static constexpr Integer simdAlignment()
Alignement pour les structures utilisant la vectorisation.
static AlignedMemoryAllocator * Simd()
Allocateur garantissant l'alignement pour utiliser la vectorisation sur la plateforme cible.
Informations sur une zone mémoire allouée.
Int64 size() const
Taille en octets de la zone mémoire utilisée. (-1) si inconnue.
Meta-Données des tableaux.
ConstIterT< ArrayView< T > > const_iter
Type d'un itérateur constant sur tout le tableau.
Tableau d'items de types quelconques.
iterator end()
Itérateur sur le premier élément après la fin du tableau.
ConstArrayView< T > constView() const
Vue constante sur ce tableau.
void remove(Int64 index)
Supprime l'entité ayant l'indice index.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
ArrayView< T > subView(Int64 abegin, Integer asize)
Sous-vue à partir de l'élément abegin et contenant asize éléments.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
reverse_iterator rbegin()
Itérateur inverse sur le premier élément du tableau.
T & at(Int64 i)
Elément d'indice i. Vérifie toujours les débordements.
void resizeNoInit(Int64 s)
Redimensionne sans initialiser les nouvelles valeurs.
ConstArrayView< T > subConstView(Int64 abegin, Int32 asize) const
Sous-vue à partir de l'élément abegin et contenant asize éléments.
SmallSpan< const T > smallSpan() const
Vue immutable sur ce tableau.
SmallSpan< const T > constSmallSpan() const
Vue immutable sur ce tableau.
void copy(Span< const T > rhs)
Copie les valeurs de rhs dans l'instance.
ArrayView< T > view() const
Vue mutable sur ce tableau.
Span< const T > span() const
Vue immutable sur ce tableau.
reverse_iterator rend()
Itérateur inverse sur le premier élément après la fin du tableau.
iterator begin()
Itérateur sur le premier élément du tableau.
Span< const T > constSpan() const
Vue constante sur ce tableau.
iterator erase(const_iterator pos)
Supprime l'élément à la position pos.
ArrayRange< pointer > range()
Intervalle d'itération du premier au dernièr élément.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
ConstIterT< ConstArrayView< T > > const_iter
Type d'un itérateur constant sur tout le tableau.
Classe de base d'une exception.
Interface d'un allocateur pour la mémoire.
Classe contenant des informations pour spécialiser les allocations.
Allocateur mémoire via malloc/realloc/free avec impression listing.
Vecteur 1D de données avec sémantique par référence.
SharedArray< T > clone() const
Clone le tableau.
Vue d'un tableau d'éléments de type T.
Definition Span.h:802
Chaîne de caractères unicode.
Vecteur 1D de données avec sémantique par valeur (style STL).
Allocateur pour tester les 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)
Échange les valeurs de v1 et v2.
Int32 Integer
Type représentant un entier.
@ MainlyHost
Indique que la donnée sera plutôt utilisée sur CPU.
@ HostAndDeviceMostlyRead
Indique que la donnée sera utilisée à la fois sur accélérateur et sur CPU et qu'elle ne sera pas souv...
@ Unknown
Localisation inconnue.
@ ManagedMemoryDevice
La mémoire est de la mémoire managée sur accélérateur.
@ Host
La mémoire est sur l'hôte.
@ ManagedMemoryHost
La mémoire est de la mémoire managée sur l'hôte.
@ Device
La mémoire est sur accélérateur.
@ HostPinned
Alloue sur l'hôte.
@ Unknown
Valeur inconnue ou non initialisée.
@ Host
Alloue sur l'hôte.
@ UnifiedMemory
Alloue en utilisant la mémoire unifiée.
@ Device
Alloue sur le device.
Espace de nom de Arccore.