Coverage Report

Created: 2024-07-18 11:41

test/zserio/AnyHolderTest.cpp
Line
Count
Source
1
#include <memory>
2
#include <tuple>
3
#include <vector>
4
5
#include "gtest/gtest.h"
6
#include "zserio/AnyHolder.h"
7
#include "zserio/pmr/MemoryResource.h"
8
#include "zserio/pmr/PolymorphicAllocator.h"
9
10
#include "TrackingAllocator.h"
11
12
namespace zserio
13
{
14
15
namespace
16
{
17
18
class SmallObject
19
{
20
public:
21
    SmallObject() :
22
            m_value(0)
23
2
    {}
24
25
    bool operator==(const SmallObject& other) const
26
52
    {
27
52
        return m_value == other.m_value;
28
52
    }
29
30
private:
31
    int m_value;
32
};
33
34
struct BigObject
35
{
36
10
    BigObject() = default;
37
38
    BigObject(NoInitT, const BigObject&)
39
13
    {}
40
41
    bool operator==(const BigObject& other) const
42
60
    {
43
60
        return std::tie(value1, value2, value3, value4) ==
44
60
                std::tie(other.value1, other.value2, other.value3, other.value4);
45
60
    }
46
47
    uint64_t value1 = 1;
48
    uint64_t value2 = 2;
49
    uint64_t value3 = 3;
50
    uint64_t value4 = 4;
51
};
52
53
} // namespace
54
55
class AnyHolderTest : public ::testing::Test
56
{
57
protected:
58
    template <typename T, typename ALLOC>
59
    void testAnyHolder(const T& value, const ALLOC& allocator)
60
8
    {
61
8
        testEmptyConstructor<ALLOC>();
62
8
        testAllocatorConstructor(allocator);
63
8
        testLvalueConstructor(value, allocator);
64
8
        testLvalueConstructorNoInit(value, allocator);
65
8
        testRvalueConstructor(value, allocator);
66
8
        testRvalueConstructorNoInit(value, allocator);
67
8
        testCopyConstructor(value, allocator);
68
8
        testCopyConstructorNoInit(value, allocator);
69
8
        testCopyConstructorWithAllocator(value, allocator);
70
8
        testCopyConstructorWithAllocatorNoInit(value, allocator);
71
8
        testCopyAssignmentOperator(value, allocator);
72
8
        testCopyAssignmentOperatorNoInit(value, allocator);
73
8
        testMoveConstructor(value, allocator);
74
8
        testMoveConstructorNoInit(value, allocator);
75
8
        testMoveConstructorWithAllocator(value, allocator);
76
8
        testMoveConstructorWithAllocatorNoInit(value, allocator);
77
8
        testMoveAssignmentOperator(value, allocator);
78
8
        testMoveAssignmentOperatorNoInit(value, allocator);
79
8
        testMoveAssignmentValueOperator(value, allocator);
80
8
        testReset(value, allocator);
81
8
        testSetGet(value, allocator);
82
8
        testIsType(value, allocator);
83
8
        testHasValue(value, allocator);
84
8
    }
85
86
private:
87
    template <typename ALLOC>
88
    void testEmptyConstructor()
89
8
    {
90
8
        AnyHolder<ALLOC> any;
91
8
        ASSERT_FALSE(any.hasValue());
92
8
    }
93
94
    template <typename ALLOC>
95
    void testAllocatorConstructor(const ALLOC& allocator)
96
8
    {
97
8
        AnyHolder<ALLOC> any(allocator);
98
8
        ASSERT_FALSE(any.hasValue());
99
8
        ASSERT_EQ(allocator, any.get_allocator());
100
8
    }
101
102
    template <typename T, typename ALLOC>
103
    void testLvalueConstructor(const T& value, const ALLOC& allocator)
104
8
    {
105
8
        const void* origAddress = &value;
106
8
        AnyHolder<ALLOC> any(value, allocator);
107
108
8
        const T& anyValue = any.template get<T>();
109
8
        ASSERT_NE(origAddress, &anyValue);
110
8
        ASSERT_EQ(value, anyValue);
111
8
    }
112
113
    template <typename T, typename ALLOC>
114
    void testLvalueConstructorNoInit(const T& value, const ALLOC& allocator)
115
8
    {
116
8
        const void* origAddress = &value;
117
8
        AnyHolder<ALLOC> any(NoInit, value, allocator);
118
119
8
        const T& anyValue = any.template get<T>();
120
8
        ASSERT_NE(origAddress, &anyValue);
121
8
        ASSERT_EQ(value, anyValue);
122
8
    }
123
124
    template <typename ALLOC>
125
    void testRvalueConstructor(const std::vector<int>& value, const ALLOC& allocator)
126
2
    {
127
2
        std::vector<int> origValue(value);
128
2
        const void* origAddress = origValue.data();
129
2
        AnyHolder<ALLOC> any(std::move(origValue), allocator);
130
131
2
        const std::vector<int>& anyValue = any.template get<std::vector<int>>();
132
2
        ASSERT_EQ(origAddress, anyValue.data());
133
2
        ASSERT_EQ(value, anyValue);
134
2
    }
135
136
    template <typename T, typename ALLOC>
137
    void testRvalueConstructor(const T& value, const ALLOC& allocator)
138
6
    {
139
6
        T origValue(value);
140
6
        AnyHolder<ALLOC> any(std::move(origValue), allocator);
141
142
6
        const T& anyValue = any.template get<T>();
143
6
        ASSERT_EQ(value, anyValue);
144
6
    }
145
146
    template <typename ALLOC>
147
    void testRvalueConstructorNoInit(const std::vector<int>& value, const ALLOC& allocator)
148
2
    {
149
2
        std::vector<int> origValue(value);
150
2
        const void* origAddress = origValue.data();
151
2
        AnyHolder<ALLOC> any(NoInit, std::move(origValue), allocator);
152
153
2
        const std::vector<int>& anyValue = any.template get<std::vector<int>>();
154
2
        ASSERT_EQ(origAddress, anyValue.data());
155
2
        ASSERT_EQ(value, anyValue);
156
2
    }
157
158
    template <typename T, typename ALLOC>
159
    void testRvalueConstructorNoInit(const T& value, const ALLOC& allocator)
160
6
    {
161
6
        T origValue(value);
162
6
        AnyHolder<ALLOC> any(NoInit, std::move(origValue), allocator);
163
164
6
        const T& anyValue = any.template get<T>();
165
6
        ASSERT_EQ(value, anyValue);
166
6
    }
167
168
    template <typename T, typename ALLOC>
169
    void testCopyConstructor(const T& value, const ALLOC& allocator)
170
8
    {
171
8
        AnyHolder<ALLOC> any(allocator);
172
173
        // copy empty holder
174
8
        AnyHolder<ALLOC> anyEmptyCopy(any);
175
8
        ASSERT_FALSE(anyEmptyCopy.hasValue());
176
177
        // copy filled holder
178
8
        any.set(value);
179
8
        AnyHolder<ALLOC> anyCopy(any);
180
8
        ASSERT_EQ(value, anyCopy.template get<T>());
181
8
    }
182
183
    template <typename T, typename ALLOC>
184
    void testCopyConstructorNoInit(const T& value, const ALLOC& allocator)
185
8
    {
186
8
        AnyHolder<ALLOC> any(allocator);
187
188
        // copy empty holder
189
8
        AnyHolder<ALLOC> anyEmptyCopy(NoInit, any);
190
8
        ASSERT_FALSE(anyEmptyCopy.hasValue());
191
192
        // copy filled holder
193
8
        any.set(value);
194
8
        AnyHolder<ALLOC> anyCopy(NoInit, any);
195
8
        ASSERT_EQ(value, anyCopy.template get<T>());
196
8
    }
197
198
    template <typename T, typename ALLOC>
199
    void testCopyConstructorWithAllocator(const T& value, const ALLOC& allocator)
200
8
    {
201
8
        AnyHolder<ALLOC> any(allocator);
202
203
        // copy empty holder
204
8
        AnyHolder<ALLOC> anyEmptyCopy(any);
205
8
        ASSERT_FALSE(anyEmptyCopy.hasValue());
206
207
        // copy filled holder
208
8
        any.set(value);
209
8
        const size_t numAllocations = allocator.numAllocs();
210
8
        const ALLOC newAllocator;
211
8
        AnyHolder<ALLOC> anyCopy(any, newAllocator);
212
8
        ASSERT_EQ(value, anyCopy.template get<T>());
213
8
        ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocation and deallocations in old allocator
214
8
    }
215
216
    template <typename T, typename ALLOC>
217
    void testCopyConstructorWithAllocatorNoInit(const T& value, const ALLOC& allocator)
218
8
    {
219
8
        AnyHolder<ALLOC> any(allocator);
220
221
        // copy empty holder
222
8
        AnyHolder<ALLOC> anyEmptyCopy(NoInit, any);
223
8
        ASSERT_FALSE(anyEmptyCopy.hasValue());
224
225
        // copy filled holder
226
8
        any.set(value);
227
8
        const size_t numAllocations = allocator.numAllocs();
228
8
        const ALLOC newAllocator;
229
8
        AnyHolder<ALLOC> anyCopy(NoInit, any, newAllocator);
230
8
        ASSERT_EQ(value, anyCopy.template get<T>());
231
8
        ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocation and deallocations in old allocator
232
8
    }
233
234
    template <typename T, typename ALLOC>
235
    void testCopyAssignmentOperator(const T& value, const ALLOC& allocator)
236
8
    {
237
8
        AnyHolder<ALLOC> any(allocator);
238
239
        // assignment empty holder
240
8
        AnyHolder<ALLOC> anyEmpty;
241
8
        anyEmpty = any;
242
8
        ASSERT_FALSE(anyEmpty.hasValue());
243
244
        // assignment filled holder to itself
245
8
        any.set(value);
246
8
        AnyHolder<ALLOC>& anyRef(any);
247
8
        anyRef = any;
248
8
        ASSERT_EQ(value, anyRef.template get<T>());
249
250
        // assignment filled holder
251
8
        AnyHolder<ALLOC> anyCopy;
252
8
        anyCopy = any;
253
8
        ASSERT_EQ(value, anyCopy.template get<T>());
254
8
    }
255
256
    template <typename T, typename ALLOC>
257
    void testCopyAssignmentOperatorNoInit(const T& value, const ALLOC& allocator)
258
8
    {
259
8
        AnyHolder<ALLOC> any(allocator);
260
261
        // assignment empty holder
262
8
        AnyHolder<ALLOC> anyEmpty;
263
8
        anyEmpty.assign(NoInit, any);
264
8
        ASSERT_FALSE(anyEmpty.hasValue());
265
266
        // assignment filled holder to itself
267
8
        any.set(value);
268
8
        AnyHolder<ALLOC>& anyRef(any);
269
8
        anyRef.assign(NoInit, any);
270
8
        ASSERT_EQ(value, anyRef.template get<T>());
271
272
        // assignment filled holder
273
8
        AnyHolder<ALLOC> anyCopy;
274
8
        anyCopy.assign(NoInit, any);
275
8
        ASSERT_EQ(value, anyCopy.template get<T>());
276
8
    }
277
278
    template <typename T, typename ALLOC>
279
    void testMoveConstructor(const T& value, const ALLOC& allocator)
280
8
    {
281
8
        {
282
            // move empty holder
283
8
            AnyHolder<ALLOC> any(allocator);
284
8
            AnyHolder<ALLOC> anyMove(std::move(any));
285
8
            ASSERT_FALSE(anyMove.hasValue());
286
8
        }
287
288
8
        {
289
            // move filled holder
290
8
            AnyHolder<ALLOC> any(allocator);
291
8
            any.set(value);
292
8
            const size_t numAllocations = allocator.numAllocs();
293
8
            AnyHolder<ALLOC> anyMove(std::move(any));
294
8
            ASSERT_EQ(value, anyMove.template get<T>());
295
8
            ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocations and deallocations
296
8
        }
297
8
    }
298
299
    template <typename T, typename ALLOC>
300
    void testMoveConstructorNoInit(const T& value, const ALLOC& allocator)
301
8
    {
302
8
        {
303
            // move empty holder
304
8
            AnyHolder<ALLOC> any(allocator);
305
8
            AnyHolder<ALLOC> anyMove(NoInit, std::move(any));
306
8
            ASSERT_FALSE(anyMove.hasValue());
307
8
        }
308
309
8
        {
310
            // move filled holder
311
8
            AnyHolder<ALLOC> any(allocator);
312
8
            any.set(value);
313
8
            const size_t numAllocations = allocator.numAllocs();
314
8
            AnyHolder<ALLOC> anyMove(NoInit, std::move(any));
315
8
            ASSERT_EQ(value, anyMove.template get<T>());
316
8
            ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocations and deallocations
317
8
        }
318
8
    }
319
320
    template <typename T, typename ALLOC>
321
    void testMoveConstructorWithAllocator(const T& value, const ALLOC& allocator)
322
8
    {
323
8
        {
324
            // empty holder with the same allocator
325
8
            AnyHolder<ALLOC> any(allocator);
326
8
            AnyHolder<ALLOC> anyMove(std::move(any));
327
8
            ASSERT_FALSE(anyMove.hasValue());
328
8
        }
329
330
8
        {
331
            // empty holder with the different allocator
332
8
            AnyHolder<ALLOC> any(allocator);
333
8
            const ALLOC newAllocator;
334
8
            AnyHolder<ALLOC> anyMove(std::move(any), newAllocator);
335
8
            ASSERT_FALSE(anyMove.hasValue());
336
8
        }
337
338
8
        {
339
            // filled holder with the same allocator
340
8
            AnyHolder<ALLOC> any(allocator);
341
8
            any.set(value);
342
8
            const size_t numAllocations = allocator.numAllocs();
343
8
            AnyHolder<ALLOC> anyMove(std::move(any), allocator);
344
8
            ASSERT_EQ(value, anyMove.template get<T>());
345
8
            ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocations and deallocations
346
8
        }
347
348
8
        {
349
            // filled holder with the different allocator
350
8
            AnyHolder<ALLOC> any(allocator);
351
8
            any.set(value);
352
8
            const size_t numAllocations = allocator.numAllocs();
353
8
            const ALLOC newAllocator;
354
8
            AnyHolder<ALLOC> anyMove(std::move(any), newAllocator);
355
8
            ASSERT_EQ(value, anyMove.template get<T>());
356
8
            ASSERT_TRUE(numAllocations >= allocator.numAllocs()); // no furher allocations
357
8
        }
358
8
    }
359
360
    template <typename T, typename ALLOC>
361
    void testMoveConstructorWithAllocatorNoInit(const T& value, const ALLOC& allocator)
362
8
    {
363
8
        {
364
            // empty holder with the same allocator
365
8
            AnyHolder<ALLOC> any(allocator);
366
8
            AnyHolder<ALLOC> anyMove(NoInit, std::move(any));
367
8
            ASSERT_FALSE(anyMove.hasValue());
368
8
        }
369
370
8
        {
371
            // empty holder with the different allocator
372
8
            AnyHolder<ALLOC> any(allocator);
373
8
            const ALLOC newAllocator;
374
8
            AnyHolder<ALLOC> anyMove(NoInit, std::move(any), newAllocator);
375
8
            ASSERT_FALSE(anyMove.hasValue());
376
8
        }
377
378
8
        {
379
            // filled holder with the same allocator
380
8
            AnyHolder<ALLOC> any(allocator);
381
8
            any.set(value);
382
8
            const size_t numAllocations = allocator.numAllocs();
383
8
            AnyHolder<ALLOC> anyMove(NoInit, std::move(any), allocator);
384
8
            ASSERT_EQ(value, anyMove.template get<T>());
385
8
            ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocations and deallocations
386
8
        }
387
388
8
        {
389
            // filled holder with the different allocator
390
8
            AnyHolder<ALLOC> any(allocator);
391
8
            any.set(value);
392
8
            const size_t numAllocations = allocator.numAllocs();
393
8
            const ALLOC newAllocator;
394
8
            AnyHolder<ALLOC> anyMove(NoInit, std::move(any), newAllocator);
395
8
            ASSERT_EQ(value, anyMove.template get<T>());
396
8
            ASSERT_TRUE(numAllocations >= allocator.numAllocs()); // no furher allocations
397
8
        }
398
8
    }
399
400
    template <typename T, typename ALLOC>
401
    void testMoveAssignmentOperator(const T& value, const ALLOC& allocator)
402
8
    {
403
8
        {
404
            // assignment empty holder
405
8
            AnyHolder<ALLOC> any(allocator);
406
8
            AnyHolder<ALLOC> anyMove;
407
8
            anyMove = std::move(any);
408
8
            ASSERT_FALSE(anyMove.hasValue());
409
8
        }
410
411
8
        {
412
            // assignment filled holder to itself
413
8
            AnyHolder<ALLOC> any(allocator);
414
8
            any.set(value);
415
8
            const size_t numAllocations = allocator.numAllocs();
416
8
            AnyHolder<ALLOC>& anyRef = any;
417
8
            anyRef = std::move(any);
418
8
            ASSERT_EQ(value, anyRef.template get<T>());
419
8
            ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocations and deallocations
420
8
        }
421
422
8
        {
423
            // assignment filled holder
424
8
            AnyHolder<ALLOC> any(allocator);
425
8
            any.set(value);
426
8
            const size_t numAllocations = allocator.numAllocs();
427
8
            AnyHolder<ALLOC> anyMove;
428
8
            anyMove = std::move(any);
429
8
            ASSERT_EQ(value, anyMove.template get<T>());
430
8
            ASSERT_TRUE(numAllocations >= allocator.numAllocs()); // no furher allocations
431
8
        }
432
8
    }
433
434
    template <typename T, typename ALLOC>
435
    void testMoveAssignmentOperatorNoInit(const T& value, const ALLOC& allocator)
436
8
    {
437
8
        {
438
            // assignment empty holder
439
8
            AnyHolder<ALLOC> any(allocator);
440
8
            AnyHolder<ALLOC> anyMove;
441
8
            anyMove.assign(NoInit, std::move(any));
442
8
            ASSERT_FALSE(anyMove.hasValue());
443
8
        }
444
445
8
        {
446
            // assignment filled holder to itself
447
8
            AnyHolder<ALLOC> any(allocator);
448
8
            any.set(value);
449
8
            const size_t numAllocations = allocator.numAllocs();
450
8
            AnyHolder<ALLOC>& anyRef = any;
451
8
            anyRef.assign(NoInit, std::move(any));
452
8
            ASSERT_EQ(value, anyRef.template get<T>());
453
8
            ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocations and deallocations
454
8
        }
455
456
8
        {
457
            // assignment filled holder
458
8
            AnyHolder<ALLOC> any(allocator);
459
8
            any.set(value);
460
8
            const size_t numAllocations = allocator.numAllocs();
461
8
            AnyHolder<ALLOC> anyMove;
462
8
            anyMove.assign(NoInit, std::move(any));
463
8
            ASSERT_EQ(value, anyMove.template get<T>());
464
8
            ASSERT_TRUE(numAllocations >= allocator.numAllocs()); // no furher allocations
465
8
        }
466
8
    }
467
468
    template <typename T, typename ALLOC>
469
    void testMoveAssignmentValueOperator(const T& value, const ALLOC& allocator)
470
8
    {
471
8
        {
472
            // assignment empty holder
473
8
            const T valueCopy(value);
474
8
            AnyHolder<ALLOC> any(allocator);
475
8
            const size_t numAllocations = allocator.numAllocs();
476
8
            AnyHolder<ALLOC> anyMove;
477
8
            anyMove = std::move(valueCopy);
478
8
            ASSERT_EQ(value, anyMove.template get<T>());
479
8
            ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocations and deallocations
480
8
        }
481
482
8
        {
483
            // assignment filled holder
484
8
            const T valueCopy(value);
485
8
            AnyHolder<ALLOC> any(allocator);
486
8
            any.set(value);
487
8
            const size_t numAllocations = allocator.numAllocs();
488
8
            AnyHolder<ALLOC> anyMove;
489
8
            anyMove = std::move(valueCopy);
490
8
            ASSERT_EQ(value, anyMove.template get<T>());
491
8
            ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocations and deallocations
492
8
        }
493
8
    }
494
495
    template <typename T, typename ALLOC>
496
    void testReset(const T& value, const ALLOC& allocator)
497
8
    {
498
8
        AnyHolder<ALLOC> any(value, allocator);
499
8
        ASSERT_TRUE(any.hasValue());
500
501
8
        any.reset();
502
8
        ASSERT_FALSE(any.hasValue());
503
504
8
        any = value;
505
8
        ASSERT_TRUE(any.hasValue());
506
8
        ASSERT_EQ(value, any.template get<T>());
507
8
    }
508
509
    template <typename T, typename ALLOC>
510
    void testSetGet(const T& value, const ALLOC& allocator)
511
8
    {
512
8
        AnyHolder<ALLOC> any(allocator);
513
8
        ASSERT_THROW(any.template get<int>(), zserio::CppRuntimeException);
514
515
8
        any.set(value);
516
8
        ASSERT_EQ(value, any.template get<T>());
517
518
8
        const int intValue = 0xDEAD;
519
8
        any.set(intValue);
520
8
        ASSERT_EQ(intValue, any.template get<int>());
521
8
        ASSERT_THROW(any.template get<float>(), CppRuntimeException);
522
523
8
        const float floatValue = 3.14F;
524
8
        any.set(floatValue);
525
8
        ASSERT_THROW(any.template get<int>(), CppRuntimeException);
526
8
        ASSERT_EQ(floatValue, any.template get<float>());
527
528
8
        const BigObject bigObjectValue;
529
8
        any.set(bigObjectValue);
530
8
        ASSERT_THROW(any.template get<int>(), CppRuntimeException);
531
8
        ASSERT_EQ(bigObjectValue, any.template get<BigObject>());
532
8
    }
533
534
    template <typename T, typename ALLOC>
535
    void testIsType(const T& value, const ALLOC& allocator)
536
8
    {
537
8
        AnyHolder<ALLOC> any(allocator);
538
8
        ASSERT_FALSE(any.template isType<int>());
539
540
8
        any.set(value);
541
8
        ASSERT_TRUE(any.template isType<T>());
542
543
8
        const int intValue = 0xDEAD;
544
8
        any.set(intValue);
545
8
        ASSERT_TRUE(any.template isType<int>());
546
547
8
        const float floatValue = 3.14F;
548
8
        any.set(floatValue);
549
8
        ASSERT_TRUE(any.template isType<float>());
550
8
        ASSERT_FALSE(any.template isType<int>());
551
8
    }
552
553
    template <typename T, typename ALLOC>
554
    void testHasValue(const T& value, const ALLOC& allocator)
555
8
    {
556
8
        AnyHolder<ALLOC> any(allocator);
557
8
        ASSERT_FALSE(any.hasValue());
558
559
8
        any.set(value);
560
8
        ASSERT_TRUE(any.hasValue());
561
562
8
        const int intValue = 0xDEAD;
563
8
        any.set(intValue);
564
8
        ASSERT_TRUE(any.hasValue());
565
566
8
        any.reset();
567
8
        ASSERT_FALSE(any.hasValue());
568
8
    }
569
};
570
571
TEST_F(AnyHolderTest, integerPropagatingAllocator)
572
1
{
573
1
    const int value = 0xDEAD;
574
1
    const TrackingAllocator<uint8_t> allocator;
575
1
    testAnyHolder(value, allocator);
576
1
}
577
578
TEST_F(AnyHolderTest, integerNonPropagatingAllocator)
579
1
{
580
1
    const int value = 0xDEAD;
581
1
    const TrackingAllocatorNonProp<uint8_t> allocator;
582
1
    testAnyHolder(value, allocator);
583
1
}
584
585
TEST_F(AnyHolderTest, vectorPropagatingAllocator)
586
1
{
587
1
    const std::vector<int> value{1, 2, 3};
588
1
    const TrackingAllocator<uint8_t> allocator;
589
1
    testAnyHolder(value, allocator);
590
1
}
591
592
TEST_F(AnyHolderTest, vectorNonPropagatingAllocator)
593
1
{
594
1
    const std::vector<int> value{1, 2, 3};
595
1
    const TrackingAllocatorNonProp<uint8_t> allocator;
596
1
    testAnyHolder(value, allocator);
597
1
}
598
599
TEST_F(AnyHolderTest, smallObjectPropagatingAllocator)
600
1
{
601
1
    const SmallObject value;
602
1
    const TrackingAllocator<uint8_t> allocator;
603
1
    testAnyHolder(value, allocator);
604
1
}
605
606
TEST_F(AnyHolderTest, smallObjectNonPropagatingAllocator)
607
1
{
608
1
    const SmallObject value;
609
1
    const TrackingAllocatorNonProp<uint8_t> allocator;
610
1
    testAnyHolder(value, allocator);
611
1
}
612
613
TEST_F(AnyHolderTest, bigObjectPropagatingAllocator)
614
1
{
615
1
    const BigObject value;
616
1
    const TrackingAllocator<uint8_t> allocator;
617
1
    testAnyHolder(value, allocator);
618
1
}
619
620
TEST_F(AnyHolderTest, bigObjectNonPropagatingAllocator)
621
1
{
622
1
    const BigObject value;
623
1
    const TrackingAllocatorNonProp<uint8_t> allocator;
624
1
    testAnyHolder(value, allocator);
625
1
}
626
627
TEST_F(AnyHolderTest, unexceptedCallsHeapHolder)
628
1
{
629
1
    const TrackingAllocator<uint8_t> allocator;
630
1
    detail::HeapHolder<BigObject, TrackingAllocator<uint8_t>>* holder =
631
1
            detail::HeapHolder<BigObject, TrackingAllocator<uint8_t>>::create(allocator);
632
1
    ASSERT_THROW(holder->clone(nullptr), CppRuntimeException);
633
1
    ASSERT_THROW(holder->clone(NoInit, nullptr), CppRuntimeException);
634
1
    ASSERT_THROW(holder->move(nullptr), CppRuntimeException);
635
1
    ASSERT_THROW(holder->move(NoInit, nullptr), CppRuntimeException);
636
1
    holder->destroy(allocator);
637
1
}
638
639
TEST_F(AnyHolderTest, unexceptedCallsNonHeapHolder)
640
1
{
641
1
    const TrackingAllocator<uint8_t> allocator;
642
1
    using MaxInPlaceType = std::aligned_storage<3 * sizeof(void*), alignof(void*)>::type;
643
1
    MaxInPlaceType inPlace = MaxInPlaceType();
644
1
    detail::NonHeapHolder<uint8_t, TrackingAllocator<uint8_t>>* holder =
645
1
            detail::NonHeapHolder<uint8_t, TrackingAllocator<uint8_t>>::create(&inPlace);
646
1
    ASSERT_THROW(holder->clone(allocator), CppRuntimeException);
647
1
    ASSERT_THROW(holder->clone(NoInit, allocator), CppRuntimeException);
648
1
    ASSERT_THROW(holder->move(allocator), CppRuntimeException);
649
1
    ASSERT_THROW(holder->move(NoInit, allocator), CppRuntimeException);
650
1
    holder->destroy(allocator);
651
1
}
652
653
} // namespace zserio