Coverage Report

Created: 2023-12-13 14:58

test/zserio/AllocatorPropagatingCopyTest.cpp
Line
Count
Source (jump to first uncovered line)
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
class RegularTypeWithStdAllocator
22
{
23
public:
24
    using allocator_type = std::allocator<RegularTypeWithStdAllocator>;
25
26
    allocator_type get_allocator() const
27
1
    {
28
1
        return m_allocator;
29
1
    }
30
31
    explicit RegularTypeWithStdAllocator(const allocator_type& allocator = allocator_type()) :
32
            m_allocator(allocator)
33
1
    {}
34
35
    RegularTypeWithStdAllocator(const RegularTypeWithStdAllocator&, const allocator_type& allocator) :
36
            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
    allocator_type get_allocator() const
50
13
    {
51
13
        return m_allocator;
52
13
    }
53
54
    explicit RegularWithAllocatorSupport(const allocator_type& allocator = allocator_type()) :
55
            m_allocator(allocator)
56
6
    {}
57
58
22
    ~RegularWithAllocatorSupport() = default;
59
60
    RegularWithAllocatorSupport(const RegularWithAllocatorSupport& other) :
61
            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
    RegularWithAllocatorSupport(PropagateAllocatorT, const RegularWithAllocatorSupport&,
71
            const allocator_type& allocator) :
72
            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
    allocator_type get_allocator() const
86
8
    {
87
8
        return m_allocator;
88
8
    }
89
90
    explicit RegularWithAllocatorSupportNoInit(const allocator_type& allocator = allocator_type()) :
91
            m_allocator(allocator)
92
4
    {}
93
94
17
    ~RegularWithAllocatorSupportNoInit() = default;
95
96
    RegularWithAllocatorSupportNoInit(const RegularWithAllocatorSupportNoInit&)
97
0
    {
98
        // must be present for proper compilation
99
0
        EXPECT_TRUE(false);
100
0
    }
101
102
    RegularWithAllocatorSupportNoInit(NoInitT, const RegularWithAllocatorSupportNoInit& other) :
103
            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
0
    {
110
        // must be present for proper compilation
111
0
        EXPECT_TRUE(false);
112
0
    }
113
114
    RegularWithAllocatorSupportNoInit(NoInitT, RegularWithAllocatorSupportNoInit&& other) :
115
            m_allocator(other.m_allocator)
116
8
    {}
117
118
    RegularWithAllocatorSupportNoInit& operator=(RegularWithAllocatorSupportNoInit&&) = delete;
119
120
    RegularWithAllocatorSupportNoInit(PropagateAllocatorT, NoInitT,
121
            const RegularWithAllocatorSupportNoInit&, const allocator_type& allocator) :
122
            m_allocator(allocator)
123
4
    {}
124
125
private:
126
    allocator_type m_allocator;
127
};
128
129
} // namespace
130
131
TEST(AllocatorPropagatingCopyTest, copyDefault)
132
1
{
133
    // not much things to be tested here - just make sure that it compiles
134
1
    std::allocator<RegularType> allocator;
135
1
    const RegularType thing;
136
1
    RegularType thingCopy(allocatorPropagatingCopy(thing, allocator));
137
1
    static_cast<void>(thingCopy);
138
1
}
139
140
TEST(AllocatorPropagatingCopyTest, copyDefaultStdAllocator)
141
1
{
142
1
    RegularTypeWithStdAllocator::allocator_type allocator;
143
1
    const RegularTypeWithStdAllocator thing(allocator);
144
1
    RegularTypeWithStdAllocator thingCopy(allocatorPropagatingCopy(thing, allocator));
145
1
    ASSERT_EQ(allocator, thingCopy.get_allocator());
146
1
}
147
148
TEST(AllocatorPropagatingCopyTest, copyDefaultAllocator)
149
1
{
150
1
    RegularWithAllocatorSupport::allocator_type allocator;
151
1
    const RegularWithAllocatorSupport thing(allocator);
152
1
    RegularWithAllocatorSupport thingCopy(allocatorPropagatingCopy(thing, allocator));
153
1
    ASSERT_EQ(allocator, thingCopy.get_allocator());
154
1
    RegularWithAllocatorSupport thingCopy2(thingCopy);
155
1
    ASSERT_NE(thingCopy.get_allocator(), thingCopy2.get_allocator());
156
1
}
157
158
TEST(AllocatorPropagatingCopyTest, copyDefaultAllocatorNoInit)
159
1
{
160
1
    RegularWithAllocatorSupportNoInit::allocator_type allocator;
161
1
    const RegularWithAllocatorSupportNoInit thing(allocator);
162
1
    RegularWithAllocatorSupportNoInit thingCopy(NoInit, allocatorPropagatingCopy(NoInit, thing, allocator));
163
1
    ASSERT_EQ(allocator, thingCopy.get_allocator());
164
1
    RegularWithAllocatorSupportNoInit thingCopy2(NoInit, thing);
165
1
    ASSERT_NE(allocator, thingCopy2.get_allocator());
166
1
}
167
168
TEST(AllocatorPropagatingCopyTest, copyHeapOptional)
169
1
{
170
1
    RegularWithAllocatorSupport::allocator_type allocator;
171
172
1
    const HeapOptionalHolder<RegularWithAllocatorSupport,
173
1
            RegularWithAllocatorSupport::allocator_type> emptyOptional(allocator);
174
1
    HeapOptionalHolder<RegularWithAllocatorSupport,
175
1
            RegularWithAllocatorSupport::allocator_type> emptyOptionalCopy(
176
1
                    allocatorPropagatingCopy(emptyOptional, allocator));
177
1
    ASSERT_EQ(emptyOptional.get_allocator(), emptyOptionalCopy.get_allocator());
178
179
1
    const HeapOptionalHolder<RegularWithAllocatorSupport,
180
1
            RegularWithAllocatorSupport::allocator_type> optional(
181
1
                    RegularWithAllocatorSupport(allocator), allocator);
182
1
    HeapOptionalHolder<RegularWithAllocatorSupport,
183
1
            RegularWithAllocatorSupport::allocator_type> optionalCopy(
184
1
                    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
1
}
189
190
TEST(AllocatorPropagatingCopyTest, copyHeapOptionalNoInit)
191
1
{
192
1
    RegularWithAllocatorSupportNoInit::allocator_type allocator;
193
194
1
    const HeapOptionalHolder<RegularWithAllocatorSupportNoInit,
195
1
            RegularWithAllocatorSupportNoInit::allocator_type> emptyOptional(allocator);
196
1
    HeapOptionalHolder<RegularWithAllocatorSupportNoInit,
197
1
            RegularWithAllocatorSupportNoInit::allocator_type> emptyOptionalCopy(
198
1
                    NoInit, allocatorPropagatingCopy(NoInit, emptyOptional, allocator));
199
1
    ASSERT_EQ(emptyOptional.get_allocator(), emptyOptionalCopy.get_allocator());
200
201
1
    const HeapOptionalHolder<RegularWithAllocatorSupportNoInit,
202
1
            RegularWithAllocatorSupportNoInit::allocator_type> optional(allocator, allocator);
203
1
    HeapOptionalHolder<RegularWithAllocatorSupportNoInit,
204
1
            RegularWithAllocatorSupportNoInit::allocator_type> optionalCopy(
205
1
                    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
1
}
210
211
TEST(AllocatorPropagatingCopyTest, copyInplaceOptional)
212
1
{
213
1
    RegularWithAllocatorSupport::allocator_type allocator;
214
215
1
    const InplaceOptionalHolder<RegularWithAllocatorSupport> emptyOptional{};
216
1
    InplaceOptionalHolder<RegularWithAllocatorSupport> emptyOptionalCopy(
217
1
            allocatorPropagatingCopy(emptyOptional, allocator));
218
219
1
    const InplaceOptionalHolder<RegularWithAllocatorSupport> optional{
220
1
            RegularWithAllocatorSupport(allocator)};
221
1
    InplaceOptionalHolder<RegularWithAllocatorSupport> optionalCopy(
222
1
            allocatorPropagatingCopy(optional, allocator));
223
1
    ASSERT_TRUE(optionalCopy.hasValue());
224
1
    ASSERT_EQ(optional->get_allocator(), optionalCopy->get_allocator());
225
1
}
226
227
TEST(AllocatorPropagatingCopyTest, copyInplaceOptionalNoInit)
228
1
{
229
1
    RegularWithAllocatorSupportNoInit::allocator_type allocator;
230
231
1
    const InplaceOptionalHolder<RegularWithAllocatorSupportNoInit> emptyOptional{};
232
1
    InplaceOptionalHolder<RegularWithAllocatorSupportNoInit> emptyOptionalCopy(
233
1
            NoInit, allocatorPropagatingCopy(NoInit, emptyOptional, allocator));
234
235
1
    const InplaceOptionalHolder<RegularWithAllocatorSupportNoInit> optional{InPlace, allocator};
236
1
    InplaceOptionalHolder<RegularWithAllocatorSupportNoInit> optionalCopy(
237
1
            NoInit, allocatorPropagatingCopy(NoInit, optional, allocator));
238
1
    ASSERT_TRUE(optionalCopy.hasValue());
239
1
    ASSERT_EQ(optional->get_allocator(), optionalCopy->get_allocator());
240
1
}
241
242
TEST(AllocatorPropagatingCopyTest, copyAny)
243
1
{
244
1
    const TrackingAllocatorNonProp<uint8_t> allocator;
245
246
1
    const AnyHolder<TrackingAllocatorNonProp<uint8_t>> emptyAny(allocator);
247
1
    AnyHolder<TrackingAllocatorNonProp<uint8_t>> emptyAnyCopy(
248
1
            allocatorPropagatingCopy<RegularWithAllocatorSupport>(emptyAny, allocator));
249
250
1
    const AnyHolder<TrackingAllocatorNonProp<uint8_t>> any(
251
1
            RegularWithAllocatorSupport(allocator), allocator);
252
1
    AnyHolder<TrackingAllocatorNonProp<uint8_t>> anyCopy(
253
1
            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
1
            anyCopy.get<RegularWithAllocatorSupport>().get_allocator());
259
1
}
260
261
TEST(AllocatorPropagatingCopyTest, copyAnyNoInit)
262
1
{
263
1
    const TrackingAllocatorNonProp<uint8_t> allocator;
264
265
1
    const AnyHolder<TrackingAllocatorNonProp<uint8_t>> emptyAny(allocator);
266
267
1
    AnyHolder<TrackingAllocatorNonProp<uint8_t>> emptyAnyCopy(
268
1
            NoInit, allocatorPropagatingCopy<RegularWithAllocatorSupportNoInit>(NoInit, emptyAny, allocator));
269
270
1
    const AnyHolder<TrackingAllocatorNonProp<uint8_t>> any(
271
1
            NoInit, RegularWithAllocatorSupportNoInit(allocator), allocator);
272
1
    AnyHolder<TrackingAllocatorNonProp<uint8_t>> anyCopy(
273
1
            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
1
            anyCopy.get<RegularWithAllocatorSupportNoInit>().get_allocator());
279
1
}
280
281
TEST(AllocatorPropagatingCopyTest, copyVector)
282
1
{
283
1
    RegularWithAllocatorSupport::allocator_type allocator;
284
285
1
    const std::vector<RegularWithAllocatorSupport,
286
1
            RegularWithAllocatorSupport::allocator_type> emptyVec(allocator);
287
1
    std::vector<RegularWithAllocatorSupport, RegularWithAllocatorSupport::allocator_type> emptyVecCopy(
288
1
            allocatorPropagatingCopy(emptyVec, allocator));
289
1
    ASSERT_EQ(emptyVec.get_allocator(), emptyVecCopy.get_allocator());
290
291
1
    std::vector<RegularWithAllocatorSupport, RegularWithAllocatorSupport::allocator_type> vec(allocator);
292
1
    vec.emplace_back(allocator);
293
1
    vec.emplace_back(allocator);
294
1
    std::vector<RegularWithAllocatorSupport, RegularWithAllocatorSupport::allocator_type> vecCopy(
295
1
            allocatorPropagatingCopy(vec, allocator));
296
1
    ASSERT_EQ(vec.get_allocator(), vecCopy.get_allocator());
297
1
    ASSERT_EQ(vec.size(), vecCopy.size());
298
1
    ASSERT_TRUE(std::equal(vec.begin(), vec.end(), vecCopy.begin(),
299
1
                           [](const RegularWithAllocatorSupport& a, const RegularWithAllocatorSupport& b)
300
1
                           {
301
1
                               return a.get_allocator() == b.get_allocator();
302
1
                           }));
303
1
}
304
305
TEST(AllocatorPropagatingCopyTest, copyVectorRegular)
306
1
{
307
1
    std::allocator<RegularType> allocator;
308
309
1
    const std::vector<RegularType> emptyVec(allocator);
310
1
    std::vector<RegularType> emptyVecCopy(allocatorPropagatingCopy(emptyVec, allocator));
311
1
    ASSERT_EQ(emptyVec.get_allocator(), emptyVecCopy.get_allocator());
312
1
}
313
314
TEST(AllocatorPropagatingCopyTest, copyString)
315
1
{
316
1
    RegularWithAllocatorSupport::allocator_type allocator;
317
318
1
    const std::basic_string<char, std::char_traits<char>,
319
1
            RegularWithAllocatorSupport::allocator_type> emptyString(allocator);
320
1
    std::basic_string<char, std::char_traits<char>,
321
1
            RegularWithAllocatorSupport::allocator_type> emptyStringCopy(
322
1
                    allocatorPropagatingCopy(emptyString, allocator));
323
1
    ASSERT_EQ(emptyString.get_allocator(), emptyStringCopy.get_allocator());
324
1
}
325
326
} // namespace zserio
327