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