147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/* 247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Copyright 2011 The WebRTC Project Authors. All rights reserved. 347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * 447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Use of this source code is governed by a BSD-style license 547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * in the file PATENTS. All contributing project authors may 847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */ 1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Originally these classes are from Chromium. 1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// http://src.chromium.org/viewvc/chrome/trunk/src/base/memory/ref_counted.h?view=markup 1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// 1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// A smart pointer class for reference counted objects. Use this class instead 1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// of calling AddRef and Release manually on a reference counted object to 1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// avoid common memory leaks caused by forgetting to Release an object 1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// reference. Sample usage: 1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// 2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// class MyFoo : public RefCounted<MyFoo> { 2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// ... 2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// }; 2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// 2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// void some_function() { 2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// scoped_refptr<MyFoo> foo = new MyFoo(); 2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// foo->Method(param); 2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// // |foo| is released when this function returns 2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// } 2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// 3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// void some_other_function() { 3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// scoped_refptr<MyFoo> foo = new MyFoo(); 3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// ... 3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// foo = NULL; // explicitly releases |foo| 3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// ... 3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// if (foo) 3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// foo->Method(param); 3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// } 3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// 3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// The above examples show how scoped_refptr<T> acts like a pointer to T. 4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Given two scoped_refptr<T> classes, it is also possible to exchange 4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// references between the two objects, like so: 4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// 4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// { 4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// scoped_refptr<MyFoo> a = new MyFoo(); 4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// scoped_refptr<MyFoo> b; 4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// 4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// b.swap(a); 4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// // now, |b| references the MyFoo object, and |a| references NULL. 4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// } 5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// 5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// To make both |a| and |b| in the above example reference the same MyFoo 5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// object, simply use the assignment operator: 5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// 5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// { 5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// scoped_refptr<MyFoo> a = new MyFoo(); 5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// scoped_refptr<MyFoo> b; 5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// 5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// b = a; 5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// // now, |a| and |b| each own a reference to the same MyFoo object. 6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// } 6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// 6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#ifndef WEBRTC_BASE_SCOPED_REF_PTR_H_ 6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WEBRTC_BASE_SCOPED_REF_PTR_H_ 6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <stddef.h> 6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc { 6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtemplate <class T> 7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass scoped_refptr { 7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public: 7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org scoped_refptr() : ptr_(NULL) { 7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org scoped_refptr(T* p) : ptr_(p) { 7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ptr_) 7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ptr_->AddRef(); 7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) { 8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ptr_) 8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ptr_->AddRef(); 8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org template <typename U> 8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) { 8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ptr_) 8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ptr_->AddRef(); 9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ~scoped_refptr() { 9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ptr_) 9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ptr_->Release(); 9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org T* get() const { return ptr_; } 9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org operator T*() const { return ptr_; } 9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org T* operator->() const { return ptr_; } 10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Release a pointer. 10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // The return value is the current pointer held by this object. 10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // If this object holds a NULL pointer, the return value is NULL. 10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // After this operation, this object will hold a NULL pointer, 10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // and will not own the object any more. 10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org T* release() { 10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org T* retVal = ptr_; 10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ptr_ = NULL; 10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return retVal; 11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org scoped_refptr<T>& operator=(T* p) { 11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // AddRef first so that self assignment should work 11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (p) 11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org p->AddRef(); 11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ptr_ ) 11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ptr_ ->Release(); 11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ptr_ = p; 11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return *this; 12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org scoped_refptr<T>& operator=(const scoped_refptr<T>& r) { 12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return *this = r.ptr_; 12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org template <typename U> 12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org scoped_refptr<T>& operator=(const scoped_refptr<U>& r) { 12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return *this = r.get(); 12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org void swap(T** pp) { 13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org T* p = ptr_; 13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ptr_ = *pp; 13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *pp = p; 13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org void swap(scoped_refptr<T>& r) { 13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org swap(&r.ptr_); 13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org protected: 14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org T* ptr_; 14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} // namespace rtc 14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // WEBRTC_BASE_SCOPED_REF_PTR_H_ 148