21 Internet protocol [internet]

21.1 Header <experimental/internet> synopsis [internet.synop]

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

21.2 Requirements [internet.reqmts]

21.2.1 Internet protocol requirements [internet.reqmts.protocol]

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.

Table 35 — InternetProtocol requirements
expressionreturn typeassertion/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).

21.2.2 Multicast group socket options [internet.reqmts.opt.mcast]

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.

Table 36 — MulticastGroupSocketOption requirements
expressiontypeassertion/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_).

21.3 Error codes [internet.resolver.err]

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()).

21.4 Class ip::address [internet.address]

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]).

21.4.1 ip::address constructors [internet.address.cons]

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.

21.4.2 ip::address assignment [internet.address.assign]

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

21.4.3 ip::address members [internet.address.members]

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).

21.4.4 ip::address comparisons [internet.address.comparisons]

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

Returns:

  • if a.is_v4() != b.is_v4(), false;

  • if a.is_v4(), the result of a.v4_ == b.v4_;

  • otherwise, the result of a.v6_ == b.v6_.

constexpr bool operator!=(const address& a, const address& b) noexcept;

Returns: !(a == b).

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

Returns:

  • if a.is_v4() && !b.is_v4(), true;

  • if !a.is_v4() && b.is_v4(), false;

  • if a.is_v4(), the result of a.v4_ < b.v4_;

  • otherwise, the result of a.v6_ < b.v6_.

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).

21.4.5 ip::address creation [internet.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;

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.

21.4.6 ip::address I/O [internet.address.io]

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().

21.5 Class ip::address_v4 [internet.address.v4]

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]).

21.5.1 Struct ip::address_v4::bytes_type [internet.address.v4.bytes]

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.

21.5.2 ip::address_v4 constructors [internet.address.v4.cons]

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:

21.5.3 ip::address_v4 members [internet.address.v4.members]

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).

21.5.4 ip::address_v4 static members [internet.address.v4.static]

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).

21.5.5 ip::address_v4 comparisons [internet.address.v4.comparisons]

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).

21.5.6 ip::address_v4 creation [internet.address.v4.creation]

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().

Error conditions:

  • errc::invalid_argument — if str is not a valid textual representation of an IPv4 address.

21.5.7 ip::address_v4 I/O [internet.address.v4.io]

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().

21.6 Class ip::address_v6 [internet.address.v6]

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 ]

21.6.1 Struct ip::address_v6::bytes_type [internet.address.v6.bytes]

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.

21.6.2 ip::address_v6 constructors [internet.address.v6.cons]

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.

21.6.3 ip::address_v6 members [internet.address.v6.members]

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).

21.6.4 ip::address_v6 static members [internet.address.v6.static]

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.

21.6.5 ip::address_v6 comparisons [internet.address.v6.comparisons]

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).

21.6.6 ip::address_v6 creation [internet.address.v6.creation]

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().

Error conditions:

  • errc::invalid_argument — if str is not a valid textual representation of an IPv6 address.

21.6.7 ip::address_v6 I/O [internet.address.v6.io]

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().

21.7 Class ip::bad_address_cast [internet.bad.address.cast]

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.

Postconditions: what() returns an implementation-defined ntbs.

21.8 Hash support [internet.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>;

Requires: the template specializations shall meet the requirements of class template hash (C++ 2014 [unord.hash]).

21.9 Class template ip::basic_address_iterator specializations [internet.address.iter]

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.

21.10 Class template ip::basic_address_range specializations [internet.address.range]

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.

21.11 Class template ip::network_v4 [internet.network.v4]

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]).

21.11.1 ip::network_v4 constructors [internet.network.v4.cons]

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.

21.11.2 ip::network_v4 members [internet.network.v4.members]

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()).

21.11.3 ip::network_v4 comparisons [internet.network.v4.comparisons]

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).

21.11.4 ip::network_v4 creation [internet.network.v4.creation]

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.

Error conditions:

  • errc::invalid_argument — if str is not a valid textual representation of an IPv4 address and prefix length.

21.11.5 ip::network_v4 I/O [internet.network.v4.io]

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().

21.12 Class template ip::network_v6 [internet.network.v6]

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]).

21.12.1 ip::network_v6 constructors [internet.network.v6.cons]

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.

