chromium/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/memory/scoped_refptr.h

// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef PARTITION_ALLOC_PARTITION_ALLOC_BASE_MEMORY_SCOPED_REFPTR_H_
#define PARTITION_ALLOC_PARTITION_ALLOC_BASE_MEMORY_SCOPED_REFPTR_H_

#include <cstddef>
#include <iosfwd>
#include <type_traits>
#include <utility>

#include "partition_alloc/partition_alloc_base/check.h"
#include "partition_alloc/partition_alloc_base/compiler_specific.h"

namespace partition_alloc::internal {

template <class T>
class scoped_refptr;

namespace base {

template <class, typename>
class RefCountedThreadSafe;

template <typename T>
scoped_refptr<T> AdoptRef(T* t);

namespace subtle {

enum AdoptRefTag {};
enum StartRefCountFromZeroTag {};
enum StartRefCountFromOneTag {};

// scoped_refptr<T> is typically used with one of several RefCounted<T> base
// classes or with custom AddRef and Release methods. These overloads dispatch
// on which was used.

template <typename T, typename U, typename V>
constexpr bool IsRefCountPreferenceOverridden(
    const T*,
    const RefCountedThreadSafe<U, V>*) {}

constexpr bool IsRefCountPreferenceOverridden(...) {}

template <typename T, typename U, typename V>
constexpr void AssertRefCountBaseMatches(const T*,
                                         const RefCountedThreadSafe<U, V>*) {}

constexpr void AssertRefCountBaseMatches(...) {}

}  // namespace subtle

// Creates a scoped_refptr from a raw pointer without incrementing the reference
// count. Use this only for a newly created object whose reference count starts
// from 1 instead of 0.
template <typename T>
scoped_refptr<T> AdoptRef(T* obj) {}

namespace subtle {

template <typename T>
scoped_refptr<T> AdoptRefIfNeeded(T* obj, StartRefCountFromZeroTag) {}

template <typename T>
scoped_refptr<T> AdoptRefIfNeeded(T* obj, StartRefCountFromOneTag) {}

}  // namespace subtle

// Constructs an instance of T, which is a ref counted type, and wraps the
// object into a scoped_refptr<T>.
template <typename T, typename... Args>
scoped_refptr<T> MakeRefCounted(Args&&... args) {}

// Takes an instance of T, which is a ref counted type, and wraps the object
// into a scoped_refptr<T>.
template <typename T>
scoped_refptr<T> WrapRefCounted(T* t) {}

}  // namespace base

//
// A smart pointer class for reference counted objects.  Use this class instead
// of calling AddRef and Release manually on a reference counted object to
// avoid common memory leaks caused by forgetting to Release an object
// reference.  Sample usage:
//
//   class MyFoo : public RefCounted<MyFoo> {
//    ...
//    private:
//     friend class RefCounted<MyFoo>;  // Allow destruction by RefCounted<>.
//     ~MyFoo();                        // Destructor must be private/protected.
//   };
//
//   void some_function() {
//     scoped_refptr<MyFoo> foo = MakeRefCounted<MyFoo>();
//     foo->Method(param);
//     // |foo| is released when this function returns
//   }
//
//   void some_other_function() {
//     scoped_refptr<MyFoo> foo = MakeRefCounted<MyFoo>();
//     ...
//     foo.reset();  // explicitly releases |foo|
//     ...
//     if (foo)
//       foo->Method(param);
//   }
//
// The above examples show how scoped_refptr<T> acts like a pointer to T.
// Given two scoped_refptr<T> classes, it is also possible to exchange
// references between the two objects, like so:
//
//   {
//     scoped_refptr<MyFoo> a = MakeRefCounted<MyFoo>();
//     scoped_refptr<MyFoo> b;
//
//     b.swap(a);
//     // now, |b| references the MyFoo object, and |a| references nullptr.
//   }
//
// To make both |a| and |b| in the above example reference the same MyFoo
// object, simply use the assignment operator:
//
//   {
//     scoped_refptr<MyFoo> a = MakeRefCounted<MyFoo>();
//     scoped_refptr<MyFoo> b;
//
//     b = a;
//     // now, |a| and |b| each own a reference to the same MyFoo object.
//   }
//
// Also see Chromium's ownership and calling conventions:
// https://chromium.googlesource.com/chromium/src/+/lkgr/styleguide/c++/c++.md#object-ownership-and-calling-conventions
// Specifically:
//   If the function (at least sometimes) takes a ref on a refcounted object,
//   declare the param as scoped_refptr<T>. The caller can decide whether it
//   wishes to transfer ownership (by calling std::move(t) when passing t) or
//   retain its ref (by simply passing t directly).
//   In other words, use scoped_refptr like you would a std::unique_ptr except
//   in the odd case where it's required to hold on to a ref while handing one
//   to another component (if a component merely needs to use t on the stack
//   without keeping a ref: pass t as a raw T*).
template <class T>
class PA_TRIVIAL_ABI scoped_refptr {};

template <typename T>
T* scoped_refptr<T>::release() {}

// static
template <typename T>
void scoped_refptr<T>::AddRef(T* ptr) {}

// static
template <typename T>
void scoped_refptr<T>::Release(T* ptr) {}

template <typename T, typename U>
bool operator==(const scoped_refptr<T>& lhs, const U* rhs) {}

template <typename T, typename U>
bool operator==(const T* lhs, const scoped_refptr<U>& rhs) {}

template <typename T>
bool operator==(const scoped_refptr<T>& lhs, std::nullptr_t null) {}

template <typename T>
bool operator==(std::nullptr_t null, const scoped_refptr<T>& rhs) {}

template <typename T, typename U>
bool operator!=(const scoped_refptr<T>& lhs, const U* rhs) {}

template <typename T, typename U>
bool operator!=(const T* lhs, const scoped_refptr<U>& rhs) {}

template <typename T>
bool operator!=(const scoped_refptr<T>& lhs, std::nullptr_t null) {}

template <typename T>
bool operator!=(std::nullptr_t null, const scoped_refptr<T>& rhs) {}

template <typename T>
std::ostream& operator<<(std::ostream& out, const scoped_refptr<T>& p) {}

template <typename T>
void swap(scoped_refptr<T>& lhs, scoped_refptr<T>& rhs) noexcept {}

}  // namespace partition_alloc::internal

#endif  // PARTITION_ALLOC_PARTITION_ALLOC_BASE_MEMORY_SCOPED_REFPTR_H_