|  | @@ -36,25 +36,49 @@ 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.
 | 
	
		
			
				|  |  | +  // Move ctors.
 | 
	
		
			
				|  |  |    RefCountedPtr(RefCountedPtr&& other) {
 | 
	
		
			
				|  |  |      value_ = other.value_;
 | 
	
		
			
				|  |  |      other.value_ = nullptr;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | +  template <typename Y>
 | 
	
		
			
				|  |  | +  RefCountedPtr(RefCountedPtr<Y>&& other) {
 | 
	
		
			
				|  |  | +    value_ = other.value_;
 | 
	
		
			
				|  |  | +    other.value_ = nullptr;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // Move assignment.
 | 
	
		
			
				|  |  |    RefCountedPtr& operator=(RefCountedPtr&& other) {
 | 
	
		
			
				|  |  |      if (value_ != nullptr) value_->Unref();
 | 
	
		
			
				|  |  |      value_ = other.value_;
 | 
	
		
			
				|  |  |      other.value_ = nullptr;
 | 
	
		
			
				|  |  |      return *this;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | +  template <typename Y>
 | 
	
		
			
				|  |  | +  RefCountedPtr& operator=(RefCountedPtr<Y>&& other) {
 | 
	
		
			
				|  |  | +    if (value_ != nullptr) value_->Unref();
 | 
	
		
			
				|  |  | +    value_ = other.value_;
 | 
	
		
			
				|  |  | +    other.value_ = nullptr;
 | 
	
		
			
				|  |  | +    return *this;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  // Copy support.
 | 
	
		
			
				|  |  | +  // Copy ctors.
 | 
	
		
			
				|  |  |    RefCountedPtr(const RefCountedPtr& other) {
 | 
	
		
			
				|  |  |      if (other.value_ != nullptr) other.value_->IncrementRefCount();
 | 
	
		
			
				|  |  |      value_ = other.value_;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | +  template <typename Y>
 | 
	
		
			
				|  |  | +  RefCountedPtr(const RefCountedPtr<Y>& other) {
 | 
	
		
			
				|  |  | +    if (other.value_ != nullptr) other.value_->IncrementRefCount();
 | 
	
		
			
				|  |  | +    value_ = other.value_;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // Copy assignment.
 | 
	
		
			
				|  |  |    RefCountedPtr& operator=(const RefCountedPtr& other) {
 | 
	
		
			
				|  |  |      // Note: Order of reffing and unreffing is important here in case value_
 | 
	
		
			
				|  |  |      // and other.value_ are the same object.
 | 
	
	
		
			
				|  | @@ -63,17 +87,32 @@ class RefCountedPtr {
 | 
	
		
			
				|  |  |      value_ = other.value_;
 | 
	
		
			
				|  |  |      return *this;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | +  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 +128,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 +164,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 */
 |