Home | History | Annotate | Download | only in interface
      1 // Copyright (c) 2011 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 under third_party_mods/chromium or at:
      4 // http://src.chromium.org/svn/trunk/src/LICENSE
      5 
      6 #ifndef SYSTEM_WRAPPERS_INTERFACE_SCOPED_REFPTR_H_
      7 #define SYSTEM_WRAPPERS_INTERFACE_SCOPED_REFPTR_H_
      8 
      9 namespace webrtc {
     10 
     11 // Extracted from Chromium's src/base/memory/ref_counted.h.
     12 
     13 //
     14 // A smart pointer class for reference counted objects.  Use this class instead
     15 // of calling AddRef and Release manually on a reference counted object to
     16 // avoid common memory leaks caused by forgetting to Release an object
     17 // reference.  Sample usage:
     18 //
     19 //   class MyFoo : public RefCounted<MyFoo> {
     20 //    ...
     21 //   };
     22 //
     23 //   void some_function() {
     24 //     scoped_refptr<MyFoo> foo = new MyFoo();
     25 //     foo->Method(param);
     26 //     // |foo| is released when this function returns
     27 //   }
     28 //
     29 //   void some_other_function() {
     30 //     scoped_refptr<MyFoo> foo = new MyFoo();
     31 //     ...
     32 //     foo = NULL;  // explicitly releases |foo|
     33 //     ...
     34 //     if (foo)
     35 //       foo->Method(param);
     36 //   }
     37 //
     38 // The above examples show how scoped_refptr<T> acts like a pointer to T.
     39 // Given two scoped_refptr<T> classes, it is also possible to exchange
     40 // references between the two objects, like so:
     41 //
     42 //   {
     43 //     scoped_refptr<MyFoo> a = new MyFoo();
     44 //     scoped_refptr<MyFoo> b;
     45 //
     46 //     b.swap(a);
     47 //     // now, |b| references the MyFoo object, and |a| references NULL.
     48 //   }
     49 //
     50 // To make both |a| and |b| in the above example reference the same MyFoo
     51 // object, simply use the assignment operator:
     52 //
     53 //   {
     54 //     scoped_refptr<MyFoo> a = new MyFoo();
     55 //     scoped_refptr<MyFoo> b;
     56 //
     57 //     b = a;
     58 //     // now, |a| and |b| each own a reference to the same MyFoo object.
     59 //   }
     60 //
     61 template <class T>
     62 class scoped_refptr {
     63  public:
     64   scoped_refptr() : ptr_(NULL) {
     65   }
     66 
     67   scoped_refptr(T* p) : ptr_(p) {
     68     if (ptr_)
     69       ptr_->AddRef();
     70   }
     71 
     72   scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
     73     if (ptr_)
     74       ptr_->AddRef();
     75   }
     76 
     77   template <typename U>
     78   scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
     79     if (ptr_)
     80       ptr_->AddRef();
     81   }
     82 
     83   ~scoped_refptr() {
     84     if (ptr_)
     85       ptr_->Release();
     86   }
     87 
     88   T* get() const { return ptr_; }
     89   operator T*() const { return ptr_; }
     90   T* operator->() const { return ptr_; }
     91 
     92   // Release a pointer.
     93   // The return value is the current pointer held by this object.
     94   // If this object holds a NULL pointer, the return value is NULL.
     95   // After this operation, this object will hold a NULL pointer,
     96   // and will not own the object any more.
     97   T* release() {
     98     T* retVal = ptr_;
     99     ptr_ = NULL;
    100     return retVal;
    101   }
    102 
    103   scoped_refptr<T>& operator=(T* p) {
    104     // AddRef first so that self assignment should work
    105     if (p)
    106       p->AddRef();
    107     if (ptr_ )
    108       ptr_->Release();
    109     ptr_ = p;
    110     return *this;
    111   }
    112 
    113   scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
    114     return *this = r.ptr_;
    115   }
    116 
    117   template <typename U>
    118   scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
    119     return *this = r.get();
    120   }
    121 
    122   void swap(T** pp) {
    123     T* p = ptr_;
    124     ptr_ = *pp;
    125     *pp = p;
    126   }
    127 
    128   void swap(scoped_refptr<T>& r) {
    129     swap(&r.ptr_);
    130   }
    131 
    132  protected:
    133   T* ptr_;
    134 };
    135 }  // namespace webrtc
    136 
    137 #endif  // SYSTEM_WRAPPERS_INTERFACE_SCOPED_REFPTR_H_
    138