Add generic socket protocols and converting move constructors.

Four new protocol classes have been added:

- asio::generic::datagram_protocol
- asio::generic::raw_protocol
- asio::generic::seq_packet_protocol
- asio::generic::stream_protocol

These classes implement the Protocol type requirements, but allow the
user to specify the address family (e.g. AF_INET) and protocol type
(e.g. IPPROTO_TCP) at runtime.

A new endpoint class template, asio::generic::basic_endpoint, has been
added to support these new protocol classes. This endpoint can hold any
other endpoint type, provided its native representation fits into a
sockaddr_storage object.

When using C++11, it is now possible to perform move construction from a
socket (or acceptor) object to convert to the more generic protocol's
socket (or acceptor) type. If the protocol conversion is valid:

  Protocol1 p1 = ...;
  Protocol2 p2(p1);

then the corresponding socket conversion is allowed:

  Protocol1::socket socket1(io_service);
  ...
  Protocol2::socket socket2(std::move(socket1));

For example, one possible conversion is from a TCP socket to a generic
stream-oriented socket:

  asio::ip::tcp::socket socket1(io_service);
  ...
  asio::generic::stream_protocol::socket socket2(std::move(socket1));

The conversion is also available for move-assignment. Note that these
conversions are not limited to the newly added generic protocol classes.
User-defined protocols may take advantage of this feature by similarly
ensuring the conversion from Protocol1 to Protocol2 is valid, as above.

As a convenience, the socket acceptor's accept() and async_accept()
functions have been changed so that they can directly accept into a
different protocol's socket type, provided the protocol conversion is
valid. For example, the following is now possible:

  asio::ip::tcp::acceptor acceptor(io_service);
  ...
  asio::generic::stream_protocol::socket socket1(io_service);
  acceptor.accept(socket1);
diff --git a/asio/boostify.pl b/asio/boostify.pl
index 03b3649..1beadd0 100755
--- a/asio/boostify.pl
+++ b/asio/boostify.pl
@@ -332,6 +332,9 @@
       "include/asio",
       "include/asio/detail",
       "include/asio/detail/impl",
+      "include/asio/generic",
+      "include/asio/generic/detail",
+      "include/asio/generic/detail/impl",
       "include/asio/impl",
       "include/asio/ip",
       "include/asio/ip/impl",
@@ -389,6 +392,7 @@
   my @dirs = (
       "src/tests/unit",
       "src/tests/unit/archetypes",
+      "src/tests/unit/generic",
       "src/tests/unit/ip",
       "src/tests/unit/local",
       "src/tests/unit/posix",
diff --git a/asio/include/Makefile.am b/asio/include/Makefile.am
index e573d6f..fa32331 100644
--- a/asio/include/Makefile.am
+++ b/asio/include/Makefile.am
@@ -238,6 +238,13 @@
 	asio/detail/wrapped_handler.hpp \
 	asio/error_code.hpp \
 	asio/error.hpp \
+	asio/generic/basic_endpoint.hpp \
+	asio/generic/datagram_protocol.hpp \
+	asio/generic/detail/endpoint.hpp \
+	asio/generic/detail/impl/endpoint.ipp \
+	asio/generic/raw_protocol.hpp \
+	asio/generic/seq_packet_protocol.hpp \
+	asio/generic/stream_protocol.hpp \
 	asio/handler_alloc_hook.hpp \
 	asio/handler_continuation_hook.hpp \
 	asio/handler_invoke_hook.hpp \
diff --git a/asio/include/asio.hpp b/asio/include/asio.hpp
index 0664728..02cd1d5 100644
--- a/asio/include/asio.hpp
+++ b/asio/include/asio.hpp
@@ -45,6 +45,11 @@
 #include "asio/deadline_timer.hpp"
 #include "asio/error.hpp"
 #include "asio/error_code.hpp"
+#include "asio/generic/basic_endpoint.hpp"
+#include "asio/generic/datagram_protocol.hpp"
+#include "asio/generic/raw_protocol.hpp"
+#include "asio/generic/seq_packet_protocol.hpp"
+#include "asio/generic/stream_protocol.hpp"
 #include "asio/handler_alloc_hook.hpp"
 #include "asio/handler_continuation_hook.hpp"
 #include "asio/handler_invoke_hook.hpp"
diff --git a/asio/include/asio/basic_datagram_socket.hpp b/asio/include/asio/basic_datagram_socket.hpp
index 75005f8..6d9b4b6 100644
--- a/asio/include/asio/basic_datagram_socket.hpp
+++ b/asio/include/asio/basic_datagram_socket.hpp
@@ -21,6 +21,7 @@
 #include "asio/datagram_socket_service.hpp"
 #include "asio/detail/handler_type_requirements.hpp"
 #include "asio/detail/throw_error.hpp"
+#include "asio/detail/type_traits.hpp"
 #include "asio/error.hpp"
 
 #include "asio/detail/push_options.hpp"
@@ -165,6 +166,50 @@
         ASIO_MOVE_CAST(basic_datagram_socket)(other));
     return *this;
   }
+
+  /// Move-construct a basic_datagram_socket from a socket of another protocol
+  /// type.
+  /**
+   * This constructor moves a datagram socket from one object to another.
+   *
+   * @param other The other basic_datagram_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_datagram_socket(io_service&) constructor.
+   */
+  template <typename Protocol1, typename DatagramSocketService1>
+  basic_datagram_socket(
+      basic_datagram_socket<Protocol1, DatagramSocketService1>&& other,
+      typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
+    : basic_socket<Protocol, DatagramSocketService>(
+        ASIO_MOVE_CAST2(basic_datagram_socket<
+          Protocol1, DatagramSocketService1>)(other))
+  {
+  }
+
+  /// Move-assign a basic_datagram_socket from a socket of another protocol
+  /// type.
+  /**
+   * This assignment operator moves a datagram socket from one object to
+   * another.
+   *
+   * @param other The other basic_datagram_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_datagram_socket(io_service&) constructor.
+   */
+  template <typename Protocol1, typename DatagramSocketService1>
+  typename enable_if<is_convertible<Protocol1, Protocol>::value,
+      basic_datagram_socket>::type& operator=(
+        basic_datagram_socket<Protocol1, DatagramSocketService1>&& other)
+  {
+    basic_socket<Protocol, DatagramSocketService>::operator=(
+        ASIO_MOVE_CAST2(basic_datagram_socket<
+          Protocol1, DatagramSocketService1>)(other));
+    return *this;
+  }
 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
 
   /// Send some data on a connected socket.
diff --git a/asio/include/asio/basic_raw_socket.hpp b/asio/include/asio/basic_raw_socket.hpp
index db144c6..33c1530 100644
--- a/asio/include/asio/basic_raw_socket.hpp
+++ b/asio/include/asio/basic_raw_socket.hpp
@@ -20,6 +20,7 @@
 #include "asio/basic_socket.hpp"
 #include "asio/detail/handler_type_requirements.hpp"
 #include "asio/detail/throw_error.hpp"
+#include "asio/detail/type_traits.hpp"
 #include "asio/error.hpp"
 #include "asio/raw_socket_service.hpp"
 
@@ -164,6 +165,46 @@
         ASIO_MOVE_CAST(basic_raw_socket)(other));
     return *this;
   }
+
+  /// Move-construct a basic_raw_socket from a socket of another protocol type.
+  /**
+   * This constructor moves a raw socket from one object to another.
+   *
+   * @param other The other basic_raw_socket object from which the move will
+   * occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_raw_socket(io_service&) constructor.
+   */
+  template <typename Protocol1, typename RawSocketService1>
+  basic_raw_socket(basic_raw_socket<Protocol1, RawSocketService1>&& other,
+      typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
+    : basic_socket<Protocol, RawSocketService>(
+        ASIO_MOVE_CAST2(basic_raw_socket<
+          Protocol1, RawSocketService1>)(other))
+  {
+  }
+
+  /// Move-assign a basic_raw_socket from a socket of another protocol type.
+  /**
+   * This assignment operator moves a raw socket from one object to another.
+   *
+   * @param other The other basic_raw_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_raw_socket(io_service&) constructor.
+   */
+  template <typename Protocol1, typename RawSocketService1>
+  typename enable_if<is_convertible<Protocol1, Protocol>::value,
+      basic_raw_socket>::type& operator=(
+        basic_raw_socket<Protocol1, RawSocketService1>&& other)
+  {
+    basic_socket<Protocol, RawSocketService>::operator=(
+        ASIO_MOVE_CAST2(basic_raw_socket<
+          Protocol1, RawSocketService1>)(other));
+    return *this;
+  }
 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
 
   /// Send some data on a connected socket.
diff --git a/asio/include/asio/basic_seq_packet_socket.hpp b/asio/include/asio/basic_seq_packet_socket.hpp
index 17f1bad..74d3976 100644
--- a/asio/include/asio/basic_seq_packet_socket.hpp
+++ b/asio/include/asio/basic_seq_packet_socket.hpp
@@ -170,6 +170,51 @@
         ASIO_MOVE_CAST(basic_seq_packet_socket)(other));
     return *this;
   }
+
+  /// Move-construct a basic_seq_packet_socket from a socket of another protocol
+  /// type.
+  /**
+   * This constructor moves a sequenced packet socket from one object to
+   * another.
+   *
+   * @param other The other basic_seq_packet_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_seq_packet_socket(io_service&) constructor.
+   */
+  template <typename Protocol1, typename SeqPacketSocketService1>
+  basic_seq_packet_socket(
+      basic_seq_packet_socket<Protocol1, SeqPacketSocketService1>&& other,
+      typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
+    : basic_socket<Protocol, SeqPacketSocketService>(
+        ASIO_MOVE_CAST2(basic_seq_packet_socket<
+          Protocol1, SeqPacketSocketService1>)(other))
+  {
+  }
+
+  /// Move-assign a basic_seq_packet_socket from a socket of another protocol
+  /// type.
+  /**
+   * This assignment operator moves a sequenced packet socket from one object to
+   * another.
+   *
+   * @param other The other basic_seq_packet_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_seq_packet_socket(io_service&) constructor.
+   */
+  template <typename Protocol1, typename SeqPacketSocketService1>
+  typename enable_if<is_convertible<Protocol1, Protocol>::value,
+      basic_seq_packet_socket>::type& operator=(
+        basic_seq_packet_socket<Protocol1, SeqPacketSocketService1>&& other)
+  {
+    basic_socket<Protocol, SeqPacketSocketService>::operator=(
+        ASIO_MOVE_CAST2(basic_seq_packet_socket<
+          Protocol1, SeqPacketSocketService1>)(other));
+    return *this;
+  }
 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
 
   /// Send some data on the socket.
diff --git a/asio/include/asio/basic_socket.hpp b/asio/include/asio/basic_socket.hpp
index 3407e76..64f55b4 100644
--- a/asio/include/asio/basic_socket.hpp
+++ b/asio/include/asio/basic_socket.hpp
@@ -20,6 +20,7 @@
 #include "asio/basic_io_object.hpp"
 #include "asio/detail/handler_type_requirements.hpp"
 #include "asio/detail/throw_error.hpp"
+#include "asio/detail/type_traits.hpp"
 #include "asio/error.hpp"
 #include "asio/socket_base.hpp"
 
@@ -173,6 +174,51 @@
         ASIO_MOVE_CAST(basic_socket)(other));
     return *this;
   }
