summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quic/platform/api/quic_reference_counted.h
blob: 6ffc237db36524918a00eb65c48da3e2bc38fe85 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// Copyright (c) 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef QUICHE_QUIC_PLATFORM_API_QUIC_REFERENCE_COUNTED_H_
#define QUICHE_QUIC_PLATFORM_API_QUIC_REFERENCE_COUNTED_H_

#include "net/quic/platform/impl/quic_reference_counted_impl.h"

namespace quic {

// Base class for explicitly reference-counted objects in QUIC.
class QUIC_EXPORT_PRIVATE QuicReferenceCounted
    : public QuicReferenceCountedImpl {
 public:
  QuicReferenceCounted() {}

 protected:
  ~QuicReferenceCounted() override {}
};

// A class representing a reference counted pointer in QUIC.
//
// Construct or initialize QuicReferenceCountedPointer from raw pointer. Here
// raw pointer MUST be a newly created object. Reference count of a newly
// created object is undefined, but that will be 1 after being added to
// QuicReferenceCountedPointer.
// QuicReferenceCountedPointer is used as a local variable.
// QuicReferenceCountedPointer<T> r_ptr(new T());
// or, equivalently:
// QuicReferenceCountedPointer<T> r_ptr;
// T* p = new T();
// r_ptr = T;
//
// QuicReferenceCountedPointer is used as a member variable:
// MyClass::MyClass() : r_ptr(new T()) {}
//
// This is WRONG, since *p is not guaranteed to be newly created:
// MyClass::MyClass(T* p) : r_ptr(p) {}
//
// Given an existing QuicReferenceCountedPointer, create a duplicate that has
// its own reference on the object:
// QuicReferenceCountedPointer<T> r_ptr_b(r_ptr_a);
// or, equivalently:
// QuicReferenceCountedPointer<T> r_ptr_b = r_ptr_a;
//
// Given an existing QuicReferenceCountedPointer, create a
// QuicReferenceCountedPointer that adopts the reference:
// QuicReferenceCountedPointer<T> r_ptr_b(std::move(r_ptr_a));
// or, equivalently:
// QuicReferenceCountedPointer<T> r_ptr_b = std::move(r_ptr_a);

template <class T>
class QuicReferenceCountedPointer {
 public:
  QuicReferenceCountedPointer() = default;

  // Constructor from raw pointer |p|. This guarantees that the reference count
  // of *p is 1. This should be only called when a new object is created.
  // Calling this on an already existent object does not increase its reference
  // count.
  explicit QuicReferenceCountedPointer(T* p) : impl_(p) {}

  // Allows implicit conversion from nullptr.
  QuicReferenceCountedPointer(std::nullptr_t) : impl_(nullptr) {}  // NOLINT

  // Copy and copy conversion constructors. It does not take the reference away
  // from |other| and they each end up with their own reference.
  template <typename U>
  QuicReferenceCountedPointer(  // NOLINT
      const QuicReferenceCountedPointer<U>& other)
      : impl_(other.impl()) {}
  QuicReferenceCountedPointer(const QuicReferenceCountedPointer& other)
      : impl_(other.impl()) {}

  // Move constructors. After move, it adopts the reference from |other|.
  template <typename U>
  QuicReferenceCountedPointer(QuicReferenceCountedPointer<U>&& other)  // NOLINT
      : impl_(std::move(other.impl())) {}
  QuicReferenceCountedPointer(QuicReferenceCountedPointer&& other)
      : impl_(std::move(other.impl())) {}

  ~QuicReferenceCountedPointer() = default;

  // Copy assignments.
  QuicReferenceCountedPointer& operator=(
      const QuicReferenceCountedPointer& other) {
    impl_ = other.impl();
    return *this;
  }
  template <typename U>
  QuicReferenceCountedPointer<T>& operator=(
      const QuicReferenceCountedPointer<U>& other) {
    impl_ = other.impl();
    return *this;
  }

  // Move assignments.
  QuicReferenceCountedPointer& operator=(QuicReferenceCountedPointer&& other) {
    impl_ = std::move(other.impl());
    return *this;
  }
  template <typename U>
  QuicReferenceCountedPointer<T>& operator=(
      QuicReferenceCountedPointer<U>&& other) {
    impl_ = std::move(other.impl());
    return *this;
  }

  // Accessors for the referenced object.
  // operator*() and operator->() will assert() if there is no current object.
  T& operator*() const { return *impl_; }
  T* operator->() const { return impl_.get(); }

  explicit operator bool() const { return static_cast<bool>(impl_); }

  // Assignment operator on raw pointer. Drops a reference to current pointee,
  // if any, and replaces it with |p|. This guarantees that the reference count
  // of *p is 1. This should only be used when a new object is created.  Calling
  // this on an already existent object is undefined behavior.
  QuicReferenceCountedPointer<T>& operator=(T* p) {
    impl_ = p;
    return *this;
  }

  // Returns the raw pointer with no change in reference count.
  T* get() const { return impl_.get(); }

  QuicReferenceCountedPointerImpl<T>& impl() { return impl_; }
  const QuicReferenceCountedPointerImpl<T>& impl() const { return impl_; }

  // Comparisons against same type.
  friend bool operator==(const QuicReferenceCountedPointer& a,
                         const QuicReferenceCountedPointer& b) {
    return a.get() == b.get();
  }
  friend bool operator!=(const QuicReferenceCountedPointer& a,
                         const QuicReferenceCountedPointer& b) {
    return a.get() != b.get();
  }

  // Comparisons against nullptr.
  friend bool operator==(const QuicReferenceCountedPointer& a, std::nullptr_t) {
    return a.get() == nullptr;
  }
  friend bool operator==(std::nullptr_t, const QuicReferenceCountedPointer& b) {
    return nullptr == b.get();
  }
  friend bool operator!=(const QuicReferenceCountedPointer& a, std::nullptr_t) {
    return a.get() != nullptr;
  }
  friend bool operator!=(std::nullptr_t, const QuicReferenceCountedPointer& b) {
    return nullptr != b.get();
  }

 private:
  QuicReferenceCountedPointerImpl<T> impl_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_PLATFORM_API_QUIC_REFERENCE_COUNTED_H_