ViewBstr: replace std::string_view<uint8_t> with std::span

In newer versions of libc++, std::char_traits<T> is no longer defined
for non-character types, and a result, std::basic_string_view<uint8_t>
is also no longer defined. See
https://discourse.llvm.org/t/deprecating-std-string-t-for-non-character-t/66779.

Trusty defaults to C++20, and this code uses std::span from C++20, so
stop pinning the language mode to C++17.

Bug: 175635923
Test: trusty/vendor/google/aosp/scripts/build.py qemu-generic-arm64-test-debug
Change-Id: Ic926a5c194f089891333597c81383cd6b69cf9d5
diff --git a/include/cppbor/cppbor.h b/include/cppbor/cppbor.h
index 8338441..35facc0 100644
--- a/include/cppbor/cppbor.h
+++ b/include/cppbor/cppbor.h
@@ -16,12 +16,14 @@
 
 #pragma once
 
+#include <algorithm>
 #include <cassert>
 #include <cstdint>
 #include <functional>
 #include <iterator>
 #include <memory>
 #include <numeric>
+#include <span>
 #include <string>
 #include <string_view>
 #include <vector>
@@ -435,7 +437,7 @@
 };
 
 /**
- * ViewBstr is a read-only version of Bstr backed by std::string_view
+ * ViewBstr is a read-only version of Bstr backed by std::span
  */
 class ViewBstr : public Item {
   public:
@@ -444,8 +446,8 @@
     // Construct an empty ViewBstr
     explicit ViewBstr() {}
 
-    // Construct from a string_view of uint8_t values
-    explicit ViewBstr(std::basic_string_view<uint8_t> v) : mView(std::move(v)) {}
+    // Construct from a span of uint8_t values
+    explicit ViewBstr(std::span<const uint8_t> v) : mView(std::move(v)) {}
 
     // Construct from a string_view
     explicit ViewBstr(std::string_view v)
@@ -461,7 +463,9 @@
     ViewBstr(const uint8_t* begin, const uint8_t* end)
         : mView(begin, std::distance(begin, end)) {}
 
-    bool operator==(const ViewBstr& other) const& { return mView == other.mView; }
+    bool operator==(const ViewBstr& other) const& {
+        return std::equal(mView.begin(), mView.end(), other.mView.begin(), other.mView.end());
+    }
 
     MajorType type() const override { return kMajorType; }
     using Item::asViewBstr;
@@ -474,14 +478,14 @@
         encodeValue(encodeCallback);
     }
 
-    const std::basic_string_view<uint8_t>& view() const { return mView; }
+    const std::span<const uint8_t>& view() const { return mView; }
 
     std::unique_ptr<Item> clone() const override { return std::make_unique<ViewBstr>(mView); }
 
   private:
     void encodeValue(EncodeCallback encodeCallback) const;
 
-    std::basic_string_view<uint8_t> mView;
+    std::span<const uint8_t> mView;
 };
 
 /**
diff --git a/rules.mk b/rules.mk
index c5a19d8..2fbbbd9 100644
--- a/rules.mk
+++ b/rules.mk
@@ -18,8 +18,6 @@
 
 MODULE := $(LOCAL_DIR)
 
-MODULE_CPPFLAGS := -std=c++17
-
 MODULE_SRCS := \
 	$(LOCAL_DIR)/src/cppbor.cpp \
 	$(LOCAL_DIR)/src/cppbor_parse.cpp
diff --git a/tests/cppbor_test.cpp b/tests/cppbor_test.cpp
index 68778dc..a193cea 100644
--- a/tests/cppbor_test.cpp
+++ b/tests/cppbor_test.cpp
@@ -942,8 +942,8 @@
 
 TEST(ConvertTest, ViewBstr) {
     array<uint8_t, 3> vec{0x23, 0x24, 0x22};
-    basic_string_view<uint8_t> sv(vec.data(), vec.size());
-    unique_ptr<Item> item = details::makeItem(ViewBstr(sv));
+    span<const uint8_t> view(vec.data(), vec.size());
+    unique_ptr<Item> item = details::makeItem(ViewBstr(view));
 
     EXPECT_EQ(BSTR, item->type());
     EXPECT_EQ(nullptr, item->asInt());
@@ -957,7 +957,10 @@
     EXPECT_EQ(nullptr, item->asViewTstr());
     EXPECT_NE(nullptr, item->asViewBstr());
 
-    EXPECT_EQ(sv, item->asViewBstr()->view());
+    auto toVec = [](span<const uint8_t> view) {
+      return std::vector<uint8_t>(view.begin(), view.end());
+    };
+    EXPECT_EQ(toVec(view), toVec(item->asViewBstr()->view()));
 }
 
 TEST(CloningTest, Uint) {
@@ -1079,7 +1082,7 @@
 
 TEST(CloningTest, ViewBstr) {
     array<uint8_t, 5> vec{1, 2, 3, 255, 0};
-    basic_string_view<uint8_t> sv(vec.data(), vec.size());
+    span<const uint8_t> sv(vec.data(), vec.size());
     ViewBstr item(sv);
     auto clone = item.clone();
     EXPECT_EQ(clone->type(), BSTR);