1  
//
1  
//
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3  
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
3  
// Copyright (c) 2022 Alan de Freitas (alandefreitas@gmail.com)
4  
//
4  
//
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
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)
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  
//
7  
//
8  
// Official repository: https://github.com/boostorg/url
8  
// Official repository: https://github.com/boostorg/url
9  
//
9  
//
10  

10  

11  
#ifndef BOOST_URL_IPV6_ADDRESS_HPP
11  
#ifndef BOOST_URL_IPV6_ADDRESS_HPP
12  
#define BOOST_URL_IPV6_ADDRESS_HPP
12  
#define BOOST_URL_IPV6_ADDRESS_HPP
13  

13  

14  
#include <boost/url/detail/config.hpp>
14  
#include <boost/url/detail/config.hpp>
15  
#include <boost/url/error.hpp>
15  
#include <boost/url/error.hpp>
16  
#include <boost/url/error_types.hpp>
16  
#include <boost/url/error_types.hpp>
17  
#include <boost/core/detail/string_view.hpp>
17  
#include <boost/core/detail/string_view.hpp>
18  
#include <boost/url/grammar/string_token.hpp>
18  
#include <boost/url/grammar/string_token.hpp>
19  
#include <array>
19  
#include <array>
20  
#include <cstdint>
20  
#include <cstdint>
21  
#include <iosfwd>
21  
#include <iosfwd>
22  

22  

