OpenShot Audio Library | OpenShotAudio 0.3.2
Loading...
Searching...
No Matches
juce_ArrayBase.cpp
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2018 - ROLI Ltd.
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
26#if JUCE_UNIT_TESTS
27
28namespace ArrayBaseTestsHelpers
29{
31 {
32 public:
33 TriviallyCopyableType() = default;
34
35 TriviallyCopyableType (int v)
36 : value (v)
37 {}
38
39 TriviallyCopyableType (float v)
40 : value ((int) v)
41 {}
42
43 bool operator== (const TriviallyCopyableType& other) const
44 {
45 return getValue() == other.getValue();
46 }
47
48 int getValue() const { return value; }
49
50 private:
51 int value { -1111 };
52 };
53
55 {
56 public:
57 NonTriviallyCopyableType() = default;
58
59 NonTriviallyCopyableType (int v)
60 : value (v)
61 {}
62
63 NonTriviallyCopyableType (float v)
64 : value ((int) v)
65 {}
66
67 NonTriviallyCopyableType (const NonTriviallyCopyableType& other)
68 : value (other.value)
69 {}
70
71 NonTriviallyCopyableType& operator= (const NonTriviallyCopyableType& other)
72 {
73 value = other.value;
74 return *this;
75 }
76
77 bool operator== (const NonTriviallyCopyableType& other) const
78 {
79 return getValue() == other.getValue();
80 }
81
82 int getValue() const { return *ptr; }
83
84 private:
85 int value { -1111 };
86 int* ptr = &value;
87 };
88}
89
90bool operator== (const ArrayBaseTestsHelpers::TriviallyCopyableType& tct,
91 const ArrayBaseTestsHelpers::NonTriviallyCopyableType& ntct)
92{
93 return tct.getValue() == ntct.getValue();
94}
95
96bool operator== (const ArrayBaseTestsHelpers::NonTriviallyCopyableType& ntct,
97 const ArrayBaseTestsHelpers::TriviallyCopyableType& tct)
98{
99 return tct == ntct;
100}
101
102class ArrayBaseTests : public UnitTest
103{
104 using CopyableType = ArrayBaseTestsHelpers::TriviallyCopyableType;
105 using NoncopyableType = ArrayBaseTestsHelpers::NonTriviallyCopyableType;
106
107 #if ! (defined(__GNUC__) && __GNUC__ < 5 && ! defined(__clang__))
108 static_assert (std::is_trivially_copyable<CopyableType>::value,
109 "Test TriviallyCopyableType is not trivially copyable");
110 static_assert (! std::is_trivially_copyable<NoncopyableType>::value,
111 "Test NonTriviallyCopyableType is trivially copyable");
112 #endif
113
114public:
116 : UnitTest ("ArrayBase", UnitTestCategories::containers)
117 {}
118
119 void runTest() override
120 {
121 beginTest ("grow capacity");
122 {
123 std::vector<CopyableType> referenceContainer;
126
128
129 int originalCapacity = 4;
130 referenceContainer.reserve ((size_t) originalCapacity);
131 expectEquals ((int) referenceContainer.capacity(), originalCapacity);
132 copyableContainer.setAllocatedSize (originalCapacity);
133 expectEquals (copyableContainer.capacity(), originalCapacity);
134 noncopyableContainer.setAllocatedSize (originalCapacity);
135 expectEquals (noncopyableContainer.capacity(), originalCapacity);
136
138
140
142
143 expect ((int) referenceContainer.capacity() != originalCapacity);
144 expect (copyableContainer.capacity() != originalCapacity);
145 expect (noncopyableContainer.capacity() != originalCapacity);
146 }
147
148 beginTest ("shrink capacity");
149 {
150 std::vector<CopyableType> referenceContainer;
153
154 int numElements = 45;
156
157 copyableContainer.shrinkToNoMoreThan (numElements);
158 noncopyableContainer.setAllocatedSize (numElements + 1);
159
161
162 referenceContainer.clear();
163 copyableContainer.removeElements (0, numElements);
164 noncopyableContainer.removeElements (0, numElements);
165
167
168 copyableContainer.setAllocatedSize (0);
169 noncopyableContainer.setAllocatedSize (0);
170
172
174
176 }
177
178 beginTest ("equality");
179 {
180 std::vector<int> referenceContainer = { 1, 2, 3 };
182
183 for (auto i : referenceContainer)
184 {
185 testContainer1.add (i);
186 testContainer2.add (i);
187 }
188
190 expect (testContainer2 == testContainer1);
191
192 testContainer1.ensureAllocatedSize (257);
193 referenceContainer.shrink_to_fit();
194
196 expect (testContainer2 == testContainer1);
197
198 testContainer1.removeElements (0, 1);
199
201 expect (testContainer2 != testContainer1);
202 }
203
204 beginTest ("accessors");
205 {
206 std::vector<CopyableType> referenceContainer;
209
211
212 int testValue = -123;
216
218
219 expect (copyableContainer .getFirst().getValue() == testValue);
220 expect (noncopyableContainer.getFirst().getValue() == testValue);
221
222 auto last = referenceContainer.back().getValue();
223
224 expectEquals (copyableContainer .getLast().getValue(), last);
225 expectEquals (noncopyableContainer.getLast().getValue(), last);
226
229
230 auto defualtValue = CopyableType().getValue();
231 expectEquals (defualtValue, NoncopyableType().getValue());
232
233 expectEquals (copyableEmpty .getFirst().getValue(), defualtValue);
234 expectEquals (noncopyableEmpty.getFirst().getValue(), defualtValue);
235 expectEquals (copyableEmpty .getLast() .getValue(), defualtValue);
236 expectEquals (noncopyableEmpty.getLast() .getValue(), defualtValue);
237
239 expect (floatPointers.getValueWithDefault (-3) == nullptr);
240 }
241
242 beginTest ("add moved");
243 {
244 std::vector<CopyableType> referenceContainer;
247
248 for (int i = 0; i < 5; ++i)
249 {
250 CopyableType ref (-i);
251 CopyableType ct (-i);
252 NoncopyableType nct (-i);
253 referenceContainer.push_back (std::move (ref));
254 copyableContainer.add (std::move (ct));
255 noncopyableContainer.add (std::move (nct));
256 }
257
259 }
260
261 beginTest ("add multiple");
262 {
263 std::vector<CopyableType> referenceContainer;
266
267 for (int i = 4; i < 7; ++i)
268 referenceContainer.push_back ({ -i });
269
272
274 }
275
276 beginTest ("add array from a pointer");
277 {
280
281 std::vector<CopyableType> copyableData = { 3, 4, 5 };
282 std::vector<NoncopyableType> noncopyableData = { 3, 4, 5 };
283
284 copyableContainer.addArray (copyableData.data(), (int) copyableData.size());
285 noncopyableContainer.addArray (noncopyableData.data(), (int) noncopyableData.size());
286
288 }
289
290 beginTest ("add array from a pointer of a different type");
291 {
292 std::vector<CopyableType> referenceContainer;
295
296 std::vector<float> floatData = { 1.4f, 2.5f, 3.6f };
297
298 for (auto f : floatData)
300
301 copyableContainer.addArray (floatData.data(), (int) floatData.size());
302 noncopyableContainer.addArray (floatData.data(), (int) floatData.size());
303
305 }
306
307 beginTest ("add array from initializer_list");
308 {
309 std::vector<CopyableType> referenceContainer;
312
313 std::initializer_list<CopyableType> ilct { { 3 }, { 4 }, { 5 } };
314 std::initializer_list<NoncopyableType> ilnct { { 3 }, { 4 }, { 5 } };
315
316 for (auto v : ilct)
318
319 copyableContainer.addArray (ilct);
320 noncopyableContainer.addArray (ilnct);
321
323 }
324
325 beginTest ("add array from containers");
326 {
327 std::vector<CopyableType> referenceContainer;
330
332
333 std::vector<CopyableType> referenceContainerCopy (referenceContainer);
334 std::vector<NoncopyableType> noncopyableReferenceContainerCopy;
337
338 for (auto& v : referenceContainerCopy)
340
341 for (size_t i = 0; i < referenceContainerCopy.size(); ++i)
342 {
343 auto value = referenceContainerCopy[i].getValue();
344 copyableContainerCopy.add ({ value });
345 noncopyableContainerCopy.add ({ value });
346 }
347
348 // From self-types
351
352 for (auto v : referenceContainerCopy)
354
356
357 // From std containers
360
361 for (auto v : referenceContainerCopy)
363
365
366 // From std containers with offset
367 int offset = 5;
368 copyableContainer.addArray (referenceContainerCopy, offset);
370
371 for (size_t i = 5; i < referenceContainerCopy.size(); ++i)
373
375 }
376
377 beginTest ("insert");
378 {
379 std::vector<CopyableType> referenceContainer;
382
384
385 referenceContainer.insert (referenceContainer.begin(), -4);
386 copyableContainer.insert (0, -4, 1);
387 noncopyableContainer.insert (0, -4, 1);
388
390
391 for (int i = 0; i < 3; ++i)
392 referenceContainer.insert (referenceContainer.begin() + 1, -3);
393
394 copyableContainer.insert (1, -3, 3);
395 noncopyableContainer.insert (1, -3, 3);
396
398
399 for (int i = 0; i < 50; ++i)
400 referenceContainer.insert (referenceContainer.end() - 1, -9);
401
402 copyableContainer.insert (copyableContainer.size() - 2, -9, 50);
403 noncopyableContainer.insert (noncopyableContainer.size() - 2, -9, 50);
404 }
405
406 beginTest ("insert array");
407 {
410
411 std::vector<CopyableType> copyableData = { 3, 4, 5, 6, 7, 8 };
412 std::vector<NoncopyableType> noncopyableData = { 3, 4, 5, 6, 7, 8 };
413
414 std::vector<CopyableType> referenceContainer { copyableData };
415
416 copyableContainer.insertArray (0, copyableData.data(), (int) copyableData.size());
417 noncopyableContainer.insertArray (0, noncopyableData.data(), (int) noncopyableData.size());
418
420
421 int insertPos = copyableContainer.size() - 1;
422
423 for (auto it = copyableData.end(); it != copyableData.begin(); --it)
425
426 copyableContainer.insertArray (insertPos, copyableData.data(), (int) copyableData.size());
427 noncopyableContainer.insertArray (insertPos, noncopyableData.data(), (int) noncopyableData.size());
428
430 }
431
432 beginTest ("remove");
433 {
434 std::vector<CopyableType> referenceContainer;
437
439
440 for (int i = 0; i < 4; ++i)
441 {
442 referenceContainer.erase (referenceContainer.begin() + i);
443 copyableContainer.removeElements (i, 1);
444 noncopyableContainer.removeElements (i, 1);
445 }
446
448
450 int blockSize = 3;
451
452 for (int i = 0; i < 4; ++i)
453 {
454 for (int j = 0; j < blockSize; ++j)
455 referenceContainer.erase (referenceContainer.begin() + i);
456
457 copyableContainer.removeElements (i, blockSize);
458 noncopyableContainer.removeElements (i, blockSize);
459 }
460
462
463 auto numToRemove = copyableContainer.size() - 2;
464
465 for (int i = 0; i < numToRemove; ++i)
466 referenceContainer.erase (referenceContainer.begin() + 1);
467
468 copyableContainer.removeElements (1, numToRemove);
469 noncopyableContainer.removeElements (1, numToRemove);
470
472 }
473
474 beginTest ("move");
475 {
476 std::vector<CopyableType> referenceContainer;
479
481
482 std::vector<std::pair<int, int>> testValues;
483 testValues.emplace_back (2, 4);
484 testValues.emplace_back (0, 5);
485 testValues.emplace_back (4, 1);
486 testValues.emplace_back (5, 0);
487
488 for (auto p : testValues)
489 {
490 if (p.second > p.first)
491 std::rotate (referenceContainer.begin() + p.first,
492 referenceContainer.begin() + p.first + 1,
493 referenceContainer.begin() + p.second + 1);
494 else
495 std::rotate (referenceContainer.begin() + p.second,
496 referenceContainer.begin() + p.first,
497 referenceContainer.begin() + p.first + 1);
498
499 copyableContainer.move (p.first, p.second);
500 noncopyableContainer.move (p.first, p.second);
501
503 }
504 }
505
506 beginTest ("After converting move construction, ownership is transferred");
507 {
508 Derived obj;
510 derived.setAllocatedSize (5);
511 derived.add (&obj);
512
514
515 expectEquals (base.capacity(), 5);
516 expectEquals (base.size(), 1);
517 expect (base.getFirst() == &obj);
518 expectEquals (derived.capacity(), 0);
519 expectEquals (derived.size(), 0);
520 expect (derived.data() == nullptr);
521 }
522
523 beginTest ("After converting move assignment, ownership is transferred");
524 {
525 Derived obj;
527 derived.setAllocatedSize (5);
528 derived.add (&obj);
530
531 base = std::move (derived);
532
533 expectEquals (base.capacity(), 5);
534 expectEquals (base.size(), 1);
535 expect (base.getFirst() == &obj);
536 expectEquals (derived.capacity(), 0);
537 expectEquals (derived.size(), 0);
538 expect (derived.data() == nullptr);
539 }
540 }
541
542private:
543 struct Base
544 {
545 virtual ~Base() = default;
546 };
547
548 struct Derived : Base
549 {
550 };
551
552 static void addData (std::vector<CopyableType>& referenceContainer,
555 int numValues)
556 {
557 for (int i = 0; i < numValues; ++i)
558 {
559 referenceContainer.push_back ({ i });
560 copyableContainer.add ({ i });
561 NoncopyableContainer.add ({ i });
562 }
563 }
564
565 template<typename A, typename B>
568 {
569 expectEquals ((int) a.size(), (int) b.size());
570
571 for (int i = 0; i < (int) a.size(); ++i)
572 expect (a[i] == b[i]);
573 }
574
575 template<typename A, typename B>
577 std::vector<B>& b)
578 {
579 expectEquals ((int) a.size(), (int) b.size());
580
581 for (int i = 0; i < (int) a.size(); ++i)
582 expect (a[i] == b[(size_t) i]);
583 }
584
585 template<typename A, typename B, typename C>
588 std::vector<C>& c)
589 {
590 checkEqual (a, b);
591 checkEqual (a, c);
592 checkEqual (b, c);
593 }
594};
595
596static ArrayBaseTests arrayBaseTests;
597
598#endif
599
600} // namespace juce
ElementType getFirst() const noexcept
Definition juce_Array.h:290
Array()=default
ElementType getLast() const noexcept
Definition juce_Array.h:300