1 | // Copyright 2023 The Abseil Authors. |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | #ifndef ABSL_BASE_INTERNAL_NULLABILITY_IMPL_H_ |
16 | #define ABSL_BASE_INTERNAL_NULLABILITY_IMPL_H_ |
17 | |
18 | #include <memory> |
19 | #include <type_traits> |
20 | |
21 | #include "absl/base/attributes.h" |
22 | #include "absl/meta/type_traits.h" |
23 | |
24 | namespace absl { |
25 | |
26 | namespace nullability_internal { |
27 | |
28 | // `IsNullabilityCompatible` checks whether its first argument is a class |
29 | // explicitly tagged as supporting nullability annotations. The tag is the type |
30 | // declaration `absl_nullability_compatible`. |
31 | template <typename, typename = void> |
32 | struct IsNullabilityCompatible : std::false_type {}; |
33 | |
34 | template <typename T> |
35 | struct IsNullabilityCompatible< |
36 | T, absl::void_t<typename T::absl_nullability_compatible>> : std::true_type { |
37 | }; |
38 | |
39 | template <typename T> |
40 | constexpr bool IsSupportedType = IsNullabilityCompatible<T>::value; |
41 | |
42 | template <typename T> |
43 | constexpr bool IsSupportedType<T*> = true; |
44 | |
45 | template <typename T, typename U> |
46 | constexpr bool IsSupportedType<T U::*> = true; |
47 | |
48 | template <typename T, typename... Deleter> |
49 | constexpr bool IsSupportedType<std::unique_ptr<T, Deleter...>> = true; |
50 | |
51 | template <typename T> |
52 | constexpr bool IsSupportedType<std::shared_ptr<T>> = true; |
53 | |
54 | template <typename T> |
55 | struct EnableNullable { |
56 | static_assert(nullability_internal::IsSupportedType<std::remove_cv_t<T>>, |
57 | "Template argument must be a raw or supported smart pointer " |
58 | "type. See absl/base/nullability.h." ); |
59 | using type = T; |
60 | }; |
61 | |
62 | template <typename T> |
63 | struct EnableNonnull { |
64 | static_assert(nullability_internal::IsSupportedType<std::remove_cv_t<T>>, |
65 | "Template argument must be a raw or supported smart pointer " |
66 | "type. See absl/base/nullability.h." ); |
67 | using type = T; |
68 | }; |
69 | |
70 | template <typename T> |
71 | struct EnableNullabilityUnknown { |
72 | static_assert(nullability_internal::IsSupportedType<std::remove_cv_t<T>>, |
73 | "Template argument must be a raw or supported smart pointer " |
74 | "type. See absl/base/nullability.h." ); |
75 | using type = T; |
76 | }; |
77 | |
78 | // Note: we do not apply Clang nullability attributes (e.g. _Nullable). These |
79 | // only support raw pointers, and conditionally enabling them only for raw |
80 | // pointers inhibits template arg deduction. Ideally, they would support all |
81 | // pointer-like types. |
82 | template <typename T, typename = typename EnableNullable<T>::type> |
83 | using NullableImpl |
84 | #if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate) |
85 | [[clang::annotate("Nullable" )]] |
86 | #endif |
87 | = T; |
88 | |
89 | template <typename T, typename = typename EnableNonnull<T>::type> |
90 | using NonnullImpl |
91 | #if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate) |
92 | [[clang::annotate("Nonnull" )]] |
93 | #endif |
94 | = T; |
95 | |
96 | template <typename T, typename = typename EnableNullabilityUnknown<T>::type> |
97 | using NullabilityUnknownImpl |
98 | #if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate) |
99 | [[clang::annotate("Nullability_Unspecified" )]] |
100 | #endif |
101 | = T; |
102 | |
103 | } // namespace nullability_internal |
104 | } // namespace absl |
105 | |
106 | #endif // ABSL_BASE_INTERNAL_NULLABILITY_IMPL_H_ |
107 | |