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