Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/core/test/test_ptr.cpp
16337 views
1
/*M///////////////////////////////////////////////////////////////////////////////////////
2
//
3
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4
//
5
// By downloading, copying, installing or using the software you agree to this license.
6
// If you do not agree to this license, do not download, install,
7
// copy or use the software.
8
//
9
//
10
// License Agreement
11
// For Open Source Computer Vision Library
12
//
13
// Copyright (C) 2013, NVIDIA Corporation, all rights reserved.
14
// Third party copyrights are property of their respective owners.
15
//
16
// Redistribution and use in source and binary forms, with or without modification,
17
// are permitted provided that the following conditions are met:
18
//
19
// * Redistribution's of source code must retain the above copyright notice,
20
// this list of conditions and the following disclaimer.
21
//
22
// * Redistribution's in binary form must reproduce the above copyright notice,
23
// this list of conditions and the following disclaimer in the documentation
24
// and/or other materials provided with the distribution.
25
//
26
// * The name of the copyright holders may not be used to endorse or promote products
27
// derived from this software without specific prior written permission.
28
//
29
// This software is provided by the copyright holders and contributors "as is" and
30
// any express or implied warranties, including, but not limited to, the implied
31
// warranties of merchantability and fitness for a particular purpose are disclaimed.
32
// In no event shall the copyright holders or contributors be liable for any direct,
33
// indirect, incidental, special, exemplary, or consequential damages
34
// (including, but not limited to, procurement of substitute goods or services;
35
// loss of use, data, or profits; or business interruption) however caused
36
// and on any theory of liability, whether in contract, strict liability,
37
// or tort (including negligence or otherwise) arising in any way out of
38
// the use of this software, even if advised of the possibility of such damage.
39
//
40
//M*/
41
42
#include "test_precomp.hpp"
43
44
namespace opencv_test { namespace {
45
46
#ifdef GTEST_CAN_COMPARE_NULL
47
# define EXPECT_NULL(ptr) EXPECT_EQ(NULL, ptr)
48
#else
49
# define EXPECT_NULL(ptr) EXPECT_TRUE(ptr == NULL)
50
#endif
51
52
using namespace cv;
53
54
namespace {
55
56
struct Reporter {
57
Reporter(bool* deleted) : deleted_(deleted)
58
{ *deleted_ = false; }
59
60
// the destructor is virtual, so that we can test dynamic_cast later
61
virtual ~Reporter()
62
{ *deleted_ = true; }
63
64
private:
65
bool* deleted_;
66
67
Reporter(const Reporter&);
68
Reporter& operator = (const Reporter&);
69
};
70
71
struct ReportingDeleter {
72
ReportingDeleter(bool* deleted) : deleted_(deleted)
73
{ *deleted_ = false; }
74
75
void operator()(void*)
76
{ *deleted_ = true; }
77
78
private:
79
bool* deleted_;
80
};
81
82
int dummyObject;
83
84
}
85
86
TEST(Core_Ptr, default_ctor)
87
{
88
Ptr<int> p;
89
EXPECT_NULL(p.get());
90
}
91
92
TEST(Core_Ptr, owning_ctor)
93
{
94
bool deleted = false;
95
96
{
97
Reporter* r = new Reporter(&deleted);
98
Ptr<void> p(r);
99
EXPECT_EQ(r, p.get());
100
}
101
EXPECT_TRUE(deleted);
102
103
{
104
Ptr<int> p(&dummyObject, ReportingDeleter(&deleted));
105
EXPECT_EQ(&dummyObject, p.get());
106
}
107
EXPECT_TRUE(deleted);
108
109
{
110
Ptr<void> p((void*)0, ReportingDeleter(&deleted));
111
EXPECT_NULL(p.get());
112
}
113
EXPECT_TRUE(deleted); // Differ from OpenCV 3.4 (but conformant to std::shared_ptr, see below)
114
115
{
116
std::shared_ptr<void> p((void*)0, ReportingDeleter(&deleted));
117
EXPECT_NULL(p.get());
118
}
119
EXPECT_TRUE(deleted);
120
}
121
122
TEST(Core_Ptr, sharing_ctor)
123
{
124
bool deleted = false;
125
126
{
127
Ptr<Reporter> p1(new Reporter(&deleted));
128
Ptr<Reporter> p2(p1);
129
EXPECT_EQ(p1.get(), p2.get());
130
p1.release();
131
EXPECT_FALSE(deleted);
132
}
133
134
EXPECT_TRUE(deleted);
135
136
{
137
Ptr<Reporter> p1(new Reporter(&deleted));
138
Ptr<void> p2(p1);
139
EXPECT_EQ(p1.get(), p2.get());
140
p1.release();
141
EXPECT_FALSE(deleted);
142
}
143
144
EXPECT_TRUE(deleted);
145
146
{
147
Ptr<Reporter> p1(new Reporter(&deleted));
148
Ptr<int> p2(p1, &dummyObject);
149
EXPECT_EQ(&dummyObject, p2.get());
150
p1.release();
151
EXPECT_FALSE(deleted);
152
}
153
154
EXPECT_TRUE(deleted);
155
}
156
157
TEST(Core_Ptr, assignment)
158
{
159
bool deleted1 = false, deleted2 = false;
160
161
{
162
Ptr<Reporter> p1(new Reporter(&deleted1));
163
p1 = p1;
164
EXPECT_FALSE(deleted1);
165
}
166
167
EXPECT_TRUE(deleted1);
168
169
{
170
Ptr<Reporter> p1(new Reporter(&deleted1));
171
Ptr<Reporter> p2(new Reporter(&deleted2));
172
p2 = p1;
173
EXPECT_TRUE(deleted2);
174
EXPECT_EQ(p1.get(), p2.get());
175
p1.release();
176
EXPECT_FALSE(deleted1);
177
}
178
179
EXPECT_TRUE(deleted1);
180
181
{
182
Ptr<Reporter> p1(new Reporter(&deleted1));
183
Ptr<void> p2(new Reporter(&deleted2));
184
p2 = p1;
185
EXPECT_TRUE(deleted2);
186
EXPECT_EQ(p1.get(), p2.get());
187
p1.release();
188
EXPECT_FALSE(deleted1);
189
}
190
191
EXPECT_TRUE(deleted1);
192
}
193
194
TEST(Core_Ptr, release)
195
{
196
bool deleted = false;
197
198
Ptr<Reporter> p1(new Reporter(&deleted));
199
p1.release();
200
EXPECT_TRUE(deleted);
201
EXPECT_NULL(p1.get());
202
}
203
204
TEST(Core_Ptr, reset)
205
{
206
bool deleted_old = false, deleted_new = false;
207
208
{
209
Ptr<void> p(new Reporter(&deleted_old));
210
Reporter* r = new Reporter(&deleted_new);
211
p.reset(r);
212
EXPECT_TRUE(deleted_old);
213
EXPECT_EQ(r, p.get());
214
}
215
216
EXPECT_TRUE(deleted_new);
217
218
{
219
Ptr<void> p(new Reporter(&deleted_old));
220
p.reset(&dummyObject, ReportingDeleter(&deleted_new));
221
EXPECT_TRUE(deleted_old);
222
EXPECT_EQ(&dummyObject, p.get());
223
}
224
225
EXPECT_TRUE(deleted_new);
226
}
227
228
TEST(Core_Ptr, swap)
229
{
230
bool deleted1 = false, deleted2 = false;
231
232
{
233
Reporter* r1 = new Reporter(&deleted1);
234
Reporter* r2 = new Reporter(&deleted2);
235
Ptr<Reporter> p1(r1), p2(r2);
236
p1.swap(p2);
237
EXPECT_EQ(r1, p2.get());
238
EXPECT_EQ(r2, p1.get());
239
EXPECT_FALSE(deleted1);
240
EXPECT_FALSE(deleted2);
241
p1.release();
242
EXPECT_TRUE(deleted2);
243
}
244
245
EXPECT_TRUE(deleted1);
246
247
{
248
Reporter* r1 = new Reporter(&deleted1);
249
Reporter* r2 = new Reporter(&deleted2);
250
Ptr<Reporter> p1(r1), p2(r2);
251
swap(p1, p2);
252
EXPECT_EQ(r1, p2.get());
253
EXPECT_EQ(r2, p1.get());
254
EXPECT_FALSE(deleted1);
255
EXPECT_FALSE(deleted2);
256
p1.release();
257
EXPECT_TRUE(deleted2);
258
}
259
260
EXPECT_TRUE(deleted1);
261
}
262
263
TEST(Core_Ptr, accessors)
264
{
265
{
266
Ptr<int> p;
267
EXPECT_NULL(static_cast<int*>(p));
268
EXPECT_TRUE(p.empty());
269
}
270
271
{
272
Size* s = new Size();
273
Ptr<Size> p(s);
274
EXPECT_EQ(s, static_cast<Size*>(p));
275
EXPECT_EQ(s, &*p);
276
EXPECT_EQ(&s->width, &p->width);
277
EXPECT_FALSE(p.empty());
278
}
279
}
280
281
namespace {
282
283
struct SubReporterBase {
284
virtual ~SubReporterBase() {}
285
int padding;
286
};
287
288
/* multiple inheritance, so that casts do something interesting */
289
struct SubReporter : SubReporterBase, Reporter
290
{
291
SubReporter(bool* deleted) : Reporter(deleted)
292
{}
293
};
294
295
}
296
297
TEST(Core_Ptr, casts)
298
{
299
bool deleted = false;
300
301
{
302
Ptr<const Reporter> p1(new Reporter(&deleted));
303
Ptr<Reporter> p2 = p1.constCast<Reporter>();
304
EXPECT_EQ(p1.get(), p2.get());
305
p1.release();
306
EXPECT_FALSE(deleted);
307
}
308
309
EXPECT_TRUE(deleted);
310
311
{
312
SubReporter* sr = new SubReporter(&deleted);
313
Ptr<Reporter> p1(sr);
314
// This next check isn't really for Ptr itself; it checks that Reporter
315
// is at a non-zero offset within SubReporter, so that the next
316
// check will give us more confidence that the cast actually did something.
317
EXPECT_NE(static_cast<void*>(sr), static_cast<void*>(p1.get()));
318
Ptr<SubReporter> p2 = p1.staticCast<SubReporter>();
319
EXPECT_EQ(sr, p2.get());
320
p1.release();
321
EXPECT_FALSE(deleted);
322
}
323
324
EXPECT_TRUE(deleted);
325
326
{
327
SubReporter* sr = new SubReporter(&deleted);
328
Ptr<Reporter> p1(sr);
329
EXPECT_NE(static_cast<void*>(sr), static_cast<void*>(p1.get()));
330
Ptr<void> p2 = p1.dynamicCast<void>();
331
EXPECT_EQ(sr, p2.get());
332
p1.release();
333
EXPECT_FALSE(deleted);
334
}
335
336
EXPECT_TRUE(deleted);
337
338
{
339
Ptr<Reporter> p1(new Reporter(&deleted));
340
Ptr<SubReporter> p2 = p1.dynamicCast<SubReporter>();
341
EXPECT_NULL(p2.get());
342
p1.release();
343
EXPECT_TRUE(deleted);
344
}
345
346
EXPECT_TRUE(deleted);
347
}
348
349
TEST(Core_Ptr, comparisons)
350
{
351
Ptr<int> p1, p2(new int), p3(new int);
352
Ptr<int> p4(p2, p3.get());
353
354
// Not using EXPECT_EQ here, since none of them are really "expected" or "actual".
355
EXPECT_TRUE(p1 == p1);
356
EXPECT_TRUE(p2 == p2);
357
EXPECT_TRUE(p2 != p3);
358
EXPECT_TRUE(p2 != p4);
359
EXPECT_TRUE(p3 == p4);
360
}
361
362
TEST(Core_Ptr, make)
363
{
364
bool deleted = true;
365
366
{
367
Ptr<void> p = makePtr<Reporter>(&deleted);
368
EXPECT_FALSE(deleted);
369
}
370
371
EXPECT_TRUE(deleted);
372
}
373
374
}} // namespace
375
376
namespace {
377
378
struct SpeciallyDeletable
379
{
380
SpeciallyDeletable() : deleted(false)
381
{}
382
bool deleted;
383
};
384
385
} // namespace
386
387
namespace cv {
388
template<> struct DefaultDeleter<SpeciallyDeletable>
389
{
390
void operator()(SpeciallyDeletable * obj) const { obj->deleted = true; }
391
};
392
} // namespace
393
394
namespace opencv_test { namespace {
395
396
TEST(Core_Ptr, specialized_deleter)
397
{
398
SpeciallyDeletable sd;
399
400
{ Ptr<void> p(&sd); }
401
402
ASSERT_TRUE(sd.deleted);
403
}
404
405
TEST(Core_Ptr, specialized_deleter_via_reset)
406
{
407
SpeciallyDeletable sd;
408
409
{
410
Ptr<SpeciallyDeletable> p;
411
p.reset(&sd);
412
}
413
414
ASSERT_TRUE(sd.deleted);
415
}
416
417
}} // namespace
418
419