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