1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_THIRD_PARTY_QUICHE_OVERRIDES_QUICHE_PLATFORM_IMPL_QUICHE_REFERENCE_COUNTED_IMPL_H_
6 #define NET_THIRD_PARTY_QUICHE_OVERRIDES_QUICHE_PLATFORM_IMPL_QUICHE_REFERENCE_COUNTED_IMPL_H_
7 
8 #include "base/memory/ref_counted.h"
9 #include "net/third_party/quiche/src/quiche/quic/platform/api/quic_export.h"
10 
11 namespace quiche {
12 
13 class QUIC_EXPORT_PRIVATE QuicheReferenceCountedImpl
14     : public base::RefCountedThreadSafe<QuicheReferenceCountedImpl> {
15  public:
16   QuicheReferenceCountedImpl() = default;
17 
18  protected:
19   virtual ~QuicheReferenceCountedImpl() = default;
20 
21  private:
22   friend class base::RefCountedThreadSafe<QuicheReferenceCountedImpl>;
23 };
24 
25 template <class T>
26 class QuicheReferenceCountedPointerImpl {
27  public:
28   QuicheReferenceCountedPointerImpl() = default;
29 
30   // Constructor from raw pointer |p|. This guarantees that the reference count
31   // of *p is 1. This should be only called when a new object is created,
32   // calling this on an already existent object does not increase its reference
33   // count.
QuicheReferenceCountedPointerImpl(T * p)34   explicit QuicheReferenceCountedPointerImpl(T* p) : refptr_(p) {}
35 
36   // Allows implicit conversion from nullptr.
QuicheReferenceCountedPointerImpl(std::nullptr_t)37   QuicheReferenceCountedPointerImpl(std::nullptr_t)  // NOLINT
38       : refptr_(nullptr) {}
39 
40   // Copy and copy conversion constructors. It does not take the reference away
41   // from |other| and they each end up with their own reference.
42   template <typename U>
QuicheReferenceCountedPointerImpl(const QuicheReferenceCountedPointerImpl<U> & other)43   QuicheReferenceCountedPointerImpl(  // NOLINT
44       const QuicheReferenceCountedPointerImpl<U>& other)
45       : refptr_(other.refptr()) {}
QuicheReferenceCountedPointerImpl(const QuicheReferenceCountedPointerImpl & other)46   QuicheReferenceCountedPointerImpl(
47       const QuicheReferenceCountedPointerImpl& other)
48       : refptr_(other.refptr()) {}
49 
50   // Move constructors. After move, it adopts the reference from |other|.
51   template <typename U>
QuicheReferenceCountedPointerImpl(QuicheReferenceCountedPointerImpl<U> && other)52   QuicheReferenceCountedPointerImpl(  // NOLINT
53       QuicheReferenceCountedPointerImpl<U>&& other)
54       : refptr_(std::move(other.refptr())) {}
QuicheReferenceCountedPointerImpl(QuicheReferenceCountedPointerImpl && other)55   QuicheReferenceCountedPointerImpl(QuicheReferenceCountedPointerImpl&& other)
56       : refptr_(std::move(other.refptr())) {}
57 
58   ~QuicheReferenceCountedPointerImpl() = default;
59 
60   // Copy assignments.
61   QuicheReferenceCountedPointerImpl& operator=(
62       const QuicheReferenceCountedPointerImpl& other) {
63     refptr_ = other.refptr();
64     return *this;
65   }
66   template <typename U>
67   QuicheReferenceCountedPointerImpl<T>& operator=(
68       const QuicheReferenceCountedPointerImpl<U>& other) {
69     refptr_ = other.refptr();
70     return *this;
71   }
72 
73   // Move assignments.
74   QuicheReferenceCountedPointerImpl& operator=(
75       QuicheReferenceCountedPointerImpl&& other) {
76     refptr_ = std::move(other.refptr());
77     return *this;
78   }
79   template <typename U>
80   QuicheReferenceCountedPointerImpl<T>& operator=(
81       QuicheReferenceCountedPointerImpl<U>&& other) {
82     refptr_ = std::move(other.refptr());
83     return *this;
84   }
85 
86   explicit operator bool() const { return static_cast<bool>(refptr_); }
87 
88   // Assignment operator on raw pointer. Drops a reference to current pointee,
89   // if any, and replaces it with |p|. This guarantees that the reference count
90   // of *p is 1. This should only be used when a new object is created.  Calling
91   // this on an already existent object is undefined behavior according to the
92   // API contract (even though the underlying implementation might have a
93   // well-defined behavior).
94   QuicheReferenceCountedPointerImpl<T>& operator=(T* p) {
95     refptr_ = p;
96     return *this;
97   }
98   // Returns the raw pointer with no change in reference count.
get()99   T* get() const { return refptr_.get(); }
100 
101   // Accessors for the referenced object.
102   // operator*() and operator->() will assert() if there is no current object.
103   T& operator*() const { return *refptr_; }
104   T* operator->() const {
105     assert(refptr_ != nullptr);
106     return refptr_.get();
107   }
108 
refptr()109   scoped_refptr<T>& refptr() { return refptr_; }
refptr()110   const scoped_refptr<T>& refptr() const { return refptr_; }
111 
112  private:
113   scoped_refptr<T> refptr_;
114 };
115 
116 }  // namespace quiche
117 
118 #endif  // NET_THIRD_PARTY_QUICHE_OVERRIDES_QUICHE_PLATFORM_IMPL_QUICHE_REFERENCE_COUNTED_IMPL_H_
119