internal::MemoryBuffer -> basic_memory_buffer
diff --git a/fmt/format.cc b/fmt/format.cc
index 563a8f7..3823c73 100644
--- a/fmt/format.cc
+++ b/fmt/format.cc
@@ -205,7 +205,7 @@
 
 void report_error(FormatFunc func, int error_code,
                   string_view message) FMT_NOEXCEPT {
-  internal::MemoryBuffer<char> full_message;
+  memory_buffer full_message;
   func(full_message, error_code, message);
   // Use Writer::data instead of Writer::c_str to avoid potential memory
   // allocation.
@@ -217,10 +217,10 @@
 FMT_FUNC void SystemError::init(
     int err_code, CStringRef format_str, args args) {
   error_code_ = err_code;
-  internal::MemoryBuffer<char> buf;
-  format_system_error(buf, err_code, vformat(format_str, args));
+  memory_buffer buffer;
+  format_system_error(buffer, err_code, vformat(format_str, args));
   std::runtime_error &base = *this;
-  base = std::runtime_error(to_string(buf));
+  base = std::runtime_error(to_string(buffer));
 }
 
 template <typename T>
@@ -382,7 +382,7 @@
 FMT_FUNC void format_system_error(
     buffer &out, int error_code, string_view message) FMT_NOEXCEPT {
   FMT_TRY {
-    internal::MemoryBuffer<char, internal::INLINE_BUFFER_SIZE> buffer;
+    memory_buffer buffer;
     buffer.resize(internal::INLINE_BUFFER_SIZE);
     for (;;) {
       char *system_message = &buffer[0];
@@ -422,7 +422,7 @@
 #endif
 
 FMT_FUNC void vprint(std::FILE *f, CStringRef format_str, args args) {
-  internal::MemoryBuffer<char> buffer;
+  memory_buffer buffer;
   vformat_to(buffer, format_str, args);
   std::fwrite(buffer.data(), 1, buffer.size(), f);
 }
@@ -444,7 +444,7 @@
             args args);
 
 FMT_FUNC int vfprintf(std::FILE *f, CStringRef format, printf_args args) {
-  internal::MemoryBuffer<char> buffer;
+  memory_buffer buffer;
   printf(buffer, format, args);
   std::size_t size = buffer.size();
   return std::fwrite(
diff --git a/fmt/format.h b/fmt/format.h
index bb3bbfd..d4de5ea 100644
--- a/fmt/format.h
+++ b/fmt/format.h
@@ -659,13 +659,39 @@
   return std::basic_string<Char>(buffer.data(), buffer.size());
 }
 
-namespace internal {
+/**
+  \rst
+  A dynamically growing memory buffer for trivially copyable/constructible types
+  with the first SIZE elements stored in the object itself.
 
-// A memory buffer for trivially copyable/constructible types with the first
-// SIZE elements stored in the object itself.
-template <typename T, std::size_t SIZE = INLINE_BUFFER_SIZE,
+  You can use one of the following typedefs for common character types:
+
+  +----------------+------------------------------+
+  | Type           | Definition                   |
+  +================+==============================+
+  | memory_buffer  | basic_memory_buffer<char>    |
+  +----------------+------------------------------+
+  | wmemory_buffer | basic_memory_buffer<wchar_t> |
+  +----------------+------------------------------+
+
+  **Example**::
+
+     memory_buffer out;
+     format_to(out, "The answer is {}.", 42);
+
+  This will write the following output to the ``out`` object:
+
+  .. code-block:: none
+
+     The answer is 42.
+
+  The output can be converted to an ``std::string`` with ``to_string(out)``.
+  \endrst
+ */
+//
+template <typename T, std::size_t SIZE = internal::INLINE_BUFFER_SIZE,
           typename Allocator = std::allocator<T> >
-class MemoryBuffer : private Allocator, public basic_buffer<T> {
+class basic_memory_buffer : private Allocator, public basic_buffer<T> {
  private:
   T data_[SIZE];
 
@@ -678,14 +704,14 @@
   void grow(std::size_t size);
 
  public:
-  explicit MemoryBuffer(const Allocator &alloc = Allocator())
+  explicit basic_memory_buffer(const Allocator &alloc = Allocator())
       : Allocator(alloc), basic_buffer<T>(data_, SIZE) {}
-  ~MemoryBuffer() { deallocate(); }
+  ~basic_memory_buffer() { deallocate(); }
 
 #if FMT_USE_RVALUE_REFERENCES
  private:
   // Move data from other to this buffer.
-  void move(MemoryBuffer &other) {
+  void move(basic_memory_buffer &other) {
     Allocator &this_alloc = *this, &other_alloc = other;
     this_alloc = std::move(other_alloc);
     this->size_ = other.size_;
@@ -693,7 +719,7 @@
     if (other.ptr_ == other.data_) {
       this->ptr_ = data_;
       std::uninitialized_copy(other.data_, other.data_ + this->size_,
-                              make_ptr(data_, this->capacity_));
+                              internal::make_ptr(data_, this->capacity_));
     } else {
       this->ptr_ = other.ptr_;
       // Set pointer to the inline array so that delete is not called
@@ -703,11 +729,22 @@
   }
 
  public:
-  MemoryBuffer(MemoryBuffer &&other) {
+  /**
+    \rst
+    Constructs a :class:`fmt::basic_memory_buffer` object moving the content
+    of the other object to it.
+    \endrst
+   */
+  basic_memory_buffer(basic_memory_buffer &&other) {
     move(other);
   }
 
-  MemoryBuffer &operator=(MemoryBuffer &&other) {
+  /**
+    \rst
+    Moves the content of the other ``basic_memory_buffer`` object to this one.
+    \endrst
+   */
+  basic_memory_buffer &operator=(basic_memory_buffer &&other) {
     assert(this != &other);
     deallocate();
     move(other);
@@ -720,14 +757,14 @@
 };
 
 template <typename T, std::size_t SIZE, typename Allocator>
-void MemoryBuffer<T, SIZE, Allocator>::grow(std::size_t size) {
+void basic_memory_buffer<T, SIZE, Allocator>::grow(std::size_t size) {
   std::size_t new_capacity = this->capacity_ + this->capacity_ / 2;
   if (size > new_capacity)
       new_capacity = size;
   T *new_ptr = this->allocate(new_capacity);
   // The following code doesn't throw, so the raw pointer above doesn't leak.
   std::uninitialized_copy(this->ptr_, this->ptr_ + this->size_,
-                          make_ptr(new_ptr, new_capacity));
+                          internal::make_ptr(new_ptr, new_capacity));
   std::size_t old_capacity = this->capacity_;
   T *old_ptr = this->ptr_;
   this->capacity_ = new_capacity;
@@ -739,6 +776,45 @@
     Allocator::deallocate(old_ptr, old_capacity);
 }
 
+typedef basic_memory_buffer<char> memory_buffer;
+typedef basic_memory_buffer<wchar_t> wmemory_buffer;
+
+/**
+  \rst
+  A fixed-size memory buffer. For a dynamically growing buffer use
+  :class:`fmt::basic_memory_buffer`.
+
+  Trying to increase the buffer size past the initial capacity will throw
+  ``std::runtime_error``.
+  \endrst
+ */
+template <typename Char>
+class FixedBuffer : public basic_buffer<Char> {
+ public:
+  /**
+   \rst
+   Constructs a :class:`fmt::FixedBuffer` object for *array* of the
+   given size.
+   \endrst
+   */
+  FixedBuffer(Char *array, std::size_t size)
+    : basic_buffer<Char>(array, size) {}
+
+  /**
+   \rst
+   Constructs a :class:`fmt::FixedBuffer` object for *array* of the
+   size known at compile time.
+   \endrst
+   */
+  template <std::size_t SIZE>
+  explicit FixedBuffer(Char (&array)[SIZE]) : basic_buffer<Char>(array, SIZE) {}
+
+ protected:
+  FMT_API void grow(std::size_t size);
+};
+
+namespace internal {
+
 template <typename Char>
 class BasicCharTraits {
  public:
@@ -1047,7 +1123,7 @@
 
 #define FMT_DISABLE_CONVERSION_TO_INT(Type) \
   template <> \
-  struct ConvertToInt<Type> {  enum { value = 0 }; }
+  struct ConvertToInt<Type> { enum { value = 0 }; }
 
 // Silence warnings about convering float to int.
 FMT_DISABLE_CONVERSION_TO_INT(float);
@@ -2762,108 +2838,6 @@
   grow_buffer(n);
 }
 
-/**
-  \rst
-  This class template provides operations for formatting and writing data
-  into a memory buffer that grows dynamically.
-
-  You can use one of the following typedefs for common character types
-  and the standard allocator:
-
-  +---------------+-----------------------------------------------------+
-  | Type          | Definition                                          |
-  +===============+=====================================================+
-  | MemoryWriter  | BasicMemoryWriter<char, std::allocator<char>>       |
-  +---------------+-----------------------------------------------------+
-  | WMemoryWriter | BasicMemoryWriter<wchar_t, std::allocator<wchar_t>> |
-  +---------------+-----------------------------------------------------+
-
-  **Example**::
-
-     MemoryWriter out;
-     out << "The answer is " << 42 << "\n";
-     out.write("({:+f}, {:+f})", -3.14, 3.14);
-
-  This will write the following output to the ``out`` object:
-
-  .. code-block:: none
-
-     The answer is 42
-     (-3.140000, +3.140000)
-
-  The output can be converted to an ``std::string`` with ``out.str()`` or
-  accessed as a C string with ``out.c_str()``.
-  \endrst
- */
-template <typename Char, typename Allocator = std::allocator<Char> >
-class BasicMemoryWriter : public basic_writer<Char> {
- private:
-  internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE, Allocator> buffer_;
-
- public:
-  explicit BasicMemoryWriter(const Allocator& alloc = Allocator())
-    : basic_writer<Char>(buffer_), buffer_(alloc) {}
-
-#if FMT_USE_RVALUE_REFERENCES
-  /**
-    \rst
-    Constructs a :class:`fmt::BasicMemoryWriter` object moving the content
-    of the other object to it.
-    \endrst
-   */
-  BasicMemoryWriter(BasicMemoryWriter &&other)
-    : basic_writer<Char>(buffer_), buffer_(std::move(other.buffer_)) {
-  }
-
-  /**
-    \rst
-    Moves the content of the other ``BasicMemoryWriter`` object to this one.
-    \endrst
-   */
-  BasicMemoryWriter &operator=(BasicMemoryWriter &&other) {
-    buffer_ = std::move(other.buffer_);
-    return *this;
-  }
-#endif
-};
-
-typedef BasicMemoryWriter<char> MemoryWriter;
-typedef BasicMemoryWriter<wchar_t> WMemoryWriter;
-
-/**
-  \rst
-  A fixed-size memory buffer. For a dynamically growing buffer use
-  :class:`fmt::internal::MemoryBuffer`.
-
-  Trying to increase the buffer size past the initial capacity will throw
-  ``std::runtime_error``.
-  \endrst
- */
-template <typename Char>
-class FixedBuffer : public basic_buffer<Char> {
- public:
-  /**
-   \rst
-   Constructs a :class:`fmt::FixedBuffer` object for *array* of the
-   given size.
-   \endrst
-   */
-  FixedBuffer(Char *array, std::size_t size)
-    : basic_buffer<Char>(array, size) {}
-
-  /**
-   \rst
-   Constructs a :class:`fmt::FixedBuffer` object for *array* of the
-   size known at compile time.
-   \endrst
-   */
-  template <std::size_t SIZE>
-  explicit FixedBuffer(Char (&array)[SIZE]) : basic_buffer<Char>(array, SIZE) {}
-
- protected:
-  FMT_API void grow(std::size_t size);
-};
-
 // Reports a system error without throwing an exception.
 // Can be used to report errors from destructors.
 FMT_API void report_system_error(int error_code,
@@ -2959,7 +2933,7 @@
 }
 
 inline std::string vformat(CStringRef format_str, args args) {
-  internal::MemoryBuffer<char> buffer;
+  memory_buffer buffer;
   vformat_to(buffer, format_str, args);
   return to_string(buffer);
 }
@@ -2979,7 +2953,7 @@
 }
 
 inline std::wstring vformat(WCStringRef format_str, wargs args) {
-  internal::MemoryBuffer<wchar_t> buffer;
+  wmemory_buffer buffer;
   vformat_to(buffer, format_str, args);
   return to_string(buffer);
 }
diff --git a/fmt/ostream.cc b/fmt/ostream.cc
index f900664..f913648 100644
--- a/fmt/ostream.cc
+++ b/fmt/ostream.cc
@@ -28,7 +28,7 @@
 }
 
 FMT_FUNC void vprint(std::ostream &os, CStringRef format_str, args args) {
-  internal::MemoryBuffer<char> buffer;
+  memory_buffer buffer;
   vformat_to(buffer, format_str, args);
   internal::write(os, buffer);
 }
diff --git a/fmt/ostream.h b/fmt/ostream.h
index 4510373..8672ac6 100644
--- a/fmt/ostream.h
+++ b/fmt/ostream.h
@@ -83,7 +83,7 @@
 template <typename Char, typename T>
 void format_value(basic_buffer<Char> &buf, const T &value,
                   basic_context<Char> &ctx) {
-  internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer;
+  basic_memory_buffer<Char> buffer;
   internal::format_value(buffer, value);
   basic_string_view<Char> str(buffer.data(), buffer.size());
   do_format_arg< arg_formatter<Char> >(
diff --git a/fmt/printf.h b/fmt/printf.h
index 0f3a200..02c33fb 100644
--- a/fmt/printf.h
+++ b/fmt/printf.h
@@ -522,7 +522,7 @@
 typedef basic_args<printf_context<char>> printf_args;
 
 inline std::string vsprintf(CStringRef format, printf_args args) {
-  internal::MemoryBuffer<char> buffer;
+  memory_buffer buffer;
   printf(buffer, format, args);
   return to_string(buffer);
 }
@@ -543,7 +543,7 @@
 
 inline std::wstring vsprintf(
     WCStringRef format, basic_args<printf_context<wchar_t>> args) {
-  internal::MemoryBuffer<wchar_t> buffer;
+  wmemory_buffer buffer;
   printf(buffer, format, args);
   return to_string(buffer);
 }
@@ -590,7 +590,7 @@
 }
 
 inline int vfprintf(std::ostream &os, CStringRef format_str, printf_args args) {
-  internal::MemoryBuffer<char> buffer;
+  memory_buffer buffer;
   printf(buffer, format_str, args);
   internal::write(os, buffer);
   return static_cast<int>(buffer.size());
diff --git a/fmt/time.h b/fmt/time.h
index f4ec481..c4700fb 100644
--- a/fmt/time.h
+++ b/fmt/time.h
@@ -24,7 +24,7 @@
     ++end;
   if (*end != '}')
     FMT_THROW(format_error("missing '}' in format string"));
-  internal::MemoryBuffer<char, internal::INLINE_BUFFER_SIZE> format;
+  memory_buffer format;
   format.append(s, end + 1);
   format[format.size() - 1] = '\0';
   std::size_t start = buf.size();
diff --git a/test/custom-formatter-test.cc b/test/custom-formatter-test.cc
index c4d1f1e..3e226d7 100644
--- a/test/custom-formatter-test.cc
+++ b/test/custom-formatter-test.cc
@@ -46,7 +46,7 @@
 };
 
 std::string custom_vformat(fmt::CStringRef format_str, fmt::args args) {
-  fmt::internal::MemoryBuffer<char> buffer;
+  fmt::memory_buffer buffer;
   // Pass custom argument formatter as a template arg to vwrite.
   fmt::vformat_to<CustomArgFormatter>(buffer, format_str, args);
   return std::string(buffer.data(), buffer.size());
@@ -64,7 +64,7 @@
 std::string custom_vsprintf(
     const char* format_str,
     fmt::basic_args<CustomPrintfFormatter> args) {
-  fmt::internal::MemoryBuffer<char> buffer;
+  fmt::memory_buffer buffer;
   CustomPrintfFormatter formatter(format_str, args);
   formatter.format(buffer);
   return std::string(buffer.data(), buffer.size());
diff --git a/test/format-impl-test.cc b/test/format-impl-test.cc
index 9102db0..f12b645 100644
--- a/test/format-impl-test.cc
+++ b/test/format-impl-test.cc
@@ -105,33 +105,33 @@
 TEST(FormatTest, FormatErrorCode) {
   std::string msg = "error 42", sep = ": ";
   {
-    fmt::MemoryWriter w;
-    w.write("garbage");
-    fmt::format_error_code(w.buffer(), 42, "test");
-    EXPECT_EQ("test: " + msg, w.str());
+    fmt::memory_buffer buffer;
+    format_to(buffer, "garbage");
+    fmt::format_error_code(buffer, 42, "test");
+    EXPECT_EQ("test: " + msg, to_string(buffer));
   }
   {
-    fmt::MemoryWriter w;
+    fmt::memory_buffer buffer;
     std::string prefix(
         fmt::internal::INLINE_BUFFER_SIZE - msg.size() - sep.size() + 1, 'x');
-    fmt::format_error_code(w.buffer(), 42, prefix);
-    EXPECT_EQ(msg, w.str());
+    fmt::format_error_code(buffer, 42, prefix);
+    EXPECT_EQ(msg, to_string(buffer));
   }
   int codes[] = {42, -1};
   for (std::size_t i = 0, n = sizeof(codes) / sizeof(*codes); i < n; ++i) {
     // Test maximum buffer size.
     msg = fmt::format("error {}", codes[i]);
-    fmt::MemoryWriter w;
+    fmt::memory_buffer buffer;
     std::string prefix(
         fmt::internal::INLINE_BUFFER_SIZE - msg.size() - sep.size(), 'x');
-    fmt::format_error_code(w.buffer(), codes[i], prefix);
-    EXPECT_EQ(prefix + sep + msg, w.str());
+    fmt::format_error_code(buffer, codes[i], prefix);
+    EXPECT_EQ(prefix + sep + msg, to_string(buffer));
     std::size_t size = fmt::internal::INLINE_BUFFER_SIZE;
-    EXPECT_EQ(size, w.size());
-    w.clear();
+    EXPECT_EQ(size, buffer.size());
+    buffer.clear();
     // Test with a message that doesn't fit into the buffer.
     prefix += 'x';
-    fmt::format_error_code(w.buffer(), codes[i], prefix);
-    EXPECT_EQ(msg, w.str());
+    fmt::format_error_code(buffer, codes[i], prefix);
+    EXPECT_EQ(msg, to_string(buffer));
   }
 }
diff --git a/test/format-test.cc b/test/format-test.cc
index bf2b153..2e1baaf 100644
--- a/test/format-test.cc
+++ b/test/format-test.cc
@@ -75,8 +75,8 @@
 using fmt::format_error;
 using fmt::string_view;
 using fmt::CStringRef;
-using fmt::MemoryWriter;
-using fmt::WMemoryWriter;
+using fmt::memory_buffer;
+using fmt::wmemory_buffer;
 using fmt::fill;
 using fmt::type;
 using fmt::width;
@@ -109,7 +109,8 @@
 // as writing it to std::basic_ostringstream<Char>.
 template <typename Char, typename T>
 ::testing::AssertionResult check_write(const T &value, const char *type) {
-  fmt::BasicMemoryWriter<Char> writer;
+  fmt::basic_memory_buffer<Char> buffer;
+  fmt::basic_writer<Char> writer(buffer);
   writer.write(value);
   std::basic_string<Char> actual = writer.str();
   std::basic_string<Char> expected;
@@ -177,90 +178,16 @@
 #endif
 
 TEST(WriterTest, Ctor) {
-  MemoryWriter w;
+  memory_buffer buf;
+  fmt::basic_writer<char> w(buf);
   EXPECT_EQ(0u, w.size());
   EXPECT_STREQ("", w.c_str());
   EXPECT_EQ("", w.str());
 }
 
-#if FMT_USE_RVALUE_REFERENCES
-
-void check_move_writer(const std::string &str, MemoryWriter &w) {
-  MemoryWriter w2(std::move(w));
-  // Move shouldn't destroy the inline content of the first writer.
-  EXPECT_EQ(str, w.str());
-  EXPECT_EQ(str, w2.str());
-}
-
-TEST(WriterTest, MoveCtor) {
-  MemoryWriter w;
-  w.write("test");
-  check_move_writer("test", w);
-  // This fills the inline buffer, but doesn't cause dynamic allocation.
-  std::string s;
-  for (int i = 0; i < fmt::internal::INLINE_BUFFER_SIZE; ++i)
-    s += '*';
-  w.clear();
-  w.write(s);
-  check_move_writer(s, w);
-  const char *inline_buffer_ptr = w.data();
-  // Adding one more character causes the content to move from the inline to
-  // a dynamically allocated buffer.
-  w.write('*');
-  MemoryWriter w2(std::move(w));
-  // Move should rip the guts of the first writer.
-  EXPECT_EQ(inline_buffer_ptr, w.data());
-  EXPECT_EQ(s + '*', w2.str());
-}
-
-void CheckMoveAssignWriter(const std::string &str, MemoryWriter &w) {
-  MemoryWriter w2;
-  w2 = std::move(w);
-  // Move shouldn't destroy the inline content of the first writer.
-  EXPECT_EQ(str, w.str());
-  EXPECT_EQ(str, w2.str());
-}
-
-TEST(WriterTest, MoveAssignment) {
-  MemoryWriter w;
-  w.write("test");
-  CheckMoveAssignWriter("test", w);
-  // This fills the inline buffer, but doesn't cause dynamic allocation.
-  std::string s;
-  for (int i = 0; i < fmt::internal::INLINE_BUFFER_SIZE; ++i)
-    s += '*';
-  w.clear();
-  w.write(s);
-  CheckMoveAssignWriter(s, w);
-  const char *inline_buffer_ptr = w.data();
-  // Adding one more character causes the content to move from the inline to
-  // a dynamically allocated buffer.
-  w.write('*');
-  MemoryWriter w2;
-  w2 = std::move(w);
-  // Move should rip the guts of the first writer.
-  EXPECT_EQ(inline_buffer_ptr, w.data());
-  EXPECT_EQ(s + '*', w2.str());
-}
-
-#endif  // FMT_USE_RVALUE_REFERENCES
-
-TEST(WriterTest, Allocator) {
-  typedef testing::StrictMock< MockAllocator<char> > MockAllocator;
-  typedef AllocatorRef<MockAllocator> TestAllocator;
-  MockAllocator alloc;
-  fmt::BasicMemoryWriter<char, TestAllocator> w((TestAllocator(&alloc)));
-  std::size_t size =
-      static_cast<std::size_t>(1.5 * fmt::internal::INLINE_BUFFER_SIZE);
-  std::vector<char> mem(size);
-  EXPECT_CALL(alloc, allocate(size)).WillOnce(testing::Return(&mem[0]));
-  for (int i = 0; i < fmt::internal::INLINE_BUFFER_SIZE + 1; ++i)
-    w.write('*');
-  EXPECT_CALL(alloc, deallocate(&mem[0], size));
-}
-
 TEST(WriterTest, Data) {
-  MemoryWriter w;
+  memory_buffer buf;
+  fmt::basic_writer<char> w(buf);
   w.write(42);
   EXPECT_EQ("42", std::string(w.data(), w.size()));
 }
@@ -312,13 +239,15 @@
 }
 
 TEST(WriterTest, WriteDoubleAtBufferBoundary) {
-  MemoryWriter writer;
+  memory_buffer buf;
+  fmt::basic_writer<char> writer(buf);
   for (int i = 0; i < 100; ++i)
     writer.write(1.23456789);
 }
 
 TEST(WriterTest, WriteDoubleWithFilledBuffer) {
-  MemoryWriter writer;
+  memory_buffer buf;
+  fmt::basic_writer<char> writer(buf);
   // Fill the buffer.
   for (int i = 0; i < fmt::internal::INLINE_BUFFER_SIZE; ++i)
     writer.write(' ');
@@ -349,7 +278,8 @@
 
 template <typename... T>
 std::string write_str(T... args) {
-  MemoryWriter writer;
+  memory_buffer buf;
+  fmt::basic_writer<char> writer(buf);
   using namespace fmt;
   writer.write(args...);
   return writer.str();
@@ -357,7 +287,8 @@
 
 template <typename... T>
 std::wstring write_wstr(T... args) {
-  WMemoryWriter writer;
+  wmemory_buffer buf;
+  fmt::basic_writer<wchar_t> writer(buf);
   using namespace fmt;
   writer.write(args...);
   return writer.str();
@@ -447,7 +378,8 @@
   EXPECT_EQ("     33", write_str(33ll, width=7));
   EXPECT_EQ("     44", write_str(44ull, width=7));
 
-  MemoryWriter w;
+  memory_buffer buf;
+  fmt::basic_writer<char> w(buf);
   w.clear();
   w.write(42, fmt::width=5, fmt::fill='0');
   EXPECT_EQ("00042", w.str());
@@ -475,13 +407,13 @@
 }
 
 TEST(FormatToTest, FormatWithoutArgs) {
-  fmt::internal::MemoryBuffer<char> buffer;
+  fmt::memory_buffer buffer;
   format_to(buffer, "test");
   EXPECT_EQ("test", std::string(buffer.data(), buffer.size()));
 }
 
 TEST(FormatToTest, Format) {
-  fmt::internal::MemoryBuffer<char> buffer;
+  fmt::memory_buffer buffer;
   format_to(buffer, "part{0}", 1);
   EXPECT_EQ(strlen("part1"), buffer.size());
   EXPECT_EQ("part1", std::string(buffer.data(), buffer.size()));
@@ -1370,18 +1302,9 @@
   EXPECT_EQ("42", format("{}", 42));
   EXPECT_EQ("42", format(std::string("{}"), 42));
 
-  MemoryWriter out;
-  out.write("The answer is ");
-  out.write(42);
-  out.write("\n");
-
-  {
-    MemoryWriter writer;
-    for (int i = 0; i < 10; i++)
-      format_to(writer.buffer(), "{}", i);
-    std::string s = writer.str(); // s == 0123456789
-    EXPECT_EQ("0123456789", s);
-  }
+  memory_buffer out;
+  format_to(out, "The answer is {}.", 42);
+  EXPECT_EQ("The answer is 42.", to_string(out));
 
   const char *filename = "nonexistent";
   FILE *ftest = safe_fopen(filename, "r");
@@ -1522,7 +1445,7 @@
 }
 
 std::string vformat_message(int id, const char *format, fmt::args args) {
-  fmt::internal::MemoryBuffer<char> buffer;
+  fmt::memory_buffer buffer;
   format_to(buffer, "[{}] ", id);
   vformat_to(buffer, format, args);
   return to_string(buffer);
@@ -1612,7 +1535,7 @@
 };
 
 void custom_vformat(fmt::CStringRef format_str, fmt::args args) {
-  fmt::internal::MemoryBuffer<char> buffer;
+  fmt::memory_buffer buffer;
   fmt::vformat_to<MockArgFormatter>(buffer, format_str, args);
 }
 
diff --git a/test/gtest-extra-test.cc b/test/gtest-extra-test.cc
index 4de17ee..97c4bee 100644
--- a/test/gtest-extra-test.cc
+++ b/test/gtest-extra-test.cc
@@ -319,9 +319,9 @@
 }
 
 TEST(UtilTest, FormatSystemError) {
-  fmt::MemoryWriter out;
-  fmt::format_system_error(out.buffer(), EDOM, "test message");
-  EXPECT_EQ(out.str(), format_system_error(EDOM, "test message"));
+  fmt::memory_buffer out;
+  fmt::format_system_error(out, EDOM, "test message");
+  EXPECT_EQ(to_string(out), format_system_error(EDOM, "test message"));
 }
 
 #if FMT_USE_FILE_DESCRIPTORS
diff --git a/test/gtest-extra.cc b/test/gtest-extra.cc
index 325216d..34daf4d 100644
--- a/test/gtest-extra.cc
+++ b/test/gtest-extra.cc
@@ -104,7 +104,7 @@
 #endif  // FMT_USE_FILE_DESCRIPTORS
 
 std::string format_system_error(int error_code, fmt::string_view message) {
-  fmt::internal::MemoryBuffer<char> out;
-  fmt::format_system_error(out, error_code, message);
+  fmt::memory_buffer out;
+  format_system_error(out, error_code, message);
   return to_string(out);
 }
diff --git a/test/ostream-test.cc b/test/ostream-test.cc
index c28635b..2ab2224 100644
--- a/test/ostream-test.cc
+++ b/test/ostream-test.cc
@@ -64,7 +64,7 @@
 };
 
 TEST(OStreamTest, CustomArg) {
-  fmt::internal::MemoryBuffer<char> buffer;
+  fmt::memory_buffer buffer;
   fmt::context ctx("}", fmt::args());
   fmt::format_specs spec;
   TestArgFormatter af(buffer, ctx, spec);
@@ -121,7 +121,7 @@
 
 TEST(OStreamTest, WriteToOStream) {
   std::ostringstream os;
-  fmt::internal::MemoryBuffer<char> buffer;
+  fmt::memory_buffer buffer;
   const char *foo = "foo";
   buffer.append(foo, foo + std::strlen(foo));
   fmt::internal::write(os, buffer);
diff --git a/test/util-test.cc b/test/util-test.cc
index 5978d91..f9ca8e5 100644
--- a/test/util-test.cc
+++ b/test/util-test.cc
@@ -54,8 +54,8 @@
 
 using fmt::basic_arg;
 using fmt::basic_buffer;
+using fmt::basic_memory_buffer;
 using fmt::string_view;
-using fmt::internal::MemoryBuffer;
 using fmt::internal::value;
 
 using testing::_;
@@ -238,7 +238,7 @@
 }
 
 TEST(MemoryBufferTest, Ctor) {
-  MemoryBuffer<char, 123> buffer;
+  basic_memory_buffer<char, 123> buffer;
   EXPECT_EQ(0u, buffer.size());
   EXPECT_EQ(123u, buffer.capacity());
 }
@@ -248,9 +248,9 @@
 typedef AllocatorRef< std::allocator<char> > TestAllocator;
 
 void check_move_buffer(const char *str,
-                       MemoryBuffer<char, 5, TestAllocator> &buffer) {
+                       basic_memory_buffer<char, 5, TestAllocator> &buffer) {
   std::allocator<char> *alloc = buffer.get_allocator().get();
-  MemoryBuffer<char, 5, TestAllocator> buffer2(std::move(buffer));
+  basic_memory_buffer<char, 5, TestAllocator> buffer2(std::move(buffer));
   // Move shouldn't destroy the inline content of the first buffer.
   EXPECT_EQ(str, std::string(&buffer[0], buffer.size()));
   EXPECT_EQ(str, std::string(&buffer2[0], buffer2.size()));
@@ -262,7 +262,7 @@
 
 TEST(MemoryBufferTest, MoveCtor) {
   std::allocator<char> alloc;
-  MemoryBuffer<char, 5, TestAllocator> buffer((TestAllocator(&alloc)));
+  basic_memory_buffer<char, 5, TestAllocator> buffer((TestAllocator(&alloc)));
   const char test[] = "test";
   buffer.append(test, test + 4);
   check_move_buffer("test", buffer);
@@ -274,15 +274,16 @@
   // Adding one more character causes the content to move from the inline to
   // a dynamically allocated buffer.
   buffer.push_back('b');
-  MemoryBuffer<char, 5, TestAllocator> buffer2(std::move(buffer));
+  basic_memory_buffer<char, 5, TestAllocator> buffer2(std::move(buffer));
   // Move should rip the guts of the first buffer.
   EXPECT_EQ(inline_buffer_ptr, &buffer[0]);
   EXPECT_EQ("testab", std::string(&buffer2[0], buffer2.size()));
   EXPECT_GT(buffer2.capacity(), 5u);
 }
 
-void check_move_assign_buffer(const char *str, MemoryBuffer<char, 5> &buffer) {
-  MemoryBuffer<char, 5> buffer2;
+void check_move_assign_buffer(
+    const char *str, basic_memory_buffer<char, 5> &buffer) {
+  basic_memory_buffer<char, 5> buffer2;
   buffer2 = std::move(buffer);
   // Move shouldn't destroy the inline content of the first buffer.
   EXPECT_EQ(str, std::string(&buffer[0], buffer.size()));
@@ -291,7 +292,7 @@
 }
 
 TEST(MemoryBufferTest, MoveAssignment) {
-  MemoryBuffer<char, 5> buffer;
+  basic_memory_buffer<char, 5> buffer;
   const char test[] = "test";
   buffer.append(test, test + 4);
   check_move_assign_buffer("test", buffer);
@@ -303,7 +304,7 @@
   // Adding one more character causes the content to move from the inline to
   // a dynamically allocated buffer.
   buffer.push_back('b');
-  MemoryBuffer<char, 5> buffer2;
+  basic_memory_buffer<char, 5> buffer2;
   buffer2 = std::move(buffer);
   // Move should rip the guts of the first buffer.
   EXPECT_EQ(inline_buffer_ptr, &buffer[0]);
@@ -315,7 +316,7 @@
 
 TEST(MemoryBufferTest, Grow) {
   typedef AllocatorRef< MockAllocator<int> > Allocator;
-  typedef MemoryBuffer<int, 10, Allocator> Base;
+  typedef basic_memory_buffer<int, 10, Allocator> Base;
   MockAllocator<int> alloc;
   struct TestMemoryBuffer : Base {
     TestMemoryBuffer(Allocator alloc) : Base(alloc) {}
@@ -341,12 +342,12 @@
 
 TEST(MemoryBufferTest, Allocator) {
   typedef AllocatorRef< MockAllocator<char> > TestAllocator;
-  MemoryBuffer<char, 10, TestAllocator> buffer;
+  basic_memory_buffer<char, 10, TestAllocator> buffer;
   EXPECT_EQ(0, buffer.get_allocator().get());
   StrictMock< MockAllocator<char> > alloc;
   char mem;
   {
-    MemoryBuffer<char, 10, TestAllocator> buffer2((TestAllocator(&alloc)));
+    basic_memory_buffer<char, 10, TestAllocator> buffer2((TestAllocator(&alloc)));
     EXPECT_EQ(&alloc, buffer2.get_allocator().get());
     std::size_t size = 2 * fmt::internal::INLINE_BUFFER_SIZE;
     EXPECT_CALL(alloc, allocate(size)).WillOnce(Return(&mem));
@@ -358,7 +359,7 @@
 TEST(MemoryBufferTest, ExceptionInDeallocate) {
   typedef AllocatorRef< MockAllocator<char> > TestAllocator;
   StrictMock< MockAllocator<char> > alloc;
-  MemoryBuffer<char, 10, TestAllocator> buffer((TestAllocator(&alloc)));
+  basic_memory_buffer<char, 10, TestAllocator> buffer((TestAllocator(&alloc)));
   std::size_t size = 2 * fmt::internal::INLINE_BUFFER_SIZE;
   std::vector<char> mem(size);
   {
@@ -435,7 +436,7 @@
   ::Test t;
   fmt::internal::value<CustomContext> arg(t);
   CustomContext ctx = {false};
-  fmt::internal::MemoryBuffer<char> buffer;
+  fmt::memory_buffer buffer;
   arg.custom.format(buffer, &t, &ctx);
   EXPECT_TRUE(ctx.called);
 }
@@ -579,7 +580,7 @@
   EXPECT_CALL(visitor, visit(_)).WillOnce(
         testing::Invoke([&](fmt::internal::CustomValue<char> custom) {
     EXPECT_EQ(&test, custom.value);
-    fmt::internal::MemoryBuffer<char> buffer;
+    fmt::memory_buffer buffer;
     fmt::context ctx("}", fmt::args());
     custom.format(buffer, &test, &ctx);
     EXPECT_EQ("test", std::string(buffer.data(), buffer.size()));
@@ -710,14 +711,14 @@
   } catch (const fmt::SystemError &e) {
     error = e;
   }
-  fmt::internal::MemoryBuffer<char> message;
+  fmt::memory_buffer message;
   format(message, error_code, "test error");
   EXPECT_EQ(to_string(message), error.what());
   EXPECT_EQ(error_code, error.error_code());
 }
 
 TEST(UtilTest, FormatSystemError) {
-  fmt::internal::MemoryBuffer<char> message;
+  fmt::memory_buffer message;
   fmt::format_system_error(message, EDOM, "test");
   EXPECT_EQ(fmt::format("test: {}", get_system_error(EDOM)),
             to_string(message));
@@ -735,7 +736,7 @@
 }
 
 TEST(UtilTest, ReportSystemError) {
-  fmt::internal::MemoryBuffer<char> out;
+  fmt::memory_buffer out;
   fmt::format_system_error(out, EDOM, "test error");
   out.push_back('\n');
   EXPECT_WRITE(stderr, fmt::report_system_error(EDOM, "test error"),