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 { 49 Reporter(bool* deleted) : deleted_(deleted) 50 { *deleted_ = false; } 51 52 // the destructor is virtual, so that we can test dynamic_cast later 53 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 { 64 ReportingDeleter(bool* deleted) : deleted_(deleted) 65 { *deleted_ = false; } 66 67 void operator()(void*) 68 { *deleted_ = true; } 69 70 private: 71 bool* deleted_; 72 }; 73 74 int dummyObject; 75 76 } 77 78 TEST(Core_Ptr, default_ctor) 79 { 80 Ptr<int> p; 81 EXPECT_EQ(NULL, p.get()); 82 } 83 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 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 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 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 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 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 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 { 273 virtual ~SubReporterBase() {} 274 int padding; 275 }; 276 277 /* multiple inheritance, so that casts do something interesting */ 278 struct SubReporter : SubReporterBase, Reporter 279 { 280 SubReporter(bool* deleted) : Reporter(deleted) 281 {} 282 }; 283 284 } 285 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 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 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 { 367 SpeciallyDeletable() : deleted(false) 368 {} 369 bool deleted; 370 }; 371 372 } 373 374 namespace cv { 375 376 template<> 377 void DefaultDeleter<SpeciallyDeletable>::operator()(SpeciallyDeletable * obj) const 378 { obj->deleted = true; } 379 380 } 381 382 TEST(Core_Ptr, specialized_deleter) 383 { 384 SpeciallyDeletable sd; 385 386 { Ptr<void> p(&sd); } 387 388 ASSERT_TRUE(sd.deleted); 389 } 390