// <experimental/socket> -*- C++ -*-

// Copyright (C) 2015-2021 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file experimental/socket
 *  This is a TS C++ Library header.
 *  @ingroup networking-ts
 */

#ifndef _GLIBCXX_EXPERIMENTAL_SOCKET
#define _GLIBCXX_EXPERIMENTAL_SOCKET

#pragma GCC system_header

#if __cplusplus >= 201402L

#include <experimental/netfwd>
#include <experimental/buffer>
#include <experimental/io_context>
#include <experimental/bits/net.h>
#include <streambuf>
#include <istream>
#include <bits/unique_ptr.h>
#if _GLIBCXX_HAVE_UNISTD_H
# include <unistd.h>
# ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
#  include <sys/socket.h>	// socket etc
# endif
# ifdef _GLIBCXX_HAVE_SYS_IOCTL_H
#  include <sys/ioctl.h>	// ioctl
# endif
# ifdef _GLIBCXX_HAVE_SYS_UIO_H
#  include <sys/uio.h>		// iovec
# endif
# ifdef _GLIBCXX_HAVE_POLL_H
#  include <poll.h>		// poll, pollfd, POLLIN, POLLOUT, POLLERR
# endif
# ifdef _GLIBCXX_HAVE_FCNTL_H
#  include <fcntl.h>		// fcntl, F_GETFL, F_SETFL
# endif
#endif

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace experimental
{
namespace net
{
inline namespace v1
{

  /** @addtogroup networking-ts
   *  @{
   */

  enum class socket_errc {  // TODO decide values
    already_open = 3,
    not_found = 4
  };

} // namespace v1
} // namespace net
} // namespace experimental

  template<>
    struct is_error_code_enum<experimental::net::v1::socket_errc>
    : public true_type {};

