// <experimental/internet> -*- 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/internet
 *  This is a TS C++ Library header.
 */

#ifndef _GLIBCXX_EXPERIMENTAL_INTERNET
#define _GLIBCXX_EXPERIMENTAL_INTERNET

#pragma GCC system_header

#if __cplusplus >= 201402L

#include <experimental/netfwd>
#include <experimental/io_context>
#include <experimental/bits/net.h>
#include <array>
#include <forward_list>
#include <sstream>
#include <cstdint>
#include <experimental/string_view>
#ifdef _GLIBCXX_HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef _GLIBCXX_HAVE_SYS_SOCKET_H
# include <sys/socket.h>	// AF_INET, AF_INET6, SOCK_DGRAM, SOCK_STREAM
#endif
#ifdef _GLIBCXX_HAVE_ARPA_INET_H
# include <arpa/inet.h>		// inet_ntop
#endif
#ifdef _GLIBCXX_HAVE_NETINET_IN_H
# include <netinet/in.h>	// IPPROTO_IP
#endif
#ifdef _GLIBCXX_HAVE_NETINET_TCP_H
# include <netinet/tcp.h>	// TCP_NODELAY
#endif
#ifdef _GLIBCXX_HAVE_NETDB_H
# include <netdb.h>		// getaddrinfo etc.
#endif

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

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

#ifdef _GLIBCXX_HAVE_NETDB_H
  /** Error codes for resolver errors.
   * @{
   */

  enum class resolver_errc : int {
    host_not_found = EAI_NONAME,
    host_not_found_try_again = EAI_AGAIN,
    service_not_found = EAI_SERVICE
  };

  /// Error category for resolver errors.
  inline const error_category& resolver_category() noexcept // TODO non-inline
  {
    struct __cat : error_category
    {
      const char* name() const noexcept { return "resolver"; }
      std::string message(int __e) const { return ::gai_strerror(__e); }
      virtual void __message(int) { } // TODO dual ABI XXX
    };
    static __cat __c;
    return __c;
  }

  error_code make_error_code(resolver_errc __e) noexcept
  { return error_code(static_cast<int>(__e), resolver_category()); }

  error_condition make_error_condition(resolver_errc __e) noexcept
  { return error_condition(static_cast<int>(__e), resolver_category()); }

  /// @}
