// 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 // 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 inline constexpr bool IsCompleteTypeV = false; template inline constexpr bool IsCompleteTypeV> = 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 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 = true; // Functions have static lifetime and are always safe for use with // `Unretained()`. template inline constexpr bool IsIncompleteTypeSafeForUnretained = true; // Various opaque system types that should still be usable with the base // callback system. Please keep sorted. template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template <> inline constexpr bool IsIncompleteTypeSafeForUnretained = true; template 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 || IsIncompleteTypeSafeForUnretained>, "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 struct TypeSupportsUnretained { static constexpr inline bool kValue = false; }; // True if `T` is annotated with `DISALLOW_UNRETAINED()` and false otherwise. template static inline constexpr bool TypeSupportsUnretainedV = TypeSupportsUnretained::kValue; } // namespace base::internal #endif // BASE_FUNCTIONAL_UNRETAINED_TRAITS_H_