namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  enum class resolver_errc {
    host_not_found = an implementation-defined non-zero value,   // EAI_NONAME
    try_again = an implementation-defined non-zero value,        // EAI_AGAIN
    service_not_found = an implementation-defined non-zero value // EAI_SERVICE
  };
  const error_category& resolver_category() noexcept;
  error_code make_error_code(resolver_errc e) noexcept;
  error_condition make_error_condition(resolver_errc e) noexcept;
  using port_type = uint_least16_t;
  using scope_id_type = uint_least32_t;
  struct v4_mapped_t {};
  constexpr v4_mapped_t v4_mapped;
  class address;
  class address_v4;
  class address_v6;
  class bad_address_cast;
  // [internet.address.comparisons], address comparisons:
  constexpr bool operator==(const address&, const address&) noexcept;
  constexpr bool operator!=(const address&, const address&) noexcept;
  constexpr bool operator< (const address&, const address&) noexcept;
  constexpr bool operator> (const address&, const address&) noexcept;
  constexpr bool operator<=(const address&, const address&) noexcept;
  constexpr bool operator>=(const address&, const address&) noexcept;
  // [internet.address.v4.comparisons], address_v4 comparisons:
  constexpr bool operator==(const address_v4&, const address_v4&) noexcept;
  constexpr bool operator!=(const address_v4&, const address_v4&) noexcept;
  constexpr bool operator< (const address_v4&, const address_v4&) noexcept;
  constexpr bool operator> (const address_v4&, const address_v4&) noexcept;
  constexpr bool operator<=(const address_v4&, const address_v4&) noexcept;
  constexpr bool operator>=(const address_v4&, const address_v4&) noexcept;
  // [internet.address.v6.comparisons], address_v6 comparisons:
  constexpr bool operator==(const address_v6&, const address_v6&) noexcept;
  constexpr bool operator!=(const address_v6&, const address_v6&) noexcept;
  constexpr bool operator< (const address_v6&, const address_v6&) noexcept;
  constexpr bool operator> (const address_v6&, const address_v6&) noexcept;
  constexpr bool operator<=(const address_v6&, const address_v6&) noexcept;
  constexpr bool operator>=(const address_v6&, const address_v6&) noexcept;
  // [internet.address.creation], address creation:
  address make_address(const char*);
  address make_address(const char*, error_code&) noexcept;
  address make_address(const string&);
  address make_address(const string&, error_code&) noexcept;
  address make_address(string_view);
  address make_address(string_view, error_code&) noexcept;
  // [internet.address.v4.creation], address_v4 creation:
  constexpr address_v4 make_address_v4(const address_v4::bytes_type&);
  constexpr address_v4 make_address_v4(address_v4::uint_type);
  constexpr address_v4 make_address_v4(v4_mapped_t, const address_v6&);
  address_v4 make_address_v4(const char*);
  address_v4 make_address_v4(const char*, error_code&) noexcept;
  address_v4 make_address_v4(const string&);
  address_v4 make_address_v4(const string&, error_code&) noexcept;
  address_v4 make_address_v4(string_view);
  address_v4 make_address_v4(string_view, error_code&) noexcept;
  // [internet.address.v6.creation], address_v6 creation:
  constexpr address_v6 make_address_v6(const address_v6::bytes_type&,
                                       scope_id_type = 0);
  constexpr address_v6 make_address_v6(v4_mapped_t, const address_v4&) noexcept;
  address_v6 make_address_v6(const char*);
  address_v6 make_address_v6(const char*, error_code&) noexcept;
  address_v6 make_address_v6(const string&);
  address_v6 make_address_v6(const string&, error_code&) noexcept;
  address_v6 make_address_v6(string_view);
  address_v6 make_address_v6(string_view, error_code&) noexcept;
  // [internet.address.io], address I/O:
  template<class CharT, class Traits>
    basic_ostream<CharT, Traits>& operator<<(
      basic_ostream<CharT, Traits>&, const address&);
  // [internet.address.v4.io], address_v4 I/O:
  template<class CharT, class Traits>
    basic_ostream<CharT, Traits>& operator<<(
      basic_ostream<CharT, Traits>&, const address_v4&);
  // [internet.address.v6.io], address_v6 I/O:
  template<class CharT, class Traits>
    basic_ostream<CharT, Traits>& operator<<(
      basic_ostream<CharT, Traits>&, const address_v6&);
  template<class> class basic_address_iterator; // not defined
  template<> class basic_address_iterator<address_v4>;
  using address_v4_iterator = basic_address_iterator<address_v4>;
  template<> class basic_address_iterator<address_v6>;
  using address_v6_iterator = basic_address_iterator<address_v6>;
  template<class> class basic_address_range; // not defined
  template<> class basic_address_range<address_v4>;
  using address_v4_range = basic_address_range<address_v4>;
  template<> class basic_address_range<address_v6>;
  using address_v6_range = basic_address_range<address_v6>;
  class network_v4;
  class network_v6;
  // [internet.network.v4.comparisons], network_v4 comparisons:
  bool operator==(const network_v4&, const network_v4&) noexcept;
  bool operator!=(const network_v4&, const network_v4&) noexcept;
  // [internet.network.v6.comparisons], network_v6 comparisons:
  bool operator==(const network_v6&, const network_v6&) noexcept;
  bool operator!=(const network_v6&, const network_v6&) noexcept;
  // [internet.network.v4.creation], network_v4 creation:
  network_v4 make_network_v4(const address_v4&, int);
  network_v4 make_network_v4(const address_v4&, const address_v4&);
  network_v4 make_network_v4(const char*);
  network_v4 make_network_v4(const char*, error_code&) noexcept;
  network_v4 make_network_v4(const string&);
  network_v4 make_network_v4(const string&, error_code&) noexcept;
  network_v4 make_network_v4(string_view);
  network_v4 make_network_v4(string_view, error_code&) noexcept;
  // [internet.network.v6.creation], network_v6 creation:
  network_v6 make_network_v6(const address_v6&, int);
  network_v6 make_network_v6(const char*);
  network_v6 make_network_v6(const char*, error_code&) noexcept;
  network_v6 make_network_v6(const string&);
  network_v6 make_network_v6(const string&, error_code&) noexcept;
  network_v6 make_network_v6(string_view);
  network_v6 make_network_v6(string_view, error_code&) noexcept;
  // [internet.network.v4.io], network_v4 I/O:
  template<class CharT, class Traits>
    basic_ostream<CharT, Traits>& operator<<(
      basic_ostream<CharT, Traits>&, const network_v4&);
  // [internet.network.v6.io], network_v6 I/O:
  template<class CharT, class Traits>
    basic_ostream<CharT, Traits>& operator<<(
      basic_ostream<CharT, Traits>&, const network_v6&);
  template<class InternetProtocol>
    class basic_endpoint;
  // [internet.endpoint.comparisons], basic_endpoint comparisons:
  template<class InternetProtocol>
    bool operator==(const basic_endpoint<InternetProtocol>&,
                    const basic_endpoint<InternetProtocol>&);
  template<class InternetProtocol>
    bool operator!=(const basic_endpoint<InternetProtocol>&,
                    const basic_endpoint<InternetProtocol>&);
  template<class InternetProtocol>
    bool operator< (const basic_endpoint<InternetProtocol>&,
                    const basic_endpoint<InternetProtocol>&);
  template<class InternetProtocol>
    bool operator> (const basic_endpoint<InternetProtocol>&,
                    const basic_endpoint<InternetProtocol>&);
  template<class InternetProtocol>
    bool operator<=(const basic_endpoint<InternetProtocol>&,
                    const basic_endpoint<InternetProtocol>&);
  template<class InternetProtocol>
    bool operator>=(const basic_endpoint<InternetProtocol>&,
                    const basic_endpoint<InternetProtocol>&);
  // [internet.endpoint.io], basic_endpoint I/O:
  template<class CharT, class Traits, class InternetProtocol>
    basic_ostream<CharT, Traits>& operator<<(
      basic_ostream<CharT, Traits>&,
      const basic_endpoint<InternetProtocol>&);
  template<class InternetProtocol>
    class basic_resolver_entry;
  template<class InternetProtocol>
    bool operator==(const basic_resolver_entry<InternetProtocol>&,
                    const basic_resolver_entry<InternetProtocol>&);
  template<class InternetProtocol>
    bool operator!=(const basic_resolver_entry<InternetProtocol>&,
                    const basic_resolver_entry<InternetProtocol>&);
  template<class InternetProtocol>
    class basic_resolver_results;
  template<class InternetProtocol>
    bool operator==(const basic_resolver_results<InternetProtocol>&,
                    const basic_resolver_results<InternetProtocol>&);
  template<class InternetProtocol>
    bool operator!=(const basic_resolver_results<InternetProtocol>&,
                    const basic_resolver_results<InternetProtocol>&);
  class resolver_base;
  template<class InternetProtocol>
    class basic_resolver;
  string host_name();
  string host_name(error_code&);
  template<class Allocator>
    basic_string<char, char_traits<char>, Allocator>
      host_name(const Allocator&);
  template<class Allocator>
    basic_string<char, char_traits<char>, Allocator>
      host_name(const Allocator&, error_code&);
  class tcp;
  // [internet.tcp.comparisons], tcp comparisons:
  bool operator==(const tcp& a, const tcp& b);
  bool operator!=(const tcp& a, const tcp& b);
  class udp;
  // [internet.udp.comparisons], udp comparisons:
  bool operator==(const udp& a, const udp& b);
  bool operator!=(const udp& a, const udp& b);
  class v6_only;
  namespace unicast {
    class hops;
  } // namespace unicast
  namespace multicast {
    class join_group;
    class leave_group;
    class outbound_interface;
    class hops;
    class enable_loopback;
  } // namespace multicast
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
  template<> struct is_error_condition_enum<experimental::net::v1::ip::resolver_errc>
    : public true_type {};
  // [internet.hash], hash support
  template<class T> struct hash;
  template<> struct hash<experimental::net::v1::ip::address>;
  template<> struct hash<experimental::net::v1::ip::address_v4>;
  template<> struct hash<experimental::net::v1::ip::address_v6>;
} // namespace std
A type X meets the InternetProtocol requirements if it satisfies the requirements of AcceptableProtocol ([socket.reqmts.acceptableprotocol]), as well as the additional requirements listed below.
In the table below, a and b denote (possibly const) values of type X.
| expression | return type | assertion/note pre/post-conditions | 
| X::resolver | ip::basic_resolver<X> | The type of a resolver for the protocol. | 
| X::v4() | X | Returns an object representing the IP version 4 protocol. | 
| X::v6() | X | Returns an object representing the IP version 6 protocol. | 
| a == b | convertible to bool | Returns true if a and b represent the same IP protocol version, otherwise false. | 
| a != b | convertible to bool | Returns !(a == b). | 
A type X meets the MulticastGroupSocketOption requirements if it satisfies the requirements of Destructible (C++ 2014 [destructible]), CopyConstructible (C++ 2014 [copyconstructible]), CopyAssignable (C++ 2014 [copyassignable]), and SettableSocketOption ([socket.reqmts.settablesocketoption]), as well as the additional requirements listed below.
In the table below, a denotes a (possibly const) value of type address, b and c denote (possibly const) values of type address_v4, d denotes a (possibly const) value of type address_v6, e denotes a (possibly const) value of type unsigned int, and u denotes an identifier.
| expression | type | assertion/note pre/post-conditions | 
| X u(a); | Constructs a multicast group socket option to join the group with the specified version-independent address. | |
| X u(b, c); | Constructs a multicast group socket option to join the specified IPv4 address on a specified network interface. | |
| X u(d, e); | Constructs a multicast group socket option to join the specified IPv6 address on a specified network interface. | 
In this document, types that satisfy the MulticastGroupSocketOption requirements are defined as follows.
class C{
public:
  // constructors:
  explicit C(const address& multicast_group) noexcept;
  explicit C(const address_v4& multicast_group,
             const address_v4& network_interface = address_v4::any()) noexcept;
  explicit C(const address_v6& multicast_group,
             unsigned int network_interface = 0) noexcept;
};
Extensible implementations provide the following member functions:
class C{
public:
  template<class Protocol> int level(const Protocol& p) const noexcept;
  template<class Protocol> int name(const Protocol& p) const noexcept;
  template<class Protocol> const void* data(const Protocol& p) const noexcept;
  template<class Protocol> size_t size(const Protocol& p) const noexcept;
  // remainder unchanged
private:
  ip_mreq v4_value_; // exposition only
  ipv6_mreq v6_value_; // exposition only
};
Let L and N identify the POSIX macros to be passed as the level and option_name arguments, respectively, to POSIX setsockopt and getsockopt.
explicit C(const address& multicast_group) noexcept;
Effects: If multicast_group.is_v6() is true, calls C(multicast_group.to_v6()); otherwise, calls C(multicast_group.to_v4()).
explicit C(const address_v4& multicast_group,
           const address_v4& network_interface = address_v4::any()) noexcept;
