summaryrefslogtreecommitdiff
path: root/src/include/openssl/span.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/openssl/span.h')
-rw-r--r--src/include/openssl/span.h52
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_;