| 297 | // |
| 298 | template <class T> |
| 299 | class scoped_refptr { |
| 300 | public: |
| 301 | typedef T element_type; |
| 302 | |
| 303 | scoped_refptr() : ptr_(NULL) {} |
| 304 | |
| 305 | scoped_refptr(T* p) : ptr_(p) { |
| 306 | if (ptr_) |
| 307 | ptr_->AddRef(); |
| 308 | } |
| 309 | |
| 310 | scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) { |
| 311 | if (ptr_) |
| 312 | ptr_->AddRef(); |
| 313 | } |
| 314 | |
| 315 | template <typename U> |
| 316 | scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) { |
| 317 | if (ptr_) |
| 318 | ptr_->AddRef(); |
| 319 | } |
| 320 | |
| 321 | ~scoped_refptr() { |
| 322 | if (ptr_) |
| 323 | ptr_->Release(); |
| 324 | } |
| 325 | |
| 326 | T* get() const { return ptr_; } |
| 327 | |
| 328 | // Allow scoped_refptr<C> to be used in boolean expression |
| 329 | // and comparison operations. |
| 330 | operator T*() const { return ptr_; } |
| 331 | |
| 332 | T* operator->() const { |
| 333 | assert(ptr_ != NULL); |
| 334 | return ptr_; |
| 335 | } |
| 336 | |
| 337 | scoped_refptr<T>& operator=(T* p) { |
| 338 | // AddRef first so that self assignment should work |
| 339 | if (p) |
| 340 | p->AddRef(); |
| 341 | T* old_ptr = ptr_; |
| 342 | ptr_ = p; |
| 343 | if (old_ptr) |
| 344 | old_ptr->Release(); |
| 345 | return *this; |
| 346 | } |
| 347 | |
| 348 | scoped_refptr<T>& operator=(const scoped_refptr<T>& r) { |
| 349 | return *this = r.ptr_; |
| 350 | } |
| 351 | |
| 352 | template <typename U> |
| 353 | scoped_refptr<T>& operator=(const scoped_refptr<U>& r) { |
| 354 | return *this = r.get(); |
| 355 | } |
| 356 | |