Effects: For extensible implementations, v4_value_.imr_multiaddr is initialized to correspond to the address multicast_group, v4_value_.imr_interface is initialized to correspond to address network_interface, and v6_value_ is zero-initialized.
explicit C(const address_v6& multicast_group,
           unsigned int network_interface = 0) noexcept;
Effects: For extensible implementations, v6_value_.ipv6mr_multiaddr is initialized to correspond to the address multicast_group, v6_value_.ipv6mr_interface is initialized to network_interface, and v4_value_ is zero-initialized.
template<class Protocol> int level(const Protocol& p) const noexcept;
Returns: L.
template<class Protocol> int name(const Protocol& p) const noexcept;
Returns: N.
template<class Protocol> const void* data(const Protocol& p) const noexcept;
Returns: addressof(v6_value_) if p.family() == AF_INET6, otherwise addressof(v4_value_).
template<class Protocol> size_t size(const Protocol& p) const noexcept;
Returns: sizeof(v6_value_) if p.family() == AF_INET6, otherwise sizeof(v4_value_).
const error_category& resolver_category() noexcept;
Returns: A reference to an object of a type derived from class error_category. All calls to this function return references to the same object.
The object's default_error_condition and equivalent virtual functions behave as specified for the class error_category. The object's name virtual function returns a pointer to the string "resolver".
error_code make_error_code(resolver_errc e) noexcept;
Returns: error_code(static_cast<int>(e), resolver_category()).
error_condition make_error_condition(resolver_errc e) noexcept;
Returns: error_condition(static_cast<int>(e), resolver_category()).
The class address is a version-independent representation for an IP address. An object of class address holds either an IPv4 address, an IPv6 address, or no valid address.
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  class address
  {
  public:
    // [internet.address.cons], constructors:
    constexpr address() noexcept;
    constexpr address(const address& a) noexcept;
    constexpr address(const address_v4& a) noexcept;
    constexpr address(const address_v6& a) noexcept;
    // [internet.address.assign], assignment:
    address& operator=(const address& a) noexcept;
    address& operator=(const address_v4& a) noexcept;
    address& operator=(const address_v6& a) noexcept;
    // [internet.address.members], members:
    constexpr bool is_v4() const noexcept;
    constexpr bool is_v6() const noexcept;
    constexpr address_v4 to_v4() const;
    constexpr address_v6 to_v6() const;
    constexpr bool is_unspecified() const noexcept;
    constexpr bool is_loopback() const noexcept;
    constexpr bool is_multicast() const noexcept;
    template<class Allocator = allocator<char>>
      basic_string<char, char_traits<char>, Allocator>
        to_string(const Allocator& a = Allocator()) const;
  private:
    address_v4 v4_; // exposition only
    address_v6 v6_; // exposition only
  };
  // [internet.address.comparisons], address comparisons:
  constexpr bool operator==(const address& a, const address& b) noexcept;
  constexpr bool operator!=(const address& a, const address& b) noexcept;
  constexpr bool operator< (const address& a, const address& b) noexcept;
  constexpr bool operator> (const address& a, const address& b) noexcept;
  constexpr bool operator<=(const address& a, const address& b) noexcept;
  constexpr bool operator>=(const address& a, const address& b) noexcept;
  // [internet.address.creation], address creation:
  address make_address(const char* str);
  address make_address(const char* str, error_code& ec) noexcept;
  address make_address(const string& str);
  address make_address(const string& str, error_code& ec) noexcept;
  address make_address(string_view str);
  address make_address(string_view str, error_code& ec) noexcept;
  // [internet.address.io], address I/O:
  template<class CharT, class Traits>
    basic_ostream<CharT, Traits>& operator<<(
      basic_ostream<CharT, Traits>& os, const address& addr);
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
address satisfies the requirements for Destructible (C++ 2014 [destructible]), CopyConstructible (C++ 2014 [copyconstructible]), and CopyAssignable (C++ 2014 [copyassignable]).
constexpr address() noexcept;
Postconditions: is_v4() == true, is_v6() == false, and is_unspecified() == true.
constexpr address(const address_v4& a) noexcept;
Effects: Initializes v4_ with a.
Postconditions: is_v4() == true and is_v6() == false.
constexpr address(const address_v6& a) noexcept;
Effects: Initializes v6_ with a.
Postconditions: is_v4() == false and is_v6() == true.
address& operator=(const address_v4& a) noexcept;
Postconditions: is_v4() == true and is_v6() == false and to_v4() == a.
Returns: *this
address& operator=(const address_v6& a) noexcept;
Postconditions: is_v4() == false and is_v6() == true and to_v6() == a.
Returns: *this
constexpr bool is_v4() const noexcept;
Returns: true if the object contains an IP version 4 address, otherwise false.
constexpr bool is_v6() const noexcept;
Returns: true if the object contains an IP version 6 address, otherwise false.
constexpr address_v4 to_v4() const;
Returns: v4_.
Remarks: bad_address_cast if is_v4() == false.
constexpr address_v6 to_v6() const;
Returns: v6_.
Remarks: bad_address_cast if is_v6() == false.
constexpr bool is_unspecified() const noexcept;
Returns: If is_v4(), returns v4_.is_unspecified(). Otherwise returns v6_.is_unspecified().
constexpr bool is_loopback() const noexcept;
Returns: If is_v4(), returns v4_.is_loopback(). Otherwise returns v6_.is_loopback().
constexpr bool is_multicast() const noexcept;
Returns: If is_v4(), returns v4_.is_multicast(). Otherwise returns v6_.is_multicast().
template<class Allocator = allocator<char>>
  basic_string<char, char_traits<char>, Allocator>
    to_string(const Allocator& a = Allocator()) const;
Returns: If is_v4(), returns v4_.to_string(a). Otherwise returns v6_.to_string(a).
constexpr bool operator==(const address& a, const address& b) noexcept;
constexpr bool operator!=(const address& a, const address& b) noexcept;
Returns: !(a == b).
constexpr bool operator< (const address& a, const address& b) noexcept;
constexpr bool operator> (const address& a, const address& b) noexcept;
Returns: b < a.
constexpr bool operator<=(const address& a, const address& b) noexcept;
Returns: !(b < a).
constexpr bool operator>=(const address& a, const address& b) noexcept;
Returns: !(a < b).
address make_address(const char* str);
address make_address(const char* str, error_code& ec) noexcept;
address make_address(const string& str);
address make_address(const string& str, error_code& ec) noexcept;
address make_address(string_view str);
address make_address(string_view str, error_code& ec) noexcept;
Effects: Converts a textual representation of an address into an object of class address, as if by calling:
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;
}
Returns: a.
template<class CharT, class Traits>
  basic_ostream<CharT, Traits>& operator<<(
    basic_ostream<CharT, Traits>& os, const address& addr);