+
+  // All sockets have access to each other's implementations.
+  template <typename Protocol1, typename SocketService1>
+  friend class basic_socket;
+
+  /// Move-construct a basic_socket from a socket of another protocol type.
+  /**
+   * This constructor moves a socket from one object to another.
+   *
+   * @param other The other basic_socket object from which the move will
+   * occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_socket(io_service&) constructor.
+   */
+  template <typename Protocol1, typename SocketService1>
+  basic_socket(basic_socket<Protocol1, SocketService1>&& other,
+      typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
+    : basic_io_object<SocketService>(other.get_io_service())
+  {
+    this->get_service().template converting_move_construct<Protocol1>(
+        this->get_implementation(), other.get_implementation());
+  }
+
+  /// Move-assign a basic_socket from a socket of another protocol type.
+  /**
+   * This assignment operator moves a socket from one object to another.
+   *
+   * @param other The other basic_socket object from which the move will
+   * occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_socket(io_service&) constructor.
+   */
+  template <typename Protocol1, typename SocketService1>
+  typename enable_if<is_convertible<Protocol1, Protocol>::value,
+      basic_socket>::type& operator=(
+        basic_socket<Protocol1, SocketService1>&& other)
+  {
+    basic_socket tmp(ASIO_MOVE_CAST2(basic_socket<
+            Protocol1, SocketService1>)(other));
+    basic_io_object<SocketService>::operator=(
+        ASIO_MOVE_CAST(basic_socket)(tmp));
+    return *this;
+  }
 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
 
   /// Get a reference to the lowest layer.
diff --git a/asio/include/asio/basic_socket_acceptor.hpp b/asio/include/asio/basic_socket_acceptor.hpp
index d8a395a..5606c51 100644
--- a/asio/include/asio/basic_socket_acceptor.hpp
+++ b/asio/include/asio/basic_socket_acceptor.hpp
@@ -20,6 +20,7 @@
 #include "asio/basic_socket.hpp"
 #include "asio/detail/handler_type_requirements.hpp"
 #include "asio/detail/throw_error.hpp"
+#include "asio/detail/type_traits.hpp"
 #include "asio/error.hpp"
 #include "asio/socket_acceptor_service.hpp"
 #include "asio/socket_base.hpp"
@@ -210,6 +211,54 @@
         ASIO_MOVE_CAST(basic_socket_acceptor)(other));
     return *this;
   }
+
+  // All socket acceptors have access to each other's implementations.
+  template <typename Protocol1, typename SocketAcceptorService1>
+  friend class basic_socket_acceptor;
+
+  /// Move-construct a basic_socket_acceptor from an acceptor of another
+  /// protocol type.
+  /**
+   * This constructor moves an acceptor from one object to another.
+   *
+   * @param other The other basic_socket_acceptor object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_socket(io_service&) constructor.
+   */
+  template <typename Protocol1, typename SocketAcceptorService1>
+  basic_socket_acceptor(
+      basic_socket_acceptor<Protocol1, SocketAcceptorService1>&& other,
+      typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
+    : basic_io_object<SocketAcceptorService>(other.get_io_service())
+  {
+    this->get_service().template converting_move_construct<Protocol1>(
+        this->get_implementation(), other.get_implementation());
+  }
+
+  /// Move-assign a basic_socket_acceptor from an acceptor of another protocol
+  /// type.
+  /**
+   * This assignment operator moves an acceptor from one object to another.
+   *
+   * @param other The other basic_socket_acceptor object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_socket(io_service&) constructor.
+   */
+  template <typename Protocol1, typename SocketAcceptorService1>
+  typename enable_if<is_convertible<Protocol1, Protocol>::value,
+      basic_socket_acceptor>::type& operator=(
+        basic_socket_acceptor<Protocol1, SocketAcceptorService1>&& other)
+  {
+    basic_socket_acceptor tmp(ASIO_MOVE_CAST2(basic_socket_acceptor<
+            Protocol1, SocketAcceptorService1>)(other));
+    basic_io_object<SocketAcceptorService>::operator=(
+        ASIO_MOVE_CAST(basic_socket_acceptor)(tmp));
+    return *this;
+  }
 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
 
   /// Open the acceptor using the specified protocol.
@@ -870,11 +919,13 @@
    * acceptor.accept(socket);
    * @endcode
    */
-  template <typename SocketService>
-  void accept(basic_socket<protocol_type, SocketService>& peer)
+  template <typename Protocol1, typename SocketService>
+  void accept(basic_socket<Protocol1, SocketService>& peer,
+      typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
   {
     asio::error_code ec;
-    this->get_service().accept(this->get_implementation(), peer, 0, ec);
+    this->get_service().accept(this->get_implementation(),
+        peer, static_cast<endpoint_type*>(0), ec);
     asio::detail::throw_error(ec, "accept");
   }
 
@@ -901,12 +952,14 @@
    * }
    * @endcode
    */
-  template <typename SocketService>
+  template <typename Protocol1, typename SocketService>
   asio::error_code accept(
-      basic_socket<protocol_type, SocketService>& peer,
-      asio::error_code& ec)
+      basic_socket<Protocol1, SocketService>& peer,
+      asio::error_code& ec,
+      typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
   {
-    return this->get_service().accept(this->get_implementation(), peer, 0, ec);
+    return this->get_service().accept(this->get_implementation(),
+        peer, static_cast<endpoint_type*>(0), ec);
   }
 
   /// Start an asynchronous accept.
@@ -947,18 +1000,20 @@
    * acceptor.async_accept(socket, accept_handler);
    * @endcode
    */
-  template <typename SocketService, typename AcceptHandler>
+  template <typename Protocol1, typename SocketService, typename AcceptHandler>
   ASIO_INITFN_RESULT_TYPE(AcceptHandler,
       void (asio::error_code))
-  async_accept(basic_socket<protocol_type, SocketService>& peer,
-      ASIO_MOVE_ARG(AcceptHandler) handler)
+  async_accept(basic_socket<Protocol1, SocketService>& peer,
+      ASIO_MOVE_ARG(AcceptHandler) handler,
+      typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
   {
     // If you get an error on the following line it means that your handler does
     // not meet the documented type requirements for a AcceptHandler.
     ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
 
     return this->get_service().async_accept(this->get_implementation(),
-        peer, 0, ASIO_MOVE_CAST(AcceptHandler)(handler));
+        peer, static_cast<endpoint_type*>(0),
+        ASIO_MOVE_CAST(AcceptHandler)(handler));
   }
 
   /// Accept a new connection and obtain the endpoint of the peer
diff --git a/asio/include/asio/basic_stream_socket.hpp b/asio/include/asio/basic_stream_socket.hpp
index b370ddd..eaa86e6 100644
--- a/asio/include/asio/basic_stream_socket.hpp
+++ b/asio/include/asio/basic_stream_socket.hpp
@@ -166,6 +166,48 @@
         ASIO_MOVE_CAST(basic_stream_socket)(other));
     return *this;
   }
+
+  /// Move-construct a basic_stream_socket from a socket of another protocol
+  /// type.
+  /**
+   * This constructor moves a stream socket from one object to another.
+   *
+   * @param other The other basic_stream_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_stream_socket(io_service&) constructor.
+   */
+  template <typename Protocol1, typename StreamSocketService1>
+  basic_stream_socket(
+      basic_stream_socket<Protocol1, StreamSocketService1>&& other,
+      typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
+    : basic_socket<Protocol, StreamSocketService>(
+        ASIO_MOVE_CAST2(basic_stream_socket<
+          Protocol1, StreamSocketService1>)(other))
+  {
+  }
+
+  /// Move-assign a basic_stream_socket from a socket of another protocol type.
+  /**
+   * This assignment operator moves a stream socket from one object to another.
+   *
+   * @param other The other basic_stream_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_stream_socket(io_service&) constructor.
+   */
+  template <typename Protocol1, typename StreamSocketService1>
+  typename enable_if<is_convertible<Protocol1, Protocol>::value,
+      basic_stream_socket>::type& operator=(
+        basic_stream_socket<Protocol1, StreamSocketService1>&& other)
+  {
+    basic_socket<Protocol, StreamSocketService>::operator=(
+        ASIO_MOVE_CAST2(basic_stream_socket<
+          Protocol1, StreamSocketService1>)(other));
+    return *this;
+  }
 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
 
   /// Send some data on the socket.
diff --git a/asio/include/asio/datagram_socket_service.hpp b/asio/include/asio/datagram_socket_service.hpp
index 2c35c79..eb8ac5e 100644
--- a/asio/include/asio/datagram_socket_service.hpp
+++ b/asio/include/asio/datagram_socket_service.hpp
@@ -18,6 +18,7 @@
 #include "asio/detail/config.hpp"
 #include <cstddef>
 #include "asio/async_result.hpp"
+#include "asio/detail/type_traits.hpp"
 #include "asio/error.hpp"
 #include "asio/io_service.hpp"
 
@@ -111,6 +112,19 @@
   {
     service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
   }
+
+  /// Move-construct a new datagram socket implementation from another protocol
+  /// type.
+  template <typename Protocol1>
+  void converting_move_construct(implementation_type& impl,
+      typename datagram_socket_service<
+        Protocol1>::implementation_type& other_impl,
+      typename enable_if<is_convertible<
+        Protocol1, Protocol>::value>::type* = 0)
+  {
+    service_impl_.template converting_move_construct<Protocol1>(
+        impl, other_impl);
+  }
 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
 
   /// Destroy a datagram socket implementation.
diff --git a/asio/include/asio/detail/config.hpp b/asio/include/asio/detail/config.hpp
index ccc74bc..3b08aac 100644
--- a/asio/include/asio/detail/config.hpp
+++ b/asio/include/asio/detail/config.hpp
@@ -106,6 +106,7 @@
 #if defined(ASIO_HAS_MOVE) && !defined(ASIO_MOVE_CAST)
 # define ASIO_MOVE_ARG(type) type&&
 # define ASIO_MOVE_CAST(type) static_cast<type&&>
+# define ASIO_MOVE_CAST2(type1, type2) static_cast<type1, type2&&>
 #endif // defined(ASIO_HAS_MOVE) && !defined(ASIO_MOVE_CAST)
 
 // If ASIO_MOVE_CAST still isn't defined, default to a C++03-compatible
@@ -130,7 +131,8 @@
 #  define ASIO_MOVE_ARG(type) type
 # endif
 # define ASIO_MOVE_CAST(type) static_cast<const type&>
-#endif // !defined_ASIO_MOVE_CAST
+# define ASIO_MOVE_CAST2(type1, type2) static_cast<const type1, type2&>
+#endif // !defined(ASIO_MOVE_CAST)
 
 // Support variadic templates on compilers known to allow it.
 #if !defined(ASIO_HAS_VARIADIC_TEMPLATES)
diff --git a/asio/include/asio/detail/reactive_socket_service.hpp b/asio/include/asio/detail/reactive_socket_service.hpp
index 4ef4b3f..bcce254 100644
--- a/asio/include/asio/detail/reactive_socket_service.hpp
+++ b/asio/include/asio/detail/reactive_socket_service.hpp
@@ -98,6 +98,18 @@
     other_impl.protocol_ = endpoint_type().protocol();
   }
 
+  // Move-construct a new socket implementation from another protocol type.
+  template <typename Protocol1>
+  void converting_move_construct(implementation_type& impl,
+      typename reactive_socket_service<
+        Protocol1>::implementation_type& other_impl)
+  {
+    this->base_move_construct(impl, other_impl);
+
+    impl.protocol_ = protocol_type(other_impl.protocol_);
+    other_impl.protocol_ = typename Protocol1::endpoint().protocol();
+  }
+
   // Open a new socket implementation.
   asio::error_code open(implementation_type& impl,
       const protocol_type& protocol, asio::error_code& ec)
