GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: test/zserio/AnyHolderTest.cpp Lines: 354 354 100.0 %
Date: 2023-12-13 14:51:09 Branches: 3732 12420 30.0 %

Line Branch Exec Source
1
#include <vector>
2
#include <memory>
3
#include <tuple>
4
5
#include "zserio/AnyHolder.h"
6
#include "zserio/pmr/MemoryResource.h"
7
#include "zserio/pmr/PolymorphicAllocator.h"
8
9
#include "TrackingAllocator.h"
10
11
#include "gtest/gtest.h"
12
13
namespace zserio
14
{
15
16
namespace
17
{
18
19
class SmallObject
20
{
21
public:
22
2
    SmallObject() : m_value(0) {}
23
24
52
    bool operator==(const SmallObject& other) const { return m_value == other.m_value; }
25
26
private:
27
    int m_value;
28
};
29
30
struct BigObject
31
{
32
    BigObject() = default;
33
34
13
    BigObject(NoInitT, const BigObject&) {}
35
36
60
    bool operator==(const BigObject& other) const
37
    {
38
120
        return std::tie(value1, value2, value3, value4) ==
39
180
                std::tie(other.value1, other.value2, other.value3, other.value4);
40
    }
41
42
    uint64_t value1 = 1;
43
    uint64_t value2 = 2;
44
    uint64_t value3 = 3;
45
    uint64_t value4 = 4;
46
};
47
48
} // namespace
49
50
20
class AnyHolderTest : public ::testing::Test
51
{
52
protected:
53
    template <typename T, typename ALLOC>
54
8
    void testAnyHolder(const T& value, const ALLOC& allocator)
55
    {
56
8
        testEmptyConstructor<ALLOC>();
57
8
        testAllocatorConstructor(allocator);
58
8
        testLvalueConstructor(value, allocator);
59
8
        testLvalueConstructorNoInit(value, allocator);
60
8
        testRvalueConstructor(value, allocator);
61
8
        testRvalueConstructorNoInit(value, allocator);
62
8
        testCopyConstructor(value, allocator);
63
8
        testCopyConstructorNoInit(value, allocator);
64
8
        testCopyConstructorWithAllocator(value, allocator);
65
8
        testCopyConstructorWithAllocatorNoInit(value, allocator);
66
8
        testCopyAssignmentOperator(value, allocator);
67
8
        testCopyAssignmentOperatorNoInit(value, allocator);
68
8
        testMoveConstructor(value, allocator);
69
8
        testMoveConstructorNoInit(value, allocator);
70
8
        testMoveConstructorWithAllocator(value, allocator);
71
8
        testMoveConstructorWithAllocatorNoInit(value, allocator);
72
8
        testMoveAssignmentOperator(value, allocator);
73
8
        testMoveAssignmentOperatorNoInit(value, allocator);
74
8
        testMoveAssignmentValueOperator(value, allocator);
75
8
        testReset(value, allocator);
76
8
        testSetGet(value, allocator);
77
8
        testIsType(value, allocator);
78
8
        testHasValue(value, allocator);
79
8
    }
80
81
private:
82
    template <typename ALLOC>
83
8
    void testEmptyConstructor()
84
    {
85

16
        AnyHolder<ALLOC> any;
86








8
        ASSERT_FALSE(any.hasValue());
87
    }
88
89
    template <typename ALLOC>
90
8
    void testAllocatorConstructor(const ALLOC& allocator)
91
    {
92

16
        AnyHolder<ALLOC> any(allocator);
93







8
        ASSERT_FALSE(any.hasValue());
94








8
        ASSERT_EQ(allocator, any.get_allocator());
95
    }
96
97
    template <typename T, typename ALLOC>
98
8
    void testLvalueConstructor(const T& value, const ALLOC& allocator)
99
    {
100
8
        const void* origAddress = &value;
101




16
        AnyHolder<ALLOC> any(value, allocator);
102
103




8
        const T& anyValue = any.template get<T>();
104
























8
        ASSERT_NE(origAddress, &anyValue);
105




























8
        ASSERT_EQ(value, anyValue);
106
    }
107
108
    template <typename T, typename ALLOC>
109
8
    void testLvalueConstructorNoInit(const T& value, const ALLOC& allocator)
110
    {
111
8
        const void* origAddress = &value;
112




16
        AnyHolder<ALLOC> any(NoInit, value, allocator);
113
114




8
        const T& anyValue = any.template get<T>();
115
























8
        ASSERT_NE(origAddress, &anyValue);
116




























8
        ASSERT_EQ(value, anyValue);
117
    }
118
119
    template <typename ALLOC>
120
2
    void testRvalueConstructor(const std::vector<int>& value, const ALLOC& allocator)
121
    {
122

4
        std::vector<int> origValue(value);
123
2
        const void* origAddress = origValue.data();
124


4
        AnyHolder<ALLOC> any(std::move(origValue), allocator);
125
126

2
        const std::vector<int>& anyValue = any.template get<std::vector<int>>();
127






2
        ASSERT_EQ(origAddress, anyValue.data());
128







2
        ASSERT_EQ(value, anyValue);
129
    }
130
131
    template <typename T, typename ALLOC>
132
6
    void testRvalueConstructor(const T& value, const ALLOC& allocator)
133
    {
134
6
        T origValue(value);
135



12
        AnyHolder<ALLOC> any(std::move(origValue), allocator);
136
137



6
        const T& anyValue = any.template get<T>();
138





















6
        ASSERT_EQ(value, anyValue);
139
    }
140
141
    template <typename ALLOC>
142
2
    void testRvalueConstructorNoInit(const std::vector<int>& value, const ALLOC& allocator)
143
    {
144

4
        std::vector<int> origValue(value);
145
2
        const void* origAddress = origValue.data();
146


4
        AnyHolder<ALLOC> any(NoInit, std::move(origValue), allocator);
147
148

2
        const std::vector<int>& anyValue = any.template get<std::vector<int>>();
149






2
        ASSERT_EQ(origAddress, anyValue.data());
150







2
        ASSERT_EQ(value, anyValue);
151
    }
152
153
    template <typename T, typename ALLOC>
154
6
    void testRvalueConstructorNoInit(const T& value, const ALLOC& allocator)
155
    {
156
6
        T origValue(value);
157



12
        AnyHolder<ALLOC> any(NoInit, std::move(origValue), allocator);
158
159



6
        const T& anyValue = any.template get<T>();
160





















6
        ASSERT_EQ(value, anyValue);
161
    }
162
163
    template <typename T, typename ALLOC>
164
8
    void testCopyConstructor(const T& value, const ALLOC& allocator)
165
    {
166




16
        AnyHolder<ALLOC> any(allocator);
167
168
        // copy empty holder
169








16
        AnyHolder<ALLOC> anyEmptyCopy(any);
170




























8
        ASSERT_FALSE(anyEmptyCopy.hasValue());
171
172
        // copy filled holder
173




8
        any.set(value);
174








16
        AnyHolder<ALLOC> anyCopy(any);
175
































8
        ASSERT_EQ(value, anyCopy.template get<T>());
176
    }
177
178
    template <typename T, typename ALLOC>
179
8
    void testCopyConstructorNoInit(const T& value, const ALLOC& allocator)
180
    {
181




16
        AnyHolder<ALLOC> any(allocator);
182
183
        // copy empty holder
184








16
        AnyHolder<ALLOC> anyEmptyCopy(NoInit, any);
185




























8
        ASSERT_FALSE(anyEmptyCopy.hasValue());
186
187
        // copy filled holder
188




8
        any.set(value);
189








16
        AnyHolder<ALLOC> anyCopy(NoInit, any);
190
































8
        ASSERT_EQ(value, anyCopy.template get<T>());
191
    }
192
193
    template <typename T, typename ALLOC>
194
8
    void testCopyConstructorWithAllocator(const T& value, const ALLOC& allocator)
195
    {
196




16
        AnyHolder<ALLOC> any(allocator);
197
198
        // copy empty holder
199








16
        AnyHolder<ALLOC> anyEmptyCopy(any);
200




























8
        ASSERT_FALSE(anyEmptyCopy.hasValue());
201
202
        // copy filled holder
203




8
        any.set(value);
204
8
        const size_t numAllocations = allocator.numAllocs();
205








16
        const ALLOC newAllocator;
206








16
        AnyHolder<ALLOC> anyCopy(any, newAllocator);
207




























8
        ASSERT_EQ(value, anyCopy.template get<T>());
208




























8
        ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocation and deallocations in old allocator
209
    }
210
211
    template <typename T, typename ALLOC>
212
8
    void testCopyConstructorWithAllocatorNoInit(const T& value, const ALLOC& allocator)
213
    {
214




16
        AnyHolder<ALLOC> any(allocator);
215
216
        // copy empty holder
217








16
        AnyHolder<ALLOC> anyEmptyCopy(NoInit, any);
218




























8
        ASSERT_FALSE(anyEmptyCopy.hasValue());
219
220
        // copy filled holder
221




8
        any.set(value);
222
8
        const size_t numAllocations = allocator.numAllocs();
223








16
        const ALLOC newAllocator;
224








16
        AnyHolder<ALLOC> anyCopy(NoInit, any, newAllocator);
225




























8
        ASSERT_EQ(value, anyCopy.template get<T>());
226




























8
        ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocation and deallocations in old allocator
227
    }
228
229
    template <typename T, typename ALLOC>
230
8
    void testCopyAssignmentOperator(const T& value, const ALLOC& allocator)
231
    {
232




16
        AnyHolder<ALLOC> any(allocator);
233
234
        // assignment empty holder
235








16
        AnyHolder<ALLOC> anyEmpty;
236




8
        anyEmpty = any;
237




























8
        ASSERT_FALSE(anyEmpty.hasValue());
238
239
        // assignment filled holder to itself
240




8
        any.set(value);
241
8
        AnyHolder<ALLOC>& anyRef(any);
242




8
        anyRef = any;
243




























8
        ASSERT_EQ(value, anyRef.template get<T>());
244
245
        // assignment filled holder
246








16
        AnyHolder<ALLOC> anyCopy;
247




8
        anyCopy = any;
248
































8
        ASSERT_EQ(value, anyCopy.template get<T>());
249
    }
250
251
    template <typename T, typename ALLOC>
252
8
    void testCopyAssignmentOperatorNoInit(const T& value, const ALLOC& allocator)
253
    {
254




16
        AnyHolder<ALLOC> any(allocator);
255
256
        // assignment empty holder
257








16
        AnyHolder<ALLOC> anyEmpty;
258




8
        anyEmpty.assign(NoInit, any);
259




























8
        ASSERT_FALSE(anyEmpty.hasValue());
260
261
        // assignment filled holder to itself
262




8
        any.set(value);
263
8
        AnyHolder<ALLOC>& anyRef(any);
264




8
        anyRef.assign(NoInit, any);
265




























8
        ASSERT_EQ(value, anyRef.template get<T>());
266
267
        // assignment filled holder
268








16
        AnyHolder<ALLOC> anyCopy;
269




8
        anyCopy.assign(NoInit, any);
270
































8
        ASSERT_EQ(value, anyCopy.template get<T>());
271
    }
272
273
    template <typename T, typename ALLOC>
274
8
    void testMoveConstructor(const T& value, const ALLOC& allocator)
275
    {
276
        {
277
            // move empty holder
278




16
            AnyHolder<ALLOC> any(allocator);
279




16
            AnyHolder<ALLOC> anyMove(std::move(any));
280
































8
            ASSERT_FALSE(anyMove.hasValue());
281
        }
282
283
        {
284
            // move filled holder
285




16
            AnyHolder<ALLOC> any(allocator);
286




8
            any.set(value);
287
8
            const size_t numAllocations = allocator.numAllocs();
288




16
            AnyHolder<ALLOC> anyMove(std::move(any));
289




























8
            ASSERT_EQ(value, anyMove.template get<T>());
290




























8
            ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocations and deallocations
291
        }
292
    }
293
294
    template <typename T, typename ALLOC>
295
8
    void testMoveConstructorNoInit(const T& value, const ALLOC& allocator)
296
    {
297
        {
298
            // move empty holder
299




16
            AnyHolder<ALLOC> any(allocator);
300




16
            AnyHolder<ALLOC> anyMove(NoInit, std::move(any));
301
































8
            ASSERT_FALSE(anyMove.hasValue());
302
        }
303
304
        {
305
            // move filled holder
306




16
            AnyHolder<ALLOC> any(allocator);
307




8
            any.set(value);
308
8
            const size_t numAllocations = allocator.numAllocs();
309




16
            AnyHolder<ALLOC> anyMove(NoInit, std::move(any));
310




























8
            ASSERT_EQ(value, anyMove.template get<T>());
311




























8
            ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocations and deallocations
312
        }
313
    }
314
315
    template <typename T, typename ALLOC>
316
8
    void testMoveConstructorWithAllocator(const T& value, const ALLOC& allocator)
317
    {
318
        {
319
            // empty holder with the same allocator
320




16
            AnyHolder<ALLOC> any(allocator);
321




16
            AnyHolder<ALLOC> anyMove(std::move(any));
322
































8
            ASSERT_FALSE(anyMove.hasValue());
323
        }
324
325
        {
326
            // empty holder with the different allocator
327




16
            AnyHolder<ALLOC> any(allocator);
328








16
            const ALLOC newAllocator;
329








16
            AnyHolder<ALLOC> anyMove(std::move(any), newAllocator);
330
































8
            ASSERT_FALSE(anyMove.hasValue());
331
        }
332
333
        {
334
            // filled holder with the same allocator
335




16
            AnyHolder<ALLOC> any(allocator);
336




8
            any.set(value);
337
8
            const size_t numAllocations = allocator.numAllocs();
338








16
            AnyHolder<ALLOC> anyMove(std::move(any), allocator);
339




























8
            ASSERT_EQ(value, anyMove.template get<T>());
340




























8
            ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocations and deallocations
341
        }
342
343
        {
344
            // filled holder with the different allocator
345




16
            AnyHolder<ALLOC> any(allocator);
346




8
            any.set(value);
347
8
            const size_t numAllocations = allocator.numAllocs();
348








16
            const ALLOC newAllocator;
349








16
            AnyHolder<ALLOC> anyMove(std::move(any), newAllocator);
350




























8
            ASSERT_EQ(value, anyMove.template get<T>());
351




























8
            ASSERT_TRUE(numAllocations >= allocator.numAllocs()); // no furher allocations
352
        }
353
    }
354
355
    template <typename T, typename ALLOC>
356
8
    void testMoveConstructorWithAllocatorNoInit(const T& value, const ALLOC& allocator)
357
    {
358
        {
359
            // empty holder with the same allocator
360




16
            AnyHolder<ALLOC> any(allocator);
361




16
            AnyHolder<ALLOC> anyMove(NoInit, std::move(any));
362
































8
            ASSERT_FALSE(anyMove.hasValue());
363
        }
364
365
        {
366
            // empty holder with the different allocator
367




16
            AnyHolder<ALLOC> any(allocator);
368








16
            const ALLOC newAllocator;
369








16
            AnyHolder<ALLOC> anyMove(NoInit, std::move(any), newAllocator);
370
































8
            ASSERT_FALSE(anyMove.hasValue());
371
        }
372
373
        {
374
            // filled holder with the same allocator
375




16
            AnyHolder<ALLOC> any(allocator);
376




8
            any.set(value);
377
8
            const size_t numAllocations = allocator.numAllocs();
378








16
            AnyHolder<ALLOC> anyMove(NoInit, std::move(any), allocator);
379




























8
            ASSERT_EQ(value, anyMove.template get<T>());
380




























8
            ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocations and deallocations
381
        }
382
383
        {
384
            // filled holder with the different allocator
385




16
            AnyHolder<ALLOC> any(allocator);
386




8
            any.set(value);
387
8
            const size_t numAllocations = allocator.numAllocs();
388








16
            const ALLOC newAllocator;
389








16
            AnyHolder<ALLOC> anyMove(NoInit, std::move(any), newAllocator);
390




























8
            ASSERT_EQ(value, anyMove.template get<T>());
391




























8
            ASSERT_TRUE(numAllocations >= allocator.numAllocs()); // no furher allocations
392
        }
393
    }
394
395
    template <typename T, typename ALLOC>
396
8
    void testMoveAssignmentOperator(const T& value, const ALLOC& allocator)
397
    {
398
        {
399
            // assignment empty holder
400




16
            AnyHolder<ALLOC> any(allocator);
401








16
            AnyHolder<ALLOC> anyMove;
402




8
            anyMove = std::move(any);
403
































8
            ASSERT_FALSE(anyMove.hasValue());
404
        }
405
406
        {
407
            // assignment filled holder to itself
408




16
            AnyHolder<ALLOC> any(allocator);
409




8
            any.set(value);
410
8
            const size_t numAllocations = allocator.numAllocs();
411
8
            AnyHolder<ALLOC>& anyRef = any;
412




8
            anyRef = std::move(any);
413




























8
            ASSERT_EQ(value, anyRef.template get<T>());
414




























8
            ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocations and deallocations
415
        }
416
417
        {
418
            // assignment filled holder
419




16
            AnyHolder<ALLOC> any(allocator);
420




8
            any.set(value);
421
8
            const size_t numAllocations = allocator.numAllocs();
422








16
            AnyHolder<ALLOC> anyMove;
423




8
            anyMove = std::move(any);
424




























8
            ASSERT_EQ(value, anyMove.template get<T>());
425




























8
            ASSERT_TRUE(numAllocations >= allocator.numAllocs()); // no furher allocations
426
        }
427
    }
428
429
    template <typename T, typename ALLOC>
430
8
    void testMoveAssignmentOperatorNoInit(const T& value, const ALLOC& allocator)
431
    {
432
        {
433
            // assignment empty holder
434




16
            AnyHolder<ALLOC> any(allocator);
435








16
            AnyHolder<ALLOC> anyMove;
436




8
            anyMove.assign(NoInit, std::move(any));
437
































8
            ASSERT_FALSE(anyMove.hasValue());
438
        }
439
440
        {
441
            // assignment filled holder to itself
442




16
            AnyHolder<ALLOC> any(allocator);
443




8
            any.set(value);
444
8
            const size_t numAllocations = allocator.numAllocs();
445
8
            AnyHolder<ALLOC>& anyRef = any;
446




8
            anyRef.assign(NoInit, std::move(any));
447




























8
            ASSERT_EQ(value, anyRef.template get<T>());
448




























8
            ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocations and deallocations
449
        }
450
451
        {
452
            // assignment filled holder
453




16
            AnyHolder<ALLOC> any(allocator);
454




8
            any.set(value);
455
8
            const size_t numAllocations = allocator.numAllocs();
456








16
            AnyHolder<ALLOC> anyMove;
457




8
            anyMove.assign(NoInit, std::move(any));
458




























8
            ASSERT_EQ(value, anyMove.template get<T>());
459




























8
            ASSERT_TRUE(numAllocations >= allocator.numAllocs()); // no furher allocations
460
        }
461
    }
462
463
    template <typename T, typename ALLOC>
464
8
    void testMoveAssignmentValueOperator(const T& value, const ALLOC& allocator)
465
    {
466
        {
467
            // assignment empty holder
468

10
            const T valueCopy(value);
469





16
            AnyHolder<ALLOC> any(allocator);
470
8
            const size_t numAllocations = allocator.numAllocs();
471








16
            AnyHolder<ALLOC> anyMove;
472




8
            anyMove = std::move(valueCopy);
473




























8
            ASSERT_EQ(value, anyMove.template get<T>());
474




























8
            ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocations and deallocations
475
        }
476
477
        {
478
            // assignment filled holder
479

10
            const T valueCopy(value);
480





16
            AnyHolder<ALLOC> any(allocator);
481




8
            any.set(value);
482
8
            const size_t numAllocations = allocator.numAllocs();
483








16
            AnyHolder<ALLOC> anyMove;
484




8
            anyMove = std::move(valueCopy);
485




























8
            ASSERT_EQ(value, anyMove.template get<T>());
486




























8
            ASSERT_EQ(numAllocations, allocator.numAllocs()); // no allocations and deallocations
487
        }
488
    }
489
490
    template <typename T, typename ALLOC>
491
8
    void testReset(const T& value, const ALLOC& allocator)
492
    {
493




16
        AnyHolder<ALLOC> any(value, allocator);
494




























8
        ASSERT_TRUE(any.hasValue());
495
496




8
        any.reset();
497




























8
        ASSERT_FALSE(any.hasValue());
498
499




8
        any = value;
500




























8
        ASSERT_TRUE(any.hasValue());
501
































8
        ASSERT_EQ(value, any.template get<T>());
502
    }
503
504
    template <typename T, typename ALLOC>
505
8
    void testSetGet(const T& value, const ALLOC& allocator)
506
    {
507










16
        AnyHolder<ALLOC> any(allocator);
508








































































16
        ASSERT_THROW(any.template get<int>(), zserio::CppRuntimeException);
509
510




8
        any.set(value);
511




























8
        ASSERT_EQ(value, any.template get<T>());
512
513
8
        const int intValue = 0xDEAD;
514




8
        any.set(intValue);
515


































8
        ASSERT_EQ(intValue, any.template get<int>());
516














































































16
        ASSERT_THROW(any.template get<float>(), CppRuntimeException);
517
518
8
        const float floatValue = 3.14F;
519




8
        any.set(floatValue);
520








































































16
        ASSERT_THROW(any.template get<int>(), CppRuntimeException);
521


































8
        ASSERT_EQ(floatValue, any.template get<float>());
522
523
8
        const BigObject bigObjectValue;
524




8
        any.set(bigObjectValue);
525








































































16
        ASSERT_THROW(any.template get<int>(), CppRuntimeException);
526
































8
        ASSERT_EQ(bigObjectValue, any.template get<BigObject>());
527
    }
528
529
    template <typename T, typename ALLOC>
530
8
    void testIsType(const T& value, const ALLOC& allocator)
531
    {
532




16
        AnyHolder<ALLOC> any(allocator);
533




























8
        ASSERT_FALSE(any.template isType<int>());
534
535




8
        any.set(value);
536




























8
        ASSERT_TRUE(any.template isType<T>());
537
538
8
        const int intValue = 0xDEAD;
539




8
        any.set(intValue);
540




























8
        ASSERT_TRUE(any.template isType<int>());
541
542
8
        const float floatValue = 3.14F;
543




8
        any.set(floatValue);
544




























8
        ASSERT_TRUE(any.template isType<float>());
545
































8
        ASSERT_FALSE(any.template isType<int>());
546
    }
547
548
    template <typename T, typename ALLOC>
549
8
    void testHasValue(const T& value, const ALLOC& allocator)
550
    {
551




16
        AnyHolder<ALLOC> any(allocator);
552




























8
        ASSERT_FALSE(any.hasValue());
553
554




8
        any.set(value);
555




























8
        ASSERT_TRUE(any.hasValue());
556
557
8
        const int intValue = 0xDEAD;
558




8
        any.set(intValue);
559




























8
        ASSERT_TRUE(any.hasValue());
560
561




8
        any.reset();
562
































8
        ASSERT_FALSE(any.hasValue());
563
    }
564
};
565
566


802
TEST_F(AnyHolderTest, integerPropagatingAllocator)
567
{
568
1
    const int value = 0xDEAD;
569
2
    const TrackingAllocator<uint8_t> allocator;
570
1
    testAnyHolder(value, allocator);
571
1
}
572
573


802
TEST_F(AnyHolderTest, integerNonPropagatingAllocator)
574
{
575
1
    const int value = 0xDEAD;
576
2
    const TrackingAllocatorNonProp<uint8_t> allocator;
577
1
    testAnyHolder(value, allocator);
578
1
}
579
580


802
TEST_F(AnyHolderTest, vectorPropagatingAllocator)
581
{
582
2
    const std::vector<int> value{1, 2, 3};
583
2
    const TrackingAllocator<uint8_t> allocator;
584
1
    testAnyHolder(value, allocator);
585
1
}
586
587


802
TEST_F(AnyHolderTest, vectorNonPropagatingAllocator)
588
{
589
2
    const std::vector<int> value{1, 2, 3};
590
2
    const TrackingAllocatorNonProp<uint8_t> allocator;
591
1
    testAnyHolder(value, allocator);
592
1
}
593
594


802
TEST_F(AnyHolderTest, smallObjectPropagatingAllocator)
595
{
596
1
    const SmallObject value;
597
2
    const TrackingAllocator<uint8_t> allocator;
598
1
    testAnyHolder(value, allocator);
599
1
}
600
601


802
TEST_F(AnyHolderTest, smallObjectNonPropagatingAllocator)
602
{
603
1
    const SmallObject value;
604
2
    const TrackingAllocatorNonProp<uint8_t> allocator;
605
1
    testAnyHolder(value, allocator);
606
1
}
607
608


802
TEST_F(AnyHolderTest, bigObjectPropagatingAllocator)
609
{
610
1
    const BigObject value;
611
2
    const TrackingAllocator<uint8_t> allocator;
612
1
    testAnyHolder(value, allocator);
613
1
}
614
615


802
TEST_F(AnyHolderTest, bigObjectNonPropagatingAllocator)
616
{
617
1
    const BigObject value;
618
2
    const TrackingAllocatorNonProp<uint8_t> allocator;
619
1
    testAnyHolder(value, allocator);
620
1
}
621
622


802
TEST_F(AnyHolderTest, unexceptedCallsHeapHolder)
623
{
624

2
    const TrackingAllocator<uint8_t> allocator;
625
    detail::HeapHolder<BigObject, TrackingAllocator<uint8_t>>* holder =
626
1
            detail::HeapHolder<BigObject, TrackingAllocator<uint8_t>>::create(allocator);
627










2
    ASSERT_THROW(holder->clone(nullptr), CppRuntimeException);
628










2
    ASSERT_THROW(holder->clone(NoInit, nullptr), CppRuntimeException);
629










2
    ASSERT_THROW(holder->move(nullptr), CppRuntimeException);
630









2
    ASSERT_THROW(holder->move(NoInit, nullptr), CppRuntimeException);
631

1
    holder->destroy(allocator);
632
}
633
634


802
TEST_F(AnyHolderTest, unexceptedCallsNonHeapHolder)
635
{
636

2
    const TrackingAllocator<uint8_t> allocator;
637
    using MaxInPlaceType = std::aligned_storage<3 * sizeof(void*), alignof(void*)>::type;
638
1
    MaxInPlaceType inPlace = MaxInPlaceType();
639
    detail::NonHeapHolder<uint8_t, TrackingAllocator<uint8_t>>* holder =
640
1
            detail::NonHeapHolder<uint8_t, TrackingAllocator<uint8_t>>::create(&inPlace);
641










2
    ASSERT_THROW(holder->clone(allocator), CppRuntimeException);
642










2
    ASSERT_THROW(holder->clone(NoInit, allocator), CppRuntimeException);
643










2
    ASSERT_THROW(holder->move(allocator), CppRuntimeException);
644









2
    ASSERT_THROW(holder->move(NoInit, allocator), CppRuntimeException);
645

1
    holder->destroy(allocator);
646
}
647
648

2394
} // namespace zserio