aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib/gprpp/ref_counted_ptr.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lib/gprpp/ref_counted_ptr.h')
-rw-r--r--src/core/lib/gprpp/ref_counted_ptr.h70
1 files changed, 59 insertions, 11 deletions
diff --git a/src/core/lib/gprpp/ref_counted_ptr.h b/src/core/lib/gprpp/ref_counted_ptr.h
index 534d3d03cb..91ca8eae63 100644
--- a/src/core/lib/gprpp/ref_counted_ptr.h
+++ b/src/core/lib/gprpp/ref_counted_ptr.h
@@ -36,7 +36,10 @@ class RefCountedPtr {
RefCountedPtr(std::nullptr_t) {}
// If value is non-null, we take ownership of a ref to it.
- explicit RefCountedPtr(T* value) { value_ = value; }
+ template <typename Y>
+ explicit RefCountedPtr(Y* value) {
+ value_ = value;
+ }
// Move support.
RefCountedPtr(RefCountedPtr&& other) {
@@ -49,6 +52,18 @@ class RefCountedPtr {
other.value_ = nullptr;
return *this;
}
+ template <typename Y>
+ RefCountedPtr(RefCountedPtr<Y>&& other) {
+ value_ = other.value_;
+ other.value_ = nullptr;
+ }
+ template <typename Y>
+ RefCountedPtr& operator=(RefCountedPtr<Y>&& other) {
+ if (value_ != nullptr) value_->Unref();
+ value_ = other.value_;
+ other.value_ = nullptr;
+ return *this;
+ }
// Copy support.
RefCountedPtr(const RefCountedPtr& other) {
@@ -63,17 +78,37 @@ class RefCountedPtr {
value_ = other.value_;
return *this;
}
+ template <typename Y>
+ RefCountedPtr(const RefCountedPtr<Y>& other) {
+ if (other.value_ != nullptr) other.value_->IncrementRefCount();
+ value_ = other.value_;
+ }
+ template <typename Y>
+ RefCountedPtr& operator=(const RefCountedPtr<Y>& other) {
+ // Note: Order of reffing and unreffing is important here in case value_
+ // and other.value_ are the same object.
+ if (other.value_ != nullptr) other.value_->IncrementRefCount();
+ if (value_ != nullptr) value_->Unref();
+ value_ = other.value_;
+ return *this;
+ }
~RefCountedPtr() {
if (value_ != nullptr) value_->Unref();
}
// If value is non-null, we take ownership of a ref to it.
- void reset(T* value = nullptr) {
+ template <typename Y>
+ void reset(Y* value) {
if (value_ != nullptr) value_->Unref();
value_ = value;
}
+ void reset() {
+ if (value_ != nullptr) value_->Unref();
+ value_ = nullptr;
+ }
+
// TODO(roth): This method exists solely as a transition mechanism to allow
// us to pass a ref to idiomatic C code that does not use RefCountedPtr<>.
// Once all of our code has been converted to idiomatic C++, this
@@ -89,16 +124,34 @@ class RefCountedPtr {
T& operator*() const { return *value_; }
T* operator->() const { return value_; }
- bool operator==(const RefCountedPtr& other) const {
+ template <typename Y>
+ bool operator==(const RefCountedPtr<Y>& other) const {
return value_ == other.value_;
}
- bool operator==(const T* other) const { return value_ == other; }
- bool operator!=(const RefCountedPtr& other) const {
+
+ template <typename Y>
+ bool operator==(const Y* other) const {
+ return value_ == other;
+ }
+
+ bool operator==(std::nullptr_t) const { return value_ == nullptr; }
+
+ template <typename Y>
+ bool operator!=(const RefCountedPtr<Y>& other) const {
return value_ != other.value_;
}
- bool operator!=(const T* other) const { return value_ != other; }
+
+ template <typename Y>
+ bool operator!=(const Y* other) const {
+ return value_ != other;
+ }
+
+ bool operator!=(std::nullptr_t) const { return value_ != nullptr; }
private:
+ template <typename Y>
+ friend class RefCountedPtr;
+
T* value_ = nullptr;
};
@@ -107,11 +160,6 @@ inline RefCountedPtr<T> MakeRefCounted(Args&&... args) {
return RefCountedPtr<T>(New<T>(std::forward<Args>(args)...));
}
-template <typename Parent, typename Child, typename... Args>
-inline RefCountedPtr<Parent> MakePolymorphicRefCounted(Args&&... args) {
- return RefCountedPtr<Parent>(New<Child>(std::forward<Args>(args)...));
-}
-
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_GPRPP_REF_COUNTED_PTR_H */