diff --git a/asio/include/asio/generic/basic_endpoint.hpp b/asio/include/asio/generic/basic_endpoint.hpp
new file mode 100644
index 0000000..77452b4
--- /dev/null
+++ b/asio/include/asio/generic/basic_endpoint.hpp
@@ -0,0 +1,193 @@
+//
+// generic/basic_endpoint.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef ASIO_GENERIC_BASIC_ENDPOINT_HPP
+#define ASIO_GENERIC_BASIC_ENDPOINT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+#include "asio/generic/detail/endpoint.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+namespace generic {
+
+/// Describes an endpoint for any socket type.
+/**
+ * The asio::generic::basic_endpoint class template describes an endpoint
+ * that may be associated with any socket type.
+ *
+ * @note The socket types sockaddr type must be able to fit into a
+ * @c sockaddr_storage structure.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ *
+ * @par Concepts:
+ * Endpoint.
+ */
+template <typename Protocol>
+class basic_endpoint
+{
+public:
+  /// The protocol type associated with the endpoint.
+  typedef Protocol protocol_type;
+
+  /// The type of the endpoint structure. This type is dependent on the
+  /// underlying implementation of the socket layer.
+#if defined(GENERATING_DOCUMENTATION)
+  typedef implementation_defined data_type;
+#else
+  typedef asio::detail::socket_addr_type data_type;
+#endif
+
+  /// Default constructor.
+  basic_endpoint()
+  {
+  }
+
+  /// Construct an endpoint from the specified socket address.
+  basic_endpoint(const void* socket_address,
+      std::size_t socket_address_size, int socket_protocol = 0)
+    : impl_(socket_address, socket_address_size, socket_protocol)
+  {
+  }
+
+  /// Construct an endpoint from the specific endpoint type.
+  template <typename Endpoint>
+  basic_endpoint(const Endpoint& endpoint)
+    : impl_(endpoint.data(), endpoint.size(), endpoint.protocol().protocol())
+  {
+  }
+
+  /// Copy constructor.
+  basic_endpoint(const basic_endpoint& other)
+    : impl_(other.impl_)
+  {
+  }
+
+#if defined(ASIO_HAS_MOVE)
+  /// Move constructor.
+  basic_endpoint(basic_endpoint&& other)
+    : impl_(other.impl_)
+  {
+  }
+#endif // defined(ASIO_HAS_MOVE)
+
+  /// Assign from another endpoint.
+  basic_endpoint& operator=(const basic_endpoint& other)
+  {
+    impl_ = other.impl_;
+    return *this;
+  }
+
+#if defined(ASIO_HAS_MOVE)
+  /// Move-assign from another endpoint.
+  basic_endpoint& operator=(basic_endpoint&& other)
+  {
+    impl_ = other.impl_;
+    return *this;
+  }
+#endif // defined(ASIO_HAS_MOVE)
+
+  /// The protocol associated with the endpoint.
+  protocol_type protocol() const
+  {
+    return protocol_type(impl_.family(), impl_.protocol());
+  }
+
+  /// Get the underlying endpoint in the native type.
+  data_type* data()
+  {
+    return impl_.data();
+  }
+
+  /// Get the underlying endpoint in the native type.
+  const data_type* data() const
+  {
+    return impl_.data();
+  }
+
+  /// Get the underlying size of the endpoint in the native type.
+  std::size_t size() const
+  {
+    return impl_.size();
+  }
+
+  /// Set the underlying size of the endpoint in the native type.
+  void resize(std::size_t new_size)
+  {
+    impl_.resize(new_size);
+  }
+
+  /// Get the capacity of the endpoint in the native type.
+  std::size_t capacity() const
+  {
+    return impl_.capacity();
+  }
+
+  /// Compare two endpoints for equality.
+  friend bool operator==(const basic_endpoint<Protocol>& e1,
+      const basic_endpoint<Protocol>& e2)
+  {
+    return e1.impl_ == e2.impl_;
+  }
+
+  /// Compare two endpoints for inequality.
+  friend bool operator!=(const basic_endpoint<Protocol>& e1,
+      const basic_endpoint<Protocol>& e2)
+  {
+    return !(e1.impl_ == e2.impl_);
+  }
+
+  /// Compare endpoints for ordering.
+  friend bool operator<(const basic_endpoint<Protocol>& e1,
+      const basic_endpoint<Protocol>& e2)
+  {
+    return e1.impl_ < e2.impl_;
+  }
+
+  /// Compare endpoints for ordering.
+  friend bool operator>(const basic_endpoint<Protocol>& e1,
+      const basic_endpoint<Protocol>& e2)
+  {
+    return e2.impl_ < e1.impl_;
+  }
+
+  /// Compare endpoints for ordering.
+  friend bool operator<=(const basic_endpoint<Protocol>& e1,
+      const basic_endpoint<Protocol>& e2)
+  {
+    return !(e2 < e1);
+  }
+
+  /// Compare endpoints for ordering.
+  friend bool operator>=(const basic_endpoint<Protocol>& e1,
+      const basic_endpoint<Protocol>& e2)
+  {
+    return !(e1 < e2);
+  }
+
+private:
+  // The underlying generic endpoint.
+  asio::generic::detail::endpoint impl_;
+};
+
+} // namespace generic
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_GENERIC_BASIC_ENDPOINT_HPP
diff --git a/asio/include/asio/generic/datagram_protocol.hpp b/asio/include/asio/generic/datagram_protocol.hpp
new file mode 100644
index 0000000..6370bc6
--- /dev/null
+++ b/asio/include/asio/generic/datagram_protocol.hpp
@@ -0,0 +1,123 @@
+//
+// generic/datagram_protocol.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef ASIO_GENERIC_DATAGRAM_PROTOCOL_HPP
+#define ASIO_GENERIC_DATAGRAM_PROTOCOL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+
+#include <typeinfo>
+#include "asio/basic_datagram_socket.hpp"
+#include "asio/detail/socket_types.hpp"
+#include "asio/detail/throw_exception.hpp"
+#include "asio/generic/basic_endpoint.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+namespace generic {
+
+/// Encapsulates the flags needed for a generic datagram-oriented socket.
+/**
+ * The asio::generic::datagram_protocol class contains flags necessary
+ * for datagram-oriented sockets of any address family and protocol.
+ *
+ * @par Examples
+ * Constructing using a native address family and socket protocol:
+ * @code datagram_protocol p(AF_INET, IPPROTO_UDP); @endcode
+ * Constructing from a specific protocol type:
+ * @code datagram_protocol p(asio::ip::udp::v4()); @endcode
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Safe.
+ *
+ * @par Concepts:
+ * Protocol.
+ */
+class datagram_protocol
+{
+public:
+  /// Construct a protocol object for a specific address family and protocol.
+  datagram_protocol(int address_family, int socket_protocol)
+    : family_(address_family),
+      protocol_(socket_protocol)
+  {
+  }
+
+  /// Construct a generic protocol object from a specific protocol.
+  /**
+   * @throws @c bad_cast Thrown if the source protocol is not datagram-oriented.
+   */
+  template <typename Protocol>
+  datagram_protocol(const Protocol& source_protocol)
+    : family_(source_protocol.family()),
+      protocol_(source_protocol.protocol())
+  {
+    if (source_protocol.type() != type())
+    {
+      std::bad_cast ex;
+      asio::detail::throw_exception(ex);
+    }
+  }
+
+  /// Obtain an identifier for the type of the protocol.
+  int type() const
+  {
+    return SOCK_DGRAM;
+  }
+
+  /// Obtain an identifier for the protocol.
+  int protocol() const
+  {
+    return protocol_;
+  }
+
+  /// Obtain an identifier for the protocol family.
+  int family() const
+  {
+    return family_;
+  }
+
+  /// Compare two protocols for equality.
+  friend bool operator==(const datagram_protocol& p1,
+      const datagram_protocol& p2)
+  {
+    return p1.family_ == p2.family_ && p1.protocol_ == p2.protocol_;
+  }
+
+  /// Compare two protocols for inequality.
+  friend bool operator!=(const datagram_protocol& p1,
+      const datagram_protocol& p2)
+  {
+    return !(p1 == p2);
+  }
+
+  /// The type of an endpoint.
+  typedef basic_endpoint<datagram_protocol> endpoint;
+
+  /// The generic socket type.
+  typedef basic_datagram_socket<datagram_protocol> socket;
+
+private:
+  int family_;
+  int protocol_;
+};
+
+} // namespace generic
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_GENERIC_DATAGRAM_PROTOCOL_HPP
diff --git a/asio/include/asio/generic/detail/endpoint.hpp b/asio/include/asio/generic/detail/endpoint.hpp
new file mode 100644
index 0000000..b9415ae
--- /dev/null
+++ b/asio/include/asio/generic/detail/endpoint.hpp
@@ -0,0 +1,133 @@
+//
+// generic/detail/endpoint.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef ASIO_GENERIC_DETAIL_ENDPOINT_HPP
+#define ASIO_GENERIC_DETAIL_ENDPOINT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+
+#include <cstddef>
+#include "asio/detail/socket_types.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+namespace generic {
+namespace detail {
+
+// Helper class for implementing a generic socket endpoint.
+class endpoint
+{
+public:
+  // Default constructor.
+  ASIO_DECL endpoint();
+
+  // Construct an endpoint from the specified raw bytes.
+  ASIO_DECL endpoint(const void* sock_addr,
+      std::size_t sock_addr_size, int sock_protocol);
+
+  // Copy constructor.
+  endpoint(const endpoint& other)
+    : data_(other.data_),
+      size_(other.size_),
+      protocol_(other.protocol_)
+  {
+  }
+
+  // Assign from another endpoint.
+  endpoint& operator=(const endpoint& other)
+  {
+    data_ = other.data_;
+    size_ = other.size_;
+    protocol_ = other.protocol_;
+    return *this;
+  }
+
+  // Get the address family associated with the endpoint.
+  int family() const
+  {
+    return data_.base.sa_family;
+  }
+
+  // Get the socket protocol associated with the endpoint.
+  int protocol() const
+  {
+    return protocol_;
+  }
+
+  // Get the underlying endpoint in the native type.
+  asio::detail::socket_addr_type* data()
+  {
+    return &data_.base;
+  }
+
+  // Get the underlying endpoint in the native type.
+  const asio::detail::socket_addr_type* data() const
+  {
+    return &data_.base;
+  }
+
+  // Get the underlying size of the endpoint in the native type.
+  std::size_t size() const
+  {
+    return size_;
+  }
+
+  // Set the underlying size of the endpoint in the native type.
+  ASIO_DECL void resize(std::size_t size);
+
+  // Get the capacity of the endpoint in the native type.
+  std::size_t capacity() const
+  {
+    return sizeof(asio::detail::sockaddr_storage_type);
+  }
+
+  // Compare two endpoints for equality.
+  ASIO_DECL friend bool operator==(
+      const endpoint& e1, const endpoint& e2);
+
+  // Compare endpoints for ordering.
+  ASIO_DECL friend bool operator<(
+      const endpoint& e1, const endpoint& e2);
+
+private:
+  // The underlying socket address.
+  union data_union
+  {
+    asio::detail::socket_addr_type base;
+    asio::detail::sockaddr_storage_type generic;
+  } data_;
+
+  // The length of the socket address stored in the endpoint.
+  std::size_t size_;
+
+  // The socket protocol associated with the endpoint.
+  int protocol_;
+
+  // Initialise with a specified memory.
+  ASIO_DECL void init(const void* sock_addr,
+      std::size_t sock_addr_size, int sock_protocol);
+};
+
+} // namespace detail
+} // namespace generic
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#if defined(ASIO_HEADER_ONLY)
+# include "asio/generic/detail/impl/endpoint.ipp"
+#endif // defined(ASIO_HEADER_ONLY)
+
+#endif // ASIO_GENERIC_DETAIL_ENDPOINT_HPP
diff --git a/asio/include/asio/generic/detail/impl/endpoint.ipp b/asio/include/asio/generic/detail/impl/endpoint.ipp
new file mode 100644
index 0000000..8399d95
--- /dev/null
+++ b/asio/include/asio/generic/detail/impl/endpoint.ipp
@@ -0,0 +1,109 @@
+//
+// generic/detail/impl/endpoint.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef ASIO_GENERIC_DETAIL_IMPL_ENDPOINT_IPP
+#define ASIO_GENERIC_DETAIL_IMPL_ENDPOINT_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+
+#include <cstring>
+#include <typeinfo>
+#include "asio/detail/socket_ops.hpp"
+#include "asio/detail/throw_error.hpp"
+#include "asio/detail/throw_exception.hpp"
+#include "asio/error.hpp"
+#include "asio/generic/detail/endpoint.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+namespace generic {
+namespace detail {
+
+endpoint::endpoint()
+{
+  init(0, 0, 0);
+}
+
+endpoint::endpoint(const void* sock_addr,
+    std::size_t sock_addr_size, int sock_protocol)
+{
+  init(sock_addr, sock_addr_size, sock_protocol);
+}
+
+void endpoint::resize(std::size_t new_size)
+{
+  if (new_size > sizeof(asio::detail::sockaddr_storage_type))
+  {
+    asio::error_code ec(asio::error::invalid_argument);
+    asio::detail::throw_error(ec);
+  }
+  else
+  {
+    size_ = new_size;
+    protocol_ = 0;
+  }
+}
+
+bool operator==(const endpoint& e1, const endpoint& e2)
+{
+  using namespace std; // For memcmp.
+  return e1.size() == e2.size() && memcmp(e1.data(), e2.data(), e1.size()) == 0;
+}
+
+bool operator<(const endpoint& e1, const endpoint& e2)
+{
+  if (e1.protocol() < e2.protocol())
+    return true;
+
+  if (e1.protocol() > e2.protocol())
+    return false;
+
+  using namespace std; // For memcmp.
+  std::size_t compare_size = e1.size() < e2.size() ? e1.size() : e2.size();
+  int compare_result = memcmp(e1.data(), e2.data(), compare_size);
+
+  if (compare_result < 0)
+    return true;
+
+  if (compare_result > 0)
+    return false;
+
+  return e1.size() < e2.size();
+}
+
+void endpoint::init(const void* sock_addr,
+    std::size_t sock_addr_size, int sock_protocol)
+{
+  if (sock_addr_size > sizeof(asio::detail::sockaddr_storage_type))
+  {
+    asio::error_code ec(asio::error::invalid_argument);
+    asio::detail::throw_error(ec);
+  }
+
+  using namespace std; // For memset and memcpy.
+  memset(&data_.generic, 0, sizeof(asio::detail::sockaddr_storage_type));
+  memcpy(&data_.generic, sock_addr, sock_addr_size);
+
+  size_ = sock_addr_size;
+  protocol_ = sock_protocol;
+}
+
+} // namespace detail
+} // namespace generic
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_GENERIC_DETAIL_IMPL_ENDPOINT_IPP
diff --git a/asio/include/asio/generic/raw_protocol.hpp b/asio/include/asio/generic/raw_protocol.hpp
new file mode 100644
index 0000000..e054a7f
--- /dev/null
+++ b/asio/include/asio/generic/raw_protocol.hpp
@@ -0,0 +1,121 @@
+//
+// generic/raw_protocol.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef ASIO_GENERIC_RAW_PROTOCOL_HPP
+#define ASIO_GENERIC_RAW_PROTOCOL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+
+#include <typeinfo>
+#include "asio/basic_raw_socket.hpp"
+#include "asio/detail/socket_types.hpp"
+#include "asio/detail/throw_exception.hpp"
+#include "asio/generic/basic_endpoint.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+namespace generic {
+
+/// Encapsulates the flags needed for a generic raw socket.
+/**
+ * The asio::generic::raw_protocol class contains flags necessary for
+ * raw sockets of any address family and protocol.
+ *
+ * @par Examples
+ * Constructing using a native address family and socket protocol:
+ * @code raw_protocol p(AF_INET, IPPROTO_ICMP); @endcode
+ * Constructing from a specific protocol type:
+ * @code raw_protocol p(asio::ip::icmp::v4()); @endcode
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Safe.
+ *
+ * @par Concepts:
+ * Protocol.
+ */
+class raw_protocol
+{
+public:
+  /// Construct a protocol object for a specific address family and protocol.
+  raw_protocol(int address_family, int socket_protocol)
+    : family_(address_family),
+      protocol_(socket_protocol)
+  {
+  }
+
+  /// Construct a generic protocol object from a specific protocol.
+  /**
+   * @throws @c bad_cast Thrown if the source protocol is not raw-oriented.
+   */
+  template <typename Protocol>
+  raw_protocol(const Protocol& source_protocol)
+    : family_(source_protocol.family()),
+      protocol_(source_protocol.protocol())
+  {
+    if (source_protocol.type() != type())
+    {
+      std::bad_cast ex;
+      asio::detail::throw_exception(ex);
+    }
+  }
+
+  /// Obtain an identifier for the type of the protocol.
+  int type() const
+  {
+    return SOCK_RAW;
+  }
+
+  /// Obtain an identifier for the protocol.
+  int protocol() const
+  {
+    return protocol_;
+  }
+
+  /// Obtain an identifier for the protocol family.
+  int family() const
+  {
+    return family_;
+  }
+
+  /// Compare two protocols for equality.
+  friend bool operator==(const raw_protocol& p1, const raw_protocol& p2)
+  {
+    return p1.family_ == p2.family_ && p1.protocol_ == p2.protocol_;
+  }
+
+  /// Compare two protocols for inequality.
+  friend bool operator!=(const raw_protocol& p1, const raw_protocol& p2)
+  {
+    return !(p1 == p2);
+  }
+
+  /// The type of an endpoint.
+  typedef basic_endpoint<raw_protocol> endpoint;
+
+  /// The generic socket type.
+  typedef basic_raw_socket<raw_protocol> socket;
+
+private:
+  int family_;
+  int protocol_;
+};
+
+} // namespace generic
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_GENERIC_RAW_PROTOCOL_HPP
diff --git a/asio/include/asio/generic/seq_packet_protocol.hpp b/asio/include/asio/generic/seq_packet_protocol.hpp
new file mode 100644
index 0000000..fdd068d
--- /dev/null
+++ b/asio/include/asio/generic/seq_packet_protocol.hpp
@@ -0,0 +1,122 @@
+//
+// generic/seq_packet_protocol.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef ASIO_GENERIC_SEQ_PACKET_PROTOCOL_HPP
+#define ASIO_GENERIC_SEQ_PACKET_PROTOCOL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+
+#include <typeinfo>
+#include "asio/basic_seq_packet_socket.hpp"
+#include "asio/detail/socket_types.hpp"
+#include "asio/detail/throw_exception.hpp"
+#include "asio/generic/basic_endpoint.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+namespace generic {
+
+/// Encapsulates the flags needed for a generic sequenced packet socket.
+/**
+ * The asio::generic::seq_packet_protocol class contains flags necessary
+ * for seq_packet-oriented sockets of any address family and protocol.
+ *
+ * @par Examples
+ * Constructing using a native address family and socket protocol:
+ * @code seq_packet_protocol p(AF_INET, IPPROTO_SCTP); @endcode
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Safe.
+ *
+ * @par Concepts:
+ * Protocol.
+ */
+class seq_packet_protocol
+{
+public:
+  /// Construct a protocol object for a specific address family and protocol.
+  seq_packet_protocol(int address_family, int socket_protocol)
+    : family_(address_family),
+      protocol_(socket_protocol)
+  {
+  }
+
+  /// Construct a generic protocol object from a specific protocol.
+  /**
+   * @throws @c bad_cast Thrown if the source protocol is not based around
+   * sequenced packets.
+   */
+  template <typename Protocol>
+  seq_packet_protocol(const Protocol& source_protocol)
+    : family_(source_protocol.family()),
+      protocol_(source_protocol.protocol())
+  {
+    if (source_protocol.type() != type())
+    {
+      std::bad_cast ex;
+      asio::detail::throw_exception(ex);
+    }
+  }
+
+  /// Obtain an identifier for the type of the protocol.
+  int type() const
+  {
+    return SOCK_SEQPACKET;
+  }
+
+  /// Obtain an identifier for the protocol.
+  int protocol() const
+  {
+    return protocol_;
+  }
+
+  /// Obtain an identifier for the protocol family.
+  int family() const
+  {
+    return family_;
+  }
+
+  /// Compare two protocols for equality.
+  friend bool operator==(const seq_packet_protocol& p1,
+      const seq_packet_protocol& p2)
+  {
+    return p1.family_ == p2.family_ && p1.protocol_ == p2.protocol_;
+  }
+
+  /// Compare two protocols for inequality.
+  friend bool operator!=(const seq_packet_protocol& p1,
+      const seq_packet_protocol& p2)
+  {
+    return !(p1 == p2);
+  }
+
+  /// The type of an endpoint.
+  typedef basic_endpoint<seq_packet_protocol> endpoint;
+
+  /// The generic socket type.
+  typedef basic_seq_packet_socket<seq_packet_protocol> socket;
+
+private:
+  int family_;
+  int protocol_;
+};
+
+} // namespace generic
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_GENERIC_SEQ_PACKET_PROTOCOL_HPP
diff --git a/asio/include/asio/generic/stream_protocol.hpp b/asio/include/asio/generic/stream_protocol.hpp
new file mode 100644
index 0000000..369071c
--- /dev/null
+++ b/asio/include/asio/generic/stream_protocol.hpp
@@ -0,0 +1,127 @@
+//
+// generic/stream_protocol.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef ASIO_GENERIC_STREAM_PROTOCOL_HPP
+#define ASIO_GENERIC_STREAM_PROTOCOL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include "asio/detail/config.hpp"
+
+#include <typeinfo>
+#include "asio/basic_socket_iostream.hpp"
+#include "asio/basic_stream_socket.hpp"
+#include "asio/detail/socket_types.hpp"
+#include "asio/detail/throw_exception.hpp"
+#include "asio/generic/basic_endpoint.hpp"
+
+#include "asio/detail/push_options.hpp"
+
+namespace asio {
+namespace generic {
+
+/// Encapsulates the flags needed for a generic stream-oriented socket.
+/**
+ * The asio::generic::stream_protocol class contains flags necessary for
+ * stream-oriented sockets of any address family and protocol.
+ *
+ * @par Examples
+ * Constructing using a native address family and socket protocol:
+ * @code stream_protocol p(AF_INET, IPPROTO_TCP); @endcode
+ * Constructing from a specific protocol type:
+ * @code stream_protocol p(asio::ip::tcp::v4()); @endcode
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Safe.
+ *
+ * @par Concepts:
+ * Protocol.
+ */
+class stream_protocol
+{
+public:
+  /// Construct a protocol object for a specific address family and protocol.
+  stream_protocol(int address_family, int socket_protocol)
+    : family_(address_family),
+      protocol_(socket_protocol)
+  {
+  }
+
+  /// Construct a generic protocol object from a specific protocol.
+  /**
+   * @throws @c bad_cast Thrown if the source protocol is not stream-oriented.
+   */
+  template <typename Protocol>
+  stream_protocol(const Protocol& source_protocol)
+    : family_(source_protocol.family()),
+      protocol_(source_protocol.protocol())
+  {
+    if (source_protocol.type() != type())
+    {
+      std::bad_cast ex;
+      asio::detail::throw_exception(ex);
+    }
+  }
+
+  /// Obtain an identifier for the type of the protocol.
+  int type() const
+  {
+    return SOCK_STREAM;
+  }
+
+  /// Obtain an identifier for the protocol.
+  int protocol() const
+  {
+    return protocol_;
+  }
+
+  /// Obtain an identifier for the protocol family.
+  int family() const
+  {
+    return family_;
+  }
+
+  /// Compare two protocols for equality.
+  friend bool operator==(const stream_protocol& p1, const stream_protocol& p2)
+  {
+    return p1.family_ == p2.family_ && p1.protocol_ == p2.protocol_;
+  }
+
+  /// Compare two protocols for inequality.
+  friend bool operator!=(const stream_protocol& p1, const stream_protocol& p2)
+  {
+    return !(p1 == p2);
+  }
+
+  /// The type of an endpoint.
+  typedef basic_endpoint<stream_protocol> endpoint;
+
+  /// The generic socket type.
+  typedef basic_stream_socket<stream_protocol> socket;
+
+#if !defined(ASIO_NO_IOSTREAM)
+  /// The generic socket iostream type.
+  typedef basic_socket_iostream<stream_protocol> iostream;
+#endif // !defined(ASIO_NO_IOSTREAM)
+
+private:
+  int family_;
+  int protocol_;
+};
+
+} // namespace generic
+} // namespace asio
+
+#include "asio/detail/pop_options.hpp"
+
+#endif // ASIO_GENERIC_STREAM_PROTOCOL_HPP
diff --git a/asio/include/asio/impl/src.hpp b/asio/include/asio/impl/src.hpp
index 7dd7c6b..1b3df96 100644
--- a/asio/include/asio/impl/src.hpp
+++ b/asio/include/asio/impl/src.hpp
@@ -60,6 +60,7 @@
 #include "asio/detail/impl/win_thread.ipp"
 #include "asio/detail/impl/win_tss_ptr.ipp"
 #include "asio/detail/impl/winsock_init.ipp"
