// 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_
