ipaddress 1.2.0
Loading...
Searching...
No Matches
ipv6-address.hpp
Go to the documentation of this file.
1/**
2 * @file ipv6-address.hpp
3 * @brief Provides a set of functions and classes for handling IPv6 addresses
4 * @author Vladimir Shaleev
5 * @copyright MIT License
6 *
7 * Includes functionalities to convert IPv6 addresses to and from various formats,
8 * perform comparisons, and query specific properties of the addresses.
9 * It serves as a foundational component for network applications that require manipulation
10 * and analysis of IPv6 address data.
11 */
12
13#ifndef IPADDRESS_IPV6_ADDRESS_HPP
14#define IPADDRESS_IPV6_ADDRESS_HPP
15
16#include "ipv4-address.hpp"
17#include "base-v6.hpp"
18
19namespace IPADDRESS_NAMESPACE {
20
21namespace internal {
22
23template <typename T>
24struct ipv6_set_scope {
25 template <typename Str>
26 static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void change(fixed_string<IPADDRESS_IPV6_SCOPE_MAX_LENGTH>& result, const Str& scope) IPADDRESS_NOEXCEPT_WHEN_NO_EXCEPTIONS {
27 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
29 uint32_t index = 0;
30 change(result, scope, code, index);
31 #ifndef IPADDRESS_NO_EXCEPTIONS
32 if (code != error_code::no_error) {
33 raise_error(code, index, scope.data(), scope.size());
34 }
35 #endif // !IPADDRESS_NO_EXCEPTIONS
36 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
37 }
38
39 template <typename Str>
40 static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void change(fixed_string<IPADDRESS_IPV6_SCOPE_MAX_LENGTH>& result, const Str& scope, error_code& code) IPADDRESS_NOEXCEPT {
41 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
42 uint32_t index = 0;
43 change(result, scope, code, index);
44 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
45 }
46
47 template <typename Str>
48 static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void change(fixed_string<IPADDRESS_IPV6_SCOPE_MAX_LENGTH>& result, const Str& scope, error_code& code, uint32_t& index) IPADDRESS_NOEXCEPT {
49 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
50 if (scope.size() > IPADDRESS_IPV6_SCOPE_MAX_LENGTH) {
52 return;
53 }
54 char str[IPADDRESS_IPV6_SCOPE_MAX_LENGTH + 1] = {};
55 auto it = scope.data();
56 auto end = it + scope.size();
57 uint32_t error_symbol = 0;
59 index = 0;
60 for (int i = 0; it < end; ++i) {
61 auto c = internal::next_char_or_error(it, end, code, error_symbol);
62 if (code != error_code::no_error) {
63 index = error_symbol;
64 return;
65 }
66 if (internal::is_invalid_scope_id_symbol(c)) {
68 return;
69 }
70 str[i] = c;
71 }
72 const auto fixed_scope = make_fixed_string(str, code);
73 if (code == error_code::no_error) {
74 result = fixed_scope;
75 }
76 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
77 }
78};
79
80} // namespace IPADDRESS_NAMESPACE::internal
81
82/**
83 * Represents the scope identifier for an IPv6 address.
84 *
85 * The scope identifier is used to distinguish between different zones for the same address,
86 * such as link-local or site-local scopes. This class provides methods to set, retrieve,
87 * and compare scope identifiers in both string and numeric formats.
88 */
89IPADDRESS_EXPORT class scope final {
90public:
91 /**
92 * Constructs a scope object with a given scope identifier.
93 *
94 * @param[in] scope_id A fixed_string representing the scope identifier.
95 * @note According to [RFC 4007](https://datatracker.ietf.org/doc/html/rfc4007.html), the string identifies the specific scope zone of the address.
96 */
97 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE scope(const fixed_string<IPADDRESS_IPV6_SCOPE_MAX_LENGTH>& scope_id) IPADDRESS_NOEXCEPT
98 :
100 parse_value();
101 }
102
103 /**
104 * Retrieves the scope identifier as a string.
105 *
106 * @return A `std::string` representing the scope identifier.
107 * @note According to [RFC 4007](https://datatracker.ietf.org/doc/html/rfc4007.html), the string identifies the specific scope zone of the address.
108 */
110 return std::string(_scope_id.begin(), _scope_id.end());
111 }
112
113 /**
114 * Retrieves the scope identifier as a numeric value.
115 *
116 * @return A uint32_t representing the numeric value of the scope identifier.
117 */
119 return _scope_id_value;
120 }
121
122 /**
123 * Checks if the scope identifier has a string representation.
124 *
125 * @return `true` if a string representation exists, `false` otherwise.
126 */
128 return !_scope_id.empty();
129 }
130
131 /**
132 * Checks if the scope identifier has a numeric representation.
133 *
134 * @return `true` if a numeric representation exists, `false` otherwise.
135 */
137 return _has_value;
138 }
139
140 /**
141 * Converts the scope object to a boolean value based on the presence of a scope representation.
142 *
143 * @return `true` if a scope exists, `false` otherwise.
144 */
145 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE explicit operator bool() const IPADDRESS_NOEXCEPT {
146 return has_string();
147 }
148
149 /**
150 * Converts the scope object to a string representation.
151 *
152 * @return A std::string representing the scope identifier.
153 */
155 return get_string();
156 }
157
158 /**
159 * Converts the scope object to a numeric representation.
160 *
161 * @return A uint32_t representing the numeric value of the scope identifier.
162 */
164 return get_uint32();
165 }
166
167 /**
168 * Compares two scope objects for equality.
169 *
170 * @param[in] rhs The right-hand side scope object for comparison.
171 * @return `true` if both scope objects are equal, `false` otherwise.
172 */
173 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator==(const scope& rhs) const IPADDRESS_NOEXCEPT {
174 return _scope_id == rhs._scope_id;
175 }
176
177 /**
178 * Compares two scope objects for inequality.
179 *
180 * @param[in] rhs The right-hand side scope object for comparison.
181 * @return `true` if both scope objects are not equal, `false` otherwise.
182 */
183 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator!=(const scope& rhs) const IPADDRESS_NOEXCEPT {
184 return !(*this == rhs);
185 }
186
187#ifdef IPADDRESS_HAS_SPACESHIP_OPERATOR
188
189 /**
190 * Compares two scope objects using the three-way comparison operator (spaceship operator).
191 *
192 * @param[in] rhs The right-hand side scope object for comparison.
193 * @return A value of type `std::strong_ordering` that represents the result of the comparison.
194 */
195 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE std::strong_ordering operator<=>(const scope& rhs) const IPADDRESS_NOEXCEPT {
196 return _scope_id <=> rhs._scope_id;
197 }
198
199#else // !IPADDRESS_HAS_SPACESHIP_OPERATOR
200
201 /**
202 * Checks if one scope object is less than another.
203 *
204 * @param[in] rhs The right-hand side scope object for comparison.
205 * @return `true` if the left-hand side scope object is less than the right-hand side, `false` otherwise.
206 */
207 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator<(const scope& rhs) const IPADDRESS_NOEXCEPT {
208 return _scope_id < rhs._scope_id;
209 }
210
211 /**
212 * Checks if one scope object is greater than another.
213 *
214 * @param[in] rhs The right-hand side scope object for comparison.
215 * @return `true` if the left-hand side scope object is greater than the right-hand side, `false` otherwise.
216 */
217 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator>(const scope& rhs) const IPADDRESS_NOEXCEPT {
218 return rhs < *this;
219 }
220
221 /**
222 * Checks if one scope object is less than or equal to another.
223 *
224 * @param[in] rhs The right-hand side scope object for comparison.
225 * @return `true` if the left-hand side scope object is less than or equal to the right-hand side, `false` otherwise.
226 */
227 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator<=(const scope& rhs) const IPADDRESS_NOEXCEPT {
228 return !(rhs < *this);
229 }
230
231 /**
232 * Checks if one scope object is greater than or equal to another.
233 *
234 * @param[in] rhs The right-hand side scope object for comparison.
235 * @return `true` if the left-hand side scope object is greater than or equal to the right-hand side, `false` otherwise.
236 */
237 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool operator>=(const scope& rhs) const IPADDRESS_NOEXCEPT {
238 return !(*this < rhs);
239 }
240
241#endif // !IPADDRESS_HAS_SPACESHIP_OPERATOR
242
243private:
244 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void parse_value() IPADDRESS_NOEXCEPT {
245 if (!_scope_id.empty()) {
246 _has_value = true;
247 uint32_t value = 0;
248 const auto scope_id_size = _scope_id.size();
249 for (size_t i = 0; i < scope_id_size; ++i) {
250 const auto c = _scope_id[i];
251 if (c >= '0' && c <= '9') {
252 value = value * 10 + (c - '0');
253 } else {
254 _has_value = false;
255 break;
256 }
257 }
258 _scope_id_value = _has_value ? value : 0;
259 }
260 }
261
262 fixed_string<IPADDRESS_IPV6_SCOPE_MAX_LENGTH> _scope_id;
263 uint32_t _scope_id_value = 0;
264 bool _has_value = false;
265}; // scope
266
267/**
268 * Represents the base class for IPv6 address manipulation.
269 *
270 * This class provides the basic functionalities required for handling IPv6 addresses,
271 * including conversion to and from numeric representations, access to the underlying bytes,
272 * and utility functions that are common across different representations of IPv6 addresses.
273 */
275public:
276 using base_type = typename base_v6<ipv6_address_base>::base_type; /**< The base type for the IPv6 address. */
277 using uint_type = typename base_v6<ipv6_address_base>::uint_type; /**< The unsigned integer type for the IPv6 address. */
278
279 /**
280 * Retrieves the scope identifier of the IPv6 address.
281 *
282 * The scope identifier is used to determine the context in which the address is valid.
283 * It is particularly relevant for link-local and site-local addresses.
284 *
285 * @return A `scope` object representing the scope identifier of the IPv6 address.
286 * @remark If the scope is disabled in the settings (`IPADDRESS_IPV6_SCOPE_MAX_LENGTH == 0`), then an empty scope will be returned.
287 */
289 return scope(
290 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
291 _data.scope_id
292 #else // IPADDRESS_IPV6_SCOPE_MAX_LENGTH <= 0
293 make_fixed_string("")
294 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH <= 0
295 );
296 }
297
298 /**
299 * Sets the scope identifier of the IPv6 address.
300 *
301 * This function sets the scope identifier using a character array. The length of the array
302 * should not exceed `IPADDRESS_IPV6_SCOPE_MAX_LENGTH + 1`.
303 *
304 * @tparam T The character type of the scope identifier.
305 * @tparam N The size of the scope identifier array.
306 * @param[in] scope_id The character array representing the scope identifier.
307 * @note According to [RFC 4007](https://datatracker.ietf.org/doc/html/rfc4007.html), the string identifies the specific scope zone of the address.
308 * @remark If scope is disabled in settings (`IPADDRESS_IPV6_SCOPE_MAX_LENGTH == 0`) then this call will have no effect.
309 */
310 template <typename T, size_t N>
311 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void set_scope_id(const T(&scope_id)[N]) IPADDRESS_NOEXCEPT_WHEN_NO_EXCEPTIONS {
312 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
313 static_assert(N <= IPADDRESS_IPV6_SCOPE_MAX_LENGTH + 1, "scope id is too long");
314 #ifdef IPADDRESS_NO_EXCEPTIONS
315 auto code = error_code::no_error;
316 const auto result = make_fixed_string(scope_id, code);
317 if (code == error_code::no_error) {
318 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, result);
319 }
320 #else // !IPADDRESS_NO_EXCEPTIONS
321 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, make_fixed_string(scope_id));
322 #endif // !IPADDRESS_NO_EXCEPTIONS
323 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
324 }
325
326 /**
327 * Sets the scope identifier of the IPv6 address and reports any errors encountered.
328 *
329 * This function sets the scope identifier using a character array. The length of the array
330 * should not exceed `IPADDRESS_IPV6_SCOPE_MAX_LENGTH + 1`.
331 *
332 * @tparam T The character type of the scope identifier.
333 * @tparam N The size of the scope identifier array.
334 * @param[in] scope_id The character array representing the scope identifier.
335 * @param[out] code An error_code object that will be set to the error that occurred, if any.
336 * @note According to [RFC 4007](https://datatracker.ietf.org/doc/html/rfc4007.html), the string identifies the specific scope zone of the address.
337 * @remark If scope is disabled in settings (`IPADDRESS_IPV6_SCOPE_MAX_LENGTH == 0`) then this call will have no effect.
338 */
339 template <typename T, size_t N>
340 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE void set_scope_id(const T(&scope_id)[N], error_code& code) IPADDRESS_NOEXCEPT {
341 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
342 static_assert(N <= IPADDRESS_IPV6_SCOPE_MAX_LENGTH + 1, "scope id is too long");
343 const auto fixed_scope = make_fixed_string(scope_id, code);
344 if (code == error_code::no_error) {
345 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, fixed_scope, code);
346 }
347 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
348 }
349
350#if IPADDRESS_CPP_VERSION >= 17
351
352 /**
353 * Sets the scope identifier of the IPv6 address using a string view.
354 *
355 * This function sets the scope identifier using a string view, which allows for a more efficient
356 * way to handle strings without copying them.
357 *
358 * @param[in] scope_id The string view representing the scope identifier.
359 * @throw parse_error Exception caused by invalid input string.
360 * @parblock
361 * @note This method is available for C++17 and later versions.
362 * @endparblock
363 * @parblock
364 * @note According to [RFC 4007](https://datatracker.ietf.org/doc/html/rfc4007.html), the string identifies the specific scope zone of the address.
365 * @endparblock
366 * @parblock
367 * @remark For C++ versions prior to C++17, member functions with `std::string` and C-strings will be used instead.
368 * @endparblock
369 * @parblock
370 * @remark If scope is disabled in settings (`IPADDRESS_IPV6_SCOPE_MAX_LENGTH == 0`) then this call will have no effect.
371 * @endparblock
372 */
374 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
376 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
377 }
378
379 /**
380 * Sets the scope identifier of the IPv6 address using a wide string view.
381 *
382 * This function sets the scope identifier using a wide string view, which allows for a more efficient
383 * way to handle strings without copying them.
384 *
385 * @param[in] scope_id The wide string view representing the scope identifier.
386 * @throw parse_error Exception caused by invalid input string.
387 * @parblock
388 * @note This method is available for C++17 and later versions.
389 * @endparblock
390 * @parblock
391 * @note According to [RFC 4007](https://datatracker.ietf.org/doc/html/rfc4007.html), the string identifies the specific scope zone of the address.
392 * @endparblock
393 * @parblock
394 * @remark For C++ versions prior to C++17, member functions with `std::wstring` and C-strings will be used instead.
395 * @endparblock
396 * @parblock
397 * @remark If scope is disabled in settings (`IPADDRESS_IPV6_SCOPE_MAX_LENGTH == 0`) then this call will have no effect.
398 * @endparblock
399 */
401 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
403 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
404 }
405
406#if __cpp_char8_t >= 201811L
407
408 /**
409 * Sets the scope identifier of the IPv6 address using UTF-8 string view.
410 *
411 * This function sets the scope identifier using UTF-8 string view, which allows for a more efficient
412 * way to handle strings without copying them.
413 *
414 * @param[in] scope_id The UTF-8 string view representing the scope identifier.
415 * @throw parse_error Exception caused by invalid input string.
416 * @parblock
417 * @note This method is available for C++20 and later versions where `char8_t` is supported.
418 * @endparblock
419 * @parblock
420 * @note According to [RFC 4007](https://datatracker.ietf.org/doc/html/rfc4007.html), the string identifies the specific scope zone of the address.
421 * @endparblock
422 * @remark If scope is disabled in settings (`IPADDRESS_IPV6_SCOPE_MAX_LENGTH == 0`) then this call will have no effect.
423 */
425 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
427 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
428 }
429
430#endif // __cpp_char8_t
431
432 /**
433 * Sets the scope identifier of the IPv6 address using UTF-16 string view.
434 *
435 * This function sets the scope identifier using UTF-16 string view, which allows for a more efficient
436 * way to handle strings without copying them.
437 *
438 * @param[in] scope_id The UTF-16 string view representing the scope identifier.
439 * @throw parse_error Exception caused by invalid input string.
440 * @parblock
441 * @note This method is available for C++17 and later versions.
442 * @endparblock
443 * @parblock
444 * @note According to [RFC 4007](https://datatracker.ietf.org/doc/html/rfc4007.html), the string identifies the specific scope zone of the address.
445 * @endparblock
446 * @parblock
447 * @remark For C++ versions prior to C++17, member functions with `std::u16string` and C-strings will be used instead.
448 * @endparblock
449 * @parblock
450 * @remark If scope is disabled in settings (`IPADDRESS_IPV6_SCOPE_MAX_LENGTH == 0`) then this call will have no effect.
451 * @endparblock
452 */
454 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
456 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
457 }
458
459 /**
460 * Sets the scope identifier of the IPv6 address using UTF-32 string view.
461 *
462 * This function sets the scope identifier using UTF-32 string view, which allows for a more efficient
463 * way to handle strings without copying them.
464 *
465 * @param[in] scope_id The UTF-32 string view representing the scope identifier.
466 * @throw parse_error Exception caused by invalid input string.
467 * @parblock
468 * @note This method is available for C++17 and later versions.
469 * @endparblock
470 * @parblock
471 * @note According to [RFC 4007](https://datatracker.ietf.org/doc/html/rfc4007.html), the string identifies the specific scope zone of the address.
472 * @endparblock
473 * @parblock
474 * @remark For C++ versions prior to C++17, member functions with `std::u32string` and C-strings will be used instead.
475 * @endparblock
476 * @parblock
477 * @remark If scope is disabled in settings (`IPADDRESS_IPV6_SCOPE_MAX_LENGTH == 0`) then this call will have no effect.
478 * @endparblock
479 */
481 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
483 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
484 }
485
486 /**
487 * Sets the scope identifier of the IPv6 address using a string view and reports any errors encountered.
488 *
489 * This function sets the scope identifier using a string view and provides an error code parameter to report any issues that occur during the operation.
490 *
491 * @param[in] scope_id The string view representing the scope identifier.
492 * @param[out] code An error_code object that will be set to the error that occurred, if any.
493 * @parblock
494 * @note This method is available for C++17 and later versions.
495 * @endparblock
496 * @parblock
497 * @note According to [RFC 4007](https://datatracker.ietf.org/doc/html/rfc4007.html), the string identifies the specific scope zone of the address.
498 * @endparblock
499 * @parblock
500 * @remark For C++ versions prior to C++17, member functions with `std::string` and C-strings will be used instead.
501 * @endparblock
502 * @parblock
503 * @remark If scope is disabled in settings (`IPADDRESS_IPV6_SCOPE_MAX_LENGTH == 0`) then this call will have no effect.
504 * @endparblock
505 */
507 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
509 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
510 }
511
512 /**
513 * Sets the scope identifier of the IPv6 address using a wide string view and reports any errors encountered.
514 *
515 * This function sets the scope identifier using a wide string view and provides an error code parameter to report any issues that occur during the operation.
516 *
517 * @param[in] scope_id The wide string view representing the scope identifier.
518 * @param[out] code An error_code object that will be set to the error that occurred, if any.
519 * @parblock
520 * @note This method is available for C++17 and later versions.
521 * @endparblock
522 * @parblock
523 * @note According to [RFC 4007](https://datatracker.ietf.org/doc/html/rfc4007.html), the string identifies the specific scope zone of the address.
524 * @endparblock
525 * @parblock
526 * @remark For C++ versions prior to C++17, member functions with `std::wstring` and C-strings will be used instead.
527 * @endparblock
528 * @parblock
529 * @remark If scope is disabled in settings (`IPADDRESS_IPV6_SCOPE_MAX_LENGTH == 0`) then this call will have no effect.
530 * @endparblock
531 */
533 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
535 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
536 }
537
538#if __cpp_char8_t >= 201811L
539
540 /**
541 * Sets the scope identifier of the IPv6 address using a UTF-8 string view and reports any errors encountered.
542 *
543 * This function sets the scope identifier using a UTF-8 string view and provides an error code parameter to report any issues that occur during the operation.
544 *
545 * @param[in] scope_id The UTF-8 string view representing the scope identifier.
546 * @param[out] code An error_code object that will be set to the error that occurred, if any.
547 * @parblock
548 * @note This method is available for C++20 and later versions.
549 * @endparblock
550 * @parblock
551 * @note According to [RFC 4007](https://datatracker.ietf.org/doc/html/rfc4007.html), the string identifies the specific scope zone of the address.
552 * @endparblock
553 * @remark If scope is disabled in settings (`IPADDRESS_IPV6_SCOPE_MAX_LENGTH == 0`) then this call will have no effect.
554 */
556 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
558 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
559 }
560
561#endif // __cpp_char8_t
562
563 /**
564 * Sets the scope identifier of the IPv6 address using a UTF-16 string view and reports any errors encountered.
565 *
566 * This function sets the scope identifier using a UTF-16 string view and provides an error code parameter to report any issues that occur during the operation.
567 *
568 * @param[in] scope_id The UTF-16 string view representing the scope identifier.
569 * @param[out] code An error_code object that will be set to the error that occurred, if any.
570 * @parblock
571 * @note This method is available for C++17 and later versions.
572 * @endparblock
573 * @parblock
574 * @note According to [RFC 4007](https://datatracker.ietf.org/doc/html/rfc4007.html), the string identifies the specific scope zone of the address.
575 * @endparblock
576 * @parblock
577 * @remark For C++ versions prior to C++17, member functions with `std::u16string` and C-strings will be used instead.
578 * @endparblock
579 * @parblock
580 * @remark If scope is disabled in settings (`IPADDRESS_IPV6_SCOPE_MAX_LENGTH == 0`) then this call will have no effect.
581 * @endparblock
582 */
584 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
586 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
587 }
588
589 /**
590 * Sets the scope identifier of the IPv6 address using a UTF-32 string view and reports any errors encountered.
591 *
592 * This function sets the scope identifier using a UTF-32 string view and provides an error code parameter to report any issues that occur during the operation.
593 *
594 * @param[in] scope_id The UTF-32 string view representing the scope identifier.
595 * @param[out] code An error_code object that will be set to the error that occurred, if any.
596 * @parblock
597 * @note This method is available for C++17 and later versions.
598 * @endparblock
599 * @parblock
600 * @note According to [RFC 4007](https://datatracker.ietf.org/doc/html/rfc4007.html), the string identifies the specific scope zone of the address.
601 * @endparblock
602 * @parblock
603 * @remark For C++ versions prior to C++17, member functions with `std::u32string` and C-strings will be used instead.
604 * @endparblock
605 * @parblock
606 * @remark If scope is disabled in settings (`IPADDRESS_IPV6_SCOPE_MAX_LENGTH == 0`) then this call will have no effect.
607 * @endparblock
608 */
610 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
612 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
613 }
614
615#else // IPADDRESS_CPP_VERSION < 17
616
617 /**
618 * Sets the scope identifier of the IPv6 address using a `std::string`.
619 *
620 * @param[in] scope_id The string representing the scope identifier.
621 * @throw parse_error Exception caused by invalid input string.
622 */
623 IPADDRESS_FORCE_INLINE void set_scope_id(const std::string& scope_id) IPADDRESS_NOEXCEPT_WHEN_NO_EXCEPTIONS {
624 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
625 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, scope_id);
626 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
627 }
628
629 /**
630 * Sets the scope identifier of the IPv6 address using a `std::wstring`.
631 *
632 * @param[in] scope_id The wide string representing the scope identifier.
633 * @throw parse_error Exception caused by invalid input wide string.
634 */
635 IPADDRESS_FORCE_INLINE void set_scope_id(const std::wstring& scope_id) IPADDRESS_NOEXCEPT_WHEN_NO_EXCEPTIONS {
636 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
637 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, scope_id);
638 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
639 }
640
641 /**
642 * Sets the scope identifier of the IPv6 address using a `std::u16string`.
643 *
644 * @param[in] scope_id The UTF-16 string representing the scope identifier.
645 * @throw parse_error Exception caused by invalid input UTF-16 string.
646 */
647 IPADDRESS_FORCE_INLINE void set_scope_id(const std::u16string& scope_id) IPADDRESS_NOEXCEPT_WHEN_NO_EXCEPTIONS {
648 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
649 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, scope_id);
650 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
651 }
652
653 /**
654 * Sets the scope identifier of the IPv6 address using a `std::u32string`.
655 *
656 * @param[in] scope_id The UTF-32 string representing the scope identifier.
657 * @throw parse_error Exception caused by invalid input UTF-32 string.
658 */
659 IPADDRESS_FORCE_INLINE void set_scope_id(const std::u32string& scope_id) IPADDRESS_NOEXCEPT_WHEN_NO_EXCEPTIONS {
660 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
661 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, scope_id);
662 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
663 }
664
665 /**
666 * Sets the scope identifier of the IPv6 address using a `std::string` and reports any errors.
667 *
668 * @param[in] scope_id The string representing the scope identifier.
669 * @param[out] code An error_code object that will store the result of the operation.
670 */
671 IPADDRESS_FORCE_INLINE void set_scope_id(const std::string& scope_id, error_code& code) IPADDRESS_NOEXCEPT {
672 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
673 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, scope_id, code);
674 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
675 }
676
677 /**
678 * Sets the scope identifier of the IPv6 address using a `std::wstring` and reports any errors.
679 *
680 * @param[in] scope_id The wide string representing the scope identifier.
681 * @param[out] code An error_code object that will store the result of the operation.
682 */
683 IPADDRESS_FORCE_INLINE void set_scope_id(const std::wstring& scope_id, error_code& code) IPADDRESS_NOEXCEPT {
684 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
685 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, scope_id, code);
686 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
687 }
688
689 /**
690 * Sets the scope identifier of the IPv6 address using a `std::u16string` and reports any errors.
691 *
692 * @param[in] scope_id The UTF-16 string representing the scope identifier.
693 * @param[out] code An error_code object that will store the result of the operation.
694 */
695 IPADDRESS_FORCE_INLINE void set_scope_id(const std::u16string& scope_id, error_code& code) IPADDRESS_NOEXCEPT {
696 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
697 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, scope_id, code);
698 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
699 }
700
701 /**
702 * Sets the scope identifier of the IPv6 address using a `std::u32string` and reports any errors.
703 *
704 * @param[in] scope_id The UTF-32 string representing the scope identifier.
705 * @param[out] code An error_code object that will store the result of the operation.
706 */
707 IPADDRESS_FORCE_INLINE void set_scope_id(const std::u32string& scope_id, error_code& code) IPADDRESS_NOEXCEPT {
708 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
709 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, scope_id, code);
710 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
711 }
712
713#endif // IPADDRESS_CPP_VERSION < 17
714
715 /**
716 * Creates an IPv6 address from an unsigned integer using a template parameter.
717 *
718 * @param[in] ip The unsigned integer representing the IPv6 address.
719 * @return An instance of ip address representing the IPv6 address.
720 */
723 auto& bytes = result._data.bytes;
724 int shift = 0;
725 int inc = 8;
726 if (is_little_endian()) {
727 shift = 56;
728 inc = -8;
729 }
730 for (int i = 0, s = shift; i < 8; ++i, s += inc) {
731 bytes[i] = uint8_t(ip.upper() >> s);
732 bytes[i + 8] = uint8_t(ip.lower() >> s);
733 }
734 return result;
735 }
736
737 /**
738 * Converts the IPv6 address to an unsigned integer.
739 *
740 * @return The unsigned integer representation of the IPv6 address.
741 * @remark Bytes in integer are presented in **host byte order**.
742 */
744 const auto& bytes = _data.bytes;
745 uint64_t upper = 0;
746 uint64_t lower = 0;
747 int shift = 0;
748 int inc = 8;
749 if (is_little_endian()) {
750 shift = 56;
751 inc = -8;
752 }
753 for (int i = 0, s = shift; i < 8; ++i, s += inc) {
754 upper |= uint64_t(bytes[i]) << s;
755 lower |= uint64_t(bytes[i + 8]) << s;
756 }
757 return uint_type(upper, lower);
758 }
759
760 /**
761 * Provides access to the underlying bytes of the IPv6 address.
762 *
763 * @return A reference to the base type containing the bytes of the IPv6 address.
764 * @remark Retrieves the data representing the IP address in **network byte order** (big-endian).
765 */
767 return _data.bytes;
768 }
769
770 /**
771 * Determines if the IPv6 address is an IPv4-mapped address.
772 *
773 * @return An `optional` containing the mapped IPv4 address if the IPv6 address is IPv4-mapped, or an empty `optional` otherwise.
774 * @remark An IPv4-mapped IPv6 address has its first 80 bits set to zero and the next 16 bits set to one (starting with `::FFFF/96`).
775 */
777 const auto& b = bytes();
778 if (b[10] != 0xFF || b[11] != 0xFF) {
779 return nullptr;
780 }
781 ipv4_address::base_type ipv4_bytes = { b[12], b[13], b[14], b[15] };
782 return ipv4_address(ipv4_bytes);
783 }
784
785 /**
786 * Determines if the IPv6 address is a 6to4 address.
787 *
788 * @return An optional containing the encapsulated IPv4 address if the IPv6 address is a 6to4 address, or an empty optional otherwise.
789 * @remark A 6to4 address uses a `2002::/16` prefix and embeds an IPv4 address in the next 32 bits.
790 * @see [RFC 3056](https://datatracker.ietf.org/doc/html/rfc3056.html).
791 */
793 const auto& b = bytes();
794 if (b[0] != 0x20 || b[1] != 0x02) {
795 return nullptr;
796 }
797 ipv4_address::base_type ipv4_bytes = { b[2], b[3], b[4], b[5] };
798 return ipv4_address(ipv4_bytes);
799 }
800
801 /**
802 * Determines if the IPv6 address is a Teredo address.
803 *
804 * @return An optional containing a pair of IPv4 addresses representing the Teredo server and client if the IPv6 address is a Teredo address, or an empty optional otherwise.
805 * @retval std::pair::first The Teredo server IPv4 address
806 * @retval std::pair::second The Teredo client IPv4 address
807 * @remark A Teredo address begins with the `2001::/32` prefix and is used for NAT traversal for IPv6.
808 * @see [RFC 4380](https://datatracker.ietf.org/doc/html/rfc4380.html).
809 */
810 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE optional<std::pair<ipv4_address, ipv4_address>> teredo() const IPADDRESS_NOEXCEPT {
811 const auto& b = bytes();
812 if (b[0] != 0x20 || b[1] != 0x01 || b[2] != 0x00 || b[3] != 0x00) {
813 return nullptr;
814 }
815 ipv4_address::base_type server_bytes = { b[4], b[5], b[6], b[7] };
816 ipv4_address::base_type client_bytes = { uint8_t(~b[12]), uint8_t(~b[13]), uint8_t(~b[14]), uint8_t(~b[15]) };
817 return std::make_pair(ipv4_address(server_bytes), ipv4_address(client_bytes));
818 }
819
820 /**
821 * Checks if the IPv6 address is a site-local address.
822 *
823 * @return `true` if the address is site-local, `false` otherwise.
824 * @parblock
825 * @note Site-local addresses are equivalent to private addresses in IPv4 and are not routable on the global internet.
826 * @endparblock
827 * @parblock
828 * @note The site-local address space is no longer recommended (per [RFC 3879](https://datatracker.ietf.org/doc/html/rfc3879.html)).
829 * Instead, use is_private to verify if the address is a unique local address ([RFC 4193](https://datatracker.ietf.org/doc/html/rfc4193.html)).
830 * @endparblock
831 * @remark These attribute is true for the network as a whole if it is true for both the network address and the broadcast address.
832 */
834
835protected:
836 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ipv6_address_base() IPADDRESS_NOEXCEPT = default;
837
838 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE explicit ipv6_address_base(const base_type& bytes) IPADDRESS_NOEXCEPT : _data(bytes) {
839 }
840
842 lhs._data.bytes.swap(rhs._data.bytes);
843 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
844 lhs._data.scope_id.swap(rhs._data.scope_id);
845 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
846 }
847
848 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE size_t hash(const base_type& bytes) const IPADDRESS_NOEXCEPT {
849 return internal::calc_hash(
850 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
851 _data.scope_id.hash(),
852 #else // IPADDRESS_IPV6_SCOPE_MAX_LENGTH <= 0
853 0,
854 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH <= 0
855 size_t(bytes[0]), size_t(bytes[1]), size_t(bytes[2]), size_t(bytes[3]),
856 size_t(bytes[4]), size_t(bytes[5]), size_t(bytes[6]), size_t(bytes[7]),
857 size_t(bytes[8]), size_t(bytes[9]), size_t(bytes[10]), size_t(bytes[11]),
858 size_t(bytes[12]), size_t(bytes[13]), size_t(bytes[14]), size_t(bytes[15]));
859 }
860
862 return lhs._data.bytes == rhs._data.bytes
863
864 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
865 && lhs._data.scope_id.compare(rhs._data.scope_id) == 0
866 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
867 ;
868 }
869
871 return lhs._data.bytes < rhs._data.bytes
872
873 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
874 ? true : lhs._data.scope_id.compare(rhs._data.scope_id) < 0;
875 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
876 ;
877 }
878
879#ifdef IPADDRESS_HAS_SPACESHIP_OPERATOR
880
882 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
884 if (const auto scope = lhs._data.scope_id.compare(rhs._data.scope_id); scope < 0) {
885 return std::strong_ordering::less;
886 } else if (scope == 0) {
888 } else {
889 return std::strong_ordering::greater;
890 }
891 } else {
892 return result;
893 }
894 #else // IPADDRESS_IPV6_SCOPE_MAX_LENGTH <= 0
895 return lhs._data.bytes <=> rhs._data.bytes;
896 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH <= 0
897 }
898
899#endif // IPADDRESS_HAS_SPACESHIP_OPERATOR
900
901 IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE size_t ip_to_chars(const base_type& bytes, format fmt, char (&result)[base_max_string_len + 1]) const IPADDRESS_NOEXCEPT {
902 return base_v6<ipv6_address_base>::ip_to_chars(bytes,
903
904 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
905 _data.scope_id,
906 #else // IPADDRESS_IPV6_SCOPE_MAX_LENGTH <= 0
907 make_fixed_string(""),
908 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH <= 0
909 fmt,
910 result);
911 }
912
913private:
915
916 template <typename>
917 friend class ip_network_base;
918
919 struct ipv6_data {
920 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ipv6_data() IPADDRESS_NOEXCEPT = default;
921 IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ipv6_data(const base_type& b) IPADDRESS_NOEXCEPT : bytes(b) {
922 }
923
924 base_type bytes{};
925 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
926 fixed_string<IPADDRESS_IPV6_SCOPE_MAX_LENGTH> scope_id;
927 #endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH
928 } _data;
929}; // ipv6_address_base
930
931/**
932 * Alias for the base class specialized for IPv6 address manipulation.
933 *
934 * This alias provides a convenient shorthand for the specialized `ip_address_base` class
935 * tailored for IPv6 address handling. It inherits all functionalities from the `ipv6_address_base`
936 * class, allowing for operations such as conversion, comparison, and property querying
937 * specific to IPv6 addresses.
938 */
940
942 const ipv4_address::base_type b = bytes();
943 ipv6_address::base_type ipv6_bytes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, b[0], b[1], b[2], b[3] };
944 return ipv6_address::from_bytes(ipv6_bytes);
945}
946
947#ifdef IPADDRESS_NONTYPE_TEMPLATE_PARAMETER
948
949 /**
950 * User-defined literal for creating an ipv6_address from a fixed string at compile time.
951 *
952 * @tparam FixedString A compile-time fixed string representing the IPv6 address.
953 * @return An ipv6_address object parsed from the fixed string.
954 */
955 IPADDRESS_EXPORT template <fixed_string FixedString>
956 IPADDRESS_NODISCARD IPADDRESS_CONSTEVAL IPADDRESS_FORCE_INLINE ipv6_address operator""_ipv6() IPADDRESS_NOEXCEPT {
957 return ipv6_address::parse<FixedString>();
958 }
959
960#else // IPADDRESS_NONTYPE_TEMPLATE_PARAMETER
961
962 /**
963 * User-defined literal for creating an ipv6_address from a string literal.
964 *
965 * @param[in] address A pointer to a character array representing the IPv6 address.
966 * @param[in] size The size of the character array.
967 * @return An ipv6_address object parsed from the string literal.
968 */
969 IPADDRESS_EXPORT IPADDRESS_NODISCARD_WHEN_NO_EXCEPTIONS IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ipv6_address operator""_ipv6(const char* address, size_t size) IPADDRESS_NOEXCEPT_WHEN_NO_EXCEPTIONS {
970 return internal::parse_ip_from_literal<ipv6_address_base, char, ipv6_address::base_max_string_len>(address, size);
971 }
972
973 /**
974 * User-defined literal for creating an ipv6_address from a wide string literal.
975 *
976 * @param[in] address A pointer to a character array representing the IPv6 address.
977 * @param[in] size The size of the character array.
978 * @return An ipv6_address object parsed from the string literal.
979 */
980 IPADDRESS_EXPORT IPADDRESS_NODISCARD_WHEN_NO_EXCEPTIONS IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ipv6_address operator""_ipv6(const wchar_t* address, size_t size) IPADDRESS_NOEXCEPT_WHEN_NO_EXCEPTIONS {
981 return internal::parse_ip_from_literal<ipv6_address_base, wchar_t, ipv6_address::base_max_string_len>(address, size);
982 }
983
984 /**
985 * User-defined literal for creating an ipv6_address from a UTF-16 string literal.
986 *
987 * @param[in] address A pointer to a character array representing the IPv6 address.
988 * @param[in] size The size of the character array.
989 * @return An ipv6_address object parsed from the string literal.
990 */
991 IPADDRESS_EXPORT IPADDRESS_NODISCARD_WHEN_NO_EXCEPTIONS IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ipv6_address operator""_ipv6(const char16_t* address, size_t size) IPADDRESS_NOEXCEPT_WHEN_NO_EXCEPTIONS {
992 return internal::parse_ip_from_literal<ipv6_address_base, char16_t, ipv6_address::base_max_string_len>(address, size);
993 }
994
995 /**
996 * User-defined literal for creating an ipv6_address from a UTF-32 string literal.
997 *
998 * @param[in] address A pointer to a character array representing the IPv6 address.
999 * @param[in] size The size of the character array.
1000 * @return An ipv6_address object parsed from the string literal.
1001 */
1002 IPADDRESS_EXPORT IPADDRESS_NODISCARD_WHEN_NO_EXCEPTIONS IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE ipv6_address operator""_ipv6(const char32_t* address, size_t size) IPADDRESS_NOEXCEPT_WHEN_NO_EXCEPTIONS {
1003 return internal::parse_ip_from_literal<ipv6_address_base, char32_t, ipv6_address::base_max_string_len>(address, size);
1004 }
1005
1006#endif // IPADDRESS_NONTYPE_TEMPLATE_PARAMETER
1007
1008} // namespace IPADDRESS_NAMESPACE
1009
1010#endif // IPADDRESS_IPV6_ADDRESS_HPP
A template class providing the base functionality for IPv6 addresses.
Definition base-v6.hpp:42
A template base class for IP address representations.
Definition ip-address-base.hpp:56
Template base class for representing a network of IP addresses.
Definition ip-network-base.hpp:32
Represents the base class for IPv4 address manipulation.
Definition ipv4-address.hpp:30
constexpr inline ipv6_address ipv6_mapped() const noexcept
Retrieves the IPv6-mapped IPv4 address.
Definition ipv6-address.hpp:941
Represents the base class for IPv6 address manipulation.
Definition ipv6-address.hpp:274
constexpr inline bool is_site_local() const noexcept
Checks if the IPv6 address is a site-local address.
Definition ip-networks.hpp:479
constexpr inline uint_type to_uint() const noexcept
Converts the IPv6 address to an unsigned integer.
Definition ipv6-address.hpp:743
constexpr inline void set_scope_id(const T(&scope_id)[N], error_code &code) noexcept
Sets the scope identifier of the IPv6 address and reports any errors encountered.
Definition ipv6-address.hpp:340
constexpr inline scope get_scope_id() const noexcept
Retrieves the scope identifier of the IPv6 address.
Definition ipv6-address.hpp:288
constexpr inline const base_type & bytes() const noexcept
Provides access to the underlying bytes of the IPv6 address.
Definition ipv6-address.hpp:766
constexpr inline void set_scope_id(const T(&scope_id)[N])
Sets the scope identifier of the IPv6 address.
Definition ipv6-address.hpp:311
constexpr inline optional< std::pair< ipv4_address, ipv4_address > > teredo() const noexcept
Determines if the IPv6 address is a Teredo address.
Definition ipv6-address.hpp:810
constexpr inline optional< ipv4_address > ipv4_mapped() const noexcept
Determines if the IPv6 address is an IPv4-mapped address.
Definition ipv6-address.hpp:776
constexpr inline optional< ipv4_address > sixtofour() const noexcept
Determines if the IPv6 address is a 6to4 address.
Definition ipv6-address.hpp:792
static constexpr inline ip_address_base< ipv6_address_base > from_uint(uint_type ip) noexcept
Creates an IPv6 address from an unsigned integer using a template parameter.
Definition ipv6-address.hpp:721
A template class to manage an optional contained value.
Definition optional.hpp:35
constexpr inline bool operator!=(const scope &rhs) const noexcept
Compares two scope objects for inequality.
Definition ipv6-address.hpp:183
inline operator std::string() const
Converts the scope object to a string representation.
Definition ipv6-address.hpp:154
constexpr inline scope(const fixed_string< IPADDRESS_IPV6_SCOPE_MAX_LENGTH > &scope_id) noexcept
Constructs a scope object with a given scope identifier.
Definition ipv6-address.hpp:97
inline std::string get_string() const
Retrieves the scope identifier as a string.
Definition ipv6-address.hpp:109
constexpr inline bool operator>(const scope &rhs) const noexcept
Checks if one scope object is greater than another.
Definition ipv6-address.hpp:217
constexpr inline operator uint32_t() const noexcept
Converts the scope object to a numeric representation.
Definition ipv6-address.hpp:163
constexpr inline bool has_uint32() const noexcept
Checks if the scope identifier has a numeric representation.
Definition ipv6-address.hpp:136
constexpr inline bool operator>=(const scope &rhs) const noexcept
Checks if one scope object is greater than or equal to another.
Definition ipv6-address.hpp:237
constexpr inline bool operator<=(const scope &rhs) const noexcept
Checks if one scope object is less than or equal to another.
Definition ipv6-address.hpp:227
constexpr inline bool has_string() const noexcept
Checks if the scope identifier has a string representation.
Definition ipv6-address.hpp:127
constexpr inline uint32_t get_uint32() const noexcept
Retrieves the scope identifier as a numeric value.
Definition ipv6-address.hpp:118
constexpr inline bool operator==(const scope &rhs) const noexcept
Compares two scope objects for equality.
Definition ipv6-address.hpp:173
constexpr inline bool operator<(const scope &rhs) const noexcept
Checks if one scope object is less than another.
Definition ipv6-address.hpp:207
constexpr inline operator bool() const noexcept
Converts the scope object to a boolean value based on the presence of a scope representation.
Definition ipv6-address.hpp:145
#define IPADDRESS_NOEXCEPT_WHEN_NO_EXCEPTIONS
Definition config.hpp:96
#define IPADDRESS_EXPORT
Definition config.hpp:45
#define IPADDRESS_NODISCARD
Definition config.hpp:101
#define IPADDRESS_FORCE_INLINE
Definition config.hpp:115
#define IPADDRESS_NAMESPACE
Definition config.hpp:41
#define IPADDRESS_NOEXCEPT
Definition config.hpp:92
#define IPADDRESS_NODISCARD_WHEN_NO_EXCEPTIONS
Definition config.hpp:105
constexpr inline bool is_little_endian() noexcept
Checks if the system is little-endian.
Definition endian.hpp:110
error_code
Enumeration of error codes for IP address parsing and validation.
Definition errors.hpp:52
@ invalid_scope_id
The scope ID in the IPv6 address is invalid.
@ no_error
Indicates the absence of any errors.
@ scope_id_is_too_long
The scope ID in the IPv6 address exceeds the maximum length.
Fixed size string class.
Definition fixed-string.hpp:29