+#include "asio/generic/detail/impl/endpoint.ipp"
 #include "asio/ip/impl/address.ipp"
 #include "asio/ip/impl/address_v4.ipp"
 #include "asio/ip/impl/address_v6.ipp"
diff --git a/asio/include/asio/raw_socket_service.hpp b/asio/include/asio/raw_socket_service.hpp
index 4a79f25..0dd63d5 100644
--- a/asio/include/asio/raw_socket_service.hpp
+++ b/asio/include/asio/raw_socket_service.hpp
@@ -18,6 +18,7 @@
 #include "asio/detail/config.hpp"
 #include <cstddef>
 #include "asio/async_result.hpp"
+#include "asio/detail/type_traits.hpp"
 #include "asio/error.hpp"
 #include "asio/io_service.hpp"
 
@@ -111,6 +112,19 @@
   {
     service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
   }
+
+  /// Move-construct a new raw socket implementation from another protocol
+  /// type.
+  template <typename Protocol1>
+  void converting_move_construct(implementation_type& impl,
+      typename raw_socket_service<
+        Protocol1>::implementation_type& other_impl,
+      typename enable_if<is_convertible<
+        Protocol1, Protocol>::value>::type* = 0)
+  {
+    service_impl_.template converting_move_construct<Protocol1>(
+        impl, other_impl);
+  }
 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
 
   /// Destroy a raw socket implementation.
