diff options
Diffstat (limited to 'src/include/openssl/span.h')
-rw-r--r-- | src/include/openssl/span.h | 52 |
1 files changed, 15 insertions, 37 deletions
diff --git a/src/include/openssl/span.h b/src/include/openssl/span.h index 79f1d416..7410bf90 100644 --- a/src/include/openssl/span.h +++ b/src/include/openssl/span.h @@ -94,6 +94,18 @@ class SpanBase { template <typename T> class Span : private internal::SpanBase<const T> { private: + // Heuristically test whether C is a container type that can be converted into + // a Span by checking for data() and size() member functions. + // + // TODO(davidben): Switch everything to std::enable_if_t when we remove + // support for MSVC 2015. Although we could write our own enable_if_t and MSVC + // 2015 has std::enable_if_t anyway, MSVC 2015's SFINAE implementation is + // problematic and does not work below unless we write the ::type at use. + template <typename C> + using EnableIfContainer = std::enable_if< + std::is_convertible<decltype(std::declval<C>().data()), T *>::value && + std::is_integral<decltype(std::declval<C>().size())>::value>; + static const size_t npos = static_cast<size_t>(-1); public: @@ -104,27 +116,12 @@ class Span : private internal::SpanBase<const T> { constexpr Span(T (&array)[N]) : Span(array, N) {} template < - typename C, - // TODO(davidben): Switch everything to std::enable_if_t when we remove - // support for MSVC 2015. Although we could write our own enable_if_t and - // MSVC 2015 has std::enable_if_t anyway, MSVC 2015's SFINAE - // implementation is problematic and does not work below unless we write - // the ::type at use. - // - // TODO(davidben): Move this and the identical copy below into an - // EnableIfContainer alias when we drop MSVC 2015 support. MSVC 2015's - // SFINAE support cannot handle type aliases. - typename = typename std::enable_if< - std::is_convertible<decltype(std::declval<C>().data()), T *>::value && - std::is_integral<decltype(std::declval<C>().size())>::value>::type, + typename C, typename = typename EnableIfContainer<C>::type, typename = typename std::enable_if<std::is_const<T>::value, C>::type> Span(const C &container) : data_(container.data()), size_(container.size()) {} template < - typename C, - typename = typename std::enable_if< - std::is_convertible<decltype(std::declval<C>().data()), T *>::value && - std::is_integral<decltype(std::declval<C>().size())>::value>::type, + typename C, typename = typename EnableIfContainer<C>::type, typename = typename std::enable_if<!std::is_const<T>::value, C>::type> explicit Span(C &container) : data_(container.data()), size_(container.size()) {} @@ -161,30 +158,11 @@ class Span : private internal::SpanBase<const T> { Span subspan(size_t pos = 0, size_t len = npos) const { if (pos > size_) { - // absl::Span throws an exception here. Note std::span and Chromium - // base::span additionally forbid pos + len being out of range, with a - // special case at npos/dynamic_extent, while absl::Span::subspan clips - // the span. For now, we align with absl::Span in case we switch to it in - // the future. - abort(); + abort(); // absl::Span throws an exception here. } return Span(data_ + pos, std::min(size_ - pos, len)); } - Span first(size_t len) { - if (len > size_) { - abort(); - } - return Span(data_, len); - } - - Span last(size_t len) { - if (len > size_) { - abort(); - } - return Span(data_ + size_ - len, len); - } - private: T *data_; size_t size_; |