Returns: os << addr.to_string().c_str().
The class address_v4 is a representation of an IPv4 address.
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  class address_v4
  {
  public:
    // [internet.address.v4.bytes], types:
    using uint_type = uint_least32_t;
    struct bytes_type;
    // [internet.address.v4.cons], constructors:
    constexpr address_v4() noexcept;
    constexpr address_v4(const address_v4& a) noexcept;
    constexpr address_v4(const bytes_type& bytes);
    explicit constexpr address_v4(uint_type val);
    // assignment:
    address_v4& operator=(const address_v4& a) noexcept;
    // [internet.address.v4.members], members:
    constexpr bool is_unspecified() const noexcept;
    constexpr bool is_loopback() const noexcept;
    constexpr bool is_multicast() const noexcept;
    constexpr bytes_type to_bytes() const noexcept;
    constexpr uint_type to_uint() const noexcept;
    template<class Allocator = allocator<char>>
      basic_string<char, char_traits<char>, Allocator>
        to_string(const Allocator& a = Allocator()) const;
    // [internet.address.v4.static], static members:
    static constexpr address_v4 any() noexcept;
    static constexpr address_v4 loopback() noexcept;
    static constexpr address_v4 broadcast() noexcept;
  };
  // [internet.address.v4.comparisons], address_v4 comparisons:
  constexpr bool operator==(const address_v4& a, const address_v4& b) noexcept;
  constexpr bool operator!=(const address_v4& a, const address_v4& b) noexcept;
  constexpr bool operator< (const address_v4& a, const address_v4& b) noexcept;
  constexpr bool operator> (const address_v4& a, const address_v4& b) noexcept;
  constexpr bool operator<=(const address_v4& a, const address_v4& b) noexcept;
  constexpr bool operator>=(const address_v4& a, const address_v4& b) noexcept;
  // [internet.address.v4.creation], address_v4 creation:
  constexpr address_v4 make_address_v4(const address_v4::bytes_type& bytes);
  constexpr address_v4 make_address_v4(address_v4::uint_type val);
  constexpr address_v4 make_address_v4(v4_mapped_t, const address_v6& a);
  address_v4 make_address_v4(const char* str);
  address_v4 make_address_v4(const char* str, error_code& ec) noexcept;
  address_v4 make_address_v4(const string& str);
  address_v4 make_address_v4(const string& str, error_code& ec) noexcept;
  address_v4 make_address_v4(string_view str);
  address_v4 make_address_v4(string_view str, error_code& ec) noexcept;
  // [internet.address.v4.io], address_v4 I/O:
  template<class CharT, class Traits>
    basic_ostream<CharT, Traits>& operator<<(
      basic_ostream<CharT, Traits>& os, const address_v4& addr);
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
address_v4 satisfies the requirements for Destructible (C++ 2014 [destructible]), CopyConstructible (C++ 2014 [copyconstructible]), and CopyAssignable (C++ 2014 [copyassignable]).
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  struct address_v4::bytes_type : array<unsigned char, 4>
  {
    template<class... T> explicit constexpr bytes_type(T... t)
      : array<unsigned char, 4>{{static_cast<unsigned char>(t)...}} {}
  };
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
The ip::address_v4::bytes_type type is a standard-layout struct that provides a byte-level representation of an IPv4 address in network byte order.
constexpr address_v4() noexcept;
Postconditions: to_bytes() yields {0, 0, 0, 0} and to_uint() == 0.
constexpr address_v4(const bytes_type& bytes);
Remarks: out_of_range if any element of bytes is not in the range [0, 0xFF]. [ Note: For implementations where numeric_limits<unsigned char>::max() == 0xFF, no out-of-range detection is needed. — end note ]
Postconditions: to_bytes() == bytes and to_uint() == (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3].
explicit constexpr address_v4(address_v4::uint_type val);
Remarks: out_of_range if val is not in the range [0, 0xFFFFFFFF]. [ Note: For implementations where numeric_limits<address_v4::uint_type>::max() == 0xFFFFFFFF, no out-of-range detection is needed. — end note ]
Postconditions: to_uint() == val and to_bytes() is:
constexpr bool is_unspecified() const noexcept;
Returns: to_uint() == 0.
constexpr bool is_loopback() const noexcept;
Returns: (to_uint() & 0xFF000000) == 0x7F000000.
constexpr bool is_multicast() const noexcept;
Returns: (to_uint() & 0xF0000000) == 0xE0000000.
constexpr bytes_type to_bytes() const noexcept;
Returns: A representation of the address in network byte order ([defs.net.byte.order]).
constexpr address_v4::uint_type to_uint() const noexcept;
Returns: A representation of the address in host byte order ([defs.host.byte.order]).
template<class Allocator = allocator<char>>
  basic_string<char, char_traits<char>, Allocator>
    to_string(const Allocator& a = Allocator()) const;
Returns: If successful, the textual representation of the address, determined as if by POSIX inet_ntop when invoked with address family AF_INET. Otherwise basic_string<char, char_traits<char>, Allocator>(a).
static constexpr address_v4 any() noexcept;
Returns: address_v4().
static constexpr address_v4 loopback() noexcept;
Returns: address_v4(0x7F000001).
static constexpr address_v4 broadcast() noexcept;
Returns: address_v4(0xFFFFFFFF).
constexpr bool operator==(const address_v4& a, const address_v4& b) noexcept;
Returns: a.to_uint() == b.to_uint().
constexpr bool operator!=(const address_v4& a, const address_v4& b) noexcept;
Returns: !(a == b).
constexpr bool operator< (const address_v4& a, const address_v4& b) noexcept;
Returns: a.to_uint() < b.to_uint().
constexpr bool operator> (const address_v4& a, const address_v4& b) noexcept;
Returns: b < a.
constexpr bool operator<=(const address_v4& a, const address_v4& b) noexcept;
Returns: !(b < a).
constexpr bool operator>=(const address_v4& a, const address_v4& b) noexcept;
Returns: !(a < b).
constexpr address_v4 make_address_v4(const address_v4::bytes_type& bytes);
Returns: address_v4(bytes).
constexpr address_v4 make_address_v4(address_v4::uint_type val);
Returns: address_v4(val).
constexpr address_v4 make_address_v4(v4_mapped_t, const address_v6& a);
Returns: An address_v4 object corresponding to the IPv4-mapped IPv6 address, as if computed by the following method:
address_v6::bytes_type v6b = a.to_bytes(); address_v4::bytes_type v4b(v6b[12], v6b[13], v6b[14], v6b[15]); return address_v4(v4b);
Remarks: bad_address_cast if a.is_v4_mapped() is false.
address_v4 make_address_v4(const char* str);
address_v4 make_address_v4(const char* str, error_code& ec) noexcept;
address_v4 make_address_v4(const string& str);
address_v4 make_address_v4(const string& str, error_code& ec) noexcept;
address_v4 make_address_v4(string_view str);
address_v4 make_address_v4(string_view str, error_code& ec) noexcept;
Effects: Converts a textual representation of an address into a corresponding address_v4 value, as if by POSIX inet_pton when invoked with address family AF_INET.
Returns: If successful, an address_v4 value corresponding to the string str. Otherwise address_v4().
template<class CharT, class Traits>
  basic_ostream<CharT, Traits>& operator<<(
    basic_ostream<CharT, Traits>& os, const address_v4& addr);
Returns: os << addr.to_string().c_str().
The class address_v6 is a representation of an IPv6 address.
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  class address_v6
  {
  public:
    // [internet.address.v6.bytes], types:
    struct bytes_type;
    // [internet.address.v6.cons], constructors:
    constexpr address_v6() noexcept;
    constexpr address_v6(const address_v6& a) noexcept;
    constexpr address_v6(const bytes_type& bytes,
                         scope_id_type scope = 0);
    // assignment:
    address_v6& operator=(const address_v6& a) noexcept;
    // [internet.address.v6.members], members:
    void scope_id(scope_id_type id) noexcept;
    constexpr scope_id_type scope_id() const noexcept;
    constexpr bool is_unspecified() const noexcept;
    constexpr bool is_loopback() const noexcept;
    constexpr bool is_multicast() const noexcept;
    constexpr bool is_link_local() const noexcept;
    constexpr bool is_site_local() const noexcept;
    constexpr bool is_v4_mapped() const noexcept;
    constexpr bool is_multicast_node_local() const noexcept;
    constexpr bool is_multicast_link_local() const noexcept;
    constexpr bool is_multicast_site_local() const noexcept;
    constexpr bool is_multicast_org_local() const noexcept;
    constexpr bool is_multicast_global() const noexcept;
    constexpr bytes_type to_bytes() const noexcept;
    template<class Allocator = allocator<char>>
      basic_string<char, char_traits<char>, Allocator>
        to_string(const Allocator& a = Allocator()) const;
    // [internet.address.v6.static], static members:
    static constexpr address_v6 any() noexcept;
    static constexpr address_v6 loopback() noexcept;
  };
  // [internet.address.v6.comparisons], address_v6 comparisons:
  constexpr bool operator==(const address_v6& a, const address_v6& b) noexcept;
  constexpr bool operator!=(const address_v6& a, const address_v6& b) noexcept;
  constexpr bool operator< (const address_v6& a, const address_v6& b) noexcept;
  constexpr bool operator> (const address_v6& a, const address_v6& b) noexcept;
  constexpr bool operator<=(const address_v6& a, const address_v6& b) noexcept;
  constexpr bool operator>=(const address_v6& a, const address_v6& b) noexcept;
  // [internet.address.v6.creation], address_v6 creation:
  constexpr address_v6 make_address_v6(const address_v6::bytes_type& bytes,
                                       scope_id_type scope_id = 0);
  constexpr address_v6 make_address_v6(v4_mapped_t, const address_v4& a) noexcept;
  address_v6 make_address_v6(const char* str);
  address_v6 make_address_v6(const char* str, error_code& ec) noexcept;
  address_v6 make_address_v6(const string& str);
  address_v6 make_address_v6(const string& str, error_code& ec) noexcept;
  address_v6 make_address_v6(string_view str);
  address_v6 make_address_v6(string_view str, error_code& ec) noexcept;
  // [internet.address.v6.io], address_v6 I/O:
  template<class CharT, class Traits>
    basic_ostream<CharT, Traits>& operator<<(
      basic_ostream<CharT, Traits>& os, const address_v6& addr);
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
address_v6 satisfies the requirements for Destructible (C++ 2014 [destructible]), CopyConstructible (C++ 2014 [copyconstructible]), and CopyAssignable (C++ 2014 [copyassignable]).
[ Note: The implementations of the functions is_unspecified, is_loopback, is_multicast, is_link_local, is_site_local, is_v4_mapped, is_multicast_node_local, is_multicast_link_local, is_multicast_site_local, is_multicast_org_local and is_multicast_global are determined by [RFC4291]. — end note ]
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  struct address_v6::bytes_type : array<unsigned char, 16>
  {
    template<class... T> explicit constexpr bytes_type(T... t)
      : array<unsigned char, 16>{{static_cast<unsigned char>(t)...}} {}
  };
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
The ip::address_v6::bytes_type type is a standard-layout struct that provides a byte-level representation of an IPv6 address in network byte order.
constexpr address_v6() noexcept;
Postconditions: is_unspecified() == true and scope_id() == 0.
constexpr address_v6(const bytes_type& bytes,
                     scope_id_type scope = 0);
Remarks: out_of_range if any element of bytes is not in the range [0, 0xFF]. [ Note: For implementations where numeric_limits<unsigned char>::max() == 0xFF, no out-of-range detection is needed. — end note ]
Postconditions: to_bytes() == bytes and scope_id() == scope.
void scope_id(scope_id_type id) noexcept;
Postconditions: scope_id() == id.
constexpr scope_id_type scope_id() const noexcept;
Returns: The scope identifier associated with the address.
constexpr bool is_unspecified() const noexcept;
Returns: *this == make_address_v6("::").
constexpr bool is_loopback() const noexcept;
Returns: *this == make_address_v6("::1").
constexpr bool is_multicast() const noexcept;
Returns: A boolean indicating whether the address_v6 object represents a multicast address, as if computed by the following method:
bytes_type b = to_bytes(); return b[0] == 0xFF;
constexpr bool is_link_local() const noexcept;
Returns: A boolean indicating whether the address_v6 object represents a unicast link-local address, as if computed by the following method:
bytes_type b = to_bytes(); return b[0] == 0xFE && (b[1] & 0xC0) == 0x80;
constexpr bool is_site_local() const noexcept;
Returns: A boolean indicating whether the address_v6 object represents a unicast site-local address, as if computed by the following method:
bytes_type b = to_bytes(); return b[0] == 0xFE && (b[1] & 0xC0) == 0xC0;
constexpr bool is_v4_mapped() const noexcept;
Returns: A boolean indicating whether the address_v6 object represents an IPv4-mapped IPv6 address, as if computed by the following method:
bytes_type b = to_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;
Returns: is_multicast() && (to_bytes()[1] & 0x0F) == 0x01.
constexpr bool is_multicast_link_local() const noexcept;
Returns: is_multicast() && (to_bytes()[1] & 0x0F) == 0x02.
constexpr bool is_multicast_site_local() const noexcept;
Returns: is_multicast() && (to_bytes()[1] & 0x0F) == 0x05.
constexpr bool is_multicast_org_local() const noexcept;
Returns: is_multicast() && (to_bytes()[1] & 0x0F) == 0x08.
constexpr bool is_multicast_global() const noexcept;
Returns: is_multicast() && (to_bytes()[1] & 0x0F) == 0x0E.
constexpr bytes_type to_bytes() const noexcept;
Returns: A representation of the address in network byte order ([defs.net.byte.order]).
template<class Allocator = allocator<char>>
  basic_string<char, char_traits<char>, Allocator>
    to_string(const Allocator& a = Allocator()) const;
