include/boost/corosio/ipv6_address.hpp

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