namespace experimental
{
namespace net
{
inline namespace v1
{
  const error_category& socket_category() noexcept
  {
    struct __cat : error_category
    {
      const char* name() const noexcept { return "socket"; }

      std::string message(int __e) const
      {
	if (__e == (int)socket_errc::already_open)
	  return "already open";
	else if (__e == (int)socket_errc::not_found)
	  return "endpoint not found";
	return "socket error";
      }

      virtual void __message(int) { } // TODO dual ABI XXX
    };
    static __cat __c;
    return __c;
  }

  inline error_code
  make_error_code(socket_errc __e) noexcept
  { return error_code(static_cast<int>(__e), socket_category()); }

  inline error_condition
  make_error_condition(socket_errc __e) noexcept
  { return error_condition(static_cast<int>(__e), socket_category()); }


  // TODO GettableSocket reqs
  // TODO SettableSocket reqs
  // TODO BooleanSocketOption reqs
  // TODO IntegerSocketOption reqs
  // TODO IoControlCommand reqs
  // TODO ConnectCondition reqs

  /** @brief Sockets
   * @{
   */

  class socket_base
  {
  public:
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
    class broadcast : public __sockopt_crtp<broadcast, bool>
    {
    public:
      using __sockopt_crtp::__sockopt_crtp;
      using __sockopt_crtp::operator=;

    private:
      friend __sockopt_crtp<broadcast, bool>;
      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_BROADCAST;
    };

    class debug : public __sockopt_crtp<debug, bool>
    {
    public:
      friend __sockopt_crtp<debug, bool>;
      using __sockopt_crtp::__sockopt_crtp;
      using __sockopt_crtp::operator=;

    private:
      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_DEBUG;
    };

    class do_not_route : public __sockopt_crtp<do_not_route, bool>
    {
    public:
      using __sockopt_crtp::__sockopt_crtp;
      using __sockopt_crtp::operator=;

    private:
      friend __sockopt_crtp<do_not_route, bool>;
      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_DONTROUTE;
    };

    class keep_alive : public __sockopt_crtp<keep_alive, bool>
    {
    public:
      using __sockopt_crtp::__sockopt_crtp;
      using __sockopt_crtp::operator=;

    private:
      friend __sockopt_crtp<keep_alive, bool>;
      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_KEEPALIVE;
    };

    class linger : public __sockopt_crtp<linger, ::linger>
    {
    public:
      using __sockopt_crtp::__sockopt_crtp;
      using __sockopt_crtp::operator=;

      linger() noexcept = default;

      linger(bool __e, chrono::seconds __t) noexcept
      {
	enabled(__e);
	timeout(__t);
      }

      bool
      enabled() const noexcept
      { return _M_value.l_onoff != 0; }

      void
      enabled(bool __e) noexcept
      { _M_value.l_onoff = int(__e); }

      chrono::seconds
      timeout() const noexcept
      { return chrono::seconds(_M_value.l_linger); }

      void
      timeout(chrono::seconds __t) noexcept
      { _M_value.l_linger = __t.count(); }

    private:
      friend __sockopt_crtp<linger, ::linger>;
      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_LINGER;
    };

    class out_of_band_inline : public __sockopt_crtp<out_of_band_inline, bool>
    {
    public:
      using __sockopt_crtp::__sockopt_crtp;
      using __sockopt_crtp::operator=;

    private:
      friend __sockopt_crtp<out_of_band_inline, bool>;
      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_OOBINLINE;
    };

    class receive_buffer_size : public __sockopt_crtp<receive_buffer_size>
    {
    public:
      using __sockopt_crtp::__sockopt_crtp;
      using __sockopt_crtp::operator=;

    private:
      friend __sockopt_crtp<receive_buffer_size>;
      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_RCVBUF;
    };

    class receive_low_watermark : public __sockopt_crtp<receive_low_watermark>
    {
    public:
      using __sockopt_crtp::__sockopt_crtp;
      using __sockopt_crtp::operator=;

    private:
      friend __sockopt_crtp<receive_low_watermark>;
      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_RCVLOWAT;
    };

    class reuse_address : public __sockopt_crtp<reuse_address, bool>
    {
    public:
      using __sockopt_crtp::__sockopt_crtp;
      using __sockopt_crtp::operator=;

    private:
      friend __sockopt_crtp<reuse_address, bool>;
      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_REUSEADDR;
    };

    class send_buffer_size : public __sockopt_crtp<send_buffer_size>
    {
    public:
      using __sockopt_crtp::__sockopt_crtp;
      using __sockopt_crtp::operator=;

    private:
      friend __sockopt_crtp<send_buffer_size>;
      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_SNDBUF;
    };

    class send_low_watermark : public __sockopt_crtp<send_low_watermark>
    {
    public:
      using __sockopt_crtp::__sockopt_crtp;
      using __sockopt_crtp::operator=;

    private:
      friend __sockopt_crtp<send_low_watermark>;
      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_SNDLOWAT;
    };
#endif // HAVE_SYS_SOCKET_H

    enum shutdown_type : int { };
#if defined SHUT_RD && defined SHUT_WR && defined SHUT_RDWR
    static constexpr shutdown_type shutdown_receive = (shutdown_type)SHUT_RD;
    static constexpr shutdown_type shutdown_send    = (shutdown_type)SHUT_WR;
    static constexpr shutdown_type shutdown_both    = (shutdown_type)SHUT_RDWR;
#endif

    enum wait_type : int { };
#ifdef _GLIBCXX_HAVE_POLL_H
    static constexpr wait_type wait_read  = (wait_type)POLLIN;
    static constexpr wait_type wait_write = (wait_type)POLLOUT;
    static constexpr wait_type wait_error = (wait_type)POLLERR;
#else
    static constexpr wait_type wait_read  = (wait_type)1;
    static constexpr wait_type wait_write = (wait_type)2;
    static constexpr wait_type wait_error = (wait_type)4;
#endif

    enum message_flags : int { };
#if defined MSG_PEEK && defined MSG_OOB && defined MSG_DONTROUTE
    static constexpr message_flags message_peek
      = (message_flags)MSG_PEEK;
    static constexpr message_flags message_out_of_band
      = (message_flags)MSG_OOB;
    static constexpr message_flags message_do_not_route
      = (message_flags)MSG_DONTROUTE;
#endif

#ifdef SOMAXCONN
    static constexpr int max_listen_connections = SOMAXCONN;
#else
    static constexpr int max_listen_connections = 4;
#endif

    // message_flags bitmask operations are defined as hidden friends.

    friend constexpr message_flags
    operator&(message_flags __f1, message_flags __f2) noexcept
    { return message_flags( int(__f1) & int(__f2) ); }

    friend constexpr message_flags
    operator|(message_flags __f1, message_flags __f2) noexcept
    { return message_flags( int(__f1) | int(__f2) ); }

    friend constexpr message_flags
    operator^(message_flags __f1, message_flags __f2) noexcept
    { return message_flags( int(__f1) ^ int(__f2) ); }

    friend constexpr message_flags
    operator~(message_flags __f) noexcept
    { return message_flags( ~int(__f) ); }

    friend constexpr message_flags&
    operator&=(message_flags& __f1, message_flags __f2) noexcept
    { return __f1 = (__f1 & __f2); }

    friend constexpr message_flags&
    operator|=(message_flags& __f1, message_flags __f2) noexcept
    { return __f1 = (__f1 | __f2); }

    friend constexpr message_flags&
    operator^=(message_flags& __f1, message_flags __f2) noexcept
    { return __f1 = (__f1 ^ __f2); }

#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
  protected:
    struct __msg_hdr : ::msghdr
    {
#ifdef IOV_MAX
      using __iovec_array = array<::iovec, IOV_MAX>;
#elif _GLIBCXX_HAVE_UNISTD_H
      struct __iovec_array
      {
	__iovec_array() : _M_ptr(new ::iovec[size()]) { }

	::iovec& operator[](size_t __n) noexcept { return _M_ptr[__n]; }

	::iovec* data() noexcept { return _M_ptr.get(); }

	static size_t size()
	{
	  static const size_t __iov_max = ::sysconf(_SC_IOV_MAX);
	  return __iov_max;
	}

      private:
	unique_ptr<::iovec[]> _M_ptr;
      };
#else
      using __iovec_array = array<::iovec, 16>;
#endif

      __iovec_array _M_iov;

      template<typename _BufferSequence>
	explicit
	__msg_hdr(const _BufferSequence& __buffers)
	: msghdr()
	{
	  auto __buf = net::buffer_sequence_begin(__buffers);
	  const auto __bufend = net::buffer_sequence_end(__buffers);
	  size_t __len = 0;
	  while (__buf != __bufend && __len != _M_iov.size())
	    {
	      _M_iov[__len].iov_base = (void*)__buf->data();
	      _M_iov[__len].iov_len = __buf->size();
	      ++__buf;
	      ++__len;
	    }
	  this->msg_iovlen = __len;
	  this->msg_iov = _M_iov.data();
	}

      template<typename _BufferSequence, typename _Endpoint>
	__msg_hdr(const _BufferSequence& __buffers, const _Endpoint& __ep)
	: __msg_hdr(__buffers)
	{
	  this->msg_name = __ep.data();
	  this->msg_namelen = __ep.size();
	}
    };
#endif

  protected:
    socket_base() = default;
    ~socket_base() = default;
  };

  // TODO define socket_base static constants in .so for C++14 mode

#if _GLIBCXX_HAVE_UNISTD_H

  class __socket_impl
  {
  protected:

    using executor_type = io_context::executor_type;
    using native_handle_type = int;

    explicit
    __socket_impl(io_context& __ctx) : _M_ctx(std::addressof(__ctx)) { }

    __socket_impl(__socket_impl&& __rhs)
    : _M_ctx(__rhs._M_ctx),
      _M_sockfd(std::__exchange(__rhs._M_sockfd, -1)),
      _M_bits(std::__exchange(__rhs._M_bits, {}))
    { }

    __socket_impl&
    operator=(__socket_impl&& __rhs)
    {
      _M_ctx = __rhs._M_ctx;
      _M_sockfd = std::__exchange(__rhs._M_sockfd, -1);
      _M_bits = std::__exchange(__rhs._M_bits, {});
      return *this;
    }

    ~__socket_impl() = default;

    __socket_impl(const __socket_impl&) = delete;
    __socket_impl& operator=(const __socket_impl&) = delete;

    executor_type get_executor() noexcept { return _M_ctx->get_executor(); }

    native_handle_type native_handle() noexcept { return _M_sockfd; }

    bool is_open() const noexcept { return _M_sockfd != -1; }

    void
    close(error_code& __ec)
    {
      if (is_open())
	{
	  cancel(__ec);
	  if (!__ec)
	    {
	      if (::close(_M_sockfd) == -1)
		__ec.assign(errno, generic_category());
	      else
		{
		  get_executor().context()._M_remove_fd(_M_sockfd);
		  _M_sockfd = -1;
		}
	    }
	}
    }

    void cancel(error_code& __ec) { _M_ctx->cancel(_M_sockfd, __ec); }

    void
    non_blocking(bool __mode, error_code&)
    { _M_bits.non_blocking = __mode; }

    bool non_blocking() const { return _M_bits.non_blocking; }

    void
    native_non_blocking(bool __mode, error_code& __ec)
    {
#if defined _GLIBCXX_HAVE_FCNTL_H && defined _GLIBCXX_HAVE_DECL_O_NONBLOCK
      int __flags = ::fcntl(_M_sockfd, F_GETFL, 0);
      if (__flags >= 0)
	{
	  if (__mode)
	    __flags |= O_NONBLOCK;
	  else
	    __flags &= ~O_NONBLOCK;
	  __flags = ::fcntl(_M_sockfd, F_SETFL, __flags);
	}
      if (__flags == -1)
	__ec.assign(errno, generic_category());
      else
	{
	  __ec.clear();
	  _M_bits.native_non_blocking = __mode;
	}
#else
      __ec = std::make_error_code(std::errc::not_supported);
#endif
    }

    bool
    native_non_blocking() const
    {
#if defined _GLIBCXX_HAVE_FCNTL_H && defined _GLIBCXX_HAVE_DECL_O_NONBLOCK
      if (_M_bits.native_non_blocking == -1)
	{
	  const int __flags = ::fcntl(_M_sockfd, F_GETFL, 0);
	  if (__flags == -1)
	    return 0;
	  _M_bits.native_non_blocking = __flags & O_NONBLOCK;
	}
      return _M_bits.native_non_blocking;
#else
      return false;
#endif
    }

    io_context*	_M_ctx;
    int		_M_sockfd{-1};
    struct {
      unsigned		non_blocking : 1;
      mutable signed	native_non_blocking : 2;
      unsigned		enable_connection_aborted : 1;
    } _M_bits{};
  };

  template<typename _Protocol>
    class __basic_socket_impl : public __socket_impl
    {
      using __base = __socket_impl;

    protected:
      using protocol_type = _Protocol;
      using endpoint_type = typename protocol_type::endpoint;

      explicit
      __basic_socket_impl(io_context& __ctx) : __base(__ctx) { }

      __basic_socket_impl(__basic_socket_impl&&) = default;

      template<typename _OtherProtocol>
	__basic_socket_impl(__basic_socket_impl<_OtherProtocol>&& __rhs)
	: __base(std::move(__rhs)), _M_protocol(std::move(__rhs._M_protocol))
	{ }

      __basic_socket_impl&
      operator=(__basic_socket_impl&& __rhs)
      {
	if (this == std::addressof(__rhs))
	  return *this;
	_M_close();
	__base::operator=(std::move(__rhs));
	return *this;
      }

      ~__basic_socket_impl() { _M_close(); }

      __basic_socket_impl(const __basic_socket_impl&) = delete;
      __basic_socket_impl& operator=(const __basic_socket_impl&) = delete;

      void
      open(const protocol_type& __protocol, error_code& __ec)
      {
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	if (is_open())
	  __ec = socket_errc::already_open;
	else
	  {
	    _M_protocol = __protocol;
	    _M_sockfd = ::socket(__protocol.family(), __protocol.type(),
				 __protocol.protocol());
	    if (is_open())
	      {
		get_executor().context()._M_add_fd(_M_sockfd);
	      __ec.clear();
	      }
	    else
	      __ec.assign(errno, std::generic_category());
	  }
#else
	__ec = std::make_error_code(errc::operation_not_supported);
#endif
      }

      void
      assign(const protocol_type& __protocol,
	     const native_handle_type& __native_socket,
	     error_code& __ec)
      {
	if (is_open())
	  __ec = socket_errc::already_open;
	else
	  {
	    _M_protocol = __protocol;
	    _M_bits.native_non_blocking = -1;
	    _M_sockfd = __native_socket;
	    if (is_open())
	      {
		get_executor().context()._M_add_fd(_M_sockfd);
		__ec.clear();
	      }
	    else
	      __ec.assign(errno, std::generic_category());
	  }
      }

      native_handle_type release(error_code& __ec)
      {
	__glibcxx_assert(is_open());
	cancel(__ec);
	return std::__exchange(_M_sockfd, -1);
      }

      template<typename _SettableSocketOption>
	void
	set_option(const _SettableSocketOption& __option, error_code& __ec)
	{
# ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	  int __result = ::setsockopt(_M_sockfd, __option.level(_M_protocol),
				      __option.name(_M_protocol),
				      __option.data(_M_protocol),
				      __option.size(_M_protocol));
	  if (__result == -1)
	    __ec.assign(errno, generic_category());
	  else
	    __ec.clear();
#else
	  __ec = std::make_error_code(std::errc::not_supported);
#endif
	}

      template<typename _GettableSocketOption>
	void
	get_option(_GettableSocketOption& __option, error_code& __ec) const
	{
# ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	  int __result = ::getsockopt(_M_sockfd, __option.level(_M_protocol),
				      __option.name(_M_protocol),
				      __option.data(_M_protocol),
				      __option.size(_M_protocol));
	  if (__result == -1)
	    __ec.assign(errno, generic_category());
	  else
	    __ec.clear();
#else
	  __ec = std::make_error_code(std::errc::not_supported);
#endif
	}

      template<typename _IoControlCommand>
	void
	io_control(_IoControlCommand& __command, error_code& __ec)
	{
#ifdef _GLIBCXX_HAVE_SYS_IOCTL_H
	  int __result = ::ioctl(_M_sockfd, __command.name(),
				 __command.data());
	  if (__result == -1)
	    __ec.assign(errno, generic_category());
	  else
	    __ec.clear();
#else
	  __ec = std::make_error_code(std::errc::not_supported);
#endif
	}

      endpoint_type
      local_endpoint(error_code& __ec) const
      {
	endpoint_type __endpoint;
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	socklen_t __endpoint_len = __endpoint.capacity();
	if (::getsockname(_M_sockfd, (sockaddr*)__endpoint.data(),
			  &__endpoint_len) == -1)
	  {
	    __ec.assign(errno, generic_category());
	    return endpoint_type{};
	  }
	__ec.clear();
	__endpoint.resize(__endpoint_len);
#else
	__ec = std::make_error_code(errc::operation_not_supported);
#endif
	return __endpoint;
      }

      void
      bind(const endpoint_type& __endpoint, error_code& __ec)
      {
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	if (::bind(_M_sockfd, (sockaddr*)__endpoint.data(), __endpoint.size())
	    == -1)
	  __ec.assign(errno, generic_category());
	else
	  __ec.clear();
#else
	__ec = std::make_error_code(errc::operation_not_supported);
#endif
      }