Effects: Converts an address into a textual representation. If scope_id() == 0, converts as if by POSIX inet_ntop when invoked with address family AF_INET6. If scope_id() != 0, the format is address%scope-id, where address is the textual representation of the equivalent address having scope_id() == 0, and scope-id is an implementation-defined textual representation of the scope identifier.
Returns: If successful, the textual representation of the address. Otherwise basic_string<char, char_traits<char>, Allocator>(a).
static constexpr address_v6 any() noexcept;
Returns: An address a such that the a.is_unspecified() == true and a.scope_id() == 0.
static constexpr address_v6 loopback() noexcept;
Returns: An address a such that the a.is_loopback() == true and a.scope_id() == 0.
constexpr bool operator==(const address_v6& a, const address_v6& b) noexcept;
Returns: a.to_bytes() == b.to_bytes() && a.scope_id() == b.scope_id().
constexpr bool operator!=(const address_v6& a, const address_v6& b) noexcept;
Returns: !(a == b).
constexpr bool operator< (const address_v6& a, const address_v6& b) noexcept;
Returns: tie(a.to_bytes(), a.scope_id()) < tie(b.to_bytes(), b.scope_id()).
constexpr bool operator> (const address_v6& a, const address_v6& b) noexcept;
Returns: b < a.
constexpr bool operator<=(const address_v6& a, const address_v6& b) noexcept;
Returns: !(b < a).
constexpr bool operator>=(const address_v6& a, const address_v6& b) noexcept;
Returns: !(a < b).
constexpr address_v6 make_address_v6(const address_v6::bytes_type& bytes,
                                     scope_id_type scope_id);
Returns: address_v6(bytes, scope_id).
constexpr address_v6 make_address_v6(v4_mapped_t, const address_v4& a) noexcept;
Returns: An address_v6 object containing the IPv4-mapped IPv6 address corresponding to the specified IPv4 address, as if computed by the following method:
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);
address_v6 make_address_v6(const char* str);
address_v6 make_address_v6(const char* str, error_code& ec) noexcept;
address_v4 make_address_v6(const string& str);
address_v4 make_address_v6(const string& str, error_code& ec) noexcept;
address_v6 make_address_v6(string_view str);
address_v6 make_address_v6(string_view str, error_code& ec) noexcept;
Effects: Converts a textual representation of an address into a corresponding address_v6 value. The format is either address or address%scope-id, where address is in the format specified by POSIX inet_pton when invoked with address family AF_INET6, and scope-id is an optional string specifying the scope identifier. All implementations accept as scope-id a textual representation of an unsigned decimal integer. It is implementation-defined whether alternative scope identifier representations are permitted. If scope-id is not supplied, an address_v6 object is returned such that scope_id() == 0.
Returns: If successful, an address_v6 value corresponding to the string str. Otherwise returns address_v6().
template<class CharT, class Traits>
  basic_ostream<CharT, Traits>& operator<<(
    basic_ostream<CharT, Traits>& os, const address_v6& addr);
Returns: os << addr.to_string().c_str().
An exception of type bad_address_cast is thrown by a failed address_cast.
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  class bad_address_cast : public bad_cast
  {
  public:
    // constructor:
    bad_address_cast() noexcept;
  };
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
bad_address_cast() noexcept;
Effects: constructs a bad_address_cast object.
template<> struct hash<experimental::net::v1::ip::address>;
template<> struct hash<experimental::net::v1::ip::address_v4>;
template<> struct hash<experimental::net::v1::ip::address_v6>;
Requires: the template specializations shall meet the requirements of class template hash (C++ 2014 [unord.hash]).
The class template basic_address_iterator enables iteration over IP addresses in network byte order. This clause defines two specializations of the class template basic_address_iterator: basic_address_iterator<address_v4> and basic_address_iterator<address_v6>. The members and operational semantics of these specializations are defined below.
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  template<> class basic_address_iterator<Address>
  {
  public:
    // types:
    using value_type = Address;
    using difference_type = ptrdiff_t;
    using pointer = const Address*;
    using reference = const Address&;
    using iterator_category = input_iterator_tag;
    // constructors:
    basic_address_iterator(const Address& a) noexcept;
    // members:
    reference operator*() const noexcept;
    pointer operator->() const noexcept;
    basic_address_iterator& operator++() noexcept;
    basic_address_iterator operator++(int) noexcept;
    basic_address_iterator& operator--() noexcept;
    basic_address_iterator operator--(int) noexcept;
    // other members as required by C++ 2014 [input.iterators]
  private:
    Address address_; // exposition only
  };
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
Specializations of basic_address_iterator satisfy the requirements for input iterators (C++ 2014 [input.iterators]).
basic_address_iterator(const Address& a) noexcept;
Effects: Initializes address_ with a.
reference operator*() const noexcept;
Returns: address_.
pointer operator->() const noexcept;
Returns: addressof(address_).
basic_address_iterator& operator++() noexcept;
Effects: Sets address_ to the next unique address in network byte order.
Returns: *this.
basic_address_iterator operator++(int) noexcept;
Effects: Sets address_ to the next unique address in network byte order.
Returns: The prior value of *this.
basic_address_iterator& operator--() noexcept;
Effects: Sets address_ to the prior unique address in network byte order.
Returns: *this.
basic_address_iterator operator--(int) noexcept;
Effects: Sets address_ to the prior unique address in network byte order.
Returns: The prior value of *this.
The class template basic_address_range represents a range of IP addresses in network byte order. This clause defines two specializations of the class template basic_address_range: basic_address_range<address_v4> and basic_address_range<address_v6>. The members and operational semantics of these specializations are defined below.
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  template<> class basic_address_range<Address>
  {
  public:
    // types:
    using iterator = basic_address_iterator<Address>;
    // constructors:
    basic_address_range() noexcept;
    basic_address_range(const Address& first,
                        const Address& last) noexcept;
    // members:
    iterator begin() const noexcept;
    iterator end() const noexcept;
    bool empty() const noexcept;
    size_t size() const noexcept; // not always defined
    iterator find(const Address& addr) const noexcept;
  };
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
Specializations of basic_address_range satisfy the requirements for Destructible (C++ 2014 [destructible]), CopyConstructible (C++ 2014 [copyconstructible]), and CopyAssignable (C++ 2014 [copyassignable]).
basic_address_range() noexcept;
Effects: Constructs an object of type basic_address_range<Address> that represents an empty range.
basic_address_range(const Address& first,
                    const Address& last) noexcept;
Effects: Constructs an object of type basic_address_range<Address> that represents the half-open range [first, last).
iterator begin() const noexcept;
Returns: An iterator that points to the beginning of the range.
iterator end() const noexcept;
Returns: An iterator that points to the end of the range.
bool empty() const noexcept;
Returns: true if *this represents an empty range, otherwise false.
size_t size() const noexcept;
Returns: The number of unique addresses in the range.
Remarks: This member function is not defined when Address is type address_v6.
iterator find(const Address& addr) const noexcept;
Returns: If addr is in the range, an iterator that points to addr; otherwise, end().
Complexity: Constant time.
The class network_v4 provides the ability to use and manipulate IPv4 network addresses.
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  class network_v4
  {
  public:
    // [internet.network.v4.cons], constructors:
    constexpr network_v4() noexcept;
    constexpr network_v4(const address_v4& addr, int prefix_len);
    constexpr network_v4(const address_v4& addr, const address_v4& mask);
    // [internet.network.v4.members], members:
    constexpr address_v4 address() const noexcept;
    constexpr int prefix_length() const noexcept;
    constexpr address_v4 netmask() const noexcept;
    constexpr address_v4 network() const noexcept;
    constexpr address_v4 broadcast() const noexcept;
    address_v4_range hosts() const noexcept;
    constexpr network_v4 canonical() const noexcept;
    constexpr bool is_host() const noexcept;
    constexpr bool is_subnet_of(const network_v4& other) const noexcept;
    template<class Allocator = allocator<char>>
      basic_string<char, char_traits<char>, Allocator>
        to_string(const Allocator& a = Allocator()) const;
  };
  // [internet.network.v4.comparisons], network_v4 comparisons:
  constexpr bool operator==(const network_v4& a, const network_v4& b) noexcept;
  constexpr bool operator!=(const network_v4& a, const network_v4& b) noexcept;
  // [internet.network.v4.creation], network_v4 creation:
  constexpr network_v4 make_network_v4(const address_v4& addr, int prefix_len);
  constexpr network_v4 make_network_v4(const address_v4& addr, const address_v4& mask);
  network_v4 make_network_v4(const char* str);
  network_v4 make_network_v4(const char* str, error_code& ec) noexcept;
  network_v4 make_network_v4(const string& str);
  network_v4 make_network_v4(const string& str, error_code& ec) noexcept;
  network_v4 make_network_v4(string_view str);
  network_v4 make_network_v4(string_view str, error_code& ec) noexcept;
  // [internet.network.v4.io], network_v4 I/O:
  template<class CharT, class Traits>
    basic_ostream<CharT, Traits>& operator<<(
      basic_ostream<CharT, Traits>& os, const network_v4& net);
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
network_v4 satisfies the requirements for Destructible (C++ 2014 [destructible]), CopyConstructible (C++ 2014 [copyconstructible]), and CopyAssignable (C++ 2014 [copyassignable]).
constexpr network_v4() noexcept;
Postconditions: this->address().is_unspecified() == true and prefix_length() == 0.
constexpr network_v4(const address_v4& addr, int prefix_len);
Postconditions: this->address() == addr and prefix_length() == prefix_len.
Remarks: out_of_range if prefix_len < 0 or prefix_len > 32.
constexpr network_v4(const address_v4& addr, const address_v4& mask);
Postconditions: this->address() == addr and prefix_length() is equal to the number of contiguous non-zero bits in mask.
Remarks: invalid_argument if mask contains non-contiguous non-zero bits, or if the most significant bit is zero and any other bits are non-zero.
constexpr address_v4 address() const noexcept;
Returns: The address specified when the network_v4 object was constructed.
constexpr int prefix_length() const noexcept;
Returns: The prefix length of the network.
constexpr address_v4 netmask() const noexcept;
Returns: An address_v4 object with prefix_length() contiguous non-zero bits set, starting from the most significant bit in network byte order. All other bits are zero.
constexpr address_v4 network() const noexcept;
Returns: An address_v4 object with the first prefix_length() bits, starting from the most significant bit in network byte order, set to the corresponding bit value of this->address(). All other bits are zero.
constexpr address_v4 broadcast() const noexcept;
Returns: An address_v4 object with the first prefix_length() bits, starting from the most significant bit in network byte order, set to the corresponding bit value of this->address(). All other bits are non-zero.
address_v4_range hosts() const noexcept;
Returns: If is_host() is true, an address_v4_range object representing the single address this->address(). Otherwise, an address_v4_range object representing the range of unique host IP addresses in the network.
[ Note: For IPv4, the network address and the broadcast address are not included in the range of host IP addresses. For example, given a network 192.168.1.0/24, the range returned by hosts() is from 192.168.1.1 to 192.168.1.254 inclusive, and neither 192.168.1.0 nor the broadcast address 192.168.1.255 are in the range. — end note ]
constexpr network_v4 canonical() const noexcept;
Returns: network_v4(network(), prefix_length()).
constexpr bool is_host() const noexcept;
Returns: prefix_length() == 32.
constexpr bool is_subnet_of(const network_v4& other) const noexcept;
Returns: true if other.prefix_length() < prefix_length() and network_v4(this->address(), other.prefix_length()).canonical() == other.canonical(), otherwise false.
template<class Allocator = allocator<char>>
  basic_string<char, char_traits<char>, Allocator>
    to_string(const Allocator& a = Allocator()) const;
