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