summaryrefslogtreecommitdiff
path: root/absl/types/span.h
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2022-07-18 07:17:15 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2022-07-18 07:18:09 -0700
commit5d9b8a9fb0a3b762e3c8f8141e19b1c0e69837ba (patch)
tree3fc407202e1ab91ba10f3cb9937c58cc766ed84e /absl/types/span.h
parent56f5477f15ab63f77a3f34487304d6c7e0965238 (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/span.h')
-rw-r--r--absl/types/span.h34
1 files changed, 28 insertions, 6 deletions
diff --git a/absl/types/span.h b/absl/types/span.h
index fdfbd77c..cd863a95 100644
--- a/absl/types/span.h
+++ b/absl/types/span.h
@@ -60,6 +60,7 @@
#include <type_traits>
#include <utility>
+#include "absl/base/attributes.h"
#include "absl/base/internal/throw_delegate.h"
#include "absl/base/macros.h"
#include "absl/base/optimization.h"
@@ -160,12 +161,12 @@ class Span {
// Used to SFINAE-enable a function when the slice elements are const.
template <typename U>
- using EnableIfConstView =
+ using EnableIfValueIsConst =
typename std::enable_if<std::is_const<T>::value, U>::type;
// Used to SFINAE-enable a function when the slice elements are mutable.
template <typename U>
- using EnableIfMutableView =
+ using EnableIfValueIsMutable =
typename std::enable_if<!std::is_const<T>::value, U>::type;
public:
@@ -196,13 +197,34 @@ class Span {
// Explicit reference constructor for a mutable `Span<T>` type. Can be
// replaced with MakeSpan() to infer the type parameter.
template <typename V, typename = EnableIfConvertibleFrom<V>,
- typename = EnableIfMutableView<V>>
- explicit Span(V& v) noexcept // NOLINT(runtime/references)
+ typename = EnableIfValueIsMutable<V>,
+ typename = span_internal::EnableIfNotIsView<V>>
+ explicit Span(
+ V& v
+ ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept // NOLINT(runtime/references)
: Span(span_internal::GetData(v), v.size()) {}
// Implicit reference constructor for a read-only `Span<const T>` type
template <typename V, typename = EnableIfConvertibleFrom<V>,
- typename = EnableIfConstView<V>>
+ typename = EnableIfValueIsConst<V>,
+ typename = span_internal::EnableIfNotIsView<V>>
+ constexpr Span(
+ const V& v
+ ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept // NOLINT(runtime/explicit)
+ : Span(span_internal::GetData(v), v.size()) {}
+
+ // Overloads of the above two functions that are only enabled for view types.
+ // This is so we can drop the ABSL_ATTRIBUTE_LIFETIME_BOUND annotation. These
+ // overloads must be made unique by using a different template parameter list
+ // (hence the = 0 for the IsView enabler).
+ template <typename V, typename = EnableIfConvertibleFrom<V>,
+ typename = EnableIfValueIsMutable<V>,
+ span_internal::EnableIfIsView<V> = 0>
+ explicit Span(V& v) noexcept // NOLINT(runtime/references)
+ : Span(span_internal::GetData(v), v.size()) {}
+ template <typename V, typename = EnableIfConvertibleFrom<V>,
+ typename = EnableIfValueIsConst<V>,
+ span_internal::EnableIfIsView<V> = 0>
constexpr Span(const V& v) noexcept // NOLINT(runtime/explicit)
: Span(span_internal::GetData(v), v.size()) {}
@@ -242,7 +264,7 @@ class Span {
// Process(ints);
//
template <typename LazyT = T,
- typename = EnableIfConstView<LazyT>>
+ typename = EnableIfValueIsConst<LazyT>>
Span(std::initializer_list<value_type> v
ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept // NOLINT(runtime/explicit)
: Span(v.begin(), v.size()) {}