Returns: this->address().to_string(a) + "/" + std::to_string(prefix_length()).
constexpr bool operator==(const network_v4& a, const network_v4& b) noexcept;
Returns: true if a.address() == b.address() and a.prefix_length() == b.prefix_length(), otherwise false.
constexpr bool operator!=(const network_v4& a, const network_v4& b) noexcept;
Returns: !(a == b).
constexpr network_v4 make_network_v4(const address_v4& addr, int prefix_len);
Returns: network_v4(addr, prefix_len).
constexpr network_v4 make_network_v4(const address_v4& addr, const address_v4& mask);
Returns: network_v4(addr, mask).
network_v4 make_network_v4(const char* str);
network_v4 make_network_v4(const char* str, error_code& ec) noexcept;
network_v4 make_network_v4(const string& str);
network_v4 make_network_v4(const string& str, error_code& ec) noexcept;
network_v4 make_network_v4(string_view str);
network_v4 make_network_v4(string_view str, error_code& ec) noexcept;
Returns: If str contains a value of the form address '/' prefix-length, a network_v4 object constructed with the result of applying make_address_v4() to the address portion of the string, and the result of converting prefix-length to an integer of type int. Otherwise returns network_v4() and sets ec to reflect the error.
template<class CharT, class Traits>
  basic_ostream<CharT, Traits>& operator<<(
    basic_ostream<CharT, Traits>& os, const network_v4& net);
Returns: os << net.to_string().c_str().
The class network_v6 provides the ability to use and manipulate IPv6 network addresses.
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  class network_v6
  {
  public:
    // [internet.network.v6.cons], constructors:
    constexpr network_v6() noexcept;
    constexpr network_v6(const address_v6& addr, int prefix_len);
    // [internet.network.v6.members], members:
    constexpr address_v6 address() const noexcept;
    constexpr int prefix_length() const noexcept;
    constexpr address_v6 network() const noexcept;
    address_v6_range hosts() const noexcept;
    constexpr network_v6 canonical() const noexcept;
    constexpr bool is_host() const noexcept;
    constexpr bool is_subnet_of(const network_v6& other) const noexcept;
    template<class Allocator = allocator<char>>
      basic_string<char, char_traits<char>, Allocator>
        to_string(const Allocator& a = Allocator()) const;
  };
  // [internet.network.v6.comparisons], network_v6 comparisons:
  constexpr bool operator==(const network_v6& a, const network_v6& b) noexcept;
  constexpr bool operator!=(const network_v6& a, const network_v6& b) noexcept;
  // [internet.network.v6.creation], network_v6 creation:
  constexpr network_v6 make_network_v6(const address_v6& addr, int prefix_len);
  network_v6 make_network_v6(const char* str);
  network_v6 make_network_v6(const char* str, error_code& ec) noexcept;
  network_v6 make_network_v6(const string& str);
  network_v6 make_network_v6(const string& str, error_code& ec) noexcept;
  network_v6 make_network_v6(string_view str);
  network_v6 make_network_v6(string_view str, error_code& ec) noexcept;
  // [internet.network.v6.io], network_v6 I/O:
  template<class CharT, class Traits>
    basic_ostream<CharT, Traits>& operator<<(
      basic_ostream<CharT, Traits>& os, const network_v6& net);
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
network_v6 satisfies the requirements for Destructible (C++ 2014 [destructible]), CopyConstructible (C++ 2014 [copyconstructible]), and CopyAssignable (C++ 2014 [copyassignable]).
constexpr network_v6() noexcept;
Postconditions: this->address().is_unspecified() == true and prefix_length() == 0.
constexpr network_v6(const address_v6& addr, int prefix_len);
Postconditions: this->address() == addr and prefix_length() == prefix_len.
Remarks: out_of_range if prefix_len < 0 or prefix_len > 128.
constexpr address_v6 address() const noexcept;
Returns: The address specified when the network_v6 object was constructed.
constexpr int prefix_length() const noexcept;
Returns: The prefix length of the network.
constexpr address_v6 network() const noexcept;
Returns: An address_v6 object with the first prefix_length() bits, starting from the most significant bit in network byte order, set to the corresponding bit value of this->address(). All other bits are zero.
address_v6_range hosts() const noexcept;
Returns: If is_host() is true, an address_v6_range object representing the single address this->address(). Otherwise, an address_v6_range object representing the range of unique host IP addresses in the network.
constexpr network_v6 canonical() const noexcept;
Returns: network_v6(network(), prefix_length()).
constexpr bool is_host() const noexcept;
Returns: prefix_length() == 128.
constexpr bool is_subnet_of(const network_v6& other) const noexcept;
Returns: true if other.prefix_length() < prefix_length() and network_v6(this->address(), other.prefix_length()).canonical() == other.canonical(), otherwise false.
template<class Allocator = allocator<char>>
  basic_string<char, char_traits<char>, Allocator>
    to_string(const Allocator& a = Allocator()) const;
Returns: this->address().to_string(a) + "/" + to_string(prefix_length()).c_str().
constexpr bool operator==(const network_v6& a, const network_v6& b) noexcept;
Returns: true if a.address() == b.address() and a.prefix_length() == b.prefix_length(), otherwise false.
constexpr bool operator!=(const network_v6& a, const network_v6& b) noexcept;
Returns: !(a == b).
constexpr network_v6 make_network_v6(const address_v6& addr, int prefix_len);
Returns: network_v6(addr, prefix_len).
network_v6 make_network_v6(const char* str);
network_v6 make_network_v6(const char* str, error_code& ec) noexcept;
network_v6 make_network_v6(const string& str);
network_v6 make_network_v6(const string& str, error_code& ec) noexcept;
network_v6 make_network_v6(string_view str);
network_v6 make_network_v6(string_view str, error_code& ec) noexcept;
Returns: If str contains a value of the form address '/' prefix-length, a network_v6 object constructed with the result of applying make_address_v6() to the address portion of the string, and the result of converting prefix-length to an integer of type int. Otherwise returns network_v6() and sets ec to reflect the error.
template<class CharT, class Traits>
  basic_ostream<CharT, Traits>& operator<<(
    basic_ostream<CharT, Traits>& os, const network_v6& net);
Returns: os << net.to_string().c_str().
An object of type basic_endpoint<InternetProtocol> represents a protocol-specific endpoint, where an endpoint consists of an IP address and port number. Endpoints may be used to identify sources and destinations for socket connections and datagrams.
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  template<class InternetProtocol>
  class basic_endpoint
  {
  public:
    // types:
    using protocol_type = InternetProtocol;
    // [internet.endpoint.cons], constructors:
    constexpr basic_endpoint() noexcept;
    constexpr basic_endpoint(const protocol_type& proto,
                             port_type port_num) noexcept;
    constexpr basic_endpoint(const ip::address& addr,
                             port_type port_num) noexcept;
    // [internet.endpoint.members], members:
    constexpr protocol_type protocol() const noexcept;
    constexpr ip::address address() const noexcept;
    void address(const ip::address& addr) noexcept;
    constexpr port_type port() const noexcept;
    void port(port_type port_num) noexcept;
  };
  // [internet.endpoint.comparisons], basic_endpoint comparisons:
  template<class InternetProtocol>
    constexpr bool operator==(const basic_endpoint<InternetProtocol>& a,
                              const basic_endpoint<InternetProtocol>& b) noexcept;
  template<class InternetProtocol>
    constexpr bool operator!=(const basic_endpoint<InternetProtocol>& a,
                              const basic_endpoint<InternetProtocol>& b) noexcept;
  template<class InternetProtocol>
    constexpr bool operator< (const basic_endpoint<InternetProtocol>& a,
                              const basic_endpoint<InternetProtocol>& b) noexcept;
  template<class InternetProtocol>
    constexpr bool operator> (const basic_endpoint<InternetProtocol>& a,
                              const basic_endpoint<InternetProtocol>& b) noexcept;
  template<class InternetProtocol>
    constexpr bool operator<=(const basic_endpoint<InternetProtocol>& a,
                              const basic_endpoint<InternetProtocol>& b) noexcept;
  template<class InternetProtocol>
    constexpr bool operator>=(const basic_endpoint<InternetProtocol>& a,
                              const basic_endpoint<InternetProtocol>& b) noexcept;
  // [internet.endpoint.io], basic_endpoint I/O:
  template<class CharT, class Traits, class InternetProtocol>
    basic_ostream<CharT, Traits>& operator<<(
      basic_ostream<CharT, Traits>& os,
      const basic_endpoint<InternetProtocol>& ep);
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
Instances of the basic_endpoint class template meet the requirements for an Endpoint ([socket.reqmts.endpoint]).
Extensible implementations provide the following member functions:
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  template<class InternetProtocol>
  class basic_endpoint
  {
  public:
    void* data() noexcept;
    const void* data() const noexcept;
    constexpr size_t size() const noexcept;
    void resize(size_t s);
    constexpr size_t capacity() const noexcept;
    // remainder unchanged
  private:
    union
    {
      sockaddr_in v4_;
      sockaddr_in6 v6_;
    } data_; // exposition only
  };
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
constexpr basic_endpoint() noexcept;
Postconditions: this->address() == ip::address() and port() == 0.
constexpr basic_endpoint(const protocol_type& proto,
                         port_type port_num) noexcept;
