123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- // Copyright 2023 The Abseil Authors.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // https://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- #ifndef ABSL_BASE_INTERNAL_NULLABILITY_IMPL_H_
- #define ABSL_BASE_INTERNAL_NULLABILITY_IMPL_H_
- #include <memory>
- #include <type_traits>
- #include "absl/base/attributes.h"
- #include "absl/base/config.h"
- #include "absl/meta/type_traits.h"
- namespace absl {
- ABSL_NAMESPACE_BEGIN
- namespace nullability_internal {
- // `IsNullabilityCompatible` checks whether its first argument is a class
- // explicitly tagged as supporting nullability annotations. The tag is the type
- // declaration `absl_nullability_compatible`.
- template <typename, typename = void>
- struct IsNullabilityCompatible : std::false_type {};
- template <typename T>
- struct IsNullabilityCompatible<
- T, absl::void_t<typename T::absl_nullability_compatible>> : std::true_type {
- };
- template <typename T>
- constexpr bool IsSupportedType = IsNullabilityCompatible<T>::value;
- template <typename T>
- constexpr bool IsSupportedType<T*> = true;
- template <typename T, typename U>
- constexpr bool IsSupportedType<T U::*> = true;
- template <typename T, typename... Deleter>
- constexpr bool IsSupportedType<std::unique_ptr<T, Deleter...>> = true;
- template <typename T>
- constexpr bool IsSupportedType<std::shared_ptr<T>> = true;
- template <typename T>
- struct EnableNullable {
- static_assert(nullability_internal::IsSupportedType<std::remove_cv_t<T>>,
- "Template argument must be a raw or supported smart pointer "
- "type. See absl/base/nullability.h.");
- using type = T;
- };
- template <typename T>
- struct EnableNonnull {
- static_assert(nullability_internal::IsSupportedType<std::remove_cv_t<T>>,
- "Template argument must be a raw or supported smart pointer "
- "type. See absl/base/nullability.h.");
- using type = T;
- };
- template <typename T>
- struct EnableNullabilityUnknown {
- static_assert(nullability_internal::IsSupportedType<std::remove_cv_t<T>>,
- "Template argument must be a raw or supported smart pointer "
- "type. See absl/base/nullability.h.");
- using type = T;
- };
- // Note: we do not apply Clang nullability attributes (e.g. _Nullable). These
- // only support raw pointers, and conditionally enabling them only for raw
- // pointers inhibits template arg deduction. Ideally, they would support all
- // pointer-like types.
- template <typename T, typename = typename EnableNullable<T>::type>
- using NullableImpl
- #if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
- [[clang::annotate("Nullable")]]
- #endif
- = T;
- template <typename T, typename = typename EnableNonnull<T>::type>
- using NonnullImpl
- #if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
- [[clang::annotate("Nonnull")]]
- #endif
- = T;
- template <typename T, typename = typename EnableNullabilityUnknown<T>::type>
- using NullabilityUnknownImpl
- #if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
- [[clang::annotate("Nullability_Unspecified")]]
- #endif
- = T;
- } // namespace nullability_internal
- ABSL_NAMESPACE_END
- } // namespace absl
- #endif // ABSL_BASE_INTERNAL_NULLABILITY_IMPL_H_
|