File: unretained_traits.h

package info (click to toggle)
chromium 120.0.6099.224-1~deb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,112,112 kB
  • sloc: cpp: 32,907,025; ansic: 8,148,123; javascript: 3,679,536; python: 2,031,248; asm: 959,718; java: 804,675; xml: 617,256; sh: 111,417; objc: 100,835; perl: 88,443; cs: 53,032; makefile: 29,579; fortran: 24,137; php: 21,162; tcl: 21,147; sql: 20,809; ruby: 17,735; pascal: 12,864; yacc: 8,045; lisp: 3,388; lex: 1,323; ada: 727; awk: 329; jsp: 267; csh: 117; exp: 43; sed: 37
file content (157 lines) | stat: -rw-r--r-- 5,668 bytes parent folder | download | duplicates (2)
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_