Requires: proto == protocol_type::v4() || proto == protocol_type::v6().
constexpr basic_endpoint(const ip::address& addr,
                         port_type port_num) noexcept;
Postconditions: this->address() == addr and port() == port_num.
constexpr protocol_type protocol() const noexcept;
Returns: protocol_type::v6() if the expression this->address().is_v6() is true, otherwise protocol_type::v4().
constexpr ip::address address() const noexcept;
Returns: The address associated with the endpoint.
void address(const ip::address& addr) noexcept;
Postconditions: this->address() == addr.
constexpr port_type port() const noexcept;
Returns: The port number associated with the endpoint.
void port(port_type port_num) noexcept;
Postconditions: port() == port_num.
template<class InternetProtocol>
  constexpr bool operator==(const basic_endpoint<InternetProtocol>& a,
                            const basic_endpoint<InternetProtocol>& b) noexcept;
Returns: a.address() == b.address() && a.port() == b.port()).
template<class InternetProtocol>
  constexpr bool operator!=(const basic_endpoint<InternetProtocol>& a,
                            const basic_endpoint<InternetProtocol>& b) noexcept;
Returns: !(a == b).
template<class InternetProtocol>
  constexpr bool operator< (const basic_endpoint<InternetProtocol>& a,
                            const basic_endpoint<InternetProtocol>& b) noexcept;
Returns: tie(a.address(), a.port()) < tie(b.address(), b.port()).
template<class InternetProtocol>
  constexpr bool operator> (const basic_endpoint<InternetProtocol>& a,
                            const basic_endpoint<InternetProtocol>& b) noexcept;
Returns: b < a.
template<class InternetProtocol>
  constexpr bool operator<=(const basic_endpoint<InternetProtocol>& a,
                            const basic_endpoint<InternetProtocol>& b) noexcept;
Returns: !(b < a).
template<class InternetProtocol>
  constexpr bool operator>=(const basic_endpoint<InternetProtocol>& a,
                            const basic_endpoint<InternetProtocol>& b) noexcept;
Returns: !(a < b).
template<class CharT, class Traits, class InternetProtocol>
  basic_ostream<CharT, Traits>& operator<<(
    basic_ostream<CharT, Traits>& os,
    const basic_endpoint<InternetProtocol>& ep);
Effects: Outputs a representation of the endpoint to the stream, as if it were implemented as follows:
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();
Returns: os.
[ Note: The representation of the endpoint when it contains an IP version 6 address is based on [RFC2732]. — end note ]
void* data() noexcept;
Returns: addressof(data_).
const void* data() const noexcept;
Returns: addressof(data_).
constexpr size_t size() const noexcept;
Returns: sizeof(sockaddr_in6) if protocol().family() == AF_INET6, otherwise sizeof(sockaddr_in).
void resize(size_t s);
constexpr size_t capacity() const noexcept;
Returns: sizeof(data_).
An object of type basic_resolver_entry<InternetProtocol> represents a single element in the results returned by a name resolution operation.
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  template<class InternetProtocol>
  class basic_resolver_entry
  {
  public:
    // types:
    using protocol_type = InternetProtocol;
    using endpoint_type = typename InternetProtocol::endpoint;
    // [internet.resolver.entry.cons], constructors:
    basic_resolver_entry();
    basic_resolver_entry(const endpoint_type& ep,
                         string_view h,
                         string_view s);
    // [internet.resolver.entry.members], members:
    endpoint_type endpoint() const;
    operator endpoint_type() const;
    template<class Allocator = allocator<char>>
      basic_string<char, char_traits<char>, Allocator>
        host_name(const Allocator& a = Allocator()) const;
    template<class Allocator = allocator<char>>
      basic_string<char, char_traits<char>, Allocator>
        service_name(const Allocator& a = Allocator()) const;
  };
  // [internet.resolver.entry.comparisons], basic_resolver_entry comparisons:
  template<class InternetProtocol>
    bool operator==(const basic_resolver_entry<InternetProtocol>& a,
                    const basic_resolver_entry<InternetProtocol>& b);
  template<class InternetProtocol>
    bool operator!=(const basic_resolver_entry<InternetProtocol>& a,
                    const basic_resolver_entry<InternetProtocol>& b);
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
basic_resolver_entry();
Effects: Equivalent to basic_resolver_entry<InternetProtocol>(endpoint_type(), "", "").
basic_resolver_entry(const endpoint_type& ep,
                     string_view h,
                     string_view s);
endpoint_type endpoint() const;
Returns: The endpoint associated with the resolver entry.
operator endpoint_type() const;
Returns: endpoint().
template<class Allocator = allocator<char>>
  basic_string<char, char_traits<char>, Allocator>
    host_name(const Allocator& a = Allocator()) const;
Returns: The host name associated with the resolver entry.
Remarks: Ill-formed unless allocator_traits<Allocator>::value_type is char.
template<class Allocator = allocator<char>>
  basic_string<char, char_traits<char>, Allocator>
    service_name(const Allocator& a = Allocator()) const;
Returns: The service name associated with the resolver entry.
Remarks: Ill-formed unless allocator_traits<Allocator>::value_type is char.
template<class InternetProtocol>
  bool operator==(const basic_resolver_entry<InternetProtocol>& a,
                  const basic_resolver_entry<InternetProtocol>& b);
Returns: a.endpoint() == b.endpoint() && a.host_name() == b.host_name() && a.service_name() == b.service_name().
template<class InternetProtocol>
  bool operator!=(const basic_resolver_entry<InternetProtocol>& a,
                  const basic_resolver_entry<InternetProtocol>& b);
Returns: !(a == b).
An object of type basic_resolver_results<InternetProtocol> represents a sequence of basic_resolver_entry<InternetProtocol> elements resulting from a single name resolution operation.
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  template<class InternetProtocol>
  class basic_resolver_results
  {
  public:
    // types:
    using protocol_type = InternetProtocol;
    using endpoint_type = typename protocol_type::endpoint;
    using value_type = basic_resolver_entry<protocol_type>;
    using const_reference = const value_type&;
    using reference = value_type&;
    using const_iterator = implementation-defined;
    using iterator = const_iterator;
    using difference_type = ptrdiff_t;
    using size_type = size_t;
    // [internet.resolver.results.cons], construct / copy / destroy:
    basic_resolver_results();
    basic_resolver_results(const basic_resolver_results& rhs);
    basic_resolver_results(basic_resolver_results&& rhs) noexcept;
    basic_resolver_results& operator=(const basic_resolver_results& rhs);
    basic_resolver_results& operator=(basic_resolver_results&& rhs);
    ~basic_resolver_results();
    // [internet.resolver.results.size], size:
    size_type size() const noexcept;
    size_type max_size() const noexcept;
    bool empty() const noexcept;
    // [internet.resolver.results.access], element access:
    const_iterator begin() const;
    const_iterator end() const;
    const_iterator cbegin() const;
    const_iterator cend() const;
    // [internet.resolver.results.swap], swap:
    void swap(basic_resolver_results& that) noexcept;
  };
  // [internet.resolver.results.comparisons], basic_resolver_results comparisons:
  template<class InternetProtocol>
    bool operator==(const basic_resolver_results<InternetProtocol>& a,
                    const basic_resolver_results<InternetProtocol>& b);
  template<class InternetProtocol>
    bool operator!=(const basic_resolver_results<InternetProtocol>& a,
                    const basic_resolver_results<InternetProtocol>& b);
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
The class template basic_resolver_results satisfies the requirements of a sequence container (C++ 2014 [sequence.reqmts]), except that only the operations defined for const-qualified sequence containers are supported. The class template basic_resolver_results supports forward iterators.
A default-constructed basic_resolver_results object is empty. A non-empty results object is obtained only by calling a basic_resolver object's wait or async_wait operations, or otherwise by copy construction, move construction, assignment, or swap from another non-empty results object.
basic_resolver_results();
Postconditions: size() == 0.
basic_resolver_results(const basic_resolver_results& rhs);
Postconditions: *this == rhs.
basic_resolver_results(basic_resolver_results&& rhs) noexcept;
Postconditions: *this is equal to the prior value of rhs.
basic_resolver_results& operator=(const basic_resolver_results& rhs);
Postconditions: *this == rhs.
Returns: *this.
basic_resolver_results& operator=(basic_resolver_results& rhs) noexcept;
Postconditions: *this is equal to the prior value of rhs.
Returns: *this.
size_type size() const noexcept;
Returns: The number of basic_resolver_entry elements in *this.
size_type max_size() const noexcept;
Returns: The maximum number of basic_resolver_entry elements that can be stored in *this.
bool empty() const noexcept;
Returns: size() == 0.
const_iterator begin() const;
const_iterator cbegin() const;
Returns: A starting iterator that enumerates over all the basic_resolver_entry elements stored in *this.
const_iterator end() const;
const_iterator cend() const;
Returns: A terminating iterator that enumerates over all the basic_resolver_entry elements stored in *this.
void swap(basic_resolver_results& that) noexcept;
Postconditions: *this is equal to the prior value of that, and that is equal to the prior value of *this.
template<class InternetProtocol>
  bool operator==(const basic_resolver_results<InternetProtocol>& a,
                  const basic_resolver_results<InternetProtocol>& b);
Returns: a.size() == b.size() && equal(a.cbegin(), a.cend(), b.cbegin()).
template<class InternetProtocol>
  bool operator!=(const basic_resolver_results<InternetProtocol>& a,
                  const basic_resolver_results<InternetProtocol>& b);
