GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: test/zserio/AllocatorPropagatingCopyTest.cpp Lines: 139 143 97.2 %
Date: 2023-12-13 14:51:09 Branches: 268 760 35.3 %

Line Branch Exec Source
1
#include "gtest/gtest.h"
2
3
#include "zserio/AllocatorPropagatingCopy.h"
4
#include "zserio/AnyHolder.h"
5
#include "zserio/NoInit.h"
6
#include "zserio/OptionalHolder.h"
7
#include "TrackingAllocator.h"
8
9
#include <algorithm>
10
11
namespace zserio
12
{
13
14
namespace
15
{
16
17
class RegularType
18
{
19
};
20
21
2
class RegularTypeWithStdAllocator
22
{
23
public:
24
    using allocator_type = std::allocator<RegularTypeWithStdAllocator>;
25
26
1
    allocator_type get_allocator() const
27
    {
28
1
        return m_allocator;
29
    }
30
31
1
    explicit RegularTypeWithStdAllocator(const allocator_type& allocator = allocator_type()) :
32
1
            m_allocator(allocator)
33
1
    {}
34
35
1
    RegularTypeWithStdAllocator(const RegularTypeWithStdAllocator&, const allocator_type& allocator) :
36
1
            m_allocator(allocator)
37
1
    {}
38
39
private:
40
    allocator_type m_allocator;
41
};
42
43
class RegularWithAllocatorSupport
44
{
45
public:
46
    using allocator_type = TrackingAllocatorNonProp<RegularWithAllocatorSupport>;
47
    using AllocTraits = std::allocator_traits<allocator_type>;
48
49
13
    allocator_type get_allocator() const
50
    {
51
13
        return m_allocator;
52
    }
53
54
6
    explicit RegularWithAllocatorSupport(const allocator_type& allocator = allocator_type()) :
55
6
            m_allocator(allocator)
56
6
    {}
57
58
22
    ~RegularWithAllocatorSupport() = default;
59
60
1
    RegularWithAllocatorSupport(const RegularWithAllocatorSupport& other) :
61
1
            m_allocator(AllocTraits::select_on_container_copy_construction(other.m_allocator))
62
1
    {}
63
64
    RegularWithAllocatorSupport& operator=(const RegularWithAllocatorSupport&) = delete;
65
66
9
    RegularWithAllocatorSupport(RegularWithAllocatorSupport&&) = default;
67
68
    RegularWithAllocatorSupport& operator=(RegularWithAllocatorSupport&&) = delete;
69
70
6
    RegularWithAllocatorSupport(PropagateAllocatorT, const RegularWithAllocatorSupport&,
71
            const allocator_type& allocator) :
72
6
            m_allocator(allocator)
73
6
    {}
74
75
private:
76
    allocator_type m_allocator;
77
};
78
79
class RegularWithAllocatorSupportNoInit
80
{
81
public:
82
    using allocator_type = TrackingAllocatorNonProp<RegularWithAllocatorSupportNoInit>;
83
    using AllocTraits = std::allocator_traits<allocator_type>;
84
85
8
    allocator_type get_allocator() const
86
    {
87
8
        return m_allocator;
88
    }
89
90
4
    explicit RegularWithAllocatorSupportNoInit(const allocator_type& allocator = allocator_type()) :
91
4
            m_allocator(allocator)
92
4
    {}
93
94
17
    ~RegularWithAllocatorSupportNoInit() = default;
95
96
    RegularWithAllocatorSupportNoInit(const RegularWithAllocatorSupportNoInit&)
97
    {
98
        // must be present for proper compilation
99
        EXPECT_TRUE(false);
100
    }
101
102
1
    RegularWithAllocatorSupportNoInit(NoInitT, const RegularWithAllocatorSupportNoInit& other) :
103
1
            m_allocator(AllocTraits::select_on_container_copy_construction(other.m_allocator))
104
1
    {}
105
106
    RegularWithAllocatorSupportNoInit& operator=(const RegularWithAllocatorSupportNoInit&) = delete;
107
108
    RegularWithAllocatorSupportNoInit(RegularWithAllocatorSupportNoInit&&)
109
    {
110
        // must be present for proper compilation
111
        EXPECT_TRUE(false);
112
    }
113
114
8
    RegularWithAllocatorSupportNoInit(NoInitT, RegularWithAllocatorSupportNoInit&& other) :
115
8
            m_allocator(other.m_allocator)
116
8
    {}
117
118
    RegularWithAllocatorSupportNoInit& operator=(RegularWithAllocatorSupportNoInit&&) = delete;
119
120
4
    RegularWithAllocatorSupportNoInit(PropagateAllocatorT, NoInitT,
121
            const RegularWithAllocatorSupportNoInit&, const allocator_type& allocator) :
122
4
            m_allocator(allocator)
123
4
    {}
124
125
private:
126
    allocator_type m_allocator;
127
};
128
129
} // namespace
130
131


802
TEST(AllocatorPropagatingCopyTest, copyDefault)
132
{
133
    // not much things to be tested here - just make sure that it compiles
134
2
    std::allocator<RegularType> allocator;
135
    const RegularType thing;
136
1
    RegularType thingCopy(allocatorPropagatingCopy(thing, allocator));
137
    static_cast<void>(thingCopy);
138
1
}
139
140


802
TEST(AllocatorPropagatingCopyTest, copyDefaultStdAllocator)
141
{
142
2
    RegularTypeWithStdAllocator::allocator_type allocator;
143
2
    const RegularTypeWithStdAllocator thing(allocator);
144

2
    RegularTypeWithStdAllocator thingCopy(allocatorPropagatingCopy(thing, allocator));
145



1
    ASSERT_EQ(allocator, thingCopy.get_allocator());
146
}
147
148


802
TEST(AllocatorPropagatingCopyTest, copyDefaultAllocator)
149
{
150
2
    RegularWithAllocatorSupport::allocator_type allocator;
151
2
    const RegularWithAllocatorSupport thing(allocator);
152

2
    RegularWithAllocatorSupport thingCopy(allocatorPropagatingCopy(thing, allocator));
153



1
    ASSERT_EQ(allocator, thingCopy.get_allocator());
154

2
    RegularWithAllocatorSupport thingCopy2(thingCopy);
155



1
    ASSERT_NE(thingCopy.get_allocator(), thingCopy2.get_allocator());
156
}
157
158


802
TEST(AllocatorPropagatingCopyTest, copyDefaultAllocatorNoInit)
159
{
160
2
    RegularWithAllocatorSupportNoInit::allocator_type allocator;
161
2
    const RegularWithAllocatorSupportNoInit thing(allocator);
162

2
    RegularWithAllocatorSupportNoInit thingCopy(NoInit, allocatorPropagatingCopy(NoInit, thing, allocator));
163



1
    ASSERT_EQ(allocator, thingCopy.get_allocator());
164

2
    RegularWithAllocatorSupportNoInit thingCopy2(NoInit, thing);
165



1
    ASSERT_NE(allocator, thingCopy2.get_allocator());
166
}
167
168


802
TEST(AllocatorPropagatingCopyTest, copyHeapOptional)
169
{
170
2
    RegularWithAllocatorSupport::allocator_type allocator;
171
172
    const HeapOptionalHolder<RegularWithAllocatorSupport,
173
2
            RegularWithAllocatorSupport::allocator_type> emptyOptional(allocator);
174
    HeapOptionalHolder<RegularWithAllocatorSupport,
175
            RegularWithAllocatorSupport::allocator_type> emptyOptionalCopy(
176

2
                    allocatorPropagatingCopy(emptyOptional, allocator));
177




1
    ASSERT_EQ(emptyOptional.get_allocator(), emptyOptionalCopy.get_allocator());
178
179
    const HeapOptionalHolder<RegularWithAllocatorSupport,
180
            RegularWithAllocatorSupport::allocator_type> optional(
181

2
                    RegularWithAllocatorSupport(allocator), allocator);
182
    HeapOptionalHolder<RegularWithAllocatorSupport,
183
            RegularWithAllocatorSupport::allocator_type> optionalCopy(
184

2
                    allocatorPropagatingCopy(optional, allocator));
185




1
    ASSERT_EQ(optional.get_allocator(), optionalCopy.get_allocator());
186



1
    ASSERT_TRUE(optionalCopy.hasValue());
187




1
    ASSERT_EQ(optional->get_allocator(), optionalCopy->get_allocator());
188
}
189
190


802
TEST(AllocatorPropagatingCopyTest, copyHeapOptionalNoInit)
191
{
192
2
    RegularWithAllocatorSupportNoInit::allocator_type allocator;
193
194
    const HeapOptionalHolder<RegularWithAllocatorSupportNoInit,
195
2
            RegularWithAllocatorSupportNoInit::allocator_type> emptyOptional(allocator);
196
    HeapOptionalHolder<RegularWithAllocatorSupportNoInit,
197
            RegularWithAllocatorSupportNoInit::allocator_type> emptyOptionalCopy(
198

2
                    NoInit, allocatorPropagatingCopy(NoInit, emptyOptional, allocator));
199




1
    ASSERT_EQ(emptyOptional.get_allocator(), emptyOptionalCopy.get_allocator());
200
201
    const HeapOptionalHolder<RegularWithAllocatorSupportNoInit,
202

2
            RegularWithAllocatorSupportNoInit::allocator_type> optional(allocator, allocator);
203
    HeapOptionalHolder<RegularWithAllocatorSupportNoInit,
204
            RegularWithAllocatorSupportNoInit::allocator_type> optionalCopy(
205

2
                    NoInit, allocatorPropagatingCopy(NoInit, optional, allocator));
206




1
    ASSERT_EQ(optional.get_allocator(), optionalCopy.get_allocator());
207



1
    ASSERT_TRUE(optionalCopy.hasValue());
208




1
    ASSERT_EQ(optional->get_allocator(), optionalCopy->get_allocator());
209
}
210
211


802
TEST(AllocatorPropagatingCopyTest, copyInplaceOptional)
212
{
213
2
    RegularWithAllocatorSupport::allocator_type allocator;
214
215
2
    const InplaceOptionalHolder<RegularWithAllocatorSupport> emptyOptional{};
216
    InplaceOptionalHolder<RegularWithAllocatorSupport> emptyOptionalCopy(
217

2
            allocatorPropagatingCopy(emptyOptional, allocator));
218
219
    const InplaceOptionalHolder<RegularWithAllocatorSupport> optional{
220

2
            RegularWithAllocatorSupport(allocator)};
221
    InplaceOptionalHolder<RegularWithAllocatorSupport> optionalCopy(
222

2
            allocatorPropagatingCopy(optional, allocator));
223



1
    ASSERT_TRUE(optionalCopy.hasValue());
224




1
    ASSERT_EQ(optional->get_allocator(), optionalCopy->get_allocator());
225
}
226
227


802
TEST(AllocatorPropagatingCopyTest, copyInplaceOptionalNoInit)
228
{
229
2
    RegularWithAllocatorSupportNoInit::allocator_type allocator;
230
231
2
    const InplaceOptionalHolder<RegularWithAllocatorSupportNoInit> emptyOptional{};
232
    InplaceOptionalHolder<RegularWithAllocatorSupportNoInit> emptyOptionalCopy(
233

2
            NoInit, allocatorPropagatingCopy(NoInit, emptyOptional, allocator));
234
235

2
    const InplaceOptionalHolder<RegularWithAllocatorSupportNoInit> optional{InPlace, allocator};
236
    InplaceOptionalHolder<RegularWithAllocatorSupportNoInit> optionalCopy(
237

2
            NoInit, allocatorPropagatingCopy(NoInit, optional, allocator));
238



1
    ASSERT_TRUE(optionalCopy.hasValue());
239




1
    ASSERT_EQ(optional->get_allocator(), optionalCopy->get_allocator());
240
}
241
242


802
TEST(AllocatorPropagatingCopyTest, copyAny)
243
{
244
2
    const TrackingAllocatorNonProp<uint8_t> allocator;
245
246

2
    const AnyHolder<TrackingAllocatorNonProp<uint8_t>> emptyAny(allocator);
247
    AnyHolder<TrackingAllocatorNonProp<uint8_t>> emptyAnyCopy(
248

2
            allocatorPropagatingCopy<RegularWithAllocatorSupport>(emptyAny, allocator));
249
250
    const AnyHolder<TrackingAllocatorNonProp<uint8_t>> any(
251

2
            RegularWithAllocatorSupport(allocator), allocator);
252
    AnyHolder<TrackingAllocatorNonProp<uint8_t>> anyCopy(
253

2
            allocatorPropagatingCopy<RegularWithAllocatorSupport>(any, allocator));
254




1
    ASSERT_EQ(any.get_allocator(), anyCopy.get_allocator());
255



1
    ASSERT_TRUE(anyCopy.hasValue());
256



1
    ASSERT_TRUE(anyCopy.isType<RegularWithAllocatorSupport>());
257




1
    ASSERT_EQ(any.get<RegularWithAllocatorSupport>().get_allocator(),
258
            anyCopy.get<RegularWithAllocatorSupport>().get_allocator());
259
}
260
261


802
TEST(AllocatorPropagatingCopyTest, copyAnyNoInit)
262
{
263
2
    const TrackingAllocatorNonProp<uint8_t> allocator;
264
265

2
    const AnyHolder<TrackingAllocatorNonProp<uint8_t>> emptyAny(allocator);
266
267
    AnyHolder<TrackingAllocatorNonProp<uint8_t>> emptyAnyCopy(
268

2
            NoInit, allocatorPropagatingCopy<RegularWithAllocatorSupportNoInit>(NoInit, emptyAny, allocator));
269
270
    const AnyHolder<TrackingAllocatorNonProp<uint8_t>> any(
271

2
            NoInit, RegularWithAllocatorSupportNoInit(allocator), allocator);
272
    AnyHolder<TrackingAllocatorNonProp<uint8_t>> anyCopy(
273

2
            NoInit, allocatorPropagatingCopy<RegularWithAllocatorSupportNoInit>(NoInit, any, allocator));
274




1
    ASSERT_EQ(any.get_allocator(), anyCopy.get_allocator());
275



1
    ASSERT_TRUE(anyCopy.hasValue());
276



1
    ASSERT_TRUE(anyCopy.isType<RegularWithAllocatorSupportNoInit>());
277




1
    ASSERT_EQ(any.get<RegularWithAllocatorSupportNoInit>().get_allocator(),
278
            anyCopy.get<RegularWithAllocatorSupportNoInit>().get_allocator());
279
}
280
281


802
TEST(AllocatorPropagatingCopyTest, copyVector)
282
{
283
2
    RegularWithAllocatorSupport::allocator_type allocator;
284
285
    const std::vector<RegularWithAllocatorSupport,
286
2
            RegularWithAllocatorSupport::allocator_type> emptyVec(allocator);
287
    std::vector<RegularWithAllocatorSupport, RegularWithAllocatorSupport::allocator_type> emptyVecCopy(
288

2
            allocatorPropagatingCopy(emptyVec, allocator));
289



1
    ASSERT_EQ(emptyVec.get_allocator(), emptyVecCopy.get_allocator());
290
291
2
    std::vector<RegularWithAllocatorSupport, RegularWithAllocatorSupport::allocator_type> vec(allocator);
292
1
    vec.emplace_back(allocator);
293
1
    vec.emplace_back(allocator);
294
    std::vector<RegularWithAllocatorSupport, RegularWithAllocatorSupport::allocator_type> vecCopy(
295

2
            allocatorPropagatingCopy(vec, allocator));
296



1
    ASSERT_EQ(vec.get_allocator(), vecCopy.get_allocator());
297



1
    ASSERT_EQ(vec.size(), vecCopy.size());
298




3
    ASSERT_TRUE(std::equal(vec.begin(), vec.end(), vecCopy.begin(),
299
                           [](const RegularWithAllocatorSupport& a, const RegularWithAllocatorSupport& b)
300
                           {
301
                               return a.get_allocator() == b.get_allocator();
302
                           }));
303
}
304
305


802
TEST(AllocatorPropagatingCopyTest, copyVectorRegular)
306
{
307
2
    std::allocator<RegularType> allocator;
308
309
2
    const std::vector<RegularType> emptyVec(allocator);
310

2
    std::vector<RegularType> emptyVecCopy(allocatorPropagatingCopy(emptyVec, allocator));
311



1
    ASSERT_EQ(emptyVec.get_allocator(), emptyVecCopy.get_allocator());
312
}
313
314


802
TEST(AllocatorPropagatingCopyTest, copyString)
315
{
316
2
    RegularWithAllocatorSupport::allocator_type allocator;
317
318
    const std::basic_string<char, std::char_traits<char>,
319

2
            RegularWithAllocatorSupport::allocator_type> emptyString(allocator);
320
    std::basic_string<char, std::char_traits<char>,
321
            RegularWithAllocatorSupport::allocator_type> emptyStringCopy(
322

2
                    allocatorPropagatingCopy(emptyString, allocator));
323



1
    ASSERT_EQ(emptyString.get_allocator(), emptyStringCopy.get_allocator());
324
}
325
326

2394
} // namespace zserio
327