diff options
author | Abseil Team <absl-team@google.com> | 2022-07-18 07:17:15 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2022-07-18 07:18:09 -0700 |
commit | 5d9b8a9fb0a3b762e3c8f8141e19b1c0e69837ba (patch) | |
tree | 3fc407202e1ab91ba10f3cb9937c58cc766ed84e /absl/types/internal/span.h | |
parent | 56f5477f15ab63f77a3f34487304d6c7e0965238 (diff) |
Make Span complain if constructed with a parameter that won't outlive it, except if that parameter is also a span or appears to be a view type.
PiperOrigin-RevId: 461612357
Change-Id: Ibba36f44465176db47dd21e1866134549143fa64
Diffstat (limited to 'absl/types/internal/span.h')
-rw-r--r-- | absl/types/internal/span.h | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/absl/types/internal/span.h b/absl/types/internal/span.h index 112612f4..1920a89e 100644 --- a/absl/types/internal/span.h +++ b/absl/types/internal/span.h @@ -28,6 +28,9 @@ namespace absl { ABSL_NAMESPACE_BEGIN +template <typename T> +class Span; + namespace span_internal { // A constexpr min function constexpr size_t Min(size_t a, size_t b) noexcept { return a < b ? a : b; } @@ -121,6 +124,36 @@ struct IsConvertible : IsConvertibleHelper<From, To>::type {}; template <typename From, typename To> using EnableIfConvertibleTo = typename std::enable_if<IsConvertible<From, To>::value>::type; + +// IsView is true for types where the return type of .data() is the same for +// mutable and const instances. This isn't foolproof, but it's only used to +// enable a compiler warning. +template <typename T, typename = void, typename = void> +struct IsView { + static constexpr bool value = false; +}; + +template <typename T> +struct IsView< + T, absl::void_t<decltype(span_internal::GetData(std::declval<const T&>()))>, + absl::void_t<decltype(span_internal::GetData(std::declval<T&>()))>> { + private: + using Container = std::remove_const_t<T>; + using ConstData = + decltype(span_internal::GetData(std::declval<const Container&>())); + using MutData = decltype(span_internal::GetData(std::declval<Container&>())); + public: + static constexpr bool value = std::is_same<ConstData, MutData>::value; +}; + +// These enablers result in 'int' so they can be used as typenames or defaults +// in template paramters lists. +template <typename T> +using EnableIfIsView = std::enable_if_t<IsView<T>::value, int>; + +template <typename T> +using EnableIfNotIsView = std::enable_if_t<!IsView<T>::value, int>; + } // namespace span_internal ABSL_NAMESPACE_END } // namespace absl |