Returns: !(a == b).
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  class resolver_base
  {
  public:
    using flags = T1;
    static const flags passive;
    static const flags canonical_name;
    static const flags numeric_host;
    static const flags numeric_service;
    static const flags v4_mapped;
    static const flags all_matching;
    static const flags address_configured;
  protected:
    resolver_base();
    ~resolver_base();
  };
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
resolver_base defines a bitmask type, flags, with the bitmask elements shown in Table [tab:internet.resolver.base.requirements].
| Constant name | POSIX macro | Definition or notes | 
| passive | AI_PASSIVE | Returned endpoints are intended for use as locally bound socket endpoints. | 
| canonical_name | AI_CANONNAME | Determine the canonical name of the host specified in the query. | 
| numeric_host | AI_NUMERICHOST | Host name should be treated as a numeric string defining an IPv4 or IPv6 address and no host name resolution should be attempted. | 
| numeric_service | AI_NUMERICSERV | Service name should be treated as a numeric string defining a port number and no service name resolution should be attempted. | 
| v4_mapped | AI_V4MAPPED | If the protocol is specified as an IPv6 protocol, return IPv4-mapped IPv6 addresses on finding no IPv6 addresses. | 
| all_matching | AI_ALL | If used with v4_mapped, return all matching IPv6 and IPv4 addresses. | 
| address_configured | AI_ADDRCONFIG | Only return IPv4 addresses if a non-loopback IPv4 address is configured for the system. Only return IPv6 addresses if a non-loopback IPv6 address is configured for the system. | 
Objects of type basic_resolver<InternetProtocol> are used to perform name resolution. Name resolution is the translation of a host name and service name into a sequence of endpoints, or the translation of an endpoint into its corresponding host name and service name.
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  template<class InternetProtocol>
  class basic_resolver : public resolver_base
  {
  public:
    // types:
    using executor_type = io_context::executor_type;
    using protocol_type = InternetProtocol;
    using endpoint_type = typename InternetProtocol::endpoint;
    using results_type = basic_resolver_results<InternetProtocol>;
    // [internet.resolver.cons], construct / copy / destroy:
    explicit basic_resolver(io_context& ctx);
    basic_resolver(const basic_resolver&) = delete;
    basic_resolver(basic_resolver&& rhs) noexcept;
    ~basic_resolver();
    basic_resolver& operator=(const basic_resolver&) = delete;
    basic_resolver& operator=(basic_resolver&& rhs);
    // [internet.resolver.ops], basic_resolver operations:
    executor_type get_executor() noexcept;
    void cancel();
    results_type resolve(string_view host_name, string_view service_name);
    results_type resolve(string_view host_name, string_view service_name,
                         error_code& ec);
    results_type resolve(string_view host_name, string_view service_name,
                         flags f);
    results_type resolve(string_view host_name, string_view service_name,
                         flags f, error_code& ec);
    template<class CompletionToken>
      DEDUCED async_resolve(string_view host_name, string_view service_name,
                            CompletionToken&& token);
    template<class CompletionToken>
      DEDUCED async_resolve(string_view host_name, string_view service_name,
                            flags f, CompletionToken&& token);
    results_type resolve(const protocol_type& protocol,
                         string_view host_name, string_view service_name);
    results_type resolve(const protocol_type& protocol,
                         string_view host_name, string_view service_name,
                         error_code& ec);
    results_type resolve(const protocol_type& protocol,
                         string_view host_name, string_view service_name,
                         flags f);
    results_type resolve(const protocol_type& protocol,
                         string_view host_name, string_view service_name,
                         flags f, error_code& ec);
    template<class CompletionToken>
      DEDUCED async_resolve(const protocol_type& protocol,
                            string_view host_name, string_view service_name,
                            CompletionToken&& token);
    template<class CompletionToken>
      DEDUCED async_resolve(const protocol_type& protocol,
                            string_view host_name, string_view service_name,
                            flags f, CompletionToken&& token);
    results_type resolve(const endpoint_type& e);
    results_type resolve(const endpoint_type& e, error_code& ec);
    template<class CompletionToken>
      DEDUCED async_resolve(const endpoint_type& e,
                            CompletionToken&& token);
  };
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
explicit basic_resolver(io_context& ctx);
Postconditions: get_executor() == ctx.get_executor().
basic_resolver(basic_resolver&& rhs) noexcept;
Effects: Move constructs an object of class basic_resolver<InternetProtocol> that refers to the state originally represented by rhs.
Postconditions: get_executor() == rhs.get_executor().
~basic_resolver();
Effects: Destroys the resolver, canceling all asynchronous operations associated with this resolver as if by calling cancel().
basic_resolver& operator=(basic_resolver&& rhs);
Effects: Cancels all outstanding asynchronous operations associated with *this as if by calling cancel(), then moves into *this the state originally represented by rhs.
Postconditions: get_executor() == rhs.get_executor().
Returns: *this.
executor_type get_executor() noexcept;
Returns: The associated executor.
void cancel();
Effects: Cancels all outstanding asynchronous resolve operations associated with *this. Completion handlers for canceled operations are passed an error code ec such that ec == errc::operation_canceled yields true.
Remarks: Does not block (C++ 2014 [defns.block]) the calling thread pending completion of the canceled operations.
results_type resolve(string_view host_name, string_view service_name);
results_type resolve(string_view host_name, string_view service_name,
                     error_code& ec);
Returns: resolve(host_name, service_name, resolver_base::flags(), ec).
results_type resolve(string_view host_name, string_view service_name,
                     flags f);
results_type resolve(string_view host_name, string_view service_name,
                     flags f, error_code& ec);
Effects: If host_name.data() != nullptr, let H be an ntbs constructed from host_name; otherwise, let H be nullptr. If service_name.data() != nullptr, let S be an ntbs constructed from service_name; otherwise, let S be nullptr. Resolves a host name and service name, as if by POSIX:
addrinfo hints; hints.ai_flags = static_cast<int>(f); hints.ai_family = AF_UNSPEC; hints.ai_socktype = endpoint_type().protocol().type(); hints.ai_protocol = endpoint_type().protocol().protocol(); hints.ai_addr = nullptr; hints.ai_addrlen = 0; hints.ai_canonname = nullptr; hints.ai_next = nullptr; addrinfo* result = nullptr; getaddrinfo(H, S, &hints, &result);
Returns: On success, a non-empty results object containing the results of the resolve operation. Otherwise results_type().
template<class CompletionToken>
  DEDUCED async_resolve(string_view host_name, string_view service_name,
                        CompletionToken&& token);
Returns:
async_resolve(host_name, service_name, resolver_base::flags(),
              forward<CompletionToken>(token))
template<class CompletionToken>
  DEDUCED async_resolve(string_view host_name, string_view service_name,
                        flags f, CompletionToken&& token);
Completion signature: void(error_code ec, results_type r).
Effects: If host_name.data() != nullptr, let H be an ntbs constructed from host_name; otherwise, let H be nullptr. If service_name.data() != nullptr, let S be an ntbs constructed from service_name; otherwise, let S be nullptr. Initiates an asynchronous operation to resolve a host name and service name, as if by POSIX:
addrinfo hints; hints.ai_flags = static_cast<int>(f); hints.ai_family = AF_UNSPEC; hints.ai_socktype = endpoint_type().protocol().type(); hints.ai_protocol = endpoint_type().protocol().protocol(); hints.ai_addr = nullptr; hints.ai_addrlen = 0; hints.ai_canonname = nullptr; hints.ai_next = nullptr; addrinfo* result = nullptr; getaddrinfo(H, S, &hints, &result);
On success, r is a non-empty results object containing the results of the resolve operation. Otherwise, r is results_type().
results_type resolve(const protocol_type& protocol,
                     string_view host_name, string_view service_name);
results_type resolve(const protocol_type& protocol,
                     string_view host_name, string_view service_name,
                     error_code& ec);
Returns: 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);
results_type resolve(const protocol_type& protocol,
                     string_view host_name, string_view service_name,
                     flags f, error_code& ec);
Effects: If host_name.data() != nullptr, let H be an ntbs constructed from host_name; otherwise, let H be nullptr. If service_name.data() != nullptr, let S be an ntbs constructed from service_name; otherwise, let S be nullptr. Resolves a host name and service name, as if by POSIX:
addrinfo hints; hints.ai_flags = static_cast<int>(f); hints.ai_family = protocol.family(); hints.ai_socktype = protocol.type(); hints.ai_protocol = protocol.protocol(); hints.ai_addr = nullptr; hints.ai_addrlen = 0; hints.ai_canonname = nullptr; hints.ai_next = nullptr; addrinfo* result = nullptr; getaddrinfo(H, S, &hints, &result);
Returns: On success, a non-empty results object containing the results of the resolve operation. Otherwise results_type().
template<class CompletionToken>
  DEDUCED async_resolve(const protocol_type& protocol,
                        string_view host_name, string_view service_name,
                        CompletionToken&& token);
Returns:
async_resolve(protocol, host_name, service_name, resolver_base::flags(),
              forward<CompletionToken>(token))
template<class CompletionToken>
  DEDUCED async_resolve(const protocol& protocol,
                        string_view host_name, string_view service_name,
                        flags f, CompletionToken&& token);
Completion signature: void(error_code ec, results_type r).
Effects: If host_name.data() != nullptr, let H be an ntbs constructed from host_name; otherwise, let H be nullptr. If service_name.data() != nullptr, let S be an ntbs constructed from service_name; otherwise, let S be nullptr. Initiates an asynchronous operation to resolve a host name and service name, as if by POSIX:
addrinfo hints; hints.ai_flags = static_cast<int>(f); hints.ai_family = protocol.family(); hints.ai_socktype = protocol.type(); hints.ai_protocol = protocol.protocol(); hints.ai_addr = nullptr; hints.ai_addrlen = 0; hints.ai_canonname = nullptr; hints.ai_next = nullptr; addrinfo* result = nullptr; getaddrinfo(H, S, &hints, &result);
On success, r is a non-empty results object containing the results of the resolve operation. Otherwise, r is results_type().
results_type resolve(const endpoint_type& e);
results_type resolve(const endpoint_type& e, error_code& ec);
Effects: Let S1 and S2 be implementation-defined values that are sufficiently large to hold the host name and service name respectively. Resolves an endpoint as if by POSIX:
char host_name[S1];
char service_name[S2];
int flags = 0;
if (endpoint_type().protocol().type() == SOCK_DGRAM)
  flags |= NI_DGRAM;
int result = getnameinfo((const sockaddr*)e.data(), e.size(),
                         host_name, S1,
                         service_name, S2,
                         flags);
if (result != 0){
  flags |= NI_NUMERICSERV;
  result = getnameinfo((const sockaddr*)e.data(), e.size(),
                       host_name, S1,
                       service_name, S2,
                       flags);
}
Returns: On success, a results object with size() == 1 containing the results of the resolve operation. Otherwise results_type().
template<class CompletionToken>
  DEDUCED async_resolve(const endpoint_type& e,
                        CompletionToken&& token);
Completion signature: void(error_code ec, results_type r).
Effects: Let S1 and S2 be implementation-defined values that are sufficiently large to hold the host name and service name respectively. Initiates an asynchronous operation to resolve an endpoint as if by POSIX:
char host_name[S1];
char service_name[S2];
int flags = 0;
if (endpoint_type().protocol().type() == SOCK_DGRAM)
  flags |= NI_DGRAM;
int result = getnameinfo((const sockaddr*)e.data(), e.size(),
                         host_name, S1,
                         service_name, S2,
                         flags);