23  
namespace boost {
23  
namespace boost {
24  
namespace urls {
24  
namespace urls {
25  

25  

26  
class ipv4_address;
26  
class ipv4_address;
27  

27  

28  
/** An IP version 6 style address.
28  
/** An IP version 6 style address.
29  

29  

30  
    Objects of this type are used to construct,
30  
    Objects of this type are used to construct,
31  
    parse, and manipulate IP version 6 addresses.
31  
    parse, and manipulate IP version 6 addresses.
32  

32  

33  
    @par BNF
33  
    @par BNF
34  
    @code
34  
    @code
35  
    IPv6address =                            6( h16 ":" ) ls32
35  
    IPv6address =                            6( h16 ":" ) ls32
36  
                /                       "::" 5( h16 ":" ) ls32
36  
                /                       "::" 5( h16 ":" ) ls32
37  
                / [               h16 ] "::" 4( h16 ":" ) ls32
37  
                / [               h16 ] "::" 4( h16 ":" ) ls32
38  
                / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
38  
                / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
39  
                / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
39  
                / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
40  
                / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
40  
                / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
41  
                / [ *4( h16 ":" ) h16 ] "::"              ls32
41  
                / [ *4( h16 ":" ) h16 ] "::"              ls32
42  
                / [ *5( h16 ":" ) h16 ] "::"              h16
42  
                / [ *5( h16 ":" ) h16 ] "::"              h16
43  
                / [ *6( h16 ":" ) h16 ] "::"
43  
                / [ *6( h16 ":" ) h16 ] "::"
44  

44  

45  
    ls32        = ( h16 ":" h16 ) / IPv4address
45  
    ls32        = ( h16 ":" h16 ) / IPv4address
46  
                ; least-significant 32 bits of address
46  
                ; least-significant 32 bits of address
47  

47  

48  
    h16         = 1*4HEXDIG
48  
    h16         = 1*4HEXDIG
49  
                ; 16 bits of address represented in hexadecimal
49  
                ; 16 bits of address represented in hexadecimal
50  
    @endcode
50  
    @endcode
51  

51  

52  
    @par Specification
52  
    @par Specification
53  
    @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
53  
    @li <a href="https://datatracker.ietf.org/doc/html/rfc4291"
54  
        >IP Version 6 Addressing Architecture (rfc4291)</a>
54  
        >IP Version 6 Addressing Architecture (rfc4291)</a>
55  
    @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
55  
    @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
56  
        >3.2.2. Host (rfc3986)</a>
56  
        >3.2.2. Host (rfc3986)</a>
57  

57  

58  
    @see
58  
    @see
59  
        @ref ipv4_address,
59  
        @ref ipv4_address,
60  
        @ref parse_ipv6_address.
60  
        @ref parse_ipv6_address.
61  
*/
61  
*/
62  
class ipv6_address
62  
class ipv6_address
63  
{
63  
{
64  
public:
64  
public:
65  
    /** The number of characters in the longest possible IPv6 string.
65  
    /** The number of characters in the longest possible IPv6 string.
66  

66  

67  
        The longest IPv6 address is:
67  
        The longest IPv6 address is:
68  
        @code
68  
        @code
69  
        ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
69  
        ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
70  
        @endcode
70  
        @endcode
71  

71  

72  
        @see
72  
        @see
73  
            @ref to_buffer.
73  
            @ref to_buffer.
74  
    */
74  
    */
75  
    // ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
75  
    // ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
76  
    // ::ffff:255.255.255.255
76  
    // ::ffff:255.255.255.255
77  
    // 12345678901234567890123456789012345678901234567890
77  
    // 12345678901234567890123456789012345678901234567890
78  
    //          1         2         3        4
78  
    //          1         2         3        4
79  
    static
79  
    static
80  
    constexpr
80  
    constexpr
81  
    std::size_t max_str_len = 49;
81  
    std::size_t max_str_len = 49;
82  

82  

83  
    /** The type used to represent an address as an array of bytes.
83  
    /** The type used to represent an address as an array of bytes.
84  

84  

85  
        Octets are stored in network byte order.
85  
        Octets are stored in network byte order.
86  
    */
86  
    */
87  
    using bytes_type = std::array<
87  
    using bytes_type = std::array<
88  
        unsigned char, 16>;
88  
        unsigned char, 16>;
89  

89  

90  
    /** Constructor.
90  
    /** Constructor.
91  

91  

92  
        Default constructed objects represent
92  
        Default constructed objects represent
93  
        the unspecified address.
93  
        the unspecified address.
94  

94  

95  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.2"
95  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.2"
96  
            >2.5.2. The Unspecified Address</a>
96  
            >2.5.2. The Unspecified Address</a>
97  

97  

98  
        @see
98  
        @see
99  
            @ref is_unspecified
99  
            @ref is_unspecified
100  
    */
100  
    */
101  
    ipv6_address() = default;
101  
    ipv6_address() = default;
102  

102  

103  
    /** Constructor.
103  
    /** Constructor.
104  
    */
104  
    */
105  
    ipv6_address(
105  
    ipv6_address(
106  
        ipv6_address const&) = default;
106  
        ipv6_address const&) = default;
107  

107  

108  
    /** Copy Assignment
108  
    /** Copy Assignment
109  

109  

110  
        @return `*this`
110  
        @return `*this`
111  
    */
111  
    */
112  
    ipv6_address&
112  
    ipv6_address&
113  
    operator=(
113  
    operator=(
114  
        ipv6_address const&) = default;
114  
        ipv6_address const&) = default;
115  

115  

116  
    /** Construct from an array of bytes.
116  
    /** Construct from an array of bytes.
117  

117  

118  
        This function constructs an address
118  
        This function constructs an address
119  
        from the array in `bytes`, which is
119  
        from the array in `bytes`, which is
120  
        interpreted in big-endian.
120  
        interpreted in big-endian.
121  

121  

122  
        @param bytes The value to construct from.
122  
        @param bytes The value to construct from.
123  
    */
123  
    */
124  
    BOOST_URL_CXX20_CONSTEXPR
124  
    BOOST_URL_CXX20_CONSTEXPR
125  
    ipv6_address(
125  
    ipv6_address(
126  
        bytes_type const& bytes) noexcept
126  
        bytes_type const& bytes) noexcept
127  
        : addr_(bytes)
127  
        : addr_(bytes)
128  
    {
128  
    {
129  
    }
129  
    }
130  

130  

131  
    /** Construct from an IPv4 address.
131  
    /** Construct from an IPv4 address.
132  

132  

133  
        This function constructs an IPv6 address
133  
        This function constructs an IPv6 address
134  
        from the IPv4 address `addr`. The resulting
134  
        from the IPv4 address `addr`. The resulting
135  
        address is an IPv4-Mapped IPv6 Address.
135  
        address is an IPv4-Mapped IPv6 Address.
136  

136  

137  
        @param addr The address to construct from.
137  
        @param addr The address to construct from.
138  

138  

139  
        @par Specification
139  
        @par Specification
140  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2"
140  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2"
141  
            >2.5.5.2. IPv4-Mapped IPv6 Address (rfc4291)</a>
141  
            >2.5.5.2. IPv4-Mapped IPv6 Address (rfc4291)</a>
142  
    */
142  
    */
143  
    BOOST_URL_DECL
143  
    BOOST_URL_DECL
144  
    ipv6_address(
144  
    ipv6_address(
145  
        ipv4_address const& addr) noexcept;
145  
        ipv4_address const& addr) noexcept;
146  

146  

147  
    /** Construct from a string.
147  
    /** Construct from a string.
148  

148  

149  
        This function constructs an address from
149  
        This function constructs an address from
150  
        the string `s`, which must contain a valid
150  
        the string `s`, which must contain a valid
151  
        IPv6 address string or else an exception
151  
        IPv6 address string or else an exception
152  
        is thrown.
152  
        is thrown.
153  

153  

154  
        @note For a non-throwing parse function,
154  
        @note For a non-throwing parse function,
155  
        use @ref parse_ipv6_address.
155  
        use @ref parse_ipv6_address.
156  

156  

157  
        @par Exception Safety
157  
        @par Exception Safety
158  
        Exceptions thrown on invalid input.
158  
        Exceptions thrown on invalid input.
159  

159  

160  
        @throw system_error
160  
        @throw system_error
161  
        The input failed to parse correctly.
161  
        The input failed to parse correctly.
162  

162  

163  
        @param s The string to parse.
163  
        @param s The string to parse.
164  

164  

165  
        @par Specification
165  
        @par Specification
166  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
166  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2"
167  
            >3.2.2. Host (rfc3986)</a>
167  
            >3.2.2. Host (rfc3986)</a>
168  

168  

169  
        @see
169  
        @see
170  
            @ref parse_ipv6_address.
170  
            @ref parse_ipv6_address.
171  
    */
171  
    */
172  
    BOOST_URL_DECL
172  
    BOOST_URL_DECL
173  
    ipv6_address(
173  
    ipv6_address(
174  
        core::string_view s);
174  
        core::string_view s);
175  

175  

176  
    /** Return the address as bytes, in network byte order
176  
    /** Return the address as bytes, in network byte order
177  

177  

178  
        @return The address as an array of bytes.
178  
        @return The address as an array of bytes.
179  
    */
179  
    */
180  
    bytes_type
180  
    bytes_type
181  
    to_bytes() const noexcept
181  
    to_bytes() const noexcept
182  
    {
182  
    {
183  
        return addr_;
183  
        return addr_;
184  
    }
184  
    }
185  

185  

186  
    /** Return the address as a string.
186  
    /** Return the address as a string.
187  

187  

188  
        The returned string does not
188  
        The returned string does not
189  
        contain surrounding square brackets.
189  
        contain surrounding square brackets.
190  

190  

191  
        When called with no arguments, the
191  
        When called with no arguments, the
192  
        return type is `std::string`.
192  
        return type is `std::string`.
193  
        Otherwise, the return type and style
193  
        Otherwise, the return type and style
194  
        of output is determined by which string
194  
        of output is determined by which string
195  
        token is passed.
195  
        token is passed.
196  

196  

197  
        @par Example
197  
        @par Example
198  
        @code
198  
        @code
199  
        ipv6_address::bytes_type b = {{
199  
        ipv6_address::bytes_type b = {{
200  
                0, 1, 0, 2, 0, 3, 0, 4,
200  
                0, 1, 0, 2, 0, 3, 0, 4,
201  
                0, 5, 0, 6, 0, 7, 0, 8 }};
201  
                0, 5, 0, 6, 0, 7, 0, 8 }};
202  
        ipv6_address a(b);
202  
        ipv6_address a(b);
203  
        assert(a.to_string() == "1:2:3:4:5:6:7:8");
203  
        assert(a.to_string() == "1:2:3:4:5:6:7:8");
204  
        assert( ipv4_address(0x01020304).to_string() == "1.2.3.4" );
204  
        assert( ipv4_address(0x01020304).to_string() == "1.2.3.4" );
205  
        @endcode
205  
        @endcode
206  

206  

207  
        @par Complexity
207  
        @par Complexity
208  
        Constant.
208  
        Constant.
209  

209  

210  
        @par Exception Safety
210  
        @par Exception Safety
211  
        Strong guarantee.
211  
        Strong guarantee.
212  
        Calls to allocate may throw.
212  
        Calls to allocate may throw.
213  
        String tokens may throw exceptions.
213  
        String tokens may throw exceptions.
214  

214  

215  
        @return The return type of the string token.
215  
        @return The return type of the string token.
216  
        If the token parameter is omitted, then
216  
        If the token parameter is omitted, then
217  
        a new `std::string` is returned.
217  
        a new `std::string` is returned.
218  
        Otherwise, the function return type
218  
        Otherwise, the function return type
219  
        is the result type of the token.
219  
        is the result type of the token.
220  

220  

221  
        @param token An optional string token.
221  
        @param token An optional string token.
222  

222  

223  
        @par Specification
223  
        @par Specification
224  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.2">
224  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.2">
225  
            2.2. Text Representation of Addresses (rfc4291)</a>
225  
            2.2. Text Representation of Addresses (rfc4291)</a>
226  
    */
226  
    */
227  
    template<BOOST_URL_STRTOK_TPARAM>
227  
    template<BOOST_URL_STRTOK_TPARAM>
228  
    BOOST_URL_STRTOK_RETURN
228  
    BOOST_URL_STRTOK_RETURN
229  
    to_string(
229  
    to_string(
230  
        BOOST_URL_STRTOK_ARG(token)) const
230  
        BOOST_URL_STRTOK_ARG(token)) const
231  
    {
231  
    {
232  
        to_string_impl(token);
232  
        to_string_impl(token);
233  
        return token.result();
233  
        return token.result();
234  
    }
234  
    }
235  

235  

236  
    /** Write a dotted decimal string representing the address to a buffer
236  
    /** Write a dotted decimal string representing the address to a buffer
237  

237  

238  
        The resulting buffer is not null-terminated.
238  
        The resulting buffer is not null-terminated.
239  

239  

240  
        @throw std::length_error `dest_size < ipv6_address::max_str_len`
240  
        @throw std::length_error `dest_size < ipv6_address::max_str_len`
241  

241  

242  
        @return The formatted string
242  
        @return The formatted string
243  

243  

244  
        @param dest The buffer in which to write,
244  
        @param dest The buffer in which to write,
245  
        which must have at least `dest_size` space.
245  
        which must have at least `dest_size` space.
246  

246  

247  
        @param dest_size The size of the output buffer.
247  
        @param dest_size The size of the output buffer.
248  
    */
248  
    */
249  
    BOOST_URL_DECL
249  
    BOOST_URL_DECL
250  
    core::string_view
250  
    core::string_view
251  
    to_buffer(
251  
    to_buffer(
252  
        char* dest,
252  
        char* dest,
253  
        std::size_t dest_size) const;
253  
        std::size_t dest_size) const;
254  

254  

255  
    /** Return true if the address is unspecified
255  
    /** Return true if the address is unspecified
256  

256  

257  
        The address 0:0:0:0:0:0:0:0 is called the
257  
        The address 0:0:0:0:0:0:0:0 is called the
258  
        unspecified address. It indicates the
258  
        unspecified address. It indicates the
259  
        absence of an address.
259  
        absence of an address.
260  

260  

261  
        @return `true` if the address is unspecified
261  
        @return `true` if the address is unspecified
262  

262  

263  
        @par Specification
263  
        @par Specification
264  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.2">
264  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.2">
265  
            2.5.2. The Unspecified Address (rfc4291)</a>
265  
            2.5.2. The Unspecified Address (rfc4291)</a>
266  
    */
266  
    */
267  
    BOOST_URL_DECL
267  
    BOOST_URL_DECL
268  
    bool
268  
    bool
269  
    is_unspecified() const noexcept;
269  
    is_unspecified() const noexcept;
270  

270  

271  
    /** Return true if the address is a loopback address
271  
    /** Return true if the address is a loopback address
272  

272  

273  
        The unicast address 0:0:0:0:0:0:0:1 is called
273  
        The unicast address 0:0:0:0:0:0:0:1 is called
274  
        the loopback address. It may be used by a node
274  
        the loopback address. It may be used by a node
275  
        to send an IPv6 packet to itself.
275  
        to send an IPv6 packet to itself.
276  

276  

277  
        @return `true` if the address is a loopback address
277  
        @return `true` if the address is a loopback address
278  

278  

279  
        @par Specification
279  
        @par Specification
280  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.3">
280  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.3">
281  
            2.5.3. The Loopback Address (rfc4291)</a>
281  
            2.5.3. The Loopback Address (rfc4291)</a>
282  
    */
282  
    */
283  
    BOOST_URL_DECL
283  
    BOOST_URL_DECL
284  
    bool
284  
    bool
285  
    is_loopback() const noexcept;
285  
    is_loopback() const noexcept;
286  

286  

287  
    /** Return true if the address is a mapped IPv4 address
287  
    /** Return true if the address is a mapped IPv4 address
288  

288  

289  
        This address type is used to represent the
289  
        This address type is used to represent the
290  
        addresses of IPv4 nodes as IPv6 addresses.
290  
        addresses of IPv4 nodes as IPv6 addresses.
291  

291  

292  
        @return `true` if the address is a mapped IPv4 address
292  
        @return `true` if the address is a mapped IPv4 address
293  

293  

294  
        @par Specification
294  
        @par Specification
295  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2">
295  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2">
296  
            2.5.5.2. IPv4-Mapped IPv6 Address (rfc4291)</a>
296  
            2.5.5.2. IPv4-Mapped IPv6 Address (rfc4291)</a>
297  
    */
297  
    */
298  
    BOOST_URL_DECL
298  
    BOOST_URL_DECL
299  
    bool
299  
    bool
300  
    is_v4_mapped() const noexcept;
300  
    is_v4_mapped() const noexcept;
301  

301  

302  
    /** Return true if two addresses are equal
302  
    /** Return true if two addresses are equal
303  

303  

304  
        @param a1 The first address to compare.
304  
        @param a1 The first address to compare.
305  
        @param a2 The second address to compare.
305  
        @param a2 The second address to compare.
306  
        @return `true` if the addresses are equal
306  
        @return `true` if the addresses are equal
307  
    */
307  
    */
308  
    friend
308  
    friend
309  
    bool
309  
    bool
310  
    operator==(
310  
    operator==(
311  
        ipv6_address const& a1,
311  
        ipv6_address const& a1,
312  
        ipv6_address const& a2) noexcept
312  
        ipv6_address const& a2) noexcept
313  
    {
313  
    {
314  
        return a1.addr_ == a2.addr_;
314  
        return a1.addr_ == a2.addr_;
315  
    }
315  
    }
316  

316  

317  
    /** Return true if two addresses are not equal
317  
    /** Return true if two addresses are not equal
318  

318  

319  
        @param a1 The first address to compare.
319  
        @param a1 The first address to compare.
320  
        @param a2 The second address to compare.
320  
        @param a2 The second address to compare.
321  
        @return `true` if the addresses are not equal
321  
        @return `true` if the addresses are not equal
322  
    */
322  
    */
323  
    friend
323  
    friend
324  
    bool
324  
    bool
325  
    operator!=(
325  
    operator!=(
326  
        ipv6_address const& a1,
326  
        ipv6_address const& a1,
327  
        ipv6_address const& a2) noexcept
327  
        ipv6_address const& a2) noexcept
328  
    {
328  
    {
329  
        return !( a1 == a2 );
329  
        return !( a1 == a2 );
330  
    }
330  
    }
331  

331  

332  
    /** Return an address object that represents the loopback address
332  
    /** Return an address object that represents the loopback address
333  

333  

334  
        The unicast address 0:0:0:0:0:0:0:1 is called
334  
        The unicast address 0:0:0:0:0:0:0:1 is called
335  
        the loopback address. It may be used by a node
335  
        the loopback address. It may be used by a node
336  
        to send an IPv6 packet to itself.
336  
        to send an IPv6 packet to itself.
337  

337  

338  
        @par Specification
338  
        @par Specification
339  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.3">
339  
        @li <a href="https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.3">
340  
            2.5.3. The Loopback Address (rfc4291)</a>
340  
            2.5.3. The Loopback Address (rfc4291)</a>
341  

341  

342  
        @return The loopback address.
342  
        @return The loopback address.
343  
    */
343  
    */
344  
    BOOST_URL_DECL
344  
    BOOST_URL_DECL
345  
    static
345  
    static
346  
    ipv6_address
346  
    ipv6_address
347  
    loopback() noexcept;
347  
    loopback() noexcept;
348  

348  

349  
    /** Format the address to an output stream
349  
    /** Format the address to an output stream
350  

350  

351  
        This function writes the address to an
351  
        This function writes the address to an
352  
        output stream using standard notation.
352  
        output stream using standard notation.
353  

353  

354  
        @return The output stream, for chaining.
354  
        @return The output stream, for chaining.
355  

355  

356  
        @param os The output stream to write to.
356  
        @param os The output stream to write to.
357  

357  

358  
        @param addr The address to write.
358  
        @param addr The address to write.
359  
    */
359  
    */
360  
    friend
360  
    friend
361  
    std::ostream&
361  
    std::ostream&
362  
    operator<<(
362  
    operator<<(
363  
        std::ostream& os,
363  
        std::ostream& os,
364  
        ipv6_address const& addr)
364  
        ipv6_address const& addr)
365  
    {
365  
    {
366  
        addr.write_ostream(os);
366  
        addr.write_ostream(os);
367  
        return os;
367  
        return os;
368  
    }
368  
    }
369  

369  

370  
private:
370  
private:
371  
    BOOST_URL_DECL void write_ostream(std::ostream&) const;
371  
    BOOST_URL_DECL void write_ostream(std::ostream&) const;
372  

372  

373  
    BOOST_URL_DECL
373  
    BOOST_URL_DECL
374  
    std::size_t
374  
    std::size_t
375  
    print_impl(
375  
    print_impl(
376  
        char* dest) const noexcept;
376  
        char* dest) const noexcept;
377  

377  

378  
    BOOST_URL_DECL
378  
    BOOST_URL_DECL
379  
    void
379  
    void
380  
    to_string_impl(
380  
    to_string_impl(
381  
        string_token::arg& t) const;
381  
        string_token::arg& t) const;
382  

382  

383  
    bytes_type addr_{{}};
383  
    bytes_type addr_{{}};
384  
};
384  
};
385  

385  

386  
//------------------------------------------------
386  
//------------------------------------------------
387  

387  

388  
/** Parse a string containing an IPv6 address.
388  
/** Parse a string containing an IPv6 address.
389  

389  

390  
    This function attempts to parse the string
390  
    This function attempts to parse the string
391  
    as an IPv6 address and returns a result
391  
    as an IPv6 address and returns a result
392  
    containing the address upon success, or
392  
    containing the address upon success, or
393  
    an error code if the string does not contain
393  
    an error code if the string does not contain
394  
    a valid IPv6 address.
394  
    a valid IPv6 address.
395  

395  

396  
    @par Exception Safety
396  
    @par Exception Safety
397  
    Throws nothing.
397  
    Throws nothing.
398  

398  

399  
    @return A result containing the address.
399  
    @return A result containing the address.
400  

400  

401  
    @param s The string to parse.
401  
    @param s The string to parse.
402  
*/
402  
*/
403  
BOOST_URL_DECL
403  
BOOST_URL_DECL
404  
system::result<ipv6_address>
404  
system::result<ipv6_address>
405  
parse_ipv6_address(
405  
parse_ipv6_address(
406  
    core::string_view s) noexcept;
406  
    core::string_view s) noexcept;
407  

407  

408  
} // urls
408  
} // urls
409  
} // boost
409  
} // boost
410  

410  

411  
#endif
411  
#endif