diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3d8cac7a..2ab07baf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ Version 170:
* Use a shared string for example HTTP server doc roots
* Remove deprecated serializer::reader_impl()
* Remove deprecated Body reader and writer ctor signatures
+* Add is_mutable_body_writer metafunction
--------------------------------------------------------------------------------
diff --git a/doc/qbk/quickref.xml b/doc/qbk/quickref.xml
index f93a756d..bd686346 100644
--- a/doc/qbk/quickref.xml
+++ b/doc/qbk/quickref.xml
@@ -114,6 +114,7 @@
is_body_reader
is_body_writer
is_fields
+ is_mutable_body_writer
Concepts
diff --git a/include/boost/beast/http/type_traits.hpp b/include/boost/beast/http/type_traits.hpp
index 02211a5c..d3b897f8 100644
--- a/include/boost/beast/http/type_traits.hpp
+++ b/include/boost/beast/http/type_traits.hpp
@@ -100,6 +100,43 @@ struct is_body_writer {};
#endif
+/** Returns true if the writer for a @b Body mutates the body container.
+*/
+#if BOOST_BEAST_DOXYGEN
+template
+struct is_mutable_body_writer : std::integral_constant {};
+#else
+template
+struct is_mutable_body_writer : std::false_type {};
+
+template
+struct is_mutable_body_writer().init(std::declval()),
+ std::declval>&>() =
+ std::declval().get(std::declval())
+ )>> : std::integral_constant::value && ((
+ std::is_constructible&,
+ typename T::value_type&>::value &&
+ std::is_constructible&,
+ typename T::value_type&>::value &&
+ ! std::is_constructible const&,
+ typename T::value_type const&>::value &&
+ ! std::is_constructible const&,
+ typename T::value_type const&>::value
+ ))
+ >{};
+#endif
+
/** Determine if a @b Body type has a reader.
This metafunction is equivalent to `std::true_type` if: