Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(709)

Side by Side Diff: base/memory/scoped_ptr_unittest.cc

Issue 1801823003: Remove legacy scoped_ptr implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Restore operators Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/memory/scoped_ptr.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/memory/scoped_ptr.h"
6
7 #include <stddef.h>
8
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/macros.h"
12 #include "build/build_config.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace {
16
17 // Used to test depth subtyping.
18 class ConDecLoggerParent {
19 public:
20 virtual ~ConDecLoggerParent() {}
21
22 virtual void SetPtr(int* ptr) = 0;
23
24 virtual int SomeMeth(int x) const = 0;
25 };
26
27 class ConDecLogger : public ConDecLoggerParent {
28 public:
29 ConDecLogger() : ptr_(NULL) { }
30 explicit ConDecLogger(int* ptr) { SetPtr(ptr); }
31 ~ConDecLogger() override { --*ptr_; }
32
33 void SetPtr(int* ptr) override {
34 ptr_ = ptr;
35 ++*ptr_;
36 }
37
38 int SomeMeth(int x) const override { return x; }
39
40 private:
41 int* ptr_;
42
43 DISALLOW_COPY_AND_ASSIGN(ConDecLogger);
44 };
45
46 struct CountingDeleter {
47 explicit CountingDeleter(int* count) : count_(count) {}
48 inline void operator()(double* ptr) const {
49 (*count_)++;
50 }
51 int* count_;
52 };
53
54 // Used to test assignment of convertible deleters.
55 struct CountingDeleterChild : public CountingDeleter {
56 explicit CountingDeleterChild(int* count) : CountingDeleter(count) {}
57 };
58
59 class OverloadedNewAndDelete {
60 public:
61 void* operator new(size_t size) {
62 g_new_count++;
63 return malloc(size);
64 }
65
66 void operator delete(void* ptr) {
67 g_delete_count++;
68 free(ptr);
69 }
70
71 static void ResetCounters() {
72 g_new_count = 0;
73 g_delete_count = 0;
74 }
75
76 static int new_count() { return g_new_count; }
77 static int delete_count() { return g_delete_count; }
78
79 private:
80 static int g_new_count;
81 static int g_delete_count;
82 };
83
84 int OverloadedNewAndDelete::g_new_count = 0;
85 int OverloadedNewAndDelete::g_delete_count = 0;
86
87 scoped_ptr<ConDecLogger> PassThru(scoped_ptr<ConDecLogger> logger) {
88 return logger;
89 }
90
91 void GrabAndDrop(scoped_ptr<ConDecLogger> logger) {
92 }
93
94 // Do not delete this function! It's existence is to test that you can
95 // return a temporarily constructed version of the scoper.
96 scoped_ptr<ConDecLogger> TestReturnOfType(int* constructed) {
97 return scoped_ptr<ConDecLogger>(new ConDecLogger(constructed));
98 }
99
100 } // namespace
101
102 TEST(ScopedPtrTest, ScopedPtr) {
103 int constructed = 0;
104
105 // Ensure size of scoped_ptr<> doesn't increase unexpectedly.
106 static_assert(sizeof(int*) >= sizeof(scoped_ptr<int>),
107 "scoped_ptr shouldn't be larger than the raw pointer");
108
109 {
110 scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
111 EXPECT_EQ(1, constructed);
112 EXPECT_TRUE(scoper.get());
113
114 EXPECT_EQ(10, scoper->SomeMeth(10));
115 EXPECT_EQ(10, scoper.get()->SomeMeth(10));
116 EXPECT_EQ(10, (*scoper).SomeMeth(10));
117 }
118 EXPECT_EQ(0, constructed);
119
120 // Test reset() and release()
121 {
122 scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
123 EXPECT_EQ(1, constructed);
124 EXPECT_TRUE(scoper.get());
125
126 scoper.reset(new ConDecLogger(&constructed));
127 EXPECT_EQ(1, constructed);
128 EXPECT_TRUE(scoper.get());
129
130 scoper.reset();
131 EXPECT_EQ(0, constructed);
132 EXPECT_FALSE(scoper.get());
133
134 scoper.reset(new ConDecLogger(&constructed));
135 EXPECT_EQ(1, constructed);
136 EXPECT_TRUE(scoper.get());
137
138 ConDecLogger* take = scoper.release();
139 EXPECT_EQ(1, constructed);
140 EXPECT_FALSE(scoper.get());
141 delete take;
142 EXPECT_EQ(0, constructed);
143
144 scoper.reset(new ConDecLogger(&constructed));
145 EXPECT_EQ(1, constructed);
146 EXPECT_TRUE(scoper.get());
147 }
148 EXPECT_EQ(0, constructed);
149
150 // Test swap().
151 {
152 scoped_ptr<ConDecLogger> scoper1;
153 scoped_ptr<ConDecLogger> scoper2;
154 EXPECT_TRUE(scoper1.get() == scoper2.get());
155 EXPECT_FALSE(scoper1.get() != scoper2.get());
156
157 ConDecLogger* logger = new ConDecLogger(&constructed);
158 scoper1.reset(logger);
159 EXPECT_EQ(logger, scoper1.get());
160 EXPECT_FALSE(scoper2.get());
161 EXPECT_FALSE(scoper1.get() == scoper2.get());
162 EXPECT_TRUE(scoper1.get() != scoper2.get());
163
164 scoper2.swap(scoper1);
165 EXPECT_EQ(logger, scoper2.get());
166 EXPECT_FALSE(scoper1.get());
167 EXPECT_FALSE(scoper1.get() == scoper2.get());
168 EXPECT_TRUE(scoper1.get() != scoper2.get());
169 }
170 EXPECT_EQ(0, constructed);
171 }
172
173 TEST(ScopedPtrTest, ScopedPtrDepthSubtyping) {
174 int constructed = 0;
175
176 // Test construction from a scoped_ptr to a derived class.
177 {
178 scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
179 EXPECT_EQ(1, constructed);
180 EXPECT_TRUE(scoper.get());
181
182 scoped_ptr<ConDecLoggerParent> scoper_parent(std::move(scoper));
183 EXPECT_EQ(1, constructed);
184 EXPECT_TRUE(scoper_parent.get());
185 EXPECT_FALSE(scoper.get());
186
187 EXPECT_EQ(10, scoper_parent->SomeMeth(10));
188 EXPECT_EQ(10, scoper_parent.get()->SomeMeth(10));
189 EXPECT_EQ(10, (*scoper_parent).SomeMeth(10));
190 }
191 EXPECT_EQ(0, constructed);
192
193 // Test assignment from a scoped_ptr to a derived class.
194 {
195 scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
196 EXPECT_EQ(1, constructed);
197 EXPECT_TRUE(scoper.get());
198
199 scoped_ptr<ConDecLoggerParent> scoper_parent;
200 scoper_parent = std::move(scoper);
201 EXPECT_EQ(1, constructed);
202 EXPECT_TRUE(scoper_parent.get());
203 EXPECT_FALSE(scoper.get());
204 }
205 EXPECT_EQ(0, constructed);
206
207 // Test construction of a scoped_ptr with an additional const annotation.
208 {
209 scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
210 EXPECT_EQ(1, constructed);
211 EXPECT_TRUE(scoper.get());
212
213 scoped_ptr<const ConDecLogger> scoper_const(std::move(scoper));
214 EXPECT_EQ(1, constructed);
215 EXPECT_TRUE(scoper_const.get());
216 EXPECT_FALSE(scoper.get());
217
218 EXPECT_EQ(10, scoper_const->SomeMeth(10));
219 EXPECT_EQ(10, scoper_const.get()->SomeMeth(10));
220 EXPECT_EQ(10, (*scoper_const).SomeMeth(10));
221 }
222 EXPECT_EQ(0, constructed);
223
224 // Test assignment to a scoped_ptr with an additional const annotation.
225 {
226 scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
227 EXPECT_EQ(1, constructed);
228 EXPECT_TRUE(scoper.get());
229
230 scoped_ptr<const ConDecLogger> scoper_const;
231 scoper_const = std::move(scoper);
232 EXPECT_EQ(1, constructed);
233 EXPECT_TRUE(scoper_const.get());
234 EXPECT_FALSE(scoper.get());
235 }
236 EXPECT_EQ(0, constructed);
237
238 // Test assignment to a scoped_ptr deleter of parent type.
239 {
240 // Custom deleters never touch these value.
241 double dummy_value, dummy_value2;
242 int deletes = 0;
243 int alternate_deletes = 0;
244 scoped_ptr<double, CountingDeleter> scoper(&dummy_value,
245 CountingDeleter(&deletes));
246 scoped_ptr<double, CountingDeleterChild> scoper_child(
247 &dummy_value2, CountingDeleterChild(&alternate_deletes));
248
249 EXPECT_TRUE(scoper);
250 EXPECT_TRUE(scoper_child);
251 EXPECT_EQ(0, deletes);
252 EXPECT_EQ(0, alternate_deletes);
253
254 // Test this compiles and correctly overwrites the deleter state.
255 scoper = std::move(scoper_child);
256 EXPECT_TRUE(scoper);
257 EXPECT_FALSE(scoper_child);
258 EXPECT_EQ(1, deletes);
259 EXPECT_EQ(0, alternate_deletes);
260
261 scoper.reset();
262 EXPECT_FALSE(scoper);
263 EXPECT_FALSE(scoper_child);
264 EXPECT_EQ(1, deletes);
265 EXPECT_EQ(1, alternate_deletes);
266
267 scoper_child.reset(&dummy_value);
268 EXPECT_TRUE(scoper_child);
269 EXPECT_EQ(1, deletes);
270 EXPECT_EQ(1, alternate_deletes);
271 scoped_ptr<double, CountingDeleter> scoper_construct(
272 std::move(scoper_child));
273 EXPECT_TRUE(scoper_construct);
274 EXPECT_FALSE(scoper_child);
275 EXPECT_EQ(1, deletes);
276 EXPECT_EQ(1, alternate_deletes);
277
278 scoper_construct.reset();
279 EXPECT_EQ(1, deletes);
280 EXPECT_EQ(2, alternate_deletes);
281 }
282 }
283
284 TEST(ScopedPtrTest, ScopedPtrWithArray) {
285 static const int kNumLoggers = 12;
286
287 int constructed = 0;
288
289 {
290 scoped_ptr<ConDecLogger[]> scoper(new ConDecLogger[kNumLoggers]);
291 EXPECT_TRUE(scoper);
292 EXPECT_EQ(&scoper[0], scoper.get());
293 for (int i = 0; i < kNumLoggers; ++i) {
294 scoper[i].SetPtr(&constructed);
295 }
296 EXPECT_EQ(12, constructed);
297
298 EXPECT_EQ(10, scoper.get()->SomeMeth(10));
299 EXPECT_EQ(10, scoper[2].SomeMeth(10));
300 }
301 EXPECT_EQ(0, constructed);
302
303 // Test reset() and release()
304 {
305 scoped_ptr<ConDecLogger[]> scoper;
306 EXPECT_FALSE(scoper.get());
307 EXPECT_FALSE(scoper.release());
308 EXPECT_FALSE(scoper.get());
309 scoper.reset();
310 EXPECT_FALSE(scoper.get());
311
312 scoper.reset(new ConDecLogger[kNumLoggers]);
313 for (int i = 0; i < kNumLoggers; ++i) {
314 scoper[i].SetPtr(&constructed);
315 }
316 EXPECT_EQ(12, constructed);
317 scoper.reset();
318 EXPECT_EQ(0, constructed);
319
320 scoper.reset(new ConDecLogger[kNumLoggers]);
321 for (int i = 0; i < kNumLoggers; ++i) {
322 scoper[i].SetPtr(&constructed);
323 }
324 EXPECT_EQ(12, constructed);
325 ConDecLogger* ptr = scoper.release();
326 EXPECT_EQ(12, constructed);
327 delete[] ptr;
328 EXPECT_EQ(0, constructed);
329 }
330 EXPECT_EQ(0, constructed);
331
332 // Test swap() and type-safe Boolean.
333 {
334 scoped_ptr<ConDecLogger[]> scoper1;
335 scoped_ptr<ConDecLogger[]> scoper2;
336 EXPECT_TRUE(scoper1.get() == scoper2.get());
337 EXPECT_FALSE(scoper1.get() != scoper2.get());
338
339 ConDecLogger* loggers = new ConDecLogger[kNumLoggers];
340 for (int i = 0; i < kNumLoggers; ++i) {
341 loggers[i].SetPtr(&constructed);
342 }
343 scoper1.reset(loggers);
344 EXPECT_TRUE(scoper1);
345 EXPECT_EQ(loggers, scoper1.get());
346 EXPECT_FALSE(scoper2);
347 EXPECT_FALSE(scoper2.get());
348 EXPECT_FALSE(scoper1.get() == scoper2.get());
349 EXPECT_TRUE(scoper1.get() != scoper2.get());
350
351 scoper2.swap(scoper1);
352 EXPECT_EQ(loggers, scoper2.get());
353 EXPECT_FALSE(scoper1.get());
354 EXPECT_FALSE(scoper1.get() == scoper2.get());
355 EXPECT_TRUE(scoper1.get() != scoper2.get());
356 }
357 EXPECT_EQ(0, constructed);
358
359 {
360 ConDecLogger* loggers = new ConDecLogger[kNumLoggers];
361 scoped_ptr<ConDecLogger[]> scoper(loggers);
362 EXPECT_TRUE(scoper);
363 for (int i = 0; i < kNumLoggers; ++i) {
364 scoper[i].SetPtr(&constructed);
365 }
366 EXPECT_EQ(kNumLoggers, constructed);
367
368 // Test moving with constructor;
369 scoped_ptr<ConDecLogger[]> scoper2(std::move(scoper));
370 EXPECT_EQ(kNumLoggers, constructed);
371
372 // Test moving with assignment;
373 scoped_ptr<ConDecLogger[]> scoper3;
374 scoper3 = std::move(scoper2);
375 EXPECT_EQ(kNumLoggers, constructed);
376 EXPECT_FALSE(scoper);
377 EXPECT_FALSE(scoper2);
378 EXPECT_TRUE(scoper3);
379 }
380 EXPECT_EQ(0, constructed);
381 }
382
383 TEST(ScopedPtrTest, MoveBehavior) {
384 int constructed = 0;
385 {
386 ConDecLogger* logger = new ConDecLogger(&constructed);
387 scoped_ptr<ConDecLogger> scoper(logger);
388 EXPECT_EQ(1, constructed);
389
390 // Test moving with constructor;
391 scoped_ptr<ConDecLogger> scoper2(std::move(scoper));
392 EXPECT_EQ(1, constructed);
393
394 // Test moving with assignment;
395 scoped_ptr<ConDecLogger> scoper3;
396 scoper3 = std::move(scoper2);
397 EXPECT_EQ(1, constructed);
398 EXPECT_FALSE(scoper.get());
399 EXPECT_FALSE(scoper2.get());
400 EXPECT_TRUE(scoper3.get());
401 }
402
403 // Test that passing to function which does nothing does not leak.
404 {
405 ConDecLogger* logger = new ConDecLogger(&constructed);
406 scoped_ptr<ConDecLogger> scoper(logger);
407 EXPECT_EQ(1, constructed);
408
409 // Should auto-destruct logger by end of scope.
410 GrabAndDrop(std::move(scoper));
411 EXPECT_FALSE(scoper.get());
412 }
413 EXPECT_EQ(0, constructed);
414 }
415
416 TEST(ScopedPtrTest, ReturnTypeBehavior) {
417 int constructed = 0;
418
419 // Test that we can return a scoped_ptr.
420 {
421 ConDecLogger* logger = new ConDecLogger(&constructed);
422 scoped_ptr<ConDecLogger> scoper(logger);
423 EXPECT_EQ(1, constructed);
424
425 PassThru(std::move(scoper));
426 EXPECT_FALSE(scoper.get());
427 }
428 EXPECT_EQ(0, constructed);
429
430 // Test uncaught return type not leak.
431 {
432 ConDecLogger* logger = new ConDecLogger(&constructed);
433 scoped_ptr<ConDecLogger> scoper(logger);
434 EXPECT_EQ(1, constructed);
435
436 // Should auto-destruct logger by end of scope.
437 PassThru(std::move(scoper));
438 EXPECT_FALSE(scoper.get());
439 }
440 EXPECT_EQ(0, constructed);
441
442 // Call TestReturnOfType() so the compiler doesn't warn for an unused
443 // function.
444 {
445 TestReturnOfType(&constructed);
446 }
447 EXPECT_EQ(0, constructed);
448 }
449
450 TEST(ScopedPtrTest, CustomDeleter) {
451 double dummy_value; // Custom deleter never touches this value.
452 int deletes = 0;
453 int alternate_deletes = 0;
454
455 // Normal delete support.
456 {
457 deletes = 0;
458 scoped_ptr<double, CountingDeleter> scoper(&dummy_value,
459 CountingDeleter(&deletes));
460 EXPECT_EQ(0, deletes);
461 EXPECT_TRUE(scoper.get());
462 }
463 EXPECT_EQ(1, deletes);
464
465 // Test reset() and release().
466 deletes = 0;
467 {
468 scoped_ptr<double, CountingDeleter> scoper(NULL,
469 CountingDeleter(&deletes));
470 EXPECT_FALSE(scoper.get());
471 EXPECT_FALSE(scoper.release());
472 EXPECT_FALSE(scoper.get());
473 scoper.reset();
474 EXPECT_FALSE(scoper.get());
475 EXPECT_EQ(0, deletes);
476
477 scoper.reset(&dummy_value);
478 scoper.reset();
479 EXPECT_EQ(1, deletes);
480
481 scoper.reset(&dummy_value);
482 EXPECT_EQ(&dummy_value, scoper.release());
483 }
484 EXPECT_EQ(1, deletes);
485
486 // Test get_deleter().
487 deletes = 0;
488 alternate_deletes = 0;
489 {
490 scoped_ptr<double, CountingDeleter> scoper(&dummy_value,
491 CountingDeleter(&deletes));
492 // Call deleter manually.
493 EXPECT_EQ(0, deletes);
494 scoper.get_deleter()(&dummy_value);
495 EXPECT_EQ(1, deletes);
496
497 // Deleter is still there after reset.
498 scoper.reset();
499 EXPECT_EQ(2, deletes);
500 scoper.get_deleter()(&dummy_value);
501 EXPECT_EQ(3, deletes);
502
503 // Deleter can be assigned into (matches C++11 unique_ptr<> spec).
504 scoper.get_deleter() = CountingDeleter(&alternate_deletes);
505 scoper.reset(&dummy_value);
506 EXPECT_EQ(0, alternate_deletes);
507
508 }
509 EXPECT_EQ(3, deletes);
510 EXPECT_EQ(1, alternate_deletes);
511
512 // Test operator= deleter support.
513 deletes = 0;
514 alternate_deletes = 0;
515 {
516 double dummy_value2;
517 scoped_ptr<double, CountingDeleter> scoper(&dummy_value,
518 CountingDeleter(&deletes));
519 scoped_ptr<double, CountingDeleter> scoper2(
520 &dummy_value2,
521 CountingDeleter(&alternate_deletes));
522 EXPECT_EQ(0, deletes);
523 EXPECT_EQ(0, alternate_deletes);
524
525 // Pass the second deleter through a constructor and an operator=. Then
526 // reinitialize the empty scopers to ensure that each one is deleting
527 // properly.
528 scoped_ptr<double, CountingDeleter> scoper3(std::move(scoper2));
529 scoper = std::move(scoper3);
530 EXPECT_EQ(1, deletes);
531
532 scoper2.reset(&dummy_value2);
533 scoper3.reset(&dummy_value2);
534 EXPECT_EQ(0, alternate_deletes);
535
536 }
537 EXPECT_EQ(1, deletes);
538 EXPECT_EQ(3, alternate_deletes);
539
540 // Test swap(), and type-safe Boolean.
541 {
542 scoped_ptr<double, CountingDeleter> scoper1(NULL,
543 CountingDeleter(&deletes));
544 scoped_ptr<double, CountingDeleter> scoper2(NULL,
545 CountingDeleter(&deletes));
546 EXPECT_TRUE(scoper1.get() == scoper2.get());
547 EXPECT_FALSE(scoper1.get() != scoper2.get());
548
549 scoper1.reset(&dummy_value);
550 EXPECT_TRUE(scoper1);
551 EXPECT_EQ(&dummy_value, scoper1.get());
552 EXPECT_FALSE(scoper2);
553 EXPECT_FALSE(scoper2.get());
554 EXPECT_FALSE(scoper1.get() == scoper2.get());
555 EXPECT_TRUE(scoper1.get() != scoper2.get());
556
557 scoper2.swap(scoper1);
558 EXPECT_EQ(&dummy_value, scoper2.get());
559 EXPECT_FALSE(scoper1.get());
560 EXPECT_FALSE(scoper1.get() == scoper2.get());
561 EXPECT_TRUE(scoper1.get() != scoper2.get());
562 }
563 }
564
565 // Sanity check test for overloaded new and delete operators. Does not do full
566 // coverage of reset/release/move operations as that is redundant with the
567 // above.
568 TEST(ScopedPtrTest, OverloadedNewAndDelete) {
569 {
570 OverloadedNewAndDelete::ResetCounters();
571 scoped_ptr<OverloadedNewAndDelete> scoper(new OverloadedNewAndDelete());
572 EXPECT_TRUE(scoper.get());
573
574 scoped_ptr<OverloadedNewAndDelete> scoper2(std::move(scoper));
575 }
576 EXPECT_EQ(1, OverloadedNewAndDelete::delete_count());
577 EXPECT_EQ(1, OverloadedNewAndDelete::new_count());
578 }
579
580 scoped_ptr<int> NullIntReturn() {
581 return nullptr;
582 }
583
584 TEST(ScopedPtrTest, Nullptr) {
585 scoped_ptr<int> scoper1(nullptr);
586 scoped_ptr<int> scoper2(new int);
587 scoper2 = nullptr;
588 scoped_ptr<int> scoper3(NullIntReturn());
589 scoped_ptr<int> scoper4 = NullIntReturn();
590 EXPECT_EQ(nullptr, scoper1.get());
591 EXPECT_EQ(nullptr, scoper2.get());
592 EXPECT_EQ(nullptr, scoper3.get());
593 EXPECT_EQ(nullptr, scoper4.get());
594 }
595
596 scoped_ptr<int[]> NullIntArrayReturn() {
597 return nullptr;
598 }
599
600 TEST(ScopedPtrTest, NullptrArray) {
601 scoped_ptr<int[]> scoper1(nullptr);
602 scoped_ptr<int[]> scoper2(new int[3]);
603 scoper2 = nullptr;
604 scoped_ptr<int[]> scoper3(NullIntArrayReturn());
605 scoped_ptr<int[]> scoper4 = NullIntArrayReturn();
606 EXPECT_EQ(nullptr, scoper1.get());
607 EXPECT_EQ(nullptr, scoper2.get());
608 EXPECT_EQ(nullptr, scoper3.get());
609 EXPECT_EQ(nullptr, scoper4.get());
610 }
611
612 class Super {};
613 class Sub : public Super {};
614
615 scoped_ptr<Sub> SubClassReturn() {
616 return make_scoped_ptr(new Sub);
617 }
618
619 TEST(ScopedPtrTest, Conversion) {
620 scoped_ptr<Sub> sub1(new Sub);
621 scoped_ptr<Sub> sub2(new Sub);
622
623 // Upcast with move works.
624 scoped_ptr<Super> super1 = std::move(sub1);
625 super1 = std::move(sub2);
626
627 // Upcast with an rvalue works.
628 scoped_ptr<Super> super2 = SubClassReturn();
629 super2 = SubClassReturn();
630 }
631
632 TEST(ScopedPtrTest, ReferenceCycle) {
633 struct StructB;
634 struct StructA {
635 scoped_ptr<StructB> b;
636 };
637
638 struct StructB {
639 scoped_ptr<StructA> a;
640 };
641
642 // Create a reference cycle.
643 StructA* a = new StructA;
644 a->b.reset(new StructB);
645 a->b->a.reset(a);
646
647 // Break the cycle by calling reset(). This will cause |a| (and hence, |a->b|)
648 // to be deleted before the call to reset() returns. This tests that the
649 // implementation of scoped_ptr::reset() doesn't access |this| after it
650 // deletes the underlying pointer. This behaviour is consistent with the
651 // definition of unique_ptr::reset in C++11.
652 a->b.reset();
653 }
654
655 TEST(ScopedPtrTest, Operators) {
656 struct Parent {};
657 struct Child : public Parent {};
658
659 scoped_ptr<Parent> p(new Parent);
660 scoped_ptr<Parent> p2(new Parent);
661 scoped_ptr<Child> c(new Child);
662 scoped_ptr<Parent> pnull;
663
664 // Operator==.
665 EXPECT_TRUE(p == p);
666 EXPECT_FALSE(p == c);
667 EXPECT_FALSE(p == p2);
668 EXPECT_FALSE(p == pnull);
669
670 EXPECT_FALSE(p == nullptr);
671 EXPECT_FALSE(nullptr == p);
672 EXPECT_TRUE(pnull == nullptr);
673 EXPECT_TRUE(nullptr == pnull);
674
675 // Operator!=.
676 EXPECT_FALSE(p != p);
677 EXPECT_TRUE(p != c);
678 EXPECT_TRUE(p != p2);
679 EXPECT_TRUE(p != pnull);
680
681 EXPECT_TRUE(p != nullptr);
682 EXPECT_TRUE(nullptr != p);
683 EXPECT_FALSE(pnull != nullptr);
684 EXPECT_FALSE(nullptr != pnull);
685
686 // Compare two scoped_ptr<T>.
687 EXPECT_EQ(p.get() < p2.get(), p < p2);
688 EXPECT_EQ(p.get() <= p2.get(), p <= p2);
689 EXPECT_EQ(p.get() > p2.get(), p > p2);
690 EXPECT_EQ(p.get() >= p2.get(), p >= p2);
691 EXPECT_EQ(p2.get() < p.get(), p2 < p);
692 EXPECT_EQ(p2.get() <= p.get(), p2 <= p);
693 EXPECT_EQ(p2.get() > p.get(), p2 > p);
694 EXPECT_EQ(p2.get() >= p.get(), p2 >= p);
695
696 // And convertible scoped_ptr<T> and scoped_ptr<U>.
697 EXPECT_EQ(p.get() < c.get(), p < c);
698 EXPECT_EQ(p.get() <= c.get(), p <= c);
699 EXPECT_EQ(p.get() > c.get(), p > c);
700 EXPECT_EQ(p.get() >= c.get(), p >= c);
701 EXPECT_EQ(c.get() < p.get(), c < p);
702 EXPECT_EQ(c.get() <= p.get(), c <= p);
703 EXPECT_EQ(c.get() > p.get(), c > p);
704 EXPECT_EQ(c.get() >= p.get(), c >= p);
705
706 // Compare to nullptr.
707 EXPECT_TRUE(p > nullptr);
708 EXPECT_FALSE(nullptr > p);
709 EXPECT_FALSE(pnull > nullptr);
710 EXPECT_FALSE(nullptr > pnull);
711
712 EXPECT_TRUE(p >= nullptr);
713 EXPECT_FALSE(nullptr >= p);
714 EXPECT_TRUE(pnull >= nullptr);
715 EXPECT_TRUE(nullptr >= pnull);
716
717 EXPECT_FALSE(p < nullptr);
718 EXPECT_TRUE(nullptr < p);
719 EXPECT_FALSE(pnull < nullptr);
720 EXPECT_FALSE(nullptr < pnull);
721
722 EXPECT_FALSE(p <= nullptr);
723 EXPECT_TRUE(nullptr <= p);
724 EXPECT_TRUE(pnull <= nullptr);
725 EXPECT_TRUE(nullptr <= pnull);
726 };
727
728 TEST(ScopedPtrTest, ArrayOperators) {
729 struct Parent {};
730 struct Child : public Parent {};
731
732 scoped_ptr<Parent[]> p(new Parent[1]);
733 scoped_ptr<Parent[]> p2(new Parent[1]);
734 scoped_ptr<Child[]> c(new Child[1]);
735 scoped_ptr<Parent[]> pnull;
736
737 // Operator==.
738 EXPECT_TRUE(p == p);
739 EXPECT_FALSE(p == c);
740 EXPECT_FALSE(p == p2);
741 EXPECT_FALSE(p == pnull);
742
743 EXPECT_FALSE(p == nullptr);
744 EXPECT_FALSE(nullptr == p);
745 EXPECT_TRUE(pnull == nullptr);
746 EXPECT_TRUE(nullptr == pnull);
747
748 // Operator!=.
749 EXPECT_FALSE(p != p);
750 EXPECT_TRUE(p != c);
751 EXPECT_TRUE(p != p2);
752 EXPECT_TRUE(p != pnull);
753
754 EXPECT_TRUE(p != nullptr);
755 EXPECT_TRUE(nullptr != p);
756 EXPECT_FALSE(pnull != nullptr);
757 EXPECT_FALSE(nullptr != pnull);
758
759 // Compare two scoped_ptr<T>.
760 EXPECT_EQ(p.get() < p2.get(), p < p2);
761 EXPECT_EQ(p.get() <= p2.get(), p <= p2);
762 EXPECT_EQ(p.get() > p2.get(), p > p2);
763 EXPECT_EQ(p.get() >= p2.get(), p >= p2);
764 EXPECT_EQ(p2.get() < p.get(), p2 < p);
765 EXPECT_EQ(p2.get() <= p.get(), p2 <= p);
766 EXPECT_EQ(p2.get() > p.get(), p2 > p);
767 EXPECT_EQ(p2.get() >= p.get(), p2 >= p);
768
769 // And convertible scoped_ptr<T> and scoped_ptr<U>.
770 EXPECT_EQ(p.get() < c.get(), p < c);
771 EXPECT_EQ(p.get() <= c.get(), p <= c);
772 EXPECT_EQ(p.get() > c.get(), p > c);
773 EXPECT_EQ(p.get() >= c.get(), p >= c);
774 EXPECT_EQ(c.get() < p.get(), c < p);
775 EXPECT_EQ(c.get() <= p.get(), c <= p);
776 EXPECT_EQ(c.get() > p.get(), c > p);
777 EXPECT_EQ(c.get() >= p.get(), c >= p);
778
779 // Compare to nullptr.
780 EXPECT_TRUE(p > nullptr);
781 EXPECT_FALSE(nullptr > p);
782 EXPECT_FALSE(pnull > nullptr);
783 EXPECT_FALSE(nullptr > pnull);
784
785 EXPECT_TRUE(p >= nullptr);
786 EXPECT_FALSE(nullptr >= p);
787 EXPECT_TRUE(pnull >= nullptr);
788 EXPECT_TRUE(nullptr >= pnull);
789
790 EXPECT_FALSE(p < nullptr);
791 EXPECT_TRUE(nullptr < p);
792 EXPECT_FALSE(pnull < nullptr);
793 EXPECT_FALSE(nullptr < pnull);
794
795 EXPECT_FALSE(p <= nullptr);
796 EXPECT_TRUE(nullptr <= p);
797 EXPECT_TRUE(pnull <= nullptr);
798 EXPECT_TRUE(nullptr <= pnull);
799 }
800
801 // Boolean tests can be performed.
802 TEST(ScopedPtrTest, BooleanTesting) {
803 scoped_ptr<int> ptr_to_an_instance(new int);
804 EXPECT_TRUE(ptr_to_an_instance);
805 EXPECT_FALSE(!ptr_to_an_instance);
806
807 if (ptr_to_an_instance) {
808 } else {
809 ADD_FAILURE() << "Pointer to an instance should result in true.";
810 }
811
812 if (!ptr_to_an_instance) { // check for operator!().
813 ADD_FAILURE() << "Pointer to an instance should result in !x being false.";
814 }
815
816 scoped_ptr<int> null_ptr;
817 EXPECT_FALSE(null_ptr);
818 EXPECT_TRUE(!null_ptr);
819
820 if (null_ptr) {
821 ADD_FAILURE() << "Null pointer should result in false.";
822 }
823
824 if (!null_ptr) { // check for operator!().
825 } else {
826 ADD_FAILURE() << "Null pointer should result in !x being true.";
827 }
828 }
OLDNEW
« no previous file with comments | « base/memory/scoped_ptr.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698