diff --git a/src/forward.tex b/src/forward.tex index b49596a..78b9745 100644 --- a/src/forward.tex +++ b/src/forward.tex @@ -22,25 +22,25 @@ class io_context; template struct wait_traits; - template> + template, class Executor = executor> class basic_waitable_timer; using system_timer = basic_waitable_timer; using steady_timer = basic_waitable_timer; using high_resolution_timer = basic_waitable_timer; - template + template class basic_socket; - template + template class basic_datagram_socket; - template + template class basic_stream_socket; - template + template class basic_socket_acceptor; template> + class WaitTraits = wait_traits, class Executor = executor> class basic_socket_streambuf; template> + class WaitTraits = wait_traits, class Executor = executor> class basic_socket_iostream; namespace ip { @@ -64,7 +64,7 @@ class basic_resolver_entry; template class basic_resolver_results; - template + template class basic_resolver; class tcp; class udp; diff --git a/src/internetprotocol.tex b/src/internetprotocol.tex index a89fbd8..5615186 100644 --- a/src/internetprotocol.tex +++ b/src/internetprotocol.tex @@ -180,7 +180,7 @@ class resolver_base; - template + template class basic_resolver; string host_name(); @@ -3060,26 +3060,31 @@ \rSec1[internet.resolver]{Class template \tcode{ip::basic_resolver}} \pnum -Objects of type \tcode{basic_resolver} are used to perform name resolution. Name resolution is the translation of a host name and service name into a sequence of endpoints, or the translation of an endpoint into its corresponding host name and service name. +Objects of type \tcode{basic_resolver} are used to perform name resolution. Name resolution is the translation of a host name and service name into a sequence of endpoints, or the translation of an endpoint into its corresponding host name and service name. \begin{codeblock} namespace std::experimental::net::inline @\namespacever@ { namespace ip { - template + template class basic_resolver : public resolver_base { public: // types: - using executor_type = io_context::executor_type; + using executor_type = Executor; using protocol_type = InternetProtocol; using endpoint_type = typename InternetProtocol::endpoint; using results_type = basic_resolver_results; + template + using rebind_executor = + basic_resolver; + // \ref{internet.resolver.cons}, construct / copy / destroy - explicit basic_resolver(io_context& ctx); + explicit basic_resolver(const executor_type& ex); + template explicit basic_resolver(ExecutionContext& ctx); basic_resolver(const basic_resolver&) = delete; basic_resolver(basic_resolver&& rhs) noexcept; @@ -3146,10 +3151,24 @@ \rSec2[internet.resolver.cons]{\tcode{ip::basic_resolver} constructors} \begin{itemdecl} -explicit basic_resolver(io_context& ctx); +explicit basic_resolver(const executor_type& ex); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\postconditions \tcode{get_executor() == ex}. +\end{itemdescr} + +\begin{itemdecl} +template explicit basic_resolver(ExecutionContext\& ctx); \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. + \pnum \postconditions \tcode{get_executor() == ctx.get_executor()}. \end{itemdescr} @@ -3506,6 +3525,8 @@ using endpoint = basic_endpoint; using resolver = basic_resolver; using socket = basic_stream_socket; + template + using socket_for = basic_stream_socket using acceptor = basic_socket_acceptor; using iostream = basic_socket_iostream; class no_delay; @@ -3614,6 +3635,8 @@ using endpoint = basic_endpoint; using resolver = basic_resolver; using socket = basic_datagram_socket; + template + using socket_for = basic_datagram_socket // static members: static constexpr udp v4() noexcept; diff --git a/src/socketalgorithms.tex b/src/socketalgorithms.tex index a32cd7f..904eeed 100644 --- a/src/socketalgorithms.tex +++ b/src/socketalgorithms.tex @@ -6,11 +6,11 @@ \rSec1[socket.algo.connect]{Synchronous connect operations} \begin{itemdecl} -template - typename Protocol::endpoint connect(basic_socket& s, +template + typename Protocol::endpoint connect(basic_socket& s, const EndpointSequence& endpoints); -template - typename Protocol::endpoint connect(basic_socket& s, +template + typename Protocol::endpoint connect(basic_socket& s, const EndpointSequence& endpoints, error_code& ec); \end{itemdecl} @@ -21,12 +21,12 @@ \end{itemdescr} \begin{itemdecl} -template - typename Protocol::endpoint connect(basic_socket& s, +template + typename Protocol::endpoint connect(basic_socket& s, const EndpointSequence& endpoints, ConnectCondition c); -template - typename Protocol::endpoint connect(basic_socket& s, +template + typename Protocol::endpoint connect(basic_socket& s, const EndpointSequence& endpoints, ConnectCondition c, error_code& ec); \end{itemdecl} @@ -57,11 +57,11 @@ \end{itemdescr} \begin{itemdecl} -template - InputIterator connect(basic_socket& s, +template + InputIterator connect(basic_socket& s, InputIterator first, InputIterator last); -template - InputIterator connect(basic_socket& s, +template + InputIterator connect(basic_socket& s, InputIterator first, InputIterator last, error_code& ec); \end{itemdecl} @@ -72,12 +72,12 @@ \end{itemdescr} \begin{itemdecl} -template - InputIterator connect(basic_socket& s, +template + InputIterator connect(basic_socket& s, InputIterator first, InputIterator last, ConnectCondition c); -template - InputIterator connect(basic_socket& s, +template + InputIterator connect(basic_socket& s, InputIterator first, InputIterator last, ConnectCondition c, error_code& ec); \end{itemdecl} @@ -112,8 +112,8 @@ \rSec1[socket.algo.async.connect]{Asynchronous connect operations} \begin{itemdecl} -template - @\DEDUCED@ async_connect(basic_socket& s, +template + @\DEDUCED@ async_connect(basic_socket& s, const EndpointSequence& endpoints, CompletionToken&& token); \end{itemdecl} @@ -127,9 +127,9 @@ \end{itemdescr} \begin{itemdecl} -template - @\DEDUCED@ async_connect(basic_socket& s, + @\DEDUCED@ async_connect(basic_socket& s, const EndpointSequence& endpoints, ConnectCondition c, CompletionToken&& token); @@ -168,8 +168,8 @@ \end{itemdescr} \begin{itemdecl} -template - @\DEDUCED@ async_connect(basic_socket& s, +template + @\DEDUCED@ async_connect(basic_socket& s, InputIterator first, InputIterator last, CompletionToken&& token); \end{itemdecl} @@ -184,9 +184,9 @@ \end{itemdescr} \begin{itemdecl} -template - @\DEDUCED@ async_connect(basic_socket& s, + @\DEDUCED@ async_connect(basic_socket& s, InputIterator first, InputIterator last, ConnectCondition c, CompletionToken&& token); diff --git a/src/sockets.tex b/src/sockets.tex index 6fee3ac..5315172 100644 --- a/src/sockets.tex +++ b/src/sockets.tex @@ -24,84 +24,84 @@ class socket_base; - template + template class basic_socket; - template + template class basic_datagram_socket; - template + template class basic_stream_socket; - template + template class basic_socket_acceptor; // \ref{socket.iostreams}, Socket streams template> + class WaitTraits = wait_traits, class Executor = executor> class basic_socket_streambuf; template> + class WaitTraits = wait_traits, class Executor = executor> class basic_socket_iostream; // \ref{socket.algo.connect}, synchronous connect operations - template - typename Protocol::endpoint connect(basic_socket& s, + template + typename Protocol::endpoint connect(basic_socket& s, const EndpointSequence& endpoints); - template - typename Protocol::endpoint connect(basic_socket& s, + template + typename Protocol::endpoint connect(basic_socket& s, const EndpointSequence& endpoints, error_code& ec); - template - typename Protocol::endpoint connect(basic_socket& s, + template + typename Protocol::endpoint connect(basic_socket& s, const EndpointSequence& endpoints, ConnectCondition c); - template - typename Protocol::endpoint connect(basic_socket& s, + template + typename Protocol::endpoint connect(basic_socket& s, const EndpointSequence& endpoints, ConnectCondition c, error_code& ec); - template - InputIterator connect(basic_socket& s, + template + InputIterator connect(basic_socket& s, InputIterator first, InputIterator last); - template - InputIterator connect(basic_socket& s, + template + InputIterator connect(basic_socket& s, InputIterator first, InputIterator last, error_code& ec); - template - InputIterator connect(basic_socket& s, + template + InputIterator connect(basic_socket& s, InputIterator first, InputIterator last, ConnectCondition c); - template - InputIterator connect(basic_socket& s, + template + InputIterator connect(basic_socket& s, InputIterator first, InputIterator last, ConnectCondition c, error_code& ec); // \ref{socket.algo.async.connect}, asynchronous connect operations - template - @\DEDUCED@ async_connect(basic_socket& s, + template + @\DEDUCED@ async_connect(basic_socket& s, const EndpointSequence& endpoints, CompletionToken&& token); - template - @\DEDUCED@ async_connect(basic_socket& s, + @\DEDUCED@ async_connect(basic_socket& s, const EndpointSequence& endpoints, ConnectCondition c, CompletionToken&& token); - template - @\DEDUCED@ async_connect(basic_socket& s, + template + @\DEDUCED@ async_connect(basic_socket& s, InputIterator first, InputIterator last, CompletionToken&& token); - template - @\DEDUCED@ async_connect(basic_socket& s, + @\DEDUCED@ async_connect(basic_socket& s, InputIterator first, InputIterator last, ConnectCondition c, CompletionToken&& token); @@ -385,6 +385,8 @@ \pnum A type \tcode{X} meets the \defnnewoldconcept{AcceptableProtocol} requirements if it meets the requirements of \newoldconcept{Protocol}~(\ref{socket.reqmts.protocol}) as well as the additional requirements listed below. +In the table below, \tcode{E} is a type that satisfies the Executor requirements~(\ref{async.reqmts.executor}). + \begin{libreqtab3} {\newoldconcept{AcceptableProtocol} requirements} {tab:socket.reqmts.acceptableprotocol.requirements} @@ -404,6 +406,10 @@ A type that meets the requirements of \oldconcept{Destructible} (\CppXref{destructible}) and \oldconcept{MoveConstructible} (\CppXref{moveconstructible}), and that is publicly and unambiguously derived from \tcode{basic_socket}. & \\ +\tcode{X::socket_for} & +A type that satisfies the requirements of \tcode{Destructible} (\CppXref{destructible}) and \tcode{MoveConstructible} (\CppXref{moveconstructible}), and that is publicly and unambiguously derived from \tcode{basic_socket}. & + \\ + \end{libreqtab3} @@ -1053,13 +1059,13 @@ \item socket option classes \tcode{broadcast}, \tcode{debug}, \tcode{do_not_route}, \tcode{keep_alive}, \tcode{linger}, \tcode{out_of_band_inline}, \tcode{receive_buffer_size}, \tcode{receive_low_watermark}, \tcode{reuse_address}, \tcode{send_buffer_size}, and \tcode{send_low_watermark}; \item -an enumerated type, \tcode{shutdown_type}, for use with the \tcode{basic_socket} class's \tcode{shutdown} member function. +an enumerated type, \tcode{shutdown_type}, for use with the \tcode{basic_socket} class's \tcode{shutdown} member function. \item -an enumerated type, \tcode{wait_type}, for use with the \tcode{basic_socket} and \tcode{basic_socket_acceptor} classes' \tcode{wait} and \tcode{async_wait} member functions, +an enumerated type, \tcode{wait_type}, for use with the \tcode{basic_socket} and \tcode{basic_socket_acceptor} classes' \tcode{wait} and \tcode{async_wait} member functions, \item -a bitmask type, \tcode{message_flags}, for use with the \tcode{basic_stream_socket} class's \tcode{send}, \tcode{async_send}, \tcode{receive}, and \tcode{async_receive} member functions, and the \tcode{basic_datagram_socket} class's \tcode{send}, \tcode{async_send}, \tcode{send_to}, \tcode{async_send_to}, \tcode{receive}, \tcode{async_receive}, \tcode{receive_from}, and \tcode{async_receive_from} member functions. +a bitmask type, \tcode{message_flags}, for use with the \tcode{basic_stream_socket} class's \tcode{send}, \tcode{async_send}, \tcode{receive}, and \tcode{async_receive} member functions, and the \tcode{basic_datagram_socket} class's \tcode{send}, \tcode{async_send}, \tcode{send_to}, \tcode{async_send_to}, \tcode{receive}, \tcode{async_receive}, \tcode{receive_from}, and \tcode{async_receive_from} member functions. \item -a constant, \tcode{max_listen_connections}, for use with the \tcode{basic_socket_acceptor} class's \tcode{listen} member function. +a constant, \tcode{max_listen_connections}, for use with the \tcode{basic_socket_acceptor} class's \tcode{listen} member function. \end{itemize} \begin{libreqtab3} @@ -1395,22 +1401,26 @@ \rSec1[socket.basic]{Class template \tcode{basic_socket}} \pnum -Class template \tcode{basic_socket} is used as the base class for the \tcode{basic_datagram_socket} and \tcode{basic_stream_socket} class templates. It provides functionality that is common to both types of socket. +Class template \tcode{basic_socket} is used as the base class for the \tcode{basic_datagram_socket} and \tcode{basic_stream_socket} class templates. It provides functionality that is common to both types of socket. \begin{codeblock} namespace std::experimental::net::inline @\namespacever@ { - template + template class basic_socket : public socket_base { public: // types: - using executor_type = io_context::executor_type; + using executor_type = Executor; using native_handle_type = @\impdefx{type of \tcode{basic_socket::native_handle_type}}@; // \nativeref using protocol_type = Protocol; using endpoint_type = typename protocol_type::endpoint; + template + using rebind_executor = + basic_socket; + // \ref{socket.basic.ops}, basic_socket operations executor_type get_executor() noexcept; @@ -1494,22 +1504,31 @@ protected: // \ref{socket.basic.cons}, construct / copy / destroy - explicit basic_socket(io_context& ctx); - basic_socket(io_context& ctx, const protocol_type& protocol); - basic_socket(io_context& ctx, const endpoint_type& endpoint); - basic_socket(io_context& ctx, const protocol_type& protocol, + explicit basic_socket(const executor_type& ex); + template + explicit basic_socket(ExecutionContext& ctx); + basic_socket(const executor_type& ex, const protocol_type& protocol); + template + basic_socket(ExecutionContext& ctx, const protocol_type& protocol); + basic_socket(const executor_type& ex, const endpoint_type& endpoint); + template + basic_socket(ExecutionContext& ctx, const endpoint_type& endpoint); + basic_socket(const executor_type& ex, const protocol_type& protocol, const native_handle_type& native_socket); // \nativeref + template + basic_socket(ExecutionContext& ctx, const protocol_type& protocol, + const native_handle_type& native_socket); // \nativeref basic_socket(const basic_socket&) = delete; basic_socket(basic_socket&& rhs); - template - basic_socket(basic_socket&& rhs); + template + basic_socket(basic_socket&& rhs); ~basic_socket(); basic_socket& operator=(const basic_socket&) = delete; basic_socket& operator=(basic_socket&& rhs); - template - basic_socket& operator=(basic_socket&& rhs); + template + basic_socket& operator=(basic_socket&& rhs); private: protocol_type protocol_; // \expos @@ -1528,7 +1547,7 @@ \rSec2[socket.basic.cons]{\tcode{basic_socket} constructors} \begin{itemdecl} -explicit basic_socket(io_context& ctx); +explicit basic_socket(const executor_type& ex); \end{itemdecl} \begin{itemdescr} @@ -1536,14 +1555,29 @@ \postconditions \begin{itemize} \item -\tcode{get_executor() == ctx.get_executor()}. +\tcode{get_executor() == ex}. \item \tcode{is_open() == false}. \end{itemize} \end{itemdescr} \begin{itemdecl} -basic_socket(io_context& ctx, const protocol_type& protocol); +template + explicit basic_socket(ExecutionContext& ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects Equivalent to \tcode{basic_socket(ctx.get_executor())}. +\end{itemdescr} + +\begin{itemdecl} +basic_socket(const executor_type& ex, const protocol_type& protocol); \end{itemdecl} \begin{itemdescr} @@ -1554,7 +1588,7 @@ \postconditions \begin{itemize} \item -\tcode{get_executor() == ctx.get_executor()}. +\tcode{get_executor() == ex}. \item \tcode{is_open() == true}. \item @@ -1565,7 +1599,22 @@ \end{itemdescr} \begin{itemdecl} -basic_socket(io_context& ctx, const endpoint_type& endpoint); +template + explicit basic_socket(ExecutionContext& ctx, const protocol_type& protocol); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects Equivalent to \tcode{basic_socket(ctx.get_executor(), protocol)}. +\end{itemdescr} + +\begin{itemdecl} +basic_socket(const executor_type& ex, const endpoint_type& endpoint); \end{itemdecl} \begin{itemdescr} @@ -1581,7 +1630,7 @@ \postconditions \begin{itemize} \item -\tcode{get_executor() == ctx.get_executor()}. +\tcode{get_executor() == ex}. \item \tcode{is_open() == true}. \item @@ -1592,7 +1641,22 @@ \end{itemdescr} \begin{itemdecl} -basic_socket(io_context& ctx, const protocol_type& protocol, +template + explicit basic_socket(ExecutionContext& ctx, const endpoint_type& endpoint); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects Equivalent to \tcode{basic_socket(ctx.get_executor(), endpoint)}. +\end{itemdescr} + +\begin{itemdecl} +basic_socket(const executor_type& ex, const protocol_type& protocol, const native_handle_type& native_socket); \end{itemdecl} @@ -1607,7 +1671,7 @@ \postconditions \begin{itemize} \item -\tcode{get_executor() == ctx.get_executor()}. +\tcode{get_executor() == ex}. \item \tcode{is_open() == true}. \item @@ -1617,13 +1681,29 @@ \end{itemize} \end{itemdescr} +\begin{itemdecl} +template + basic_socket(ExecutionContext& ctx, const protocol_type& protocol, + const native_handle_type& native_socket); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects Equivalent to \tcode{basic_socket(ctx.get_executor(), protocol, native_socket)}. +\end{itemdescr} + \begin{itemdecl} basic_socket(basic_socket&& rhs); \end{itemdecl} \begin{itemdescr} \pnum -\effects Move constructs an object of class \tcode{basic_socket} that refers to the state originally represented by \tcode{rhs}. +\effects Move constructs an object of class \tcode{basic_socket} that refers to the state originally represented by \tcode{rhs}. \pnum \postconditions @@ -1644,16 +1724,16 @@ \end{itemdescr} \begin{itemdecl} -template - basic_socket(basic_socket&& rhs); +template + basic_socket(basic_socket&& rhs); \end{itemdecl} \begin{itemdescr} \pnum -\constraints \tcode{is_convertible_v} is \tcode{true}. +\constraints \tcode{is_convertible_v} is \tcode{true} and \tcode{is_convertible_v} is \tcode{true}. \pnum -\effects Move constructs an object of class \tcode{basic_socket} that refers to the state originally represented by \tcode{rhs}. +\effects Move constructs an object of class \tcode{basic_socket} that refers to the state originally represented by \tcode{rhs}. \pnum \postconditions @@ -1718,13 +1798,13 @@ \end{itemdescr} \begin{itemdecl} -template - basic_socket& operator=(basic_socket&& rhs); +template + basic_socket& operator=(basic_socket&& rhs); \end{itemdecl} \begin{itemdescr} \pnum -\constraints \tcode{is_convertible_v} is \tcode{true}. +\constraints \tcode{is_convertible_v} is \tcode{true} and \tcode{is_convertible_v} is \tcode{true}. \pnum \effects If \tcode{is_open()} is \tcode{true}, cancels all outstanding asynchronous operations associated with this socket. Completion handlers for canceled operations are passed an error code \tcode{ec} such that \tcode{ec == errc::operation_canceled} yields \tcode{true}. Disables the linger socket option to prevent the assignment from blocking, and releases socket resources as if by POSIX \tcode{close(native_handle())}. Moves into \tcode{*this} the state originally represented by \tcode{rhs}. @@ -2205,39 +2285,53 @@ \rSec1[socket.dgram]{Class template \tcode{basic_datagram_socket}} \pnum -The class template \tcode{basic_datagram_socket} is used to send and receive discrete messages of fixed maximum length. +The class template \tcode{basic_datagram_socket} is used to send and receive discrete messages of fixed maximum length. \begin{codeblock} namespace std::experimental::net::inline @\namespacever@ { - template - class basic_datagram_socket : public basic_socket + template + class basic_datagram_socket : public basic_socket { public: // types: + using executor_type = Executor; using native_handle_type = @\impdefx{type of \tcode{basic_datagram_socket::native_handle_type}}@; // \nativeref using protocol_type = Protocol; using endpoint_type = typename protocol_type::endpoint; + template + using rebind_executor = + basic_datagram_socket; + // \ref{socket.dgram.cons}, construct / copy / destroy - explicit basic_datagram_socket(io_context& ctx); - basic_datagram_socket(io_context& ctx, const protocol_type& protocol); - basic_datagram_socket(io_context& ctx, const endpoint_type& endpoint); - basic_datagram_socket(io_context& ctx, const protocol_type& protocol, + explicit basic_datagram_socket(const executor_type& ex); + template + explicit basic_datagram_socket(ExecutionContext& ctx); + basic_datagram_socket(const executor_type& ex, const protocol_type& protocol); + template + basic_datagram_socket(ExecutionContext& ctx, const protocol_type& protocol); + basic_datagram_socket(const executor_type& ex, const endpoint_type& endpoint); + template + basic_datagram_socket(ExecutionContext& ctx, const endpoint_type& endpoint); + basic_datagram_socket(const executor_type& ex, const protocol_type& protocol, const native_handle_type& native_socket); + template + basic_datagram_socket(ExecutionContext& ctx, const protocol_type& protocol, + const native_handle_type& native_socket); basic_datagram_socket(const basic_datagram_socket&) = delete; basic_datagram_socket(basic_datagram_socket&& rhs); - template - basic_datagram_socket(basic_datagram_socket&& rhs); + template + basic_datagram_socket(basic_datagram_socket&& rhs); ~basic_datagram_socket(); basic_datagram_socket& operator=(const basic_datagram_socket&) = delete; basic_datagram_socket& operator=(basic_datagram_socket&& rhs); - template - basic_datagram_socket& operator=(basic_datagram_socket&& rhs); + template + basic_datagram_socket& operator=(basic_datagram_socket&& rhs); // \ref{socket.dgram.op}, basic_datagram_socket operations @@ -2356,36 +2450,81 @@ When an operation has its effects specified as if by passing the result of \tcode{native_handle()} to a POSIX function, then the operation fails with error condition \tcode{errc::bad_file_descriptor} if \tcode{is_open() == false} at the point in the effects when the POSIX function is called. \pnum -If \tcode{native_handle_type} and \tcode{basic_socket::native_handle_type} +If \tcode{native_handle_type} and \tcode{basic_socket::native_handle_type} are both defined then they name the same type. \rSec2[socket.dgram.cons]{\tcode{basic_datagram_socket} constructors} \begin{itemdecl} -explicit basic_datagram_socket(io_context& ctx); +explicit basic_datagram_socket(const executor_type& ex); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes the base class with \tcode{basic_socket(ex)}. +\end{itemdescr} + +\begin{itemdecl} +template + explicit basic_datagram_socket(ExecutionContext& ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects Equivalent to \tcode{basic_datagram_socket(ctx.get_executor())}. +\end{itemdescr} + +\begin{itemdecl} +basic_datagram_socket(const executor_type& ex, const protocol_type& protocol); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes the base class with \tcode{basic_socket(ctx, protocol)}. +\end{itemdescr} + +\begin{itemdecl} +template + explicit basic_datagram_socket(ExecutionContext& ctx, const protocol_type& protocol); \end{itemdecl} \begin{itemdescr} \pnum -\effects Initializes the base class with \tcode{basic_socket(ctx)}. +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects Equivalent to \tcode{basic_datagram_socket(ctx.get_executor(), protocol)}. \end{itemdescr} \begin{itemdecl} -basic_datagram_socket(io_context& ctx, const protocol_type& protocol); +basic_datagram_socket(const executor_type& ex, const endpoint_type& endpoint); \end{itemdecl} \begin{itemdescr} \pnum -\effects Initializes the base class with \tcode{basic_socket(ctx, protocol)}. +\effects Initializes the base class with \tcode{basic_socket(ctx, endpoint)}. \end{itemdescr} \begin{itemdecl} -basic_datagram_socket(io_context& ctx, const endpoint_type& endpoint); +template + explicit basic_datagram_socket(ExecutionContext& ctx, const endpoint_type& endpoint); \end{itemdecl} \begin{itemdescr} \pnum -\effects Initializes the base class with \tcode{basic_socket(ctx, endpoint)}. +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects Equivalent to \tcode{basic_datagram_socket(ctx.get_executor(), endpoint)}. \end{itemdescr} \begin{itemdecl} @@ -2395,7 +2534,23 @@ \begin{itemdescr} \pnum -\effects Initializes the base class with \tcode{basic_socket(ctx, protocol, native_socket)}. +\effects Initializes the base class with \tcode{basic_socket(ctx, protocol, native_socket)}. +\end{itemdescr} + +\begin{itemdecl} +template + basic_datagram_socket(ExecutionContext& ctx, const protocol_type& protocol, + const native_handle_type& native_socket); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. +\pnum + +\effects Equivalent to \tcode{basic_datagram_socket(ctx.get_executor(), protocol, native_socket)}. \end{itemdescr} \begin{itemdecl} @@ -2404,20 +2559,20 @@ \begin{itemdescr} \pnum -\effects Move constructs an object of class \tcode{basic_datagram_socket}, initializing the base class with \tcode{basic_socket(std::move(rhs))}. +\effects Move constructs an object of class \tcode{basic_datagram_socket}, initializing the base class with \tcode{basic_socket(std::move(rhs))}. \end{itemdescr} \begin{itemdecl} -template - basic_datagram_socket(basic_datagram_socket&& rhs); +template + basic_datagram_socket(basic_datagram_socket&& rhs); \end{itemdecl} \begin{itemdescr} \pnum -\constraints \tcode{is_convertible_v} is \tcode{true}. +\constraints \tcode{is_convertible_v} is \tcode{true} and \tcode{is_convertible_v} is \tcode{true}. \pnum -\effects Move constructs an object of class \tcode{basic_datagram_socket}, initializing the base class with \tcode{basic_socket(std::move(rhs))}. +\effects Move constructs an object of class \tcode{basic_datagram_socket}, initializing the base class with \tcode{basic_socket(std::move(rhs))}. \end{itemdescr} @@ -2430,26 +2585,29 @@ \begin{itemdescr} \pnum -\effects Equivalent to \tcode{basic_socket::operator=(std::move(rhs))}. +\effects Equivalent to \tcode{basic_socket::operator=(std::move(rhs))}. \pnum \returns \tcode{*this}. \end{itemdescr} \begin{itemdecl} -template - basic_datagram_socket& operator=(basic_datagram_socket&& rhs); +template + basic_datagram_socket& operator=(basic_datagram_socket&& rhs); \end{itemdecl} \begin{itemdescr} \pnum -\constraints \tcode{is_convertible_v} is \tcode{true}. +\requires \tcode{OtherProtocol} is implicitly convertible to \tcode{Protocol} and \tcode{OtherExecutor} is implicitly convertible to \tcode{Executor}. \pnum -\effects Equivalent to \tcode{basic_socket::operator=(std::move(rhs))}. +\effects Equivalent to \tcode{basic_socket::operator=(std::move(rhs))}. \pnum \returns \tcode{*this}. + +\pnum +\remarks This assignment operator not participate in overload resolution unless \tcode{OtherProtocol} is implicitly convertible to \tcode{Protocol} and \tcode{OtherExecutor} is implicitly convertible to \tcode{Executor}. \end{itemdescr} @@ -2866,39 +3024,53 @@ \rSec1[socket.stream]{Class template \tcode{basic_stream_socket}} \pnum -The class template \tcode{basic_stream_socket} is used to exchange data with a peer over a sequenced, reliable, bidirectional, connection-mode byte stream. +The class template \tcode{basic_stream_socket} is used to exchange data with a peer over a sequenced, reliable, bidirectional, connection-mode byte stream. \begin{codeblock} namespace std::experimental::net::inline @\namespacever@ { - template - class basic_stream_socket : public basic_socket + template + class basic_stream_socket : public basic_socket { public: // types: + using executor_type = Executor; using native_handle_type = @\impdefx{type of \tcode{basic_stream_socket::native_handle_type}}@; // \nativeref using protocol_type = Protocol; using endpoint_type = typename protocol_type::endpoint; + template + using rebind_executor = + basic_stream_socket; + // \ref{socket.stream.cons}, construct / copy / destroy - explicit basic_stream_socket(io_context& ctx); - basic_stream_socket(io_context& ctx, const protocol_type& protocol); - basic_stream_socket(io_context& ctx, const endpoint_type& endpoint); - basic_stream_socket(io_context& ctx, const protocol_type& protocol, + explicit basic_stream_socket(const executor_type& ex); + template + explicit basic_stream_socket(ExecutionContext& ctx); + basic_stream_socket(const executor_type& ex, const protocol_type& protocol); + template + basic_stream_socket(ExecutionContext& ctx, const protocol_type& protocol); + basic_stream_socket(const executor_type& ex, const endpoint_type& endpoint); + template + basic_stream_socket(ExecutionContext& ctx, const endpoint_type& endpoint); + basic_stream_socket(const executor_type& ex, const protocol_type& protocol, const native_handle_type& native_socket); + template + basic_stream_socket(ExecutionContext& ctx, const protocol_type& protocol, + const native_handle_type& native_socket); basic_stream_socket(const basic_stream_socket&) = delete; basic_stream_socket(basic_stream_socket&& rhs); - template - basic_stream_socket(basic_stream_socket&& rhs); + template + basic_stream_socket(basic_stream_socket&& rhs); ~basic_stream_socket(); basic_stream_socket& operator=(const basic_stream_socket&) = delete; basic_stream_socket& operator=(basic_stream_socket&& rhs); - template - basic_stream_socket& operator=(basic_stream_socket&& rhs); + template + basic_stream_socket& operator=(basic_stream_socket&& rhs); // \ref{socket.stream.ops}, basic_stream_socket operations @@ -2982,47 +3154,108 @@ When an operation has its effects specified as if by passing the result of \tcode{native_handle()} to a POSIX function, then the operation fails with error condition \tcode{errc::bad_file_descriptor} if \tcode{is_open() == false} at the point in the effects when the POSIX function is called. \pnum -If \tcode{native_handle_type} and \tcode{basic_socket::native_handle_type} +If \tcode{native_handle_type} and \tcode{basic_socket::native_handle_type} are both defined then they name the same type. \rSec2[socket.stream.cons]{\tcode{basic_stream_socket} constructors} \begin{itemdecl} -explicit basic_stream_socket(io_context& ctx); +explicit basic_stream_socket(const executor_type& ex); \end{itemdecl} \begin{itemdescr} \pnum -\effects Initializes the base class with \tcode{basic_socket(ctx)}. +\effects Initializes the base class with \tcode{basic_socket(ctx)}. \end{itemdescr} \begin{itemdecl} -basic_stream_socket(io_context& ctx, const protocol_type& protocol); +template + explicit basic_stream_socket(ExecutionContext& ctx); \end{itemdecl} \begin{itemdescr} \pnum -\effects Initializes the base class with \tcode{basic_socket(ctx, protocol)}. +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects Equivalent to \tcode{basic_stream_socket(ctx.get_executor())}. \end{itemdescr} \begin{itemdecl} -basic_stream_socket(io_context& ctx, const endpoint_type& endpoint); +basic_stream_socket(const executor_type& ex, const protocol_type& protocol); \end{itemdecl} \begin{itemdescr} \pnum -\effects Initializes the base class with \tcode{basic_socket(ctx, endpoint)}. +\effects Initializes the base class with \tcode{basic_socket(ctx, protocol)}. \end{itemdescr} \begin{itemdecl} -basic_stream_socket(io_context& ctx, const protocol_type& protocol, +template + explicit basic_stream_socket(ExecutionContext& ctx, const protocol_type& protocol); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects Equivalent to \tcode{basic_stream_socket(ctx.get_executor(), protocol)}. +\end{itemdescr} + +\begin{itemdecl} +basic_stream_socket(const executor_type& ex, const endpoint_type& endpoint); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes the base class with \tcode{basic_socket(ctx, endpoint)}. +\end{itemdescr} + +\begin{itemdecl} +template + explicit basic_stream_socket(ExecutionContext& ctx, const endpoint_type& endpoint); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects Equivalent to \tcode{basic_stream_socket(ctx.get_executor(), endpoint)}. +\end{itemdescr} + +\begin{itemdecl} +basic_stream_socket(const executor_type& ex, const protocol_type& protocol, + const native_handle_type& native_socket); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Initializes the base class with \tcode{basic_socket(ctx, protocol, native_socket)}. +\end{itemdescr} + +\begin{itemdecl} +template + basic_stream_socket(ExecutionContext& ctx, const protocol_type& protocol, const native_handle_type& native_socket); \end{itemdecl} \begin{itemdescr} \pnum -\effects Initializes the base class with \tcode{basic_socket(ctx, protocol, native_socket)}. +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects Equivalent to \tcode{basic_stream_socket(ctx.get_executor(), protocol, native_socket)}. \end{itemdescr} \begin{itemdecl} @@ -3031,20 +3264,20 @@ \begin{itemdescr} \pnum -\effects Move constructs an object of class \tcode{basic_stream_socket}, initializing the base class with \tcode{basic_socket(std::move(rhs))}. +\effects Move constructs an object of class \tcode{basic_stream_socket}, initializing the base class with \tcode{basic_socket(std::move(rhs))}. \end{itemdescr} \begin{itemdecl} -template - basic_stream_socket(basic_stream_socket&& rhs); +template + basic_stream_socket(basic_stream_socket&& rhs); \end{itemdecl} \begin{itemdescr} \pnum -\constraints \tcode{is_convertible_v} is \tcode{true}. +\constraints \tcode{is_convertible_v} is \tcode{true} and \tcode{is_convertible_v} is \tcode{true}. \pnum -\effects Move constructs an object of class \tcode{basic_stream_socket}, initializing the base class with \tcode{basic_socket(std::move(rhs))}. +\effects Move constructs an object of class \tcode{basic_stream_socket}, initializing the base class with \tcode{basic_socket(std::move(rhs))}. \end{itemdescr} @@ -3057,23 +3290,23 @@ \begin{itemdescr} \pnum -\effects Equivalent to \tcode{basic_socket::operator=(std::move(rhs))}. +\effects Equivalent to \tcode{basic_socket::operator=(std::move(rhs))}. \pnum \returns \tcode{*this}. \end{itemdescr} \begin{itemdecl} -template - basic_stream_socket& operator=(basic_stream_socket&& rhs); +template + basic_stream_socket& operator=(basic_stream_socket&& rhs); \end{itemdecl} \begin{itemdescr} \pnum -\constraints \tcode{is_convertible_v} is \tcode{true}. +\constraints \tcode{is_convertible_v} is \tcode{true} and \tcode{is_convertible_v} is \tcode{true}. \pnum -\effects Equivalent to \tcode{basic_socket::operator=(std::move(rhs))}. +\effects Equivalent to \tcode{basic_socket::operator=(std::move(rhs))}. \pnum \returns \tcode{*this}. @@ -3336,42 +3569,59 @@ \rSec1[socket.acceptor]{Class template \tcode{basic_socket_acceptor}} \pnum -An object of class template \tcode{basic_socket_acceptor} is used to listen for, and queue, incoming socket connections. Socket objects that represent the incoming connections are dequeued by calling \tcode{accept} or \tcode{async_accept}. +An object of class template \tcode{basic_socket_acceptor} is used to listen for, and queue, incoming socket connections. Socket objects that represent the incoming connections are dequeued by calling \tcode{accept} or \tcode{async_accept}. \begin{codeblock} namespace std::experimental::net::inline @\namespacever@ { - template + template class basic_socket_acceptor : public socket_base { public: // types: - using executor_type = io_context::executor_type; + using executor_type = Executor; using native_handle_type = @\impdefx{type of \tcode{basic_socket_acceptor::native_handle_type}}@; // \nativeref using protocol_type = AcceptableProtocol; using endpoint_type = typename protocol_type::endpoint; using socket_type = typename protocol_type::socket; + template + using socket_type_for + = typename protocol_type::socket_for; + + template + using rebind_executor = + basic_socket_acceptor; // \ref{socket.acceptor.cons}, construct / copy / destroy - explicit basic_socket_acceptor(io_context& ctx); - basic_socket_acceptor(io_context& ctx, const protocol_type& protocol); - basic_socket_acceptor(io_context& ctx, const endpoint_type& endpoint, + explicit basic_socket_acceptor(const executor_type& ex); + template + explicit basic_socket_acceptor(ExecutionContext& ctx); + basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol); + template + basic_socket_acceptor(ExecutionContext& ctx, const protocol_type& protocol); + basic_socket_acceptor(const executor_type& ex, const endpoint_type& endpoint, bool reuse_addr = true); - basic_socket_acceptor(io_context& ctx, const protocol_type& protocol, - const native_handle_type& native_acceptor); + template + basic_socket_acceptor(ExecutionContext& ctx, const endpoint_type& endpoint, + bool reuse_addr = true); + basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol, + const native_handle_type& native_socket); + template + basic_socket_acceptor(ExecutionContext& ctx, const protocol_type& protocol, + const native_handle_type& native_socket); basic_socket_acceptor(const basic_socket_acceptor&) = delete; basic_socket_acceptor(basic_socket_acceptor&& rhs); - template - basic_socket_acceptor(basic_socket_acceptor&& rhs); + template + basic_socket_acceptor(basic_socket_acceptor&& rhs); ~basic_socket_acceptor(); basic_socket_acceptor& operator=(const basic_socket_acceptor&) = delete; basic_socket_acceptor& operator=(basic_socket_acceptor&& rhs); - template - basic_socket_acceptor& operator=(basic_socket_acceptor&& rhs); + template + basic_socket_acceptor& operator=(basic_socket_acceptor&& rhs); // \ref{socket.acceptor.ops}, basic_socket_acceptor operations @@ -3436,25 +3686,49 @@ socket_type accept(); socket_type accept(error_code& ec); - socket_type accept(io_context& ctx); - socket_type accept(io_context& ctx, error_code& ec); + template + socket_type_for + accept(const OtherExecutor& ex); + template + socket_type_for + accept(const OtherExecutor& ex, error_code& ec); + template + socket_type_for + accept(ExecutionContext& ctx); + template + socket_type_for + accept(ExecutionContext& ctx, error_code& ec); template @\DEDUCED@ async_accept(CompletionToken&& token); - template - @\DEDUCED@ async_accept(io_context& ctx, CompletionToken&& token); + template + \DEDUCED\ async_accept(const OtherExecutor& ex, CompletionToken&& token); + template + \DEDUCED\ async_accept(ExecutionContext& ctx, CompletionToken&& token); socket_type accept(endpoint_type& endpoint); socket_type accept(endpoint_type& endpoint, error_code& ec); - socket_type accept(io_context& ctx, endpoint_type& endpoint); - socket_type accept(io_context& ctx, endpoint_type& endpoint, - error_code& ec); + template + socket_type_for + accept(const OtherExecutor& ex, endpoint_type& endpoint); + template + socket_type_for + accept(const OtherExecutor& ex, endpoint_type& endpoint, error_code& ec); + template + socket_type_for + accept(ExecutionContext& ctx, endpoint_type& endpoint); + template + socket_type_for + accept(ExecutionContext& ctx, endpoint_type& endpoint, error_code& ec); template @\DEDUCED@ async_accept(endpoint_type& endpoint, CompletionToken&& token); - template - @\DEDUCED@ async_accept(io_context& ctx, endpoint_type& endpoint, + template + \DEDUCED\ async_accept(const OtherExecutor& ex, endpoint_type& endpoint, + CompletionToken&& token); + template + \DEDUCED\ async_accept(ExecutionContext& ctx, endpoint_type& endpoint, CompletionToken&& token); void wait(wait_type w); @@ -3483,7 +3757,7 @@ \rSec2[socket.acceptor.cons]{\tcode{basic_socket_acceptor} constructors} \begin{itemdecl} -explicit basic_socket_acceptor(io_context& ctx); +explicit basic_socket_acceptor(const executor_type& ex); \end{itemdecl} \begin{itemdescr} @@ -3491,14 +3765,29 @@ \postconditions \begin{itemize} \item -\tcode{get_executor() == ctx.get_executor()}. +\tcode{get_executor() == ex}. \item \tcode{is_open() == false}. \end{itemize} \end{itemdescr} \begin{itemdecl} -basic_socket_acceptor(io_context& ctx, const protocol_type& protocol); +template + explicit basic_socket_acceptor(ExecutionContext& ctx); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects Equivalent to \tcode{basic_socket_acceptor(ctx.get_executor())}. +\end{itemdescr} + +\begin{itemdecl} +basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol); \end{itemdecl} \begin{itemdescr} @@ -3509,7 +3798,7 @@ \postconditions \begin{itemize} \item -\tcode{get_executor() == ctx.get_executor()}. +\tcode{get_executor() == ex}. \item \tcode{is_open() == true}. \item @@ -3522,7 +3811,22 @@ \end{itemdescr} \begin{itemdecl} -basic_socket_acceptor(io_context& ctx, const endpoint_type& endpoint, +template + explicit basic_socket_acceptor(ExecutionContext& ctx, const protocol_type& protocol); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects Equivalent to \tcode{basic_socket_acceptor(ctx.get_executor(), protocol)}. +\end{itemdescr} + +\begin{itemdecl} +basic_socket_acceptor(const executor_type& ex, const endpoint_type& endpoint, bool reuse_addr = true); \end{itemdecl} @@ -3542,7 +3846,7 @@ \postconditions \begin{itemize} \item -\tcode{get_executor() == ctx.get_executor()}. +\tcode{get_executor() == ex}. \item \tcode{is_open() == true}. \item @@ -3555,7 +3859,23 @@ \end{itemdescr} \begin{itemdecl} -basic_socket_acceptor(io_context& ctx, const protocol_type& protocol, +template + explicit basic_socket_acceptor(ExecutionContext& ctx, const endpoint_type& endpoint, + bool reuse_addr = true); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects Equivalent to \tcode{basic_socket_acceptor(ctx.get_executor(), endpoint, reuse_addr)}. +\end{itemdescr} + +\begin{itemdecl} +basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol, const native_handle_type& native_acceptor); \end{itemdecl} @@ -3570,7 +3890,7 @@ \postconditions \begin{itemize} \item -\tcode{get_executor() == ctx.get_executor()}. +\tcode{get_executor() == ex}. \item \tcode{is_open() == true}. \item @@ -3582,13 +3902,29 @@ \end{itemize} \end{itemdescr} +\begin{itemdecl} +template + basic_socket_acceptor(ExecutionContext& ctx, const protocol_type& protocol, + const native_handle_type& native_socket); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects Equivalent to \tcode{basic_socket_acceptor(ctx.get_executor(), protocol, native_socket)}. +\end{itemdescr} + \begin{itemdecl} basic_socket_acceptor(basic_socket_acceptor&& rhs); \end{itemdecl} \begin{itemdescr} \pnum -\effects Move constructs an object of class \tcode{basic_socket_acceptor} that refers to the state originally represented by \tcode{rhs}. +\effects Move constructs an object of class \tcode{basic_socket_acceptor} that refers to the state originally represented by \tcode{rhs}. \pnum \postconditions @@ -3611,16 +3947,16 @@ \end{itemdescr} \begin{itemdecl} -template - basic_socket_acceptor(basic_socket_acceptor&& rhs); +template + basic_socket_acceptor(basic_socket_acceptor&& rhs); \end{itemdecl} \begin{itemdescr} \pnum -\constraints \tcode{is_convertible_v} is \tcode{true}. +\constraints \tcode{is_convertible_v} is \tcode{true} and \tcode{is_convertible_v} is \tcode{true}. \pnum -\effects Move constructs an object of class \tcode{basic_socket_acceptor} that refers to the state originally represented by \tcode{rhs}. +\effects Move constructs an object of class \tcode{basic_socket_acceptor} that refers to the state originally represented by \tcode{rhs}. \pnum \postconditions @@ -3691,13 +4027,13 @@ \end{itemdescr} \begin{itemdecl} -template - basic_socket_acceptor& operator=(basic_socket_acceptor&& rhs); +template + basic_socket_acceptor& operator=(basic_socket_acceptor&& rhs); \end{itemdecl} \begin{itemdescr} \pnum -\constraints \tcode{is_convertible_v} is \tcode{true}. +\constraints \tcode{is_convertible_v} is \tcode{true} and \tcode{is_convertible_v} is \tcode{true}. \pnum \effects If \tcode{is_open()} is \tcode{true}, cancels all outstanding asynchronous operations associated with this acceptor, and releases acceptor resources as if by POSIX \tcode{close(native_handle())}. Then moves into \tcode{*this} the state originally represented by \tcode{rhs}. Completion handlers for canceled operations are passed an error code \tcode{ec} such that \tcode{ec == errc::operation_canceled} yields \tcode{true}. @@ -4090,12 +4426,16 @@ \begin{itemdescr} \pnum -\returns \tcode{accept(get_executor().context(), ec)}. +\returns \tcode{accept(get_executor(), ec)}. \end{itemdescr} \begin{itemdecl} -socket_type accept(io_context& ctx); -socket_type accept(io_context& ctx, error_code& ec); +template + socket_type_for + accept(const OtherExecutor& ex); +template + socket_type_for + accept(const OtherExecutor& ex, error_code& ec); \end{itemdecl} \begin{itemdescr} @@ -4107,7 +4447,21 @@ \pnum -\returns On success, \tcode{socket_type(ctx, protocol_, h)}. Otherwise \tcode{socket_type(ctx)}. +\returns On success, \tcode{socket_type_for(ex, protocol_, h)}. Otherwise \tcode{socket_type_for(ex)}. +\end{itemdescr} + +\begin{itemdecl} +template + socket_type_for + accept(ExecutionContext& ctx); +template + socket_type_for + accept(ExecutionContext& ctx, error_code& ec); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{accept(ctx.get_executor(), ec)}. \end{itemdescr} \begin{itemdecl} @@ -4119,25 +4473,41 @@ \pnum \returns \begin{codeblock} -async_accept(get_executor().context(), forward(token)) +async_accept(get_executor(), forward(token)) \end{codeblock} \end{itemdescr} \begin{itemdecl} -template - @\DEDUCED@ async_accept(io_context& ctx, CompletionToken&& token); +template + \DEDUCED\ async_accept(const OtherExecutor& ex, CompletionToken&& token); \end{itemdecl} \begin{itemdescr} \pnum -\completionsig \tcode{void(error_code ec, socket_type s)}. +Let \tcode{S} be the type \tcode{socket_type_for}. + +\pnum +\completionsig \tcode{void(error_code ec, S s)}. \pnum \effects Initiates an asynchronous operation to extract a socket from the queue of pending connections of the acceptor, as if by POSIX: \begin{codeblock} native_handle_type h = accept(native_handle(), nullptr, 0); \end{codeblock} - On success, \tcode{s} is \tcode{socket_type(ctx, protocol_, h)}. Otherwise, \tcode{s} is \tcode{socket_type(ctx)}. +On success, \tcode{s} is \tcode{S(ex, protocol_, h)}. Otherwise, \tcode{s} is \tcode{S(ex)}. +\end{itemdescr} + +\begin{itemdecl} +template + \DEDUCED\ async_accept(ExecutionContext& ctx, CompletionToken&& token); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +async_accept(ctx.get_executor(), forward(token)) +\end{codeblock} \end{itemdescr} \begin{itemdecl} @@ -4147,13 +4517,16 @@ \begin{itemdescr} \pnum -\returns \tcode{accept(get_executor().context(), endpoint, ec)}. +\returns \tcode{accept(get_executor(), endpoint, ec)}. \end{itemdescr} \begin{itemdecl} -socket_type accept(io_context& ctx, endpoint_type& endpoint); -socket_type accept(io_context& ctx, endpoint_type& endpoint, - error_code& ec); +template + socket_type_for + accept(const OtherExecutor& ex, endpoint_type& endpoint); +template + socket_type_for + accept(const OtherExecutor& ex, endpoint_type& endpoint, error_code& ec); \end{itemdecl} \begin{itemdescr} @@ -4170,7 +4543,21 @@ \pnum -\returns On success, \tcode{socket_type(ctx, protocol_, h)}. Otherwise \tcode{socket_type(ctx)}. +\returns On success, \tcode{socket_type(ex, protocol_, h)}. Otherwise \tcode{socket_type(ex)}. +\end{itemdescr} + +\begin{itemdecl} +template + socket_type_for + accept(ExecutionContext& ctx, endpoint_type& endpoint); +template + socket_type_for + accept(ExecutionContext& ctx, endpoint_type& endpoint, error_code& ec); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns \tcode{accept(ctx.get_executor(), endpoint, ec)}. \end{itemdescr} \begin{itemdecl} @@ -4183,19 +4570,22 @@ \pnum \returns \begin{codeblock} -async_accept(get_executor().context(), endpoint, forward(token)) +async_accept(get_executor(), endpoint, forward(token)) \end{codeblock} \end{itemdescr} \begin{itemdecl} -template - @\DEDUCED@ async_accept(io_context& ctx, endpoint_type& endpoint, +template + \DEDUCED\ async_accept(const OtherExecutor& ex, endpoint_type& endpoint, CompletionToken&& token); \end{itemdecl} \begin{itemdescr} \pnum -\completionsig \tcode{void(error_code ec, socket_type s)}. +Let \tcode{S} be the type \tcode{socket_type_for}. + +\pnum +\completionsig \tcode{void(error_code ec, S s)}. \pnum \effects Initiates an asynchronous operation to extract a socket from the queue of pending connections of the acceptor, as if by POSIX: @@ -4207,7 +4597,21 @@ if (h >= 0) endpoint.resize(endpoint_len); \end{codeblock} -On success, \tcode{s} is \tcode{socket_type(ctx, protocol_, h)}. Otherwise, \tcode{s} is \tcode{socket_type(ctx)}. +On success, \tcode{s} is \tcode{S(ex, protocol_, h)}. Otherwise, \tcode{s} is \tcode{S(ex)}. +\end{itemdescr} + +\begin{itemdecl} +template + \DEDUCED\ async_accept(ExecutionContext& ctx, endpoint_type& endpoint, + CompletionToken&& token); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\returns +\begin{codeblock} +async_accept(ctx.get_executor(), forward(token)) +\end{codeblock} \end{itemdescr} \begin{itemdecl} diff --git a/src/socketstreams.tex b/src/socketstreams.tex index 987248a..a3c34f4 100644 --- a/src/socketstreams.tex +++ b/src/socketstreams.tex @@ -6,7 +6,7 @@ \rSec1[socket.streambuf]{Class template \tcode{basic_socket_streambuf}} \pnum -The class \tcode{basic_socket_streambuf} associates both the input sequence and the output sequence with a socket. The input and output sequences do not support seeking. \begin{note} The input and output sequences are independent as a stream socket provides full duplex I/O. \end{note} +The class \tcode{basic_socket_streambuf} associates both the input sequence and the output sequence with a socket. The input and output sequences do not support seeking. \begin{note} The input and output sequences are independent as a stream socket provides full duplex I/O. \end{note} \pnum \begin{note} This class is intended for sending and receiving bytes, not characters. Any conversion from characters to bytes, and vice versa, occurs elsewhere. \end{note} @@ -14,12 +14,13 @@ \begin{codeblock} namespace std::experimental::net::inline @\namespacever@ { - template + template class basic_socket_streambuf : public basic_streambuf { public: // types: + using executor_type = Executor; using protocol_type = Protocol; using endpoint_type = typename protocol_type::endpoint; using clock_type = Clock; @@ -30,7 +31,7 @@ // \ref{socket.streambuf.cons}, construct / copy / destroy basic_socket_streambuf(); - explicit basic_socket_streambuf(basic_stream_socket s); + explicit basic_socket_streambuf(basic_stream_socket s); basic_socket_streambuf(const basic_socket_streambuf&) = delete; basic_socket_streambuf(basic_socket_streambuf&& rhs); @@ -46,7 +47,7 @@ basic_socket_streambuf* close(); - basic_socket& socket(); + basic_socket& socket(); error_code error() const; time_point expiry() const; @@ -62,7 +63,7 @@ virtual streambuf* setbuf(char_type* s, streamsize n) override; private: - basic_stream_socket socket_; // \expos + basic_stream_socket socket_; // \expos error_code ec_; // \expos time_point expiry_; // \expos }; @@ -81,6 +82,10 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_constructible_v} is \tcode{true}. + \pnum \effects Initializes \tcode{socket_} with \tcode{ctx}, where \tcode{ctx} is an unspecified object of class \tcode{io_context}. @@ -89,7 +94,7 @@ \end{itemdescr} \begin{itemdecl} -explicit basic_socket_streambuf(basic_stream_socket s); +explicit basic_socket_streambuf(basic_stream_socket s); \end{itemdecl} \begin{itemdescr} @@ -152,7 +157,7 @@ \begin{itemdescr} \pnum -\effects If a put area exists, calls \tcode{overflow(traits_type::eof())} to flush characters. \begin{note} The socket is closed by the \tcode{basic_stream_socket} destructor. \end{note} +\effects If a put area exists, calls \tcode{overflow(traits_type::eof())} to flush characters. \begin{note} The socket is closed by the \tcode{basic_stream_socket} destructor. \end{note} \end{itemdescr} \begin{itemdecl} @@ -210,7 +215,7 @@ \begin{itemdescr} \pnum -\effects If a put area exists, calls \tcode{overflow(traits_type::eof())} to flush characters. Regardless of whether the preceding call fails or throws an exception, the function closes the socket as if by \tcode{basic_socket::close(ec_)}. If any of the calls made by the function fail, \tcode{close} fails by returning a null pointer. If one of these calls throws an exception, the exception is caught and rethrown after closing the socket. +\effects If a put area exists, calls \tcode{overflow(traits_type::eof())} to flush characters. Regardless of whether the preceding call fails or throws an exception, the function closes the socket as if by \tcode{basic_socket::close(ec_)}. If any of the calls made by the function fail, \tcode{close} fails by returning a null pointer. If one of these calls throws an exception, the exception is caught and rethrown after closing the socket. \pnum \returns \tcode{this} on success, a null pointer otherwise. @@ -220,7 +225,7 @@ \end{itemdescr} \begin{itemdecl} -basic_socket& socket(); +basic_socket& socket(); \end{itemdecl} \begin{itemdescr} @@ -349,7 +354,7 @@ \rSec1[socket.iostream]{Class template \tcode{basic_socket_iostream}} \pnum -The class template \tcode{basic_socket_iostream} supports reading and writing on sockets. It uses a \tcode{basic_socket_streambuf} object to control the associated sequences. +The class template \tcode{basic_socket_iostream} supports reading and writing on sockets. It uses a \tcode{basic_socket_streambuf} object to control the associated sequences. \pnum \begin{note} This class is intended for sending and receiving bytes, not characters. Any conversion from characters to bytes, and vice versa, occurs elsewhere. \end{note} @@ -357,12 +362,13 @@ \begin{codeblock} namespace std::experimental::net::inline @\namespacever@ { - template + template class basic_socket_iostream : public basic_iostream { public: // types: + using executor_type = Executor; using protocol_type = Protocol; using endpoint_type = typename protocol_type::endpoint; using clock_type = Clock; @@ -373,7 +379,7 @@ // \ref{socket.iostream.cons}, construct / copy / destroy basic_socket_iostream(); - explicit basic_socket_iostream(basic_stream_socket s); + explicit basic_socket_iostream(basic_stream_socket s); basic_socket_iostream(const basic_socket_iostream&) = delete; basic_socket_iostream(basic_socket_iostream&& rhs); template @@ -388,9 +394,9 @@ void close(); - basic_socket_streambuf* rdbuf() const; + basic_socket_streambuf* rdbuf() const; - basic_socket& socket(); + basic_socket& socket(); error_code error() const; time_point expiry() const; @@ -398,7 +404,7 @@ void expires_after(const duration& d); private: - basic_socket_streambuf sb_; // \expos + basic_socket_streambuf sb_; // \expos }; } // inline namespace std::experimental::net::\namespacever @@ -415,12 +421,16 @@ \end{itemdecl} \begin{itemdescr} +\pnum +\constraints +\tcode{is_default_constructible_v>} is \tcode{true}. + \pnum \effects Initializes the base class as \tcode{basic_iostream(addressof(sb_))}, value-initializes \tcode{sb_}, and performs \tcode{setf(std::ios_base::unitbuf)}. \end{itemdescr} \begin{itemdecl} -explicit basic_socket_iostream(basic_stream_socket s); +explicit basic_socket_iostream(basic_stream_socket s); \end{itemdecl} \begin{itemdescr} @@ -487,19 +497,19 @@ \end{itemdescr} \begin{itemdecl} -basic_socket_streambuf* rdbuf() const; +basic_socket_streambuf* rdbuf() const; \end{itemdecl} \begin{itemdescr} \pnum -Let \tcode{SB} be the type \tcode{basic_socket_streambuf}. +Let \tcode{SB} be the type \tcode{basic_socket_streambuf}. \pnum \returns \tcode{const_cast(addressof(sb_))}. \end{itemdescr} \begin{itemdecl} -basic_socket& socket(); +basic_socket& socket(); \end{itemdecl} \begin{itemdescr} diff --git a/src/timers.tex b/src/timers.tex index 0d15fe0..d3087b4 100644 --- a/src/timers.tex +++ b/src/timers.tex @@ -39,7 +39,7 @@ template struct wait_traits; - template> + template, class Executor = executor> class basic_waitable_timer; using system_timer = basic_waitable_timer; @@ -155,23 +155,33 @@ \begin{codeblock} namespace std::experimental::net::inline @\namespacever@ { - template> + template, class Executor = executor> class basic_waitable_timer { public: // types: - using executor_type = io_context::executor_type; + using executor_type = Executor; using clock_type = Clock; using duration = typename clock_type::duration; using time_point = typename clock_type::time_point; using traits_type = WaitTraits; + template + using rebind_executor = + basic_waitable_timer; + // \ref{timer.waitable.cons}, construct / copy / destroy - explicit basic_waitable_timer(io_context& ctx); - basic_waitable_timer(io_context& ctx, const time_point& t); - basic_waitable_timer(io_context& ctx, const duration& d); + explicit basic_waitable_timer(const executor_type& ex); + template + explicit basic_waitable_timer(ExecutionContext& ctx); + basic_waitable_timer(const executor_type& ex, const time_point& t); + template + basic_waitable_timer(ExecutionContext& ctx, const time_point& t); + basic_waitable_timer(const executor_type& ex, const duration& d); + template + basic_waitable_timer(ExecutionContext& ctx, const duration& d); basic_waitable_timer(const basic_waitable_timer&) = delete; basic_waitable_timer(basic_waitable_timer&& rhs); @@ -209,16 +219,31 @@ \indexlibrary{\idxcode{basic_waitable_timer}!constructor}% \begin{itemdecl} -explicit basic_waitable_timer(io_context& ctx); +explicit basic_waitable_timer(const executor_type& ex); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects Equivalent to \tcode{basic_waitable_timer(ex, time_point())}. +\end{itemdescr} + +\begin{itemdecl} +template + explicit basic_waitable_timer(ExecutionContext& ctx); \end{itemdecl} \begin{itemdescr} \pnum -\effects Equivalent to \tcode{basic_waitable_timer(ctx, time_point())}. +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects Equivalent to \tcode{basic_waitable_timer(ctx.get_executor())}. \end{itemdescr} \begin{itemdecl} -basic_waitable_timer(io_context& ctx, const time_point& t); +basic_waitable_timer(const executor_type& ex, const time_point& t); \end{itemdecl} \begin{itemdescr} @@ -226,14 +251,29 @@ \postconditions \begin{itemize} \item -\tcode{get_executor() == ctx.get_executor()}. +\tcode{get_executor() == ex}. \item \tcode{expiry() == t}. \end{itemize} \end{itemdescr} \begin{itemdecl} -basic_waitable_timer(io_context& ctx, const duration& d); +template + basic_waitable_timer(ExecutionContext& ctx, const time_point& t); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects Equivalent to \tcode{basic_waitable_timer(ctx.get_executor(), t)}. +\end{itemdescr} + +\begin{itemdecl} +basic_waitable_timer(const executor_type& ex, const duration& d); \end{itemdecl} \begin{itemdescr} @@ -241,7 +281,22 @@ \effects Sets the expiry time as if by calling \tcode{expires_after(d)}. \pnum -\postconditions \tcode{get_executor() == ctx.get_executor()}. +\postconditions \tcode{get_executor() == ex}. +\end{itemdescr} + +\begin{itemdecl} +template + basic_waitable_timer(ExecutionContext& ctx, const duration& d); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\constraints +\tcode{is_convertible_v} is \tcode{true} +and \tcode{is_constructible_v} is \tcode{true}. + +\pnum +\effects Equivalent to \tcode{basic_waitable_timer(ctx.get_executor(), d)}. \end{itemdescr} \begin{itemdecl}