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

// Copyright (C) 2015-2019 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.
 */

#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
{

  /**
   * @ingroup networking
   * @{
   */

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

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

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

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

      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)
      {
	if (!is_open())
	  {
	    open(__endpoint.protocol(), __ec);
	    if (__ec)
	      return;
	  }
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
	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(std::addressof(__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); }

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

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

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // C++14

#endif // _GLIBCXX_EXPERIMENTAL_SOCKET
