1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
// 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 BASE_FUNCTIONAL_UNRETAINED_TRAITS_H_
#define BASE_FUNCTIONAL_UNRETAINED_TRAITS_H_
#include "build/build_config.h"
#include <type_traits>
// Various opaque system types that should still be usable with the base
// callback system. Please keep sorted.
struct ANativeWindow;
struct DBusMessage;
struct HWND__;
struct VkBuffer_T;
struct VkDeviceMemory_T;
struct VkImage_T;
struct VkSemaphore_T;
struct VmaAllocation_T;
struct WGPUAdapterImpl;
struct fpdf_action_t__;
struct fpdf_annotation_t__;
struct fpdf_attachment_t__;
struct fpdf_bookmark_t__;
struct fpdf_document_t__;
struct fpdf_form_handle_t__;
struct fpdf_page_t__;
struct fpdf_structelement_t__;
struct hb_set_t;
struct wl_gpu;
struct wl_shm;
struct wl_surface;
namespace base::internal {
// True if `T` is completely defined or false otherwise. Note that this always
// returns false for function types.
template <typename T, typename = void>
inline constexpr bool IsCompleteTypeV = false;
template <typename T>
inline constexpr bool IsCompleteTypeV<T, std::void_t<decltype(sizeof(T))>> =
true;
// Determining whether a type can be used with `Unretained()` requires that `T`
// be completely defined. Some system types have an intentionally opaque and
// incomplete representation, but should still be usable with `Unretained()`.
// The specializations here provide intentional escape hatches for those
// instances.
template <typename T>
inline constexpr bool IsIncompleteTypeSafeForUnretained = false;
// void* is occasionally used with callbacks; in the future, this may be more
// restricted/limited, but allow it for now.
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<void> = true;
// Functions have static lifetime and are always safe for use with
// `Unretained()`.
template <typename R, typename... Args>
inline constexpr bool IsIncompleteTypeSafeForUnretained<R(Args...)> = true;
// Various opaque system types that should still be usable with the base
// callback system. Please keep sorted.
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<ANativeWindow> = true;
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<DBusMessage> = true;
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<HWND__> = true;
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<VkBuffer_T> = true;
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<VkDeviceMemory_T> =
true;
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<VkImage_T> = true;
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<VkSemaphore_T> = true;
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<VmaAllocation_T> = true;
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<WGPUAdapterImpl> = true;
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<fpdf_action_t__> = true;
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<fpdf_annotation_t__> =
true;
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<fpdf_attachment_t__> =
true;
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<fpdf_bookmark_t__> =
true;
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<fpdf_document_t__> =
true;
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<fpdf_form_handle_t__> =
true;
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<fpdf_page_t__> = true;
template <>
inline constexpr bool
IsIncompleteTypeSafeForUnretained<fpdf_structelement_t__> = true;
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<hb_set_t> = true;
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<wl_gpu> = true;
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<wl_shm> = true;
template <>
inline constexpr bool IsIncompleteTypeSafeForUnretained<wl_surface> = true;
template <typename T, typename SFINAE = void>
struct TypeSupportsUnretained {
// Incrementally enforce the requirement to be completely defined. For now,
// limit the failures to:
//
// - non-test code
// - non-official code (because these builds don't run as part of the default CQ
// and are slower due to PGO and LTO)
// - Android, Linux or Windows
//
// to make this easier to land without potentially breaking the tree.
//
// TODO(https://crbug.com/1392872): Enable this on all platforms, then in
// official builds, and then in non-test code as well.
#if !defined(UNIT_TEST) && !defined(OFFICIAL_BUILD)
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) || \
defined(FORCE_UNRETAINED_COMPLETENESS_CHECKS_FOR_TESTS)
static_assert(IsCompleteTypeV<T> ||
IsIncompleteTypeSafeForUnretained<std::remove_cv_t<T>>,
"T must be fully defined.");
#endif
#endif // !defined(UNIT_TEST) && !defined(OFFICIAL_BUILD)
static constexpr inline bool kValue = true;
};
// Matches against the marker tag created by the `DISALLOW_UNRETAINED()` macro
// in //base/functional/disallow_unretained.h.
template <typename T>
struct TypeSupportsUnretained<T, typename T::DisallowBaseUnretainedMarker> {
static constexpr inline bool kValue = false;
};
// True if `T` is annotated with `DISALLOW_UNRETAINED()` and false otherwise.
template <typename T>
static inline constexpr bool TypeSupportsUnretainedV =
TypeSupportsUnretained<T>::kValue;
} // namespace base::internal
#endif // BASE_FUNCTIONAL_UNRETAINED_TRAITS_H_
|