chromium/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ref.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.

// IWYU pragma: private, include "base/memory/raw_ref.h"

#ifndef PARTITION_ALLOC_POINTERS_RAW_REF_H_
#define PARTITION_ALLOC_POINTERS_RAW_REF_H_

#include <memory>
#include <type_traits>
#include <utility>

#include "partition_alloc/buildflags.h"
#include "partition_alloc/partition_alloc_base/augmentations/compiler_specific.h"
#include "partition_alloc/partition_alloc_base/compiler_specific.h"
#include "partition_alloc/partition_alloc_config.h"
#include "partition_alloc/pointers/raw_ptr.h"

namespace base {

template <class T, RawPtrTraits Traits>
class raw_ref;

namespace internal {

template <class T>
struct is_raw_ref : std::false_type {};

is_raw_ref< ::base::raw_ref<T, Traits>>;

is_raw_ref_v;

}  // namespace internal

// A smart pointer for a pointer which can not be null, and which provides
// Use-after-Free protection in the same ways as raw_ptr. This class acts like a
// combination of std::reference_wrapper and raw_ptr.
//
// See raw_ptr and //base/memory/raw_ptr.md for more details on the
// Use-after-Free protection.
//
// # Use after move
//
// The raw_ref type will abort if used after being moved.
//
// # Constness
//
// Use a `const raw_ref<T>` when the smart pointer should not be able to rebind
// to a new reference. Use a `const raw_ref<const T>` do the same for a const
// reference, which is like `const T&`.
//
// Unlike a native `T&` reference, a mutable `raw_ref<T>` can be changed
// independent of the underlying `T`, similar to `std::reference_wrapper`. That
// means the reference inside it can be moved and reassigned.
template <class T, RawPtrTraits ReferenceTraits = RawPtrTraits::kEmpty>
class PA_TRIVIAL_ABI PA_GSL_POINTER raw_ref {};

template <typename U, typename V, RawPtrTraits Traits1, RawPtrTraits Traits2>
PA_ALWAYS_INLINE bool operator==(const raw_ref<U, Traits1>& lhs,
                                 const raw_ref<V, Traits2>& rhs) {}
template <typename U, typename V, RawPtrTraits Traits1, RawPtrTraits Traits2>
PA_ALWAYS_INLINE bool operator!=(const raw_ref<U, Traits1>& lhs,
                                 const raw_ref<V, Traits2>& rhs) {}
template <typename U, typename V, RawPtrTraits Traits1, RawPtrTraits Traits2>
PA_ALWAYS_INLINE bool operator<(const raw_ref<U, Traits1>& lhs,
                                const raw_ref<V, Traits2>& rhs) {}
template <typename U, typename V, RawPtrTraits Traits1, RawPtrTraits Traits2>
PA_ALWAYS_INLINE bool operator>(const raw_ref<U, Traits1>& lhs,
                                const raw_ref<V, Traits2>& rhs) {}
template <typename U, typename V, RawPtrTraits Traits1, RawPtrTraits Traits2>
PA_ALWAYS_INLINE bool operator<=(const raw_ref<U, Traits1>& lhs,
                                 const raw_ref<V, Traits2>& rhs) {}
template <typename U, typename V, RawPtrTraits Traits1, RawPtrTraits Traits2>
PA_ALWAYS_INLINE bool operator>=(const raw_ref<U, Traits1>& lhs,
                                 const raw_ref<V, Traits2>& rhs) {}

// CTAD deduction guide.
template <class T>
raw_ref(T&) -> raw_ref<T>;
template <class T>
raw_ref(const T&) -> raw_ref<const T>;

// Template helpers for working with raw_ref<T>.
template <typename T>
struct IsRawRef : std::false_type {};

IsRawRef<raw_ref<T, Traits>>;

IsRawRefV;

template <typename T>
struct RemoveRawRef {};

RemoveRawRef<raw_ref<T, Traits>>;

RemoveRawRefT;

}  // namespace base

raw_ref;

template <base::RawPtrTraits Traits = base::RawPtrTraits::kEmpty, typename T>
auto ToRawRef(T& ref) {}

namespace std {

// Override so set/map lookups do not create extra raw_ref. This also
// allows C++ references to be used for lookup.
less<raw_ref<T, Traits>>;

// Specialize std::pointer_traits. The latter is required to obtain the
// underlying raw pointer in the std::to_address(pointer) overload.
// Implementing the pointer_traits is the standard blessed way to customize
// `std::to_address(pointer)` in C++20 [3].
//
// [1] https://wg21.link/pointer.traits.optmem

pointer_traits< ::raw_ref<T, Traits>>;

}  // namespace std

#endif  // PARTITION_ALLOC_POINTERS_RAW_REF_H_