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 using namespace cv;
45 
46 namespace {
47 
48 struct Reporter {
Reporter__anon67708fb30111::Reporter49     Reporter(bool* deleted) : deleted_(deleted)
50     { *deleted_ = false; }
51 
52     // the destructor is virtual, so that we can test dynamic_cast later
~Reporter__anon67708fb30111::Reporter53     virtual ~Reporter()
54     { *deleted_ = true; }
55 
56 private:
57     bool* deleted_;
58 
59     Reporter(const Reporter&);
60     Reporter& operator = (const Reporter&);
61 };
62 
63 struct ReportingDeleter {
ReportingDeleter__anon67708fb30111::ReportingDeleter64     ReportingDeleter(bool* deleted) : deleted_(deleted)
65     { *deleted_ = false; }
66 
operator ()__anon67708fb30111::ReportingDeleter67     void operator()(void*)
68     { *deleted_ = true; }
69 
70 private:
71     bool* deleted_;
72 };
73 
74 int dummyObject;
75 
76 }
77 
TEST(Core_Ptr,default_ctor)78 TEST(Core_Ptr, default_ctor)
79 {
80     Ptr<int> p;
81     EXPECT_EQ(NULL, p.get());
82 }
83 
TEST(Core_Ptr,owning_ctor)84 TEST(Core_Ptr, owning_ctor)
85 {
86     bool deleted = false;
87 
88     {
89         Reporter* r = new Reporter(&deleted);
90         Ptr<void> p(r);
91         EXPECT_EQ(r, p.get());
92     }
93 
94     EXPECT_TRUE(deleted);
95 
96     {
97         Ptr<int> p(&dummyObject, ReportingDeleter(&deleted));
98         EXPECT_EQ(&dummyObject, p.get());
99     }
100 
101     EXPECT_TRUE(deleted);
102 
103     {
104         Ptr<void> p((void*)0, ReportingDeleter(&deleted));
105         EXPECT_EQ(NULL, p.get());
106     }
107 
108     EXPECT_FALSE(deleted);
109 }
110 
TEST(Core_Ptr,sharing_ctor)111 TEST(Core_Ptr, sharing_ctor)
112 {
113     bool deleted = false;
114 
115     {
116         Ptr<Reporter> p1(new Reporter(&deleted));
117         Ptr<Reporter> p2(p1);
118         EXPECT_EQ(p1.get(), p2.get());
119         p1.release();
120         EXPECT_FALSE(deleted);
121     }
122 
123     EXPECT_TRUE(deleted);
124 
125     {
126         Ptr<Reporter> p1(new Reporter(&deleted));
127         Ptr<void> p2(p1);
128         EXPECT_EQ(p1.get(), p2.get());
129         p1.release();
130         EXPECT_FALSE(deleted);
131     }
132 
133     EXPECT_TRUE(deleted);
134 
135     {
136         Ptr<Reporter> p1(new Reporter(&deleted));
137         Ptr<int> p2(p1, &dummyObject);
138         EXPECT_EQ(&dummyObject, p2.get());
139         p1.release();
140         EXPECT_FALSE(deleted);
141     }
142 
143     EXPECT_TRUE(deleted);
144 }
145 
TEST(Core_Ptr,assignment)146 TEST(Core_Ptr, assignment)
147 {
148     bool deleted1 = false, deleted2 = false;
149 
150     {
151         Ptr<Reporter> p1(new Reporter(&deleted1));
152         p1 = p1;
153         EXPECT_FALSE(deleted1);
154     }
155 
156     EXPECT_TRUE(deleted1);
157 
158     {
159         Ptr<Reporter> p1(new Reporter(&deleted1));
160         Ptr<Reporter> p2(new Reporter(&deleted2));
161         p2 = p1;
162         EXPECT_TRUE(deleted2);
163         EXPECT_EQ(p1.get(), p2.get());
164         p1.release();
165         EXPECT_FALSE(deleted1);
166     }
167 
168     EXPECT_TRUE(deleted1);
169 
170     {
171         Ptr<Reporter> p1(new Reporter(&deleted1));
172         Ptr<void> p2(new Reporter(&deleted2));
173         p2 = p1;
174         EXPECT_TRUE(deleted2);
175         EXPECT_EQ(p1.get(), p2.get());
176         p1.release();
177         EXPECT_FALSE(deleted1);
178     }
179 
180     EXPECT_TRUE(deleted1);
181 }
182 
TEST(Core_Ptr,release)183 TEST(Core_Ptr, release)
184 {
185     bool deleted = false;
186 
187     Ptr<Reporter> p1(new Reporter(&deleted));
188     p1.release();
189     EXPECT_TRUE(deleted);
190     EXPECT_EQ(NULL, p1.get());
191 }
192 
TEST(Core_Ptr,reset)193 TEST(Core_Ptr, reset)
194 {
195     bool deleted_old = false, deleted_new = false;
196 
197     {
198         Ptr<void> p(new Reporter(&deleted_old));
199         Reporter* r = new Reporter(&deleted_new);
200         p.reset(r);
201         EXPECT_TRUE(deleted_old);
202         EXPECT_EQ(r, p.get());
203     }
204 
205     EXPECT_TRUE(deleted_new);
206 
207     {
208         Ptr<void> p(new Reporter(&deleted_old));
209         p.reset(&dummyObject, ReportingDeleter(&deleted_new));
210         EXPECT_TRUE(deleted_old);
211         EXPECT_EQ(&dummyObject, p.get());
212     }
213 
214     EXPECT_TRUE(deleted_new);
215 }
216 
TEST(Core_Ptr,swap)217 TEST(Core_Ptr, swap)
218 {
219     bool deleted1 = false, deleted2 = false;
220 
221     {
222         Reporter* r1 = new Reporter(&deleted1);
223         Reporter* r2 = new Reporter(&deleted2);
224         Ptr<Reporter> p1(r1), p2(r2);
225         p1.swap(p2);
226         EXPECT_EQ(r1, p2.get());
227         EXPECT_EQ(r2, p1.get());
228         EXPECT_FALSE(deleted1);
229         EXPECT_FALSE(deleted2);
230         p1.release();
231         EXPECT_TRUE(deleted2);
232     }
233 
234     EXPECT_TRUE(deleted1);
235 
236     {
237         Reporter* r1 = new Reporter(&deleted1);
238         Reporter* r2 = new Reporter(&deleted2);
239         Ptr<Reporter> p1(r1), p2(r2);
240         swap(p1, p2);
241         EXPECT_EQ(r1, p2.get());
242         EXPECT_EQ(r2, p1.get());
243         EXPECT_FALSE(deleted1);
244         EXPECT_FALSE(deleted2);
245         p1.release();
246         EXPECT_TRUE(deleted2);
247     }
248 
249     EXPECT_TRUE(deleted1);
250 }
251 
TEST(Core_Ptr,accessors)252 TEST(Core_Ptr, accessors)
253 {
254     {
255         Ptr<int> p;
256         EXPECT_EQ(NULL, static_cast<int*>(p));
257         EXPECT_TRUE(p.empty());
258     }
259 
260     {
261         Size* s = new Size();
262         Ptr<Size> p(s);
263         EXPECT_EQ(s, static_cast<Size*>(p));
264         EXPECT_EQ(s, &*p);
265         EXPECT_EQ(&s->width, &p->width);
266         EXPECT_FALSE(p.empty());
267     }
268 }
269 
270 namespace {
271 
272 struct SubReporterBase {
~SubReporterBase__anon67708fb30211::SubReporterBase273     virtual ~SubReporterBase() {}
274     int padding;
275 };
276 
277 /* multiple inheritance, so that casts do something interesting */
278 struct SubReporter : SubReporterBase, Reporter
279 {
SubReporter__anon67708fb30211::SubReporter280     SubReporter(bool* deleted) : Reporter(deleted)
281     {}
282 };
283 
284 }
285 
TEST(Core_Ptr,casts)286 TEST(Core_Ptr, casts)
287 {
288     bool deleted = false;
289 
290     {
291         Ptr<const Reporter> p1(new Reporter(&deleted));
292         Ptr<Reporter> p2 = p1.constCast<Reporter>();
293         EXPECT_EQ(p1.get(), p2.get());
294         p1.release();
295         EXPECT_FALSE(deleted);
296     }
297 
298     EXPECT_TRUE(deleted);
299 
300     {
301         SubReporter* sr = new SubReporter(&deleted);
302         Ptr<Reporter> p1(sr);
303         // This next check isn't really for Ptr itself; it checks that Reporter
304         // is at a non-zero offset within SubReporter, so that the next
305         // check will give us more confidence that the cast actually did something.
306         EXPECT_NE(static_cast<void*>(sr), static_cast<void*>(p1.get()));
307         Ptr<SubReporter> p2 = p1.staticCast<SubReporter>();
308         EXPECT_EQ(sr, p2.get());
309         p1.release();
310         EXPECT_FALSE(deleted);
311     }
312 
313     EXPECT_TRUE(deleted);
314 
315     {
316         SubReporter* sr = new SubReporter(&deleted);
317         Ptr<Reporter> p1(sr);
318         EXPECT_NE(static_cast<void*>(sr), static_cast<void*>(p1.get()));
319         Ptr<void> p2 = p1.dynamicCast<void>();
320         EXPECT_EQ(sr, p2.get());
321         p1.release();
322         EXPECT_FALSE(deleted);
323     }
324 
325     EXPECT_TRUE(deleted);
326 
327     {
328         Ptr<Reporter> p1(new Reporter(&deleted));
329         Ptr<SubReporter> p2 = p1.dynamicCast<SubReporter>();
330         EXPECT_EQ(NULL, p2.get());
331         p1.release();
332         EXPECT_FALSE(deleted);
333     }
334 
335     EXPECT_TRUE(deleted);
336 }
337 
TEST(Core_Ptr,comparisons)338 TEST(Core_Ptr, comparisons)
339 {
340     Ptr<int> p1, p2(new int), p3(new int);
341     Ptr<int> p4(p2, p3.get());
342 
343     // Not using EXPECT_EQ here, since none of them are really "expected" or "actual".
344     EXPECT_TRUE(p1 == p1);
345     EXPECT_TRUE(p2 == p2);
346     EXPECT_TRUE(p2 != p3);
347     EXPECT_TRUE(p2 != p4);
348     EXPECT_TRUE(p3 == p4);
349 }
350 
TEST(Core_Ptr,make)351 TEST(Core_Ptr, make)
352 {
353     bool deleted = true;
354 
355     {
356         Ptr<void> p = makePtr<Reporter>(&deleted);
357         EXPECT_FALSE(deleted);
358     }
359 
360     EXPECT_TRUE(deleted);
361 }
362 
363 namespace {
364 
365 struct SpeciallyDeletable
366 {
SpeciallyDeletable__anon67708fb30311::SpeciallyDeletable367     SpeciallyDeletable() : deleted(false)
368     {}
369     bool deleted;
370 };
371 
372 }
373 
374 namespace cv {
375 
376 template<>
operator ()(SpeciallyDeletable * obj) const377 void DefaultDeleter<SpeciallyDeletable>::operator()(SpeciallyDeletable * obj) const
378 { obj->deleted = true; }
379 
380 }
381 
TEST(Core_Ptr,specialized_deleter)382 TEST(Core_Ptr, specialized_deleter)
383 {
384     SpeciallyDeletable sd;
385 
386     { Ptr<void> p(&sd); }
387 
388     ASSERT_TRUE(sd.deleted);
389 }
390