| // 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; |
| #ifdef COBALT_PENDING_CLEAN_UP |
| struct SbPlayerPrivate; |
| struct SbWindowPrivate; |
| struct SbUiNavItemPrivate; |
| struct SbDrmSystemPrivate; |
| #endif |
| |
| 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; |
| |
| #ifdef COBALT_PENDING_CLEAN_UP |
| template <> |
| inline constexpr bool IsIncompleteTypeSafeForUnretained<SbPlayerPrivate> = true; |
| template <> |
| inline constexpr bool IsIncompleteTypeSafeForUnretained<SbWindowPrivate> = true; |
| template <> |
| inline constexpr bool IsIncompleteTypeSafeForUnretained<SbUiNavItemPrivate> = true; |
| template <> |
| inline constexpr bool IsIncompleteTypeSafeForUnretained<SbDrmSystemPrivate> = true; |
| #endif |
| |
| 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_ |