Add bssl::Span<T>::subspan and use it.

This roughly aligns with absl::Span<T>::subspan.

Bug: 132
Change-Id: Iaf29418c1b10e2d357763dec90b6cb1371b86c3b
Reviewed-on: https://boringssl-review.googlesource.com/20824
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Martin Kreichgauer <martinkr@google.com>
diff --git a/include/openssl/span.h b/include/openssl/span.h
index d447314..97361c2 100644
--- a/include/openssl/span.h
+++ b/include/openssl/span.h
@@ -22,6 +22,7 @@
 extern "C++" {
 
 #include <algorithm>
+#include <cstdlib>
 #include <type_traits>
 
 namespace bssl {
@@ -104,6 +105,8 @@
       std::is_convertible<decltype(std::declval<C>().data()), T *>::value &&
       std::is_integral<decltype(std::declval<C>().size())>::value>;
 
+  static const size_t npos = -1;
+
  public:
   constexpr Span() : Span(nullptr, 0) {}
   constexpr Span(T *ptr, size_t len) : data_(ptr), size_(len) {}
@@ -124,6 +127,7 @@
 
   T *data() const { return data_; }
   size_t size() const { return size_; }
+  bool empty() const { return size_ == 0; }
 
   T *begin() const { return data_; }
   const T *cbegin() const { return data_; }
@@ -133,12 +137,22 @@
   T &operator[](size_t i) const { return data_[i]; }
   T &at(size_t i) const { return data_[i]; }
 
+  Span subspan(size_t pos = 0, size_t len = npos) const {
+    if (pos > size_) {
+      abort();  // absl::Span throws an exception here.
+    }
+    return Span(data_ + pos, std::min(size_ - pos, len));
+  }
+
  private:
   T *data_;
   size_t size_;
 };
 
 template <typename T>
+const size_t Span<T>::npos;
+
+template <typename T>
 Span<T> MakeSpan(T *ptr, size_t size) {
   return Span<T>(ptr, size);
 }