2
3
4
5
6
7
8
9
10
11
13#ifndef IPADDRESS_IPV6_ADDRESS_HPP
14#define IPADDRESS_IPV6_ADDRESS_HPP
24struct ipv6_set_scope {
25 template <
typename Str>
27 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH
> 0
30 change(result, scope, code, index);
31 #ifndef IPADDRESS_NO_EXCEPTIONS
33 raise_error(code, index, scope.data(), scope.size());
39 template <
typename Str>
41 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH
> 0
43 change(result, scope, code, index);
47 template <
typename Str>
49 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH
> 0
50 if (scope.size() > IPADDRESS_IPV6_SCOPE_MAX_LENGTH) {
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;
60 for (
int i = 0; it < end; ++i) {
61 auto c = internal::next_char_or_error(it, end, code, error_symbol);
66 if (internal::is_invalid_scope_id_symbol(c)) {
72 const auto fixed_scope = make_fixed_string(str, code);
83
84
85
86
87
88
92
93
94
95
96
104
105
106
107
108
110 return std::string(_scope_id.begin(), _scope_id.end());
114
115
116
117
119 return _scope_id_value;
123
124
125
126
128 return !_scope_id.empty();
132
133
134
135
141
142
143
144
150
151
152
153
159
160
161
162
168
169
170
171
172
174 return _scope_id == rhs._scope_id;
178
179
180
181
182
184 return !(*
this == rhs);
187#ifdef IPADDRESS_HAS_SPACESHIP_OPERATOR
190
191
192
193
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;
202
203
204
205
206
208 return _scope_id < rhs._scope_id;
212
213
214
215
216
222
223
224
225
226
228 return !(rhs
< *
this);
232
233
234
235
236
238 return !(*
this < rhs);
245 if (!_scope_id.empty()) {
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');
258 _scope_id_value = _has_value ? value : 0;
262 fixed_string<IPADDRESS_IPV6_SCOPE_MAX_LENGTH> _scope_id;
263 uint32_t _scope_id_value = 0;
264 bool _has_value =
false;
268
269
270
271
272
273
280
281
282
283
284
285
286
287
290 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH
> 0
293 make_fixed_string(
"")
299
300
301
302
303
304
305
306
307
308
309
310 template <
typename T, size_t N>
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);
321 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, make_fixed_string(scope_id));
327
328
329
330
331
332
333
334
335
336
337
338
339 template <
typename T, size_t N>
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);
345 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, fixed_scope, code);
350#if IPADDRESS_CPP_VERSION
>= 17
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
374 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
401 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
406#if __cpp_char8_t >= 201811L
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
425 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
454 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
481 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
507 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
533 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
538#if __cpp_char8_t >= 201811L
541
542
543
544
545
546
547
548
549
550
551
552
553
554
556 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
584 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
610 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
618
619
620
621
622
624 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH
> 0
625 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, scope_id);
630
631
632
633
634
636 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH
> 0
637 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, scope_id);
642
643
644
645
646
648 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH
> 0
649 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, scope_id);
654
655
656
657
658
660 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH
> 0
661 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, scope_id);
666
667
668
669
670
672 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH
> 0
673 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, scope_id, code);
678
679
680
681
682
684 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH
> 0
685 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, scope_id, code);
690
691
692
693
694
696 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH
> 0
697 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, scope_id, code);
702
703
704
705
706
708 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH
> 0
709 internal::ipv6_set_scope<ipv6_address_base>::change(_data.scope_id, scope_id, code);
716
717
718
719
720
723 auto& bytes = result._data.bytes;
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);
738
739
740
741
742
744 const auto& bytes = _data.bytes;
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;
757 return uint_type(upper, lower);
761
762
763
764
765
771
772
773
774
775
777 const auto& b = bytes();
778 if (b[10] != 0xFF || b[11] != 0xFF) {
781 ipv4_address::base_type ipv4_bytes = { b[12], b[13], b[14], b[15] };
782 return ipv4_address(ipv4_bytes);
786
787
788
789
790
791
793 const auto& b = bytes();
794 if (b[0] != 0x20 || b[1] != 0x02) {
797 ipv4_address::base_type ipv4_bytes = { b[2], b[3], b[4], b[5] };
798 return ipv4_address(ipv4_bytes);
802
803
804
805
806
807
808
809
811 const auto& b = bytes();
812 if (b[0] != 0x20 || b[1] != 0x01 || b[2] != 0x00 || b[3] != 0x00) {
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));
821
822
823
824
825
826
827
828
829
830
831
832
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);
849 return internal::calc_hash(
850 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH
> 0
851 _data.scope_id.hash(),
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]));
862 return lhs._data.bytes == rhs._data.bytes
864 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH
> 0
865 && lhs._data.scope_id.compare(rhs._data.scope_id) == 0
871 return lhs._data.bytes < rhs._data.bytes
873 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH
> 0
874 ?
true : lhs._data.scope_id.compare(rhs._data.scope_id) < 0;
879#ifdef IPADDRESS_HAS_SPACESHIP_OPERATOR
882 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
886 }
else if (
scope == 0) {
902 return base_v6<ipv6_address_base>::ip_to_chars(bytes,
904 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH
> 0
907 make_fixed_string(
""),
925 #if IPADDRESS_IPV6_SCOPE_MAX_LENGTH
> 0
932
933
934
935
936
937
938
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);
947#ifdef IPADDRESS_NONTYPE_TEMPLATE_PARAMETER
950
951
952
953
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>();
963
964
965
966
967
968
970 return internal::parse_ip_from_literal<ipv6_address_base,
char, ipv6_address::base_max_string_len>(address, size);
974
975
976
977
978
979
981 return internal::parse_ip_from_literal<ipv6_address_base,
wchar_t, ipv6_address::base_max_string_len>(address, size);
985
986
987
988
989
990
992 return internal::parse_ip_from_literal<ipv6_address_base,
char16_t, ipv6_address::base_max_string_len>(address, size);
996
997
998
999
1000
1001
1003 return internal::parse_ip_from_literal<ipv6_address_base,
char32_t, ipv6_address::base_max_string_len>(address, size);
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