if (result != 0){
  flags |= NI_NUMERICSERV;
  result = getnameinfo((const sockaddr*)e.data(), e.size(),
                       host_name, S1,
                       service_name, S2,
                       flags);
}
On success, r is a results object with size() == 1 containing the results of the resolve operation; otherwise, r is results_type().
string host_name();
string host_name(error_code& ec);
template<class Allocator>
  basic_string<char, char_traits<char>, Allocator>
    host_name(const Allocator& a);
template<class Allocator>
  basic_string<char, char_traits<char>, Allocator>
    host_name(const Allocator& a, error_code& ec);
Returns: The standard host name for the current machine, determined as if by POSIX gethostname.
Remarks: In the last two overloads, ill-formed unless allocator_traits<Allocator>::value_type is char.
The class tcp encapsulates the types and flags necessary for TCP sockets.
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  class tcp
  {
  public:
    // types:
    using endpoint = basic_endpoint<tcp>;
    using resolver = basic_resolver<tcp>;
    using socket = basic_stream_socket<tcp>;
    using acceptor = basic_socket_acceptor<tcp>;
    using iostream = basic_socket_iostream<tcp>;
    class no_delay;
    // static members:
    static constexpr tcp v4() noexcept;
    static constexpr tcp v6() noexcept;
    tcp() = delete;
  };
  // [internet.tcp.comparisons], tcp comparisons:
  constexpr bool operator==(const tcp& a, const tcp& b) noexcept;
  constexpr bool operator!=(const tcp& a, const tcp& b) noexcept;
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
Extensible implementations provide the following member functions:
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  class tcp
  {
  public:
    constexpr int family() const noexcept;
    constexpr int type() const noexcept;
    constexpr int protocol() const noexcept;
    // remainder unchanged
  };
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
The return values for these member functions are listed in Table [tab:internet.tcp.requirements].
| value | family() | type() | protocol() | 
| tcp::v4() | AF_INET | SOCK_STREAM | IPPROTO_TCP | 
| tcp::v6() | AF_INET6 | SOCK_STREAM | IPPROTO_TCP | 
[ Note: The constants AF_INET, AF_INET6 and SOCK_STREAM are defined in the POSIX <sys/socket.h> header. The constant IPPROTO_TCP is defined in the POSIX <netinet/in.h> header. — end note ]
constexpr bool operator==(const tcp& a, const tcp& b) noexcept;
Returns: A boolean indicating whether two objects of class tcp are equal, such that the expression tcp::v4() == tcp::v4() is true, the expression tcp::v6() == tcp::v6() is true, and the expression tcp::v4() == tcp::v6() is false.
constexpr bool operator!=(const tcp& a, const tcp& b) noexcept;
Returns: !(a == b).
The class udp encapsulates the types and flags necessary for UDP sockets.
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  class udp
  {
  public:
    // types:
    using endpoint = basic_endpoint<udp>;
    using resolver = basic_resolver<udp>;
    using socket = basic_datagram_socket<udp>;
    // static members:
    static constexpr udp v4() noexcept;
    static constexpr udp v6() noexcept;
    udp() = delete;
  };
  // [internet.udp.comparisons], udp comparisons:
  constexpr bool operator==(const udp& a, const udp& b) noexcept;
  constexpr bool operator!=(const udp& a, const udp& b) noexcept;
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
Extensible implementations provide the following member functions:
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
  class udp
  {
  public:
    constexpr int family() const noexcept;
    constexpr int type() const noexcept;
    constexpr int protocol() const noexcept;
    // remainder unchanged
  };
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
The return values for these member functions are listed in Table [tab:internet.udp.requirements].
| value | family() | type() | protocol() | 
| udp::v4() | AF_INET | SOCK_DGRAM | IPPROTO_UDP | 
| udp::v6() | AF_INET6 | SOCK_DGRAM | IPPROTO_UDP | 
[ Note: The constants AF_INET, AF_INET6 and SOCK_DGRAM are defined in the POSIX <sys/socket.h> header. The constant IPPROTO_UDP is defined in the POSIX <netinet/in.h> header. — end note ]
constexpr bool operator==(const udp& a, const udp& b) noexcept;
Returns: A boolean indicating whether two objects of class udp are equal, such that the expression udp::v4() == udp::v4() is true, the expression udp::v6() == udp::v6() is true, and the expression udp::v4() == udp::v6() is false.
constexpr bool operator!=(const udp& a, const udp& b) noexcept;
Returns: !(a == b).
In Table [tab:internet.socket.opt.requirements], let C denote a socket option class; let L identify the POSIX macro to be passed as the level argument to POSIX setsockopt and getsockopt; let N identify the POSIX macro to be passed as the option_name argument to POSIX setsockopt and getsockopt; let T identify the type of the value whose address will be passed as the option_value argument to POSIX setsockopt and getsockopt; let p denote a (possibly const) value of a type meeting the protocol ([socket.reqmts.protocol]) requirements, as passed to the socket option's level and name member functions; and let F be the value of p.family().
| C | L | N | T | Requirements, | 
| definition or notes | ||||
|  
ip::tcp:: no_delay  | IPPROTO_TCP | TCP_NODELAY | int | Satisfies the BooleanSocketOption ([socket.reqmts.opt.bool]) type requirements. Determines whether a TCP socket will avoid coalescing of small segments. [ Note: That is, setting this option disables the Nagle algorithm. — end note ] | 
| ip::v6_only | IPPROTO_IPV6 | IPV6_V6ONLY | int | Satisfies the BooleanSocketOption ([socket.reqmts.opt.bool]) type requirements. Determines whether a socket created for an IPv6 protocol is restricted to IPv6 communications only. Implementations are not required to support setting the v6_only option to false, and the initial value of the v6_only option for a socket is implementation-defined. [ Note: As not all operating systems support dual stack IP networking. Some operating systems that do provide dual stack support offer a configuration option to disable it or to set the initial value of the v6_only socket option. — end note ] | 
| ip::unicast:: hops | IPPROTO_IPV6 if F == AF_INET6, otherwise IPPROTO_IP | IPV6_UNICAST_HOPS if F == AF_INET6, otherwise IP_TTL | int | Satisfies the IntegerSocketOption ([socket.reqmts.opt.int]) type requirements. Specifies the default number of hops (also known as time-to-live or TTL) on outbound datagrams. The constructor and assignment operator for the ip::unicast::hops class throw out_of_range if the int argument is not in the range [0, 255]. | 
| ip::multicast:: join_group | IPPROTO_IPV6 if F == AF_INET6, otherwise IPPROTO_IP | IPV6_JOIN_GROUP if F == AF_INET6, otherwise IP_ADD_MEMBERSHIP | ipv6_mreq if F == AF_INET6, otherwise ip_mreq | Satisfies the MulticastGroupSocketOption ([internet.reqmts.opt.mcast]) type requirements. Requests that the socket join the specified multicast group. | 
| ip::multicast:: leave_group | IPPROTO_IPV6 if F == AF_INET6, otherwise IPPROTO_IP | IPV6_LEAVE_GROUP if F == AF_INET6, otherwise IP_DROP_MEMBERSHIP | ipv6_mreq if F == AF_INET6, otherwise ip_mreq | Satisfies the MulticastGroupSocketOption ([internet.reqmts.opt.mcast]) type requirements. Requests that the socket leave the specified multicast group. | 
|  ip::multicast::
outbound_interface ([internet.multicast.outbound])  | IPPROTO_IPV6 if F == AF_INET6, otherwise IPPROTO_IP | IPV6_MULTICAST_IF if F == AF_INET6, otherwise IP_MULTICAST_IF | unsigned int if F == AF_INET6, otherwise in_addr | Specifies the network interface to use for outgoing multicast datagrams. | 
| ip::multicast:: hops | IPPROTO_IPV6 if F == AF_INET6, otherwise IPPROTO_IP | IPV6_MULTICAST_HOPS if F == AF_INET6, otherwise IP_MULTICAST_TTL | int | Satisfies the IntegerSocketOption ([socket.reqmts.opt.int]) type requirements. Specifies the default number of hops (also known as time-to-live or TTL) on outbound datagrams. The constructor and assignment operator for the ip::multicast::hops class throw out_of_range if the int argument is not in the range [0, 255]. | 
| ip::multicast:: enable_loopback | IPPROTO_IPV6 if F == AF_INET6, otherwise IPPROTO_IP | IPV6_MULTICAST_LOOP if F == AF_INET6, otherwise IP_MULTICAST_LOOP | int | Satisfies the BooleanSocketOption ([socket.reqmts.opt.bool]) type requirements. Determines whether multicast datagrams are delivered back to the local application. | 
The outbound_interface class represents a socket option that specifies the network interface to use for outgoing multicast datagrams.
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
namespace multicast {
  class outbound_interface
  {
  public:
    // constructors:
    explicit outbound_interface(const address_v4& network_interface) noexcept;
    explicit outbound_interface(unsigned int network_interface) noexcept;
  };
} // namespace multicast
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
outbound_interface satisfies the requirements for Destructible (C++ 2014 [destructible]), CopyConstructible (C++ 2014 [copyconstructible]), CopyAssignable (C++ 2014 [copyassignable]), and SettableSocketOption ([socket.reqmts.settablesocketoption]).
Extensible implementations provide the following member functions:
namespace std {
namespace experimental {
namespace net {
inline namespace v1 {
namespace ip {
namespace multicast {
  class outbound_interface
  {
  public:
    template<class Protocol> int level(const Protocol& p) const noexcept;
    template<class Protocol> int name(const Protocol& p) const noexcept;
    template<class Protocol> const void* data(const Protocol& p) const noexcept;
    template<class Protocol> size_t size(const Protocol& p) const noexcept;
    // remainder unchanged
  private:
      in_addr v4_value_; // exposition only
      unsigned int v6_value_; // exposition only
  };
} // namespace multicast
} // namespace ip
} // inline namespace v1
} // namespace net
} // namespace experimental
} // namespace std
explicit outbound_interface(const address_v4& network_interface) noexcept;
Effects: For extensible implementations, v4_value_ is initialized to correspond to the IPv4 address network_interface, and v6_value_ is zero-initialized.
explicit outbound_interface(unsigned int network_interface) noexcept;
Effects: For extensible implementations, v6_value_ is initialized to network_interface, and v4_value_ is zero-initialized.
template<class Protocol> int level(const Protocol& p) const noexcept;
Returns: IPPROTO_IPV6 if p.family() == AF_INET6, otherwise IPPROTO_IP.
template<class Protocol> int name(const Protocol& p) const noexcept;
Returns: IPV6_MULTICAST_IF if p.family() == AF_INET6, otherwise IP_MULTICAST_IF.
template<class Protocol> const void* data(const Protocol& p) const noexcept;
Returns: addressof(v6_value_) if p.family() == AF_INET6, otherwise addressof(v4_value_).
template<class Protocol> size_t size(const Protocol& p) const noexcept;
Returns: sizeof(v6_value_) if p.family() == AF_INET6, otherwise sizeof(v4_value_).