libs/corosio/include/boost/corosio/ipv6_address.hpp

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