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