LCOV - code coverage report
Current view: top level - corosio - ipv6_address.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 9 9
Test Date: 2026-02-27 19:39:18 Functions: 100.0 % 5 5

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2026 Vinnie Falco (vinnie.falco@gmail.com)
       3                 : //
       4                 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       5                 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       6                 : //
       7                 : // Official repository: https://github.com/cppalliance/corosio
       8                 : //
       9                 : 
      10                 : #ifndef BOOST_COROSIO_IPV6_ADDRESS_HPP
      11                 : #define BOOST_COROSIO_IPV6_ADDRESS_HPP
      12                 : 
      13                 : #include <boost/corosio/detail/config.hpp>
      14                 : 
      15                 : #include <array>
      16                 : #include <iosfwd>
      17                 : #include <string>
      18                 : #include <string_view>
      19                 : #include <system_error>
      20                 : 
      21                 : namespace boost::corosio {
      22                 : 
      23                 : class ipv4_address;
      24                 : 
      25                 : /** An IP version 6 style address.
      26                 : 
      27                 :     Objects of this type are used to construct,
      28                 :     parse, and manipulate IP version 6 addresses.
      29                 : 
      30                 :     @par BNF
      31                 :     @code
      32                 :     IPv6address =                            6( h16 ":" ) ls32
      33                 :                 /                       "::" 5( h16 ":" ) ls32
      34                 :                 / [               h16 ] "::" 4( h16 ":" ) ls32
      35                 :                 / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
      36                 :                 / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
      37                 :                 / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
      38                 :                 / [ *4( h16 ":" ) h16 ] "::"              ls32
      39                 :                 / [ *5( h16 ":" ) h16 ] "::"              h16
      40                 :                 / [ *6( h16 ":" ) h16 ] "::"
      41                 : 
      42                 :     ls32        = ( h16 ":" h16 ) / IPv4address
      43                 :                 ; least-significant 32 bits of address
      44                 : 
      45                 :     h16         = 1*4HEXDIG
      46                 :                 ; 16 bits of address represented in hexadecimal
      47                 :     @endcode
      48                 : 
      49                 :     @par Specification
      50                 :     @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
      51                 :         >IP Version 6 Addressing Architecture (rfc4291)</a>
      52                 :     @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
      53                 :         >3.2.2. Host (rfc3986)</a>
      54                 : 
      55                 :     @see
      56                 :         @ref ipv4_address,
      57                 :         @ref parse_ipv6_address.
      58                 : */
      59                 : class BOOST_COROSIO_DECL ipv6_address
      60                 : {
      61                 :     std::array<unsigned char, 16> addr_{};
      62                 : 
      63                 : public:
      64                 :     /** The number of characters in the longest possible IPv6 string.
      65                 : 
      66                 :         The longest IPv6 address is:
      67                 :         @code
      68                 :         ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
      69                 :         @endcode
      70                 :         or with IPv4-mapped:
      71                 :         @code
      72                 :         ::ffff:255.255.255.255
      73                 :         @endcode
      74                 :     */
      75                 :     static constexpr std::size_t max_str_len = 49;
      76                 : 
      77                 :     /** The type used to represent an address as an array of bytes.
      78                 : 
      79                 :         Octets are stored in network byte order.
      80                 :     */
      81                 :     using bytes_type = std::array<unsigned char, 16>;
      82                 : 
      83                 :     /** Default constructor.
      84                 : 
      85                 :         Constructs the unspecified address (::).
      86                 : 
      87                 :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.2"
      88                 :             >2.5.2. The Unspecified Address</a>
      89                 : 
      90                 :         @see
      91                 :             @ref is_unspecified
      92                 :     */
      93 HIT      275670 :     ipv6_address() = default;
      94                 : 
      95                 :     /** Copy constructor.
      96                 :     */
      97                 :     ipv6_address(ipv6_address const&) = default;
      98                 : 
      99                 :     /** Copy assignment.
     100                 : 
     101                 :         @return A reference to this object.
     102                 :     */
     103                 :     ipv6_address& operator=(ipv6_address const&) = default;
     104                 : 
     105                 :     /** Construct from an array of bytes.
     106                 : 
     107                 :         This function constructs an address
     108                 :         from the array in `bytes`, which is
     109                 :         interpreted in big-endian.
     110                 : 
     111                 :         @param bytes The value to construct from.
     112                 :     */
     113                 :     explicit ipv6_address(bytes_type const& bytes) noexcept;
     114                 : 
     115                 :     /** Construct from an IPv4 address.
     116                 : 
     117                 :         This function constructs an IPv6 address
     118                 :         from the IPv4 address `addr`. The resulting
     119                 :         address is an IPv4-Mapped IPv6 Address.
     120                 : 
     121                 :         @param addr The address to construct from.
     122                 : 
     123                 :         @par Specification
     124                 :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2"
     125                 :             >2.5.5.2. IPv4-Mapped IPv6 Address (rfc4291)</a>
     126                 :     */
     127                 :     explicit ipv6_address(ipv4_address const& addr) noexcept;
     128                 : 
     129                 :     /** Construct from a string.
     130                 : 
     131                 :         This function constructs an address from
     132                 :         the string `s`, which must contain a valid
     133                 :         IPv6 address string or else an exception
     134                 :         is thrown.
     135                 : 
     136                 :         @note For a non-throwing parse function,
     137                 :         use @ref parse_ipv6_address.
     138                 : 
     139                 :         @par Exception Safety
     140                 :         Exceptions thrown on invalid input.
     141                 : 
     142                 :         @throw std::invalid_argument
     143                 :         The input failed to parse correctly.
     144                 : 
     145                 :         @param s The string to parse.
     146                 : 
     147                 :         @par Specification
     148                 :         @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
     149                 :             >3.2.2. Host (rfc3986)</a>
     150                 : 
     151                 :         @see
     152                 :             @ref parse_ipv6_address.
     153                 :     */
     154                 :     explicit ipv6_address(std::string_view s);
     155                 : 
     156                 :     /** Return the address as bytes, in network byte order.
     157                 : 
     158                 :         @return The address as an array of bytes.
     159                 :     */
     160              24 :     bytes_type to_bytes() const noexcept
     161                 :     {
     162              24 :         return addr_;
     163                 :     }
     164                 : 
     165                 :     /** Return the address as a string.
     166                 : 
     167                 :         The returned string does not
     168                 :         contain surrounding square brackets.
     169                 : 
     170                 :         @par Example
     171                 :         @code
     172                 :         ipv6_address::bytes_type b = {{
     173                 :                 0, 1, 0, 2, 0, 3, 0, 4,
     174                 :                 0, 5, 0, 6, 0, 7, 0, 8 }};
     175                 :         ipv6_address a(b);
     176                 :         assert(a.to_string() == "1:2:3:4:5:6:7:8");
     177                 :         @endcode
     178                 : 
     179                 :         @return The address as a string.
     180                 : 
     181                 :         @par Specification
     182                 :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.2">
     183                 :             2.2. Text Representation of Addresses (rfc4291)</a>
     184                 :     */
     185                 :     std::string to_string() const;
     186                 : 
     187                 :     /** Write a string representing the address to a buffer.
     188                 : 
     189                 :         The resulting buffer is not null-terminated.
     190                 : 
     191                 :         @throw std::length_error `dest_size < ipv6_address::max_str_len`
     192                 : 
     193                 :         @return The formatted string view.
     194                 : 
     195                 :         @param dest The buffer in which to write,
     196                 :         which must have at least `dest_size` space.
     197                 : 
     198                 :         @param dest_size The size of the output buffer.
     199                 :     */
     200                 :     std::string_view to_buffer(char* dest, std::size_t dest_size) const;
     201                 : 
     202                 :     /** Return true if the address is unspecified.
     203                 : 
     204                 :         The address 0:0:0:0:0:0:0:0 is called the
     205                 :         unspecified address. It indicates the
     206                 :         absence of an address.
     207                 : 
     208                 :         @return `true` if the address is unspecified.
     209                 : 
     210                 :         @par Specification
     211                 :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.2">
     212                 :             2.5.2. The Unspecified Address (rfc4291)</a>
     213                 :     */
     214                 :     bool is_unspecified() const noexcept;
     215                 : 
     216                 :     /** Return true if the address is a loopback address.
     217                 : 
     218                 :         The unicast address 0:0:0:0:0:0:0:1 is called
     219                 :         the loopback address. It may be used by a node
     220                 :         to send an IPv6 packet to itself.
     221                 : 
     222                 :         @return `true` if the address is a loopback address.
     223                 : 
     224                 :         @par Specification
     225                 :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.3">
     226                 :             2.5.3. The Loopback Address (rfc4291)</a>
     227                 :     */
     228                 :     bool is_loopback() const noexcept;
     229                 : 
     230                 :     /** Return true if the address is a mapped IPv4 address.
     231                 : 
     232                 :         This address type is used to represent the
     233                 :         addresses of IPv4 nodes as IPv6 addresses.
     234                 : 
     235                 :         @return `true` if the address is a mapped IPv4 address.
     236                 : 
     237                 :         @par Specification
     238                 :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2">
     239                 :             2.5.5.2. IPv4-Mapped IPv6 Address (rfc4291)</a>
     240                 :     */
     241                 :     bool is_v4_mapped() const noexcept;
     242                 : 
     243                 :     /** Return true if two addresses are equal.
     244                 : 
     245                 :         @return `true` if the addresses are equal.
     246                 :     */
     247                 :     friend bool
     248              16 :     operator==(ipv6_address const& a1, ipv6_address const& a2) noexcept
     249                 :     {
     250              16 :         return a1.addr_ == a2.addr_;
     251                 :     }
     252                 : 
     253                 :     /** Return true if two addresses are not equal.
     254                 : 
     255                 :         @return `true` if the addresses are not equal.
     256                 :     */
     257                 :     friend bool
     258               2 :     operator!=(ipv6_address const& a1, ipv6_address const& a2) noexcept
     259                 :     {
     260               2 :         return a1.addr_ != a2.addr_;
     261                 :     }
     262                 : 
     263                 :     /** Return an address object that represents the unspecified address.
     264                 : 
     265                 :         The address 0:0:0:0:0:0:0:0 (::) may be used to bind a socket
     266                 :         to all available interfaces.
     267                 : 
     268                 :         @return The unspecified address (::).
     269                 :     */
     270               6 :     static ipv6_address any() noexcept
     271                 :     {
     272               6 :         return ipv6_address();
     273                 :     }
     274                 : 
     275                 :     /** Return an address object that represents the loopback address.
     276                 : 
     277                 :         The unicast address 0:0:0:0:0:0:0:1 is called
     278                 :         the loopback address. It may be used by a node
     279                 :         to send an IPv6 packet to itself.
     280                 : 
     281                 :         @par Specification
     282                 :         @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.3">
     283                 :             2.5.3. The Loopback Address (rfc4291)</a>
     284                 : 
     285                 :         @return The loopback address (::1).
     286                 :     */
     287                 :     static ipv6_address loopback() noexcept;
     288                 : 
     289                 :     /** Format the address to an output stream.
     290                 : 
     291                 :         This function writes the address to an
     292                 :         output stream using standard notation.
     293                 : 
     294                 :         @return The output stream, for chaining.
     295                 : 
     296                 :         @param os The output stream to write to.
     297                 : 
     298                 :         @param addr The address to write.
     299                 :     */
     300                 :     friend BOOST_COROSIO_DECL std::ostream&
     301                 :     operator<<(std::ostream& os, ipv6_address const& addr);
     302                 : 
     303                 : private:
     304                 :     std::size_t print_impl(char* dest) const noexcept;
     305                 : };
     306                 : 
     307                 : /** Parse a string containing an IPv6 address.
     308                 : 
     309                 :     This function attempts to parse the string
     310                 :     as an IPv6 address and returns an error code
     311                 :     if the string does not contain a valid IPv6 address.
     312                 : 
     313                 :     @par Exception Safety
     314                 :     Throws nothing.
     315                 : 
     316                 :     @return An error code (empty on success).
     317                 : 
     318                 :     @param s The string to parse.
     319                 :     @param addr The address to store the result.
     320                 : */
     321                 : [[nodiscard]] BOOST_COROSIO_DECL std::error_code
     322                 : parse_ipv6_address(std::string_view s, ipv6_address& addr) noexcept;
     323                 : 
     324                 : } // namespace boost::corosio
     325                 : 
     326                 : #endif
        

Generated by: LCOV version 2.3