tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

scoped_refptr.h (5961B)


      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 = make_ref_counted<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 = make_ref_counted<MyFoo>();
     32 //     ...
     33 //     foo = nullptr;  // 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 = make_ref_counted<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 = make_ref_counted<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 API_SCOPED_REFPTR_H_
     64 #define API_SCOPED_REFPTR_H_
     65 
     66 #include <cstddef>
     67 #include <utility>
     68 
     69 #include "absl/base/nullability.h"
     70 
     71 namespace webrtc {
     72 
     73 template <class T>
     74 class ABSL_NULLABILITY_COMPATIBLE scoped_refptr {
     75 public:
     76  using element_type = T;
     77 
     78  scoped_refptr() : ptr_(nullptr) {}
     79  scoped_refptr(std::nullptr_t) : ptr_(nullptr) {}  // NOLINT(runtime/explicit)
     80 
     81  explicit scoped_refptr(T* absl_nullable p) : ptr_(p) {
     82    if (ptr_)
     83      ptr_->AddRef();
     84  }
     85 
     86  scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
     87    if (ptr_)
     88      ptr_->AddRef();
     89  }
     90 
     91  template <typename U>
     92  scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
     93    if (ptr_)
     94      ptr_->AddRef();
     95  }
     96 
     97  // Move constructors.
     98  scoped_refptr(scoped_refptr<T>&& r) noexcept : ptr_(r.release()) {}
     99 
    100  template <typename U>
    101  scoped_refptr(scoped_refptr<U>&& r) noexcept : ptr_(r.release()) {}
    102 
    103  ~scoped_refptr() {
    104    if (ptr_)
    105      ptr_->Release();
    106  }
    107 
    108  T* get() const { return ptr_; }
    109  explicit operator bool() const { return ptr_ != nullptr; }
    110  T& operator*() const { return *ptr_; }
    111  T* operator->() const { return ptr_; }
    112 
    113  // Returns the (possibly null) raw pointer, and makes the scoped_refptr hold a
    114  // null pointer, all without touching the reference count of the underlying
    115  // pointed-to object. The object is still reference counted, and the caller of
    116  // release() is now the proud owner of one reference, so it is responsible for
    117  // calling Release() once on the object when no longer using it.
    118  T* release() {
    119    T* retVal = ptr_;
    120    ptr_ = nullptr;
    121    return retVal;
    122  }
    123 
    124  scoped_refptr<T>& operator=(T* absl_nullable p) {
    125    // AddRef first so that self assignment should work
    126    if (p)
    127      p->AddRef();
    128    if (ptr_)
    129      ptr_->Release();
    130    ptr_ = p;
    131    return *this;
    132  }
    133 
    134  scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
    135    return *this = r.ptr_;
    136  }
    137 
    138  template <typename U>
    139  scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
    140    return *this = r.get();
    141  }
    142 
    143  scoped_refptr<T>& operator=(scoped_refptr<T>&& r) noexcept {
    144    scoped_refptr<T>(std::move(r)).swap(*this);
    145    return *this;
    146  }
    147 
    148  template <typename U>
    149  scoped_refptr<T>& operator=(scoped_refptr<U>&& r) noexcept {
    150    scoped_refptr<T>(std::move(r)).swap(*this);
    151    return *this;
    152  }
    153 
    154  void swap(T** absl_nonnull pp) noexcept {
    155    T* p = ptr_;
    156    ptr_ = *pp;
    157    *pp = p;
    158  }
    159 
    160  void swap(scoped_refptr<T>& r) noexcept { swap(&r.ptr_); }
    161 
    162 protected:
    163  T* ptr_;
    164 };
    165 
    166 template <typename T, typename U>
    167 bool operator==(const scoped_refptr<T>& a, const scoped_refptr<U>& b) {
    168  return a.get() == b.get();
    169 }
    170 template <typename T, typename U>
    171 bool operator!=(const scoped_refptr<T>& a, const scoped_refptr<U>& b) {
    172  return !(a == b);
    173 }
    174 
    175 template <typename T>
    176 bool operator==(const scoped_refptr<T>& a, std::nullptr_t) {
    177  return a.get() == nullptr;
    178 }
    179 
    180 template <typename T>
    181 bool operator!=(const scoped_refptr<T>& a, std::nullptr_t) {
    182  return !(a == nullptr);
    183 }
    184 
    185 template <typename T>
    186 bool operator==(std::nullptr_t, const scoped_refptr<T>& a) {
    187  return a.get() == nullptr;
    188 }
    189 
    190 template <typename T>
    191 bool operator!=(std::nullptr_t, const scoped_refptr<T>& a) {
    192  return !(a == nullptr);
    193 }
    194 
    195 // Comparison with raw pointer.
    196 template <typename T, typename U>
    197 bool operator==(const scoped_refptr<T>& a, const U* b) {
    198  return a.get() == b;
    199 }
    200 template <typename T, typename U>
    201 bool operator!=(const scoped_refptr<T>& a, const U* b) {
    202  return !(a == b);
    203 }
    204 
    205 template <typename T, typename U>
    206 bool operator==(const T* a, const scoped_refptr<U>& b) {
    207  return a == b.get();
    208 }
    209 template <typename T, typename U>
    210 bool operator!=(const T* a, const scoped_refptr<U>& b) {
    211  return !(a == b);
    212 }
    213 
    214 // Ordered comparison, needed for use as a std::map key.
    215 template <typename T, typename U>
    216 bool operator<(const scoped_refptr<T>& a, const scoped_refptr<U>& b) {
    217  return a.get() < b.get();
    218 }
    219 
    220 }  // namespace webrtc
    221 
    222 
    223 #endif  // API_SCOPED_REFPTR_H_