Home | History | Annotate | Download | only in memory
      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 "base/basictypes.h"
      8 #include "base/bind.h"
      9 #include "base/callback.h"
     10 #include "testing/gtest/include/gtest/gtest.h"
     11 
     12 namespace {
     13 
     14 // Used to test depth subtyping.
     15 class ConDecLoggerParent {
     16  public:
     17   virtual ~ConDecLoggerParent() {}
     18 
     19   virtual void SetPtr(int* ptr) = 0;
     20 
     21   virtual int SomeMeth(int x) const = 0;
     22 };
     23 
     24 class ConDecLogger : public ConDecLoggerParent {
     25  public:
     26   ConDecLogger() : ptr_(NULL) { }
     27   explicit ConDecLogger(int* ptr) { SetPtr(ptr); }
     28   virtual ~ConDecLogger() { --*ptr_; }
     29 
     30   virtual void SetPtr(int* ptr) OVERRIDE { ptr_ = ptr; ++*ptr_; }
     31 
     32   virtual int SomeMeth(int x) const OVERRIDE { return x; }
     33 
     34  private:
     35   int* ptr_;
     36 
     37   DISALLOW_COPY_AND_ASSIGN(ConDecLogger);
     38 };
     39 
     40 struct CountingDeleter {
     41   explicit CountingDeleter(int* count) : count_(count) {}
     42   inline void operator()(double* ptr) const {
     43     (*count_)++;
     44   }
     45   int* count_;
     46 };
     47 
     48 // Used to test assignment of convertible deleters.
     49 struct CountingDeleterChild : public CountingDeleter {
     50   explicit CountingDeleterChild(int* count) : CountingDeleter(count) {}
     51 };
     52 
     53 class OverloadedNewAndDelete {
     54  public:
     55   void* operator new(size_t size) {
     56     g_new_count++;
     57     return malloc(size);
     58   }
     59 
     60   void operator delete(void* ptr) {
     61     g_delete_count++;
     62     free(ptr);
     63   }
     64 
     65   static void ResetCounters() {
     66     g_new_count = 0;
     67     g_delete_count = 0;
     68   }
     69 
     70   static int new_count() { return g_new_count; }
     71   static int delete_count() { return g_delete_count; }
     72 
     73  private:
     74   static int g_new_count;
     75   static int g_delete_count;
     76 };
     77 
     78 int OverloadedNewAndDelete::g_new_count = 0;
     79 int OverloadedNewAndDelete::g_delete_count = 0;
     80 
     81 scoped_ptr<ConDecLogger> PassThru(scoped_ptr<ConDecLogger> logger) {
     82   return logger.Pass();
     83 }
     84 
     85 void GrabAndDrop(scoped_ptr<ConDecLogger> logger) {
     86 }
     87 
     88 // Do not delete this function!  It's existence is to test that you can
     89 // return a temporarily constructed version of the scoper.
     90 scoped_ptr<ConDecLogger> TestReturnOfType(int* constructed) {
     91   return scoped_ptr<ConDecLogger>(new ConDecLogger(constructed));
     92 }
     93 
     94 scoped_ptr<ConDecLoggerParent> UpcastUsingPassAs(
     95     scoped_ptr<ConDecLogger> object) {
     96   return object.PassAs<ConDecLoggerParent>();
     97 }
     98 
     99 }  // namespace
    100 
    101 TEST(ScopedPtrTest, ScopedPtr) {
    102   int constructed = 0;
    103 
    104   // Ensure size of scoped_ptr<> doesn't increase unexpectedly.
    105   COMPILE_ASSERT(sizeof(int*) >= sizeof(scoped_ptr<int>),
    106                  scoped_ptr_larger_than_raw_ptr);
    107 
    108   {
    109     scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
    110     EXPECT_EQ(1, constructed);
    111     EXPECT_TRUE(scoper.get());
    112 
    113     EXPECT_EQ(10, scoper->SomeMeth(10));
    114     EXPECT_EQ(10, scoper.get()->SomeMeth(10));
    115     EXPECT_EQ(10, (*scoper).SomeMeth(10));
    116   }
    117   EXPECT_EQ(0, constructed);
    118 
    119   // Test reset() and release()
    120   {
    121     scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
    122     EXPECT_EQ(1, constructed);
    123     EXPECT_TRUE(scoper.get());
    124 
    125     scoper.reset(new ConDecLogger(&constructed));
    126     EXPECT_EQ(1, constructed);
    127     EXPECT_TRUE(scoper.get());
    128 
    129     scoper.reset();
    130     EXPECT_EQ(0, constructed);
    131     EXPECT_FALSE(scoper.get());
    132 
    133     scoper.reset(new ConDecLogger(&constructed));
    134     EXPECT_EQ(1, constructed);
    135     EXPECT_TRUE(scoper.get());
    136 
    137     ConDecLogger* take = scoper.release();
    138     EXPECT_EQ(1, constructed);
    139     EXPECT_FALSE(scoper.get());
    140     delete take;
    141     EXPECT_EQ(0, constructed);
    142 
    143     scoper.reset(new ConDecLogger(&constructed));
    144     EXPECT_EQ(1, constructed);
    145     EXPECT_TRUE(scoper.get());
    146   }
    147   EXPECT_EQ(0, constructed);
    148 
    149   // Test swap(), == and !=
    150   {
    151     scoped_ptr<ConDecLogger> scoper1;
    152     scoped_ptr<ConDecLogger> scoper2;
    153     EXPECT_TRUE(scoper1 == scoper2.get());
    154     EXPECT_FALSE(scoper1 != scoper2.get());
    155 
    156     ConDecLogger* logger = new ConDecLogger(&constructed);
    157     scoper1.reset(logger);
    158     EXPECT_EQ(logger, scoper1.get());
    159     EXPECT_FALSE(scoper2.get());
    160     EXPECT_FALSE(scoper1 == scoper2.get());
    161     EXPECT_TRUE(scoper1 != scoper2.get());
    162 
    163     scoper2.swap(scoper1);
    164     EXPECT_EQ(logger, scoper2.get());
    165     EXPECT_FALSE(scoper1.get());
    166     EXPECT_FALSE(scoper1 == scoper2.get());
    167     EXPECT_TRUE(scoper1 != scoper2.get());
    168   }
    169   EXPECT_EQ(0, constructed);
    170 }
    171 
    172 TEST(ScopedPtrTest, ScopedPtrDepthSubtyping) {
    173   int constructed = 0;
    174 
    175   // Test construction from a scoped_ptr to a derived class.
    176   {
    177     scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
    178     EXPECT_EQ(1, constructed);
    179     EXPECT_TRUE(scoper.get());
    180 
    181     scoped_ptr<ConDecLoggerParent> scoper_parent(scoper.Pass());
    182     EXPECT_EQ(1, constructed);
    183     EXPECT_TRUE(scoper_parent.get());
    184     EXPECT_FALSE(scoper.get());
    185 
    186     EXPECT_EQ(10, scoper_parent->SomeMeth(10));
    187     EXPECT_EQ(10, scoper_parent.get()->SomeMeth(10));
    188     EXPECT_EQ(10, (*scoper_parent).SomeMeth(10));
    189   }
    190   EXPECT_EQ(0, constructed);
    191 
    192   // Test assignment from a scoped_ptr to a derived class.
    193   {
    194     scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
    195     EXPECT_EQ(1, constructed);
    196     EXPECT_TRUE(scoper.get());
    197 
    198     scoped_ptr<ConDecLoggerParent> scoper_parent;
    199     scoper_parent = scoper.Pass();
    200     EXPECT_EQ(1, constructed);
    201     EXPECT_TRUE(scoper_parent.get());
    202     EXPECT_FALSE(scoper.get());
    203   }
    204   EXPECT_EQ(0, constructed);
    205 
    206   // Test construction of a scoped_ptr with an additional const annotation.
    207   {
    208     scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
    209     EXPECT_EQ(1, constructed);
    210     EXPECT_TRUE(scoper.get());
    211 
    212     scoped_ptr<const ConDecLogger> scoper_const(scoper.Pass());
    213     EXPECT_EQ(1, constructed);
    214     EXPECT_TRUE(scoper_const.get());
    215     EXPECT_FALSE(scoper.get());
    216 
    217     EXPECT_EQ(10, scoper_const->SomeMeth(10));
    218     EXPECT_EQ(10, scoper_const.get()->SomeMeth(10));
    219     EXPECT_EQ(10, (*scoper_const).SomeMeth(10));
    220   }
    221   EXPECT_EQ(0, constructed);
    222 
    223   // Test assignment to a scoped_ptr with an additional const annotation.
    224   {
    225     scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
    226     EXPECT_EQ(1, constructed);
    227     EXPECT_TRUE(scoper.get());
    228 
    229     scoped_ptr<const ConDecLogger> scoper_const;
    230     scoper_const = scoper.Pass();
    231     EXPECT_EQ(1, constructed);
    232     EXPECT_TRUE(scoper_const.get());
    233     EXPECT_FALSE(scoper.get());
    234   }
    235   EXPECT_EQ(0, constructed);
    236 
    237   // Test assignment to a scoped_ptr deleter of parent type.
    238   {
    239     // Custom deleters never touch these value.
    240     double dummy_value, dummy_value2;
    241     int deletes = 0;
    242     int alternate_deletes = 0;
    243     scoped_ptr<double, CountingDeleter> scoper(&dummy_value,
    244                                                CountingDeleter(&deletes));
    245     scoped_ptr<double, CountingDeleterChild> scoper_child(
    246         &dummy_value2, CountingDeleterChild(&alternate_deletes));
    247 
    248     EXPECT_TRUE(scoper);
    249     EXPECT_TRUE(scoper_child);
    250     EXPECT_EQ(0, deletes);
    251     EXPECT_EQ(0, alternate_deletes);
    252 
    253     // Test this compiles and correctly overwrites the deleter state.
    254     scoper = scoper_child.Pass();
    255     EXPECT_TRUE(scoper);
    256     EXPECT_FALSE(scoper_child);
    257     EXPECT_EQ(1, deletes);
    258     EXPECT_EQ(0, alternate_deletes);
    259 
    260     scoper.reset();
    261     EXPECT_FALSE(scoper);
    262     EXPECT_FALSE(scoper_child);
    263     EXPECT_EQ(1, deletes);
    264     EXPECT_EQ(1, alternate_deletes);
    265 
    266     scoper_child.reset(&dummy_value);
    267     EXPECT_TRUE(scoper_child);
    268     EXPECT_EQ(1, deletes);
    269     EXPECT_EQ(1, alternate_deletes);
    270     scoped_ptr<double, CountingDeleter> scoper_construct(scoper_child.Pass());
    271     EXPECT_TRUE(scoper_construct);
    272     EXPECT_FALSE(scoper_child);
    273     EXPECT_EQ(1, deletes);
    274     EXPECT_EQ(1, alternate_deletes);
    275 
    276     scoper_construct.reset();
    277     EXPECT_EQ(1, deletes);
    278     EXPECT_EQ(2, alternate_deletes);
    279   }
    280 }
    281 
    282 TEST(ScopedPtrTest, ScopedPtrWithArray) {
    283   static const int kNumLoggers = 12;
    284 
    285   int constructed = 0;
    286 
    287   {
    288     scoped_ptr<ConDecLogger[]> scoper(new ConDecLogger[kNumLoggers]);
    289     EXPECT_TRUE(scoper);
    290     EXPECT_EQ(&scoper[0], scoper.get());
    291     for (int i = 0; i < kNumLoggers; ++i) {
    292       scoper[i].SetPtr(&constructed);
    293     }
    294     EXPECT_EQ(12, constructed);
    295 
    296     EXPECT_EQ(10, scoper.get()->SomeMeth(10));
    297     EXPECT_EQ(10, scoper[2].SomeMeth(10));
    298   }
    299   EXPECT_EQ(0, constructed);
    300 
    301   // Test reset() and release()
    302   {
    303     scoped_ptr<ConDecLogger[]> scoper;
    304     EXPECT_FALSE(scoper.get());
    305     EXPECT_FALSE(scoper.release());
    306     EXPECT_FALSE(scoper.get());
    307     scoper.reset();
    308     EXPECT_FALSE(scoper.get());
    309 
    310     scoper.reset(new ConDecLogger[kNumLoggers]);
    311     for (int i = 0; i < kNumLoggers; ++i) {
    312       scoper[i].SetPtr(&constructed);
    313     }
    314     EXPECT_EQ(12, constructed);
    315     scoper.reset();
    316     EXPECT_EQ(0, constructed);
    317 
    318     scoper.reset(new ConDecLogger[kNumLoggers]);
    319     for (int i = 0; i < kNumLoggers; ++i) {
    320       scoper[i].SetPtr(&constructed);
    321     }
    322     EXPECT_EQ(12, constructed);
    323     ConDecLogger* ptr = scoper.release();
    324     EXPECT_EQ(12, constructed);
    325     delete[] ptr;
    326     EXPECT_EQ(0, constructed);
    327   }
    328   EXPECT_EQ(0, constructed);
    329 
    330   // Test swap(), ==, !=, and type-safe Boolean.
    331   {
    332     scoped_ptr<ConDecLogger[]> scoper1;
    333     scoped_ptr<ConDecLogger[]> scoper2;
    334     EXPECT_TRUE(scoper1 == scoper2.get());
    335     EXPECT_FALSE(scoper1 != scoper2.get());
    336 
    337     ConDecLogger* loggers = new ConDecLogger[kNumLoggers];
    338     for (int i = 0; i < kNumLoggers; ++i) {
    339       loggers[i].SetPtr(&constructed);
    340     }
    341     scoper1.reset(loggers);
    342     EXPECT_TRUE(scoper1);
    343     EXPECT_EQ(loggers, scoper1.get());
    344     EXPECT_FALSE(scoper2);
    345     EXPECT_FALSE(scoper2.get());
    346     EXPECT_FALSE(scoper1 == scoper2.get());
    347     EXPECT_TRUE(scoper1 != scoper2.get());
    348 
    349     scoper2.swap(scoper1);
    350     EXPECT_EQ(loggers, scoper2.get());
    351     EXPECT_FALSE(scoper1.get());
    352     EXPECT_FALSE(scoper1 == scoper2.get());
    353     EXPECT_TRUE(scoper1 != scoper2.get());
    354   }
    355   EXPECT_EQ(0, constructed);
    356 
    357   {
    358     ConDecLogger* loggers = new ConDecLogger[kNumLoggers];
    359     scoped_ptr<ConDecLogger[]> scoper(loggers);
    360     EXPECT_TRUE(scoper);
    361     for (int i = 0; i < kNumLoggers; ++i) {
    362       scoper[i].SetPtr(&constructed);
    363     }
    364     EXPECT_EQ(kNumLoggers, constructed);
    365 
    366     // Test Pass() with constructor;
    367     scoped_ptr<ConDecLogger[]> scoper2(scoper.Pass());
    368     EXPECT_EQ(kNumLoggers, constructed);
    369 
    370     // Test Pass() with assignment;
    371     scoped_ptr<ConDecLogger[]> scoper3;
    372     scoper3 = scoper2.Pass();
    373     EXPECT_EQ(kNumLoggers, constructed);
    374     EXPECT_FALSE(scoper);
    375     EXPECT_FALSE(scoper2);
    376     EXPECT_TRUE(scoper3);
    377   }
    378   EXPECT_EQ(0, constructed);
    379 }
    380 
    381 TEST(ScopedPtrTest, PassBehavior) {
    382   int constructed = 0;
    383   {
    384     ConDecLogger* logger = new ConDecLogger(&constructed);
    385     scoped_ptr<ConDecLogger> scoper(logger);
    386     EXPECT_EQ(1, constructed);
    387 
    388     // Test Pass() with constructor;
    389     scoped_ptr<ConDecLogger> scoper2(scoper.Pass());
    390     EXPECT_EQ(1, constructed);
    391 
    392     // Test Pass() with assignment;
    393     scoped_ptr<ConDecLogger> scoper3;
    394     scoper3 = scoper2.Pass();
    395     EXPECT_EQ(1, constructed);
    396     EXPECT_FALSE(scoper.get());
    397     EXPECT_FALSE(scoper2.get());
    398     EXPECT_TRUE(scoper3.get());
    399   }
    400 
    401   // Test uncaught Pass() does not leak.
    402   {
    403     ConDecLogger* logger = new ConDecLogger(&constructed);
    404     scoped_ptr<ConDecLogger> scoper(logger);
    405     EXPECT_EQ(1, constructed);
    406 
    407     // Should auto-destruct logger by end of scope.
    408     scoper.Pass();
    409     EXPECT_FALSE(scoper.get());
    410   }
    411   EXPECT_EQ(0, constructed);
    412 
    413   // Test that passing to function which does nothing does not leak.
    414   {
    415     ConDecLogger* logger = new ConDecLogger(&constructed);
    416     scoped_ptr<ConDecLogger> scoper(logger);
    417     EXPECT_EQ(1, constructed);
    418 
    419     // Should auto-destruct logger by end of scope.
    420     GrabAndDrop(scoper.Pass());
    421     EXPECT_FALSE(scoper.get());
    422   }
    423   EXPECT_EQ(0, constructed);
    424 }
    425 
    426 TEST(ScopedPtrTest, ReturnTypeBehavior) {
    427   int constructed = 0;
    428 
    429   // Test that we can return a scoped_ptr.
    430   {
    431     ConDecLogger* logger = new ConDecLogger(&constructed);
    432     scoped_ptr<ConDecLogger> scoper(logger);
    433     EXPECT_EQ(1, constructed);
    434 
    435     PassThru(scoper.Pass());
    436     EXPECT_FALSE(scoper.get());
    437   }
    438   EXPECT_EQ(0, constructed);
    439 
    440   // Test uncaught return type not leak.
    441   {
    442     ConDecLogger* logger = new ConDecLogger(&constructed);
    443     scoped_ptr<ConDecLogger> scoper(logger);
    444     EXPECT_EQ(1, constructed);
    445 
    446     // Should auto-destruct logger by end of scope.
    447     PassThru(scoper.Pass());
    448     EXPECT_FALSE(scoper.get());
    449   }
    450   EXPECT_EQ(0, constructed);
    451 
    452   // Call TestReturnOfType() so the compiler doesn't warn for an unused
    453   // function.
    454   {
    455     TestReturnOfType(&constructed);
    456   }
    457   EXPECT_EQ(0, constructed);
    458 }
    459 
    460 TEST(ScopedPtrTest, PassAs) {
    461   int constructed = 0;
    462   {
    463     scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
    464     EXPECT_EQ(1, constructed);
    465     EXPECT_TRUE(scoper.get());
    466 
    467     scoped_ptr<ConDecLoggerParent> scoper_parent;
    468     scoper_parent = UpcastUsingPassAs(scoper.Pass());
    469     EXPECT_EQ(1, constructed);
    470     EXPECT_TRUE(scoper_parent.get());
    471     EXPECT_FALSE(scoper.get());
    472   }
    473   EXPECT_EQ(0, constructed);
    474 }
    475 
    476 TEST(ScopedPtrTest, CustomDeleter) {
    477   double dummy_value;  // Custom deleter never touches this value.
    478   int deletes = 0;
    479   int alternate_deletes = 0;
    480 
    481   // Normal delete support.
    482   {
    483     deletes = 0;
    484     scoped_ptr<double, CountingDeleter> scoper(&dummy_value,
    485                                                CountingDeleter(&deletes));
    486     EXPECT_EQ(0, deletes);
    487     EXPECT_TRUE(scoper.get());
    488   }
    489   EXPECT_EQ(1, deletes);
    490 
    491   // Test reset() and release().
    492   deletes = 0;
    493   {
    494     scoped_ptr<double, CountingDeleter> scoper(NULL,
    495                                                CountingDeleter(&deletes));
    496     EXPECT_FALSE(scoper.get());
    497     EXPECT_FALSE(scoper.release());
    498     EXPECT_FALSE(scoper.get());
    499     scoper.reset();
    500     EXPECT_FALSE(scoper.get());
    501     EXPECT_EQ(0, deletes);
    502 
    503     scoper.reset(&dummy_value);
    504     scoper.reset();
    505     EXPECT_EQ(1, deletes);
    506 
    507     scoper.reset(&dummy_value);
    508     EXPECT_EQ(&dummy_value, scoper.release());
    509   }
    510   EXPECT_EQ(1, deletes);
    511 
    512   // Test get_deleter().
    513   deletes = 0;
    514   alternate_deletes = 0;
    515   {
    516     scoped_ptr<double, CountingDeleter> scoper(&dummy_value,
    517                                                CountingDeleter(&deletes));
    518     // Call deleter manually.
    519     EXPECT_EQ(0, deletes);
    520     scoper.get_deleter()(&dummy_value);
    521     EXPECT_EQ(1, deletes);
    522 
    523     // Deleter is still there after reset.
    524     scoper.reset();
    525     EXPECT_EQ(2, deletes);
    526     scoper.get_deleter()(&dummy_value);
    527     EXPECT_EQ(3, deletes);
    528 
    529     // Deleter can be assigned into (matches C++11 unique_ptr<> spec).
    530     scoper.get_deleter() = CountingDeleter(&alternate_deletes);
    531     scoper.reset(&dummy_value);
    532     EXPECT_EQ(0, alternate_deletes);
    533 
    534   }
    535   EXPECT_EQ(3, deletes);
    536   EXPECT_EQ(1, alternate_deletes);
    537 
    538   // Test operator= deleter support.
    539   deletes = 0;
    540   alternate_deletes = 0;
    541   {
    542     double dummy_value2;
    543     scoped_ptr<double, CountingDeleter> scoper(&dummy_value,
    544                                                CountingDeleter(&deletes));
    545     scoped_ptr<double, CountingDeleter> scoper2(
    546         &dummy_value2,
    547         CountingDeleter(&alternate_deletes));
    548     EXPECT_EQ(0, deletes);
    549     EXPECT_EQ(0, alternate_deletes);
    550 
    551     // Pass the second deleter through a constructor and an operator=. Then
    552     // reinitialize the empty scopers to ensure that each one is deleting
    553     // properly.
    554     scoped_ptr<double, CountingDeleter> scoper3(scoper2.Pass());
    555     scoper = scoper3.Pass();
    556     EXPECT_EQ(1, deletes);
    557 
    558     scoper2.reset(&dummy_value2);
    559     scoper3.reset(&dummy_value2);
    560     EXPECT_EQ(0, alternate_deletes);
    561 
    562   }
    563   EXPECT_EQ(1, deletes);
    564   EXPECT_EQ(3, alternate_deletes);
    565 
    566   // Test swap(), ==, !=, and type-safe Boolean.
    567   {
    568     scoped_ptr<double, CountingDeleter> scoper1(NULL,
    569                                                 CountingDeleter(&deletes));
    570     scoped_ptr<double, CountingDeleter> scoper2(NULL,
    571                                                 CountingDeleter(&deletes));
    572     EXPECT_TRUE(scoper1 == scoper2.get());
    573     EXPECT_FALSE(scoper1 != scoper2.get());
    574 
    575     scoper1.reset(&dummy_value);
    576     EXPECT_TRUE(scoper1);
    577     EXPECT_EQ(&dummy_value, scoper1.get());
    578     EXPECT_FALSE(scoper2);
    579     EXPECT_FALSE(scoper2.get());
    580     EXPECT_FALSE(scoper1 == scoper2.get());
    581     EXPECT_TRUE(scoper1 != scoper2.get());
    582 
    583     scoper2.swap(scoper1);
    584     EXPECT_EQ(&dummy_value, scoper2.get());
    585     EXPECT_FALSE(scoper1.get());
    586     EXPECT_FALSE(scoper1 == scoper2.get());
    587     EXPECT_TRUE(scoper1 != scoper2.get());
    588   }
    589 }
    590 
    591 // Sanity check test for overloaded new and delete operators. Does not do full
    592 // coverage of reset/release/Pass() operations as that is redundant with the
    593 // above.
    594 TEST(ScopedPtrTest, OverloadedNewAndDelete) {
    595   {
    596     OverloadedNewAndDelete::ResetCounters();
    597     scoped_ptr<OverloadedNewAndDelete> scoper(new OverloadedNewAndDelete());
    598     EXPECT_TRUE(scoper.get());
    599 
    600     scoped_ptr<OverloadedNewAndDelete> scoper2(scoper.Pass());
    601   }
    602   EXPECT_EQ(1, OverloadedNewAndDelete::delete_count());
    603   EXPECT_EQ(1, OverloadedNewAndDelete::new_count());
    604 }
    605 
    606 // TODO scoped_ptr_malloc
    607