#endif

  typedef uint_least16_t port_type;	///< Type used for port numbers.
  typedef uint_least32_t scope_id_type;	///< Type used for IPv6 scope IDs.

  /// Convenience alias for constraining allocators for strings.
  template<typename _Alloc>
    using __string_with
      = enable_if_t<std::is_same<typename _Alloc::value_type, char>::value,
		    std::basic_string<char, std::char_traits<char>, _Alloc>>;

  /** Tag indicating conversion between IPv4 and IPv4-mapped IPv6 addresses.
   * @{
   */

  struct v4_mapped_t {};
  constexpr v4_mapped_t v4_mapped;

  // @}

  /// An IPv4 address.
  class address_v4
  {
  public:
    // types:
    typedef uint_least32_t uint_type;

    struct bytes_type : array<unsigned char, 4>
    {
      template<typename... _Tp>
	explicit constexpr
	bytes_type(_Tp... __tp)
	: array<unsigned char, 4>{{static_cast<unsigned char>(__tp)...}}
	{
#if UCHAR_MAX > 0xFF
	  for (auto __b : *this)
	    if (__b > 0xFF)
	      __throw_out_of_range("invalid address_v4::bytes_type value");
#endif
	}
    };

    // constructors:
    constexpr address_v4() noexcept : _M_addr(0) { }

    constexpr address_v4(const address_v4& a) noexcept = default;

    constexpr
    address_v4(const bytes_type& __b)
    : _M_addr((__b[0] << 24) | (__b[1] << 16) | (__b[2] << 8) | __b[3])
    { }

    explicit constexpr
    address_v4(uint_type __val) : _M_addr(_S_hton_32(__val))
    {
#if UINT_LEAST32_MAX > 0xFFFFFFFF
      if (__val > 0xFFFFFFFF)
	__throw_out_of_range("invalid address_v4::uint_type value");
#endif
    }

    // assignment:
    address_v4& operator=(const address_v4& a) noexcept = default;

    // members:
    constexpr bool is_unspecified() const noexcept { return to_uint() == 0; }

    constexpr bool
    is_loopback() const noexcept
    { return (to_uint() & 0xFF000000) == 0x7F000000; }

    constexpr bool
    is_multicast() const noexcept
    { return (to_uint() & 0xF0000000) == 0xE0000000; }

    constexpr bytes_type
    to_bytes() const noexcept
    {
      return bytes_type{
	  (_M_addr >> 24) & 0xFF,
	  (_M_addr >> 16) & 0xFF,
	  (_M_addr >> 8) & 0xFF,
	  _M_addr & 0xFF
      };
    }

    constexpr uint_type
    to_uint() const noexcept { return _S_ntoh_32(_M_addr); }

#ifdef _GLIBCXX_HAVE_ARPA_INET_H
    template<typename _Allocator = allocator<char>>
      __string_with<_Allocator>
      to_string(const _Allocator& __a = _Allocator()) const
      {
	__string_with<_Allocator> __str(__a);
	__str.resize(INET6_ADDRSTRLEN);
	if (inet_ntop(AF_INET, &_M_addr, &__str.front(), __str.size()))
	  __str.erase(__str.find('\0'));
	else
	  __str.resize(0);
	return __str;
      }
#endif

    // static members:
    static constexpr address_v4 any() noexcept { return address_v4{}; }

    static constexpr
    address_v4 loopback() noexcept { return address_v4{0x7F000001}; }

    static constexpr
    address_v4 broadcast() noexcept { return address_v4{0xFFFFFFFF}; }

  private:
    template<typename _InternetProtocol>
      friend class basic_endpoint;

    friend address_v4 make_address_v4(const char*, error_code&) noexcept;

#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
    static constexpr uint16_t _S_hton_16(uint16_t __h) { return __h; }
    static constexpr uint16_t _S_ntoh_16(uint16_t __n) { return __n; }
    static constexpr uint32_t _S_hton_32(uint32_t __h) { return __h; }
    static constexpr uint32_t _S_ntoh_32(uint32_t __n) { return __n; }
#else
    static constexpr uint16_t
    _S_hton_16(uint16_t __h) { return __builtin_bswap16(__h); }

    static constexpr uint16_t
    _S_ntoh_16(uint16_t __n) { return __builtin_bswap16(__n); }

    static constexpr uint32_t
    _S_hton_32(uint32_t __h) { return __builtin_bswap32(__h); }

    static constexpr uint32_t
    _S_ntoh_32(uint32_t __n) { return __builtin_bswap32(__n); }
#endif

    in_addr_t _M_addr; // network byte order
  };

  /// An IPv6 address.
  class address_v6
  {
  public:
    // types:
    struct bytes_type : array<unsigned char, 16>
    {
      template<typename... _Tp> explicit constexpr bytes_type(_Tp... __t)
	: array<unsigned char, 16>{{static_cast<unsigned char>(__t)...}} { }
    };

    // constructors:
    constexpr address_v6() noexcept : _M_bytes(), _M_scope_id() { }

    constexpr address_v6(const address_v6& __a) noexcept = default;

    constexpr
    address_v6(const bytes_type& __bytes, scope_id_type __scope = 0)
    : _M_bytes(__bytes), _M_scope_id(__scope)
    { }

    // assignment:
    address_v6& operator=(const address_v6& __a) noexcept = default;

    // members:
    void scope_id(scope_id_type __id) noexcept { _M_scope_id = __id; }

    constexpr scope_id_type scope_id() const noexcept { return _M_scope_id; }

    constexpr bool
    is_unspecified() const noexcept
    {
      for (int __i = 0; __i < 16; ++__i)
	if (_M_bytes[__i] != 0x00)
	  return false;
      return _M_scope_id == 0;
    }

    constexpr bool
    is_loopback() const noexcept
    {
      for (int __i = 0; __i < 15; ++__i)
	if (_M_bytes[__i] != 0x00)
	  return false;
      return _M_bytes[15] == 0x01 && _M_scope_id == 0;
    }

    constexpr bool
    is_multicast() const noexcept { return _M_bytes[0] == 0xFF; }

    constexpr bool
    is_link_local() const noexcept
    { return _M_bytes[0] == 0xFE && (_M_bytes[1] & 0xC0) == 0x80; }

    constexpr bool
    is_site_local() const noexcept
    { return _M_bytes[0] == 0xFE && (_M_bytes[1] & 0xC0) == 0xC0; }

    constexpr bool
    is_v4_mapped() const noexcept
    {
      const bytes_type& __b = _M_bytes;
      return __b[0] == 0 && __b[1] == 0 && __b[ 2] == 0    && __b[ 3] == 0
	  && __b[4] == 0 && __b[5] == 0 && __b[ 6] == 0    && __b[ 7] == 0
	  && __b[8] == 0 && __b[9] == 0 && __b[10] == 0xFF && __b[11] == 0xFF;
    }

    constexpr bool
    is_multicast_node_local() const noexcept
    { return is_multicast() && (_M_bytes[1] & 0x0F) == 0x01; }

    constexpr bool
    is_multicast_link_local() const noexcept
    { return is_multicast() && (_M_bytes[1] & 0x0F) == 0x02; }

    constexpr bool
    is_multicast_site_local() const noexcept
    { return is_multicast() && (_M_bytes[1] & 0x0F) == 0x05; }

    constexpr bool
    is_multicast_org_local() const noexcept
    { return is_multicast() && (_M_bytes[1] & 0x0F) == 0x08; }

    constexpr bool
    is_multicast_global() const noexcept
    { return is_multicast() && (_M_bytes[1] & 0x0F) == 0x0b; }

    constexpr bytes_type to_bytes() const noexcept { return _M_bytes; }

#ifdef _GLIBCXX_HAVE_ARPA_INET_H
    template<typename _Allocator = allocator<char>>
      __string_with<_Allocator>
      to_string(const _Allocator& __a = _Allocator()) const
      {
	__string_with<_Allocator> __str(__a);
	__str.resize(INET6_ADDRSTRLEN);
	if (inet_ntop(AF_INET6, &_M_bytes, &__str.front(), __str.size()))
	  __str.erase(__str.find('\0'));
	else
	  __str.resize(0);
	return __str;
      }
#endif

    // static members:
    static constexpr address_v6
    any() noexcept
    {
      address_v6 __addr;
      __builtin_memcpy(&__addr._M_bytes, in6addr_any.s6_addr, 16);
      return __addr;
    }

    static constexpr address_v6
    loopback() noexcept
    {
      address_v6 __addr;
      __builtin_memcpy(&__addr._M_bytes, in6addr_loopback.s6_addr, 16);
      return __addr;
    }

  private:
    template<typename _InternetProtocol>
      friend class basic_endpoint;

    friend constexpr bool
    operator==(const address_v6&, const address_v6&) noexcept;

    friend constexpr bool
    operator< (const address_v6&, const address_v6&) noexcept;

    bytes_type _M_bytes;
    scope_id_type _M_scope_id;
  };

  /// Exception type thrown on misuse of IPv4 addresses as IPv6 or vice versa.
  class bad_address_cast : public bad_cast
  {
  public:
    bad_address_cast() { }

    const char* what() const noexcept { return "bad address cast"; }
  };

  /// An IPv4 or IPv6 address.
  class address
  {
  public:
    // constructors:
    constexpr address() noexcept : _M_v4(), _M_is_v4(true) { }

    constexpr
    address(const address& __a) noexcept : _M_uninit(), _M_is_v4(__a._M_is_v4)
    {
      if (_M_is_v4)
	::new (std::addressof(_M_v4)) address_v4(__a.to_v4());
      else
	::new (std::addressof(_M_v6)) address_v6(__a.to_v6());
    }

    constexpr
    address(const address_v4& __a) noexcept : _M_v4(__a), _M_is_v4(true) { }

    constexpr
    address(const address_v6& __a) noexcept : _M_v6(__a), _M_is_v4(false) { }

    // assignment:
    address&
    operator=(const address& __a) noexcept
    {
      if (__a._M_is_v4)
	*this = __a.to_v4();
      else
	*this = __a.to_v6();
      return *this;
    }

    address&
    operator=(const address_v4& __a) noexcept
    {
      ::new (std::addressof(_M_v4)) address_v4(__a);
      _M_is_v4 = true;
      return *this;
    }

    address&
    operator=(const address_v6& __a) noexcept
    {
      ::new (std::addressof(_M_v6)) address_v6(__a);
      _M_is_v4 = false;
      return *this;
    }

    // members:

    constexpr bool is_v4() const noexcept { return _M_is_v4; }
    constexpr bool is_v6() const noexcept { return !_M_is_v4; }

    constexpr address_v4
    to_v4() const
    {
      if (!is_v4())
	_GLIBCXX_THROW_OR_ABORT(bad_address_cast());
      return _M_v4;
    }

    constexpr address_v6
    to_v6() const
    {
      if (!is_v6())
	_GLIBCXX_THROW_OR_ABORT(bad_address_cast());
      return _M_v6;
    }

    constexpr bool
    is_unspecified() const noexcept
    { return _M_is_v4 ? _M_v4.is_unspecified() : _M_v6.is_unspecified(); }

    constexpr bool
    is_loopback() const noexcept
    { return _M_is_v4 ? _M_v4.is_loopback() : _M_v6.is_loopback(); }

    constexpr bool
    is_multicast() const noexcept
    { return _M_is_v4 ? _M_v4.is_multicast() : _M_v6.is_multicast(); }

    template<typename _Allocator = allocator<char>>
      __string_with<_Allocator>
      to_string(const _Allocator& __a = _Allocator()) const
      {
	if (_M_is_v4)
	  return to_v4().to_string(__a);
	return to_v6().to_string(__a);
      }

  private:
    template<typename _InternetProtocol>
      friend class basic_endpoint;

    friend constexpr bool
    operator==(const address&, const address&) noexcept;

    friend constexpr bool
    operator<(const address&, const address&) noexcept;

    union {
      address_v4 _M_v4;
      address_v6 _M_v6;
      bool	 _M_uninit;
    };
    bool _M_is_v4;
  };

  /** ip::address_v4 comparisons
   * @{
   */

  constexpr bool
  operator==(const address_v4& __a, const address_v4& __b) noexcept
  { return __a.to_uint() == __b.to_uint(); }

  constexpr bool
  operator!=(const address_v4& __a, const address_v4& __b) noexcept
  { return !(__a == __b); }

  constexpr bool
  operator< (const address_v4& __a, const address_v4& __b) noexcept
  { return __a.to_uint() < __b.to_uint(); }

  constexpr bool
  operator> (const address_v4& __a, const address_v4& __b) noexcept
  { return __b < __a; }

  constexpr bool
  operator<=(const address_v4& __a, const address_v4& __b) noexcept
  { return !(__b < __a); }

  constexpr bool
  operator>=(const address_v4& __a, const address_v4& __b) noexcept
  { return !(__a < __b); }

  // @}

  /** ip::address_v6 comparisons
   * @{
   */

  constexpr bool
  operator==(const address_v6& __a, const address_v6& __b) noexcept
  {
    const auto& __aa = __a._M_bytes;
    const auto& __bb = __b._M_bytes;
    int __i = 0;
    for (; __i < 16 && __aa[__i] == __bb[__i]; ++__i)
      ;
    return __i == 16 ? __a.scope_id() == __b.scope_id() : false;
  }

  constexpr bool
  operator!=(const address_v6& __a, const address_v6& __b) noexcept
  { return !(__a == __b); }

  constexpr bool
  operator< (const address_v6& __a, const address_v6& __b) noexcept
  {
    const auto& __aa = __a._M_bytes;
    const auto& __bb = __b._M_bytes;
    int __i = 0;
    for (; __i < 16 && __aa[__i] == __bb[__i]; ++__i)
      ;
    return __i == 16 ? __a.scope_id() < __b.scope_id() : __aa[__i] < __bb[__i];
  }

  constexpr bool
  operator> (const address_v6& __a, const address_v6& __b) noexcept
  { return __b < __a; }

  constexpr bool
  operator<=(const address_v6& __a, const address_v6& __b) noexcept
  { return !(__b < __a); }

  constexpr bool
  operator>=(const address_v6& __a, const address_v6& __b) noexcept
  { return !(__a < __b); }

  // @}

  /** ip::address comparisons
   * @{
   */

  constexpr bool
  operator==(const address& __a, const address& __b) noexcept
  {
    if (__a.is_v4())
      return __b.is_v4() ? __a._M_v4 == __b._M_v4 : false;
    return __b.is_v4() ? false : __a._M_v6 == __b._M_v6;
  }

  constexpr bool
  operator!=(const address& __a, const address& __b) noexcept
  { return !(__a == __b); }

  constexpr bool
  operator< (const address& __a, const address& __b) noexcept
  {
    if (__a.is_v4())
      return __b.is_v4() ? __a._M_v4 < __b._M_v4 : true;
    return __b.is_v4() ? false : __a._M_v6 < __b._M_v6;
  }

  constexpr bool
  operator> (const address& __a, const address& __b) noexcept
  { return __b < __a; }

  constexpr bool
  operator<=(const address& __a, const address& __b) noexcept
  { return !(__b < __a); }

  constexpr bool
  operator>=(const address& __a, const address& __b) noexcept
  { return !(__a < __b); }

  // @}

  /** ip::address_v4 creation
   * @{
   */

  constexpr address_v4
  make_address_v4(const address_v4::bytes_type& __b)
  { return address_v4{__b}; }

  constexpr address_v4
  make_address_v4(address_v4::uint_type __val)
  { return address_v4{__val}; }

  constexpr address_v4
  make_address_v4(v4_mapped_t, const address_v6& __a)
  {
    if (!__a.is_v4_mapped())
      _GLIBCXX_THROW_OR_ABORT(bad_address_cast());

    const auto __v6b = __a.to_bytes();
    return address_v4::bytes_type(__v6b[12], __v6b[13], __v6b[14], __v6b[15]);
  }

  inline address_v4
  make_address_v4(const char* __str, error_code& __ec) noexcept
  {
    address_v4 __a;
    const int __res = ::inet_pton(AF_INET, __str, &__a._M_addr);
    if (__res == 1)
      {
	__ec.clear();
	return __a;
      }
    if (__res == 0)
      __ec = std::make_error_code(std::errc::invalid_argument);
    else
      __ec.assign(errno, generic_category());
    return {};
  }

  inline address_v4
  make_address_v4(const char* __str)
  { return make_address_v4(__str, __throw_on_error{"make_address_v4"}); }

  inline address_v4
  make_address_v4(const string& __str, error_code& __ec) noexcept
  { return make_address_v4(__str.c_str(), __ec); }

  inline address_v4
  make_address_v4(const string& __str)
  { return make_address_v4(__str.c_str()); }

  inline address_v4
  make_address_v4(string_view __str, error_code& __ec) noexcept
  {
    char __buf[INET_ADDRSTRLEN];
    auto __len = __str.copy(__buf, sizeof(__buf));
    if (__len == sizeof(__buf))
      {
	__ec = std::make_error_code(std::errc::invalid_argument);
	return {};
      }
    __ec.clear();
    __buf[__len] = '\0';
    return make_address_v4(__buf, __ec);
  }

  inline address_v4
  make_address_v4(string_view __str)
  { return make_address_v4(__str, __throw_on_error{"make_address_v4"}); }

  // @}

  /** ip::address_v6 creation
   * @{
   */

  constexpr address_v6
  make_address_v6(const address_v6::bytes_type& __b, scope_id_type __scope = 0)
  { return address_v6{__b, __scope}; }

  constexpr address_v6
  make_address_v6(v4_mapped_t, const address_v4& __a) noexcept
  {
    const address_v4::bytes_type __v4b = __a.to_bytes();
    address_v6::bytes_type __v6b(0, 0, 0, 0, 0, 0, 0, 0,
				 0, 0, 0xFF, 0xFF,
				 __v4b[0], __v4b[1], __v4b[2], __v4b[3]);
    return address_v6(__v6b);
  }

  inline address_v6
  __make_address_v6(const char* __addr, const char* __scope, error_code& __ec)
  {
    address_v6::bytes_type __b;
    int __res = ::inet_pton(AF_INET6, __addr, __b.data());
    if (__res == 1)
      {
	__ec.clear();
	if (!__scope)
	  {
	    return { __b };
	  }

	char* __eptr;
	unsigned long __val = std::strtoul(__scope, &__eptr, 10);
	if (__eptr != __scope && !*__eptr
	    && __val <= numeric_limits<scope_id_type>::max())
	  {
	    return { __b, static_cast<scope_id_type>(__val) };
	  }
	__ec = std::make_error_code(std::errc::invalid_argument);
      }
    else if (__res == 0)
      __ec = std::make_error_code(std::errc::invalid_argument);
    else
      __ec.assign(errno, generic_category());
    return {};
  }

  inline address_v6
  make_address_v6(const char* __str, error_code& __ec) noexcept
  {
    auto __p = __builtin_strchr(__str, '%');
    if (__p == nullptr)
      return __make_address_v6(__str, nullptr, __ec);
    char __buf[64];
    char* __out = __buf;
    bool __skip_leading_zero = true;
    while (__str < __p && __out < std::end(__buf))
      {
	if (!__skip_leading_zero || *__str != '0')
	  {
	    if (*__str == ':' || *__str == '.')
	      __skip_leading_zero = true;
	    else
	      __skip_leading_zero = false;
	    *__out = *__str;
	  }
	__str++;
      }
    if (__out == std::end(__buf))
      __ec = std::make_error_code(std::errc::invalid_argument);
    else
      {
	*__out = '\0';
	return __make_address_v6(__buf, __p + 1, __ec);
      }
  }

  inline address_v6
  make_address_v6(const char* __str)
  { return make_address_v6(__str, __throw_on_error{"make_address_v6"}); }

  inline address_v6
  make_address_v6(const string& __str, error_code& __ec) noexcept
  {
    auto __pos = __str.find('%');
    if (__pos == string::npos)
      return __make_address_v6(__str.c_str(), nullptr, __ec);
    char __buf[64];
    char* __out = __buf;
    bool __skip_leading_zero = true;
    size_t __n = 0;
    while (__n < __pos && __out < std::end(__buf))
      {
	if (!__skip_leading_zero || __str[__n] != '0')
	  {
	    if (__str[__n] == ':' || __str[__n] == '.')
	      __skip_leading_zero = true;
	    else
	      __skip_leading_zero = false;
	    *__out = __str[__n];
	  }
	__n++;
      }
    if (__out == std::end(__buf))
      __ec = std::make_error_code(std::errc::invalid_argument);
    else
      {
	*__out = '\0';
	return __make_address_v6(__buf, __str.c_str() + __pos + 1, __ec);
      }
  }

  inline address_v6
  make_address_v6(const string& __str)
  { return make_address_v6(__str, __throw_on_error{"make_address_v6"}); }

  inline address_v6
  make_address_v6(string_view __str, error_code& __ec) noexcept
  {
    char __buf[64];
    char* __out = __buf;
    char* __scope = nullptr;
    bool __skip_leading_zero = true;
    size_t __n = 0;
    while (__n < __str.length() && __out < std::end(__buf))
      {
	if (__str[__n] == '%')
	  {
	    if (__scope)
	      __out = std::end(__buf);
	    else
	      {
		*__out = '\0';
		__scope = ++__out;
		__skip_leading_zero = true;
	      }
	  }
	else if (!__skip_leading_zero || __str[__n] != '0')
	  {
	    if (__str[__n] == ':' || __str[__n] == '.')
	      __skip_leading_zero = true;
	    else
	      __skip_leading_zero = false;
	    *__out = __str[__n];
	    __out++;
	  }
	__n++;
      }
    if (__out == std::end(__buf))
      __ec = std::make_error_code(std::errc::invalid_argument);
    else
      {
	*__out = '\0';
	return __make_address_v6(__buf, __scope, __ec);
      }
  }

  inline address_v6
  make_address_v6(string_view __str)
  { return make_address_v6(__str, __throw_on_error{"make_address_v6"}); }

  // @}

  /** ip::address creation
   * @{
   */

  inline address
  make_address(const char* __str, error_code& __ec) noexcept
  {
    address __a;
    address_v6 __v6a = make_address_v6(__str, __ec);
    if (!__ec)
      __a = __v6a;
    else
    {
      address_v4 __v4a = make_address_v4(__str, __ec);
      if (!__ec)
	__a = __v4a;
    }
    return __a;
  }

  inline address
  make_address(const char* __str)
  { return make_address(__str, __throw_on_error{"make_address"}); }

  inline address
  make_address(const string& __str, error_code& __ec) noexcept; // TODO

  inline address
  make_address(const string& __str)
  { return make_address(__str, __throw_on_error{"make_address"}); }

  inline address
  make_address(string_view __str, error_code& __ec) noexcept
  {
    if (__str.rfind('\0') != string_view::npos)
      return make_address(__str.data(), __ec);
    return make_address(__str.to_string(), __ec); // TODO don't allocate
  }

  inline address
  make_address(string_view __str)
  { return make_address(__str, __throw_on_error{"make_address"}); }

  // @}

  /// ip::address I/O
  template<typename _CharT, typename _Traits>
    inline basic_ostream<_CharT, _Traits>&
    operator<<(basic_ostream<_CharT, _Traits>& __os, const address& __a)
    { return __os << __a.to_string(); }

  /// ip::address_v4 I/O
  template<typename _CharT, typename _Traits>
    inline basic_ostream<_CharT, _Traits>&
    operator<<(basic_ostream<_CharT, _Traits>& __os, const address_v4& __a)
    { return __os << __a.to_string(); }

  /// ip::address_v6 I/O
  template<typename _CharT, typename _Traits>
    inline basic_ostream<_CharT, _Traits>&
    operator<<(basic_ostream<_CharT, _Traits>& __os, const address_v6& __a)
    { return __os << __a.to_string(); }

  template<typename> class basic_address_iterator; // not defined

  template<> class basic_address_iterator<address_v4>
  {
  public:
    // types:
    typedef address_v4 value_type;
    typedef ptrdiff_t difference_type;
    typedef const address_v4* pointer;
    typedef const address_v4& reference;
    typedef input_iterator_tag iterator_category;

    // constructors:
    basic_address_iterator(const address_v4& __a) noexcept
    : _M_address(__a) { }

    // members:
    reference operator*() const noexcept { return _M_address; }
    pointer operator->() const noexcept { return &_M_address; }

    basic_address_iterator&
    operator++() noexcept
    {
      _M_address = value_type(_M_address.to_uint() + 1);
      return *this;
    }

    basic_address_iterator operator++(int) noexcept
    {
      auto __tmp = *this;
      ++*this;
      return __tmp;
    }

    basic_address_iterator& operator--() noexcept
    {
      _M_address = value_type(_M_address.to_uint() - 1);
      return *this;
    }

    basic_address_iterator
    operator--(int) noexcept
    {
      auto __tmp = *this;
      --*this;
      return __tmp;
    }

    bool
    operator==(const basic_address_iterator& __rhs) const noexcept
    { return _M_address == __rhs._M_address; }

    bool
    operator!=(const basic_address_iterator& __rhs) const noexcept
    { return _M_address != __rhs._M_address; }

  private:
    address_v4 _M_address;
  };

  typedef basic_address_iterator<address_v4> address_v4_iterator;

  template<> class basic_address_iterator<address_v6>
  {
  public:
    // types:
    typedef address_v6 value_type;
    typedef ptrdiff_t difference_type;
    typedef const address_v6* pointer;
    typedef const address_v6& reference;
    typedef input_iterator_tag iterator_category;

    // constructors:
    basic_address_iterator(const address_v6& __a) noexcept
    : _M_address(__a) { }

    // members:
    reference operator*() const noexcept { return _M_address; }
    pointer operator->() const noexcept { return &_M_address; }

    basic_address_iterator&
    operator++() noexcept; // TODO

    basic_address_iterator
    operator++(int) noexcept
    {
      auto __tmp = *this;
      ++*this;
      return __tmp;
    }

    basic_address_iterator&
    operator--() noexcept; // TODO

    basic_address_iterator
    operator--(int) noexcept
    {
      auto __tmp = *this;
      --*this;
      return __tmp;
    }

    bool
    operator==(const basic_address_iterator& __rhs) const noexcept
    { return _M_address == __rhs._M_address; }

    bool
    operator!=(const basic_address_iterator& __rhs) const noexcept
    { return _M_address != __rhs._M_address; }

  private:
    address_v6 _M_address;
  };

  typedef basic_address_iterator<address_v6> address_v6_iterator;

  template<typename> class basic_address_range; // not defined

  /** An IPv6 address range.
   * @{
   */

  template<> class basic_address_range<address_v4>
  {
  public:
    // types:

    typedef basic_address_iterator<address_v4> iterator;

    // constructors:

    basic_address_range() noexcept : _M_begin({}), _M_end({}) { }

    basic_address_range(const address_v4& __first,
                        const address_v4& __last) noexcept
    : _M_begin(__first), _M_end(__last) { }

    // members:

    iterator begin() const noexcept { return _M_begin; }
    iterator end() const noexcept { return _M_end; }
    _GLIBCXX_NODISCARD bool empty() const noexcept { return _M_begin == _M_end; }

    size_t
    size() const noexcept { return _M_end->to_uint() - _M_begin->to_uint(); }

    iterator
    find(const address_v4& __addr) const noexcept
    {
      if (*_M_begin <= __addr && __addr < *_M_end)
	return iterator{__addr};
      return end();
    }

  private:
    iterator _M_begin;
    iterator _M_end;
  };

  typedef basic_address_range<address_v4> address_v4_range;

  // @}

  /** An IPv6 address range.
   * @{
   */

  template<> class basic_address_range<address_v6>
  {
  public:
    // types:

    typedef basic_address_iterator<address_v6> iterator;

    // constructors:

    basic_address_range() noexcept : _M_begin({}), _M_end({}) { }
    basic_address_range(const address_v6& __first,
                        const address_v6& __last) noexcept
    : _M_begin(__first), _M_end(__last) { }

    // members:

    iterator begin() const noexcept { return _M_begin; }
    iterator end() const noexcept { return _M_end; }
    _GLIBCXX_NODISCARD bool empty() const noexcept { return _M_begin == _M_end; }

    iterator
    find(const address_v6& __addr) const noexcept
    {
      if (*_M_begin <= __addr && __addr < *_M_end)
	return iterator{__addr};
      return end();
    }

  private:
    iterator _M_begin;
    iterator _M_end;
  };

  typedef basic_address_range<address_v6> address_v6_range;

  bool
  operator==(const network_v4& __a, const network_v4& __b) noexcept;

  bool
  operator==(const network_v6& __a, const network_v6& __b) noexcept;

  // @}

  /// An IPv4 network address.
  class network_v4
  {
  public:
    // constructors:
    constexpr network_v4() noexcept : _M_addr(), _M_prefix_len(0) { }

    constexpr
    network_v4(const address_v4& __addr, int __prefix_len)
    : _M_addr(__addr), _M_prefix_len(__prefix_len)
    {
      if (_M_prefix_len < 0 || _M_prefix_len > 32)
	__throw_out_of_range("network_v4: invalid prefix length");
    }

    constexpr
    network_v4(const address_v4& __addr, const address_v4& __mask)
    : _M_addr(__addr), _M_prefix_len(__builtin_popcount(__mask.to_uint()))
    {
      if (_M_prefix_len != 0)
	{
	  address_v4::uint_type __mask_uint = __mask.to_uint();
	  if (__builtin_ctz(__mask_uint) != (32 - _M_prefix_len))
	    __throw_invalid_argument("network_v4: invalid mask");
	  if ((__mask_uint & 0x80000000) == 0)
	    __throw_invalid_argument("network_v4: invalid mask");
	}
    }

    // members:

    constexpr address_v4 address() const noexcept { return _M_addr; }
    constexpr int prefix_length() const noexcept { return _M_prefix_len; }

    constexpr address_v4
    netmask() const noexcept
    {
      address_v4::uint_type __val = address_v4::broadcast().to_uint();
      __val >>= (32 - _M_prefix_len);
      __val <<= (32 - _M_prefix_len);
      return address_v4{__val};
    }

    constexpr address_v4
    network() const noexcept
    { return address_v4{_M_addr.to_uint() & netmask().to_uint()}; }

    constexpr address_v4
    broadcast() const noexcept
    { return address_v4{_M_addr.to_uint() | ~netmask().to_uint()}; }

    address_v4_range
    hosts() const noexcept
    {
      if (is_host())
	return { address(), *++address_v4_iterator(address()) };
      return { network(), broadcast() };
    }

    constexpr network_v4
    canonical() const noexcept
    { return network_v4(network(), prefix_length()); }

    constexpr bool is_host() const noexcept { return _M_prefix_len == 32; }

    constexpr bool
    is_subnet_of(const network_v4& __other) const noexcept
    {
      if (__other.prefix_length() < prefix_length())
	{
	  network_v4 __net(address(), __other.prefix_length());
	  return __net.canonical() == __other.canonical();
	}
      return false;
    }

    template<typename _Allocator = allocator<char>>
      __string_with<_Allocator>
      to_string(const _Allocator& __a = _Allocator()) const
      {
	return address().to_string(__a) + '/'
	  + std::to_string(prefix_length());
      }

  private:
    address_v4 _M_addr;
    int _M_prefix_len;
  };

  /// An IPv6 network address.
  class network_v6
  {
  public:
    // constructors:
    constexpr network_v6() noexcept : _M_addr(), _M_prefix_len(0) { }

    constexpr
    network_v6(const address_v6& __addr, int __prefix_len)
    : _M_addr(__addr), _M_prefix_len(__prefix_len)
    {
      if (_M_prefix_len < 0 || _M_prefix_len > 128)
	__throw_out_of_range("network_v6: invalid prefix length");
    }

    // members:
    constexpr address_v6 address() const noexcept { return _M_addr; }
    constexpr int prefix_length() const noexcept { return _M_prefix_len; }

    constexpr address_v6 network() const noexcept; // TODO

    address_v6_range
    hosts() const noexcept
    {
      if (is_host())
	return { address(), *++address_v6_iterator(address()) };
      return {}; // { network(), XXX broadcast() XXX }; // TODO
    }

    constexpr network_v6
    canonical() const noexcept
    { return network_v6{network(), prefix_length()}; }

    constexpr bool is_host() const noexcept { return _M_prefix_len == 128; }

    constexpr bool
    is_subnet_of(const network_v6& __other) const noexcept
    {
      if (__other.prefix_length() < prefix_length())
	{
	  network_v6 __net(address(), __other.prefix_length());
	  return __net.canonical() == __other.canonical();
	}
      return false;
    }

    template<typename _Allocator = allocator<char>>
      __string_with<_Allocator>
      to_string(const _Allocator& __a = _Allocator()) const
      {
	return address().to_string(__a) + '/'
	  + std::to_string(prefix_length());
      }

  private:
    address_v6 _M_addr;
    int _M_prefix_len;
  };


  /** ip::network_v4 comparisons
   * @{
   */

  inline bool
  operator==(const network_v4& __a, const network_v4& __b) noexcept
  {
    return __a.address() == __b.address()
      && __a.prefix_length() == __b.prefix_length();
  }

  inline bool
  operator!=(const network_v4& __a, const network_v4& __b) noexcept
  { return !(__a == __b); }

  // @}

  /** ip::network_v6 comparisons
   * @{
   */

  inline bool
  operator==(const network_v6& __a, const network_v6& __b) noexcept
  {
    return __a.address() == __b.address()
      && __a.prefix_length() == __b.prefix_length();
  }

  inline bool
  operator!=(const network_v6& __a, const network_v6& __b) noexcept
  { return !(__a == __b); }

  // @}

  /** ip::network_v4 creation
   * @{
   */

  inline network_v4
  make_network_v4(const address_v4& __a, int __prefix_len)
  { return network_v4{__a, __prefix_len}; }

  network_v4
  make_network_v4(const address_v4& __a, const address_v4& __mask)
  { return network_v4{ __a, __mask }; }

  network_v4 make_network_v4(const char*, error_code&) noexcept; // TODO

  inline network_v4
  make_network_v4(const char* __str)
  { return make_network_v4(__str, __throw_on_error{"make_network_v4"}); }

  network_v4 make_network_v4(const string&, error_code&) noexcept; // TODO

  inline network_v4
  make_network_v4(const string& __str)
  { return make_network_v4(__str, __throw_on_error{"make_network_v4"}); }

  network_v4 make_network_v4(string_view, error_code&) noexcept; // TODO

  inline network_v4
  make_network_v4(string_view __str)
  { return make_network_v4(__str, __throw_on_error{"make_network_v4"}); }

  // @}

  /** ip::network_v6 creation
   * @{
   */

  inline network_v6
  make_network_v6(const address_v6& __a, int __prefix_len)
  { return network_v6{__a, __prefix_len}; }

  network_v6 make_network_v6(const char*, error_code&) noexcept; // TODO

  inline network_v6
  make_network_v6(const char* __str)
  { return make_network_v6(__str, __throw_on_error{"make_network_v6"}); }

  network_v6 make_network_v6(const string&, error_code&) noexcept; // TODO

  inline network_v6
  make_network_v6(const string& __str)
  { return make_network_v6(__str, __throw_on_error{"make_network_v6"}); }

  network_v6 make_network_v6(string_view, error_code&) noexcept; // TODO

  inline network_v6
  make_network_v6(string_view __str)
  { return make_network_v6(__str, __throw_on_error{"make_network_v6"}); }

  // @}

  /// ip::network_v4 I/O
  template<typename _CharT, typename _Traits>
    inline basic_ostream<_CharT, _Traits>&
    operator<<(basic_ostream<_CharT, _Traits>& __os, const network_v4& __net)
    { return __os << __net.to_string(); }

  /// ip::network_v6 I/O
  template<typename _CharT, typename _Traits>
    inline basic_ostream<_CharT, _Traits>&
    operator<<(basic_ostream<_CharT, _Traits>& __os, const network_v6& __net)
    { return __os << __net.to_string(); }

  /// An IP endpoint.
  template<typename _InternetProtocol>
    class basic_endpoint
    {
    public:
      // types:
      typedef _InternetProtocol protocol_type;

      // constructors:

      constexpr
      basic_endpoint() noexcept : _M_data()
      { _M_data._M_v4.sin_family = protocol_type::v4().family(); }

      constexpr
      basic_endpoint(const protocol_type& __proto,
		     port_type __port_num) noexcept
      : _M_data()
      {
	__glibcxx_assert(__proto == protocol_type::v4()
			  || __proto == protocol_type::v6());

	_M_data._M_v4.sin_family = __proto.family();
	_M_data._M_v4.sin_port = address_v4::_S_hton_16(__port_num);
      }

      constexpr
      basic_endpoint(const ip::address& __addr,
		     port_type __port_num) noexcept
      : _M_data()
      {
	if (__addr.is_v4())
	  {
	    _M_data._M_v4.sin_family = protocol_type::v4().family();
	    _M_data._M_v4.sin_port = address_v4::_S_hton_16(__port_num);
	    _M_data._M_v4.sin_addr.s_addr = __addr._M_v4._M_addr;
	  }
	else
	  {
	    _M_data._M_v6 = {};
	    _M_data._M_v6.sin6_family = protocol_type::v6().family();
	    _M_data._M_v6.sin6_port = address_v4::_S_hton_16(__port_num);
	    __builtin_memcpy(_M_data._M_v6.sin6_addr.s6_addr,
			     __addr._M_v6._M_bytes.data(), 16);
	    _M_data._M_v6.sin6_scope_id = __addr._M_v6._M_scope_id;
	  }
      }

      // members:
      constexpr protocol_type protocol() const noexcept
      {
	return _M_data._M_v4.sin_family == AF_INET6
	  ? protocol_type::v6() : protocol_type::v4();
      }

      constexpr ip::address
      address() const noexcept
      {
	ip::address __addr;
	if (protocol().family() == AF_INET6)
	  {
	    __builtin_memcpy(&__addr._M_v6._M_bytes,
			     _M_data._M_v6.sin6_addr.s6_addr, 16);
	    __addr._M_is_v4 = false;
	  }
	else
	  {
	    __builtin_memcpy(&__addr._M_v4._M_addr,
			     &_M_data._M_v4.sin_addr.s_addr, 4);
	  }
	return __addr;
      }

      void
      address(const ip::address& __addr) noexcept
      {
	if (__addr.is_v6())
	  {
	    _M_data._M_v6 = {};
	    _M_data._M_v6.sin6_family = protocol_type::v6().family();
	    __builtin_memcpy(_M_data._M_v6.sin6_addr.s6_addr,
			     __addr._M_v6._M_bytes.data(), 16);
	    _M_data._M_v6.sin6_scope_id = __addr._M_v6._M_scope_id;
	  }
	else
	  {
	    _M_data._M_v4.sin_family = protocol_type::v4().family();
	    _M_data._M_v4.sin_addr.s_addr = __addr._M_v4._M_addr;
	  }
      }

      constexpr port_type
      port() const noexcept
      { return address_v4::_S_ntoh_16(_M_data._M_v4.sin_port); }

      void
      port(port_type __port_num) noexcept
      { _M_data._M_v4.sin_port = address_v4::_S_hton_16(__port_num); }

      void* data() noexcept { return &_M_data; }
      const void* data() const noexcept { return &_M_data; }
      constexpr size_t size() const noexcept
      {
	return protocol().family() == AF_INET6
	  ? sizeof(sockaddr_in6) : sizeof(sockaddr_in);
      }

      void
      resize(size_t __s)
      {
	if ((protocol().family() == AF_INET6 && __s != sizeof(sockaddr_in6))
	    || (protocol().family() == AF_INET && __s != sizeof(sockaddr_in)))
	  __throw_length_error("net::ip::basic_endpoint::resize");
      }

      constexpr size_t capacity() const noexcept { return sizeof(_M_data); }

    private:
      union
      {
	sockaddr_in	_M_v4;
	sockaddr_in6	_M_v6;
      } _M_data;
    };

  /** basic_endpoint comparisons
   * @{
   */

  template<typename _InternetProtocol>
    inline bool
    operator==(const basic_endpoint<_InternetProtocol>& __a,
	       const basic_endpoint<_InternetProtocol>& __b)
    { return __a.address() == __b.address() && __a.port() == __b.port(); }

  template<typename _InternetProtocol>
    inline bool
    operator!=(const basic_endpoint<_InternetProtocol>& __a,
	       const basic_endpoint<_InternetProtocol>& __b)
    { return !(__a == __b); }

  template<typename _InternetProtocol>
    inline bool
    operator< (const basic_endpoint<_InternetProtocol>& __a,
	       const basic_endpoint<_InternetProtocol>& __b)
    {
      return __a.address() < __b.address()
	|| (!(__b.address() < __a.address()) && __a.port() < __b.port());
    }

  template<typename _InternetProtocol>
    inline bool
    operator> (const basic_endpoint<_InternetProtocol>& __a,
	       const basic_endpoint<_InternetProtocol>& __b)
    { return __b < __a; }

  template<typename _InternetProtocol>
    inline bool
    operator<=(const basic_endpoint<_InternetProtocol>& __a,
	       const basic_endpoint<_InternetProtocol>& __b)
    { return !(__b < __a); }

  template<typename _InternetProtocol>
    inline bool
    operator>=(const basic_endpoint<_InternetProtocol>& __a,
	       const basic_endpoint<_InternetProtocol>& __b)
    { return !(__a < __b); }

  // @}

  /// basic_endpoint I/O
  template<typename _CharT, typename _Traits, typename _InternetProtocol>
    inline basic_ostream<_CharT, _Traits>&
    operator<<(basic_ostream<_CharT, _Traits>& __os,
	       const basic_endpoint<_InternetProtocol>& __ep)
    {
      basic_ostringstream<_CharT, _Traits> __ss;
      if (__ep.protocol()
	  == basic_endpoint<_InternetProtocol>::protocol_type::v6())
	__ss << '[' << __ep.address() << ']';
      else
	__ss << __ep.address();
      __ss << ':' << __ep.port();
      __os << __ss.str();
      return __os;
    }

  /** Type representing a single result of name/address resolution.
   * @{
   */

  template<typename _InternetProtocol>
    class basic_resolver_entry
    {
    public:
      // types:
      typedef _InternetProtocol protocol_type;
      typedef typename _InternetProtocol::endpoint endpoint_type;

      // constructors:
      basic_resolver_entry() { }

      basic_resolver_entry(const endpoint_type& __ep,
			   string_view __h, string_view __s)
      : _M_ep(__ep), _M_host(__h), _M_svc(__s) { }

      // members:
      endpoint_type endpoint() const { return _M_ep; }
      operator endpoint_type() const { return _M_ep; }

      template<typename _Allocator = allocator<char>>
	__string_with<_Allocator>
	host_name(const _Allocator& __a = _Allocator()) const
	{ return { _M_host, __a }; }

      template<typename _Allocator = allocator<char>>
	__string_with<_Allocator>
	service_name(const _Allocator& __a = _Allocator()) const
	{ return { _M_svc, __a }; }

    private:
      basic_endpoint<_InternetProtocol> _M_ep;
      string _M_host;
      string _M_svc;
    };

  template<typename _InternetProtocol>
    inline bool
    operator==(const basic_resolver_entry<_InternetProtocol>& __a,
	       const basic_resolver_entry<_InternetProtocol>& __b)
    {
      return __a.endpoint() == __b.endpoint()
	&& __a.host_name() == __b.host_name()
	&& __a.service_name() == __b.service_name();
    }

  template<typename _InternetProtocol>
    inline bool
    operator!=(const basic_resolver_entry<_InternetProtocol>& __a,
	       const basic_resolver_entry<_InternetProtocol>& __b)
    { return !(__a == __b); }

  // @}

  /** Base class defining flags for name/address resolution.
   * @{
   */

  class resolver_base
  {
  public:
    enum flags : int
    {
      __flags_passive			= AI_PASSIVE,
      __flags_canonical_name		= AI_CANONNAME,
      __flags_numeric_host		= AI_NUMERICHOST,
#ifdef AI_NUMERICSERV
      __flags_numeric_service		= AI_NUMERICSERV,
#endif
      __flags_v4_mapped			= AI_V4MAPPED,
      __flags_all_matching		= AI_ALL,
      __flags_address_configured	= AI_ADDRCONFIG
    };
    static constexpr flags passive		= __flags_passive;
    static constexpr flags canonical_name	= __flags_canonical_name;
    static constexpr flags numeric_host		= __flags_numeric_host;
#ifdef AI_NUMERICSERV
    static constexpr flags numeric_service	= __flags_numeric_service;
#endif
    static constexpr flags v4_mapped		= __flags_v4_mapped;
    static constexpr flags all_matching		= __flags_all_matching;
    static constexpr flags address_configured	= __flags_address_configured;

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

  constexpr resolver_base::flags
  operator&(resolver_base::flags __f1, resolver_base::flags __f2)
  { return resolver_base::flags( int(__f1) & int(__f2) ); }

  constexpr resolver_base::flags
  operator|(resolver_base::flags __f1, resolver_base::flags __f2)
  { return resolver_base::flags( int(__f1) | int(__f2) ); }

  constexpr resolver_base::flags
  operator^(resolver_base::flags __f1, resolver_base::flags __f2)
  { return resolver_base::flags( int(__f1) ^ int(__f2) ); }

  constexpr resolver_base::flags
  operator~(resolver_base::flags __f)
  { return resolver_base::flags( ~int(__f) ); }

  inline resolver_base::flags&
  operator&=(resolver_base::flags& __f1, resolver_base::flags __f2)
  { return __f1 = (__f1 & __f2); }

  inline resolver_base::flags&
  operator|=(resolver_base::flags& __f1, resolver_base::flags __f2)
  { return __f1 = (__f1 | __f2); }

  inline resolver_base::flags&
  operator^=(resolver_base::flags& __f1, resolver_base::flags __f2)
  { return __f1 = (__f1 ^ __f2); }

  // TODO define resolver_base::flags static constants for C++14 mode

  // @}

  /** Container for results of name/address resolution.
   * @{
   */

  template<typename _InternetProtocol>
    class basic_resolver_results
    {
    public:
      // types:
      typedef _InternetProtocol protocol_type;
      typedef typename protocol_type::endpoint endpoint_type;
      typedef basic_resolver_entry<protocol_type> value_type;
      typedef const value_type& const_reference;
      typedef value_type& reference;
      typedef typename forward_list<value_type>::const_iterator const_iterator;
      typedef const_iterator iterator;
      typedef ptrdiff_t difference_type;
      typedef size_t size_type;

      // construct / copy / destroy:

      basic_resolver_results() = default;

      basic_resolver_results(const basic_resolver_results&) = default;

      basic_resolver_results(basic_resolver_results&&) noexcept = default;

      basic_resolver_results&
      operator=(const basic_resolver_results&) = default;

      basic_resolver_results&
      operator=(basic_resolver_results&&) = default;

      ~basic_resolver_results() = default;

      // size:
      size_type size() const noexcept { return _M_size; }
      size_type max_size() const noexcept { return _M_results.max_size(); }
      _GLIBCXX_NODISCARD bool empty() const noexcept { return _M_results.empty(); }

      // element access:
      const_iterator begin() const { return _M_results.begin(); }
      const_iterator end() const { return _M_results.end(); }
      const_iterator cbegin() const { return _M_results.begin(); }
      const_iterator cend() const { return _M_results.end(); }

      // swap:
      void
      swap(basic_resolver_results& __that) noexcept
      { _M_results.swap(__that._M_results); }

    private:
      friend class basic_resolver<protocol_type>;

      basic_resolver_results(string_view, string_view, resolver_base::flags,
			     error_code&, protocol_type* = nullptr);

      basic_resolver_results(const endpoint_type&, error_code&);

      forward_list<value_type> _M_results;
      size_t _M_size = 0;
    };

  template<typename _InternetProtocol>
    inline bool
    operator==(const basic_resolver_results<_InternetProtocol>& __a,
	       const basic_resolver_results<_InternetProtocol>& __b)
    {
      return __a.size() == __b.size()
	&& std::equal(__a.begin(), __a.end(), __b.begin());
    }

  template<typename _InternetProtocol>
    inline bool
    operator!=(const basic_resolver_results<_InternetProtocol>& __a,
	       const basic_resolver_results<_InternetProtocol>& __b)
    { return !(__a == __b); }

  // @}

  /// Perform name/address resolution.
  template<typename _InternetProtocol>
    class basic_resolver : public resolver_base
    {
    public:
      // types:

      typedef io_context::executor_type executor_type;
      typedef _InternetProtocol protocol_type;
      typedef typename _InternetProtocol::endpoint endpoint_type;
      typedef basic_resolver_results<_InternetProtocol> results_type;

      // construct / copy / destroy:

      explicit basic_resolver(io_context& __ctx) : _M_ctx(&__ctx) { }

      basic_resolver(const basic_resolver&) = delete;

      basic_resolver(basic_resolver&& __rhs) noexcept
      : _M_ctx(__rhs._M_ctx)
      { } // TODO move state/tasks etc.

      ~basic_resolver() { cancel(); }

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

      basic_resolver& operator=(basic_resolver&& __rhs)
      {
	cancel();
	_M_ctx = __rhs._M_ctx;
	// TODO move state/tasks etc.
	return *this;
      }

      // basic_resolver operations:

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

      void cancel() { } // TODO

      results_type
      resolve(string_view __host_name, string_view __service_name)
      {
	return resolve(__host_name, __service_name, resolver_base::flags(),
		       __throw_on_error{"basic_resolver::resolve"});
      }

      results_type
      resolve(string_view __host_name, string_view __service_name,
	      error_code& __ec)
      {
	return resolve(__host_name, __service_name, resolver_base::flags(),
		       __ec);
      }

      results_type
      resolve(string_view __host_name, string_view __service_name, flags __f)
      {
	return resolve(__host_name, __service_name, __f,
		       __throw_on_error{"basic_resolver::resolve"});
      }

      results_type
      resolve(string_view __host_name, string_view __service_name, flags __f,
	      error_code& __ec)
      { return {__host_name, __service_name, __f, __ec}; }

      template<typename _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, results_type)>
	async_resolve(string_view __host_name, string_view __service_name,
		      _CompletionToken&& __token)
	{
	  return async_resolve(__host_name, __service_name,
			       resolver_base::flags(),
			       forward<_CompletionToken>(__token));
	}

      template<typename _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, results_type)>
	async_resolve(string_view __host_name, string_view __service_name,
		      flags __f, _CompletionToken&& __token); // TODO

      results_type
      resolve(const protocol_type& __protocol,
	      string_view __host_name, string_view __service_name)
      {
	return resolve(__protocol, __host_name, __service_name,
		       resolver_base::flags(),
		       __throw_on_error{"basic_resolver::resolve"});
      }

      results_type
      resolve(const protocol_type& __protocol,
	      string_view __host_name, string_view __service_name,
	      error_code& __ec)
      {
	return resolve(__protocol, __host_name, __service_name,
		       resolver_base::flags(), __ec);
      }

      results_type
      resolve(const protocol_type& __protocol,
	      string_view __host_name, string_view __service_name, flags __f)
      {
	return resolve(__protocol, __host_name, __service_name, __f,
		       __throw_on_error{"basic_resolver::resolve"});
      }

      results_type
      resolve(const protocol_type& __protocol,
	      string_view __host_name, string_view __service_name,
	      flags __f, error_code& __ec)
      { return {__host_name, __service_name, __f, __ec, &__protocol}; }

      template<typename _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, results_type)>
	async_resolve(const protocol_type& __protocol,
		      string_view __host_name, string_view __service_name,
		      _CompletionToken&& __token)
	{
	  return async_resolve(__protocol, __host_name, __service_name,
			       resolver_base::flags(),
			       forward<_CompletionToken>(__token));
	}

      template<typename _CompletionToken>
	__deduced_t<_CompletionToken, void(error_code, results_type)>
	async_resolve(const protocol_type& __protocol,
		      string_view __host_name, string_view __service_name,
		      flags __f, _CompletionToken&& __token); // TODO

      results_type
      resolve(const endpoint_type& __ep)
      { return resolve(__ep, __throw_on_error{"basic_resolver::resolve"}); }

      results_type
      resolve(const endpoint_type& __ep, error_code& __ec)
      { return { __ep, __ec }; }

      template<typename _CompletionToken> // TODO
	__deduced_t<_CompletionToken, void(error_code, results_type)>
	async_resolve(const endpoint_type& __ep, _CompletionToken&& __token);

    private:
      io_context* _M_ctx;
    };

  /// Private constructor to synchronously resolve host and service names.
  template<typename _InternetProtocol>
    basic_resolver_results<_InternetProtocol>::
    basic_resolver_results(string_view __host_name, string_view __service_name,
			   resolver_base::flags __f, error_code& __ec,
			   protocol_type* __protocol)
    {
#ifdef _GLIBCXX_HAVE_NETDB_H
      string __host;
      const char* __h = __host_name.data()
	? (__host = __host_name.to_string()).c_str()
	: nullptr;
      string __svc;
      const char* __s = __service_name.data()
	? (__svc = __service_name.to_string()).c_str()
	: nullptr;

      ::addrinfo __hints{ };
      __hints.ai_flags = static_cast<int>(__f);
      if (__protocol)
	{
	  __hints.ai_family = __protocol->family();
	  __hints.ai_socktype = __protocol->type();
	  __hints.ai_protocol = __protocol->protocol();
	}
      else
	{
	  auto __p = endpoint_type{}.protocol();
	  __hints.ai_family = AF_UNSPEC;
	  __hints.ai_socktype = __p.type();
	  __hints.ai_protocol = __p.protocol();
	}

      struct __scoped_addrinfo
      {
	~__scoped_addrinfo() { if (_M_p) ::freeaddrinfo(_M_p); }
	::addrinfo* _M_p = nullptr;
      } __sai;

      if (int __err = ::getaddrinfo(__h, __s, &__hints, &__sai._M_p))
	{
	  __ec.assign(__err, resolver_category());
	  return;
	}
      __ec.clear();

      endpoint_type __ep;
      auto __tail = _M_results.before_begin();
      for (auto __ai = __sai._M_p; __ai != nullptr; __ai = __ai->ai_next)
	{
	  if (__ai->ai_family == AF_INET || __ai->ai_family == AF_INET6)
	    {
	      if (__ai->ai_addrlen <= __ep.capacity())
		__builtin_memcpy(__ep.data(), __ai->ai_addr, __ai->ai_addrlen);
	      __ep.resize(__ai->ai_addrlen);
	      __tail = _M_results.emplace_after(__tail, __ep, __host, __svc);
	      _M_size++;
	    }
	}
#else
      __ec = std::make_error_code(errc::operation_not_supported);
#endif
    }

  /// Private constructor to synchronously resolve an endpoint.
  template<typename _InternetProtocol>
    basic_resolver_results<_InternetProtocol>::
    basic_resolver_results(const endpoint_type& __ep, error_code& __ec)
    {
#ifdef _GLIBCXX_HAVE_NETDB_H
      char __host_name[256];
      char __service_name[128];
      int __flags = 0;
      if (__ep.protocol().type() == SOCK_DGRAM)
	__flags |= NI_DGRAM;
      auto __sa = static_cast<const sockaddr*>(__ep.data());
      int __err = ::getnameinfo(__sa, __ep.size(),
				__host_name, sizeof(__host_name),
				__service_name, sizeof(__service_name),
				__flags);
      if (__err)
	{
	  __flags |= NI_NUMERICSERV;
	  __err = ::getnameinfo(__sa, __ep.size(),
				__host_name, sizeof(__host_name),
				__service_name, sizeof(__service_name),
				__flags);
	}
      if (__err)
	__ec.assign(__err, resolver_category());
      else
	{
	  __ec.clear();
	  _M_results.emplace_front(__ep, __host_name, __service_name);
	  _M_size = 1;
	}
#else
      __ec = std::make_error_code(errc::operation_not_supported);
#endif
    }

  /** The name of the local host.
   * @{
   */

  template<typename _Allocator>
    __string_with<_Allocator>
    host_name(const _Allocator& __a, error_code& __ec)
    {
#ifdef HOST_NAME_MAX
      constexpr size_t __maxlen = HOST_NAME_MAX;
#else
      constexpr size_t __maxlen = 256;
#endif
      char __buf[__maxlen + 1];
      if (::gethostname(__buf, __maxlen) == -1)
	__ec.assign(errno, generic_category());
      __buf[__maxlen] = '\0';
      return { __buf, __a };
    }

  template<typename _Allocator>
    inline __string_with<_Allocator>
    host_name(const _Allocator& __a)
    { return host_name(__a, __throw_on_error{"host_name"}); }

  inline string
  host_name(error_code& __ec)
  { return host_name(std::allocator<char>{}, __ec); }

  inline string
  host_name()
  { return host_name(std::allocator<char>{}, __throw_on_error{"host_name"}); }

  // @}

  /// The TCP byte-stream protocol.
  class tcp
  {
  public:
    // types:
    typedef basic_endpoint<tcp> endpoint;	 ///< A TCP endpoint.
    typedef basic_resolver<tcp> resolver;	 ///< A TCP resolver.
    typedef basic_stream_socket<tcp> socket;	 ///< A TCP socket.
    typedef basic_socket_acceptor<tcp> acceptor; ///< A TCP acceptor.
    typedef basic_socket_iostream<tcp> iostream; /// A TCP iostream.

#ifdef _GLIBCXX_HAVE_NETINET_TCP_H
    /// Disable coalescing of small segments (i.e. the Nagle algorithm).
    struct no_delay : __sockopt_crtp<no_delay, bool>
    {
      using __sockopt_crtp::__sockopt_crtp;

      static const int _S_level = IPPROTO_TCP;
      static const int _S_name = TCP_NODELAY;
    };
#endif

    // static members:

    /// A protocol object representing IPv4 TCP.
    static constexpr tcp v4() noexcept { return tcp(AF_INET); }
    /// A protocol object representing IPv6 TCP.
    static constexpr tcp v6() noexcept { return tcp(AF_INET6); }

    tcp() = delete;

    constexpr int family() const noexcept { return _M_family; }
    constexpr int type() const noexcept { return SOCK_STREAM; }
    constexpr int protocol() const noexcept { return IPPROTO_TCP; }

  private:
    constexpr explicit tcp(int __family) : _M_family(__family) { }

    int _M_family;
  };

  /** tcp comparisons
   * @{
   */

  inline bool
  operator==(const tcp& __a, const tcp& __b)
  { return __a.family() == __b.family(); }

  inline bool
  operator!=(const tcp& __a, const tcp& __b)
  { return !(__a == __b); }

  // @}

  /// The UDP datagram protocol.
  class udp
  {
  public:
    // types:
    typedef basic_endpoint<udp> endpoint;
    typedef basic_resolver<udp> resolver;
    typedef basic_datagram_socket<udp> socket;

    // static members:
    static constexpr udp v4() noexcept { return udp(AF_INET); }
    static constexpr udp v6() noexcept { return udp(AF_INET6); }

    udp() = delete;

    constexpr int family() const noexcept { return _M_family; }
    constexpr int type() const noexcept { return SOCK_DGRAM; }
    constexpr int protocol() const noexcept { return IPPROTO_UDP; }

  private:
    constexpr explicit udp(int __family) : _M_family(__family) { }

    int _M_family;
  };

  /** udp comparisons
   * @{
   */

  bool
  operator==(const udp& __a, const udp& __b)
  { return __a.family() == __b.family(); }

  inline bool
  operator!=(const udp& __a, const udp& __b)
  { return !(__a == __b); }

  // @}

  /// Restrict a socket created for an IPv6 protocol to IPv6 only.
  struct v6_only : __sockopt_crtp<v6_only, bool>
  {
    using __sockopt_crtp::__sockopt_crtp;

    static const int _S_level = IPPROTO_IPV6;
    static const int _S_name = IPV6_V6ONLY;
  };

  namespace unicast
  {
    /// Set the default number of hops (TTL) for outbound datagrams.
    struct hops : __sockopt_crtp<hops>
    {
      using __sockopt_crtp::__sockopt_crtp;

      template<typename _Protocol>
	int
	level(const _Protocol& __p) const noexcept
	{ return __p.family() == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP; }

      template<typename _Protocol>
	int
	name(const _Protocol& __p) const noexcept
	{ return __p.family() == AF_INET6 ? IPV6_UNICAST_HOPS : IP_TTL; }
    };
  } // namespace unicast

  namespace multicast
  {
    /// Request that a socket joins a multicast group.
    struct join_group
    {
      explicit
      join_group(const address&);

      explicit
      join_group(const address_v4&, const address_v4& = address_v4::any());

      explicit
      join_group(const address_v6&, unsigned int = 0);

      template<typename _Protocol>
	int
	level(const _Protocol& __p) const noexcept
	{ return __p.family() == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP; }

      template<typename _Protocol>
	int
	name(const _Protocol& __p) const noexcept
	{
	  return __p.family() == AF_INET6
	    ? IPV6_JOIN_GROUP : IP_ADD_MEMBERSHIP;
	}
      template<typename _Protocol>
	void*
	data(const _Protocol&) noexcept
	{ return std::addressof(_M_value); }

      template<typename _Protocol>
	const void*
	data(const _Protocol&) const noexcept
	{ return std::addressof(_M_value); }

      template<typename _Protocol>
	size_t
	size(const _Protocol& __p) const noexcept
	{
	  return __p.family() == AF_INET6
	    ? sizeof(_M_value._M_v6) : sizeof(_M_value._M_v4);
	}

      template<typename _Protocol>
	void
	resize(const _Protocol& __p, size_t __s)
	{
	  if (__s != size(__p))
	    __throw_length_error("invalid value for socket option resize");
	}

    protected:
      union
      {
	ipv6_mreq _M_v6;
	ip_mreq _M_v4;
      } _M_value;
    };

    /// Request that a socket leaves a multicast group.
    struct leave_group
    {
      explicit
      leave_group(const address&);

      explicit
      leave_group(const address_v4&, const address_v4& = address_v4::any());

      explicit
      leave_group(const address_v6&, unsigned int = 0);

      template<typename _Protocol>
	int
	level(const _Protocol& __p) const noexcept
	{ return __p.family() == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP; }

      template<typename _Protocol>
	int
	name(const _Protocol& __p) const noexcept
	{
	  return __p.family() == AF_INET6
	    ? IPV6_LEAVE_GROUP : IP_DROP_MEMBERSHIP;
	}
      template<typename _Protocol>
	void*
	data(const _Protocol&) noexcept
	{ return std::addressof(_M_value); }

      template<typename _Protocol>
	const void*
	data(const _Protocol&) const noexcept
	{ return std::addressof(_M_value); }

      template<typename _Protocol>
	size_t
	size(const _Protocol& __p) const noexcept
	{
	  return __p.family() == AF_INET6
	    ? sizeof(_M_value._M_v6) : sizeof(_M_value._M_v4);
	}

      template<typename _Protocol>
	void
	resize(const _Protocol& __p, size_t __s)
	{
	  if (__s != size(__p))
	    __throw_length_error("invalid value for socket option resize");
	}

    protected:
      union
      {
	ipv6_mreq _M_v6;
	ip_mreq _M_v4;
      } _M_value;
    };

    /// Specify the network interface for outgoing multicast datagrams.
    class outbound_interface
    {
      explicit
      outbound_interface(const address_v4&);

      explicit
      outbound_interface(unsigned int);

      template<typename _Protocol>
	int
	level(const _Protocol& __p) const noexcept
	{ return __p.family() == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP; }

      template<typename _Protocol>
	int
	name(const _Protocol& __p) const noexcept
	{
	  return __p.family() == AF_INET6
	    ? IPV6_MULTICAST_IF : IP_MULTICAST_IF;
	}

      template<typename _Protocol>
	const void*
	data(const _Protocol&) const noexcept
	{ return std::addressof(_M_value); }

      template<typename _Protocol>
	size_t
	size(const _Protocol& __p) const noexcept
	{
	  return __p.family() == AF_INET6
	    ? sizeof(_M_value._M_v6) : sizeof(_M_value._M_v4);
	}

    protected:
      union {
	unsigned _M_v6;
	in_addr _M_v4;
      } _M_value;
    };

    /// Set the default number of hops (TTL) for outbound datagrams.
    struct hops : __sockopt_crtp<hops>
    {
      using __sockopt_crtp::__sockopt_crtp;

      template<typename _Protocol>
	int
	level(const _Protocol& __p) const noexcept
	{ return __p.family() == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP; }

      template<typename _Protocol>
	int
	name(const _Protocol& __p) const noexcept
	{
	  return __p.family() == AF_INET6
	    ? IPV6_MULTICAST_HOPS : IP_MULTICAST_TTL;
	}
    };

    /// Set whether datagrams are delivered back to the local application.
    struct enable_loopback : __sockopt_crtp<enable_loopback>
    {
      using __sockopt_crtp::__sockopt_crtp;

      template<typename _Protocol>
	int
	level(const _Protocol& __p) const noexcept
	{ return __p.family() == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP; }

      template<typename _Protocol>
	int
	name(const _Protocol& __p) const noexcept
	{
	  return __p.family() == AF_INET6
	    ? IPV6_MULTICAST_LOOP : IP_MULTICAST_LOOP;
	}
    };

  } // namespace multicast

  // @}

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

  template<>
    struct is_error_condition_enum<experimental::net::v1::ip::resolver_errc>
    : public true_type {};

  // hash support
  template<typename _Tp> struct hash;
  template<>
    struct hash<experimental::net::v1::ip::address>
    : __hash_base<size_t, experimental::net::v1::ip::address>
    {
      size_t
      operator()(const argument_type& __a) const
      {
	if (__a.is_v4())
	  return _Hash_impl::hash(__a.to_v4());
	else
	  return _Hash_impl::hash(__a.to_v6());
      }
    };

  template<>
    struct hash<experimental::net::v1::ip::address_v4>
    : __hash_base<size_t, experimental::net::v1::ip::address_v4>
    {
      size_t
      operator()(const argument_type& __a) const
      { return _Hash_impl::hash(__a.to_bytes()); }
    };

  template<> struct hash<experimental::net::v1::ip::address_v6>
    : __hash_base<size_t, experimental::net::v1::ip::address_v6>
    {
      size_t
      operator()(const argument_type& __a) const
      { return _Hash_impl::hash(__a.to_bytes()); }
    };

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // C++14

#endif // _GLIBCXX_EXPERIMENTAL_INTERNET