diff --git a/asio/include/asio/seq_packet_socket_service.hpp b/asio/include/asio/seq_packet_socket_service.hpp
index 6f62c51..955a234 100644
--- a/asio/include/asio/seq_packet_socket_service.hpp
+++ b/asio/include/asio/seq_packet_socket_service.hpp
@@ -18,6 +18,7 @@
 #include "asio/detail/config.hpp"
 #include <cstddef>
 #include "asio/async_result.hpp"
+#include "asio/detail/type_traits.hpp"
 #include "asio/error.hpp"
 #include "asio/io_service.hpp"
 
@@ -113,6 +114,19 @@
   {
     service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
   }
+
+  /// Move-construct a new sequenced packet socket implementation from another
+  /// protocol type.
+  template <typename Protocol1>
+  void converting_move_construct(implementation_type& impl,
+      typename seq_packet_socket_service<
+        Protocol1>::implementation_type& other_impl,
+      typename enable_if<is_convertible<
+        Protocol1, Protocol>::value>::type* = 0)
+  {
+    service_impl_.template converting_move_construct<Protocol1>(
+        impl, other_impl);
+  }
 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
 
   /// Destroy a sequenced packet socket implementation.
diff --git a/asio/include/asio/socket_acceptor_service.hpp b/asio/include/asio/socket_acceptor_service.hpp
index 39e9587..d07fa52 100644
--- a/asio/include/asio/socket_acceptor_service.hpp
+++ b/asio/include/asio/socket_acceptor_service.hpp
@@ -17,6 +17,7 @@
 
 #include "asio/detail/config.hpp"
 #include "asio/basic_socket.hpp"
+#include "asio/detail/type_traits.hpp"
 #include "asio/error.hpp"
 #include "asio/io_service.hpp"
 
@@ -110,6 +111,19 @@
   {
     service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
   }
+
+  /// Move-construct a new socket acceptor implementation from another protocol
+  /// type.
+  template <typename Protocol1>
+  void converting_move_construct(implementation_type& impl,
+      typename socket_acceptor_service<
+        Protocol1>::implementation_type& other_impl,
+      typename enable_if<is_convertible<
+        Protocol1, Protocol>::value>::type* = 0)
+  {
+    service_impl_.template converting_move_construct<Protocol1>(
+        impl, other_impl);
+  }
 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
 
   /// Destroy a socket acceptor implementation.
@@ -238,22 +252,24 @@
   }
 
   /// Accept a new connection.
-  template <typename SocketService>
+  template <typename Protocol1, typename SocketService>
   asio::error_code accept(implementation_type& impl,
-      basic_socket<protocol_type, SocketService>& peer,
-      endpoint_type* peer_endpoint, asio::error_code& ec)
+      basic_socket<Protocol1, SocketService>& peer,
+      endpoint_type* peer_endpoint, asio::error_code& ec,
+      typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
   {
     return service_impl_.accept(impl, peer, peer_endpoint, ec);
   }
 
   /// Start an asynchronous accept.
