diff --git a/test/fuzzing/chrono-duration.cc b/test/fuzzing/chrono-duration.cc
index e8e51934..71463a92 100644
--- a/test/fuzzing/chrono-duration.cc
+++ b/test/fuzzing/chrono-duration.cc
@@ -6,9 +6,9 @@
 
 #include "fuzzer-common.h"
 
-template <typename Item, typename Ratio>
-void invoke_inner(fmt::string_view format_str, Item item) {
-  auto value = std::chrono::duration<Item, Ratio>(item);
+template <typename Period, typename Rep>
+void invoke_inner(fmt::string_view format_str, Rep rep) {
+  auto value = std::chrono::duration<Rep, Period>(rep);
   try {
 #if FMT_FUZZ_FORMAT_TO_STRING
     std::string message = fmt::format(format_str, value);
@@ -20,71 +20,67 @@ void invoke_inner(fmt::string_view format_str, Item item) {
   }
 }
 
-// Item is the underlying type for duration (int, long, etc.)
-template <typename Item>
-void invoke_outer(const uint8_t* data, size_t size, int scaling) {
+// Rep is a duration's representation type.
+template <typename Rep>
+void invoke_outer(const uint8_t* data, size_t size, int period) {
   // Always use a fixed location of the data.
-  using fmt_fuzzer::nfixed;
+  static_assert(sizeof(Rep) <= fixed_size, "fixed size is too small");
+  if (size <= fixed_size + 1) return;
 
-  static_assert(sizeof(Item) <= nfixed, "fixed size is too small");
-  if (size <= nfixed + 1) return;
-
-  const Item item = fmt_fuzzer::assignFromBuf<Item>(data);
-
-  // Fast forward.
-  data += nfixed;
-  size -= nfixed;
+  const Rep rep = assign_from_buf<Rep>(data);
+  data += fixed_size;
+  size -= fixed_size;
 
   // data is already allocated separately in libFuzzer so reading past the end 
   // will most likely be detected anyway.
-  const auto format_str = fmt::string_view(fmt_fuzzer::as_chars(data), size);
+  const auto format_str = fmt::string_view(as_chars(data), size);
 
   // yocto, zepto, zetta and yotta are not handled.
-  switch (scaling) {
+  switch (period) {
   case 1:
-    invoke_inner<Item, std::atto>(format_str, item);
+    invoke_inner<std::atto>(format_str, rep);
     break;
   case 2:
-    invoke_inner<Item, std::femto>(format_str, item);
+    invoke_inner<std::femto>(format_str, rep);
     break;
   case 3:
-    invoke_inner<Item, std::pico>(format_str, item);
+    invoke_inner<std::pico>(format_str, rep);
     break;
   case 4:
-    invoke_inner<Item, std::nano>(format_str, item);
+    invoke_inner<std::nano>(format_str, rep);
     break;
   case 5:
-    invoke_inner<Item, std::micro>(format_str, item);
+    invoke_inner<std::micro>(format_str, rep);
     break;
   case 6:
-    invoke_inner<Item, std::milli>(format_str, item);
+    invoke_inner<std::milli>(format_str, rep);
     break;
   case 7:
-    invoke_inner<Item, std::centi>(format_str, item);
+    invoke_inner<std::centi>(format_str, rep);
     break;
   case 8:
-    invoke_inner<Item, std::deci>(format_str, item);
+    invoke_inner<std::deci>(format_str, rep);
     break;
   case 9:
-    invoke_inner<Item, std::deca>(format_str, item);
+    invoke_inner<std::deca>(format_str, rep);
     break;
   case 10:
-    invoke_inner<Item, std::kilo>(format_str, item);
+    invoke_inner<std::kilo>(format_str, rep);
     break;
   case 11:
-    invoke_inner<Item, std::mega>(format_str, item);
+    invoke_inner<std::mega>(format_str, rep);
     break;
   case 12:
-    invoke_inner<Item, std::giga>(format_str, item);
+    invoke_inner<std::giga>(format_str, rep);
     break;
   case 13:
-    invoke_inner<Item, std::tera>(format_str, item);
+    invoke_inner<std::tera>(format_str, rep);
     break;
   case 14:
-    invoke_inner<Item, std::peta>(format_str, item);
+    invoke_inner<std::peta>(format_str, rep);
     break;
   case 15:
-    invoke_inner<Item, std::exa>(format_str, item);
+    invoke_inner<std::exa>(format_str, rep);
   }
 }
 
@@ -92,46 +88,46 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   if (size <= 4)  return 0;
 
   const auto representation = data[0];
-  const auto scaling = data[1];
+  const auto period = data[1];
   data += 2;
   size -= 2;
 
   switch (representation) {
   case 1:
-    invoke_outer<char>(data, size, scaling);
+    invoke_outer<char>(data, size, period);
     break;
   case 2:
-    invoke_outer<signed char>(data, size, scaling);
+    invoke_outer<signed char>(data, size, period);
     break;
   case 3:
-    invoke_outer<unsigned char>(data, size, scaling);
+    invoke_outer<unsigned char>(data, size, period);
     break;
   case 4:
-    invoke_outer<short>(data, size, scaling);
+    invoke_outer<short>(data, size, period);
     break;
   case 5:
-    invoke_outer<unsigned short>(data, size, scaling);
+    invoke_outer<unsigned short>(data, size, period);
     break;
   case 6:
-    invoke_outer<int>(data, size, scaling);
+    invoke_outer<int>(data, size, period);
     break;
   case 7:
-    invoke_outer<unsigned int>(data, size, scaling);
+    invoke_outer<unsigned int>(data, size, period);
     break;
   case 8:
-    invoke_outer<long>(data, size, scaling);
+    invoke_outer<long>(data, size, period);
     break;
   case 9:
-    invoke_outer<unsigned long>(data, size, scaling);
+    invoke_outer<unsigned long>(data, size, period);
     break;
   case 10:
-    invoke_outer<float>(data, size, scaling);
+    invoke_outer<float>(data, size, period);
     break;
   case 11:
-    invoke_outer<double>(data, size, scaling);
+    invoke_outer<double>(data, size, period);
     break;
   case 12:
-    invoke_outer<long double>(data, size, scaling);
+    invoke_outer<long double>(data, size, period);
     break;
   default:
     break;
diff --git a/test/fuzzing/fuzzer-common.h b/test/fuzzing/fuzzer-common.h
index 6aef8d8f..635a5d99 100644
--- a/test/fuzzing/fuzzer-common.h
+++ b/test/fuzzing/fuzzer-common.h
@@ -6,6 +6,9 @@
 
 #include <cstdint>      // std::uint8_t
 #include <cstring>      // memcpy
+#include <vector>
+
+#include <fmt/core.h>
 
 // One can format to either a string, or a buffer. The latter is faster, but
 // one may be interested in formatting to a string instead to verify it works
@@ -18,13 +21,11 @@
 // the fuzzing.
 #define FMT_FUZZ_SEPARATE_ALLOCATION 1
 
-namespace fmt_fuzzer {
-
 // The size of the largest possible type in use.
 // To let the the fuzzer mutation be efficient at cross pollinating between
 // different types, use a fixed size format. The same bit pattern, interpreted
 // as another type, is likely interesting.
-constexpr auto nfixed = 16;
+constexpr auto fixed_size = 16;
 
 // Casts data to a char pointer.
 template <typename T> inline const char* as_chars(const T* data) {
@@ -38,17 +39,37 @@ template <typename T> inline const std::uint8_t* as_bytes(const T* data) {
 
 // Blits bytes from data to form an (assumed trivially constructible) object
 // of type Item.
-template <class Item> inline Item assignFromBuf(const std::uint8_t* data) {
+template <class Item> inline Item assign_from_buf(const std::uint8_t* data) {
   auto item = Item();
   std::memcpy(&item, data, sizeof(Item));
   return item;
 }
 
 // Reads a boolean value by looking at the first byte from data.
-template <> inline bool assignFromBuf<bool>(const std::uint8_t* data) {
+template <> inline bool assign_from_buf<bool>(const std::uint8_t* data) {
   return *data != 0;
 }
 
-}  // namespace fmt_fuzzer
+struct data_to_string {
+#if FMT_FUZZ_SEPARATE_ALLOCATION
+  std::vector<char> buffer;
+
+  data_to_string(const uint8_t* data, size_t size, bool add_terminator = false)
+      : buffer(size + (add_terminator ? 1 : 0)) {
+    std::memcpy(buffer.data(), data, size);
+  }
+
+  fmt::string_view get() const { return {buffer.data(), buffer.size()}; }
+#else
+  fmt::string_view sv;
+
+  data_to_string(const uint8_t* data, size_t size, bool = false)
+      : str(as_chars(data), size) {}
+
+  fmt::string_view get() const { return sv; }
+#endif
+
+  const char* data() const { return get().data(); }
+};
 
 #endif  // FUZZER_COMMON_H
diff --git a/test/fuzzing/main.cc b/test/fuzzing/main.cc
index 7fd7cc70..8f8c719b 100644
--- a/test/fuzzing/main.cc
+++ b/test/fuzzing/main.cc
@@ -17,6 +17,6 @@ int main(int argc, char** argv) {
     std::vector<char> buf(static_cast<size_t>(size));
     in.read(buf.data(), size);
     assert(in.gcount() == size);
-    LLVMFuzzerTestOneInput(fmt_fuzzer::as_bytes(buf.data()), buf.size());
+    LLVMFuzzerTestOneInput(as_bytes(buf.data()), buf.size());
   }
 }
diff --git a/test/fuzzing/named-arg.cc b/test/fuzzing/named-arg.cc
index 9db51555..26a9c26a 100644
--- a/test/fuzzing/named-arg.cc
+++ b/test/fuzzing/named-arg.cc
@@ -1,54 +1,40 @@
 // Copyright (c) 2019, Paul Dreik
 // For the license information refer to format.h.
 
+#include <fmt/chrono.h>
+
 #include <cstdint>
 #include <type_traits>
 #include <vector>
-#include <fmt/chrono.h>
 
 #include "fuzzer-common.h"
 
-template <typename Item1>
-void invoke_fmt(const uint8_t* data, size_t size, unsigned int argsize) {
-  static_assert(sizeof(Item1) <= fmt_fuzzer::nfixed, "nfixed too small");
-  if (size <= fmt_fuzzer::nfixed) return;
-  const Item1 item1 = fmt_fuzzer::assignFromBuf<Item1>(data);
+template <typename T>
+void invoke_fmt(const uint8_t* data, size_t size, unsigned arg_name_size) {
+  static_assert(sizeof(T) <= fixed_size, "fixed_size too small");
+  if (size <= fixed_size) return;
+  const T value = assign_from_buf<T>(data);
+  data += fixed_size;
+  size -= fixed_size;
 
-  data += fmt_fuzzer::nfixed;
-  size -= fmt_fuzzer::nfixed;
-
-  // How many chars should be used for the argument name?
-  if (argsize <= 0 || argsize >= size) return;
-
-#if FMT_FUZZ_SEPARATE_ALLOCATION
-  std::vector<char> argnamebuffer(argsize + 1);
-  std::memcpy(argnamebuffer.data(), data, argsize);
-  auto argname = argnamebuffer.data();
-#else
-  auto argname = fmt_fuzzer::as_chars(data);
-#endif
-  data += argsize;
-  size -= argsize;
-
-#if FMT_FUZZ_SEPARATE_ALLOCATION
-  std::vector<char> fmtstringbuffer(size);
-  std::memcpy(fmtstringbuffer.data(), data, size);
-  auto format_str = fmt::string_view(fmtstringbuffer.data(), size);
-#else
-  auto format_str = fmt::string_view(fmt_fuzzer::as_chars(data), size);
-#endif
+  if (arg_name_size <= 0 || arg_name_size >= size) return;
+  data_to_string arg_name(data, arg_name_size, true);
+  data += arg_name_size;
+  size -= arg_name_size;
 
+  data_to_string format_str(data, size);
 #if FMT_FUZZ_FORMAT_TO_STRING
-  std::string message = fmt::format(format_str, fmt::arg(argname, item1));
+  std::string message =
+    fmt::format(format_str.get(), fmt::arg(arg_name.data(), value));
 #else
   fmt::memory_buffer out;
-  fmt::format_to(out, format_str, fmt::arg(argname, item1));
+  fmt::format_to(out, format_str.get(), fmt::arg(arg_name.data(), value));
 #endif
 }
 
 // For dynamic dispatching to an explicit instantiation.
-template <typename Callback> void invoke(int index, Callback callback) {
-  switch (index) {
+template <typename Callback> void invoke(int type, Callback callback) {
+  switch (type) {
   case 0:
     callback(bool());
     break;
@@ -100,14 +86,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   if (size <= 3) return 0;
 
   // Switch types depending on the first byte of the input.
-  const auto first = data[0] & 0x0F;
-  const unsigned second = (data[0] & 0xF0) >> 4;
+  const auto type = data[0] & 0x0F;
+  const unsigned arg_name_size = (data[0] & 0xF0) >> 4;
   data++;
   size--;
 
   try {
-    invoke(first, [=](auto param1) {
-      invoke_fmt<decltype(param1)>(data, size, second);
+    invoke(type, [=](auto arg) {
+      invoke_fmt<decltype(arg)>(data, size, arg_name_size);
     });
   } catch (std::exception&) {
   }
diff --git a/test/fuzzing/one-arg.cc b/test/fuzzing/one-arg.cc
index 170d3b0a..c386772a 100644
--- a/test/fuzzing/one-arg.cc
+++ b/test/fuzzing/one-arg.cc
@@ -2,63 +2,35 @@
 // For the license information refer to format.h.
 
 #include <cstdint>
-#include <stdexcept>
-#include <type_traits>
-#include <vector>
+#include <exception>
 #include <fmt/chrono.h>
 
 #include "fuzzer-common.h"
 
-using fmt_fuzzer::nfixed;
+template <typename T, typename Repr>
+const T* from_repr(const Repr& r) { return &r; }
 
-template <typename Item>
-void invoke_fmt(const uint8_t* data, size_t size) {
-  constexpr auto N = sizeof(Item);
-  static_assert(N <= nfixed, "Nfixed is too small");
-  if (size <= nfixed) return;
-  const Item item = fmt_fuzzer::assignFromBuf<Item>(data);
-  data += nfixed;
-  size -= nfixed;
-
-#if FMT_FUZZ_SEPARATE_ALLOCATION
-  std::vector<char> fmtstringbuffer(size);
-  std::memcpy(fmtstringbuffer.data(), data, size);
-  auto format_str = fmt::string_view(fmtstringbuffer.data(), size);
-#else
-  auto format_str = fmt::string_view(fmt_fuzzer::as_chars(data), size);
-#endif
-
-#if FMT_FUZZ_FORMAT_TO_STRING
-  std::string message = fmt::format(format_str, item);
-#else
-  fmt::memory_buffer message;
-  fmt::format_to(message, format_str, item);
-#endif
+template <>
+const std::tm* from_repr<std::tm>(const std::time_t& t) {
+  return std::localtime(&t);
 }
 
-void invoke_fmt_time(const uint8_t* data, size_t size) {
-  using Item = std::time_t;
-  static_assert(sizeof(Item) <= nfixed, "Nfixed too small");
-  if (size <= nfixed) return;
-  const Item item = fmt_fuzzer::assignFromBuf<Item>(data);
-  data += nfixed;
-  size -= nfixed;
-#if FMT_FUZZ_SEPARATE_ALLOCATION
-  std::vector<char> fmtstringbuffer(size);
-  std::memcpy(fmtstringbuffer.data(), data, size);
-  auto format_str = fmt::string_view(fmtstringbuffer.data(), size);
-#else
-  auto format_str = fmt::string_view(fmt_fuzzer::as_chars(data), size);
-#endif
-  auto* b = std::localtime(&item);
-  if (b) {
+template <typename T, typename Repr = T>
+void invoke_fmt(const uint8_t* data, size_t size) {
+  static_assert(sizeof(Repr) <= fixed_size, "Nfixed is too small");
+  if (size <= fixed_size) return;
+  auto repr = assign_from_buf<Repr>(data);
+  const T* value = from_repr<T>(repr);
+  if (!value) return;
+  data += fixed_size;
+  size -= fixed_size;
+  data_to_string format_str(data, size);
 #if FMT_FUZZ_FORMAT_TO_STRING
-    std::string message = fmt::format(format_str, *b);
+  std::string message = fmt::format(format_str.get(), *value);
 #else
-    fmt::memory_buffer message;
-    fmt::format_to(message, format_str, *b);
+  fmt::memory_buffer message;
+  fmt::format_to(message, format_str.get(), *value);
 #endif
-  }
 }
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
@@ -110,7 +82,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
       invoke_fmt<long double>(data, size);
       break;
     case 13:
-      invoke_fmt_time(data, size);
+      invoke_fmt<std::tm, std::time_t>(data, size);
       break;
     default:
       break;
diff --git a/test/fuzzing/two-args.cc b/test/fuzzing/two-args.cc
index bcbd033a..4d7d3453 100644
--- a/test/fuzzing/two-args.cc
+++ b/test/fuzzing/two-args.cc
@@ -10,21 +10,19 @@
 
 template <typename Item1, typename Item2>
 void invoke_fmt(const uint8_t* data, size_t size) {
-  using fmt_fuzzer::nfixed;
-  static_assert(sizeof(Item1) <= nfixed, "size1 exceeded");
-  static_assert(sizeof(Item2) <= nfixed, "size2 exceeded");
-  if (size <= nfixed + nfixed) return;
+  static_assert(sizeof(Item1) <= fixed_size, "size1 exceeded");
+  static_assert(sizeof(Item2) <= fixed_size, "size2 exceeded");
+  if (size <= fixed_size + fixed_size) return;
 
-  const Item1 item1 = fmt_fuzzer::assignFromBuf<Item1>(data);
-  data += nfixed;
-  size -= nfixed;
+  const Item1 item1 = assign_from_buf<Item1>(data);
+  data += fixed_size;
+  size -= fixed_size;
 
-  const Item2 item2 = fmt_fuzzer::assignFromBuf<Item2>(data);
-  data += nfixed;
-  size -= nfixed;
-
-  auto format_str = fmt::string_view(fmt_fuzzer::as_chars(data), size);
+  const Item2 item2 = assign_from_buf<Item2>(data);
+  data += fixed_size;
+  size -= fixed_size;
 
+  auto format_str = fmt::string_view(as_chars(data), size);
 #if FMT_FUZZ_FORMAT_TO_STRING
   std::string message = fmt::format(format_str, item1, item2);
 #else
@@ -91,13 +89,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   if (size <= 3) return 0;
 
   // Switch types depending on the first byte of the input.
-  const auto first = data[0] & 0x0F;
-  const auto second = (data[0] & 0xF0) >> 4;
+  const auto type1 = data[0] & 0x0F;
+  const auto type2 = (data[0] & 0xF0) >> 4;
   data++;
   size--;
   try {
-    invoke(first, [=](auto param1) {
-      invoke(second, [=](auto param2) {
+    invoke(type1, [=](auto param1) {
+      invoke(type2, [=](auto param2) {
         invoke_fmt<decltype(param1), decltype(param2)>(data, size);
       });
     });