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