-  template <typename SocketService, typename AcceptHandler>
+  template <typename Protocol1, typename SocketService, typename AcceptHandler>
   ASIO_INITFN_RESULT_TYPE(AcceptHandler,
       void (asio::error_code))
   async_accept(implementation_type& impl,
-      basic_socket<protocol_type, SocketService>& peer,
+      basic_socket<Protocol1, SocketService>& peer,
       endpoint_type* peer_endpoint,
-      ASIO_MOVE_ARG(AcceptHandler) handler)
+      ASIO_MOVE_ARG(AcceptHandler) handler,
+      typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
   {
     detail::async_result_init<
       AcceptHandler, void (asio::error_code)> init(
diff --git a/asio/include/asio/stream_socket_service.hpp b/asio/include/asio/stream_socket_service.hpp
index 3fc3d21..e94e731 100644
--- a/asio/include/asio/stream_socket_service.hpp
+++ b/asio/include/asio/stream_socket_service.hpp
@@ -18,6 +18,7 @@
 #include "asio/detail/config.hpp"
 #include <cstddef>
 #include "asio/async_result.hpp"
+#include "asio/detail/type_traits.hpp"
 #include "asio/error.hpp"
 #include "asio/io_service.hpp"
 
@@ -111,6 +112,19 @@
   {
     service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
   }
+
+  /// Move-construct a new stream socket implementation from another protocol
+  /// type.
+  template <typename Protocol1>
+  void converting_move_construct(implementation_type& impl,
+      typename stream_socket_service<
+        Protocol1>::implementation_type& other_impl,
+      typename enable_if<is_convertible<
+        Protocol1, Protocol>::value>::type* = 0)
+  {
+    service_impl_.template converting_move_construct<Protocol1>(
+        impl, other_impl);
+  }
 #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
 
   /// Destroy a stream socket implementation.
diff --git a/asio/src/Makefile.mgw b/asio/src/Makefile.mgw
index 655e79d..015da58 100644
--- a/asio/src/Makefile.mgw
+++ b/asio/src/Makefile.mgw
@@ -36,6 +36,11 @@
 	tests/unit/deadline_timer_service.exe \
 	tests/unit/deadline_timer.exe \
 	tests/unit/error.exe \
+	tests/unit/generic/basic_endpoint.exe \
+	tests/unit/generic/datagram_protocol.exe \
+	tests/unit/generic/raw_protocol.exe \
+	tests/unit/generic/seq_packet_protocol.exe \
+	tests/unit/generic/stream_protocol.exe \
 	tests/unit/high_resolution_timer.exe \
 	tests/unit/io_service.exe \
 	tests/unit/ip/address.exe \
diff --git a/asio/src/Makefile.msc b/asio/src/Makefile.msc
index 04cb776..ca491a1 100644
--- a/asio/src/Makefile.msc
+++ b/asio/src/Makefile.msc
@@ -106,6 +106,11 @@
 	tests\unit\deadline_timer_service.exe \
 	tests\unit\deadline_timer.exe \
 	tests\unit\error.exe \
+	tests\unit\generic\basic_endpoint.exe \
+	tests\unit\generic\datagram_protocol.exe \
+	tests\unit\generic\raw_protocol.exe \
+	tests\unit\generic\seq_packet_protocol.exe \
+	tests\unit\generic\stream_protocol.exe \
 	tests\unit\high_resolution_timer.exe \
 	tests\unit\io_service.exe \
 	tests\unit\ip\address.exe \
@@ -261,6 +266,9 @@
 {tests\unit}.cpp{tests\unit}.exe:
 	cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(UNIT_TEST_OBJ) $(LIBS) -link -opt:ref
 
+{tests\unit\generic}.cpp{tests\unit\generic}.exe:
+	cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(UNIT_TEST_OBJ) $(LIBS) -link -opt:ref
+
 {tests\unit\ip}.cpp{tests\unit\ip}.exe:
 	cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(UNIT_TEST_OBJ) $(LIBS) -link -opt:ref
 
diff --git a/asio/src/doc/reference.xsl b/asio/src/doc/reference.xsl
index 640e35f..24c6f03 100644
--- a/asio/src/doc/reference.xsl
+++ b/asio/src/doc/reference.xsl
@@ -1443,6 +1443,9 @@
         <xsl:when test="declname = 'Context_Service'">
           <xsl:value-of select="declname"/>
         </xsl:when>
+        <xsl:when test="declname = 'DatagramSocketService1'">
+          <xsl:value-of select="concat('``[link asio.reference.DatagramSocketService ', declname, ']``')"/>
+        </xsl:when>
         <xsl:when test="declname = 'Elem'">
           <xsl:value-of select="declname"/>
         </xsl:when>
@@ -1470,12 +1473,24 @@
         <xsl:when test="declname = 'PointerToPodType'">
           <xsl:value-of select="declname"/>
         </xsl:when>
+        <xsl:when test="declname = 'Protocol1'">
+          <xsl:value-of select="concat('``[link asio.reference.Protocol ', declname, ']``')"/>
+        </xsl:when>
+        <xsl:when test="declname = 'RawSocketService1'">
+          <xsl:value-of select="concat('``[link asio.reference.RawSocketService ', declname, ']``')"/>
+        </xsl:when>
+        <xsl:when test="declname = 'SeqPacketSocketService1'">
+          <xsl:value-of select="concat('``[link asio.reference.SeqPacketSocketService ', declname, ']``')"/>
+        </xsl:when>
         <xsl:when test="declname = 'SocketService1' or declname = 'SocketService2'">
           <xsl:value-of select="concat('``[link asio.reference.SocketService ', declname, ']``')"/>
         </xsl:when>
         <xsl:when test="declname = 'Stream'">
           <xsl:value-of select="declname"/>
         </xsl:when>
+        <xsl:when test="declname = 'StreamSocketService1'">
+          <xsl:value-of select="concat('``[link asio.reference.StreamSocketService ', declname, ']``')"/>
+        </xsl:when>
         <xsl:when test="declname = 'T'">
           <xsl:value-of select="declname"/>
         </xsl:when>
diff --git a/asio/src/tests/Makefile.am b/asio/src/tests/Makefile.am
index 0aeedef..f3d601e 100644
--- a/asio/src/tests/Makefile.am
+++ b/asio/src/tests/Makefile.am
@@ -32,6 +32,11 @@
 	unit/deadline_timer_service \
 	unit/deadline_timer \
 	unit/error \
+	unit/generic/basic_endpoint \
+	unit/generic/datagram_protocol \
+	unit/generic/raw_protocol \
+	unit/generic/seq_packet_protocol \
+	unit/generic/stream_protocol \
 	unit/high_resolution_timer \
 	unit/io_service \
 	unit/ip/address \
@@ -260,6 +265,11 @@
 unit_deadline_timer_service_SOURCES = unit/deadline_timer_service.cpp unit/unit_test.cpp
 unit_deadline_timer_SOURCES = unit/deadline_timer.cpp unit/unit_test.cpp
 unit_error_SOURCES = unit/error.cpp unit/unit_test.cpp
+unit_generic_basic_endpoint_SOURCES = unit/generic/basic_endpoint.cpp unit/unit_test.cpp
+unit_generic_datagram_protocol_SOURCES = unit/generic/datagram_protocol.cpp unit/unit_test.cpp
+unit_generic_raw_protocol_SOURCES = unit/generic/raw_protocol.cpp unit/unit_test.cpp
+unit_generic_seq_packet_protocol_SOURCES = unit/generic/seq_packet_protocol.cpp unit/unit_test.cpp
+unit_generic_stream_protocol_SOURCES = unit/generic/stream_protocol.cpp unit/unit_test.cpp
 unit_high_resolution_timer_SOURCES = unit/high_resolution_timer.cpp unit/unit_test.cpp
 unit_io_service_SOURCES = unit/io_service.cpp unit/unit_test.cpp
 unit_ip_address_SOURCES = unit/ip/address.cpp unit/unit_test.cpp
diff --git a/asio/src/tests/unit/generic/.gitignore b/asio/src/tests/unit/generic/.gitignore
new file mode 100644
index 0000000..c057144
--- /dev/null
+++ b/asio/src/tests/unit/generic/.gitignore
@@ -0,0 +1,14 @@
+.deps
+.dirstamp
+*.o
+*.obj
+*.exe
+*.ilk
+*.manifest
+*.pdb
+*.tds
+basic_endpoint
+datagram_protocol
+raw_protocol
+seq_packet_protocol
+stream_protocol
diff --git a/asio/src/tests/unit/generic/basic_endpoint.cpp b/asio/src/tests/unit/generic/basic_endpoint.cpp
new file mode 100644
index 0000000..6e42fd2
--- /dev/null
+++ b/asio/src/tests/unit/generic/basic_endpoint.cpp
@@ -0,0 +1,25 @@
+//
+// generic/basic_endpoint.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/generic/basic_endpoint.hpp"
+
+#include "../unit_test.hpp"
+
+ASIO_TEST_SUITE
+(
+  "generic/basic_endpoint",
+  ASIO_TEST_CASE(null_test)
+)
diff --git a/asio/src/tests/unit/generic/datagram_protocol.cpp b/asio/src/tests/unit/generic/datagram_protocol.cpp
new file mode 100644
index 0000000..6bd35af
--- /dev/null
+++ b/asio/src/tests/unit/generic/datagram_protocol.cpp
@@ -0,0 +1,243 @@
+//
+// generic/datagram_protocol.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/generic/datagram_protocol.hpp"
+
+#include <cstring>
+#include "asio/io_service.hpp"
+#include "asio/ip/udp.hpp"
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// generic_datagram_protocol_socket_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// generic::datagram_socket::socket compile and link correctly. Runtime
+// failures are ignored.
+
+namespace generic_datagram_protocol_socket_compile {
+
+void connect_handler(const asio::error_code&)
+{
+}
+
+void send_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void receive_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void test()
+{
+  using namespace asio;
+  namespace generic = asio::generic;
+  typedef generic::datagram_protocol dp;
+
+  try
+  {
+    io_service ios;
+    char mutable_char_buffer[128] = "";
+    const char const_char_buffer[128] = "";
+    socket_base::message_flags in_flags = 0;
+    socket_base::send_buffer_size socket_option;
+    socket_base::bytes_readable io_control_command;
+    asio::error_code ec;
+
+    // basic_datagram_socket constructors.
+
+    dp::socket socket1(ios);
+    dp::socket socket2(ios, dp(AF_INET, IPPROTO_UDP));
+    dp::socket socket3(ios, dp::endpoint());
+    int native_socket1 = ::socket(AF_INET, SOCK_DGRAM, 0);
+    dp::socket socket4(ios, dp(AF_INET, IPPROTO_UDP), native_socket1);
+
+#if defined(ASIO_HAS_MOVE)
+    dp::socket socket5(std::move(socket4));
+    dp::socket socket6(asio::ip::udp::socket(ios));
+#endif // defined(ASIO_HAS_MOVE)
+
+    // basic_datagram_socket operators.
+
+#if defined(ASIO_HAS_MOVE)
+    socket1 = dp::socket(ios);
+    socket1 = std::move(socket2);
+    socket1 = asio::ip::udp::socket(ios);
+#endif // defined(ASIO_HAS_MOVE)
+
+    // basic_io_object functions.
+
+    io_service& ios_ref = socket1.get_io_service();
+    (void)ios_ref;
+
+    // basic_socket functions.
+
+    dp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer();
+    (void)lowest_layer;
+
+    socket1.open(dp(AF_INET, IPPROTO_UDP));
+    socket1.open(dp(AF_INET, IPPROTO_UDP), ec);
+
+    int native_socket2 = ::socket(AF_INET, SOCK_DGRAM, 0);
+    socket1.assign(dp(AF_INET, IPPROTO_UDP), native_socket2);
+    int native_socket3 = ::socket(AF_INET, SOCK_DGRAM, 0);
+    socket1.assign(dp(AF_INET, IPPROTO_UDP), native_socket3, ec);
+
+    bool is_open = socket1.is_open();
+    (void)is_open;
+
+    socket1.close();
+    socket1.close(ec);
+
+    dp::socket::native_type native_socket4 = socket1.native();
+    (void)native_socket4;
+
+    socket1.cancel();
+    socket1.cancel(ec);
+
+    bool at_mark1 = socket1.at_mark();
+    (void)at_mark1;
+    bool at_mark2 = socket1.at_mark(ec);
+    (void)at_mark2;
+
+    std::size_t available1 = socket1.available();
+    (void)available1;
+    std::size_t available2 = socket1.available(ec);
+    (void)available2;
+
+    socket1.bind(dp::endpoint());
+    socket1.bind(dp::endpoint(), ec);
+
+    socket1.connect(dp::endpoint());
+    socket1.connect(dp::endpoint(), ec);
+
+    socket1.async_connect(dp::endpoint(), connect_handler);
+
+    socket1.set_option(socket_option);
+    socket1.set_option(socket_option, ec);
+
+    socket1.get_option(socket_option);
+    socket1.get_option(socket_option, ec);
+
+    socket1.io_control(io_control_command);
+    socket1.io_control(io_control_command, ec);
+
+    dp::endpoint endpoint1 = socket1.local_endpoint();
+    dp::endpoint endpoint2 = socket1.local_endpoint(ec);
+
+    dp::endpoint endpoint3 = socket1.remote_endpoint();
+    dp::endpoint endpoint4 = socket1.remote_endpoint(ec);
+
+    socket1.shutdown(socket_base::shutdown_both);
+    socket1.shutdown(socket_base::shutdown_both, ec);
+
+    // basic_datagram_socket functions.
+
+    socket1.send(buffer(mutable_char_buffer));
+    socket1.send(buffer(const_char_buffer));
+    socket1.send(null_buffers());
+    socket1.send(buffer(mutable_char_buffer), in_flags);
+    socket1.send(buffer(const_char_buffer), in_flags);
+    socket1.send(null_buffers(), in_flags);
+    socket1.send(buffer(mutable_char_buffer), in_flags, ec);
+    socket1.send(buffer(const_char_buffer), in_flags, ec);
+    socket1.send(null_buffers(), in_flags, ec);
+
+    socket1.async_send(buffer(mutable_char_buffer), send_handler);
+    socket1.async_send(buffer(const_char_buffer), send_handler);
+    socket1.async_send(null_buffers(), send_handler);
+    socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler);
+    socket1.async_send(buffer(const_char_buffer), in_flags, send_handler);
+    socket1.async_send(null_buffers(), in_flags, send_handler);
+
+    socket1.send_to(buffer(mutable_char_buffer),
+        dp::endpoint());
+    socket1.send_to(buffer(const_char_buffer),
+        dp::endpoint());
+    socket1.send_to(null_buffers(),
+        dp::endpoint());
+    socket1.send_to(buffer(mutable_char_buffer),
+        dp::endpoint(), in_flags);
+    socket1.send_to(buffer(const_char_buffer),
+        dp::endpoint(), in_flags);
+    socket1.send_to(null_buffers(),
+        dp::endpoint(), in_flags);
+    socket1.send_to(buffer(mutable_char_buffer),
+        dp::endpoint(), in_flags, ec);
+    socket1.send_to(buffer(const_char_buffer),
+        dp::endpoint(), in_flags, ec);
+    socket1.send_to(null_buffers(),
+        dp::endpoint(), in_flags, ec);
+
+    socket1.async_send_to(buffer(mutable_char_buffer),
+        dp::endpoint(), send_handler);
+    socket1.async_send_to(buffer(const_char_buffer),
+        dp::endpoint(), send_handler);
+    socket1.async_send_to(null_buffers(),
+        dp::endpoint(), send_handler);
+    socket1.async_send_to(buffer(mutable_char_buffer),
+        dp::endpoint(), in_flags, send_handler);
+    socket1.async_send_to(buffer(const_char_buffer),
+        dp::endpoint(), in_flags, send_handler);
+    socket1.async_send_to(null_buffers(),
+        dp::endpoint(), in_flags, send_handler);
+
+    socket1.receive(buffer(mutable_char_buffer));
+    socket1.receive(null_buffers());
+    socket1.receive(buffer(mutable_char_buffer), in_flags);
+    socket1.receive(null_buffers(), in_flags);
+    socket1.receive(buffer(mutable_char_buffer), in_flags, ec);
+    socket1.receive(null_buffers(), in_flags, ec);
+
+    socket1.async_receive(buffer(mutable_char_buffer), receive_handler);
+    socket1.async_receive(null_buffers(), receive_handler);
+    socket1.async_receive(buffer(mutable_char_buffer), in_flags,
+        receive_handler);
+    socket1.async_receive(null_buffers(), in_flags, receive_handler);
+
+    dp::endpoint endpoint;
+    socket1.receive_from(buffer(mutable_char_buffer), endpoint);
+    socket1.receive_from(null_buffers(), endpoint);
+    socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags);
+    socket1.receive_from(null_buffers(), endpoint, in_flags);
+    socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags, ec);
+    socket1.receive_from(null_buffers(), endpoint, in_flags, ec);
+
+    socket1.async_receive_from(buffer(mutable_char_buffer),
+        endpoint, receive_handler);
+    socket1.async_receive_from(null_buffers(),
+        endpoint, receive_handler);
+    socket1.async_receive_from(buffer(mutable_char_buffer),
+        endpoint, in_flags, receive_handler);
+    socket1.async_receive_from(null_buffers(),
+        endpoint, in_flags, receive_handler);
+  }
+  catch (std::exception&)
+  {
+  }
+}
+
+} // namespace generic_datagram_protocol_socket_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+  "generic/datagram_protocol",
+  ASIO_TEST_CASE(generic_datagram_protocol_socket_compile::test)
+)
diff --git a/asio/src/tests/unit/generic/raw_protocol.cpp b/asio/src/tests/unit/generic/raw_protocol.cpp
new file mode 100644
index 0000000..f53335b
--- /dev/null
+++ b/asio/src/tests/unit/generic/raw_protocol.cpp
@@ -0,0 +1,243 @@
+//
+// generic/raw_protocol.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/generic/raw_protocol.hpp"
+
+#include <cstring>
+#include "asio/io_service.hpp"
+#include "asio/ip/icmp.hpp"
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// generic_raw_protocol_socket_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// generic::raw_socket::socket compile and link correctly. Runtime failures
+// are ignored.
+
+namespace generic_raw_protocol_socket_compile {
+
+void connect_handler(const asio::error_code&)
+{
+}
+
+void send_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void receive_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void test()
+{
+  using namespace asio;
+  namespace generic = asio::generic;
+  typedef generic::raw_protocol rp;
+
+  try
+  {
+    io_service ios;
+    char mutable_char_buffer[128] = "";
+    const char const_char_buffer[128] = "";
+    socket_base::message_flags in_flags = 0;
+    socket_base::send_buffer_size socket_option;
+    socket_base::bytes_readable io_control_command;
+    asio::error_code ec;
+
+    // basic_raw_socket constructors.
+
+    rp::socket socket1(ios);
+    rp::socket socket2(ios, rp(AF_INET, IPPROTO_ICMP));
+    rp::socket socket3(ios, rp::endpoint());
+    int native_socket1 = ::socket(AF_INET, SOCK_DGRAM, 0);
+    rp::socket socket4(ios, rp(AF_INET, IPPROTO_ICMP), native_socket1);
+
+#if defined(ASIO_HAS_MOVE)
+    rp::socket socket5(std::move(socket4));
+    rp::socket socket6(asio::ip::icmp::socket(ios));
+#endif // defined(ASIO_HAS_MOVE)
+
+    // basic_datagram_socket operators.
+
+#if defined(ASIO_HAS_MOVE)
+    socket1 = rp::socket(ios);
+    socket1 = std::move(socket2);
+    socket1 = asio::ip::icmp::socket(ios);
+#endif // defined(ASIO_HAS_MOVE)
+
+    // basic_io_object functions.
+
+    io_service& ios_ref = socket1.get_io_service();
+    (void)ios_ref;
+
+    // basic_socket functions.
+
+    rp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer();
+    (void)lowest_layer;
+
+    socket1.open(rp(AF_INET, IPPROTO_ICMP));
+    socket1.open(rp(AF_INET, IPPROTO_ICMP), ec);
+
+    int native_socket2 = ::socket(AF_INET, SOCK_DGRAM, 0);
+    socket1.assign(rp(AF_INET, IPPROTO_ICMP), native_socket2);
+    int native_socket3 = ::socket(AF_INET, SOCK_DGRAM, 0);
+    socket1.assign(rp(AF_INET, IPPROTO_ICMP), native_socket3, ec);
+
+    bool is_open = socket1.is_open();
+    (void)is_open;
+
+    socket1.close();
+    socket1.close(ec);
+
+    rp::socket::native_type native_socket4 = socket1.native();
+    (void)native_socket4;
+
+    socket1.cancel();
+    socket1.cancel(ec);
+
+    bool at_mark1 = socket1.at_mark();
+    (void)at_mark1;
+    bool at_mark2 = socket1.at_mark(ec);
+    (void)at_mark2;
+
+    std::size_t available1 = socket1.available();
+    (void)available1;
+    std::size_t available2 = socket1.available(ec);
+    (void)available2;
+
+    socket1.bind(rp::endpoint());
+    socket1.bind(rp::endpoint(), ec);
+
+    socket1.connect(rp::endpoint());
+    socket1.connect(rp::endpoint(), ec);
+
+    socket1.async_connect(rp::endpoint(), connect_handler);
+
+    socket1.set_option(socket_option);
+    socket1.set_option(socket_option, ec);
+
+    socket1.get_option(socket_option);
+    socket1.get_option(socket_option, ec);
+
+    socket1.io_control(io_control_command);
+    socket1.io_control(io_control_command, ec);
+
+    rp::endpoint endpoint1 = socket1.local_endpoint();
+    rp::endpoint endpoint2 = socket1.local_endpoint(ec);
+
+    rp::endpoint endpoint3 = socket1.remote_endpoint();
+    rp::endpoint endpoint4 = socket1.remote_endpoint(ec);
+
+    socket1.shutdown(socket_base::shutdown_both);
+    socket1.shutdown(socket_base::shutdown_both, ec);
+
+    // basic_raw_socket functions.
+
+    socket1.send(buffer(mutable_char_buffer));
+    socket1.send(buffer(const_char_buffer));
+    socket1.send(null_buffers());
+    socket1.send(buffer(mutable_char_buffer), in_flags);
+    socket1.send(buffer(const_char_buffer), in_flags);
+    socket1.send(null_buffers(), in_flags);
+    socket1.send(buffer(mutable_char_buffer), in_flags, ec);
+    socket1.send(buffer(const_char_buffer), in_flags, ec);
+    socket1.send(null_buffers(), in_flags, ec);
+
+    socket1.async_send(buffer(mutable_char_buffer), send_handler);
+    socket1.async_send(buffer(const_char_buffer), send_handler);
+    socket1.async_send(null_buffers(), send_handler);
+    socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler);
+    socket1.async_send(buffer(const_char_buffer), in_flags, send_handler);
+    socket1.async_send(null_buffers(), in_flags, send_handler);
+
+    socket1.send_to(buffer(mutable_char_buffer),
+        rp::endpoint());
+    socket1.send_to(buffer(const_char_buffer),
+        rp::endpoint());
+    socket1.send_to(null_buffers(),
+        rp::endpoint());
+    socket1.send_to(buffer(mutable_char_buffer),
+        rp::endpoint(), in_flags);
+    socket1.send_to(buffer(const_char_buffer),
+        rp::endpoint(), in_flags);
+    socket1.send_to(null_buffers(),
+        rp::endpoint(), in_flags);
+    socket1.send_to(buffer(mutable_char_buffer),
+        rp::endpoint(), in_flags, ec);
+    socket1.send_to(buffer(const_char_buffer),
+        rp::endpoint(), in_flags, ec);
+    socket1.send_to(null_buffers(),
+        rp::endpoint(), in_flags, ec);
+
+    socket1.async_send_to(buffer(mutable_char_buffer),
+        rp::endpoint(), send_handler);
+    socket1.async_send_to(buffer(const_char_buffer),
+        rp::endpoint(), send_handler);
+    socket1.async_send_to(null_buffers(),
+        rp::endpoint(), send_handler);
+    socket1.async_send_to(buffer(mutable_char_buffer),
+        rp::endpoint(), in_flags, send_handler);
+    socket1.async_send_to(buffer(const_char_buffer),
+        rp::endpoint(), in_flags, send_handler);
+    socket1.async_send_to(null_buffers(),
+        rp::endpoint(), in_flags, send_handler);
+
+    socket1.receive(buffer(mutable_char_buffer));
+    socket1.receive(null_buffers());
+    socket1.receive(buffer(mutable_char_buffer), in_flags);
+    socket1.receive(null_buffers(), in_flags);
+    socket1.receive(buffer(mutable_char_buffer), in_flags, ec);
+    socket1.receive(null_buffers(), in_flags, ec);
+
+    socket1.async_receive(buffer(mutable_char_buffer), receive_handler);
+    socket1.async_receive(null_buffers(), receive_handler);
+    socket1.async_receive(buffer(mutable_char_buffer), in_flags,
+        receive_handler);
+    socket1.async_receive(null_buffers(), in_flags, receive_handler);
+
+    rp::endpoint endpoint;
+    socket1.receive_from(buffer(mutable_char_buffer), endpoint);
+    socket1.receive_from(null_buffers(), endpoint);
+    socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags);
+    socket1.receive_from(null_buffers(), endpoint, in_flags);
+    socket1.receive_from(buffer(mutable_char_buffer), endpoint, in_flags, ec);
+    socket1.receive_from(null_buffers(), endpoint, in_flags, ec);
+
+    socket1.async_receive_from(buffer(mutable_char_buffer),
+        endpoint, receive_handler);
+    socket1.async_receive_from(null_buffers(),
+        endpoint, receive_handler);
+    socket1.async_receive_from(buffer(mutable_char_buffer),
+        endpoint, in_flags, receive_handler);
+    socket1.async_receive_from(null_buffers(),
+        endpoint, in_flags, receive_handler);
+  }
+  catch (std::exception&)
+  {
+  }
+}
+
+} // namespace generic_raw_protocol_socket_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+  "generic/raw_protocol",
+  ASIO_TEST_CASE(generic_raw_protocol_socket_compile::test)
+)
diff --git a/asio/src/tests/unit/generic/seq_packet_protocol.cpp b/asio/src/tests/unit/generic/seq_packet_protocol.cpp
new file mode 100644
index 0000000..705dbdf
--- /dev/null
+++ b/asio/src/tests/unit/generic/seq_packet_protocol.cpp
@@ -0,0 +1,187 @@
+//
+// generic/seq_packet_protocol.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/generic/seq_packet_protocol.hpp"
+
+#include <cstring>
+#include "asio/io_service.hpp"
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// generic_seq_packet_protocol_socket_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// generic::seq_packet_socket::socket compile and link correctly. Runtime
+// failures are ignored.
+
+namespace generic_seq_packet_protocol_socket_compile {
+
+void connect_handler(const asio::error_code&)
+{
+}
+
+void send_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void receive_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void test()
+{
+  using namespace asio;
+  namespace generic = asio::generic;
+  typedef generic::seq_packet_protocol spp;
+
+  try
+  {
+    io_service ios;
+    char mutable_char_buffer[128] = "";
+    const char const_char_buffer[128] = "";
+    const socket_base::message_flags in_flags = 0;
+    socket_base::message_flags out_flags = 0;
+    socket_base::send_buffer_size socket_option;
+    socket_base::bytes_readable io_control_command;
+    asio::error_code ec;
+
+    // basic_seq_packet_socket constructors.
+
+    spp::socket socket1(ios);
+    spp::socket socket2(ios, spp(AF_INET, 0));
+    spp::socket socket3(ios, spp::endpoint());
+    int native_socket1 = ::socket(AF_INET, SOCK_SEQPACKET, 0);
+    spp::socket socket4(ios, spp(AF_INET, 0), native_socket1);
+
+#if defined(ASIO_HAS_MOVE)
+    spp::socket socket5(std::move(socket4));
+#endif // defined(ASIO_HAS_MOVE)
+
+    // basic_seq_packet_socket operators.
+
+#if defined(ASIO_HAS_MOVE)
+    socket1 = spp::socket(ios);
+    socket1 = std::move(socket2);
+#endif // defined(ASIO_HAS_MOVE)
+
+    // basic_io_object functions.
+
+    io_service& ios_ref = socket1.get_io_service();
+    (void)ios_ref;
+
+    // basic_socket functions.
+
+    spp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer();
+    (void)lowest_layer;
+
+    socket1.open(spp(AF_INET, 0));
+    socket1.open(spp(AF_INET, 0), ec);
+
+    int native_socket2 = ::socket(AF_INET, SOCK_SEQPACKET, 0);
+    socket1.assign(spp(AF_INET, 0), native_socket2);
+    int native_socket3 = ::socket(AF_INET, SOCK_SEQPACKET, 0);
+    socket1.assign(spp(AF_INET, 0), native_socket3, ec);
+
+    bool is_open = socket1.is_open();
+    (void)is_open;
+
+    socket1.close();
+    socket1.close(ec);
+
+    spp::socket::native_type native_socket4 = socket1.native();
+    (void)native_socket4;
+
+    socket1.cancel();
+    socket1.cancel(ec);
+
+    bool at_mark1 = socket1.at_mark();
+    (void)at_mark1;
+    bool at_mark2 = socket1.at_mark(ec);
+    (void)at_mark2;
+
+    std::size_t available1 = socket1.available();
+    (void)available1;
+    std::size_t available2 = socket1.available(ec);
+    (void)available2;
+
+    socket1.bind(spp::endpoint());
+    socket1.bind(spp::endpoint(), ec);
+
+    socket1.connect(spp::endpoint());
+    socket1.connect(spp::endpoint(), ec);
+
+    socket1.async_connect(spp::endpoint(), connect_handler);
+
+    socket1.set_option(socket_option);
+    socket1.set_option(socket_option, ec);
+
+    socket1.get_option(socket_option);
+    socket1.get_option(socket_option, ec);
+
+    socket1.io_control(io_control_command);
+    socket1.io_control(io_control_command, ec);
+
+    spp::endpoint endpoint1 = socket1.local_endpoint();
+    spp::endpoint endpoint2 = socket1.local_endpoint(ec);
+
+    spp::endpoint endpoint3 = socket1.remote_endpoint();
+    spp::endpoint endpoint4 = socket1.remote_endpoint(ec);
+
+    socket1.shutdown(socket_base::shutdown_both);
+    socket1.shutdown(socket_base::shutdown_both, ec);
+
+    // basic_seq_packet_socket functions.
+
+    socket1.send(buffer(mutable_char_buffer), in_flags);
+    socket1.send(buffer(const_char_buffer), in_flags);
+    socket1.send(null_buffers(), in_flags);
+    socket1.send(buffer(mutable_char_buffer), in_flags, ec);
+    socket1.send(buffer(const_char_buffer), in_flags, ec);
+    socket1.send(null_buffers(), in_flags, ec);
+
+    socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler);
+    socket1.async_send(buffer(const_char_buffer), in_flags, send_handler);
+    socket1.async_send(null_buffers(), in_flags, send_handler);
+
+    socket1.receive(buffer(mutable_char_buffer), out_flags);
+    socket1.receive(null_buffers(), out_flags);
+    socket1.receive(buffer(mutable_char_buffer), in_flags, out_flags);
+    socket1.receive(null_buffers(), in_flags, out_flags);
+    socket1.receive(buffer(mutable_char_buffer), in_flags, out_flags, ec);
+    socket1.receive(null_buffers(), in_flags, out_flags, ec);
+
+    socket1.async_receive(buffer(mutable_char_buffer), out_flags,
+        receive_handler);
+    socket1.async_receive(null_buffers(), out_flags, receive_handler);
+    socket1.async_receive(buffer(mutable_char_buffer), in_flags,
+        out_flags, receive_handler);
+    socket1.async_receive(null_buffers(), in_flags, out_flags, receive_handler);
+  }
+  catch (std::exception&)
+  {
+  }
+}
+
+} // namespace generic_seq_packet_protocol_socket_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+  "generic/seq_packet_protocol",
+  ASIO_TEST_CASE(generic_seq_packet_protocol_socket_compile::test)
+)
diff --git a/asio/src/tests/unit/generic/stream_protocol.cpp b/asio/src/tests/unit/generic/stream_protocol.cpp
new file mode 100644
index 0000000..d40e3cc
--- /dev/null
+++ b/asio/src/tests/unit/generic/stream_protocol.cpp
@@ -0,0 +1,220 @@
+//
+// generic/stream_protocol.cpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Disable autolinking for unit tests.
+#if !defined(BOOST_ALL_NO_LIB)
+#define BOOST_ALL_NO_LIB 1
+#endif // !defined(BOOST_ALL_NO_LIB)
+
+// Test that header file is self-contained.
+#include "asio/generic/stream_protocol.hpp"
+
+#include <cstring>
+#include "asio/io_service.hpp"
+#include "asio/ip/tcp.hpp"
+#include "../unit_test.hpp"
+
+//------------------------------------------------------------------------------
+
+// generic_stream_protocol_socket_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// generic::stream_protocol::socket compile and link correctly. Runtime
+// failures are ignored.
+
+namespace generic_stream_protocol_socket_compile {
+
+void connect_handler(const asio::error_code&)
+{
+}
+
+void send_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void receive_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void write_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void read_some_handler(const asio::error_code&, std::size_t)
+{
+}
+
+void test()
+{
+  using namespace asio;
+  namespace generic = asio::generic;
+  typedef generic::stream_protocol sp;
+
+  try
+  {
+    io_service ios;
+    char mutable_char_buffer[128] = "";
+    const char const_char_buffer[128] = "";
+    socket_base::message_flags in_flags = 0;
+    socket_base::keep_alive socket_option;
+    socket_base::bytes_readable io_control_command;
+    asio::error_code ec;
+
+    // basic_stream_socket constructors.
+
+    sp::socket socket1(ios);
+    sp::socket socket2(ios, sp(AF_INET, IPPROTO_TCP));
+    sp::socket socket3(ios, sp::endpoint());
+    int native_socket1 = ::socket(AF_INET, SOCK_STREAM, 0);
+    sp::socket socket4(ios, sp(AF_INET, IPPROTO_TCP), native_socket1);
+
+#if defined(ASIO_HAS_MOVE)
+    sp::socket socket5(std::move(socket4));
+    sp::socket socket6(asio::ip::tcp::socket(ios));
+#endif // defined(ASIO_HAS_MOVE)
+
+    // basic_stream_socket operators.
+
+#if defined(ASIO_HAS_MOVE)
+    socket1 = sp::socket(ios);
+    socket1 = std::move(socket2);
+    socket1 = asio::ip::tcp::socket(ios);
+#endif // defined(ASIO_HAS_MOVE)
+
+    // basic_io_object functions.
+
+    io_service& ios_ref = socket1.get_io_service();
+    (void)ios_ref;
+
+    // basic_socket functions.
+
+    sp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer();
+    (void)lowest_layer;
+
+    socket1.open(sp(AF_INET, IPPROTO_TCP));
+    socket1.open(sp(AF_INET, IPPROTO_TCP), ec);
+
+    int native_socket2 = ::socket(AF_INET, SOCK_STREAM, 0);
+    socket1.assign(sp(AF_INET, IPPROTO_TCP), native_socket2);
+    int native_socket3 = ::socket(AF_INET, SOCK_STREAM, 0);
+    socket1.assign(sp(AF_INET, IPPROTO_TCP), native_socket3, ec);
+
+    bool is_open = socket1.is_open();
+    (void)is_open;
+
+    socket1.close();
+    socket1.close(ec);
+
+    sp::socket::native_type native_socket4 = socket1.native();
+    (void)native_socket4;
+
+    socket1.cancel();
+    socket1.cancel(ec);
+
+    bool at_mark1 = socket1.at_mark();
+    (void)at_mark1;
+    bool at_mark2 = socket1.at_mark(ec);
+    (void)at_mark2;
+
+    std::size_t available1 = socket1.available();
+    (void)available1;
+    std::size_t available2 = socket1.available(ec);
+    (void)available2;
+
+    socket1.bind(sp::endpoint());
+    socket1.bind(sp::endpoint(), ec);
+
+    socket1.connect(sp::endpoint());
+    socket1.connect(sp::endpoint(), ec);
+
+    socket1.async_connect(sp::endpoint(), connect_handler);
+
+    socket1.set_option(socket_option);
+    socket1.set_option(socket_option, ec);
+
+    socket1.get_option(socket_option);
+    socket1.get_option(socket_option, ec);
+
+    socket1.io_control(io_control_command);
+    socket1.io_control(io_control_command, ec);
+
+    sp::endpoint endpoint1 = socket1.local_endpoint();
+    sp::endpoint endpoint2 = socket1.local_endpoint(ec);
+
+    sp::endpoint endpoint3 = socket1.remote_endpoint();
+    sp::endpoint endpoint4 = socket1.remote_endpoint(ec);
+
+    socket1.shutdown(socket_base::shutdown_both);
+    socket1.shutdown(socket_base::shutdown_both, ec);
+
+    // basic_stream_socket functions.
+
+    socket1.send(buffer(mutable_char_buffer));
+    socket1.send(buffer(const_char_buffer));
+    socket1.send(null_buffers());
+    socket1.send(buffer(mutable_char_buffer), in_flags);
+    socket1.send(buffer(const_char_buffer), in_flags);
+    socket1.send(null_buffers(), in_flags);
+    socket1.send(buffer(mutable_char_buffer), in_flags, ec);
+    socket1.send(buffer(const_char_buffer), in_flags, ec);
+    socket1.send(null_buffers(), in_flags, ec);
+
+    socket1.async_send(buffer(mutable_char_buffer), send_handler);
+    socket1.async_send(buffer(const_char_buffer), send_handler);
+    socket1.async_send(null_buffers(), send_handler);
+    socket1.async_send(buffer(mutable_char_buffer), in_flags, send_handler);
+    socket1.async_send(buffer(const_char_buffer), in_flags, send_handler);
+    socket1.async_send(null_buffers(), in_flags, send_handler);
+
+    socket1.receive(buffer(mutable_char_buffer));
+    socket1.receive(null_buffers());
+    socket1.receive(buffer(mutable_char_buffer), in_flags);
+    socket1.receive(null_buffers(), in_flags);
+    socket1.receive(buffer(mutable_char_buffer), in_flags, ec);
+    socket1.receive(null_buffers(), in_flags, ec);
+
+    socket1.async_receive(buffer(mutable_char_buffer), receive_handler);
+    socket1.async_receive(null_buffers(), receive_handler);
+    socket1.async_receive(buffer(mutable_char_buffer), in_flags,
+        receive_handler);
+    socket1.async_receive(null_buffers(), in_flags, receive_handler);
+
+    socket1.write_some(buffer(mutable_char_buffer));
+    socket1.write_some(buffer(const_char_buffer));
+    socket1.write_some(null_buffers());
+    socket1.write_some(buffer(mutable_char_buffer), ec);
+    socket1.write_some(buffer(const_char_buffer), ec);
+    socket1.write_some(null_buffers(), ec);
+
+    socket1.async_write_some(buffer(mutable_char_buffer), write_some_handler);
+    socket1.async_write_some(buffer(const_char_buffer), write_some_handler);
+    socket1.async_write_some(null_buffers(), write_some_handler);
+
+    socket1.read_some(buffer(mutable_char_buffer));
+    socket1.read_some(buffer(mutable_char_buffer), ec);
+    socket1.read_some(null_buffers(), ec);
+
+    socket1.async_read_some(buffer(mutable_char_buffer), read_some_handler);
+    socket1.async_read_some(null_buffers(), read_some_handler);
+  }
+  catch (std::exception&)
+  {
+  }
+}
+
+} // namespace generic_stream_protocol_socket_compile
+
+//------------------------------------------------------------------------------
+
+ASIO_TEST_SUITE
+(
+  "generic/stream_protocol",
+  ASIO_TEST_CASE(generic_stream_protocol_socket_compile::test)
+)