blob: 18f6f37f5ab1a5a4420fccec50db12a327544cd3 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2016 The Chromium Authors. All rights reserved.
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 QUICHE_QUIC_PLATFORM_API_QUIC_REFERENCE_COUNTED_H_
6#define QUICHE_QUIC_PLATFORM_API_QUIC_REFERENCE_COUNTED_H_
7
8#include "net/quic/platform/impl/quic_reference_counted_impl.h"
9
10namespace quic {
11
12// Base class for explicitly reference-counted objects in QUIC.
13class QUIC_EXPORT_PRIVATE QuicReferenceCounted
14 : public QuicReferenceCountedImpl {
15 public:
16 QuicReferenceCounted() {}
17
18 protected:
19 ~QuicReferenceCounted() override {}
20};
21
22// A class representing a reference counted pointer in QUIC.
23//
24// Construct or initialize QuicReferenceCountedPointer from raw pointer. Here
25// raw pointer MUST be a newly created object. Reference count of a newly
26// created object is undefined, but that will be 1 after being added to
27// QuicReferenceCountedPointer.
28// QuicReferenceCountedPointer is used as a local variable.
29// QuicReferenceCountedPointer<T> r_ptr(new T());
30// or, equivalently:
31// QuicReferenceCountedPointer<T> r_ptr;
32// T* p = new T();
33// r_ptr = T;
34//
35// QuicReferenceCountedPointer is used as a member variable:
36// MyClass::MyClass() : r_ptr(new T()) {}
37//
38// This is WRONG, since *p is not guaranteed to be newly created:
39// MyClass::MyClass(T* p) : r_ptr(p) {}
40//
41// Given an existing QuicReferenceCountedPointer, create a duplicate that has
42// its own reference on the object:
43// QuicReferenceCountedPointer<T> r_ptr_b(r_ptr_a);
44// or, equivalently:
45// QuicReferenceCountedPointer<T> r_ptr_b = r_ptr_a;
46//
47// Given an existing QuicReferenceCountedPointer, create a
48// QuicReferenceCountedPointer that adopts the reference:
49// QuicReferenceCountedPointer<T> r_ptr_b(std::move(r_ptr_a));
50// or, equivalently:
51// QuicReferenceCountedPointer<T> r_ptr_b = std::move(r_ptr_a);
52
53template <class T>
dschinazie2116422019-10-29 11:54:26 -070054class QUIC_NO_EXPORT QuicReferenceCountedPointer {
QUICHE teama6ef0a62019-03-07 20:34:33 -050055 public:
56 QuicReferenceCountedPointer() = default;
57
bnc04dd0402019-03-08 10:24:19 -050058 // Constructor from raw pointer |p|. This guarantees that the reference count
59 // of *p is 1. This should be only called when a new object is created.
60 // Calling this on an already existent object does not increase its reference
61 // count.
QUICHE teama6ef0a62019-03-07 20:34:33 -050062 explicit QuicReferenceCountedPointer(T* p) : impl_(p) {}
63
64 // Allows implicit conversion from nullptr.
65 QuicReferenceCountedPointer(std::nullptr_t) : impl_(nullptr) {} // NOLINT
66
67 // Copy and copy conversion constructors. It does not take the reference away
68 // from |other| and they each end up with their own reference.
69 template <typename U>
70 QuicReferenceCountedPointer( // NOLINT
71 const QuicReferenceCountedPointer<U>& other)
72 : impl_(other.impl()) {}
73 QuicReferenceCountedPointer(const QuicReferenceCountedPointer& other)
74 : impl_(other.impl()) {}
75
bnc04dd0402019-03-08 10:24:19 -050076 // Move constructors. After move, it adopts the reference from |other|.
QUICHE teama6ef0a62019-03-07 20:34:33 -050077 template <typename U>
78 QuicReferenceCountedPointer(QuicReferenceCountedPointer<U>&& other) // NOLINT
79 : impl_(std::move(other.impl())) {}
80 QuicReferenceCountedPointer(QuicReferenceCountedPointer&& other)
81 : impl_(std::move(other.impl())) {}
82
83 ~QuicReferenceCountedPointer() = default;
84
85 // Copy assignments.
86 QuicReferenceCountedPointer& operator=(
87 const QuicReferenceCountedPointer& other) {
88 impl_ = other.impl();
89 return *this;
90 }
91 template <typename U>
92 QuicReferenceCountedPointer<T>& operator=(
93 const QuicReferenceCountedPointer<U>& other) {
94 impl_ = other.impl();
95 return *this;
96 }
97
98 // Move assignments.
99 QuicReferenceCountedPointer& operator=(QuicReferenceCountedPointer&& other) {
100 impl_ = std::move(other.impl());
101 return *this;
102 }
103 template <typename U>
104 QuicReferenceCountedPointer<T>& operator=(
105 QuicReferenceCountedPointer<U>&& other) {
106 impl_ = std::move(other.impl());
107 return *this;
108 }
109
110 // Accessors for the referenced object.
bnc04dd0402019-03-08 10:24:19 -0500111 // operator*() and operator->() will assert() if there is no current object.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500112 T& operator*() const { return *impl_; }
113 T* operator->() const { return impl_.get(); }
114
115 explicit operator bool() const { return static_cast<bool>(impl_); }
116
117 // Assignment operator on raw pointer. Drops a reference to current pointee,
bnc04dd0402019-03-08 10:24:19 -0500118 // if any, and replaces it with |p|. This guarantees that the reference count
119 // of *p is 1. This should only be used when a new object is created. Calling
120 // this on an already existent object is undefined behavior.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500121 QuicReferenceCountedPointer<T>& operator=(T* p) {
122 impl_ = p;
123 return *this;
124 }
125
bnc04dd0402019-03-08 10:24:19 -0500126 // Returns the raw pointer with no change in reference count.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500127 T* get() const { return impl_.get(); }
128
129 QuicReferenceCountedPointerImpl<T>& impl() { return impl_; }
130 const QuicReferenceCountedPointerImpl<T>& impl() const { return impl_; }
131
132 // Comparisons against same type.
133 friend bool operator==(const QuicReferenceCountedPointer& a,
134 const QuicReferenceCountedPointer& b) {
135 return a.get() == b.get();
136 }
137 friend bool operator!=(const QuicReferenceCountedPointer& a,
138 const QuicReferenceCountedPointer& b) {
139 return a.get() != b.get();
140 }
141
142 // Comparisons against nullptr.
143 friend bool operator==(const QuicReferenceCountedPointer& a, std::nullptr_t) {
144 return a.get() == nullptr;
145 }
146 friend bool operator==(std::nullptr_t, const QuicReferenceCountedPointer& b) {
147 return nullptr == b.get();
148 }
149 friend bool operator!=(const QuicReferenceCountedPointer& a, std::nullptr_t) {
150 return a.get() != nullptr;
151 }
152 friend bool operator!=(std::nullptr_t, const QuicReferenceCountedPointer& b) {
153 return nullptr != b.get();
154 }
155
156 private:
157 QuicReferenceCountedPointerImpl<T> impl_;
158};
159
160} // namespace quic
161
162#endif // QUICHE_QUIC_PLATFORM_API_QUIC_REFERENCE_COUNTED_H_