nullability_impl.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. #ifndef ABSL_BASE_INTERNAL_NULLABILITY_IMPL_H_
  15. #define ABSL_BASE_INTERNAL_NULLABILITY_IMPL_H_
  16. #include <memory>
  17. #include <type_traits>
  18. #include "absl/base/attributes.h"
  19. #include "absl/base/config.h"
  20. #include "absl/meta/type_traits.h"
  21. namespace absl {
  22. ABSL_NAMESPACE_BEGIN
  23. namespace nullability_internal {
  24. // `IsNullabilityCompatible` checks whether its first argument is a class
  25. // explicitly tagged as supporting nullability annotations. The tag is the type
  26. // declaration `absl_nullability_compatible`.
  27. template <typename, typename = void>
  28. struct IsNullabilityCompatible : std::false_type {};
  29. template <typename T>
  30. struct IsNullabilityCompatible<
  31. T, absl::void_t<typename T::absl_nullability_compatible>> : std::true_type {
  32. };
  33. template <typename T>
  34. constexpr bool IsSupportedType = IsNullabilityCompatible<T>::value;
  35. template <typename T>
  36. constexpr bool IsSupportedType<T*> = true;
  37. template <typename T, typename U>
  38. constexpr bool IsSupportedType<T U::*> = true;
  39. template <typename T, typename... Deleter>
  40. constexpr bool IsSupportedType<std::unique_ptr<T, Deleter...>> = true;
  41. template <typename T>
  42. constexpr bool IsSupportedType<std::shared_ptr<T>> = true;
  43. template <typename T>
  44. struct EnableNullable {
  45. static_assert(nullability_internal::IsSupportedType<std::remove_cv_t<T>>,
  46. "Template argument must be a raw or supported smart pointer "
  47. "type. See absl/base/nullability.h.");
  48. using type = T;
  49. };
  50. template <typename T>
  51. struct EnableNonnull {
  52. static_assert(nullability_internal::IsSupportedType<std::remove_cv_t<T>>,
  53. "Template argument must be a raw or supported smart pointer "
  54. "type. See absl/base/nullability.h.");
  55. using type = T;
  56. };
  57. template <typename T>
  58. struct EnableNullabilityUnknown {
  59. static_assert(nullability_internal::IsSupportedType<std::remove_cv_t<T>>,
  60. "Template argument must be a raw or supported smart pointer "
  61. "type. See absl/base/nullability.h.");
  62. using type = T;
  63. };
  64. // Note: we do not apply Clang nullability attributes (e.g. _Nullable). These
  65. // only support raw pointers, and conditionally enabling them only for raw
  66. // pointers inhibits template arg deduction. Ideally, they would support all
  67. // pointer-like types.
  68. template <typename T, typename = typename EnableNullable<T>::type>
  69. using NullableImpl
  70. #if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
  71. [[clang::annotate("Nullable")]]
  72. #endif
  73. = T;
  74. template <typename T, typename = typename EnableNonnull<T>::type>
  75. using NonnullImpl
  76. #if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
  77. [[clang::annotate("Nonnull")]]
  78. #endif
  79. = T;
  80. template <typename T, typename = typename EnableNullabilityUnknown<T>::type>
  81. using NullabilityUnknownImpl
  82. #if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
  83. [[clang::annotate("Nullability_Unspecified")]]
  84. #endif
  85. = T;
  86. } // namespace nullability_internal
  87. ABSL_NAMESPACE_END
  88. } // namespace absl
  89. #endif // ABSL_BASE_INTERNAL_NULLABILITY_IMPL_H_