LCOV - code coverage report
Current view: directory - ipc/chromium/src/base - scoped_ptr.h (source / functions) Found Hit Coverage
Test: app.info Lines: 42 18 42.9 %
Date: 2012-06-02 Functions: 53 16 30.2 %

       1                 : // Copyright (c) 2006-2008 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                 : // Scopers help you manage ownership of a pointer, helping you easily manage the
       6                 : // a pointer within a scope, and automatically destroying the pointer at the
       7                 : // end of a scope.  There are two main classes you will use, which coorespond
       8                 : // to the operators new/delete and new[]/delete[].
       9                 : //
      10                 : // Example usage (scoped_ptr):
      11                 : //   {
      12                 : //     scoped_ptr<Foo> foo(new Foo("wee"));
      13                 : //   }  // foo goes out of scope, releasing the pointer with it.
      14                 : //
      15                 : //   {
      16                 : //     scoped_ptr<Foo> foo;          // No pointer managed.
      17                 : //     foo.reset(new Foo("wee"));    // Now a pointer is managed.
      18                 : //     foo.reset(new Foo("wee2"));   // Foo("wee") was destroyed.
      19                 : //     foo.reset(new Foo("wee3"));   // Foo("wee2") was destroyed.
      20                 : //     foo->Method();                // Foo::Method() called.
      21                 : //     foo.get()->Method();          // Foo::Method() called.
      22                 : //     SomeFunc(foo.Release());      // SomeFunc takes owernship, foo no longer
      23                 : //                                   // manages a pointer.
      24                 : //     foo.reset(new Foo("wee4"));   // foo manages a pointer again.
      25                 : //     foo.reset();                  // Foo("wee4") destroyed, foo no longer
      26                 : //                                   // manages a pointer.
      27                 : //   }  // foo wasn't managing a pointer, so nothing was destroyed.
      28                 : //
      29                 : // Example usage (scoped_array):
      30                 : //   {
      31                 : //     scoped_array<Foo> foo(new Foo[100]);
      32                 : //     foo.get()->Method();  // Foo::Method on the 0th element.
      33                 : //     foo[10].Method();     // Foo::Method on the 10th element.
      34                 : //   }
      35                 : 
      36                 : #ifndef BASE_SCOPED_PTR_H_
      37                 : #define BASE_SCOPED_PTR_H_
      38                 : 
      39                 : // This is an implementation designed to match the anticipated future TR2
      40                 : // implementation of the scoped_ptr class, and its closely-related brethren,
      41                 : // scoped_array, scoped_ptr_malloc.
      42                 : 
      43                 : #include <assert.h>
      44                 : #include <stdlib.h>
      45                 : #include <cstddef>
      46                 : 
      47                 : // A scoped_ptr<T> is like a T*, except that the destructor of scoped_ptr<T>
      48                 : // automatically deletes the pointer it holds (if any).
      49                 : // That is, scoped_ptr<T> owns the T object that it points to.
      50                 : // Like a T*, a scoped_ptr<T> may hold either NULL or a pointer to a T object.
      51                 : // Also like T*, scoped_ptr<T> is thread-compatible, and once you
      52                 : // dereference it, you get the threadsafety guarantees of T.
      53                 : //
      54                 : // The size of a scoped_ptr is small:
      55                 : // sizeof(scoped_ptr<C>) == sizeof(C*)
      56                 : template <class C>
      57                 : class scoped_ptr {
      58                 :  public:
      59                 : 
      60                 :   // The element type
      61                 :   typedef C element_type;
      62                 : 
      63                 :   // Constructor.  Defaults to intializing with NULL.
      64                 :   // There is no way to create an uninitialized scoped_ptr.
      65                 :   // The input parameter must be allocated with new.
      66            1424 :   explicit scoped_ptr(C* p = NULL) : ptr_(p) { }
      67                 : 
      68                 :   // Destructor.  If there is a C object, delete it.
      69                 :   // We don't need to test ptr_ == NULL because C++ does that for us.
      70            1420 :   ~scoped_ptr() {
      71                 :     enum { type_must_be_complete = sizeof(C) };
      72            1420 :     delete ptr_;
      73            1420 :   }
      74                 : 
      75                 :   // Reset.  Deletes the current owned object, if any.
      76                 :   // Then takes ownership of a new object, if given.
      77                 :   // this->reset(this->get()) works.
      78               1 :   void reset(C* p = NULL) {
      79               1 :     if (p != ptr_) {
      80                 :       enum { type_must_be_complete = sizeof(C) };
      81               1 :       delete ptr_;
      82               1 :       ptr_ = p;
      83                 :     }
      84               1 :   }
      85                 : 
      86                 :   // Accessors to get the owned object.
      87                 :   // operator* and operator-> will assert() if there is no current object.
      88               0 :   C& operator*() const {
      89               0 :     assert(ptr_ != NULL);
      90               0 :     return *ptr_;
      91                 :   }
      92            1421 :   C* operator->() const  {
      93            1421 :     assert(ptr_ != NULL);
      94            1421 :     return ptr_;
      95                 :   }
      96            1423 :   C* get() const { return ptr_; }
      97                 : 
      98                 :   // Comparison operators.
      99                 :   // These return whether two scoped_ptr refer to the same object, not just to
     100                 :   // two different but equal objects.
     101                 :   bool operator==(C* p) const { return ptr_ == p; }
     102                 :   bool operator!=(C* p) const { return ptr_ != p; }
     103                 : 
     104                 :   // Swap two scoped pointers.
     105                 :   void swap(scoped_ptr& p2) {
     106                 :     C* tmp = ptr_;
     107                 :     ptr_ = p2.ptr_;
     108                 :     p2.ptr_ = tmp;
     109                 :   }
     110                 : 
     111                 :   // Release a pointer.
     112                 :   // The return value is the current pointer held by this object.
     113                 :   // If this object holds a NULL pointer, the return value is NULL.
     114                 :   // After this operation, this object will hold a NULL pointer,
     115                 :   // and will not own the object any more.
     116            1420 :   C* release() {
     117            1420 :     C* retVal = ptr_;
     118            1420 :     ptr_ = NULL;
     119            1420 :     return retVal;
     120                 :   }
     121                 : 
     122                 :  private:
     123                 :   C* ptr_;
     124                 : 
     125                 :   // Forbid comparison of scoped_ptr types.  If C2 != C, it totally doesn't
     126                 :   // make sense, and if C2 == C, it still doesn't make sense because you should
     127                 :   // never have the same object owned by two different scoped_ptrs.
     128                 :   template <class C2> bool operator==(scoped_ptr<C2> const& p2) const;
     129                 :   template <class C2> bool operator!=(scoped_ptr<C2> const& p2) const;
     130                 : 
     131                 :   // Disallow evil constructors
     132                 :   scoped_ptr(const scoped_ptr&);
     133                 :   void operator=(const scoped_ptr&);
     134                 : };
     135                 : 
     136                 : // Free functions
     137                 : template <class C>
     138                 : void swap(scoped_ptr<C>& p1, scoped_ptr<C>& p2) {
     139                 :   p1.swap(p2);
     140                 : }
     141                 : 
     142                 : template <class C>
     143                 : bool operator==(C* p1, const scoped_ptr<C>& p2) {
     144                 :   return p1 == p2.get();
     145                 : }
     146                 : 
     147                 : template <class C>
     148                 : bool operator!=(C* p1, const scoped_ptr<C>& p2) {
     149                 :   return p1 != p2.get();
     150                 : }
     151                 : 
     152                 : // scoped_array<C> is like scoped_ptr<C>, except that the caller must allocate
     153                 : // with new [] and the destructor deletes objects with delete [].
     154                 : //
     155                 : // As with scoped_ptr<C>, a scoped_array<C> either points to an object
     156                 : // or is NULL.  A scoped_array<C> owns the object that it points to.
     157                 : // scoped_array<T> is thread-compatible, and once you index into it,
     158                 : // the returned objects have only the threadsafety guarantees of T.
     159                 : //
     160                 : // Size: sizeof(scoped_array<C>) == sizeof(C*)
     161                 : template <class C>
     162                 : class scoped_array {
     163                 :  public:
     164                 : 
     165                 :   // The element type
     166                 :   typedef C element_type;
     167                 : 
     168                 :   // Constructor.  Defaults to intializing with NULL.
     169                 :   // There is no way to create an uninitialized scoped_array.
     170                 :   // The input parameter must be allocated with new [].
     171               0 :   explicit scoped_array(C* p = NULL) : array_(p) { }
     172                 : 
     173                 :   // Destructor.  If there is a C object, delete it.
     174                 :   // We don't need to test ptr_ == NULL because C++ does that for us.
     175               0 :   ~scoped_array() {
     176                 :     enum { type_must_be_complete = sizeof(C) };
     177               0 :     delete[] array_;
     178               0 :   }
     179                 : 
     180                 :   // Reset.  Deletes the current owned object, if any.
     181                 :   // Then takes ownership of a new object, if given.
     182                 :   // this->reset(this->get()) works.
     183                 :   void reset(C* p = NULL) {
     184                 :     if (p != array_) {
     185                 :       enum { type_must_be_complete = sizeof(C) };
     186                 :       delete[] array_;
     187                 :       array_ = p;
     188                 :     }
     189                 :   }
     190                 : 
     191                 :   // Get one element of the current object.
     192                 :   // Will assert() if there is no current object, or index i is negative.
     193               0 :   C& operator[](std::ptrdiff_t i) const {
     194               0 :     assert(i >= 0);
     195               0 :     assert(array_ != NULL);
     196               0 :     return array_[i];
     197                 :   }
     198                 : 
     199                 :   // Get a pointer to the zeroth element of the current object.
     200                 :   // If there is no current object, return NULL.
     201               0 :   C* get() const {
     202               0 :     return array_;
     203                 :   }
     204                 : 
     205                 :   // Comparison operators.
     206                 :   // These return whether two scoped_array refer to the same object, not just to
     207                 :   // two different but equal objects.
     208                 :   bool operator==(C* p) const { return array_ == p; }
     209                 :   bool operator!=(C* p) const { return array_ != p; }
     210                 : 
     211                 :   // Swap two scoped arrays.
     212                 :   void swap(scoped_array& p2) {
     213                 :     C* tmp = array_;
     214                 :     array_ = p2.array_;
     215                 :     p2.array_ = tmp;
     216                 :   }
     217                 : 
     218                 :   // Release an array.
     219                 :   // The return value is the current pointer held by this object.
     220                 :   // If this object holds a NULL pointer, the return value is NULL.
     221                 :   // After this operation, this object will hold a NULL pointer,
     222                 :   // and will not own the object any more.
     223                 :   C* release() {
     224                 :     C* retVal = array_;
     225                 :     array_ = NULL;
     226                 :     return retVal;
     227                 :   }
     228                 : 
     229                 :  private:
     230                 :   C* array_;
     231                 : 
     232                 :   // Forbid comparison of different scoped_array types.
     233                 :   template <class C2> bool operator==(scoped_array<C2> const& p2) const;
     234                 :   template <class C2> bool operator!=(scoped_array<C2> const& p2) const;
     235                 : 
     236                 :   // Disallow evil constructors
     237                 :   scoped_array(const scoped_array&);
     238                 :   void operator=(const scoped_array&);
     239                 : };
     240                 : 
     241                 : // Free functions
     242                 : template <class C>
     243                 : void swap(scoped_array<C>& p1, scoped_array<C>& p2) {
     244                 :   p1.swap(p2);
     245                 : }
     246                 : 
     247                 : template <class C>
     248                 : bool operator==(C* p1, const scoped_array<C>& p2) {
     249                 :   return p1 == p2.get();
     250                 : }
     251                 : 
     252                 : template <class C>
     253                 : bool operator!=(C* p1, const scoped_array<C>& p2) {
     254                 :   return p1 != p2.get();
     255                 : }
     256                 : 
     257                 : // This class wraps the c library function free() in a class that can be
     258                 : // passed as a template argument to scoped_ptr_malloc below.
     259                 : class ScopedPtrMallocFree {
     260                 :  public:
     261                 :   inline void operator()(void* x) const {
     262                 :     free(x);
     263                 :   }
     264                 : };
     265                 : 
     266                 : // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
     267                 : // second template argument, the functor used to free the object.
     268                 : 
     269                 : template<class C, class FreeProc = ScopedPtrMallocFree>
     270                 : class scoped_ptr_malloc {
     271                 :  public:
     272                 : 
     273                 :   // The element type
     274                 :   typedef C element_type;
     275                 : 
     276                 :   // Constructor.  Defaults to intializing with NULL.
     277                 :   // There is no way to create an uninitialized scoped_ptr.
     278                 :   // The input parameter must be allocated with an allocator that matches the
     279                 :   // Free functor.  For the default Free functor, this is malloc, calloc, or
     280                 :   // realloc.
     281               0 :   explicit scoped_ptr_malloc(C* p = NULL): ptr_(p) {}
     282                 : 
     283                 :   // Destructor.  If there is a C object, call the Free functor.
     284               0 :   ~scoped_ptr_malloc() {
     285               0 :     free_(ptr_);
     286               0 :   }
     287                 : 
     288                 :   // Reset.  Calls the Free functor on the current owned object, if any.
     289                 :   // Then takes ownership of a new object, if given.
     290                 :   // this->reset(this->get()) works.
     291               0 :   void reset(C* p = NULL) {
     292               0 :     if (ptr_ != p) {
     293               0 :       free_(ptr_);
     294               0 :       ptr_ = p;
     295                 :     }
     296               0 :   }
     297                 : 
     298                 :   // Get the current object.
     299                 :   // operator* and operator-> will cause an assert() failure if there is
     300                 :   // no current object.
     301                 :   C& operator*() const {
     302                 :     assert(ptr_ != NULL);
     303                 :     return *ptr_;
     304                 :   }
     305                 : 
     306                 :   C* operator->() const {
     307                 :     assert(ptr_ != NULL);
     308                 :     return ptr_;
     309                 :   }
     310                 : 
     311               0 :   C* get() const {
     312               0 :     return ptr_;
     313                 :   }
     314                 : 
     315                 :   // Comparison operators.
     316                 :   // These return whether a scoped_ptr_malloc and a plain pointer refer
     317                 :   // to the same object, not just to two different but equal objects.
     318                 :   // For compatibility wwith the boost-derived implementation, these
     319                 :   // take non-const arguments.
     320                 :   bool operator==(C* p) const {
     321                 :     return ptr_ == p;
     322                 :   }
     323                 : 
     324                 :   bool operator!=(C* p) const {
     325                 :     return ptr_ != p;
     326                 :   }
     327                 : 
     328                 :   // Swap two scoped pointers.
     329                 :   void swap(scoped_ptr_malloc & b) {
     330                 :     C* tmp = b.ptr_;
     331                 :     b.ptr_ = ptr_;
     332                 :     ptr_ = tmp;
     333                 :   }
     334                 : 
     335                 :   // Release a pointer.
     336                 :   // The return value is the current pointer held by this object.
     337                 :   // If this object holds a NULL pointer, the return value is NULL.
     338                 :   // After this operation, this object will hold a NULL pointer,
     339                 :   // and will not own the object any more.
     340                 :   C* release() {
     341                 :     C* tmp = ptr_;
     342                 :     ptr_ = NULL;
     343                 :     return tmp;
     344                 :   }
     345                 : 
     346                 :  private:
     347                 :   C* ptr_;
     348                 : 
     349                 :   // no reason to use these: each scoped_ptr_malloc should have its own object
     350                 :   template <class C2, class GP>
     351                 :   bool operator==(scoped_ptr_malloc<C2, GP> const& p) const;
     352                 :   template <class C2, class GP>
     353                 :   bool operator!=(scoped_ptr_malloc<C2, GP> const& p) const;
     354                 : 
     355                 :   static FreeProc const free_;
     356                 : 
     357                 :   // Disallow evil constructors
     358                 :   scoped_ptr_malloc(const scoped_ptr_malloc&);
     359                 :   void operator=(const scoped_ptr_malloc&);
     360                 : };
     361                 : 
     362                 : template<class C, class FP>
     363            2928 : FP const scoped_ptr_malloc<C, FP>::free_ = FP();
     364                 : 
     365                 : template<class C, class FP> inline
     366                 : void swap(scoped_ptr_malloc<C, FP>& a, scoped_ptr_malloc<C, FP>& b) {
     367                 :   a.swap(b);
     368                 : }
     369                 : 
     370                 : template<class C, class FP> inline
     371                 : bool operator==(C* p, const scoped_ptr_malloc<C, FP>& b) {
     372                 :   return p == b.get();
     373                 : }
     374                 : 
     375                 : template<class C, class FP> inline
     376                 : bool operator!=(C* p, const scoped_ptr_malloc<C, FP>& b) {
     377                 :   return p != b.get();
     378                 : }
     379                 : 
     380                 : #endif  // BASE_SCOPED_PTR_H_

Generated by: LCOV version 1.7