      _Protocol	_M_protocol{ endpoint_type{}.protocol() };

    private:
      void
      _M_close()
      {
	if (is_open())
	  {
	    error_code __ec;
	    cancel(__ec);
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	    set_option(socket_base::linger{false, chrono::seconds{}}, __ec);
#endif
	    ::close(_M_sockfd);
	  }
      }
    };

  template<typename _Protocol>
    class basic_socket
    : public socket_base, private __basic_socket_impl<_Protocol>
    {
      using __base = __basic_socket_impl<_Protocol>;

    public:
      // types:

      using executor_type = io_context::executor_type;
      using native_handle_type = int;
      using protocol_type = _Protocol;
      using endpoint_type = typename protocol_type::endpoint;

      static_assert(__detail::__protocol<protocol_type>,
		    "protocol_type meets the Protocol requirements");

      // basic_socket operations:

      executor_type get_executor() noexcept { return __base::get_executor(); }

      native_handle_type
      native_handle() noexcept { return __base::native_handle(); }

      void
      open(const protocol_type& __protocol = protocol_type())
      { open(__protocol, __throw_on_error{"basic_socket::open"}); }

      void
      open(const protocol_type& __protocol, error_code& __ec)
      { __base::open(__protocol, __ec); }

      void
      assign(const protocol_type& __protocol,
	     const native_handle_type& __native_socket)
      {
	assign(__protocol, __native_socket,
	       __throw_on_error{"basic_socket::assign"});
      }

      void
      assign(const protocol_type& __protocol,
	     const native_handle_type& __native_socket,
	     error_code& __ec)
      { __base::assign(__protocol, __native_socket, __ec); }

      native_handle_type release()
      { return release(__throw_on_error{"basic_socket::release"}); }

      native_handle_type release(error_code& __ec)
      { return __base::release(__ec); }

      _GLIBCXX_NODISCARD bool
      is_open() const noexcept { return __base::is_open(); }

      void close() { close(__throw_on_error{"basic_socket::close"}); }

      void close(error_code& __ec) { __base::close(__ec); }

      void cancel() { cancel(__throw_on_error{"basic_socket::cancel"}); }

      void cancel(error_code& __ec) { __base::cancel(__ec); }

      template<typename _SettableSocketOption>
	void
	set_option(const _SettableSocketOption& __option)
	{ set_option(__option, __throw_on_error{"basic_socket::set_option"}); }

      template<typename _SettableSocketOption>
	void
	set_option(const _SettableSocketOption& __option, error_code& __ec)
	{ __base::set_option(__option, __ec); }

      template<typename _GettableSocketOption>
	void
	get_option(_GettableSocketOption& __option) const
	{ get_option(__option, __throw_on_error{"basic_socket::get_option"}); }

      template<typename _GettableSocketOption>
	void
	get_option(_GettableSocketOption& __option, error_code& __ec) const
	{ __base::get_option(__option, __ec); }

      template<typename _IoControlCommand>
	void
	io_control(_IoControlCommand& __command)
	{
	  io_control(__command, __throw_on_error{"basic_socket::io_control"});
	}

      template<typename _IoControlCommand>
	void
	io_control(_IoControlCommand& __command, error_code& __ec)
	{ __base::io_control(__command, __ec); }

      void
      non_blocking(bool __mode)
      { non_blocking(__mode, __throw_on_error{"basic_socket::non_blocking"}); }

      void
      non_blocking(bool __mode, error_code& __ec)
      { __base::non_blocking(__mode, __ec); }

      bool non_blocking() const { return __base::non_blocking(); }

      void
      native_non_blocking(bool __mode)
      {
	native_non_blocking(__mode, __throw_on_error{
	    "basic_socket::native_non_blocking"});
      }

      void
      native_non_blocking(bool __mode, error_code& __ec)
      { __base::native_non_blocking(__mode, __ec); }

      bool
      native_non_blocking() const
      { return __base::native_non_blocking(); }

      bool at_mark() const
      { return at_mark(__throw_on_error{"basic_socket::at_mark"}); }

      bool
      at_mark(error_code& __ec) const
      {
#ifdef _GLIBCXX_HAVE_SOCKATMARK
	const int __result = ::sockatmark(native_handle());
	if (__result == -1)
	  {
	    __ec.assign(errno, generic_category());
	    return false;
	  }
	__ec.clear();
	return (bool)__result;
#else
	__ec = std::make_error_code(errc::operation_not_supported);
	return false;
#endif
      }

      size_t
      available() const
      { return available(__throw_on_error{"basic_socket::available"}); }

      size_t
      available(error_code& __ec) const
      {
	if (!is_open())
	  {
	    __ec = std::make_error_code(errc::bad_file_descriptor);
	    return 0;
	  }
#if defined _GLIBCXX_HAVE_SYS_IOCTL_H && defined FIONREAD
	int __avail = 0;
	if (::ioctl(this->_M_sockfd, FIONREAD, &__avail) == -1)
	  {
	    __ec.assign(errno, generic_category());
	    return 0;
	  }
	__ec.clear();
	return __avail;
#else
	return 0;
#endif
      }

      void
      bind(const endpoint_type& __endpoint)
      { return bind(__endpoint, __throw_on_error{"basic_socket::bind"}); }

      void
      bind(const endpoint_type& __endpoint, error_code& __ec)
      { __base::bind(__endpoint, __ec); }

      void shutdown(shutdown_type __what)
      { return shutdown(__what, __throw_on_error{"basic_socket::shutdown"}); }

      void
      shutdown(shutdown_type __what, error_code& __ec)
      {
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	if (::shutdown(native_handle(), static_cast<int>(__what)) == -1)
	  __ec.assign(errno, generic_category());
	else
	  __ec.clear();
#else
	__ec = std::make_error_code(errc::operation_not_supported);
#endif
      }

      endpoint_type
      local_endpoint() const
      {
	return local_endpoint(
	    __throw_on_error{"basic_socket::local_endpoint"});
      }

      endpoint_type
      local_endpoint(error_code& __ec) const
      { return __base::local_endpoint(__ec); }

      endpoint_type
      remote_endpoint() const
      {
	return remote_endpoint(
	    __throw_on_error{"basic_socket::remote_endpoint"});
      }

      endpoint_type
      remote_endpoint(error_code& __ec) const
      {
	endpoint_type __endpoint;
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	socklen_t __endpoint_len = __endpoint.capacity();
	if (::getpeername(this->_M_sockfd, (sockaddr*)__endpoint.data(),
			  &__endpoint_len)
	    == -1)
	  {
	    __ec.assign(errno, generic_category());
	    return endpoint_type{};
	  }
	__ec.clear();
	__endpoint.resize(__endpoint_len);
#else
	__ec = std::make_error_code(errc::operation_not_supported);
#endif
	return __endpoint;
      }

      void
      connect(const endpoint_type& __endpoint)
      {
	return connect(__endpoint, __throw_on_error{"basic_socket::connect"});
      }

      void
      connect(const endpoint_type& __endpoint, error_code& __ec)
      {
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	if (!is_open())
	  {
	    open(__endpoint.protocol(), __ec);
	    if (__ec)
	      return;
	  }
	if (::connect(native_handle(), (const sockaddr*)__endpoint.data(),
		      __endpoint.size()) == -1)
	  __ec.assign(errno, generic_category());
	else
	  __ec.clear();
#else
	__ec = std::make_error_code(errc::operation_not_supported);
#endif
      }

      template<typename _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code)>
	async_connect(const endpoint_type& __endpoint,
		      _CompletionToken&& __token)
	{
	  async_completion<_CompletionToken, void(error_code)> __init{__token};

	  if (!is_open())
	    {
	      error_code __ec;
	      open(__endpoint.protocol(), __ec);
	      if (__ec)
		{
                  auto __ex = net::get_associated_executor(
                      __init.completion_handler, get_executor());
                  auto __a = get_associated_allocator(
                      __init.completion_handler, std::allocator<void>());
                  __ex.post(
                      [__h = std::move(__init.completion_handler), __ec]
                      () mutable
                      { __h(__ec); }, __a);
		  return __init.result.get();
		}
	    }

	  get_executor().context().async_wait( native_handle(),
	      (int) socket_base::wait_read,
	      [__h = std::move(__init.completion_handler),
               __ep = std::move(__endpoint),
               __fd = native_handle()]
               (error_code __ec) mutable {
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
                  if (!__ec && ::connect(__fd, (const sockaddr*)__ep.data(),
					 __ep.size()) == -1)
                    __ec.assign(errno, generic_category());
#else
		  __ec = std::make_error_code(errc::operation_not_supported);
#endif
		  __h(__ec);
	      });
	  return __init.result.get();
	}

      void
      wait(wait_type __w)
      { return wait(__w, __throw_on_error{"basic_socket::wait"}); }

      void
      wait(wait_type __w, error_code& __ec)
      {
#ifdef _GLIBCXX_HAVE_POLL_H
	::pollfd __fd;
	__fd.fd = native_handle();
	__fd.events = static_cast<int>(__w);
	int __res = ::poll(&__fd, 1, -1);
	if (__res == -1)
	  __ec.assign(errno, generic_category());
	else
	  __ec.clear();
#else
	__ec = std::make_error_code(errc::operation_not_supported);
#endif
      }

