Add skstd::string_view::substr

Change-Id: I06ba9dd9ed8af8555233ddfa10d3e0ec6babc2ea
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/444759
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
diff --git a/include/core/SkStringView.h b/include/core/SkStringView.h
index c705b11..de3777a 100644
--- a/include/core/SkStringView.h
+++ b/include/core/SkStringView.h
@@ -8,6 +8,7 @@
 #ifndef SkStringView_DEFINED
 #define SkStringView_DEFINED
 
+#include <algorithm>
 #include <cstring>
 #include <string>
 
@@ -22,6 +23,7 @@
     using iterator = const_pointer;
     using const_iterator = iterator;
     using size_type = size_t;
+    static constexpr size_type npos = size_type(-1);
 
     constexpr string_view()
         : fData(nullptr)
@@ -99,6 +101,13 @@
         return !this->empty() && this->back() == c;
     }
 
+    constexpr string_view substr(size_type pos = 0, size_type count = npos) const {
+        if (pos > fLength) {
+            return {};
+        }
+        return string_view{fData + pos, std::min(count, fLength - pos)};
+    }
+
     constexpr void swap(string_view& other) {
         const_pointer tempData = fData;
         fData = other.fData;
diff --git a/tests/SkStringViewTest.cpp b/tests/SkStringViewTest.cpp
index f40bdac..5aace30 100644
--- a/tests/SkStringViewTest.cpp
+++ b/tests/SkStringViewTest.cpp
@@ -130,3 +130,29 @@
     REPORTER_ASSERT(r, !(str > str));
     REPORTER_ASSERT(r, !(str >= "b"));
 }
+
+DEF_TEST(SkStringViewSubstr, r) {
+    skstd::string_view xyz("xyz");
+    REPORTER_ASSERT(r, xyz.substr() == xyz);
+    REPORTER_ASSERT(r, xyz.substr(0, 1) == "x");
+    REPORTER_ASSERT(r, xyz.substr(0, 2) == "xy");
+    REPORTER_ASSERT(r, xyz.substr(0, 3) == "xyz");
+    REPORTER_ASSERT(r, xyz.substr(0, 4) == "xyz");
+
+    REPORTER_ASSERT(r, xyz.substr(1) == "yz");
+    REPORTER_ASSERT(r, xyz.substr(1, 1) == "y");
+    REPORTER_ASSERT(r, xyz.substr(1, 2) == "yz");
+    REPORTER_ASSERT(r, xyz.substr(1, 3) == "yz");
+
+    REPORTER_ASSERT(r, xyz.substr(2) == "z");
+    REPORTER_ASSERT(r, xyz.substr(2, 1) == "z");
+    REPORTER_ASSERT(r, xyz.substr(2, 2) == "z");
+
+    REPORTER_ASSERT(r, xyz.substr(0, 0).empty());
+    REPORTER_ASSERT(r, xyz.substr(1, 0).empty());
+    REPORTER_ASSERT(r, xyz.substr(2, 0).empty());
+    REPORTER_ASSERT(r, xyz.substr(3, 0).empty());
+
+    REPORTER_ASSERT(r, xyz.substr(3).empty());
+    REPORTER_ASSERT(r, xyz.substr(4).empty());
+}