diff --git a/CHANGELOG b/CHANGELOG
index a467786b..48e29388 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,10 +4,8 @@
* Use beast::error_code instead of nested types
* Tidy up use of GENERATING_DOCS
* Remove obsolete RFC2616 functions
-* Add HTTP field value parser containers:
- - ext_list
- - param_list
- - token_list
+* Add message swap members and free functions
+* Add HTTP field value parser containers: ext_list, param_list, token_list
API Changes:
diff --git a/TODO.txt b/TODO.txt
index 2efbbb77..3b66fc11 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -44,3 +44,5 @@ HTTP:
* Custom HTTP error codes for various situations
* Branch prediction hints in parser
* Check basic_parser_v1 against rfc7230 for leading message whitespace
+* Fix the order of message constructor parameters:
+ body first then headers (since body is constructed with arguments more often)
diff --git a/doc/quickref.xml b/doc/quickref.xml
index 8aec0524..929876ff 100644
--- a/doc/quickref.xml
+++ b/doc/quickref.xml
@@ -56,6 +56,7 @@
parse
prepare
read
+ swap
write
Constants
diff --git a/include/beast/http/message.hpp b/include/beast/http/message.hpp
index 04c77037..6c1a57c9 100644
--- a/include/beast/http/message.hpp
+++ b/include/beast/http/message.hpp
@@ -24,12 +24,30 @@ struct request_fields
{
std::string method;
std::string url;
+
+protected:
+ void
+ swap(request_fields& other)
+ {
+ using std::swap;
+ swap(method, other.method);
+ swap(url, other.url);
+ }
};
struct response_fields
{
int status;
std::string reason;
+
+protected:
+ void
+ swap(response_fields& other)
+ {
+ using std::swap;
+ swap(status, other.status);
+ swap(reason, other.reason);
+ }
};
} // detail
@@ -125,7 +143,14 @@ struct message
{
}
+ /// Swap this message for another message.
+ void
+ swap(message& other);
+
private:
+ using base = typename std::conditional::type;
+
template
message(std::piecewise_construct_t,
std::tuple& tu, beast::detail::index_sequence)
@@ -145,6 +170,27 @@ private:
}
};
+template
+void
+message::
+swap(message& other)
+{
+ using std::swap;
+ base::swap(other);
+ swap(headers, other.headers);
+ swap(body, other.body);
+}
+
+/// Swap one message for another message.
+template
+inline
+void
+swap(message& lhs,
+ message& rhs)
+{
+ lhs.swap(rhs);
+}
+
/// A typical HTTP request
template>>
diff --git a/include/beast/http/message_v1.hpp b/include/beast/http/message_v1.hpp
index fb700b81..68abc68c 100644
--- a/include/beast/http/message_v1.hpp
+++ b/include/beast/http/message_v1.hpp
@@ -48,8 +48,32 @@ struct message_v1 : message
std::forward(argn)...)
{
}
+
+ /// Swap this message for another message.
+ void
+ swap(message_v1& other);
};
+template
+void
+message_v1::
+swap(message_v1& other)
+{
+ using std::swap;
+ message::swap(other);
+ swap(version, other.version);
+}
+
+/// Swap one message for another message.
+template
+inline
+void
+swap(message_v1& lhs,
+ message_v1& rhs)
+{
+ lhs.swap(rhs);
+}
+
/// A typical HTTP/1 request
template>>
diff --git a/test/http/message.cpp b/test/http/message.cpp
index 6d46ed47..3c549248 100644
--- a/test/http/message.cpp
+++ b/test/http/message.cpp
@@ -9,6 +9,7 @@
#include
#include
+#include
#include
#include
@@ -126,9 +127,30 @@ public:
}
}
+ void testSwap()
+ {
+ message m1;
+ message m2;
+ m1.url = "u";
+ m1.body = "1";
+ m1.headers.insert("h", "v");
+ m2.method = "G";
+ m2.body = "2";
+ swap(m1, m2);
+ expect(m1.method == "G");
+ expect(m2.method.empty());
+ expect(m1.url.empty());
+ expect(m2.url == "u");
+ expect(m1.body == "2");
+ expect(m2.body == "1");
+ expect(! m1.headers.exists("h"));
+ expect(m2.headers.exists("h"));
+ }
+
void run() override
{
testConstruction();
+ testSwap();
}
};
diff --git a/test/http/message_v1.cpp b/test/http/message_v1.cpp
index d86097dd..a8954c68 100644
--- a/test/http/message_v1.cpp
+++ b/test/http/message_v1.cpp
@@ -8,6 +8,8 @@
// Test that header file is self-contained.
#include
+#include
+#include
#include
#include
@@ -78,10 +80,36 @@ public:
expect(! is_keep_alive(m));
}
+ void testSwap()
+ {
+ message_v1 m1;
+ message_v1 m2;
+ m1.status = 200;
+ m1.version = 10;
+ m1.body = "1";
+ m1.headers.insert("h", "v");
+ m2.status = 404;
+ m2.reason = "OK";
+ m2.body = "2";
+ m2.version = 11;
+ swap(m1, m2);
+ expect(m1.status == 404);
+ expect(m2.status == 200);
+ expect(m1.reason == "OK");
+ expect(m2.reason.empty());
+ expect(m1.version == 11);
+ expect(m2.version == 10);
+ expect(m1.body == "2");
+ expect(m2.body == "1");
+ expect(! m1.headers.exists("h"));
+ expect(m2.headers.exists("h"));
+ }
+
void run() override
{
testFreeFunctions();
testPrepare();
+ testSwap();
}
};