pw_varint: use std::byte instead of uint8_t

This change switches pw_varint to using spans of std::byte instead of
uint8_t for encoding and decoding. The pw_protobuf module, which uses
pw_varint, is also updated.

A ToString formatter for std::byte is also added to pw_string (required
to use std::byte in unit test EXPECT statements).

Change-Id: I198370eecdabde32a85987dda98aed84c85b9c91
diff --git a/pw_protobuf/codegen_test.cc b/pw_protobuf/codegen_test.cc
index a441f3a..cf98dce 100644
--- a/pw_protobuf/codegen_test.cc
+++ b/pw_protobuf/codegen_test.cc
@@ -32,7 +32,7 @@
 using namespace pw::protobuf::test;
 
 TEST(Codegen, Codegen) {
-  uint8_t encode_buffer[512];
+  std::byte encode_buffer[512];
   NestedEncoder<20, 20> encoder(encode_buffer);
 
   Pigweed::Encoder pigweed(&encoder);
@@ -163,7 +163,7 @@
   };
   // clang-format on
 
-  span<const uint8_t> proto;
+  span<const std::byte> proto;
   EXPECT_EQ(encoder.Encode(&proto), Status::OK);
   EXPECT_EQ(proto.size(), sizeof(expected_proto));
   EXPECT_EQ(std::memcmp(proto.data(), expected_proto, sizeof(expected_proto)),
@@ -171,7 +171,7 @@
 }
 
 TEST(CodegenRepeated, NonPackedScalar) {
-  uint8_t encode_buffer[32];
+  std::byte encode_buffer[32];
   NestedEncoder encoder(encode_buffer);
 
   RepeatedTest::Encoder repeated_test(&encoder);
@@ -182,7 +182,7 @@
   constexpr uint8_t expected_proto[] = {
       0x08, 0x00, 0x08, 0x10, 0x08, 0x20, 0x08, 0x30};
 
-  span<const uint8_t> proto;
+  span<const std::byte> proto;
   EXPECT_EQ(encoder.Encode(&proto), Status::OK);
   EXPECT_EQ(proto.size(), sizeof(expected_proto));
   EXPECT_EQ(std::memcmp(proto.data(), expected_proto, sizeof(expected_proto)),
@@ -190,7 +190,7 @@
 }
 
 TEST(CodegenRepeated, PackedScalar) {
-  uint8_t encode_buffer[32];
+  std::byte encode_buffer[32];
   NestedEncoder encoder(encode_buffer);
 
   RepeatedTest::Encoder repeated_test(&encoder);
@@ -198,7 +198,7 @@
   repeated_test.WriteUint32s(values);
 
   constexpr uint8_t expected_proto[] = {0x0a, 0x04, 0x00, 0x10, 0x20, 0x30};
-  span<const uint8_t> proto;
+  span<const std::byte> proto;
   EXPECT_EQ(encoder.Encode(&proto), Status::OK);
   EXPECT_EQ(proto.size(), sizeof(expected_proto));
   EXPECT_EQ(std::memcmp(proto.data(), expected_proto, sizeof(expected_proto)),
@@ -206,7 +206,7 @@
 }
 
 TEST(CodegenRepeated, NonScalar) {
-  uint8_t encode_buffer[32];
+  std::byte encode_buffer[32];
   NestedEncoder encoder(encode_buffer);
 
   RepeatedTest::Encoder repeated_test(&encoder);
@@ -218,7 +218,7 @@
   constexpr uint8_t expected_proto[] = {
       0x1a, 0x03, 't', 'h', 'e', 0x1a, 0x5, 'q',  'u', 'i', 'c', 'k',
       0x1a, 0x5,  'b', 'r', 'o', 'w',  'n', 0x1a, 0x3, 'f', 'o', 'x'};
-  span<const uint8_t> proto;
+  span<const std::byte> proto;
   EXPECT_EQ(encoder.Encode(&proto), Status::OK);
   EXPECT_EQ(proto.size(), sizeof(expected_proto));
   EXPECT_EQ(std::memcmp(proto.data(), expected_proto, sizeof(expected_proto)),
@@ -226,7 +226,7 @@
 }
 
 TEST(CodegenRepeated, Message) {
-  uint8_t encode_buffer[64];
+  std::byte encode_buffer[64];
   NestedEncoder<1, 3> encoder(encode_buffer);
 
   RepeatedTest::Encoder repeated_test(&encoder);
@@ -242,7 +242,7 @@
     0x01, 0x10, 0x02, 0x2a, 0x04, 0x08, 0x02, 0x10, 0x04};
   // clang-format on
 
-  span<const uint8_t> proto;
+  span<const std::byte> proto;
   EXPECT_EQ(encoder.Encode(&proto), Status::OK);
   EXPECT_EQ(proto.size(), sizeof(expected_proto));
   EXPECT_EQ(std::memcmp(proto.data(), expected_proto, sizeof(expected_proto)),
@@ -250,7 +250,7 @@
 }
 
 TEST(Codegen, Proto2) {
-  uint8_t encode_buffer[64];
+  std::byte encode_buffer[64];
   NestedEncoder<1, 3> encoder(encode_buffer);
 
   Foo::Encoder foo(&encoder);
@@ -266,7 +266,7 @@
   constexpr uint8_t expected_proto[] = {
       0x08, 0x03, 0x1a, 0x06, 0x0a, 0x04, 0xde, 0xad, 0xbe, 0xef};
 
-  span<const uint8_t> proto;
+  span<const std::byte> proto;
   EXPECT_EQ(encoder.Encode(&proto), Status::OK);
   EXPECT_EQ(proto.size(), sizeof(expected_proto));
   EXPECT_EQ(std::memcmp(proto.data(), expected_proto, sizeof(expected_proto)),
diff --git a/pw_protobuf/encoder.cc b/pw_protobuf/encoder.cc
index e58e8ca..05ce88a 100644
--- a/pw_protobuf/encoder.cc
+++ b/pw_protobuf/encoder.cc
@@ -17,7 +17,7 @@
 namespace pw::protobuf {
 
 Status Encoder::WriteUint64(uint32_t field_number, uint64_t value) {
-  uint8_t* original_cursor = cursor_;
+  std::byte* original_cursor = cursor_;
   WriteFieldKey(field_number, WireType::kVarint);
   Status status = WriteVarint(value);
   IncreaseParentSize(cursor_ - original_cursor);
@@ -72,7 +72,7 @@
   }
 
   // Write the key for the nested field.
-  uint8_t* original_cursor = cursor_;
+  std::byte* original_cursor = cursor_;
   if (Status status = WriteFieldKey(field_number, WireType::kDelimited);
       !status.ok()) {
     encode_status_ = status;
@@ -90,7 +90,7 @@
   IncreaseParentSize(cursor_ - original_cursor);
 
   union {
-    uint8_t* cursor;
+    std::byte* cursor;
     SizeType* size_cursor;
   };
 
@@ -123,9 +123,9 @@
   return Status::OK;
 }
 
-Status Encoder::Encode(span<const uint8_t>* out) {
+Status Encoder::Encode(span<const std::byte>* out) {
   if (!encode_status_.ok()) {
-    *out = span<const uint8_t>();
+    *out = span<const std::byte>();
     return encode_status_;
   }
 
@@ -136,7 +136,7 @@
   }
 
   union {
-    uint8_t* read_cursor;
+    std::byte* read_cursor;
     SizeType* size_cursor;
   };
 
@@ -144,12 +144,12 @@
   // shift all subsequent data downwards.
   unsigned int blob = 0;
   size_cursor = blob_locations_[blob];
-  uint8_t* write_cursor = read_cursor;
+  std::byte* write_cursor = read_cursor;
 
   while (read_cursor < cursor_) {
     SizeType nested_size = *size_cursor;
 
-    span<uint8_t> varint_buf(write_cursor, sizeof(*size_cursor));
+    span<std::byte> varint_buf(write_cursor, sizeof(*size_cursor));
     size_t varint_size =
         pw::varint::EncodeLittleEndianBase128(nested_size, varint_buf);
 
@@ -163,7 +163,7 @@
     if (blob == blob_count_ - 1) {
       to_copy = cursor_ - read_cursor;
     } else {
-      uint8_t* end = reinterpret_cast<uint8_t*>(blob_locations_[blob + 1]);
+      std::byte* end = reinterpret_cast<std::byte*>(blob_locations_[blob + 1]);
       to_copy = end - read_cursor;
     }
 
diff --git a/pw_protobuf/encoder_test.cc b/pw_protobuf/encoder_test.cc
index 4da077e..259fd09 100644
--- a/pw_protobuf/encoder_test.cc
+++ b/pw_protobuf/encoder_test.cc
@@ -82,7 +82,7 @@
   };
   // clang-format on
 
-  uint8_t encode_buffer[32];
+  std::byte encode_buffer[32];
   NestedEncoder encoder(encode_buffer);
 
   EXPECT_EQ(encoder.WriteUint32(kTestProtoMagicNumberField, 42), Status::OK);
@@ -93,14 +93,14 @@
   EXPECT_EQ(encoder.WriteString(kTestProtoErrorMessageField, "broken 💩"),
             Status::OK);
 
-  span<const uint8_t> encoded;
+  span<const std::byte> encoded;
   EXPECT_EQ(encoder.Encode(&encoded), Status::OK);
   EXPECT_EQ(encoded.size(), sizeof(encoded_proto));
   EXPECT_EQ(std::memcmp(encoded.data(), encoded_proto, encoded.size()), 0);
 }
 
 TEST(Encoder, EncodeInsufficientSpace) {
-  uint8_t encode_buffer[12];
+  std::byte encode_buffer[12];
   NestedEncoder encoder(encode_buffer);
 
   // 2 bytes.
@@ -115,13 +115,13 @@
   EXPECT_EQ(encoder.WriteFloat(kTestProtoRatioField, 1.618034),
             Status::RESOURCE_EXHAUSTED);
 
-  span<const uint8_t> encoded;
+  span<const std::byte> encoded;
   EXPECT_EQ(encoder.Encode(&encoded), Status::RESOURCE_EXHAUSTED);
   EXPECT_EQ(encoded.size(), 0u);
 }
 
 TEST(Encoder, EncodeInvalidArguments) {
-  uint8_t encode_buffer[12];
+  std::byte encode_buffer[12];
   NestedEncoder encoder(encode_buffer);
 
   EXPECT_EQ(encoder.WriteUint32(kTestProtoMagicNumberField, 42), Status::OK);
@@ -133,13 +133,13 @@
   encoder.Clear();
 
   EXPECT_EQ(encoder.WriteBool(19091, false), Status::INVALID_ARGUMENT);
-  span<const uint8_t> encoded;
+  span<const std::byte> encoded;
   EXPECT_EQ(encoder.Encode(&encoded), Status::INVALID_ARGUMENT);
   EXPECT_EQ(encoded.size(), 0u);
 }
 
 TEST(Encoder, Nested) {
-  uint8_t encode_buffer[128];
+  std::byte encode_buffer[128];
   NestedEncoder<5, 10> encoder(encode_buffer);
 
   // TestProto test_proto;
@@ -213,14 +213,14 @@
   };
   // clang-format on
 
-  span<const uint8_t> encoded;
+  span<const std::byte> encoded;
   EXPECT_EQ(encoder.Encode(&encoded), Status::OK);
   EXPECT_EQ(encoded.size(), sizeof(encoded_proto));
   EXPECT_EQ(std::memcmp(encoded.data(), encoded_proto, encoded.size()), 0);
 }
 
 TEST(Encoder, NestedDepthLimit) {
-  uint8_t encode_buffer[128];
+  std::byte encode_buffer[128];
   NestedEncoder<2, 10> encoder(encode_buffer);
 
   // One level of nesting.
@@ -237,7 +237,7 @@
 }
 
 TEST(Encoder, NestedBlobLimit) {
-  uint8_t encode_buffer[128];
+  std::byte encode_buffer[128];
   NestedEncoder<5, 3> encoder(encode_buffer);
 
   // Write first blob.
@@ -261,7 +261,7 @@
 }
 
 TEST(Encoder, RepeatedField) {
-  uint8_t encode_buffer[32];
+  std::byte encode_buffer[32];
   NestedEncoder encoder(encode_buffer);
 
   // repeated uint32 values = 1;
@@ -273,14 +273,14 @@
   constexpr uint8_t encoded_proto[] = {
       0x08, 0x00, 0x08, 0x32, 0x08, 0x64, 0x08, 0x96, 0x01, 0x08, 0xc8, 0x01};
 
-  span<const uint8_t> encoded;
+  span<const std::byte> encoded;
   EXPECT_EQ(encoder.Encode(&encoded), Status::OK);
   EXPECT_EQ(encoded.size(), sizeof(encoded_proto));
   EXPECT_EQ(std::memcmp(encoded.data(), encoded_proto, encoded.size()), 0);
 }
 
 TEST(Encoder, PackedVarint) {
-  uint8_t encode_buffer[32];
+  std::byte encode_buffer[32];
   NestedEncoder encoder(encode_buffer);
 
   // repeated uint32 values = 1;
@@ -291,26 +291,26 @@
       0x0a, 0x07, 0x00, 0x32, 0x64, 0x96, 0x01, 0xc8, 0x01};
   //  key   size  v[0]  v[1]  v[2]  v[3]        v[4]
 
-  span<const uint8_t> encoded;
+  span<const std::byte> encoded;
   EXPECT_EQ(encoder.Encode(&encoded), Status::OK);
   EXPECT_EQ(encoded.size(), sizeof(encoded_proto));
   EXPECT_EQ(std::memcmp(encoded.data(), encoded_proto, encoded.size()), 0);
 }
 
 TEST(Encoder, PackedVarintInsufficientSpace) {
-  uint8_t encode_buffer[8];
+  std::byte encode_buffer[8];
   NestedEncoder encoder(encode_buffer);
 
   constexpr uint32_t values[] = {0, 50, 100, 150, 200};
   encoder.WritePackedUint32(1, values);
 
-  span<const uint8_t> encoded;
+  span<const std::byte> encoded;
   EXPECT_EQ(encoder.Encode(&encoded), Status::RESOURCE_EXHAUSTED);
   EXPECT_EQ(encoded.size(), 0u);
 }
 
 TEST(Encoder, PackedFixed) {
-  uint8_t encode_buffer[32];
+  std::byte encode_buffer[32];
   NestedEncoder encoder(encode_buffer);
 
   // repeated fixed32 values = 1;
@@ -321,14 +321,14 @@
       0x0a, 0x14, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x64,
       0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00};
 
-  span<const uint8_t> encoded;
+  span<const std::byte> encoded;
   EXPECT_EQ(encoder.Encode(&encoded), Status::OK);
   EXPECT_EQ(encoded.size(), sizeof(encoded_proto));
   EXPECT_EQ(std::memcmp(encoded.data(), encoded_proto, encoded.size()), 0);
 }
 
 TEST(Encoder, PackedZigzag) {
-  uint8_t encode_buffer[32];
+  std::byte encode_buffer[32];
   NestedEncoder encoder(encode_buffer);
 
   // repeated sint32 values = 1;
@@ -338,7 +338,7 @@
   constexpr uint8_t encoded_proto[] = {
       0x0a, 0x09, 0xc7, 0x01, 0x31, 0x01, 0x00, 0x02, 0x32, 0xc8, 0x01};
 
-  span<const uint8_t> encoded;
+  span<const std::byte> encoded;
   EXPECT_EQ(encoder.Encode(&encoded), Status::OK);
   EXPECT_EQ(encoded.size(), sizeof(encoded_proto));
   EXPECT_EQ(std::memcmp(encoded.data(), encoded_proto, encoded.size()), 0);
diff --git a/pw_protobuf/public/pw_protobuf/encoder.h b/pw_protobuf/public/pw_protobuf/encoder.h
index 360b88f..ef4865e 100644
--- a/pw_protobuf/public/pw_protobuf/encoder.h
+++ b/pw_protobuf/public/pw_protobuf/encoder.h
@@ -13,6 +13,7 @@
 // the License.
 #pragma once
 
+#include <cstddef>
 #include <cstring>
 
 #include "pw_span/span.h"
@@ -29,7 +30,7 @@
   // message. This can be templated to minimize the overhead.
   using SizeType = size_t;
 
-  constexpr Encoder(span<uint8_t> buffer,
+  constexpr Encoder(span<std::byte> buffer,
                     span<SizeType*> locations,
                     span<SizeType*> stack)
       : buffer_(buffer),
@@ -128,7 +129,7 @@
 
   // Writes a proto fixed32 key-value pair.
   Status WriteFixed32(uint32_t field_number, uint32_t value) {
-    uint8_t* original_cursor = cursor_;
+    std::byte* original_cursor = cursor_;
     WriteFieldKey(field_number, WireType::kFixed32);
     Status status = WriteRawBytes(value);
     IncreaseParentSize(cursor_ - original_cursor);
@@ -143,7 +144,7 @@
 
   // Writes a proto fixed64 key-value pair.
   Status WriteFixed64(uint32_t field_number, uint64_t value) {
-    uint8_t* original_cursor = cursor_;
+    std::byte* original_cursor = cursor_;
     WriteFieldKey(field_number, WireType::kFixed64);
     Status status = WriteRawBytes(value);
     IncreaseParentSize(cursor_ - original_cursor);
@@ -182,7 +183,7 @@
   Status WriteFloat(uint32_t field_number, float value) {
     static_assert(sizeof(float) == sizeof(uint32_t),
                   "Float and uint32_t are not the same size");
-    uint8_t* original_cursor = cursor_;
+    std::byte* original_cursor = cursor_;
     WriteFieldKey(field_number, WireType::kFixed32);
     Status status = WriteRawBytes(value);
     IncreaseParentSize(cursor_ - original_cursor);
@@ -198,7 +199,7 @@
   Status WriteDouble(uint32_t field_number, double value) {
     static_assert(sizeof(double) == sizeof(uint64_t),
                   "Double and uint64_t are not the same size");
-    uint8_t* original_cursor = cursor_;
+    std::byte* original_cursor = cursor_;
     WriteFieldKey(field_number, WireType::kFixed64);
     Status status = WriteRawBytes(value);
     IncreaseParentSize(cursor_ - original_cursor);
@@ -212,7 +213,7 @@
 
   // Writes a proto bytes key-value pair.
   Status WriteBytes(uint32_t field_number, span<const std::byte> value) {
-    uint8_t* original_cursor = cursor_;
+    std::byte* original_cursor = cursor_;
     WriteFieldKey(field_number, WireType::kDelimited);
     WriteVarint(value.size_bytes());
     Status status = WriteRawBytes(value.data(), value.size_bytes());
@@ -252,7 +253,7 @@
 
   // Runs a final encoding pass over the intermediary data and returns the
   // encoded protobuf message.
-  Status Encode(span<const uint8_t>* out);
+  Status Encode(span<const std::byte>* out);
 
  private:
   enum class WireType : uint8_t {
@@ -303,7 +304,7 @@
       return status;
     }
 
-    uint8_t* original_cursor = cursor_;
+    std::byte* original_cursor = cursor_;
     for (T value : values) {
       if (zigzag) {
         WriteZigzagVarint(static_cast<std::make_signed_t<T>>(value));
@@ -334,8 +335,8 @@
   }
 
   // The buffer into which the proto is encoded.
-  span<uint8_t> buffer_;
-  uint8_t* cursor_;
+  span<std::byte> buffer_;
+  std::byte* cursor_;
 
   // List of pointers to sub-messages' delimiting size fields.
   span<SizeType*> blob_locations_;
@@ -353,7 +354,7 @@
 template <size_t kMaxNestedDepth = 1, size_t kMaxBlobs = 1>
 class NestedEncoder : public Encoder {
  public:
-  NestedEncoder(span<uint8_t> buffer) : Encoder(buffer, blobs_, stack_) {}
+  NestedEncoder(span<std::byte> buffer) : Encoder(buffer, blobs_, stack_) {}
 
   // Disallow copy/assign to avoid confusion about who owns the buffer.
   NestedEncoder(const NestedEncoder& other) = delete;
diff --git a/pw_string/public/pw_string/to_string.h b/pw_string/public/pw_string/to_string.h
index e91e77d..41ec052 100644
--- a/pw_string/public/pw_string/to_string.h
+++ b/pw_string/public/pw_string/to_string.h
@@ -90,4 +90,8 @@
   return string::CopyString(status.str(), buffer);
 }
 
+inline StatusWithSize ToString(std::byte byte, const span<char>& buffer) {
+  return string::IntToHexString(static_cast<uint64_t>(byte), buffer);
+}
+
 }  // namespace pw
diff --git a/pw_varint/public/pw_varint/varint.h b/pw_varint/public/pw_varint/varint.h
index 03a5177..dd4e34e 100644
--- a/pw_varint/public/pw_varint/varint.h
+++ b/pw_varint/public/pw_varint/varint.h
@@ -43,7 +43,8 @@
 }
 
 // Encodes a uint64_t with Little-Endian Base 128 (LEB128) encoding.
-size_t EncodeLittleEndianBase128(uint64_t integer, const span<uint8_t>& output);
+size_t EncodeLittleEndianBase128(uint64_t integer,
+                                 const span<std::byte>& output);
 
 // Encodes the provided integer using a variable-length encoding and returns the
 // number of bytes written.
@@ -56,7 +57,7 @@
 // Returns the number of bytes written or 0 if the result didn't fit in the
 // encoding buffer.
 template <typename T>
-size_t EncodeVarint(T integer, const span<uint8_t>& output) {
+size_t EncodeVarint(T integer, const span<std::byte>& output) {
   if constexpr (std::is_signed<T>()) {
     return EncodeLittleEndianBase128(ZigZagEncode(integer), output);
   } else {
@@ -84,7 +85,7 @@
 //     data = data.subspan(bytes)
 //   }
 //
-size_t DecodeVarint(const span<const uint8_t>& input, int64_t* value);
-size_t DecodeVarint(const span<const uint8_t>& input, uint64_t* value);
+size_t DecodeVarint(const span<const std::byte>& input, int64_t* value);
+size_t DecodeVarint(const span<const std::byte>& input, uint64_t* value);
 
 }  // namespace pw::varint
diff --git a/pw_varint/varint.cc b/pw_varint/varint.cc
index 28b8af0..1c9084c 100644
--- a/pw_varint/varint.cc
+++ b/pw_varint/varint.cc
@@ -26,7 +26,7 @@
 }  // namespace
 
 size_t EncodeLittleEndianBase128(uint64_t integer,
-                                 const span<uint8_t>& output) {
+                                 const span<std::byte>& output) {
   size_t written = 0;
   do {
     if (written >= output.size()) {
@@ -34,21 +34,21 @@
     }
 
     // Grab 7 bits; the eighth bit is set to 1 to indicate more data coming.
-    output[written++] = static_cast<uint8_t>(integer) | '\x80';
+    output[written++] = static_cast<std::byte>(integer) | std::byte{0x80};
     integer >>= 7;
   } while (integer != 0u);
 
-  output[written - 1] &= '\x7f';  // clear the top bit of the last byte
+  output[written - 1] &= std::byte{0x7f};  // clear the top bit of the last byte
   return written;
 }
 
-size_t DecodeVarint(const span<const uint8_t>& input, int64_t* value) {
+size_t DecodeVarint(const span<const std::byte>& input, int64_t* value) {
   const size_t bytes = DecodeVarint(input, reinterpret_cast<uint64_t*>(value));
   *value = ZigZagDecode64(*value);
   return bytes;
 }
 
-size_t DecodeVarint(const span<const uint8_t>& input, uint64_t* value) {
+size_t DecodeVarint(const span<const std::byte>& input, uint64_t* value) {
   uint64_t decoded_value = 0;
   uint_fast8_t count = 0;
 
@@ -61,11 +61,11 @@
     }
 
     // Add the bottom seven bits of the next byte to the result.
-    decoded_value |= static_cast<uint64_t>(input[count] & '\x7f')
+    decoded_value |= static_cast<uint64_t>(input[count] & std::byte{0x7f})
                      << (7 * count);
 
     // Stop decoding if the top bit is not set.
-    if ((input[count++] & '\x80') == 0) {
+    if ((input[count++] & std::byte{0x80}) == std::byte{0}) {
       break;
     }
   }
diff --git a/pw_varint/varint_test.cc b/pw_varint/varint_test.cc
index ca45dab..b3818ae 100644
--- a/pw_varint/varint_test.cc
+++ b/pw_varint/varint_test.cc
@@ -26,28 +26,38 @@
 
 class Varint : public ::testing::Test {
  protected:
-  Varint() : buffer_{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'} {}
-  uint8_t buffer_[10];
+  Varint()
+      : buffer_{std::byte{'a'},
+                std::byte{'b'},
+                std::byte{'c'},
+                std::byte{'d'},
+                std::byte{'e'},
+                std::byte{'f'},
+                std::byte{'g'},
+                std::byte{'h'},
+                std::byte{'i'},
+                std::byte{'j'}} {}
+  std::byte buffer_[10];
 };
 
 TEST_F(Varint, EncodeSizeUnsigned32_SmallSingleByte) {
   ASSERT_EQ(1u, EncodeVarint(UINT32_C(0), buffer_));
-  EXPECT_EQ(0u, buffer_[0]);
+  EXPECT_EQ(std::byte{0}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(UINT32_C(1), buffer_));
-  EXPECT_EQ(1u, buffer_[0]);
+  EXPECT_EQ(std::byte{1}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(UINT32_C(2), buffer_));
-  EXPECT_EQ(2u, buffer_[0]);
+  EXPECT_EQ(std::byte{2}, buffer_[0]);
 }
 
 TEST_F(Varint, EncodeSizeUnsigned32_LargeSingleByte) {
   ASSERT_EQ(1u, EncodeVarint(UINT32_C(63), buffer_));
-  EXPECT_EQ(63u, buffer_[0]);
+  EXPECT_EQ(std::byte{63}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(UINT32_C(64), buffer_));
-  EXPECT_EQ(64u, buffer_[0]);
+  EXPECT_EQ(std::byte{64}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(UINT32_C(126), buffer_));
-  EXPECT_EQ(126u, buffer_[0]);
+  EXPECT_EQ(std::byte{126}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(UINT32_C(127), buffer_));
-  EXPECT_EQ(127u, buffer_[0]);
+  EXPECT_EQ(std::byte{127}, buffer_[0]);
 }
 
 TEST_F(Varint, EncodeSizeUnsigned32_MultiByte) {
@@ -66,24 +76,24 @@
 
 TEST_F(Varint, EncodeSizeSigned32_SmallSingleByte) {
   ASSERT_EQ(1u, EncodeVarint(INT32_C(0), buffer_));
-  EXPECT_EQ(0u, buffer_[0]);
+  EXPECT_EQ(std::byte{0}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(INT32_C(-1), buffer_));
-  EXPECT_EQ(1u, buffer_[0]);
+  EXPECT_EQ(std::byte{1}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(INT32_C(1), buffer_));
-  EXPECT_EQ(2u, buffer_[0]);
+  EXPECT_EQ(std::byte{2}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(INT32_C(-2), buffer_));
-  EXPECT_EQ(3u, buffer_[0]);
+  EXPECT_EQ(std::byte{3}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(INT32_C(2), buffer_));
-  EXPECT_EQ(4u, buffer_[0]);
+  EXPECT_EQ(std::byte{4}, buffer_[0]);
 }
 
 TEST_F(Varint, EncodeSizeSigned32_LargeSingleByte) {
   ASSERT_EQ(1u, EncodeVarint(INT32_C(-63), buffer_));
-  EXPECT_EQ(125u, buffer_[0]);
+  EXPECT_EQ(std::byte{125}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(INT32_C(63), buffer_));
-  EXPECT_EQ(126u, buffer_[0]);
+  EXPECT_EQ(std::byte{126}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(INT32_C(-64), buffer_));
-  EXPECT_EQ(127u, buffer_[0]);
+  EXPECT_EQ(std::byte{127}, buffer_[0]);
 }
 
 TEST_F(Varint, EncodeSizeSigned32_MultiByte) {
@@ -103,22 +113,22 @@
 
 TEST_F(Varint, EncodeSizeUnsigned64_SmallSingleByte) {
   ASSERT_EQ(1u, EncodeVarint(UINT64_C(0), buffer_));
-  EXPECT_EQ(0u, buffer_[0]);
+  EXPECT_EQ(std::byte{0}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(UINT64_C(1), buffer_));
-  EXPECT_EQ(1u, buffer_[0]);
+  EXPECT_EQ(std::byte{1}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(UINT64_C(2), buffer_));
-  EXPECT_EQ(2u, buffer_[0]);
+  EXPECT_EQ(std::byte{2}, buffer_[0]);
 }
 
 TEST_F(Varint, EncodeSizeUnsigned64_LargeSingleByte) {
   ASSERT_EQ(1u, EncodeVarint(UINT64_C(63), buffer_));
-  EXPECT_EQ(63u, buffer_[0]);
+  EXPECT_EQ(std::byte{63}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(UINT64_C(64), buffer_));
-  EXPECT_EQ(64u, buffer_[0]);
+  EXPECT_EQ(std::byte{64}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(UINT64_C(126), buffer_));
-  EXPECT_EQ(126u, buffer_[0]);
+  EXPECT_EQ(std::byte{126}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(UINT64_C(127), buffer_));
-  EXPECT_EQ(127u, buffer_[0]);
+  EXPECT_EQ(std::byte{127}, buffer_[0]);
 }
 
 TEST_F(Varint, EncodeSizeUnsigned64_MultiByte) {
@@ -146,24 +156,24 @@
 
 TEST_F(Varint, EncodeSizeSigned64_SmallSingleByte) {
   ASSERT_EQ(1u, EncodeVarint(INT64_C(0), buffer_));
-  EXPECT_EQ(0u, buffer_[0]);
+  EXPECT_EQ(std::byte{0}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(INT64_C(-1), buffer_));
-  EXPECT_EQ(1u, buffer_[0]);
+  EXPECT_EQ(std::byte{1}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(INT64_C(1), buffer_));
-  EXPECT_EQ(2u, buffer_[0]);
+  EXPECT_EQ(std::byte{2}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(INT64_C(-2), buffer_));
-  EXPECT_EQ(3u, buffer_[0]);
+  EXPECT_EQ(std::byte{3}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(INT64_C(2), buffer_));
-  EXPECT_EQ(4u, buffer_[0]);
+  EXPECT_EQ(std::byte{4}, buffer_[0]);
 }
 
 TEST_F(Varint, EncodeSizeSigned64_LargeSingleByte) {
   ASSERT_EQ(1u, EncodeVarint(INT64_C(-63), buffer_));
-  EXPECT_EQ(125u, buffer_[0]);
+  EXPECT_EQ(std::byte{125}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(INT64_C(63), buffer_));
-  EXPECT_EQ(126u, buffer_[0]);
+  EXPECT_EQ(std::byte{126}, buffer_[0]);
   ASSERT_EQ(1u, EncodeVarint(INT64_C(-64), buffer_));
-  EXPECT_EQ(127u, buffer_[0]);
+  EXPECT_EQ(std::byte{127}, buffer_[0]);
 }
 
 TEST_F(Varint, EncodeSizeSigned64_MultiByte) {
@@ -244,7 +254,7 @@
   constexpr size_t kSizeBytes = kStringSize - 1;
   static_assert(kSizeBytes <= 10, "Varint arrays never need be larger than 10");
 
-  std::array<uint8_t, kSizeBytes> array;
+  std::array<std::byte, kSizeBytes> array;
   std::memcpy(array.data(), data, kSizeBytes);
   return array;
 }