chromium/third_party/ipcz/src/util/ref_counted.h

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

#ifndef IPCZ_SRC_UTIL_REF_COUNTED_H_
#define IPCZ_SRC_UTIL_REF_COUNTED_H_

#include <algorithm>
#include <atomic>
#include <cstddef>
#include <type_traits>
#include <utility>

#include "third_party/abseil-cpp/absl/base/macros.h"

namespace ipcz {

namespace internal {

// Base class for RefCounted<T> instances. See that definition below.
class RefCountedBase {};

}  // namespace internal

// Tag used to construct a Ref<T> which does not increase ref-count.
enum {};

// Base class for any ref-counted type T whose ownership can be shared by any
// number of Ref<T> objects.
template <typename T>
class RefCounted : public internal::RefCountedBase {};

// A smart pointer which can be used to share ownership of an instance of T,
// where T is any type derived from RefCounted above.
//
// This is used instead of std::shared_ptr so that ipcz can release and
// re-acquire ownership of individual references, as some object references may
// be conceptually owned by the embedding application via an IpczHandle across
// ipcz ABI boundary. std::shared_ptr design does not allow for such manual ref
// manipulation without additional indirection.
template <typename T>
class Ref {};

// Wraps `ptr` as a Ref<T>, increasing the refcount by 1.
template <typename T>
Ref<T> WrapRefCounted(T* ptr) {}

// Wraps `ptr` as a Ref<T>, assuming ownership of an existing reference. Does
// not change the object's refcount.
template <typename T>
Ref<T> AdoptRef(T* ptr) {}

template <typename T, typename... Args>
Ref<T> MakeRefCounted(Args&&... args) {}

}  // namespace ipcz

#endif  // IPCZ_SRC_UTIL_REF_COUNTED_H_