21.12.2 ip::network_v6 members [internet.network.v6.members]

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().

21.12.3 ip::network_v6 comparisons [internet.network.v6.comparisons]

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).

21.12.4 ip::network_v6 creation [internet.network.v6.creation]

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.

Error conditions:

  • errc::invalid_argument — if str is not a valid textual representation of an IPv6 address and prefix length.

21.12.5 ip::network_v6 I/O [internet.network.v6.io]

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().

21.13 Class template ip::basic_endpoint [internet.endpoint]

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

21.13.1 ip::basic_endpoint constructors [internet.endpoint.cons]

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().

Postconditions:

  • If proto == protocol_type::v6(), this->address() == ip::address_v6(); otherwise,
    this->address() == ip::address_v4().

  • port() == port_num.

constexpr basic_endpoint(const ip::address& addr, port_type port_num) noexcept;

Postconditions: this->address() == addr and port() == port_num.

21.13.2 ip::basic_endpoint members [internet.endpoint.members]

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.

21.13.3 ip::basic_endpoint comparisons [internet.endpoint.comparisons]

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).

21.13.4 ip::basic_endpoint I/O [internet.endpoint.io]

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 ]

21.13.5 ip::basic_endpoint members (extensible implementations) [internet.endpoint.extensible]

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

Remarks: length_error if either of the following conditions is true:

  • protocol().family() == AF_INET6 && s != sizeof(sockaddr_in6),

  • protocol().family() == AF_INET4 && s != sizeof(sockaddr_in).

constexpr size_t capacity() const noexcept;

Returns: sizeof(data_).

21.14 Class template ip::basic_resolver_entry [internet.resolver.entry]

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

21.14.1 ip::basic_resolver_entry constructors [internet.resolver.entry.cons]

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

Postconditions:

21.14.2 ip::basic_resolver_entry members [internet.resolver.entry.members]

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.

21.14.3 op::basic_resolver_entry comparisons [internet.resolver.entry.comparisons]

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).

21.15 Class template ip::basic_resolver_results [internet.resolver.results]

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.

21.15.1 ip::basic_resolver_results constructors [internet.resolver.results.cons]

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.

21.15.2 ip::basic_resolver_results assignment [internet.resolver.results.assign]

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.

21.15.3 ip::basic_resolver_results size [internet.resolver.results.size]

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.

21.15.4 ip::basic_resolver_results element access [internet.resolver.results.access]

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.

21.15.5 ip::basic_resolver_results swap [internet.resolver.results.swap]

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.

21.15.6 ip::basic_resolver_results comparisons [internet.resolver.results.comparisons]

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).

21.16 Class ip::resolver_base [internet.resolver.base]

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].

Table 37 — Resolver flags
Constant namePOSIX macroDefinition 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.

21.17 Class template ip::basic_resolver [internet.resolver]

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

21.17.1 ip::basic_resolver constructors [internet.resolver.cons]

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().

21.17.2 ip::basic_resolver destructor [internet.resolver.dtor]

~basic_resolver();

Effects: Destroys the resolver, canceling all asynchronous operations associated with this resolver as if by calling cancel().

21.17.3 ip::basic_resolver assignment [internet.resolver.assign]

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.

21.17.4 ip::basic_resolver operations [internet.resolver.ops]

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().

21.18 Host name functions [internet.host.name]

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.

21.19 Class ip::tcp [internet.tcp]

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

The tcp class meets the requirements for an InternetProtocol ([internet.reqmts.protocol]).

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].

Table 38 — Behavior of extensible ip::tcp implementations
valuefamily()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 ]

21.19.1 ip::tcp comparisons [internet.tcp.comparisons]

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).

21.20 Class ip::udp [internet.udp]

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

The udp class meets the requirements for an InternetProtocol ([internet.reqmts.protocol]).

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].

Table 39 — Behavior of extensible ip::udp implementations
valuefamily()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 ]

21.20.1 ip::udp comparisons [internet.udp.comparisons]

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).

21.21 Internet socket options [internet.socket.opt]

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().

Table 40 — Internet socket options
CLNTRequirements,
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.

21.21.1 Class ip::multicast::outbound_interface [internet.multicast.outbound]

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_).