llvm/llvm/include/llvm/ADT/IntrusiveRefCntPtr.h

//==- llvm/ADT/IntrusiveRefCntPtr.h - Smart Refcounting Pointer --*- C++ -*-==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file defines the RefCountedBase, ThreadSafeRefCountedBase, and
/// IntrusiveRefCntPtr classes.
///
/// IntrusiveRefCntPtr is a smart pointer to an object which maintains a
/// reference count.  (ThreadSafe)RefCountedBase is a mixin class that adds a
/// refcount member variable and methods for updating the refcount.  An object
/// that inherits from (ThreadSafe)RefCountedBase deletes itself when its
/// refcount hits zero.
///
/// For example:
///
/// ```
///   class MyClass : public RefCountedBase<MyClass> {};
///
///   void foo() {
///     // Constructing an IntrusiveRefCntPtr increases the pointee's refcount
///     // by 1 (from 0 in this case).
///     IntrusiveRefCntPtr<MyClass> Ptr1(new MyClass());
///
///     // Copying an IntrusiveRefCntPtr increases the pointee's refcount by 1.
///     IntrusiveRefCntPtr<MyClass> Ptr2(Ptr1);
///
///     // Constructing an IntrusiveRefCntPtr has no effect on the object's
///     // refcount.  After a move, the moved-from pointer is null.
///     IntrusiveRefCntPtr<MyClass> Ptr3(std::move(Ptr1));
///     assert(Ptr1 == nullptr);
///
///     // Clearing an IntrusiveRefCntPtr decreases the pointee's refcount by 1.
///     Ptr2.reset();
///
///     // The object deletes itself when we return from the function, because
///     // Ptr3's destructor decrements its refcount to 0.
///   }
/// ```
///
/// You can use IntrusiveRefCntPtr with isa<T>(), dyn_cast<T>(), etc.:
///
/// ```
///   IntrusiveRefCntPtr<MyClass> Ptr(new MyClass());
///   OtherClass *Other = dyn_cast<OtherClass>(Ptr);  // Ptr.get() not required
/// ```
///
/// IntrusiveRefCntPtr works with any class that
///
///  - inherits from (ThreadSafe)RefCountedBase,
///  - has Retain() and Release() methods, or
///  - specializes IntrusiveRefCntPtrInfo.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_ADT_INTRUSIVEREFCNTPTR_H
#define LLVM_ADT_INTRUSIVEREFCNTPTR_H

#include <atomic>
#include <cassert>
#include <cstddef>
#include <memory>

namespace llvm {

/// A CRTP mixin class that adds reference counting to a type.
///
/// The lifetime of an object which inherits from RefCountedBase is managed by
/// calls to Release() and Retain(), which increment and decrement the object's
/// refcount, respectively.  When a Release() call decrements the refcount to 0,
/// the object deletes itself.
template <class Derived> class RefCountedBase {};

/// A thread-safe version of \c RefCountedBase.
template <class Derived> class ThreadSafeRefCountedBase {};

/// Class you can specialize to provide custom retain/release functionality for
/// a type.
///
/// Usually specializing this class is not necessary, as IntrusiveRefCntPtr
/// works with any type which defines Retain() and Release() functions -- you
/// can define those functions yourself if RefCountedBase doesn't work for you.
///
/// One case when you might want to specialize this type is if you have
///  - Foo.h defines type Foo and includes Bar.h, and
///  - Bar.h uses IntrusiveRefCntPtr<Foo> in inline functions.
///
/// Because Foo.h includes Bar.h, Bar.h can't include Foo.h in order to pull in
/// the declaration of Foo.  Without the declaration of Foo, normally Bar.h
/// wouldn't be able to use IntrusiveRefCntPtr<Foo>, which wants to call
/// T::Retain and T::Release.
///
/// To resolve this, Bar.h could include a third header, FooFwd.h, which
/// forward-declares Foo and specializes IntrusiveRefCntPtrInfo<Foo>.  Then
/// Bar.h could use IntrusiveRefCntPtr<Foo>, although it still couldn't call any
/// functions on Foo itself, because Foo would be an incomplete type.
template <typename T> struct IntrusiveRefCntPtrInfo {};

/// A smart pointer to a reference-counted object that inherits from
/// RefCountedBase or ThreadSafeRefCountedBase.
///
/// This class increments its pointee's reference count when it is created, and
/// decrements its refcount when it's destroyed (or is changed to point to a
/// different object).
template <typename T> class IntrusiveRefCntPtr {};

template <class T, class U>
inline bool operator==(const IntrusiveRefCntPtr<T> &A,
                       const IntrusiveRefCntPtr<U> &B) {}

template <class T, class U>
inline bool operator!=(const IntrusiveRefCntPtr<T> &A,
                       const IntrusiveRefCntPtr<U> &B) {}

template <class T, class U>
inline bool operator==(const IntrusiveRefCntPtr<T> &A, U *B) {}

template <class T, class U>
inline bool operator!=(const IntrusiveRefCntPtr<T> &A, U *B) {}

template <class T, class U>
inline bool operator==(T *A, const IntrusiveRefCntPtr<U> &B) {}

template <class T, class U>
inline bool operator!=(T *A, const IntrusiveRefCntPtr<U> &B) {}

template <class T>
bool operator==(std::nullptr_t, const IntrusiveRefCntPtr<T> &B) {}

template <class T>
bool operator==(const IntrusiveRefCntPtr<T> &A, std::nullptr_t B) {}

template <class T>
bool operator!=(std::nullptr_t A, const IntrusiveRefCntPtr<T> &B) {}

template <class T>
bool operator!=(const IntrusiveRefCntPtr<T> &A, std::nullptr_t B) {}

// Make IntrusiveRefCntPtr work with dyn_cast, isa, and the other idioms from
// Casting.h.
template <typename From> struct simplify_type;

simplify_type<IntrusiveRefCntPtr<T>>;

simplify_type<const IntrusiveRefCntPtr<T>>;

/// Factory function for creating intrusive ref counted pointers.
template <typename T, typename... Args>
IntrusiveRefCntPtr<T> makeIntrusiveRefCnt(Args &&...A) {}

} // end namespace llvm

#endif // LLVM_ADT_INTRUSIVEREFCNTPTR_H