      template<typename _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code)>
	async_wait(wait_type __w, _CompletionToken&& __token)
	{
	  async_completion<_CompletionToken, void(error_code)> __init{__token};
	  get_executor().context().async_wait( native_handle(),
	      static_cast<int>(__w),
	      [__h = std::move(__init.completion_handler)]
              (error_code __ec) mutable {
		  __h(__ec);
	      });
	  return __init.result.get();
	}

    protected:
      // construct / copy / destroy:

      using __base::__base;

      explicit
      basic_socket(io_context& __ctx) : __base(__ctx) { }

      basic_socket(io_context& __ctx, const protocol_type& __protocol)
      : __base(__ctx)
      { open(__protocol); }

      basic_socket(io_context& __ctx, const endpoint_type& __endpoint)
      : basic_socket(__ctx, __endpoint.protocol())
      { bind(__endpoint); }

      basic_socket(io_context& __ctx, const protocol_type& __protocol,
		   const native_handle_type& __native_socket)
      : __base(__ctx)
      { assign(__protocol, __native_socket); }

      basic_socket(const basic_socket&) = delete;

      basic_socket(basic_socket&& __rhs) = default;

      template<typename _OtherProtocol, typename _Requires
	       = _Require<is_convertible<_OtherProtocol, _Protocol>>>
	basic_socket(basic_socket<_OtherProtocol>&& __rhs)
	: __base(std::move(__rhs)) { }

      ~basic_socket() = default;

      basic_socket& operator=(const basic_socket&) = delete;

      basic_socket& operator=(basic_socket&& __rhs) = default;

      template<typename _OtherProtocol>
	enable_if_t<is_convertible<_OtherProtocol, _Protocol>::value,
		    basic_socket&>
	operator=(basic_socket<_OtherProtocol>&& __rhs)
        { return *this = basic_socket{std::move(__rhs)}; }
    };

  template<typename _Protocol>
    class basic_datagram_socket : public basic_socket<_Protocol>
    {
      using __base = basic_socket<_Protocol>;

    public:
      // types:

      using native_handle_type = int;
      using protocol_type = _Protocol;
      using endpoint_type = typename protocol_type::endpoint;

      // construct / copy / destroy:

      explicit
      basic_datagram_socket(io_context& __ctx) : __base(__ctx) { }

      basic_datagram_socket(io_context& __ctx, const protocol_type& __protocol)
      : __base(__ctx, __protocol) { }

      basic_datagram_socket(io_context& __ctx, const endpoint_type& __endpoint)
      : __base(__ctx, __endpoint) { }

      basic_datagram_socket(io_context& __ctx, const protocol_type& __protocol,
			    const native_handle_type& __native_socket)
      : __base(__ctx, __protocol, __native_socket) { }

      basic_datagram_socket(const basic_datagram_socket&) = delete;

      basic_datagram_socket(basic_datagram_socket&& __rhs) = default;

      template<typename _OtherProtocol, typename _Requires
	       = _Require<is_convertible<_OtherProtocol, _Protocol>>>
	basic_datagram_socket(basic_datagram_socket<_OtherProtocol>&& __rhs)
	: __base(std::move(__rhs)) { }

      ~basic_datagram_socket() = default;

      basic_datagram_socket& operator=(const basic_datagram_socket&) = delete;

      basic_datagram_socket& operator=(basic_datagram_socket&& __rhs) = default;

      template<typename _OtherProtocol>
	enable_if_t<is_convertible<_OtherProtocol, _Protocol>::value,
		    basic_datagram_socket&>
	operator=(basic_datagram_socket<_OtherProtocol>&& __rhs)
	{
	  __base::operator=(std::move(__rhs));
	  return *this;
	}

      // basic_datagram_socket operations:

      template<typename _MutableBufferSequence>
	size_t
	receive(const _MutableBufferSequence& __buffers)
	{
	  return receive(__buffers, socket_base::message_flags(),
			 __throw_on_error{"basic_datagram_socket::receive"});
	}

      template<typename _MutableBufferSequence>
	size_t
	receive(const _MutableBufferSequence& __buffers, error_code& __ec)
        { return receive(__buffers, socket_base::message_flags(), __ec); }

      template<typename _MutableBufferSequence>
	size_t
	receive(const _MutableBufferSequence& __buffers,
		       socket_base::message_flags __flags)
	{
	  return receive(__buffers, __flags,
			 __throw_on_error{"basic_datagram_socket::receive"});
	}

      template<typename _MutableBufferSequence>
	size_t
	receive(const _MutableBufferSequence& __buffers,
		socket_base::message_flags __flags, error_code& __ec)
	{
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	  socket_base::__msg_hdr __msg(__buffers);
	  ssize_t __result = ::recvmsg(this->native_handle(), &__msg,
				       static_cast<int>(__flags));
	  if (__result == -1)
            {
              __ec.assign(errno, generic_category());
              return 0;
            }
          __ec.clear();
          return __result;
#else
	  __ec = std::make_error_code(errc::operation_not_supported);
	  return 0;
#endif
	}

      template<typename _MutableBufferSequence, typename _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, size_t)>
	async_receive(const _MutableBufferSequence& __buffers,
		      _CompletionToken&& __token)
	{
	  return async_receive(__buffers, socket_base::message_flags(),
			       std::forward<_CompletionToken>(__token));
	}

      template<typename _MutableBufferSequence, typename _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, size_t)>
	async_receive(const _MutableBufferSequence& __buffers,
		      socket_base::message_flags __flags,
		      _CompletionToken&& __token)
	{
          async_completion<_CompletionToken, void(error_code, size_t)>
            __init{__token};

	  this->get_executor().context().async_wait(this->native_handle(),
	      (int) socket_base::wait_read,
	      [__h = std::move(__init.completion_handler),
               &__buffers, __flags = static_cast<int>(__flags),
               __fd = this->native_handle()]
              (error_code __ec) mutable {
                  if (__ec)
                    {
                      __h(__ec);
                      return;
                    }
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
                  socket_base::__msg_hdr __msg(__buffers);
                  ssize_t __result = ::recvmsg(__fd, &__msg, __flags);
                  if (__result == -1)
                    {
                      __ec.assign(errno, generic_category());
                      __result = 0;
                    }
                  else
                    __ec.clear();
		  __h(__ec, __result);
#else
		  __h(std::make_error_code(errc::operation_not_supported), 0);
#endif
	      });
	  return __init.result.get();
	}

      template<typename _MutableBufferSequence>
	size_t
	receive_from(const _MutableBufferSequence& __buffers,
		     endpoint_type& __sender)
	{
	  return receive_from(__buffers, __sender,
			      socket_base::message_flags(),
			      __throw_on_error{
				  "basic_datagram_socket::receive_from"});
	}

      template<typename _MutableBufferSequence>
	size_t
	receive_from(const _MutableBufferSequence& __buffers,
		     endpoint_type& __sender, error_code& __ec)
	{
	  return receive_from(__buffers, __sender,
			      socket_base::message_flags(), __ec);
	}

      template<typename _MutableBufferSequence>
	size_t
	receive_from(const _MutableBufferSequence& __buffers,
		     endpoint_type& __sender,
		     socket_base::message_flags __flags)
	{
	  return receive_from(__buffers, __sender, __flags,
			      __throw_on_error{
				  "basic_datagram_socket::receive_from"});
	}

      template<typename _MutableBufferSequence>
	size_t
	receive_from(const _MutableBufferSequence& __buffers,
		     endpoint_type& __sender,
		     socket_base::message_flags __flags,
		     error_code& __ec)
	{
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	  socket_base::__msg_hdr __msg(__buffers, __sender);
	  ssize_t __result = ::recvmsg(this->native_handle(), &__msg,
				       static_cast<int>(__flags));
	  if (__result == -1)
            {
              __ec.assign(errno, generic_category());
              return 0;
            }
          __ec.clear();
          __sender.resize(__msg.msg_namelen);
          return __result;
#else
	  __ec = std::make_error_code(errc::operation_not_supported);
	  return 0;
#endif
	}

      template<typename _MutableBufferSequence, typename _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, size_t)>
	async_receive_from(const _MutableBufferSequence& __buffers,
			   endpoint_type& __sender,
			   _CompletionToken&& __token)
	{
	  return async_receive_from(__buffers, __sender,
				    socket_base::message_flags(),
				    std::forward<_CompletionToken>(__token));
	}

      template<typename _MutableBufferSequence, typename _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, size_t)>
	async_receive_from(const _MutableBufferSequence& __buffers,
			   endpoint_type& __sender,
			   socket_base::message_flags __flags,
			   _CompletionToken&& __token)
	{
	  async_completion<_CompletionToken, void(error_code, size_t)>
            __init{__token};

	  this->get_executor().context().async_wait( this->native_handle(),
	      (int) socket_base::wait_read,
	      [__h = std::move(__init.completion_handler),
               &__buffers, __flags = static_cast<int>(__flags),
               __sender = std::move(__sender),
               __fd = this->native_handle()]
              (error_code __ec) mutable {
                  if (__ec)
                    {
                      __h(__ec);
                      return;
                    }
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
                  socket_base::__msg_hdr __msg(__buffers, __sender);
                  ssize_t __result = ::recvmsg(__fd, &__msg, __flags);
                  if (__result == -1)
                    {
                      __ec.assign(errno, generic_category());
                      __result = 0;
                    }
                  else
                    {
                      __ec.clear();
                      __sender.resize(__msg.msg_namelen);
                    }
		  __h(__ec, __result);
#else
		  __h(std::make_error_code(errc::operation_not_supported), 0);
#endif
	      });
	  return __init.result.get();
	}

      template<typename _ConstBufferSequence>
	size_t
	send(const _ConstBufferSequence& __buffers)
	{
	  return send(__buffers, socket_base::message_flags(),
		      __throw_on_error{"basic_datagram_socket::send"});
	}

      template<typename _ConstBufferSequence>
	size_t
	send(const _ConstBufferSequence& __buffers, error_code& __ec)
	{ return send(__buffers, socket_base::message_flags(), __ec); }

      template<typename _ConstBufferSequence>
	size_t
	send(const _ConstBufferSequence& __buffers,
	     socket_base::message_flags __flags)
	{
	  return send(__buffers, __flags,
		      __throw_on_error{"basic_datagram_socket::send"});
	}

      template<typename _ConstBufferSequence>
	size_t
	send(const _ConstBufferSequence& __buffers,
	     socket_base::message_flags __flags, error_code& __ec)
	{
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	  socket_base::__msg_hdr __msg(__buffers);
	  ssize_t __result = ::sendmsg(this->native_handle(), &__msg,
				       static_cast<int>(__flags));
	  if (__result == -1)
            {
              __ec.assign(errno, generic_category());
              return 0;
            }
          __ec.clear();
          return __result;
#else
	  __ec = std::make_error_code(errc::operation_not_supported);
	  return 0;
#endif
	}

      template<typename _ConstBufferSequence, typename _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, size_t)>
	async_send(const _ConstBufferSequence& __buffers,
			_CompletionToken&& __token)
	{
	  return async_send(__buffers, socket_base::message_flags(),
			    std::forward<_CompletionToken>(__token));
	}

      template<typename _ConstBufferSequence, typename _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, size_t)>
	async_send(const _ConstBufferSequence& __buffers,
		   socket_base::message_flags __flags,
		   _CompletionToken&& __token)
	{
	  async_completion<_CompletionToken, void(error_code, size_t)>
            __init{__token};

	  this->get_executor().context().async_wait( this->native_handle(),
	      (int) socket_base::wait_write,
	      [__h = std::move(__init.completion_handler),
               &__buffers, __flags = static_cast<int>(__flags),
               __fd = this->native_handle()]
              (error_code __ec) mutable {
                  if (__ec)
                    {
                      __h(__ec);
                      return;
                    }
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
                  socket_base::__msg_hdr __msg(__buffers);
                  ssize_t __result = ::sendmsg(__fd, &__msg, __flags);
                  if (__result == -1)
                    {
                      __ec.assign(errno, generic_category());
                      __result = 0;
                    }
                  else
                    __ec.clear();
		  __h(__ec, __result);
#else
		  __h(std::make_error_code(errc::operation_not_supported), 0);
#endif
	      });
	  return __init.result.get();
	}

      template<typename _ConstBufferSequence>
	size_t
	send_to(const _ConstBufferSequence& __buffers,
	        const endpoint_type& __recipient)
	{
	  return send_to(__buffers, __recipient,
			 socket_base::message_flags(),
			 __throw_on_error{"basic_datagram_socket::send_to"});
	}

      template<typename _ConstBufferSequence>
	size_t
	send_to(const _ConstBufferSequence& __buffers,
		const endpoint_type& __recipient, error_code& __ec)
	{
	  return send_to(__buffers, __recipient,
			 socket_base::message_flags(), __ec);
	}

      template<typename _ConstBufferSequence>
	size_t
	send_to(const _ConstBufferSequence& __buffers,
		const endpoint_type& __recipient,
		socket_base::message_flags __flags)
	{
	  return send_to(__buffers, __recipient, __flags,
			 __throw_on_error{"basic_datagram_socket::send_to"});
	}

      template<typename _ConstBufferSequence>
	size_t
	send_to(const _ConstBufferSequence& __buffers,
	        const endpoint_type& __recipient,
		socket_base::message_flags __flags, error_code& __ec)
	{
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	  socket_base::__msg_hdr __msg(__buffers, __recipient);
	  ssize_t __result = ::sendmsg(this->native_handle(), &__msg,
				       static_cast<int>(__flags));
	  if (__result == -1)
            {
              __ec.assign(errno, generic_category());
              return 0;
            }
          __ec.clear();
          __recipient.resize(__msg.msg_namelen);
          return __result;
#else
	  __ec = std::make_error_code(errc::operation_not_supported);
	  return 0;
#endif
	}

      template<typename _ConstBufferSequence, typename _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, size_t)>
	async_send_to(const _ConstBufferSequence& __buffers,
		      const endpoint_type& __recipient,
		      _CompletionToken&& __token)
	{
	  return async_send_to(__buffers, __recipient,
			       socket_base::message_flags(),
			       std::forward<_CompletionToken>(__token));
	}

      template<typename _ConstBufferSequence, typename _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, size_t)>
	async_send_to(const _ConstBufferSequence& __buffers,
		      const endpoint_type& __recipient,
		      socket_base::message_flags __flags,
		      _CompletionToken&& __token)
	{
	  async_completion<_CompletionToken, void(error_code, size_t)>
            __init{__token};

	  this->get_executor().context().async_wait( this->native_handle(),
	      (int) socket_base::wait_write,
	      [__h = std::move(__init.completion_handler),
               &__buffers, __flags = static_cast<int>(__flags),
               __recipient = std::move(__recipient),
               __fd = this->native_handle()]
              (error_code __ec) mutable {
                  if (__ec)
                    {
                      __h(__ec);
                      return;
                    }
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
                  socket_base::__msg_hdr __msg(__buffers, __recipient);
                  ssize_t __result = ::sendmsg(__fd, &__msg, __flags);
                  if (__result == -1)
                    {
                      __ec.assign(errno, generic_category());
                      __result = 0;
                    }
                  else
                    {
                      __ec.clear();
                      __recipient.resize(__msg.msg_namelen);
                    }
		  __h(__ec, __result);
#else
		  __h(std::make_error_code(errc::operation_not_supported), 0);
#endif
	      });
	  return __init.result.get();
	}
    };

  template<typename _Protocol>
    class basic_stream_socket : public basic_socket<_Protocol>
    {
      using __base = basic_socket<_Protocol>;

    public:
      // types:

      using native_handle_type = int;
      using protocol_type = _Protocol;
      using endpoint_type = typename protocol_type::endpoint;

      // construct / copy / destroy:

      explicit
      basic_stream_socket(io_context& __ctx) : __base(__ctx) { }

      basic_stream_socket(io_context& __ctx, const protocol_type& __protocol)
      : __base(__ctx, __protocol) { }

      basic_stream_socket(io_context& __ctx, const endpoint_type& __endpoint)
      : __base(__ctx, __endpoint) { }

      basic_stream_socket(io_context& __ctx, const protocol_type& __protocol,
			  const native_handle_type& __native_socket)
      : __base(__ctx, __protocol, __native_socket) { }

      basic_stream_socket(const basic_stream_socket&) = delete;

      basic_stream_socket(basic_stream_socket&& __rhs) = default;

      template<typename _OtherProtocol, typename _Requires
	       = _Require<is_convertible<_OtherProtocol, _Protocol>>>
	basic_stream_socket(basic_stream_socket<_OtherProtocol>&& __rhs)
	: __base(std::move(__rhs)) { }

      ~basic_stream_socket() = default;

      basic_stream_socket& operator=(const basic_stream_socket&) = delete;

      basic_stream_socket& operator=(basic_stream_socket&& __rhs) = default;

      template<class _OtherProtocol>
	enable_if_t<is_convertible<_OtherProtocol, _Protocol>::value,
		    basic_stream_socket&>
	operator=(basic_stream_socket<_OtherProtocol>&& __rhs)
	{
	  __base::operator=(std::move(__rhs));
	  return *this;
	}

      // basic_stream_socket operations:

      template<class _MutableBufferSequence>
	size_t
	receive(const _MutableBufferSequence& __buffers)
	{
	  return receive(__buffers, socket_base::message_flags(),
			 __throw_on_error{"basic_stream_socket::receive"});
	}

      template<class _MutableBufferSequence>
	size_t
	receive(const _MutableBufferSequence& __buffers, error_code& __ec)
        { return receive(__buffers, socket_base::message_flags(), __ec); }

      template<class _MutableBufferSequence>
	size_t
	receive(const _MutableBufferSequence& __buffers,
		socket_base::message_flags __flags)
	{
	  return receive(__buffers, __flags,
			 __throw_on_error{"basic_stream_socket::receive"});
	}

      template<class _MutableBufferSequence>
	size_t
	receive(const _MutableBufferSequence& __buffers,
		socket_base::message_flags __flags, error_code& __ec)
	{
	  if (__buffer_empty(__buffers))
	    {
	      __ec.clear();
	      return 0;
	    }
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	  socket_base::__msg_hdr __msg(__buffers);
	  ssize_t __result = ::recvmsg(this->native_handle(), &__msg,
				       static_cast<int>(__flags));
	  if (__result >= 0)
	    {
	      __ec.clear();
	      return __result;
	    }
	  __ec.assign(errno, generic_category());
#else
	  __ec = std::make_error_code(errc::operation_not_supported);
#endif
	  return 0;
	}

      template<class _MutableBufferSequence, class _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, size_t)>
	async_receive(const _MutableBufferSequence& __buffers,
		      _CompletionToken&& __token)
	{
	  return async_receive(__buffers, socket_base::message_flags(),
			       std::forward<_CompletionToken>(__token));
	}

      template<class _MutableBufferSequence, class _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, size_t)>
	async_receive(const _MutableBufferSequence& __buffers,
		      socket_base::message_flags __flags,
		      _CompletionToken&& __token)
	{
	  async_completion<_CompletionToken, void(error_code, size_t)>
            __init{__token};

          if (__buffer_empty(__buffers))
	    {
              auto __ex = net::get_associated_executor(
                  __init.completion_handler, this->get_executor());
              auto __a = get_associated_allocator(
                  __init.completion_handler, std::allocator<void>());
              __ex.post(
                  [__h=std::move(__init.completion_handler)] () mutable
                  { __h(error_code{}, 0); }, __a);
              return __init.result.get();
	    }

          this->get_executor().context().async_wait(this->native_handle(),
	      (int) socket_base::wait_read,
	      [__h = std::move(__init.completion_handler),
               &__buffers, __flags = static_cast<int>(__flags),
               __fd = this->native_handle()]
              (error_code __ec) mutable {
                  if (__ec)
                    {
                      __h(__ec);
                      return;
                    }
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
                  socket_base::__msg_hdr __msg(__buffers);
                  ssize_t __result = ::recvmsg(__fd, &__msg, __flags);
                  if (__result == -1)
                    {
                      __ec.assign(errno, generic_category());
                      __result = 0;
                    }
                  else
                    __ec.clear();
		  __h(__ec, __result);
#else
		  __h(std::make_error_code(errc::operation_not_supported), 0);
#endif
	      });
	  return __init.result.get();
	}

      template<class _ConstBufferSequence>
	size_t
	send(const _ConstBufferSequence& __buffers)
	{
	  return send(__buffers, socket_base::message_flags(),
		      __throw_on_error{"basic_stream_socket::send"});
	}

      template<class _ConstBufferSequence>
	size_t
	send(const _ConstBufferSequence& __buffers, error_code& __ec)
	{ return send(__buffers, socket_base::message_flags(), __ec); }

      template<class _ConstBufferSequence>
	size_t
	send(const _ConstBufferSequence& __buffers,
	     socket_base::message_flags __flags)
	{
	  return send(__buffers, socket_base::message_flags(),
		      __throw_on_error{"basic_stream_socket::send"});
	}

      template<class _ConstBufferSequence>
	size_t
	send(const _ConstBufferSequence& __buffers,
	     socket_base::message_flags __flags, error_code& __ec)
	{
	  if (__buffer_empty(__buffers))
	    {
	      __ec.clear();
	      return 0;
	    }
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	  socket_base::__msg_hdr __msg(__buffers);
	  ssize_t __result = ::sendmsg(this->native_handle(), &__msg,
				       static_cast<int>(__flags));
	  if (__result >= 0)
	    {
	      __ec.clear();
	      return __result;
	    }
	  __ec.assign(errno, generic_category());
#else
	  __ec = std::make_error_code(errc::operation_not_supported);
#endif
	  return 0;
	}

      template<class _ConstBufferSequence, class _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, size_t)>
	async_send(const _ConstBufferSequence& __buffers,
		   _CompletionToken&& __token)
	{
	  return async_send(__buffers, socket_base::message_flags(),
			    std::forward<_CompletionToken>(__token));
	}

      template<class _ConstBufferSequence, class _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, size_t)>
	async_send(const _ConstBufferSequence& __buffers,
		   socket_base::message_flags __flags,
		   _CompletionToken&& __token)
	{
	  async_completion<_CompletionToken, void(error_code, size_t)>
            __init{__token};

          if (__buffer_empty(__buffers))
	    {
              auto __ex = net::get_associated_executor(
                  __init.completion_handler, this->get_executor());
              auto __a = get_associated_allocator(
                  __init.completion_handler, std::allocator<void>());
              __ex.post(
                  [__h=std::move(__init.completion_handler)] () mutable
                  { __h(error_code{}, 0); }, __a);
              return __init.result.get();
	    }

          this->get_executor().context().async_wait(this->native_handle(),
	      (int) socket_base::wait_write,
	      [__h = std::move(__init.completion_handler),
               &__buffers, __flags = static_cast<int>(__flags),
               __fd = this->native_handle()]
              (error_code __ec) mutable {
                  if (__ec)
                    {
                      __h(__ec);
                      return;
                    }
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
                  socket_base::__msg_hdr __msg(__buffers);
                  ssize_t __result = ::sendmsg(__fd, &__msg, __flags);
                  if (__result == -1)
                    {
                      __ec.assign(errno, generic_category());
                      __result = 0;
                    }
                  else
                    __ec.clear();
		  __h(__ec, __result);
#else
		  __h(std::make_error_code(errc::operation_not_supported), 0);
#endif
	      });
	  return __init.result.get();
	}

      template<class _MutableBufferSequence>
	size_t
	read_some(const _MutableBufferSequence& __buffers)
	{
	  return receive(__buffers,
			 __throw_on_error{"basic_stream_socket::read_some"});
	}

      template<class _MutableBufferSequence>
	size_t
	read_some(const _MutableBufferSequence& __buffers, error_code& __ec)
	{ return receive(__buffers, __ec); }

      template<class _MutableBufferSequence, class _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, size_t)>
	async_read_some(const _MutableBufferSequence& __buffers,
			_CompletionToken&& __token)
	{
	  return async_receive(__buffers,
			       std::forward<_CompletionToken>(__token));
	}

      template<class _ConstBufferSequence>
	size_t
	write_some(const _ConstBufferSequence& __buffers)
	{
	  return send(__buffers,
		      __throw_on_error{"basic_stream_socket:write_some"});
	}

      template<class _ConstBufferSequence>
	size_t
	write_some(const _ConstBufferSequence& __buffers, error_code& __ec)
	{  return send(__buffers, __ec); }

      template<class _ConstBufferSequence, class _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, size_t)>
	async_write_some(const _ConstBufferSequence& __buffers,
			      _CompletionToken&& __token)
	{
	  return async_send(__buffers,
			    std::forward<_CompletionToken>(__token));
	}
    };

  template<typename _AcceptableProtocol>
    class basic_socket_acceptor
    : public socket_base, private __basic_socket_impl<_AcceptableProtocol>
    {
      using __base = __basic_socket_impl<_AcceptableProtocol>;

    public:
      // types:

      using executor_type = io_context::executor_type;
      using native_handle_type = int;
      using protocol_type = _AcceptableProtocol;
      using endpoint_type = typename protocol_type::endpoint;
      using socket_type = typename protocol_type::socket;

      static_assert(__detail::__acceptable_protocol<protocol_type>,
		    "protocol_type meets the AcceptableProtocol requirements");

      // construct / copy / destroy:

      explicit
      basic_socket_acceptor(io_context& __ctx)
      : __base(__ctx), _M_protocol(endpoint_type{}.protocol()) { }

      basic_socket_acceptor(io_context& __ctx,
			    const protocol_type& __protocol)
      : __base(__ctx), _M_protocol(__protocol)
      { open(__protocol); }

      basic_socket_acceptor(io_context& __ctx, const endpoint_type& __endpoint,
			    [[__maybe_unused__]] bool __reuse_addr = true)
      : basic_socket_acceptor(__ctx, __endpoint.protocol())
      {
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	if (__reuse_addr)
	  set_option(reuse_address(true));
#endif
	bind(__endpoint);
	listen();
      }

      basic_socket_acceptor(io_context& __ctx, const protocol_type& __protocol,
			    const native_handle_type& __native_acceptor)
      : basic_socket_acceptor(__ctx, __protocol)
      { assign(__protocol, __native_acceptor); }

      basic_socket_acceptor(const basic_socket_acceptor&) = delete;

      basic_socket_acceptor(basic_socket_acceptor&&) = default;

      template<typename _OtherProtocol, typename _Requires
	       = _Require<is_convertible<_OtherProtocol, protocol_type>>>
	basic_socket_acceptor(basic_socket_acceptor<_OtherProtocol>&& __rhs)
	: __base(std::move(__rhs)) { }

      ~basic_socket_acceptor() = default;

      basic_socket_acceptor& operator=(const basic_socket_acceptor&) = delete;

      basic_socket_acceptor& operator=(basic_socket_acceptor&&) = default;

      template<class _OtherProtocol>
	enable_if_t<is_convertible<_OtherProtocol, protocol_type>::value,
		    basic_socket_acceptor&>
	operator=(basic_socket_acceptor<_OtherProtocol>&& __rhs)
	{
	  __base::operator=(std::move(__rhs));
	  return *this;
	}

      // basic_socket_acceptor operations:

      executor_type get_executor() noexcept { return __base::get_executor(); }

      native_handle_type
      native_handle() noexcept { return __base::native_handle(); }

      void
      open(const protocol_type& __protocol = protocol_type())
      { open(__protocol, __throw_on_error{"basic_socket_acceptor::open"}); }

      void
      open(const protocol_type& __protocol, error_code& __ec)
      { __base::open(__protocol, __ec); }

      void
      assign(const protocol_type& __protocol,
	     const native_handle_type& __native_acceptor)
      {
	assign(__protocol, __native_acceptor,
	       __throw_on_error{"basic_socket_acceptor::assign"});
      }

      void
      assign(const protocol_type& __protocol,
	     const native_handle_type& __native_acceptor,
	     error_code& __ec)
      { __base::assign(__protocol, __native_acceptor, __ec); }

      native_handle_type release()
      { return release(__throw_on_error{"basic_socket_acceptor::release"}); }

      native_handle_type release(error_code& __ec)
      { return __base::release(__ec); }

      _GLIBCXX_NODISCARD bool
      is_open() const noexcept { return __base::is_open(); }

      void
      close() { close(__throw_on_error{"basic_socket_acceptor::close"}); }

      void
      close(error_code& __ec) { __base::_close(__ec); }

      void
      cancel() { cancel(__throw_on_error{"basic_socket_acceptor::cancel"}); }

      void
      cancel(error_code& __ec) { __base::cancel(__ec); }

      template<typename _SettableSocketOption>
	void
	set_option(const _SettableSocketOption& __option)
	{
	  set_option(__option,
		     __throw_on_error{"basic_socket_acceptor::set_option"});
	}

      template<typename _SettableSocketOption>
	void
	set_option(const _SettableSocketOption& __option, error_code& __ec)
	{ __base::set_option(__option, __ec); }

      template<typename _GettableSocketOption>
	void
	get_option(_GettableSocketOption& __option) const
	{
	  get_option(__option,
		     __throw_on_error{"basic_socket_acceptor::get_option"});
	}

      template<typename _GettableSocketOption>
	void
	get_option(_GettableSocketOption& __option, error_code& __ec) const
	{ __base::get_option(__option, __ec); }

      template<typename _IoControlCommand>
	void
	io_control(_IoControlCommand& __command)
	{
	  io_control(__command,
		     __throw_on_error{"basic_socket_acceptor::io_control"});
	}

      template<typename _IoControlCommand>
	void
	io_control(_IoControlCommand& __command, error_code& __ec)
	{ __base::io_control(__command, __ec); }

      void
      non_blocking(bool __mode)
      {
	non_blocking(__mode,
		     __throw_on_error{"basic_socket_acceptor::non_blocking"});
      }

      void
      non_blocking(bool __mode, error_code& __ec)
      { __base::non_blocking(__mode, __ec); }

      bool non_blocking() const { return __base::non_blocking(); }

      void
      native_non_blocking(bool __mode)
      {
	native_non_blocking(__mode, __throw_on_error{
	    "basic_socket_acceptor::native_non_blocking"});
      }

      void
      native_non_blocking(bool __mode, error_code& __ec)
      { __base::native_non_blocking(__mode, __ec); }

      bool
      native_non_blocking() const
      { return __base::native_non_blocking(); }

      void
      bind(const endpoint_type& __endpoint)
      {
	return bind(__endpoint,
		    __throw_on_error{"basic_socket_acceptor::bind"});
      }

      void
      bind(const endpoint_type& __endpoint, error_code& __ec)
      { __base::bind(__endpoint, __ec); }

      void
      listen(int __backlog = max_listen_connections)
      {
	return listen(__backlog,
		      __throw_on_error{"basic_socket_acceptor::listen"});
      }

      void
      listen(int __backlog, error_code& __ec)
      {
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	if (::listen(native_handle(), __backlog) == -1)
	  __ec.assign(errno, generic_category());
	else
	  __ec.clear();
#else
	__ec = std::make_error_code(errc::operation_not_supported);
#endif
      }

      endpoint_type
      local_endpoint() const
      {
	return local_endpoint(
	    __throw_on_error{"basic_socket_acceptor::local_endpoint"});
      }

      endpoint_type
      local_endpoint(error_code& __ec) const
      { return __base::local_endpoint(__ec); }

      void
      enable_connection_aborted(bool __mode)
      { __base::_M_bits.enable_connection_aborted = __mode; }

      bool
      enable_connection_aborted() const
      { return __base::_M_bits.enable_connection_aborted; }

      socket_type
      accept()
      { return accept(__throw_on_error{"basic_socket_acceptor::accept"}); }

      socket_type
      accept(error_code& __ec)
      { return accept(get_executor().context(), __ec); }

      socket_type accept(io_context& __ctx)
      {
	return accept(__ctx,
		      __throw_on_error{"basic_socket_acceptor::accept"});
      }

      socket_type
      accept(io_context& __ctx, error_code& __ec)
      {
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	do
	  {
	    int __h = ::accept(native_handle(), nullptr, 0);
	    if (__h != -1)
	      {
		__ec.clear();
		return socket_type{__ctx, _M_protocol, __h};
	      }
	  } while (errno == ECONNABORTED && enable_connection_aborted());
	__ec.assign(errno, generic_category());
#else
	__ec = std::make_error_code(errc::operation_not_supported);
#endif
	return socket_type{__ctx};
      }

      template<class _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, socket_type)>
	async_accept(_CompletionToken&& __token)
	{
	  return async_accept(get_executor().context(),
			      std::forward<_CompletionToken>(__token));
	}

      template<class _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, socket_type)>
	async_accept(io_context& __ctx, _CompletionToken&& __token)
	{
          async_completion<_CompletionToken, void(error_code, socket_type)>
            __init{__token};

	  __ctx.async_wait(native_handle(),
	      (int) socket_base::wait_read,
	      [__h = std::move(__init.completion_handler),
               __connabort = enable_connection_aborted(),
               __fd = native_handle(),
               __protocol = _M_protocol,
               &__ctx
              ]
              (error_code __ec) mutable {
                  if (__ec)
                    {
                      __h(__ec, socket_type(__ctx));
                      return;
                    }
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
                  do
                    {
                      int __newfd = ::accept(__fd, nullptr, 0);
                      if (__newfd != -1)
                        {
                          __ec.clear();
                          __h(__ec, socket_type{__ctx, __protocol, __newfd});
                          return;
                        }
                    } while (errno == ECONNABORTED && __connabort);
                  __ec.assign(errno, generic_category());
                  __h(__ec, socket_type(__ctx));
#else
		  __h(std::make_error_code(errc::operation_not_supported), 0);
#endif
	      });
	  return __init.result.get();
	}

      socket_type
      accept(endpoint_type& __endpoint)
      {
	return accept(get_executor().context(), __endpoint,
		      __throw_on_error{"basic_socket_acceptor::accept"});
      }

      socket_type
      accept(endpoint_type& __endpoint, error_code& __ec)
      { return accept(get_executor().context(), __endpoint, __ec); }

      socket_type
      accept(io_context& __ctx, endpoint_type& __endpoint)
      {
	return accept(__ctx, __endpoint,
		      __throw_on_error{"basic_socket_acceptor::accept"});
      }

      socket_type
      accept(io_context& __ctx, endpoint_type& __endpoint, error_code& __ec)
      {
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	do
	  {
	    socklen_t __len = __endpoint.capacity();
	    int __h = ::accept(native_handle(), (sockaddr*)__endpoint.data(),
			       &__len);
	    if (__h != -1)
	      {
		__endpoint.resize(__len);
		return socket_type{__ctx, _M_protocol, __h};
	      }
	  } while (errno == ECONNABORTED && enable_connection_aborted());
	__ec.assign(errno, generic_category());
#else
	__ec = std::make_error_code(errc::operation_not_supported);
#endif
	return socket_type{__ctx};
      }

      template<class _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, socket_type)>
	async_accept(endpoint_type& __endpoint,
			     _CompletionToken&& __token)
	{
	  return async_accept(get_executor().context(), __endpoint,
			      std::forward<_CompletionToken>(__token));
	}

      template<class _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, socket_type)>
	async_accept(io_context& __ctx, endpoint_type& __endpoint,
			     _CompletionToken&& __token)
        {
          async_completion<_CompletionToken, void(error_code, socket_type)>
            __init{__token};

	  __ctx.async_wait(native_handle(),
	      (int) socket_base::wait_read,
	      [__h = std::move(__init.completion_handler),
              __ep = std::move(__endpoint),
               __connabort = enable_connection_aborted(),
               __fd = native_handle(),
               &__ctx
              ]
              (error_code __ec) mutable {
                  if (__ec)
                    {
                      __h(__ec, socket_type(__ctx));
                      return;
                    }
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
                  do
                    {
                      socklen_t __len = __ep.capacity();
                      int __newfd = ::accept(__fd, __ep.data, &__len);
                      if (__newfd != -1)
                        {
                          __ep.resize(__len);
                          auto __protocol = __ep.protocol();
                          __ec.clear();
                          __h(__ec, socket_type{__ctx, __protocol, __newfd});
                          return;
                        }
                    } while (errno == ECONNABORTED && __connabort);
                  __ec.assign(errno, generic_category());
#else
		  __ec = std::make_error_code(errc::operation_not_supported);
#endif
                  __h(__ec, socket_type(__ctx));
	      });
	  return __init.result.get();
        }

      void
      wait(wait_type __w)
      { wait(__w, __throw_on_error{"basic_socket_acceptor::wait"}); }

      void
      wait(wait_type __w, error_code& __ec)
      {
#ifdef _GLIBCXX_HAVE_POLL_H
	::pollfd __fds;
	__fds.fd = native_handle();
	__fds.events = __w; // __w | POLLIN;
	if (::poll(&__fds, 1, -1) == -1)
	  __ec.assign(errno, generic_category());
	else
	  __ec.clear();
#else
	__ec = std::make_error_code(errc::operation_not_supported);
#endif
      }

      template<class _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code)>
	async_wait(wait_type __w, _CompletionToken&& __token)
        {
	  async_completion<_CompletionToken, void(error_code)> __init{__token};
	  get_executor().context().async_wait( native_handle(),
	      static_cast<int>(__w),
	      [__h = std::move(__init.completion_handler)]
              (error_code __ec) mutable {
		  __h(__ec);
	      });
	  return __init.result.get();
	}

    private:
      protocol_type _M_protocol;
    };

  /// @}

  /** @brief Socket streams
   * @{
   */

  template<typename _Protocol, typename _Clock, typename _WaitTraits>
    class basic_socket_streambuf : public basic_streambuf<char>
    {
    public:
      // types:

      using protocol_type = _Protocol;
      using endpoint_type = typename protocol_type::endpoint;
      using clock_type = _Clock;
      using time_point = typename clock_type::time_point;
      using duration = typename clock_type::duration;
      using wait_traits_type = _WaitTraits;

      // construct / copy / destroy:

      basic_socket_streambuf() : _M_socket(_S_ctx()) { }

      explicit
      basic_socket_streambuf(basic_stream_socket<protocol_type> __s)
      : _M_socket(std::move(__s)) { }

      basic_socket_streambuf(const basic_socket_streambuf&) = delete;

      basic_socket_streambuf(basic_socket_streambuf&& __rhs); // TODO


      virtual ~basic_socket_streambuf(); // TODO

      basic_socket_streambuf& operator=(const basic_socket_streambuf&) = delete;

      basic_socket_streambuf& operator=(basic_socket_streambuf&& __rhs); // TODO

      // members:

      basic_socket_streambuf* connect(const endpoint_type& __e); // TODO

      template<typename... _Args>
	basic_socket_streambuf* connect(_Args&&... ); // TODO

      basic_socket_streambuf* close(); // TODO

      basic_socket<protocol_type>& socket() { return _M_socket; }

      error_code error() const noexcept { return _M_ec; }

      time_point expiry() const { return _M_expiry; }

      void
      expires_at(const time_point& __t)
      { _M_expiry = __t; }

      void
      expires_after(const duration& __d)
      { expires_at(clock_type::now() + __d); }

    protected:
      // overridden virtual functions: // TODO
      virtual int_type underflow() override;
      virtual int_type pbackfail(int_type __c = traits_type::eof()) override;
      virtual int_type overflow(int_type __c = traits_type::eof()) override;
      virtual int sync() override;
      virtual streambuf* setbuf(char_type* __s, streamsize __n) override;

    private:
      static io_context&
      _S_ctx()
      {
	static io_context __ctx;
	return __ctx;
      }

      basic_stream_socket<protocol_type> _M_socket;
      error_code _M_ec;
      time_point _M_expiry{ time_point::max() };
    };

  template<typename _Protocol, class _Clock, typename _WaitTraits>
    class basic_socket_iostream : public basic_iostream<char>
    {
      using __streambuf_type
	= basic_socket_streambuf<_Protocol, _Clock, _WaitTraits>;

    public:
      // types:

      using protocol_type = _Protocol;
      using endpoint_type = typename protocol_type::endpoint;
      using clock_type = _Clock;
      using time_point = typename clock_type::time_point;
      using duration = typename clock_type::duration;
      using wait_traits_type = _WaitTraits;

      // construct / copy / destroy:

      // TODO base-from-member ?
      basic_socket_iostream() : basic_iostream(nullptr), _M_sb()
      {
	this->init(std::addressof(_M_sb));
	this->setf(std::ios::unitbuf);
      }

      explicit
      basic_socket_iostream(basic_stream_socket<protocol_type> __s)
      : basic_iostream(nullptr), _M_sb(std::move(__s))
      {
	this->init(std::addressof(_M_sb));
	this->setf(std::ios::unitbuf);
      }

      basic_socket_iostream(const basic_socket_iostream&) = delete;

      basic_socket_iostream(basic_socket_iostream&& __rhs)
      : basic_iostream(nullptr), _M_sb(std::move(__rhs._M_sb))
	// XXX ???     ^^^^^^^
      {
	// XXX ??? this->init(std::addressof(_M_sb));
	this->set_rbduf(std::addressof(_M_sb));
      }

      template<typename... _Args>
	explicit
	basic_socket_iostream(_Args&&... __args)
	: basic_iostream(nullptr), _M_sb()
	{
	  this->init(std::addressof(_M_sb));
	  this->setf(std::ios::unitbuf);
	  connect(forward<_Args>(__args)...);
	}

      basic_socket_iostream& operator=(const basic_socket_iostream&) = delete;

      basic_socket_iostream& operator=(basic_socket_iostream&& __rhs); // TODO

      // members:

      template<typename... _Args>
	void
	connect(_Args&&... __args)
	{
	  if (rdbuf()->connect(forward<_Args>(__args)...) == nullptr)
	    this->setstate(failbit);
	}

      void
      close()
      {
	if (rdbuf()->close() == nullptr)
	  this->setstate(failbit);
      }

      basic_socket_streambuf<protocol_type, clock_type, wait_traits_type>*
      rdbuf() const
      { return const_cast<__streambuf_type*>(std::addressof(_M_sb)); }

      basic_socket<protocol_type>& socket() { return rdbuf()->socket(); }
      error_code error() const noexcept { return rdbuf()->error(); }

      time_point expiry() const { return rdbuf()->expiry(); }
      void expires_at(const time_point& __t) { rdbuf()->expires_at(__t); }
      void expires_after(const duration& __d) { rdbuf()->expires_after(__d); }

    private:
      __streambuf_type _M_sb;
    };

  /// @}

  /** @brief synchronous connect operations
   * @{
   */

  template<typename _Protocol, typename _EndpointSequence,
	   typename _ConnectCondition>
    inline typename _Protocol::endpoint
    connect(basic_socket<_Protocol>& __s,
	    const _EndpointSequence& __endpoints,
	    _ConnectCondition __c, error_code& __ec)
    {
      __ec.clear();
      bool __found = false;
      for (auto& __ep : __endpoints)
	{
	  if (__c(__ec, __ep))
	    {
	      __found = true;
	      __s.close(__ec);
	      if (!__ec)
		__s.open(__ep.protocol(), __ec);
	      if (!__ec)
		__s.connect(__ep, __ec);
	      if (!__ec)
		return __ep;
	    }
	}
      if (!__found)
	__ec = socket_errc::not_found;
      return typename _Protocol::endpoint{};
    }

  template<typename _Protocol, typename _InputIterator,
	   typename _ConnectCondition>
    inline _InputIterator
    connect(basic_socket<_Protocol>& __s,
	    _InputIterator __first, _InputIterator __last,
	    _ConnectCondition __c, error_code& __ec)
    {
      __ec.clear();
      bool __found = false;
      for (auto __i = __first; __i != __last; ++__i)
	{
	  if (__c(__ec, *__i))
	    {
	      __found = true;
	      __s.close(__ec);
	      if (!__ec)
		__s.open(typename _Protocol::endpoint(*__i).protocol(), __ec);
	      if (!__ec)
		__s.connect(*__i, __ec);
	      if (!__ec)
		return __i;
	    }
	}
      if (!__found)
	__ec = socket_errc::not_found;
      return __last;
    }

  template<typename _Protocol, typename _EndpointSequence,
	   typename _ConnectCondition>
    inline typename _Protocol::endpoint
    connect(basic_socket<_Protocol>& __s,
	    const _EndpointSequence& __endpoints,
	    _ConnectCondition __c)
    {
      return net::connect(__s, __endpoints, __c, __throw_on_error{"connect"});
    }

  template<typename _Protocol, typename _InputIterator,
	   typename _ConnectCondition>
    inline _InputIterator
    connect(basic_socket<_Protocol>& __s,
	    _InputIterator __first, _InputIterator __last,
	    _ConnectCondition __c)
    {
      return net::connect(__s, __first, __last, __c,
			  __throw_on_error{"connect"});
    }

  template<typename _Protocol, typename _EndpointSequence>
    inline typename _Protocol::endpoint
    connect(basic_socket<_Protocol>& __s,
	    const _EndpointSequence& __endpoints)
    {
      return net::connect(__s, __endpoints, [](auto, auto){ return true; },
			  __throw_on_error{"connect"});
    }

  template<typename _Protocol, typename _EndpointSequence>
    inline typename _Protocol::endpoint
    connect(basic_socket<_Protocol>& __s,
	    const _EndpointSequence& __endpoints,
	    error_code& __ec)
    {
      return net::connect(__s, __endpoints, [](auto, auto){ return true; },
			  __ec);
    }

  template<typename _Protocol, typename _InputIterator>
    inline _InputIterator
    connect(basic_socket<_Protocol>& __s,
	    _InputIterator __first, _InputIterator __last)
    {
      return net::connect(__s, __first, __last, [](auto, auto){ return true; },
			  __throw_on_error{"connect"});
    }

  template<typename _Protocol, typename _InputIterator>
    inline _InputIterator
    connect(basic_socket<_Protocol>& __s,
	    _InputIterator __first, _InputIterator __last,
	    error_code& __ec)
    {
      return net::connect(__s, __first, __last, [](auto, auto){ return true; },
			  __ec);
    }

  /// @}

  /** @brief asynchronous connect operations
   * @{
   */

  template<typename _Protocol, typename _EndpointSequence,
	   typename _ConnectCondition, typename _CompletionToken>
    inline
    __deduced_t<_CompletionToken,
		void(error_code, typename _Protocol::endpoint)>
    async_connect(basic_socket<_Protocol>& __s,
		  const _EndpointSequence& __endpoints,
		  _ConnectCondition __c, _CompletionToken&& __token); // TODO

  template<typename _Protocol, typename _EndpointSequence,
	   typename _CompletionToken>
    inline
    __deduced_t<_CompletionToken,
		void(error_code, typename _Protocol::endpoint)>
    async_connect(basic_socket<_Protocol>& __s,
		  const _EndpointSequence& __endpoints,
		  _CompletionToken&& __token)
    {
      return net::async_connect(__s, __endpoints,
				[](auto, auto){ return true; },
				forward<_CompletionToken>(__token));
    }

  template<typename _Protocol, typename _InputIterator,
	   typename _ConnectCondition, typename _CompletionToken>
    inline
    __deduced_t<_CompletionToken, void(error_code, _InputIterator)>
    async_connect(basic_socket<_Protocol>& __s,
		  _InputIterator __first, _InputIterator __last,
		  _ConnectCondition __c, _CompletionToken&& __token); // TODO

  template<typename _Protocol, typename _InputIterator,
	   typename _CompletionToken>
    inline
    __deduced_t<_CompletionToken, void(error_code, _InputIterator)>
    async_connect(basic_socket<_Protocol>& __s,
		  _InputIterator __first, _InputIterator __last,
		  _CompletionToken&& __token)
    {
      return net::async_connect(__s, __first, __last,
				[](auto, auto){ return true; },
				forward<_CompletionToken>(__token));
    }

  /// @}

#endif  // _GLIBCXX_HAVE_UNISTD_H

  /// @}

} // namespace v1
} // namespace net
} // namespace experimental

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // C++14

#endif // _GLIBCXX_EXPERIMENTAL_SOCKET
