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

// Copyright (C) 2015-2020 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()); }

  template<typename _Tp, typename = __void_t<>>
    struct __is_endpoint_impl : false_type
    { };

  // Check Endpoint requirements.
  template<typename _Tp>
    auto
    __endpoint_reqs(const _Tp* __a = 0)
    -> enable_if_t<__and_<
      is_default_constructible<_Tp>,
      __is_value_constructible<_Tp>,
      is_same<decltype(__a->__protocol()), typename _Tp::protocol_type>
      >::value,
    __void_t< typename _Tp::protocol_type::endpoint >>;

  template<typename _Tp>
    struct __is_endpoint_impl<_Tp, decltype(__endpoint_reqs<_Tp>())>
    : true_type
    { };

  template<typename _Tp>
    struct __is_endpoint : __is_endpoint_impl<_Tp>
    { };

  // TODO Endpoint reqs for extensible implementations
  // TODO _Protocol reqs
  // TODO AcceptableProtocol reqs
  // 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
    struct broadcast : __sockopt_crtp<broadcast, bool>
    {
      using __sockopt_crtp::__sockopt_crtp;

      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_BROADCAST;
    };

    struct debug : __sockopt_crtp<debug, bool>
    {
      using __sockopt_crtp::__sockopt_crtp;

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

    struct do_not_route : __sockopt_crtp<do_not_route, bool>
    {
      using __sockopt_crtp::__sockopt_crtp;

      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_DONTROUTE;
    };

    struct keep_alive : __sockopt_crtp<keep_alive, bool>
    {
      using __sockopt_crtp::__sockopt_crtp;

      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_KEEPALIVE;
    };

    struct linger : __sockopt_crtp<linger, ::linger>
    {
      using __sockopt_crtp::__sockopt_crtp;

      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(); }

      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_LINGER;
    };

    struct out_of_band_inline : __sockopt_crtp<out_of_band_inline, bool>
    {
      using __sockopt_crtp::__sockopt_crtp;

      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_OOBINLINE;
    };

    struct receive_buffer_size : __sockopt_crtp<receive_buffer_size>
    {
      using __sockopt_crtp::__sockopt_crtp;

      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_RCVBUF;
    };

    struct receive_low_watermark : __sockopt_crtp<receive_low_watermark>
    {
      using __sockopt_crtp::__sockopt_crtp;

      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_RCVLOWAT;
    };

    struct reuse_address : __sockopt_crtp<reuse_address, bool>
    {
      using __sockopt_crtp::__sockopt_crtp;

      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_REUSEADDR;
    };

    struct send_buffer_size : __sockopt_crtp<send_buffer_size>
    {
      using __sockopt_crtp::__sockopt_crtp;

      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_SNDBUF;
    };

    struct send_low_watermark : __sockopt_crtp<send_low_watermark>
    {
      using __sockopt_crtp::__sockopt_crtp;

      static const int _S_level = SOL_SOCKET;
      static const int _S_name = SO_SNDLOWAT;
    };

    enum shutdown_type : int
    {
      __shutdown_receive	= SHUT_RD,
      __shutdown_send		= SHUT_WR,
      __shutdown_both		= SHUT_RDWR
    };
    static constexpr shutdown_type shutdown_receive	= __shutdown_receive;
    static constexpr shutdown_type shutdown_send	= __shutdown_send;
    static constexpr shutdown_type shutdown_both	= __shutdown_both;

#ifdef _GLIBCXX_HAVE_POLL_H
    enum wait_type : int
    {
      __wait_read		= POLLIN,
      __wait_write		= POLLOUT,
      __wait_error		= POLLERR
    };
    static constexpr wait_type wait_read		= __wait_read;
    static constexpr wait_type wait_write		= __wait_write;
    static constexpr wait_type wait_error		= __wait_error;
#endif

    enum message_flags : int
    {
      __message_peek		= MSG_PEEK,
      __message_oob		= MSG_OOB,
      __message_dontroute	= MSG_DONTROUTE
    };
    static constexpr message_flags message_peek		= __message_peek;
    static constexpr message_flags message_out_of_band	= __message_oob;
    static constexpr message_flags message_do_not_route	= __message_dontroute;

    static const int max_listen_connections = SOMAXCONN;
#endif

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

#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
    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
  };

  constexpr socket_base::message_flags
  operator&(socket_base::message_flags __f1, socket_base::message_flags __f2)
  { return socket_base::message_flags( int(__f1) & int(__f2) ); }

  constexpr socket_base::message_flags
  operator|(socket_base::message_flags __f1, socket_base::message_flags __f2)
  { return socket_base::message_flags( int(__f1) | int(__f2) ); }

  constexpr socket_base::message_flags
  operator^(socket_base::message_flags __f1, socket_base::message_flags __f2)
  { return socket_base::message_flags( int(__f1) ^ int(__f2) ); }

  constexpr socket_base::message_flags
  operator~(socket_base::message_flags __f)
  { return socket_base::message_flags( ~int(__f) ); }

  inline socket_base::message_flags&
  operator&=(socket_base::message_flags& __f1, socket_base::message_flags __f2)
  { return __f1 = (__f1 & __f2); }

  inline socket_base::message_flags&
  operator|=(socket_base::message_flags& __f1, socket_base::message_flags __f2)
  { return __f1 = (__f1 | __f2); }

  inline socket_base::message_flags&
  operator^=(socket_base::message_flags& __f1, socket_base::message_flags __f2)
  { return __f1 = (__f1 ^ __f2); }

#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)
    {
#ifdef _GLIBCXX_HAVE_FCNTL_H
      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
    {
#ifdef _GLIBCXX_HAVE_FCNTL_H
      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)
	{
	  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();
	}

      template<typename _GettableSocketOption>
	void
	get_option(_GettableSocketOption& __option, error_code& __ec) const
	{
	  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();
	}

      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);
	    set_option(socket_base::linger{false, chrono::seconds{}}, __ec);
	    ::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:

      typedef io_context::executor_type executor_type;
      typedef int native_handle_type;
      typedef _Protocol protocol_type;
      typedef typename protocol_type::endpoint endpoint_type;

      // 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(),
	      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:

      typedef int native_handle_type;
      typedef _Protocol protocol_type;
      typedef typename protocol_type::endpoint endpoint_type;

      // 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(),
	      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(),
	      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(),
	      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(),
	      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:

      typedef int native_handle_type;
      typedef _Protocol protocol_type;
      typedef typename protocol_type::endpoint endpoint_type;

      // 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(),
	      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(),
	      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:

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

      // 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,
			    bool __reuse_addr = true)
      : basic_socket_acceptor(__ctx, __endpoint.protocol())
      {
	if (__reuse_addr)
	  set_option(reuse_address(true));
	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.get_executor().context().async_wait(native_handle(),
	      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.get_executor().context().async_wait(native_handle(),
	      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:

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

      // 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:

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

      // 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
