pw_fuzzer: Add domains for Pigweed types

This CL adds FuzzTest domains for the following Pigweed types:

* FlatMap, InlineDeque, InlineQueue, IntrusiveList and Vector from
  pw_containers
* Result from pw_result
* Status and StatusWithSize from pw_status
* InlineString from pw_string

Change-Id: I59f0c7d07ebd21eb4c3cb8b696968ba79648befa
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/148336
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
Commit-Queue: Aaron Green <aarongreen@google.com>
Reviewed-by: Taylor Cramer <cramertj@google.com>
diff --git a/pw_fuzzer/BUILD.gn b/pw_fuzzer/BUILD.gn
index 8062aba..7bf7607 100644
--- a/pw_fuzzer/BUILD.gn
+++ b/pw_fuzzer/BUILD.gn
@@ -65,6 +65,7 @@
 
 pw_test_group("tests") {
   group_deps = [
+    ":fuzztest_tests",
     "examples/fuzztest:tests",
     "examples/libfuzzer:tests",
   ]
@@ -109,6 +110,11 @@
   }
 }
 
+pw_test("fuzztest_tests") {
+  sources = [ "domain_test.cc" ]
+  deps = [ ":fuzztest" ]
+}
+
 # This target should only be when defining a fuzzing toolchain, e.g. to set
 # `pw_unit_test_GOOGLETEST_BACKEND = "$dir_pw_fuzzer:gtest"
 if (dir_pw_third_party_googletest != "") {
diff --git a/pw_fuzzer/domain_test.cc b/pw_fuzzer/domain_test.cc
new file mode 100644
index 0000000..342bf7d
--- /dev/null
+++ b/pw_fuzzer/domain_test.cc
@@ -0,0 +1,508 @@
+// Copyright 2023 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+#include <cctype>
+
+#include "gtest/gtest.h"
+#include "pw_fuzzer/fuzztest.h"
+#include "pw_result/result.h"
+
+// Most of the tests in this file only validate that the domains provided by
+// Pigweed build, both with and without FuzzTest. Each domain comprises one or
+// more FuzzTest domains, so the validation of the distribution of values
+// produced by domains is left to and assumed from FuzzTest's own domain tests.
+
+namespace pw::fuzzer {
+namespace {
+
+////////////////////////////////////////////////////////////////
+// Constants, macros, and types used by the domain tests below.
+
+constexpr size_t kSize = 8;
+constexpr char kMin = 4;
+constexpr char kMax = 16;
+
+/// Generates a target function and fuzz test for a specific type.
+///
+/// The generated test simply checks that the provided domain can produce values
+/// of the appropriate type. Generally, explicitly providing a target function
+/// is preferred for readability, but this macro can be useful for templated
+/// domains that are tested for many repetitive numerical types.
+///
+/// This macro should not be used directly. Instead, use
+/// `FUZZ_TEST_FOR_INTEGRAL`, `FUZZ_TEST_FOR_FLOATING_POINT`, or
+/// `FUZZ_TEST_FOR_ARITHMETIC`.
+#define FUZZ_TEST_FOR_TYPE(Suite, Target, Domain, Type, ...) \
+  void Target(Type t) { Take##Domain<Type>(t); }             \
+  FUZZ_TEST(Suite, Target).WithDomains(Domain<Type>(__VA_ARGS__))
+
+/// Generates target functions and fuzz tests for a integral types.
+#define FUZZ_TEST_FOR_INTEGRAL(Suite, Target, Domain, ...)                     \
+  FUZZ_TEST_FOR_TYPE(Suite, Target##_Char, Domain, char, __VA_ARGS__);         \
+  FUZZ_TEST_FOR_TYPE(                                                          \
+      Suite, Target##_UChar, Domain, unsigned char, __VA_ARGS__);              \
+  FUZZ_TEST_FOR_TYPE(Suite, Target##_Short, Domain, short, __VA_ARGS__);       \
+  FUZZ_TEST_FOR_TYPE(                                                          \
+      Suite, Target##_UShort, Domain, unsigned short, __VA_ARGS__);            \
+  FUZZ_TEST_FOR_TYPE(Suite, Target##_Int, Domain, int, __VA_ARGS__);           \
+  FUZZ_TEST_FOR_TYPE(Suite, Target##_UInt, Domain, unsigned int, __VA_ARGS__); \
+  FUZZ_TEST_FOR_TYPE(Suite, Target##_Long, Domain, long, __VA_ARGS__);         \
+  FUZZ_TEST_FOR_TYPE(Suite, Target##_ULong, Domain, unsigned long, __VA_ARGS__)
+
+/// Generates target functions and fuzz tests for a floating point types.
+#define FUZZ_TEST_FOR_FLOATING_POINT(Suite, Target, Domain, ...)         \
+  FUZZ_TEST_FOR_TYPE(Suite, Target##_Float, Domain, float, __VA_ARGS__); \
+  FUZZ_TEST_FOR_TYPE(Suite, Target##_Double, Domain, double, __VA_ARGS__)
+
+/// Generates target functions and fuzz tests for a all arithmetic types.
+#define FUZZ_TEST_FOR_ARITHMETIC(Suite, Target, Domain, ...)  \
+  FUZZ_TEST_FOR_INTEGRAL(Suite, Target, Domain, __VA_ARGS__); \
+  FUZZ_TEST_FOR_FLOATING_POINT(Suite, Target, Domain, __VA_ARGS__)
+
+// Test struct that can be produced by FuzzTest.
+struct StructForTesting {
+  int a;
+  long b;
+};
+
+// Test class that can be produced by FuzzTest.
+class ClassForTesting {
+ public:
+  ClassForTesting(unsigned char c, short d) : c_(c), d_(d) {}
+  unsigned char c() const { return c_; }
+  short d() const { return d_; }
+
+ private:
+  unsigned char c_;
+  short d_;
+};
+
+////////////////////////////////////////////////////////////////
+// Arbitrary domains forwarded or stubbed from FuzzTest
+
+template <typename T>
+void TakeArbitrary(T) {}
+
+void TakeArbitraryBool(bool b) { TakeArbitrary<bool>(b); }
+FUZZ_TEST(ArbitraryTest, TakeArbitraryBool).WithDomains(Arbitrary<bool>());
+
+FUZZ_TEST_FOR_ARITHMETIC(ArbitraryTest, TakeArbitrary, Arbitrary);
+
+void TakeArbitraryStruct(const StructForTesting& s) {
+  TakeArbitrary<StructForTesting>(s);
+}
+FUZZ_TEST(ArbitraryTest, TakeArbitraryStruct)
+    .WithDomains(Arbitrary<StructForTesting>());
+
+void TakeArbitraryTuple(const std::tuple<int, long>& t) {
+  TakeArbitrary<std::tuple<int, long>>(t);
+}
+FUZZ_TEST(ArbitraryTest, TakeArbitraryTuple)
+    .WithDomains(Arbitrary<std::tuple<int, long>>());
+
+void TakeArbitraryOptional(const std::optional<int>& o) {
+  TakeArbitrary<std::optional<int>>(o);
+}
+FUZZ_TEST(ArbitraryTest, TakeArbitraryOptional)
+    .WithDomains(Arbitrary<std::optional<int>>());
+
+////////////////////////////////////////////////////////////////
+// Numerical domains forwarded or stubbed from FuzzTest
+
+template <typename Arithmetic>
+void TakeInRange(Arithmetic x) {
+  EXPECT_GE(x, Arithmetic(kMin));
+  EXPECT_LE(x, Arithmetic(kMax));
+}
+FUZZ_TEST_FOR_ARITHMETIC(DomainTest, TakeInRange, InRange, kMin, kMax);
+
+template <typename Arithmetic>
+void TakeNonZero(Arithmetic x) {
+  EXPECT_NE(x, Arithmetic(0));
+}
+FUZZ_TEST_FOR_ARITHMETIC(DomainTest, TakeNonZero, NonZero);
+
+template <typename Arithmetic>
+void TakePositive(Arithmetic x) {
+  EXPECT_GT(x, Arithmetic(0));
+}
+FUZZ_TEST_FOR_ARITHMETIC(DomainTest, TakePositive, Positive);
+
+template <typename Arithmetic>
+void TakeNonNegative(Arithmetic x) {
+  EXPECT_GE(x, Arithmetic(0));
+}
+FUZZ_TEST_FOR_ARITHMETIC(DomainTest, TakeNonNegative, NonNegative);
+
+template <typename Arithmetic>
+void TakeNegative(Arithmetic x) {
+  EXPECT_LT(x, Arithmetic(0));
+}
+FUZZ_TEST_FOR_ARITHMETIC(DomainTest, TakeNegative, Positive);
+
+template <typename Arithmetic>
+void TakeNonPositive(Arithmetic x) {
+  EXPECT_LE(x, Arithmetic(0));
+}
+FUZZ_TEST_FOR_ARITHMETIC(DomainTest, TakeNonPositive, NonNegative);
+
+template <typename FloatingPoint>
+void TakeFinite(FloatingPoint f) {
+  EXPECT_TRUE(std::isfinite(f));
+}
+FUZZ_TEST_FOR_FLOATING_POINT(DomainTest, TakeFinite, Finite);
+
+////////////////////////////////////////////////////////////////
+// Character domains forwarded or stubbed from FuzzTest
+
+void TakeNonZeroChar(char c) { EXPECT_NE(c, 0); }
+FUZZ_TEST(DomainTest, TakeNonZeroChar).WithDomains(NonZeroChar());
+
+void TakeNumericChar(char c) { EXPECT_TRUE(std::isdigit(c)); }
+FUZZ_TEST(DomainTest, TakeNumericChar).WithDomains(NumericChar());
+
+void TakeLowerChar(char c) { EXPECT_TRUE(std::islower(c)); }
+FUZZ_TEST(DomainTest, TakeLowerChar).WithDomains(LowerChar());
+
+void TakeUpperChar(char c) { EXPECT_TRUE(std::isupper(c)); }
+FUZZ_TEST(DomainTest, TakeUpperChar).WithDomains(UpperChar());
+
+void TakeAlphaChar(char c) { EXPECT_TRUE(std::isalpha(c)); }
+FUZZ_TEST(DomainTest, TakeAlphaChar).WithDomains(AlphaChar());
+
+void TakeAlphaNumericChar(char c) { EXPECT_TRUE(std::isalnum(c)); }
+FUZZ_TEST(DomainTest, TakeAlphaNumericChar).WithDomains(AlphaNumericChar());
+
+void TakePrintableAsciiChar(char c) { EXPECT_TRUE(std::isprint(c)); }
+FUZZ_TEST(DomainTest, TakePrintableAsciiChar).WithDomains(PrintableAsciiChar());
+
+void TakeAsciiChar(char c) {
+  EXPECT_GE(c, 0);
+  EXPECT_LE(c, 127);
+}
+FUZZ_TEST(DomainTest, TakeAsciiChar).WithDomains(AsciiChar());
+
+////////////////////////////////////////////////////////////////
+// Regular expression domains forwarded or stubbed from FuzzTest
+
+// TODO: b/285775246 - Add support for `fuzztest::InRegexp`.
+// void TakeMatch(std::string_view sv) {
+//   ASSERT_EQ(sv.size(), 3U);
+//   EXPECT_EQ(sv[0], 'a');
+//   EXPECT_EQ(sv[2], 'c');
+// }
+// FUZZ_TEST(DomainTest, TakeMatch).WithDomains(InRegexp("a.c"));
+
+////////////////////////////////////////////////////////////////
+// Enumerated domains forwarded or stubbed from FuzzTest
+
+void TakeSingleDigitEvenNumber(int n) {
+  EXPECT_LT(n, 10);
+  EXPECT_EQ(n % 2, 0);
+}
+FUZZ_TEST(DomainTest, TakeSingleDigitEvenNumber)
+    .WithDomains(ElementOf({0, 2, 4, 6, 8}));
+
+enum Flags : uint8_t {
+  kFlag1 = 1 << 0,
+  kFlag2 = 1 << 1,
+  kFlag3 = 1 << 2,
+};
+void TakeFlagCombination(uint8_t flags) { EXPECT_FALSE(flags & Flags::kFlag2); }
+FUZZ_TEST(DomainTest, TakeFlagCombination)
+    .WithDomains(BitFlagCombinationOf({Flags::kFlag1, Flags::kFlag3}));
+
+////////////////////////////////////////////////////////////////
+// Aggregate domains forwarded or stubbed from FuzzTest
+
+void TakeStructForTesting(const StructForTesting& obj) {
+  EXPECT_NE(obj.a, 0);
+  EXPECT_LT(obj.b, 0);
+}
+FUZZ_TEST(DomainTest, TakeStructForTesting)
+    .WithDomains(StructOf<StructForTesting>(NonZero<int>(), Negative<long>()));
+
+void TakeClassForTesting(const ClassForTesting& obj) {
+  EXPECT_GE(obj.c(), kMin);
+  EXPECT_LE(obj.c(), kMax);
+  EXPECT_GE(obj.d(), 0);
+}
+FUZZ_TEST(DomainTest, TakeClassForTesting)
+    .WithDomains(ConstructorOf<ClassForTesting>(InRange<unsigned char>(kMin,
+                                                                       kMax),
+                                                NonNegative<short>()));
+
+void TakePair(const std::pair<char, float>& p) {
+  EXPECT_TRUE(std::islower(p.first));
+  EXPECT_TRUE(std::isfinite(p.second));
+}
+FUZZ_TEST(DomainTest, TakePair)
+    .WithDomains(PairOf(LowerChar(), Finite<float>()));
+
+void TakeTuple(std::tuple<short, int> a, long b) {
+  EXPECT_NE(std::get<short>(a), 0);
+  EXPECT_NE(std::get<int>(a), 0);
+  EXPECT_NE(b, 0);
+}
+FUZZ_TEST(DomainTest, TakeTuple)
+    .WithDomains(TupleOf(NonZero<short>(), NonZero<int>()), NonZero<long>());
+
+void TakeVariant(const std::variant<int, long>&) {}
+FUZZ_TEST(DomainTest, TakeVariant)
+    .WithDomains(VariantOf(Arbitrary<int>(), Arbitrary<long>()));
+
+void TakeOptional(const std::optional<int>&) {}
+FUZZ_TEST(DomainTest, TakeOptional).WithDomains(OptionalOf(Arbitrary<int>()));
+
+void TakeNullOpt(const std::optional<int>& option) { EXPECT_FALSE(option); }
+FUZZ_TEST(DomainTest, TakeNullOpt).WithDomains(NullOpt<int>());
+
+void TakeNonNull(const std::optional<int>& option) { EXPECT_TRUE(option); }
+FUZZ_TEST(DomainTest, TakeNonNull)
+    .WithDomains(NonNull(OptionalOf(Arbitrary<int>())));
+
+////////////////////////////////////////////////////////////////
+// Other miscellaneous domains forwarded or stubbed from FuzzTest
+
+void TakePositiveOrMinusOne(int n) {
+  if (n != -1) {
+    EXPECT_GT(n, 0);
+  }
+}
+FUZZ_TEST(DomainTest, TakePositiveOrMinusOne)
+    .WithDomains(OneOf(Just(-1), Positive<int>()));
+
+void TakePackedValue(uint32_t value) {
+  EXPECT_GE(value & 0xFFFF, 1000U);
+  EXPECT_LT(value >> 16, 2048U);
+}
+FUZZ_TEST(DomainTest, TakePackedValue)
+    .WithDomains(
+        Map([](uint16_t lower,
+               uint16_t upper) { return (uint32_t(upper) << 16) | lower; },
+            InRange<uint16_t>(1000U, std::numeric_limits<uint16_t>::max()),
+            InRange<uint16_t>(0U, 2047U)));
+
+void TakeOrdered(size_t x, size_t y) { EXPECT_LT(x, y); }
+void FlatMapAdapter(const std::pair<size_t, size_t>& p) {
+  TakeOrdered(p.first, p.second);
+}
+FUZZ_TEST(DomainTest, FlatMapAdapter)
+    .WithDomains(FlatMap(
+        [](size_t x) {
+          return PairOf(
+              Just(x),
+              InRange<size_t>(x + 1, std::numeric_limits<size_t>::max()));
+        },
+        InRange<size_t>(0, std::numeric_limits<size_t>::max() - 1)));
+
+void TakeEven(unsigned int n) { EXPECT_EQ(n % 2, 0U); }
+FUZZ_TEST(DomainTest, TakeEven)
+    .WithDomains(Filter([](unsigned int n) { return n % 2 == 0; },
+                        Arbitrary<unsigned int>()));
+
+////////////////////////////////////////////////////////////////
+// pw_status-related types
+
+void TakeStatus(const Status&) {}
+FUZZ_TEST(ArbitraryTest, TakeStatus).WithDomains(Arbitrary<Status>());
+
+void TakeStatusWithSize(const StatusWithSize&) {}
+FUZZ_TEST(ArbitraryTest, TakeStatusWithSize)
+    .WithDomains(Arbitrary<StatusWithSize>());
+
+void TakeNonOkStatus(const Status& status) { EXPECT_FALSE(status.ok()); }
+FUZZ_TEST(FilterTest, TakeNonOkStatus).WithDomains(NonOkStatus());
+
+////////////////////////////////////////////////////////////////
+// pw_result-related types
+
+void TakeResult(const Result<int>&) {}
+FUZZ_TEST(DomainTest, TakeResult).WithDomains(ResultOf(Arbitrary<int>()));
+FUZZ_TEST(ArbitraryTest, TakeResult).WithDomains(Arbitrary<Result<int>>());
+
+////////////////////////////////////////////////////////////////
+// pw_containers-related types
+
+void TakeVector(const Vector<int>& vector) {
+  EXPECT_EQ(vector.max_size(), kSize);
+}
+FUZZ_TEST(DomainTest, TakeVector)
+    .WithDomains(VectorOf<kSize>(Arbitrary<int>()));
+FUZZ_TEST(ArbitraryTest, TakeVector)
+    .WithDomains(Arbitrary<Vector<int, kSize>>());
+
+void TakeVectorAsContainer(const Vector<int>&) {}
+FUZZ_TEST(ContainerTest, TakeVectorAsContainer)
+    .WithDomains(ContainerOf<Vector<int, kSize>>(Arbitrary<int>()));
+
+void TakeVectorNonEmpty(const Vector<int>& vector) {
+  EXPECT_FALSE(vector.empty());
+}
+FUZZ_TEST(ContainerTest, TakeVectorNonEmpty)
+    .WithDomains(NonEmpty(ContainerOf<Vector<int, kSize>>(Arbitrary<int>())));
+
+void TakeVectorLessThan3(const Vector<int>& vector) {
+  EXPECT_LT(vector.size(), 3U);
+}
+FUZZ_TEST(ContainerTest, TakeVectorLessThan3)
+    .WithDomains(
+        ContainerOf<Vector<int, kSize>>(Arbitrary<int>()).WithMaxSize(2));
+
+void TakeVectorAtLeast3(const Vector<int>& vector) {
+  EXPECT_GE(vector.size(), 3U);
+}
+FUZZ_TEST(ContainerTest, TakeVectorAtLeast3)
+    .WithDomains(
+        ContainerOf<Vector<int, kSize>>(Arbitrary<int>()).WithMinSize(3));
+
+void TakeVectorExactly3(const Vector<int>& vector) {
+  EXPECT_EQ(vector.size(), 3U);
+}
+FUZZ_TEST(ContainerTest, TakeVectorExactly3)
+    .WithDomains(ContainerOf<Vector<int, kSize>>(Arbitrary<int>()).WithSize(3));
+
+void TakeVectorUnique(const Vector<int>& vector) {
+  for (auto i = vector.begin(); i != vector.end(); ++i) {
+    for (auto j = i + 1; j != vector.end(); ++j) {
+      EXPECT_NE(*i, *j);
+    }
+  }
+}
+FUZZ_TEST(ContainerTest, TakeVectorUnique)
+    .WithDomains(
+        UniqueElementsContainerOf<Vector<int, kSize>>(Arbitrary<int>()));
+FUZZ_TEST(DomainTest, TakeVectorUnique)
+    .WithDomains(UniqueElementsVectorOf<kSize>(Arbitrary<int>()));
+
+void TakeFlatMap(const containers::FlatMap<int, size_t, kSize>&) {}
+FUZZ_TEST(DomainTest, TakeFlatMap)
+    .WithDomains(FlatMapOf<kSize>(Arbitrary<int>(), Arbitrary<size_t>()));
+FUZZ_TEST(ArbitraryTest, TakeFlatMap)
+    .WithDomains(Arbitrary<containers::FlatMap<int, size_t, kSize>>());
+FUZZ_TEST(ContainerTest, TakeFlatMap)
+    .WithDomains(ContainerOf<containers::FlatMap<int, size_t, kSize>>(
+        FlatMapPairOf(Arbitrary<int>(), Arbitrary<size_t>())));
+FUZZ_TEST(MapToTest, TakeFlatMap)
+    .WithDomains(MapToFlatMap<kSize>(
+        UniqueElementsVectorOf<kSize>(Arbitrary<int>()).WithSize(kSize),
+        ArrayOf<kSize>(Arbitrary<size_t>())));
+
+void TakeDeque(const InlineDeque<int, kSize>& deque) {
+  EXPECT_EQ(deque.max_size(), kSize);
+}
+FUZZ_TEST(DomainTest, TakeDeque).WithDomains(DequeOf<kSize>(Arbitrary<int>()));
+FUZZ_TEST(ArbitraryTest, TakeDeque)
+    .WithDomains(Arbitrary<InlineDeque<int, kSize>>());
+
+void TakeBasicDeque(const BasicInlineDeque<int, unsigned short, kSize>& deque) {
+  EXPECT_EQ(deque.max_size(), kSize);
+}
+FUZZ_TEST(DomainTest, TakeBasicDeque)
+    .WithDomains(BasicDequeOf<unsigned short, kSize>(Arbitrary<int>()));
+FUZZ_TEST(ArbitraryTest, TakeBasicDeque)
+    .WithDomains(Arbitrary<BasicInlineDeque<int, unsigned short, kSize>>());
+
+void TakeQueue(const InlineQueue<int, kSize>& queue) {
+  EXPECT_EQ(queue.max_size(), kSize);
+}
+FUZZ_TEST(DomainTest, TakeQueue).WithDomains(QueueOf<kSize>(Arbitrary<int>()));
+FUZZ_TEST(ArbitraryTest, TakeQueue)
+    .WithDomains(Arbitrary<InlineQueue<int, kSize>>());
+
+void TakeBasicQueue(const BasicInlineQueue<int, unsigned short, kSize>& queue) {
+  EXPECT_EQ(queue.max_size(), kSize);
+}
+FUZZ_TEST(DomainTest, TakeBasicQueue)
+    .WithDomains(BasicQueueOf<unsigned short, kSize>(Arbitrary<int>()));
+FUZZ_TEST(ArbitraryTest, TakeBasicQueue)
+    .WithDomains(Arbitrary<BasicInlineQueue<int, unsigned short, kSize>>());
+
+// Test item that can be added to an intrusive list.
+class TestItem : public IntrusiveList<TestItem>::Item {
+ public:
+  constexpr explicit TestItem(long value) : value_(value) {}
+  long value() const { return value_; }
+
+ private:
+  long value_;
+};
+
+// IntrusiveLists cannot be generated directly, but ScopedLists can.
+void TakeIntrusiveList(const IntrusiveList<TestItem>& list) {
+  EXPECT_LE(list.size(), kSize);
+}
+void ScopedListAdapter(const ScopedList<TestItem, kSize>& scoped) {
+  TakeIntrusiveList(scoped.list());
+}
+FUZZ_TEST(DomainTest, ScopedListAdapter)
+    .WithDomains(ScopedListOf<TestItem, kSize>(Arbitrary<long>()));
+
+////////////////////////////////////////////////////////////////
+// pw_string-related types
+
+void TakeString(const InlineString<>& string) {
+  EXPECT_EQ(string.max_size(), kSize);
+}
+FUZZ_TEST(DomainTest, TakeString)
+    .WithDomains(StringOf<kSize>(Arbitrary<char>()));
+FUZZ_TEST(ArbitraryTest, TakeString)
+    .WithDomains(Arbitrary<InlineString<kSize>>());
+FUZZ_TEST(FilterTest, TakeString).WithDomains(String<kSize>());
+
+void TakeStringAsContainer(const InlineString<>&) {}
+FUZZ_TEST(ContainerTest, TakeStringAsContainer)
+    .WithDomains(ContainerOf<InlineString<kSize>>(Arbitrary<char>()));
+
+void TakeStringNonEmpty(const InlineString<>& string) {
+  EXPECT_FALSE(string.empty());
+}
+FUZZ_TEST(ContainerTest, TakeStringNonEmpty)
+    .WithDomains(NonEmpty(ContainerOf<InlineString<kSize>>(Arbitrary<char>())));
+
+void TakeStringLessThan3(const InlineString<>& string) {
+  EXPECT_LT(string.size(), 3U);
+}
+FUZZ_TEST(ContainerTest, TakeStringLessThan3)
+    .WithDomains(
+        ContainerOf<InlineString<kSize>>(Arbitrary<char>()).WithMaxSize(2));
+
+void TakeStringAtLeast3(const InlineString<>& string) {
+  EXPECT_GE(string.size(), 3U);
+}
+FUZZ_TEST(ContainerTest, TakeStringAtLeast3)
+    .WithDomains(
+        ContainerOf<InlineString<kSize>>(Arbitrary<char>()).WithMinSize(3));
+
+void TakeStringExactly3(const InlineString<>& string) {
+  EXPECT_EQ(string.size(), 3U);
+}
+FUZZ_TEST(ContainerTest, TakeStringExactly3)
+    .WithDomains(
+        ContainerOf<InlineString<kSize>>(Arbitrary<char>()).WithSize(3));
+
+void TakeAsciiString(const InlineString<>& string) {
+  EXPECT_TRUE(std::all_of(
+      string.begin(), string.end(), [](int c) { return c < 0x80; }));
+}
+FUZZ_TEST(FilterTest, TakeAsciiString).WithDomains(AsciiString<kSize>());
+
+void TakePrintableAsciiString(const InlineString<>& string) {
+  EXPECT_TRUE(std::all_of(string.begin(), string.end(), isprint));
+}
+FUZZ_TEST(FilterTest, TakePrintableAsciiString)
+    .WithDomains(PrintableAsciiString<kSize>());
+
+}  // namespace
+}  // namespace pw::fuzzer
diff --git a/pw_fuzzer/private_overrides/pw_fuzzer/internal/fuzztest.h b/pw_fuzzer/private_overrides/pw_fuzzer/internal/fuzztest.h
index b23c88e..61066d5 100644
--- a/pw_fuzzer/private_overrides/pw_fuzzer/internal/fuzztest.h
+++ b/pw_fuzzer/private_overrides/pw_fuzzer/internal/fuzztest.h
@@ -59,15 +59,13 @@
 
 /// Stub for a FuzzTest domain that produces values.
 ///
-/// @rst
 /// In FuzzTest, domains are used to provide values of specific types when
 /// fuzzing. However, FuzzTest is only optionally supported on host with Clang.
 /// For other build configurations, this struct provides a FuzzTest-compatible
 /// stub that can be used to perform limited type-checking at build time.
 ///
 /// Fuzzer authors must not invoke this type directly. Instead, use the factory
-/// methods for domains such as ``Arbitrary``, ``VectorOf``, ``Map``, etc.
-/// @endrst
+/// methods for domains such as `Arbitrary`, `VectorOf`, `Map`, etc.
 template <typename T>
 struct Domain {
   using value_type = T;
@@ -75,38 +73,44 @@
 
 /// Stub for a FuzzTest domain that produces containers of values.
 ///
-/// @rst
-/// This struct is an extension of ``Domain`` that add stubs for the methods
-/// that control container size.
-/// @endrst
+/// This struct is an extension of `Domain` that add stubs for the methods that
+/// control container size.
 template <typename T>
-struct AggregateDomain : public Domain<T> {
+struct ContainerDomain : public Domain<T> {
   template <typename U, typename = std::enable_if_t<std::is_integral_v<U>>>
-  Domain<T>& WithSize(U) {
+  ContainerDomain<T>& WithSize(U) {
     return *this;
   }
 
   template <typename U, typename = std::enable_if_t<std::is_integral_v<U>>>
-  Domain<T>& WithMinSize(U) {
+  ContainerDomain<T>& WithMinSize(U) {
     return *this;
   }
 
   template <typename U, typename = std::enable_if_t<std::is_integral_v<U>>>
-  Domain<T>& WithMaxSize(U) {
+  ContainerDomain<T>& WithMaxSize(U) {
     return *this;
   }
 };
 
+/// Stub for a FuzzTest domain that produces optional values.
+///
+/// This struct is an extension of `Domain` that add stubs for the methods that
+/// control nullability.
+template <typename T>
+struct OptionalDomain : public Domain<T> {
+  OptionalDomain<T>& SetAlwaysNull() { return *this; }
+  OptionalDomain<T>& SetWithoutNull() { return *this; }
+};
+
 /// Register a FuzzTest stub.
 ///
-/// @rst
 /// FuzzTest is only optionally supported on host with Clang. For other build
 /// configurations, this struct provides a FuzzTest-compatible stub of a test
 /// registration that only performs limited type-checking at build time.
 ///
 /// Fuzzer authors must not invoke this type directly. Instead, use the
-/// ``FUZZ_TEST`` and/or ``FUZZ_TEST_F`` macros.
-/// @endrst
+/// `FUZZ_TEST` and/or `FUZZ_TEST_F` macros.
 template <typename TargetFunction>
 struct TypeCheckFuzzTest {
   TypeCheckFuzzTest(TargetFunction) {}
@@ -139,41 +143,70 @@
 // lookup). Names should be used from the fuzztest:: namespace.
 namespace internal_no_adl {
 
+////////////////////////////////////////////////////////////////
+// Arbitrary domains
+// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#arbitrary-domains
+
 template <typename T>
 auto Arbitrary() {
   return internal::Domain<T>{};
 }
 
-template <typename T>
-auto ElementOf(std::initializer_list<T>) {
-  return internal::Domain<T>{};
-}
+////////////////////////////////////////////////////////////////
+// Other miscellaneous domains
+// These typically appear later in docs and tests. They are placed early in this
+// file to allow other domains to be defined using them.
 
-template <typename T>
-auto Just(T) {
-  return internal::Domain<T>{};
-}
-
+// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#oneof
 template <int&... ExplicitArgumentBarrier, typename T, typename... Domains>
 auto OneOf(internal::Domain<T>, Domains...) {
   return internal::Domain<T>{};
 }
 
+// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#oneof
+template <typename T>
+auto Just(T) {
+  return internal::Domain<T>{};
+}
+
+// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#map
+template <int&... ExplicitArgumentBarrier, typename Mapper, typename... Inner>
+auto Map(Mapper, Inner...) {
+  return internal::Domain<std::decay_t<
+      std::invoke_result_t<Mapper, typename Inner::value_type&...>>>{};
+}
+
+// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#flatmap
+template <typename FlatMapper, typename... Inner>
+using FlatMapOutputDomain = std::decay_t<
+    std::invoke_result_t<FlatMapper, typename Inner::value_type&...>>;
+template <int&... ExplicitArgumentBarrier,
+          typename FlatMapper,
+          typename... Inner>
+auto FlatMap(FlatMapper, Inner...) {
+  return internal::Domain<
+      typename FlatMapOutputDomain<FlatMapper, Inner...>::value_type>{};
+}
+
+// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#filter
 template <int&... ExplicitArgumentBarrier, typename T, typename Pred>
 auto Filter(Pred, internal::Domain<T>) {
   return internal::Domain<T>{};
 }
 
+////////////////////////////////////////////////////////////////
+// Numerical domains
+// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#numerical-domains
+
 template <typename T>
-auto InRange(T, T) {
-  return internal::Domain<T>{};
+auto InRange(T min, T max) {
+  return Filter([min, max](T t) { return min <= t && t <= max; },
+                Arbitrary<T>());
 }
 
 template <typename T>
-auto Finite() {
-  static_assert(std::is_floating_point_v<T>,
-                "Finite<T>() can only be used with floating point types!");
-  return Filter([](T f) { return std::isfinite(f); }, Arbitrary<T>());
+auto NonZero() {
+  return Filter([](T t) { return t != 0; }, Arbitrary<T>());
 }
 
 template <typename T>
@@ -213,12 +246,41 @@
 }
 
 template <typename T>
-auto NonZero() {
-  if constexpr (std::is_signed_v<T>) {
-    return OneOf(Negative<T>(), Positive<T>());
-  } else {
-    return Positive<T>();
-  }
+auto Finite() {
+  static_assert(std::is_floating_point_v<T>,
+                "Finite<T>() can only be used with floating point types!");
+  return Filter([](T f) { return std::isfinite(f); }, Arbitrary<T>());
+}
+
+////////////////////////////////////////////////////////////////
+// Character domains
+// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#character-domains
+
+inline auto NonZeroChar() { return Positive<char>(); }
+inline auto NumericChar() { return InRange<char>('0', '9'); }
+inline auto LowerChar() { return InRange<char>('a', 'z'); }
+inline auto UpperChar() { return InRange<char>('A', 'Z'); }
+inline auto AlphaChar() { return OneOf(LowerChar(), UpperChar()); }
+inline auto AlphaNumericChar() { return OneOf(AlphaChar(), NumericChar()); }
+inline auto AsciiChar() { return InRange<char>(0, 127); }
+inline auto PrintableAsciiChar() { return InRange<char>(32, 126); }
+
+////////////////////////////////////////////////////////////////
+// Regular expression domains
+
+// TODO: b/285775246 - Add support for `fuzztest::InRegexp`.
+// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#inregexp-domains
+// inline auto InRegexp(std::string_view) {
+//   return internal::Domain<std::string_view>{};
+// }
+
+////////////////////////////////////////////////////////////////
+// Enumerated domains
+// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#elementof-domains
+
+template <typename T>
+auto ElementOf(std::initializer_list<T>) {
+  return internal::Domain<T>{};
 }
 
 template <typename T>
@@ -226,32 +288,64 @@
   return internal::Domain<T>{};
 }
 
+////////////////////////////////////////////////////////////////
+// Container domains
+// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#container-combinators
+
 template <typename T, int&... ExplicitArgumentBarrier, typename U>
 auto ContainerOf(internal::Domain<U>) {
-  return internal::AggregateDomain<T>{};
+  return internal::ContainerDomain<T>{};
 }
 
 template <template <typename, typename...> class T,
           int&... ExplicitArgumentBarrier,
           typename U>
 auto ContainerOf(internal::Domain<U>) {
-  return internal::AggregateDomain<T<U>>{};
+  return internal::ContainerDomain<T<U>>{};
 }
 
-inline auto NonZeroChar() { return Positive<char>(); }
-inline auto AsciiChar() { return InRange<char>(0, 127); }
-inline auto PrintableAsciiChar() { return InRange<char>(32, 126); }
-inline auto NumericChar() { return InRange<char>('0', '9'); }
-inline auto LowerChar() { return InRange<char>('a', 'z'); }
-inline auto UpperChar() { return InRange<char>('A', 'Z'); }
-inline auto AlphaChar() { return OneOf(LowerChar(), UpperChar()); }
-inline auto AlphaNumericChar() { return OneOf(AlphaChar(), NumericChar()); }
+template <typename T, int&... ExplicitArgumentBarrier, typename U>
+auto UniqueElementsContainerOf(internal::Domain<U>) {
+  return internal::ContainerDomain<T>{};
+}
+
+template <int&... ExplicitArgumentBarrier, typename T>
+auto NonEmpty(internal::ContainerDomain<T> inner) {
+  return inner.WithMinSize(1);
+}
+
+////////////////////////////////////////////////////////////////
+// Aggregate domains
+// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#container-combinators
+
+template <int&... ExplicitArgumentBarrier, typename T, typename... Domains>
+auto ArrayOf(internal::Domain<T>, Domains... others) {
+  return internal::Domain<std::array<T, 1 + sizeof...(others)>>{};
+}
+
+template <int N, int&... ExplicitArgumentBarrier, typename T>
+auto ArrayOf(const internal::Domain<T>&) {
+  return internal::Domain<std::array<T, N>>{};
+}
 
 template <typename T, int&... ExplicitArgumentBarrier, typename... Inner>
 auto StructOf(Inner...) {
   return internal::Domain<T>{};
 }
 
+template <typename T, int&... ExplicitArgumentBarrier>
+auto ConstructorOf() {
+  return internal::Domain<T>{};
+}
+
+template <typename T,
+          int&... ExplicitArgumentBarrier,
+          typename U,
+          typename... Inner>
+auto ConstructorOf(internal::Domain<U>, Inner... inner) {
+  return ConstructorOf<T>(inner...);
+}
+
 template <int&... ExplicitArgumentBarrier, typename T1, typename T2>
 auto PairOf(internal::Domain<T1>, internal::Domain<T2>) {
   return internal::Domain<std::pair<T1, T2>>{};
@@ -276,7 +370,7 @@
           int&... ExplicitArgumentBarrier,
           typename T>
 auto OptionalOf(internal::Domain<T>) {
-  return internal::Domain<Optional<T>>{};
+  return internal::OptionalDomain<Optional<T>>{};
 }
 
 template <int&... ExplicitArgumentBarrier, typename T>
@@ -286,65 +380,14 @@
 
 template <typename T>
 auto NullOpt() {
-  return internal::Domain<std::optional<T>>{}.SetAlwaysNull();
+  return internal::OptionalDomain<std::optional<T>>{}.SetAlwaysNull();
 }
 
 template <int&... ExplicitArgumentBarrier, typename T>
-auto NonNull(internal::Domain<T> inner) {
+auto NonNull(internal::OptionalDomain<T> inner) {
   return inner.SetWithoutNull();
 }
 
-template <int&... ExplicitArgumentBarrier, typename Mapper, typename... Inner>
-auto Map(Mapper, Inner...) {
-  return internal::Domain<std::decay_t<
-      std::invoke_result_t<Mapper, const typename Inner::value_type&...>>>{};
-}
-
-template <typename FlatMapper, typename... Inner>
-using FlatMapOutputDomain = std::decay_t<
-    std::invoke_result_t<FlatMapper, const typename Inner::value_type&...>>;
-
-template <int&... ExplicitArgumentBarrier,
-          typename FlatMapper,
-          typename... Inner>
-auto FlatMap(FlatMapper, Inner...) {
-  return internal::Domain<
-      typename FlatMapOutputDomain<FlatMapper, Inner...>::value_type>{};
-}
-
-template <int&... ExplicitArgumentBarrier, typename T, typename... Domains>
-auto ArrayOf(internal::Domain<T>, Domains... others) {
-  return internal::Domain<std::array<T, 1 + sizeof...(others)>>{};
-}
-
-template <int N, int&... ExplicitArgumentBarrier, typename T>
-auto ArrayOf(const internal::Domain<T>&) {
-  return internal::Domain<std::array<T, N>>{};
-}
-
-template <typename T, int&... ExplicitArgumentBarrier, typename U>
-auto UniqueElementsContainerOf(internal::Domain<U>) {
-  return internal::AggregateDomain<T>{};
-}
-
-template <typename T, int&... ExplicitArgumentBarrier>
-auto ConstructorOf() {
-  return internal::Domain<T>{};
-}
-
-template <typename T,
-          int&... ExplicitArgumentBarrier,
-          typename U,
-          typename... Inner>
-auto ConstructorOf(internal::Domain<U>, Inner... inner) {
-  return ConstructorOf<T>(inner...);
-}
-
-template <int&... ExplicitArgumentBarrier, typename T>
-auto NonEmpty(internal::Domain<T> inner) {
-  return inner.WithMinSize(1);
-}
-
 }  // namespace internal_no_adl
 
 // Inject the names from internal_no_adl into fuzztest, without allowing for
diff --git a/pw_fuzzer/public/pw_fuzzer/fuzztest.h b/pw_fuzzer/public/pw_fuzzer/fuzztest.h
index 62c532b..f2eea67 100644
--- a/pw_fuzzer/public/pw_fuzzer/fuzztest.h
+++ b/pw_fuzzer/public/pw_fuzzer/fuzztest.h
@@ -21,30 +21,60 @@
 /// on permitted C++ standard library `headers`_, including `macros`_ and
 /// `domains`_.
 ///
+/// It also extends the interface to provide domains for common Pigweed types,
+/// such as those from the following modules:
+///
+/// * :ref:`module-pw_containers`
+/// * :ref:`module-pw_result`
+/// * :ref:`module-pw_status`
+/// * :ref:`module-pw_string`
 ///
 /// .. _domains:
-///     https://github.com/google/fuzztest/blob/main/doc/domains-reference.md
+///    https://github.com/google/fuzztest/blob/main/doc/domains-reference.md
 /// .. _headers: https://pigweed.dev/docs/style_guide.html#permitted-headers
 /// .. _macros:
-///     https://github.com/google/fuzztest/blob/main/doc/fuzz-test-macro.md
+///    https://github.com/google/fuzztest/blob/main/doc/fuzz-test-macro.md
 /// @endrst
 
+#include "pw_containers/flat_map.h"
+#include "pw_containers/inline_deque.h"
+#include "pw_containers/inline_queue.h"
+#include "pw_containers/intrusive_list.h"
+#include "pw_containers/vector.h"
 #include "pw_fuzzer/internal/fuzztest.h"
+#include "pw_result/result.h"
+#include "pw_status/status.h"
+#include "pw_status/status_with_size.h"
+#include "pw_string/string.h"
 
 namespace pw::fuzzer {
 
+////////////////////////////////////////////////////////////////
+// Arbitrary domains
+// Additional specializations are provided with the Pigweed domains.
+
+/// @struct ArbitraryImpl
+/// @fn Arbitrary
+///
 /// Produces values for fuzz target function parameters.
 ///
 /// This defines a new template rather than using the `fuzztest` one directly in
-/// order to facilitate specializations.
+/// order to facilitate specializations for Pigweed types.
 ///
 /// See
 /// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#arbitrary-domains
+template <typename T, typename = void>
+struct ArbitraryImpl {
+  auto operator()() { return fuzztest::Arbitrary<T>(); }
+};
 template <typename T>
 auto Arbitrary() {
-  return fuzztest::Arbitrary<T>();
+  return ArbitraryImpl<T>()();
 }
 
+////////////////////////////////////////////////////////////////
+// Numerical domains
+
 /// Produces values from a closed interval.
 ///
 /// See
@@ -87,6 +117,9 @@
 /// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#numerical-domains
 using fuzztest::Finite;
 
+////////////////////////////////////////////////////////////////
+// Character domains
+
 /// Produces any char except '\0'.
 ///
 /// See
@@ -135,6 +168,16 @@
 /// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#character-domains
 using fuzztest::AsciiChar;
 
+////////////////////////////////////////////////////////////////
+// Regular expression domains
+
+// TODO: b/285775246 - Add support for `fuzztest::InRegexp`.
+// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#inregexp-domains
+// using fuzztest::InRegexp;
+
+////////////////////////////////////////////////////////////////
+// Enumerated domains
+
 /// Produces values from an enumerated set.
 ///
 /// See
@@ -147,13 +190,43 @@
 /// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#bitflagcombinationof-domains
 using fuzztest::BitFlagCombinationOf;
 
+////////////////////////////////////////////////////////////////
+// Container domains
+
+/// @struct ContainerOfImpl
+/// @fn ContainerOf
+///
 /// Produces containers of elements provided by inner domains.
 ///
-/// The container type is given by a template parameter.
+/// This defines a new template rather than using the `fuzztest` one directly in
+/// order to specify the static container capacity as part of the container
+/// type.
 ///
 /// See
 /// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#container-combinators
-using fuzztest::ContainerOf;
+template <typename Container, typename = void>
+struct ContainerOfImpl {
+  template <int&... ExplicitArgumentBarrier, typename Inner>
+  auto operator()(Inner inner) {
+    return fuzztest::ContainerOf<Container>(std::move(inner))
+        .WithMaxSize(Container{}.max_size());
+  }
+};
+template <typename Container, int&... ExplicitArgumentBarrier, typename Inner>
+auto ContainerOf(Inner inner) {
+  return ContainerOfImpl<Container>()(std::move(inner));
+}
+
+namespace internal {
+
+template <typename T, typename = void>
+struct IsContainer : std::false_type {};
+
+template <typename T>
+struct IsContainer<T, std::void_t<decltype(T().begin(), T().end())>>
+    : std::true_type {};
+
+}  // namespace internal
 
 /// Produces containers of at least one element provided by inner domains.
 ///
@@ -163,13 +236,32 @@
 /// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#container-combinators
 using fuzztest::NonEmpty;
 
+/// @struct UniqueElementsContainerOfImpl
+/// @fn UniqueElementsContainerOf
+///
 /// Produces containers of unique elements provided by inner domains.
 ///
-/// The container type is given by a template parameter.
+/// This defines a new template rather than using the `fuzztest` one directly in
+/// order to specify the static container capacity as part of the container
+/// type.
 ///
 /// See
 /// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#container-combinators
-using fuzztest::UniqueElementsContainerOf;
+template <typename Container, typename = void>
+struct UniqueElementsContainerOfImpl {
+  template <int&... ExplicitArgumentBarrier, typename Inner>
+  auto operator()(Inner inner) {
+    return fuzztest::UniqueElementsContainerOf<Container>(std::move(inner))
+        .WithMaxSize(Container{}.max_size());
+  }
+};
+template <typename Container, int&... ExplicitArgumentBarrier, typename Inner>
+auto UniqueElementsContainerOf(Inner inner) {
+  return UniqueElementsContainerOfImpl<Container>()(std::move(inner));
+}
+
+////////////////////////////////////////////////////////////////
+// Aggregate domains
 
 /// Produces std::array<T>s of elements provided by inner domains.
 ///
@@ -177,6 +269,20 @@
 /// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#container-combinators
 using fuzztest::ArrayOf;
 
+/// Specializes @cpp_class{pw::fuzzer::ContainerOfImpl} for arrays, which do not
+/// need a maximum size applied.
+///
+/// @param[in]  inner   Domain the produces values of type `T`.
+///
+/// @retval     Domain that produces `std::array<T, kArraySize>`s.
+template <typename T, size_t N>
+struct ContainerOfImpl<std::array<T, N>> {
+  template <int&... ExplicitArgumentBarrier, typename Inner>
+  auto operator()(Inner inner) {
+    return fuzztest::ContainerOf<std::array<T, N>>(std::move(inner));
+  }
+};
+
 /// Produces user-defined structs.
 ///
 /// The struct type is given by a template parameter.
@@ -229,6 +335,9 @@
 /// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#optionalof
 using fuzztest::NonNull;
 
+////////////////////////////////////////////////////////////////
+// Other miscellaneous domains
+
 /// Produces values by choosing between provided inner domains.
 ///
 /// See
@@ -260,4 +369,646 @@
 /// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md#filter
 using fuzztest::Filter;
 
+////////////////////////////////////////////////////////////////
+// pw_status-related types
+
+/// Implementation of @cpp_func{pw::fuzzer::Arbitrary} for
+/// @cpp_class{pw::Status}.
+template <>
+struct ArbitraryImpl<Status> {
+  auto operator()() {
+    return ConstructorOf<Status>(
+        Map([](int code) { return static_cast<pw_Status>(code); },
+            InRange<int>(PW_STATUS_OK, PW_STATUS_LAST)));
+  }
+};
+
+/// Implementation of @cpp_func{pw::fuzzer::Arbitrary} for
+/// @cpp_class{pw::StatusWithSize}.
+template <>
+struct ArbitraryImpl<StatusWithSize> {
+  auto operator()() {
+    return ConstructorOf<StatusWithSize>(Arbitrary<Status>(),
+                                         Arbitrary<size_t>());
+  }
+};
+
+/// Like @cpp_func{pw::fuzzer::Arbitrary<Status>}, except that
+/// @cpp_func{pw::OkStatus} is filtered out.
+auto NonOkStatus() {
+  return ConstructorOf<pw::Status>(
+      Map([](int code) { return static_cast<pw_Status>(code); },
+          InRange<int>(PW_STATUS_CANCELLED, PW_STATUS_UNAUTHENTICATED)));
+}
+
+////////////////////////////////////////////////////////////////
+// pw_result-related types
+
+/// Returns a FuzzTest domain that produces @cpp_class{pw::Result}s.
+///
+/// The value produced may either be value produced by the given domain, or a
+/// @cpp_class{pw::Status} indicating an error.
+///
+/// Alternatively, you can use `Arbitrary<Result<T>>`.
+///
+/// @param[in] inner  Domain that produces values of type `T`.
+///
+/// @retval    Domain that produces `Result<T>`s.
+template <int&... ExplicitArgumentBarrier, typename Inner>
+auto ResultOf(Inner inner) {
+  return Map(
+      [](std::optional<typename Inner::value_type> value, Status status) {
+        if (value) {
+          return Result<typename Inner::value_type>(*value);
+        }
+        return Result<typename Inner::value_type>(status);
+      },
+      OptionalOf(std::move(inner)),
+      NonOkStatus());
+}
+
+/// Implementation of @cpp_func{pw::fuzzer::Arbitrary} for
+/// @cpp_class{pw::Result}.
+template <typename T>
+struct ArbitraryImpl<Result<T>> {
+  auto operator()() { return ResultOf(Arbitrary<T>()); }
+};
+
+////////////////////////////////////////////////////////////////
+// pw_containers-related types
+
+/// Returns a FuzzTest domain that produces @cpp_class{pw::Vector}s.
+///
+/// Use this in place of `fuzztest::VectorOf`. The vector's maximum size is set
+/// by the template parameter.
+///
+/// Alternatively, you can use `Arbitrary<Vector<T, kMaxSize>>`.
+///
+/// @param[in] inner  Domain that produces values of type `T`.
+///
+/// @retval    Domain that produces `Vector<T>`s.
+template <size_t kMaxSize, int&... ExplicitArgumentBarrier, typename Inner>
+auto VectorOf(Inner inner) {
+  return ContainerOf<Vector<typename Inner::value_type, kMaxSize>>(inner)
+      .WithMaxSize(kMaxSize);
+}
+
+/// Implementation of @cpp_func{pw::fuzzer::Arbitrary} for
+/// @cpp_class{pw::Vector}.
+template <typename T, size_t kMaxSize>
+struct ArbitraryImpl<Vector<T, kMaxSize>> {
+  auto operator()() { return VectorOf<kMaxSize>(Arbitrary<T>()); }
+};
+
+/// Like `fuzztest::UniqueElementsVectorOf`, but uses a @cpp_class{pw::Vector}
+/// in place of a `std::vector`.
+///
+/// @param[in]  inner   Domain the produces values for the vector.
+///
+/// @retval     Domain that produces `@cpp_class{pw::Vector}`s.
+template <size_t kMaxSize, int&... ExplicitArgumentBarrier, typename Inner>
+auto UniqueElementsVectorOf(Inner inner) {
+  return UniqueElementsContainerOf<
+      Vector<typename Inner::value_type, kMaxSize>>(std::move(inner));
+}
+
+/// Returns a FuzzTest domain that produces @cpp_class{pw::containers::Pair}s.
+///
+/// Use this in place of `fuzztest::PairOf` when working with
+/// @cpp_class{pw::containers::FlatMap}s.
+///
+/// Alternatively, you can use `Arbitrary<pw::containers::Pair<K, V>>`.
+///
+/// @param[in] keys     Domain that produces values of type `K`.
+/// @param[in] values   Domain that produces values of type `V`.
+///
+/// @retval    Domain that produces `containers::Pair<T>`s.
+template <int&... ExplicitArgumentBarrier,
+          typename KeyDomain,
+          typename ValueDomain>
+auto FlatMapPairOf(KeyDomain keys, ValueDomain values) {
+  return StructOf<containers::Pair<typename KeyDomain::value_type,
+                                   typename ValueDomain::value_type>>(
+      std::move(keys), std::move(values));
+}
+
+/// Implementation of @cpp_func{pw::fuzzer::Arbitrary} for
+/// @cpp_class{pw::containers::Pair}.
+template <typename K, typename V>
+struct ArbitraryImpl<containers::Pair<K, V>> {
+  auto operator()() { return FlatMapPairOf(Arbitrary<K>(), Arbitrary<V>()); }
+};
+
+/// Transforms a domain that produces containers of keys and values into a
+/// domain that produces @cpp_class{pw::containers::FlatMap}s
+///
+/// This method can be used to apply additional constraints to the set of keys
+/// and/or values overall, e.g. by requiring all keys to be unique.
+///
+/// @param[in] keys     Domain that produces containers of keys.
+/// @param[in] values   Domain that produces containers of values.
+///
+/// @retval    Domain that produces `containers::Pair<T>`s.
+template <size_t kArraySize,
+          int&... ExplicitArgumentBarrier,
+          typename KeyDomain,
+          typename ValueDomain>
+auto MapToFlatMap(KeyDomain keys, ValueDomain values) {
+  using ContainerK = typename KeyDomain::value_type;
+  using ContainerV = typename ValueDomain::value_type;
+  static_assert(internal::IsContainer<ContainerK>::value);
+  static_assert(internal::IsContainer<ContainerV>::value);
+  using K = typename ContainerK::value_type;
+  using V = typename ContainerV::value_type;
+  return Map(
+      [](const ContainerK& keys_c, const ContainerV& vals_c) {
+        auto key = keys_c.begin();
+        auto val = vals_c.begin();
+        std::array<containers::Pair<K, V>, kArraySize> pairs;
+        for (auto& item : pairs) {
+          PW_ASSERT(key != keys_c.end());
+          PW_ASSERT(val != vals_c.end());
+          item.first = *key++;
+          item.second = *val++;
+        }
+        return pairs;
+      },
+      std::move(keys),
+      std::move(values));
+}
+
+/// Returns a FuzzTest domain that produces
+/// @cpp_class{pw::containers::FlatMap}s.
+///
+/// Use this in place of `fuzztest::MapOf` and/or `fuzztest::UnorderedMapOf`.
+/// The map's size is set by the template parameter. The map is populated by
+/// pairs of values from the given `KeyDomain` and `ValueDomain`.
+///
+/// Alternatively, you can use `Arbitrary<FlatMap<K, V, kArraySize>>`.
+///
+/// Note that neither approach returns a domain that produces `FlatMap<K< V>`s.
+/// Such a domain is infeasible, since `FlatMap<K, V>`s are not movable or
+/// copyable. Instead, these functions return domains that produce arrays of
+/// `Pair<K, V>`s that can be implicitly converted to `FlatMap<K, V>`s.
+///
+/// @param[in] keys    Domain that produces map keys.
+/// @param[in] values  Domain that produces map values.
+///
+/// @retval    Domain that produces `std::array<T, kArraySize>`s.
+template <size_t kArraySize,
+          int&... ExplicitArgumentBarrier,
+          typename KeyDomain,
+          typename ValueDomain>
+auto FlatMapOf(KeyDomain keys, ValueDomain values) {
+  return ArrayOf<kArraySize>(FlatMapPairOf(std::move(keys), std::move(values)));
+}
+
+/// Implementation of @cpp_func{pw::fuzzer::Arbitrary} for
+/// @cpp_class{pw::containers::FlatMap}.
+template <typename K, typename V, size_t kArraySize>
+struct ArbitraryImpl<containers::FlatMap<K, V, kArraySize>> {
+  auto operator()() {
+    return FlatMapOf<kArraySize>(Arbitrary<K>(), Arbitrary<V>());
+  }
+};
+
+/// Implementation of @cpp_func{pw::fuzzer::ContainerOf} for
+/// @cpp_class{pw::containers::FlatMap}.
+///
+/// Since flat maps have a static capacity, the returned domains do not produce
+/// FuzzTest containers, but aggregates. As a result, container methods such as
+/// `WithMaxSize` cannot be applied. Use @cpp_func{pw::fuzzer::MapToFlatMap}
+/// instead to apply constraints to the set of keys and values.
+///
+/// @param[in]  inner   Domain the produces @cpp_class{pw::containers::Pair}s.
+///
+/// @retval     Domain that produces `@cpp_class{pw::containers::FlatMap}`s.
+template <typename K, typename V, size_t kArraySize>
+struct ContainerOfImpl<containers::FlatMap<K, V, kArraySize>> {
+  template <int&... ExplicitArgumentBarrier, typename Inner>
+  auto operator()(Inner inner) {
+    static_assert(
+        std::is_same_v<typename Inner::value_type, containers::Pair<K, V>>,
+        "The domain passed to `pw::fuzzer::ContainerOf<FlatMap<K, V>>` must "
+        "produce `pw::containers::Pair<K, V>`s. An example of a valid domain is"
+        "`pw::fuzzer::FlatMapPairOf(FooDomain<K>(), BarDomain<V>())`");
+    return ArrayOf<kArraySize>(std::move(inner));
+  }
+};
+
+/// Transforms a domain that produces containers into a domain that produces
+/// @cpp_class{pw::BasicInlineDeque}s.
+///
+/// The domains returned by @cpp_func{pw::fuzzer::BasicDequeOf} and
+/// `Arbitrary<BasicInlineDeque>` do not create FuzzTest containers. This method
+/// can be used to apply container methods such as `WithMinSize` or
+/// `UniqueElementsContainerOf` before building a deque from that container.
+///
+/// @param[in] inner  Domain that produces containers.
+///
+/// @retval    Domain that produces `@cpp_class{pw::BasicInlineDeque}`s.
+template <typename SizeType,
+          size_t kCapacity,
+          int&... ExplicitArgumentBarrier,
+          typename Inner>
+auto MapToBasicDeque(Inner inner) {
+  using Container = typename Inner::value_type;
+  static_assert(internal::IsContainer<Container>::value);
+  using T = typename Container::value_type;
+  return Map(
+      [](const Container& items) {
+        return BasicInlineDeque<T, SizeType, kCapacity>(items.begin(),
+                                                        items.end());
+      },
+      std::move(inner));
+}
+
+/// Returns a FuzzTest domain that produces @cpp_class{pw::BasicInlineDeque}s.
+///
+/// Use this or @cpp_func{pw::fuzzer::DequeOf} in place of `fuzztest::DequeOf`.
+/// The deque's maximum size is set by the template parameter.
+///
+/// Alternatively, you can use `Arbitrary<BasicInlineDeque<T, kCapacity>>`.
+///
+/// @param[in] inner  Domain that produces values of type `T`.
+///
+/// @retval    Domain that produces values of type
+///            `BasicInlineDeque<T, SizeType, kCapacity>`.
+template <typename SizeType,
+          size_t kCapacity,
+          int&... ExplicitArgumentBarrier,
+          typename Inner>
+auto BasicDequeOf(Inner inner) {
+  return MapToBasicDeque<SizeType, kCapacity>(
+      VectorOf<kCapacity>(std::move(inner)));
+}
+
+// BasicDequeFrom(VectorOf<kCapacity>(Arbitrary<int>()))
+/// Implementation of @cpp_func{pw::fuzzer::Arbitrary} for
+/// @cpp_class{pw::BasicInlineDeque}.
+template <typename T, typename SizeType, size_t kCapacity>
+struct ArbitraryImpl<BasicInlineDeque<T, SizeType, kCapacity>> {
+  auto operator()() {
+    return BasicDequeOf<SizeType, kCapacity>(Arbitrary<T>());
+  }
+};
+
+/// Implementation of @cpp_func{pw::fuzzer::ContainerOf} for
+/// @cpp_class{pw::containers::BasicInlineDeque}.
+///
+/// Since inline deques have a static capacity, the returned domains do not
+/// produce FuzzTest containers, but aggregates. As a result, container methods
+/// such as `WithMaxSize` cannot be applied. Instead, use
+/// @cpp_func{pw::fuzzer::MapToDeque} or @cpp_func{pw::fuzzer::MapToBasicDeque}
+/// to apply constraints to the set of keys and values.
+///
+/// @param[in]  inner   Domain the produces values of type `T`.
+///
+/// @retval     Domain that produces `@cpp_class{pw::BasicInlineDeque}`s.
+template <typename T, typename SizeType, size_t kCapacity>
+struct ContainerOfImpl<BasicInlineDeque<T, SizeType, kCapacity>> {
+  template <int&... ExplicitArgumentBarrier, typename Inner>
+  auto operator()(Inner inner) {
+    return BasicDequeOf<SizeType, kCapacity>(std::move(inner));
+  }
+};
+
+/// Transforms a domain that produces containers into a domain that produces
+/// @cpp_class{pw::InlineDeque}s.
+///
+/// The domains returned by @cpp_func{pw::fuzzer::equeOf} and
+/// `Arbitrary<InlineDeque>` do not create FuzzTest containers. This method
+/// can be used to apply container methods such as `WithMinSize` or
+/// `UniqueElementsContainerOf` before building a deque from that container.
+///
+/// @param[in] inner  Domain that produces containers.
+///
+/// @retval    Domain that produces `@cpp_class{pw::InlineDeque}`s.
+template <size_t kCapacity, int&... ExplicitArgumentBarrier, typename Inner>
+auto MapToDeque(Inner inner) {
+  return MapToBasicDeque<uint16_t, kCapacity>(std::move(inner));
+}
+
+/// Returns a FuzzTest domain that produces @cpp_class{pw::InlineDeque}s.
+///
+/// Use this or @cpp_func{pw::fuzzer::BasicDequeOf} in place of
+/// `fuzztest::DequeOf`. The deque's maximum size is set by the template
+/// parameter.
+///
+/// Alternatively, you can use `Arbitrary<InlineDeque<T, kCapacity>>`.
+///
+/// @param[in] inner  Domain that produces values of type `T`.
+///
+/// @retval    Domain that produces values of type `InlineDeque<T, kCapacity>`.
+template <size_t kCapacity, int&... ExplicitArgumentBarrier, typename Inner>
+auto DequeOf(Inner inner) {
+  return BasicDequeOf<uint16_t, kCapacity>(std::move(inner));
+}
+
+/// Implementation of @cpp_func{pw::fuzzer::Arbitrary} for
+/// @cpp_class{pw::InlineDeque}.
+template <typename T, size_t kCapacity>
+struct ArbitraryImpl<InlineDeque<T, kCapacity>> {
+  auto operator()() { return DequeOf<kCapacity>(Arbitrary<T>()); }
+};
+
+/// Transforms a domain that produces containers into a domain that produces
+/// @cpp_class{pw::BasicInlineQueue}s.
+///
+/// The domains returned by @cpp_func{pw::fuzzer::BasicQueueOf} and
+/// `Arbitrary<BasicInlineQueue>` do not create FuzzTest containers. This method
+/// can be used to apply container methods such as `WithMinSize` or
+/// `UniqueElementsContainerOf` before building a queue from that container.
+///
+/// @param[in] inner  Domain that produces containers.
+///
+/// @retval    Domain that produces `@cpp_class{pw::BasicInlineQueue}`s.
+template <typename SizeType,
+          size_t kCapacity,
+          int&... ExplicitArgumentBarrier,
+          typename Inner>
+auto MapToBasicQueue(Inner inner) {
+  using Container = typename Inner::value_type;
+  static_assert(internal::IsContainer<Container>::value);
+  using T = typename Container::value_type;
+  return Map(
+      [](const Container& items) {
+        return BasicInlineQueue<T, SizeType, kCapacity>(items.begin(),
+                                                        items.end());
+      },
+      std::move(inner));
+}
+
+/// Returns a FuzzTest domain that produces @cpp_class{pw::BasicInlineQueue}s.
+///
+/// Use this, @cpp_func{pw::fuzzer::QueueOf}, or
+/// @cpp_func{pw::fuzzer::ScopedListOf} in place of `fuzztest::ListOf`. The
+/// queue's maximum size is set by the template parameter.
+///
+/// Alternatively, you can use `Arbitrary<BasicInlineQueue<T, kCapacity>>`.
+///
+/// @param[in] inner  Domain that produces values of type `T`.
+///
+/// @retval    Domain that produces values of type
+///            `BasicInlineQueue<T, SizeType, kCapacity>`.
+template <typename SizeType,
+          size_t kCapacity,
+          int&... ExplicitArgumentBarrier,
+          typename Inner>
+auto BasicQueueOf(Inner inner) {
+  return MapToBasicQueue<SizeType, kCapacity>(
+      VectorOf<kCapacity>(std::move(inner)));
+}
+
+/// Implementation of @cpp_func{pw::fuzzer::Arbitrary} for
+/// @cpp_class{pw::BasicInlineQueue}.
+template <typename T, typename SizeType, size_t kCapacity>
+struct ArbitraryImpl<BasicInlineQueue<T, SizeType, kCapacity>> {
+  auto operator()() {
+    return BasicQueueOf<SizeType, kCapacity>(Arbitrary<T>());
+  }
+};
+
+/// Implementation of @cpp_func{pw::fuzzer::ContainerOf} for
+/// @cpp_class{pw::containers::BasicInlineQueue}.
+///
+/// Since inline queues have a static capacity, the returned domains do not
+/// produce FuzzTest containers, but aggregates. As a result, container methods
+/// such as `WithMaxSize` cannot be applied. Instead, use
+/// @cpp_func{pw::fuzzer::MapToQueue} or @cpp_func{pw::fuzzer::MapToBasicQueue}
+/// to apply constraints to the set of keys and values.
+///
+/// @param[in]  inner   Domain the produces values of type `T`.
+///
+/// @retval     Domain that produces `@cpp_class{pw::BasicInlineQueue}`s.
+template <typename T, typename SizeType, size_t kCapacity>
+struct ContainerOfImpl<BasicInlineQueue<T, SizeType, kCapacity>> {
+  template <int&... ExplicitArgumentBarrier, typename Inner>
+  auto operator()(Inner inner) {
+    return BasicQueueOf<SizeType, kCapacity>(std::move(inner));
+  }
+};
+
+/// Transforms a domain that produces containers into a domain that produces
+/// @cpp_class{pw::InlineQueue}s.
+///
+/// The domains returned by @cpp_func{pw::fuzzer::QueueOf} and
+/// `Arbitrary<InlineQueue>` do not create FuzzTest containers. This method
+/// can be used to apply container methods such as `WithMinSize` or
+/// `UniqueElementsContainerOf` before building a queue from that container.
+///
+/// @param[in] inner  Domain that produces containers.
+///
+/// @retval    Domain that produces `@cpp_class{pw::InlineQueue}`s.
+template <size_t kCapacity, int&... ExplicitArgumentBarrier, typename Inner>
+auto MapToQueue(Inner inner) {
+  return MapToBasicQueue<uint16_t, kCapacity>(std::move(inner));
+}
+
+/// Returns a FuzzTest domain that produces @cpp_class{pw::InlineQueue}s.
+///
+/// Use this, @cpp_func{pw::fuzzer::BasicQueueOf}, or
+/// @cpp_func{pw::fuzzer::ScopedListOf} in place of `fuzztest::ListOf`. The
+/// queue's maximum size is set by the template parameter.
+///
+/// Alternatively, you can use `Arbitrary<InlineQueue<T, kCapacity>>`.
+///
+/// @param[in] inner  Domain that produces values of type `T`.
+///
+/// @retval    Domain that produces values of type `InlineQueue<T, kCapacity>`.
+template <size_t kCapacity, int&... ExplicitArgumentBarrier, typename Inner>
+auto QueueOf(Inner inner) {
+  return BasicQueueOf<uint16_t, kCapacity>(std::move(inner));
+}
+
+/// Implementation of @cpp_func{pw::fuzzer::Arbitrary} for
+/// @cpp_class{pw::InlineQueue}.
+template <typename T, size_t kCapacity>
+struct ArbitraryImpl<InlineQueue<T, kCapacity>> {
+  auto operator()() { return QueueOf<kCapacity>(Arbitrary<T>()); }
+};
+
+// Supporting types and functions for creating `IntrusiveList<T>`s.
+namespace internal {
+
+/// Construct an `Item` and emplace it in the given `Vector`.
+///
+/// The `Item` is constructed using arguments passed as a tuple.
+/// This should only be called by the overload that generates the index sequence
+/// used to expand the tuple.
+///
+/// @param[out] vector The vector to add the item to.
+/// @param[in]  args   A tuple of arguments to pass to the constructor of `T`.
+/// @param[in]  (n/a)  An sequence used to index the tuple.
+template <int&... ExplicitArgumentBarrier,
+          typename T,
+          typename Args,
+          size_t... Index>
+void EmplaceItem(Vector<T>& vector,
+                 const Args& args,
+                 std::index_sequence<Index...>) {
+  vector.emplace_back(std::get<Index>(args)...);
+}
+
+/// Construct an `Item` and emplace it in the given `Vector`.
+///
+/// The `Item` is constructed using arguments passed as a tuple.
+///
+/// @param[out] vector The vector to add the item to.
+/// @param[in]  args   A tuple of arguments to pass to the constructor of `T`.
+template <int&... ExplicitArgumentBarrier, typename T, typename Args>
+void EmplaceItem(Vector<T>& vector, const Args& args) {
+  EmplaceItem(
+      vector,
+      args,
+      std::make_index_sequence<std::tuple_size<std::decay_t<Args>>::value>{});
+}
+
+}  // namespace internal
+
+/// Associates an `IntrusiveList<T>` with a `Vector<T>` that stores its `Item`s.
+///
+/// The `Item`s are constructed from a sequence of argument tuples passed to
+// constructor.
+template <typename T, size_t kMaxSize>
+class ScopedList {
+ public:
+  ~ScopedList() { list_.clear(); }
+
+  template <int&... ExplicitArgumentBarrier, typename Tuple>
+  explicit ScopedList(const Vector<Tuple>& arg_tuples) {
+    for (const auto& arg_tuple : arg_tuples) {
+      items_.emplace_back(std::make_from_tuple<T>(arg_tuple));
+      // internal::EmplaceItem(items_, arg);
+      list_.push_back(items_.back());
+    }
+  }
+
+  ScopedList(const ScopedList& other) = delete;
+  ScopedList& operator=(const ScopedList& other) = delete;
+
+  ScopedList(ScopedList&& other) { *this = std::move(other); }
+  ScopedList& operator=(ScopedList&& other) {
+    list_.clear();
+    other.list_.clear();
+    items_ = std::move(other.items_);
+    list_.assign(items_.begin(), items_.end());
+    return *this;
+  }
+
+  const IntrusiveList<T>& list() const { return list_; }
+
+ private:
+  IntrusiveList<T> list_;
+  Vector<T, kMaxSize> items_;
+};
+
+/// Transforms a domain that produces containers into a domain that produces
+/// @cpp_class{pw::fuzzer::ScopedList}s.
+///
+/// The domains returned by @cpp_func{pw::fuzzer::ScopedListOf} do not create
+/// FuzzTest containers. This method can be used to apply container methods such
+/// as `WithMinSize` or `UniqueElementsContainerOf` before building an intrusive
+/// list from that container.
+///
+/// @param[in] inner  Domain that produces containers.
+///
+/// @retval    Domain that produces `@cpp_class{pw::fuzzer::ScopedList}`s.
+template <typename T,
+          size_t kMaxSize,
+          int&... ExplicitArgumentBarrier,
+          typename Inner>
+auto MapToScopedList(Inner inner) {
+  using Container = typename Inner::value_type;
+  static_assert(internal::IsContainer<Container>::value);
+  using Tuple = typename Container::value_type;
+  static_assert(
+      std::is_same_v<T, decltype(std::make_from_tuple<T>(Tuple()))>,
+      "The domain passed to `pw::fuzzer::MapToScopedList<T, kMaxSize>>` must "
+      "produce `std::tuple`s of constructor arguments for `T`, e.g. using "
+      "`pw::fuzzer::TupleOf`.");
+  return ConstructorOf<ScopedList<T, kMaxSize>>(std::move(inner));
+}
+
+/// Returns a FuzzTest domain that produces @cpp_class{pw::fuzzer::ScopedList}s.
+///
+/// Use this, @cpp_func{pw::fuzzer::BasicQueueOf}, or
+/// @cpp_func{pw::fuzzer::QueueOf} in place of `fuzztest::ListOf`. The list's
+/// maximum size is set by the template parameter.
+///
+/// @param[in] inner...  Domains that produces `IntrusiveList<T>::Item`s.
+///
+/// @retval    Domain that produces `ScopedList<T, kMaxSize>`s.
+template <typename T,
+          size_t kMaxSize,
+          int&... ExplicitArgumentBarrier,
+          typename... Inner>
+auto ScopedListOf(Inner... inner) {
+  return MapToScopedList<T, kMaxSize>(
+      VectorOf<kMaxSize>(TupleOf(std::move(inner)...)));
+}
+
+////////////////////////////////////////////////////////////////
+// pw_string-related types
+
+/// Returns a FuzzTest domain that produces @cpp_class{pw::InlineBasicString}s.
+///
+/// Use this in place of `fuzztest::StringOf`. The characters of the string
+/// are drawn from the given domain. The string capacity is given by the
+/// template parameter.
+///
+/// Alternatively, you can use `Arbitrary<InlineString<kCapacity>>`.
+///
+/// @param[in] inner  Domain that produces values of a character type.
+///
+/// @retval    Domain that produces `InlineBasicString<kCapacity>`s.
+template <size_t kCapacity, int&... ExplicitArgumentBarrier, typename Inner>
+auto StringOf(Inner inner) {
+  return ContainerOf<InlineBasicString<typename Inner::value_type, kCapacity>>(
+             inner)
+      .WithMaxSize(kCapacity);
+}
+
+/// Implementation of @cpp_func{pw::fuzzer::Arbitrary} for
+/// @cpp_class{pw::InlineBasicString}.
+template <typename T, size_t kCapacity>
+struct ArbitraryImpl<InlineBasicString<T, kCapacity>> {
+  auto operator()() { return StringOf<kCapacity>(Arbitrary<T>()); }
+};
+
+/// Returns a FuzzTest domain that produces @cpp_class{pw::InlineString}s.
+///
+/// Use this in place of `fuzztest::String`. The string capacity is given by the
+/// template parameter.
+///
+/// @retval    Domain that produces `InlineString<kCapacity>`s.
+template <size_t kCapacity>
+auto String() {
+  return StringOf<kCapacity>(Arbitrary<char>());
+}
+
+/// Returns a FuzzTest domain that produces @cpp_class{pw::InlineString}s
+/// containing only ASCII characters.
+///
+/// Use this in place of `fuzztest::AsciiString`. The string capacity is given
+/// by the template parameter.
+///
+/// @retval    Domain that produces `InlineString<kCapacity>`s.
+template <size_t kCapacity>
+auto AsciiString() {
+  return StringOf<kCapacity>(AsciiChar());
+}
+
+/// Returns a FuzzTest domain that produces @cpp_class{pw::InlineString}s
+/// containing only printable ASCII characters.
+///
+/// Use this in place of `fuzztest::PrintableAsciiString`. The string capacity
+/// is given by the template parameter.
+///
+/// @retval    Domain that produces printable `InlineString<kCapacity>`s.
+template <size_t kCapacity>
+auto PrintableAsciiString() {
+  return StringOf<kCapacity>(PrintableAsciiChar());
+}
+
 }  // namespace pw::fuzzer
diff --git a/pw_fuzzer/public_overrides/fuzztest/fuzztest.h b/pw_fuzzer/public_overrides/fuzztest/fuzztest.h
index 3720e7a..a7ddc6e 100644
--- a/pw_fuzzer/public_overrides/fuzztest/fuzztest.h
+++ b/pw_fuzzer/public_overrides/fuzztest/fuzztest.h
@@ -67,17 +67,13 @@
 
 template <int&... ExplicitArgumentBarrier, typename T>
 inline auto StringOf(internal::Domain<T> inner) {
-  return ContainerOf<std::string>(inner);
+  return ContainerOf<std::string>(std::move(inner));
 }
 
 inline auto AsciiString() { return StringOf(AsciiChar()); }
 
 inline auto PrintableAsciiString() { return StringOf(PrintableAsciiChar()); }
 
-inline auto InRegexp(std::string_view) {
-  return internal::Domain<std::string>{};
-}
-
 template <template <typename> class Ptr,
           int&... ExplicitArgumentBarrier,
           typename T>
@@ -97,42 +93,44 @@
 
 template <int&... ExplicitArgumentBarrier, typename T>
 auto VectorOf(internal::Domain<T> inner) {
-  return ContainerOf<std::vector<T>>(inner);
+  return ContainerOf<std::vector<T>>(std::move(inner));
 }
 
 template <int&... ExplicitArgumentBarrier, typename T>
 auto DequeOf(internal::Domain<T> inner) {
-  return ContainerOf<std::deque<T>>(inner);
+  return ContainerOf<std::deque<T>>(std::move(inner));
 }
 
 template <int&... ExplicitArgumentBarrier, typename T>
 auto ListOf(internal::Domain<T> inner) {
-  return ContainerOf<std::list<T>>(inner);
+  return ContainerOf<std::list<T>>(std::move(inner));
 }
 
 template <int&... ExplicitArgumentBarrier, typename T>
 auto SetOf(internal::Domain<T> inner) {
-  return ContainerOf<std::set<T>>(inner);
+  return ContainerOf<std::set<T>>(std::move(inner));
 }
 
 template <int&... ExplicitArgumentBarrier, typename K, typename V>
 auto MapOf(internal::Domain<K> keys, internal::Domain<V> values) {
-  return ContainerOf<std::map<K, V>>(PairOf(keys, values));
+  return ContainerOf<std::map<K, V>>(
+      PairOf(std::move(keys), std::move(values)));
 }
 
 template <int&... ExplicitArgumentBarrier, typename T>
 auto UnorderedSetOf(internal::Domain<T> inner) {
-  return ContainerOf<std::unordered_set<T>>(inner);
+  return ContainerOf<std::unordered_set<T>>(std::move(inner));
 }
 
 template <int&... ExplicitArgumentBarrier, typename K, typename V>
 auto UnorderedMapOf(internal::Domain<K> keys, internal::Domain<V> values) {
-  return ContainerOf<std::unordered_map<K, V>>(PairOf(keys, values));
+  return ContainerOf<std::unordered_map<K, V>>(
+      PairOf(std::move(keys), std::move(values)));
 }
 
 template <typename T>
-auto UniqueElementsVectorOf(internal::Domain<T>) {
-  return internal::AggregateDomain<std::vector<T>>{};
+auto UniqueElementsVectorOf(internal::Domain<T> inner) {
+  return VectorOf(std::move(inner));
 }
 
 template <typename P,
diff --git a/pw_status/public/pw_status/status.h b/pw_status/public/pw_status/status.h
index 51be466..9f6c3e6 100644
--- a/pw_status/public/pw_status/status.h
+++ b/pw_status/public/pw_status/status.h
@@ -64,6 +64,9 @@
 // Returns a null-terminated string representation of the pw_Status.
 const char* pw_StatusString(pw_Status status);
 
+// Indicates the status code with the highest valid value.
+#define PW_STATUS_LAST PW_STATUS_UNAUTHENTICATED
+
 #ifdef __cplusplus
 
 }  // extern "C"
diff --git a/third_party/fuzztest/centipede/BUILD.gn b/third_party/fuzztest/centipede/BUILD.gn
index efddad8..3c5fa71 100644
--- a/third_party/fuzztest/centipede/BUILD.gn
+++ b/third_party/fuzztest/centipede/BUILD.gn
@@ -43,7 +43,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -70,7 +70,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -94,7 +94,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -122,7 +122,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -146,7 +146,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -171,7 +171,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -192,7 +192,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -231,7 +231,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -258,7 +258,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -299,7 +299,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -377,7 +377,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
     ":centipede_config1",
     ":centipede_config2",
   ]
@@ -435,7 +435,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
     ":centipede_config1",
     ":centipede_config2",
   ]
@@ -493,7 +493,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
     ":centipede_config1",
     ":centipede_config2",
   ]
@@ -551,7 +551,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
     ":centipede_config1",
     ":centipede_config2",
   ]
@@ -608,7 +608,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
     ":centipede_config1",
     ":centipede_config2",
   ]
@@ -634,7 +634,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -663,7 +663,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -694,7 +694,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -724,7 +724,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -754,7 +754,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -790,7 +790,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -822,7 +822,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -843,7 +843,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -874,7 +874,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -898,7 +898,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -928,7 +928,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -952,7 +952,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -978,7 +978,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -998,7 +998,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -1022,7 +1022,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -1047,7 +1047,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -1074,7 +1074,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -1094,7 +1094,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -1118,7 +1118,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -1141,7 +1141,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -1160,7 +1160,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -1180,7 +1180,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -1209,7 +1209,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -1236,7 +1236,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -1266,7 +1266,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
     ":centipede_config1",
   ]
   remove_configs = [
@@ -1287,7 +1287,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -1313,7 +1313,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -1344,7 +1344,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -1373,7 +1373,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
diff --git a/third_party/fuzztest/codelab/BUILD.gn b/third_party/fuzztest/codelab/BUILD.gn
index e3b8eb1..6f5fdc0 100644
--- a/third_party/fuzztest/codelab/BUILD.gn
+++ b/third_party/fuzztest/codelab/BUILD.gn
@@ -30,7 +30,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
diff --git a/third_party/fuzztest/configs/BUILD.gn b/third_party/fuzztest/configs/BUILD.gn
index d836df1..da09a52 100644
--- a/third_party/fuzztest/configs/BUILD.gn
+++ b/third_party/fuzztest/configs/BUILD.gn
@@ -17,12 +17,7 @@
   cflags = [
     "-Wno-sign-compare",
     "-Wno-unused-parameter",
+    "-Wno-missing-field-initializers",
   ]
   cflags_cc = [ "-Wno-extra-semi" ]
 }
-
-# This config should only be used to build the FuzzTest library itself.
-config("internal_disabled_warnings") {
-  cflags = [ "-Wno-missing-field-initializers" ]
-  configs = [ ":disabled_warnings" ]
-}
diff --git a/third_party/fuzztest/docs.rst b/third_party/fuzztest/docs.rst
index 92e3a2b..854175e 100644
--- a/third_party/fuzztest/docs.rst
+++ b/third_party/fuzztest/docs.rst
@@ -96,8 +96,10 @@
   python pw_build/py/pw_build/generate_3p_gn.py \
     -w third_party/fuzztest/src
 
+.. DO NOT EDIT BELOW THIS LINE. Generated section.
+
 Version
 =======
-The update script was last run for revision `3c77f97`_.
+The update script was last run for revision `3c77f971`_.
 
-.. _3c77f97: https://github.com/google/fuzztest/tree/3c77f97183a1270796d25db1a8956706a25af238
+.. _3c77f971: https://github.com/google/fuzztes/tree/3c77f97183a1270796d25db1a8956706a25af238
diff --git a/third_party/fuzztest/domain_tests/BUILD.gn b/third_party/fuzztest/domain_tests/BUILD.gn
index a0a34e8..5eecbd5 100644
--- a/third_party/fuzztest/domain_tests/BUILD.gn
+++ b/third_party/fuzztest/domain_tests/BUILD.gn
@@ -33,7 +33,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
diff --git a/third_party/fuzztest/fuzztest.bazelrc b/third_party/fuzztest/fuzztest.bazelrc
index 144b87a..e297041 100644
--- a/third_party/fuzztest/fuzztest.bazelrc
+++ b/third_party/fuzztest/fuzztest.bazelrc
@@ -44,4 +44,4 @@
 
 # We apply coverage tracking instrumentation to everything but the
 # FuzzTest framework itself (including GoogleTest and GoogleMock).
-build:fuzztest --per_file_copt=+//,-//fuzztest:,-googletest/.*,-googlemock/.*@-fsanitize-coverage=inline-8bit-counters,-fsanitize-coverage=trace-cmp
+build:fuzztest --per_file_copt=+//,-//fuzztest:,-googletest/.*,-googlemock/.*@-fsanitize-coverage=inline-8bit-counters,-fsanitize-coverage=trace-cmp
\ No newline at end of file
diff --git a/third_party/fuzztest/fuzztest/BUILD.gn b/third_party/fuzztest/fuzztest/BUILD.gn
index 8ceeb81..b5a8320 100644
--- a/third_party/fuzztest/fuzztest/BUILD.gn
+++ b/third_party/fuzztest/fuzztest/BUILD.gn
@@ -34,7 +34,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -57,7 +57,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -83,7 +83,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -112,7 +112,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -164,7 +164,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -209,7 +209,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -239,7 +239,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -266,7 +266,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -294,7 +294,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -319,7 +319,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -343,7 +343,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -368,7 +368,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -388,7 +388,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -412,7 +412,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -438,7 +438,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -466,7 +466,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -494,7 +494,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -535,7 +535,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -562,7 +562,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -589,7 +589,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -616,7 +616,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
@@ -642,7 +642,7 @@
   configs = [
     "../../abseil-cpp/configs:disabled_warnings",
     "../../re2/configs:disabled_warnings",
-    "../configs:internal_disabled_warnings",
+    "../configs:disabled_warnings",
   ]
   remove_configs = [
     "$dir_pw_fuzzer:instrumentation",
diff --git a/third_party/fuzztest/repo.json b/third_party/fuzztest/repo.json
index 3c9c3d7..3758126 100644
--- a/third_party/fuzztest/repo.json
+++ b/third_party/fuzztest/repo.json
@@ -10,7 +10,7 @@
         "$dir_pw_third_party/googletest:gtest": "$dir_pw_third_party/googletest"
     },
     "add": [
-        "$dir_pw_third_party/fuzztest/configs:internal_disabled_warnings",
+        "$dir_pw_third_party/fuzztest/configs:disabled_warnings",
         "$dir_pw_third_party/abseil-cpp/configs:disabled_warnings",
         "$dir_pw_third_party/re2/configs:disabled_warnings"
     ],