2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
23#ifndef IPADDRESS_UINT128_HPP
24#define IPADDRESS_UINT128_HPP
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
56
57
58
59
60
68
69
70
71
75
76
77
78
79
80
84
85
86
87
88
89
93
94
95
96
97
98
99
103
104
105
106
107
108
109
113
114
115
116
117
118
119
122#if IPADDRESS_ENDIAN == IPADDRESS_BIG_ENDIAN
124 : _upper(upper), _lower(lower)
134
135
136
137
138
139
140
145
146
147
148
149
150
151
156
157
158
159
160
161
162
167
168
169
170
171
172
173
178
179
180
181
182
183
184
187#if IPADDRESS_ENDIAN == IPADDRESS_BIG_ENDIAN
189 : _upper(uint64_t(int64_t(lower) >> 63)), _lower(uint64_t(lower))
199
200
201
202
203
204
205
210
211
212
213
214
215
216
221
222
223
224
225
226
227
232
233
234
235
236
237
238
240 const auto result = from_double(value);
241 _upper = result._upper;
242 _lower = result._lower;
246
247
248
249
250
251
252
257
258
259
260
261
262
263
268
269
270
271
272
273
279
280
281
282
283
284
290
291
292
293
294
295
297 internal::hash_combine<8> hasher{};
298 const auto seed = hasher(_upper);
299 const auto hash = hasher(seed + 0x9e3779b9 + _lower);
304
305
306
307
308
309
311 const auto tmp = *
this;
317
318
319
320
321
322
323
324
327 std::ostringstream ss;
345 return uint128_to_oct_str(*
this);
347 return uint128_to_hex_str(*
this);
349 return uint128_to_dec_str(*
this);
354
355
356
357
358
359
360
361
363 return internal::string_converter<
wchar_t>::convert(to_string(fmt));
367
368
369
370
371
372
373
374
376 return internal::string_converter<
char16_t>::convert(to_string(fmt));
380
381
382
383
384
385
386
387
389 return internal::string_converter<
char32_t>::convert(to_string(fmt));
392#if __cpp_char8_t >= 201811L
395
396
397
398
399
400
401
402
410
411
412
413
414
415
416
417
418
420 return str_to_uint128(str.data(), str.data() + str.length(), fmt);
424
425
426
427
428
429
430
431
432
434 return str_to_uint128(str.data(), str.data() + str.length(), fmt);
438
439
440
441
442
443
444
445
446
448 return str_to_uint128(str.data(), str.data() + str.length(), fmt);
452
453
454
455
456
457
458
459
460
462 return str_to_uint128(str.data(), str.data() + str.length(), fmt);
465#if __cpp_char8_t >= 201811L
468
469
470
471
472
473
474
475
476
484
485
486
487
488
489
490
491
492
493
494
495 template <
typename T, size_t N>
497 return str_to_uint128(str, str + N, fmt);
501
502
503
504
505
506
508 return _upper || _lower;
512
513
514
515
516
517
519 return (
unsigned long long) _lower;
523
524
525
526
527
528
530 return (
long long) _lower;
534
535
536
537
538
539
541 return (
unsigned long) _lower;
545
546
547
548
549
550
552 return (
long) _lower;
556
557
558
559
560
561
563 return (
unsigned int) _lower;
567
568
569
570
571
572
578
579
580
581
582
583
585 return (
unsigned short) _lower;
589
590
591
592
593
594
596 return (
short) _lower;
600
601
602
603
604
605
607 return (
char) _lower;
611
612
613
614
615
616
618 return (
char) _lower;
622
623
624
625
626
627
629 return (
signed char) _lower;
633
634
635
636
637
638
640 return (
long double) to_double(*
this);
644
645
646
647
648
649
651 return to_double(*
this);
655
656
657
658
659
660
662 return (
float) to_double(*
this);
666
667
668
669
670
671
672
674 *
this = *
this + other;
679
680
681
682
683
684
685
687 *
this = *
this - other;
692
693
694
695
696
697
698
700 *
this = *
this * other;
705
706
707
708
709
710
711
713 *
this = *
this / other;
718
719
720
721
722
723
724
726 *
this = *
this % other;
731
732
733
734
735
736
737
739 _upper &= other._upper;
740 _lower &= other._lower;
745
746
747
748
749
750
751
753 _upper |= other._upper;
754 _lower |= other._lower;
759
760
761
762
763
764
765
767 _upper ^= other._upper;
768 _lower ^= other._lower;
773
774
775
776
777
778
779
780
781 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
783 *
this = *
this << shift;
788
789
790
791
792
793
794
795
796 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
798 *
this = *
this >> shift;
803
804
805
806
807
808
814
815
816
817
818
819
825
826
827
828
829
830
832 return { ~_upper
, ~_lower
};
836
837
838
839
840
841
842
844 const uint64_t lower = _lower + other._lower;
845 const uint64_t carry = lower < _lower ? 1 : 0;
846 return { _upper + other._upper + carry
, lower
};
850
851
852
853
854
855
856
858 const uint64_t lower = _lower - other._lower;
859 const uint64_t borrow = lower > _lower ? 1 : 0;
860 return { _upper - other._upper - borrow
, lower
};
864
865
866
867
868
869
870
873 uint64_t upper = big_mul(_lower, other._lower, lower);
874 upper += (_upper * other._lower) + (_lower * other._upper);
875 return { upper
, lower
};
879
880
881
882
883
884
885
887 return divide(*
this, other);
891
892
893
894
895
896
897
899 const auto quotient = divide(*
this, other);
900 return *
this - quotient
* other;
904
905
906
907
908
909
910
912 return { _upper & other._upper
, _lower & other._lower
};
916
917
918
919
920
921
922
924 return { _upper | other._upper
, _lower | other._lower
};
928
929
930
931
932
933
934
936 return { _upper ^ other._upper
, _lower ^ other._lower
};
940
941
942
943
944
945
946
947
948 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
953 if (shift >= 64 && shift <= 128) {
954 return { _lower << (shift - 64), 0 };
956 if (shift < 64 && shift > 0) {
957 return { (_upper << shift) + (_lower >> (64 - shift)), _lower << shift };
963
964
965
966
967
968
969
970
971 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
976 if (shift >= 64 && shift <= 128) {
977 return { 0, _upper >> (shift - 64) };
979 if (shift < 64 && shift > 0) {
980 return { _upper >> shift, (_lower >> shift) + (_upper << (64 - shift)) };
986
987
988
989
990
991
998
999
1000
1001
1002
1003
1010
1011
1012
1013
1014
1015
1023
1024
1025
1026
1027
1028
1036
1037
1038
1039
1040
1041
1043 return !_upper && !_lower;
1047
1048
1049
1050
1051
1052
1053
1055 return (_upper || _lower) && (other._upper || other._lower);
1059
1060
1061
1062
1063
1064
1065
1067 return (_upper || _lower) || (other._upper || other._lower);
1071
1072
1073
1074
1075
1076
1077
1078
1079 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1085
1086
1087
1088
1089
1090
1091
1093 return _upper == other._upper && _lower == other._lower;
1097
1098
1099
1100
1101
1102
1103
1104
1105 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1111
1112
1113
1114
1115
1116
1117
1119 return !(*
this == other);
1122#ifdef IPADDRESS_HAS_SPACESHIP_OPERATOR
1125
1126
1127
1128
1129
1130
1131
1132
1139
1140
1141
1142
1143
1144
1145
1157
1158
1159
1160
1161
1162
1163
1164
1165 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1171
1172
1173
1174
1175
1176
1177
1179 return _upper < other._upper || (_upper == other._upper && _lower < other._lower);
1183
1184
1185
1186
1187
1188
1189
1190
1191 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1197
1198
1199
1200
1201
1202
1203
1205 return other
< *
this;
1209
1210
1211
1212
1213
1214
1215
1216
1217 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1223
1224
1225
1226
1227
1228
1229
1231 return !(other
< *
this);
1235
1236
1237
1238
1239
1240
1241
1242
1243 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1249
1250
1251
1252
1253
1254
1255
1257 return !(*
this < other);
1264 auto al = uint32_t(a);
1265 auto ah = uint32_t(a >> 32);
1266 auto bl = uint32_t(b);
1267 auto bh = uint32_t(b >> 32);
1269 uint64_t mull = uint64_t(al) * bl;
1270 uint64_t t = uint64_t(ah) * bl + (mull >> 32);
1271 uint64_t tl = uint64_t(al) * bh + uint32_t(t);
1273 lower = tl << 32 | uint32_t(mull);
1275 return uint64_t(ah) * bh + (t >> 32) + (tl >> 32);
1279 if (rhs._upper == 0) {
1280 if (rhs._lower == 0) {
1284 if (lhs._upper == 0) {
1285 return lhs._lower / rhs._lower;
1290 return rhs
== lhs ? 1 : 0;
1293 return divide_slow(lhs, rhs);
1298 uint32_t(quotient._lower),
1299 uint32_t(quotient._lower >> 32),
1300 uint32_t(quotient._upper),
1301 uint32_t(quotient._upper >> 32)
1303 int32_t left_size = 4 - int32_t(leading_zero_count(quotient)) / 32;
1306 uint32_t(divisor._lower),
1307 uint32_t(divisor._lower >> 32),
1308 uint32_t(divisor._upper),
1309 uint32_t(divisor._upper >> 32)
1311 int32_t right_size = 4 - int32_t(leading_zero_count(divisor)) / 32;
1314 int32_t bits_size = left_size - right_size + 1;
1316 assert(left_size >= 1);
1317 assert(right_size >= 1);
1318 assert(left_size >= right_size);
1320 uint32_t div_hi = right[right_size - 1];
1321 uint32_t div_lo = right_size > 1 ? right[right_size - 2] : 0;
1323 uint32_t shift = leading_zero_count(div_hi);
1324 uint32_t back_shift = 32 - shift;
1327 uint32_t div_nx = right_size > 2 ? right[right_size - 3] : 0;
1328 div_hi = (div_hi << shift) | (div_lo >> back_shift);
1329 div_lo = (div_lo << shift) | (div_nx >> back_shift);
1332 for (int32_t i = left_size; i >= right_size; --i) {
1333 int32_t n = i - right_size;
1334 uint32_t t = uint32_t(i) < uint32_t(left_size) ? left[i] : 0;
1336 uint64_t val_hi = (uint64_t(t) << 32) | left[i - 1];
1337 uint32_t val_lo = (i > 1) ? left[i - 2] : 0;
1340 uint32_t val_nx = i > 2 ? left[i - 3] : 0;
1341 val_hi = (val_hi << shift) | (val_lo >> back_shift);
1342 val_lo = (val_lo << shift) | (val_nx >> back_shift);
1345 uint64_t digit = val_hi / div_hi;
1347 if (digit > 0xFFFFFFFF) {
1351 while (divide_guess_too_big(digit, val_hi, val_lo, div_hi, div_lo)) {
1356 uint32_t carry = subtract_divisor(left + n, left_size - n, right, right_size, digit);
1359 assert(carry == t + 1);
1362 carry = add_divisor(left + n, left_size - n, right, right_size);
1369 if (uint32_t(n) < uint32_t(bits_size)) {
1370 bits[n] = uint32_t(digit);
1373 if (uint32_t(i) < uint32_t(left_size)) {
1378 return { uint64_t(bits[3]) << 32 | bits[2]
, uint64_t(bits[1]) << 32 | bits[0]
};
1382 assert(q <= 0xFFFFFFFF);
1384 uint64_t chk_hi = div_hi * q;
1385 uint64_t chk_lo = div_lo * q;
1387 chk_hi += chk_lo >> 32;
1388 chk_lo = uint32_t(chk_lo);
1390 return (chk_hi > val_hi) || (chk_hi == val_hi && chk_lo > val_lo);
1395 assert(q <= 0xFFFFFFFF);
1399 for (int32_t i = 0; i < rs; ++i) {
1400 carry += right[i] * q;
1402 auto digit = uint32_t(carry);
1405 if (left[i] < digit) {
1411 return uint32_t(carry);
1419 for (int32_t i = 0; i < rs; ++i) {
1420 uint64_t digit = left[i] + carry + right[i];
1421 left[i] = uint32_t(digit);
1422 carry = digit >> 32;
1425 return uint32_t(carry);
1429 constexpr double two_pow_128 = 340282366920938463463374607431768211456.0;
1431 if (value < 0 || std::isnan(value)) {
1435 if (value >= two_pow_128) {
1436 return uint128_t(0xFFFFFFFFFFFFFFFF
, 0xFFFFFFFFFFFFFFFF
);
1440 uint64_t bits = double_to_uint64_bits(value);
1441 uint128_t result
((bits << 12) >> 1 | 0x8000000000000000
, 0x0000000000000000
);
1442 result >>= (1023 + 128 - 1 - int32_t(bits >> 52));
1450 constexpr double two_pow_52 = 4503599627370496.0;
1451 constexpr double two_pow_76 = 75557863725914323419136.0;
1452 constexpr double two_pow_104 = 20282409603651670423947251286016.0;
1453 constexpr double two_pow_128 = 340282366920938463463374607431768211456.0;
1455 constexpr uint64_t two_pow_52_bits = 0x4330000000000000;
1456 constexpr uint64_t two_pow_76_bits = 0x44B0000000000000;
1457 constexpr uint64_t two_pow_104_bits = 0x4670000000000000;
1458 constexpr uint64_t two_pow_128_bits = 0x47F0000000000000;
1460 if (value._upper == 0) {
1461 return double(value._lower);
1464 if ((value._upper >> 24) == 0) {
1465 double lower = uint64_bits_to_double(two_pow_52_bits | ((value._lower << 12) >> 12)) - two_pow_52;
1466 double upper = uint64_bits_to_double(two_pow_104_bits | (uint64_t)(value >> 52)) - two_pow_104;
1467 return double(lower + upper);
1470 double lower = uint64_bits_to_double(two_pow_76_bits | ((uint64_t)(value >> 12) >> 12) | (value._lower & 0xFFFFFF)) - two_pow_76;
1471 double upper = uint64_bits_to_double(two_pow_128_bits | (uint64_t)(value >> 76)) - two_pow_128;
1472 return double(lower + upper);
1477 std::memcpy(&result, &bits,
sizeof(
double));
1483 std::memcpy(&result, &value,
sizeof(uint64_t));
1488 if (value._upper != 0) {
1489 for (uint32_t i = 0; i < 64; ++i) {
1490 if (value._upper & (1ULL << (63 - i))) {
1495 if (value._lower != 0) {
1496 for (uint32_t i = 0; i < 64; ++i) {
1497 if (value._lower & (1ULL << (63 - i))) {
1508 for (shift = 0; shift < 32; ++shift) {
1509 if (value & (1ULL << (31 - shift))) {
1518 std::ostringstream ss;
1521 const auto q = value
/ 10;
1522 const auto r = value
- q
* 10;
1529 auto result = ss.str();
1530 std::reverse(result.begin(), result.end());
1535 std::ostringstream ss;
1538 const auto q = value
/ 8;
1539 const auto r = value
- q
* 8;
1546 auto result = ss.str();
1547 std::reverse(result.begin(), result.end());
1552 constexpr char digits[] =
"0123456789abcdef";
1554 std::ostringstream ss;
1556 const auto q = value
/ 16;
1557 const auto r = value
- q
* 16;
1559 ss << digits[r._lower];
1564 auto result = ss.str();
1565 std::reverse(result.begin(), result.end());
1569#pragma warning(push, 3
)
1571 _Pragma(
"clang diagnostic push")
1572 _Pragma(
"clang diagnostic ignored \"-Wundefined-inline\"")
1574 template <
typename T>
1578 return oct_str_to_uint128(begin, end);
1580 return hex_str_to_uint128(begin, end);
1582 return dec_str_to_uint128(begin, end);
1586 _Pragma(
"clang diagnostic pop")
1590 template <
typename T>
1593 uint32_t error_symbol = 0;
1595 const T* it = begin;
1597 const auto c = internal::next_char_or_error(it, end, code, error_symbol);
1600 }
else if (c ==
'\0') {
1602 }
else if (c <
'0' || c >
'9') {
1605 result = result
* 10 + (c -
'0');
1610 template <
typename T>
1613 uint32_t error_symbol = 0;
1615 const T* it = begin;
1617 const auto c = internal::next_char_or_error(it, end, code, error_symbol);
1620 }
else if (c ==
'\0') {
1622 }
else if (c <
'0' || c >
'7') {
1625 result = result
* 8 + (c -
'0');
1630 template <
typename T>
1633 uint32_t error_symbol = 0;
1636 const T* it = begin;
1638 const auto c = internal::next_char_or_error(it, end, code, error_symbol);
1641 }
else if (c ==
'\0') {
1643 }
else if (c >=
'0' && c <=
'9') {
1645 }
else if (c >=
'A' && c <=
'F') {
1647 }
else if (c >=
'a' && c <=
'f') {
1652 result
= result
* 16
+ digit;
1657#if IPADDRESS_ENDIAN == IPADDRESS_BIG_ENDIAN
1671
1672
1673
1674
1675
1676
1677
1678IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1684
1685
1686
1687
1688
1689
1690
1691IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1697
1698
1699
1700
1701
1702
1703
1704IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1710
1711
1712
1713
1714
1715
1716
1717IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1723
1724
1725
1726
1727
1728
1729
1730IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1736
1737
1738
1739
1740
1741
1742
1743IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1749
1750
1751
1752
1753
1754
1755
1756IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1762
1763
1764
1765
1766
1767
1768
1769IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1775
1776
1777
1778
1779
1780
1781
1782IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1788
1789
1790
1791
1792
1793
1794
1795IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1800#ifdef IPADDRESS_HAS_SPACESHIP_OPERATOR
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814IPADDRESS_EXPORT
template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1815IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE std::strong_ordering operator<=>(T lower,
const uint128_t& other) IPADDRESS_NOEXCEPT {
1816 return uint128_t(lower) <=> other;
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1889#ifndef IPADDRESS_NO_OVERLOAD_STD
1893#pragma warning(push, 3
)
1894#if defined(_MSC_VER)
1895# pragma warning(disable:4996
)
1896#elif defined(__GNUC__
)
1897# pragma GCC diagnostic push
1898# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1899#elif defined(__clang__)
1900 _Pragma(
"clang diagnostic push")
1901 _Pragma(
"clang diagnostic ignored \"-Wdeprecated\"")
1904template <
typename T>
1905struct _numeric_limits_uint128 {
1906 static constexpr bool is_bounded =
true;
1907 static constexpr bool is_exact =
true;
1908 static constexpr bool is_integer =
true;
1909 static constexpr bool is_modulo =
true;
1910 static constexpr bool is_specialized =
true;
1911 static constexpr bool is_iec559 =
false;
1912 static constexpr bool is_signed =
false;
1913 static constexpr bool has_denorm_loss =
false;
1914 static constexpr bool has_infinity =
false;
1915 static constexpr bool has_quiet_NaN =
false;
1916 static constexpr bool has_signaling_NaN =
false;
1917 static constexpr bool tinyness_before =
false;
1918 static constexpr bool traps =
false;
1919 static constexpr int max_digits10 = 0;
1920 static constexpr int max_exponent = 0;
1921 static constexpr int max_exponent10 = 0;
1922 static constexpr int min_exponent = 0;
1923 static constexpr int min_exponent10 = 0;
1924 static constexpr int digits = 128;
1925 static constexpr int digits10 = 38;
1926 static constexpr int radix = 2;
1927 static constexpr std::float_denorm_style has_denorm = std::denorm_absent;
1928 static constexpr std::float_round_style round_style = std::round_toward_zero;
1935 return T(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF);
1967template <
typename T>
1968constexpr bool _numeric_limits_uint128<T>::is_bounded;
1970template <
typename T>
1971constexpr bool _numeric_limits_uint128<T>::is_exact;
1973template <
typename T>
1974constexpr bool _numeric_limits_uint128<T>::is_integer;
1976template <
typename T>
1977constexpr bool _numeric_limits_uint128<T>::is_modulo;
1979template <
typename T>
1980constexpr bool _numeric_limits_uint128<T>::is_specialized;
1982template <
typename T>
1983constexpr bool _numeric_limits_uint128<T>::is_iec559;
1985template <
typename T>
1986constexpr bool _numeric_limits_uint128<T>::is_signed;
1988template <
typename T>
1989constexpr bool _numeric_limits_uint128<T>::has_denorm_loss;
1991template <
typename T>
1992constexpr bool _numeric_limits_uint128<T>::has_infinity;
1994template <
typename T>
1995constexpr bool _numeric_limits_uint128<T>::has_quiet_NaN;
1997template <
typename T>
1998constexpr bool _numeric_limits_uint128<T>::has_signaling_NaN;
2000template <
typename T>
2001constexpr bool _numeric_limits_uint128<T>::tinyness_before;
2003template <
typename T>
2004constexpr bool _numeric_limits_uint128<T>::traps;
2006template <
typename T>
2007constexpr int _numeric_limits_uint128<T>::max_digits10;
2009template <
typename T>
2010constexpr int _numeric_limits_uint128<T>::max_exponent;
2012template <
typename T>
2013constexpr int _numeric_limits_uint128<T>::max_exponent10;
2015template <
typename T>
2016constexpr int _numeric_limits_uint128<T>::min_exponent;
2018template <
typename T>
2019constexpr int _numeric_limits_uint128<T>::min_exponent10;
2021template <
typename T>
2022constexpr int _numeric_limits_uint128<T>::digits;
2024template <
typename T>
2025constexpr int _numeric_limits_uint128<T>::digits10;
2027template <
typename T>
2028constexpr int _numeric_limits_uint128<T>::radix;
2030template <
typename T>
2031constexpr std::float_denorm_style _numeric_limits_uint128<T>::has_denorm;
2033template <
typename T>
2034constexpr std::float_round_style _numeric_limits_uint128<T>::round_style;
2036#if defined(_MSC_VER)
2037# pragma warning(default:4996
)
2038#elif defined(__GNUC__
)
2039# pragma GCC diagnostic pop
2040#elif defined(__clang__)
2041 _Pragma(
"clang diagnostic pop")
2052 return value.hash();
2057 const auto tmp = value1;
2077 if (stream.flags() & ios_base::hex) {
2079 }
else if (stream.flags() & ios_base::oct) {
2083 if (stream.flags() & ios_base::uppercase) {
2084 std::transform(str.cbegin(), str.cend(), str.begin(), [](
char c){
2085 return std::toupper(c);
2094 if (stream.flags() & ios_base::hex) {
2096 }
else if (stream.flags() & ios_base::oct) {
2099 std::basic_string<T, std::char_traits<T>, std::allocator<T>> str;
2103 value = result.value();
2105 stream.setstate(std::ios_base::failbit);
A template class to manage an optional contained value.
Definition optional.hpp:35
constexpr inline uint128_t() noexcept=default
Default constructor.
constexpr inline uint128_t operator~() const noexcept
Bitwise NOT operator.
Definition uint128.hpp:831
constexpr inline uint128_t & operator++() noexcept
Pre-increment operator.
Definition uint128.hpp:992
constexpr inline uint128_t & operator-=(const uint128_t &other) noexcept
Subtraction assignment operator.
Definition uint128.hpp:686
constexpr inline uint128_t(short lower) noexcept
Constructs a uint128_t instance from a signed integer.
Definition uint128.hpp:228
constexpr inline operator char() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:617
constexpr inline uint64_t lower() const noexcept
Retrieves the lower 64 bits of the uint128_t value.
Definition uint128.hpp:274
constexpr inline operator unsigned char() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:606
constexpr inline operator unsigned short() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:584
constexpr inline uint128_t(unsigned short lower) noexcept
Constructs a uint128_t instance from an unsigned integer.
Definition uint128.hpp:174
constexpr inline uint128_t & operator|=(const uint128_t &other) noexcept
Bitwise OR assignment operator.
Definition uint128.hpp:752
constexpr inline uint128_t operator++(int) noexcept
Post-increment operator.
Definition uint128.hpp:1016
constexpr inline uint128_t operator^(const uint128_t &other) const noexcept
Bitwise XOR operator with another uint128_t instance.
Definition uint128.hpp:935
constexpr inline void swap(uint128_t &other) noexcept
Swaps the values of two uint128_t instances.
Definition uint128.hpp:310
constexpr inline uint128_t & operator>>=(T shift) noexcept
Bitwise right shift assignment operator.
Definition uint128.hpp:797
constexpr inline bool operator<(const uint128_t &other) const noexcept
Less than operator with another uint128_t instance.
Definition uint128.hpp:1178
constexpr inline uint128_t(long long lower) noexcept
Constructs a uint128_t instance from a signed integer.
Definition uint128.hpp:185
constexpr inline uint128_t operator|(const uint128_t &other) const noexcept
Bitwise OR operator with another uint128_t instance.
Definition uint128.hpp:923
constexpr inline bool operator>=(T lower) const noexcept
Greater than or equal to operator with an integral type.
Definition uint128.hpp:1244
constexpr inline bool operator>(const uint128_t &other) const noexcept
Greater than operator with another uint128_t instance.
Definition uint128.hpp:1204
format
Enumerates the string formats available for uint128_t.
Definition uint128.hpp:61
@ hexadecimal
Represents the number in hexadecimal format.
@ octal
Represents the number in octal format.
@ decimal
Represents the number in decimal format.
constexpr inline bool operator||(const uint128_t &other) const noexcept
Logical OR operator.
Definition uint128.hpp:1066
constexpr inline bool operator==(T lower) const noexcept
Equality operator with an integral type.
Definition uint128.hpp:1080
constexpr inline bool operator!=(const uint128_t &other) const noexcept
Inequality operator with another uint128_t instance.
Definition uint128.hpp:1118
constexpr inline uint128_t & operator%=(const uint128_t &other) noexcept
Remainder assignment operator.
Definition uint128.hpp:725
inline std::string to_string(format fmt=format::decimal) const
Converts the uint128_t value to a string representation.
Definition uint128.hpp:325
constexpr inline uint64_t upper() const noexcept
Retrieves the upper 64 bits of the uint128_t value.
Definition uint128.hpp:285
inline uint128_t(long double value) noexcept
Constructs a uint128_t instance from a floating-point value.
Definition uint128.hpp:253
constexpr inline operator signed char() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:628
constexpr inline operator unsigned int() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:562
constexpr inline uint128_t(unsigned long lower) noexcept
Constructs a uint128_t instance from an unsigned integer.
Definition uint128.hpp:152
constexpr inline operator int() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:573
constexpr inline uint128_t(const uint128_t &other) noexcept=default
Copy constructor.
static inline optional< uint128_t > from_string(const std::string &str, format fmt=format::decimal) noexcept
Parses a string to a uint128_t instance.
Definition uint128.hpp:419
constexpr inline bool operator&&(const uint128_t &other) const noexcept
Logical AND operator.
Definition uint128.hpp:1054
constexpr inline bool operator<=(const uint128_t &other) const noexcept
Less than or equal to operator with another uint128_t instance.
Definition uint128.hpp:1230
constexpr inline uint128_t operator+() const noexcept
Unary plus operator.
Definition uint128.hpp:809
inline std::u32string to_u32string(format fmt=format::decimal) const
Converts the uint128_t value to a string representation.
Definition uint128.hpp:388
constexpr inline uint128_t operator+(const uint128_t &other) const noexcept
Addition operator with another uint128_t instance.
Definition uint128.hpp:843
inline std::u16string to_u16string(format fmt=format::decimal) const
Converts the uint128_t value to a string representation.
Definition uint128.hpp:375
constexpr inline bool operator!() const noexcept
Logical NOT operator.
Definition uint128.hpp:1042
constexpr inline uint128_t & operator*=(const uint128_t &other) noexcept
Multiplication assignment operator.
Definition uint128.hpp:699
constexpr inline uint128_t(long lower) noexcept
Constructs a uint128_t instance from a signed integer.
Definition uint128.hpp:206
constexpr inline operator long() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:551
constexpr inline operator long long() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:529
constexpr inline uint128_t & operator^=(const uint128_t &other) noexcept
Bitwise XOR assignment operator.
Definition uint128.hpp:766
inline operator float() const noexcept
Casts the uint128_t value to a floating-point type.
Definition uint128.hpp:661
inline operator double() const noexcept
Casts the uint128_t value to a floating-point type.
Definition uint128.hpp:650
inline uint128_t(double value) noexcept
Constructs a uint128_t instance from a floating-point value.
Definition uint128.hpp:239
constexpr inline uint128_t & operator=(uint128_t &&other) noexcept=default
Move assignment operator.
constexpr inline operator short() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:595
constexpr inline uint128_t(int lower) noexcept
Constructs a uint128_t instance from a signed integer.
Definition uint128.hpp:217
constexpr inline bool operator==(const uint128_t &other) const noexcept
Equality operator with another uint128_t instance.
Definition uint128.hpp:1092
inline operator long double() const noexcept
Casts the uint128_t value to a floating-point type.
Definition uint128.hpp:639
constexpr inline uint128_t & operator&=(const uint128_t &other) noexcept
Bitwise AND assignment operator.
Definition uint128.hpp:738
constexpr inline uint128_t & operator=(const uint128_t &other) noexcept=default
Assignment operator.
constexpr inline uint128_t(uint128_t &&other) noexcept=default
Move constructor.
constexpr inline uint128_t operator-() const noexcept
Unary minus operator.
Definition uint128.hpp:820
constexpr inline operator unsigned long() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:540
constexpr inline size_t hash() const noexcept
Computes the hash value of the uint128_t instance.
Definition uint128.hpp:296
constexpr inline uint128_t(unsigned int lower) noexcept
Constructs a uint128_t instance from an unsigned integer.
Definition uint128.hpp:163
constexpr inline bool operator<(T lower) const noexcept
Less than operator with an integral type.
Definition uint128.hpp:1166
constexpr inline uint128_t & operator--() noexcept
Pre-decrement operator.
Definition uint128.hpp:1004
static constexpr inline optional< uint128_t > from_string(const T(&str)[N], format fmt=format::decimal) noexcept
Parses a string to a uint128_t instance.
Definition uint128.hpp:496
constexpr inline operator unsigned long long() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:518
constexpr inline uint128_t operator*(const uint128_t &other) const noexcept
Multiplication operator with another uint128_t instance.
Definition uint128.hpp:871
constexpr inline uint128_t operator&(const uint128_t &other) const noexcept
Bitwise AND operator with another uint128_t instance.
Definition uint128.hpp:911
inline uint128_t(float value) noexcept
Constructs a uint128_t instance from a floating-point value.
Definition uint128.hpp:264
constexpr inline bool operator!=(T lower) const noexcept
Inequality operator with an integral type.
Definition uint128.hpp:1106
constexpr inline uint128_t & operator+=(const uint128_t &other) noexcept
Addition assignment operator.
Definition uint128.hpp:673
constexpr inline uint128_t operator-(const uint128_t &other) const noexcept
Subtraction operator with another uint128_t instance.
Definition uint128.hpp:857
constexpr inline uint128_t & operator/=(const uint128_t &other) noexcept
Division assignment operator.
Definition uint128.hpp:712
constexpr inline uint128_t operator>>(T shift) const noexcept
Bitwise right shift operator with an integral type.
Definition uint128.hpp:972
constexpr inline bool operator>=(const uint128_t &other) const noexcept
Greater than or equal to operator with another uint128_t instance.
Definition uint128.hpp:1256
constexpr inline uint128_t operator%(const uint128_t &other) const noexcept
Remainder operator with another uint128_t instance.
Definition uint128.hpp:898
constexpr inline operator bool() const noexcept
Checks if the uint128_t value is non-zero.
Definition uint128.hpp:507
constexpr inline uint128_t(uint64_t upper, uint64_t lower) noexcept
Constructs a uint128_t instance from upper and lower parts.
Definition uint128.hpp:120
constexpr inline uint128_t operator--(int) noexcept
Post-decrement operator.
Definition uint128.hpp:1029
inline std::wstring to_wstring(format fmt=format::decimal) const
Converts the uint128_t value to a string representation.
Definition uint128.hpp:362
constexpr inline uint128_t operator/(const uint128_t &other) const noexcept
Division operator with another uint128_t instance.
Definition uint128.hpp:886
constexpr inline bool operator<=(T lower) const noexcept
Less than or equal to operator with an integral type.
Definition uint128.hpp:1218
constexpr inline bool operator>(T lower) const noexcept
Greater than operator with an integral type.
Definition uint128.hpp:1192
inline std::u8string to_u8string(format fmt=format::decimal) const
Converts the uint128_t value to a string representation.
Definition uint128.hpp:403
constexpr inline uint128_t(unsigned long long lower) noexcept
Constructs a uint128_t instance from an unsigned integer.
Definition uint128.hpp:141
#define IPADDRESS_EXPORT
Definition config.hpp:42
#define IPADDRESS_NODISCARD
Definition config.hpp:98
#define IPADDRESS_FORCE_INLINE
Definition config.hpp:112
#define IPADDRESS_NAMESPACE
Definition config.hpp:38
#define IPADDRESS_NOEXCEPT
Definition config.hpp:89
constexpr inline uint128_t operator^(T lower, const uint128_t &value) noexcept
Performs bitwise XOR operation between an integer and a uint128_t value.
Definition uint128.hpp:1770
constexpr inline uint128_t operator|(T lower, const uint128_t &value) noexcept
Performs bitwise OR operation between an integer and a uint128_t value.
Definition uint128.hpp:1757
constexpr inline uint128_t operator+(T lower, const uint128_t &value) noexcept
Performs addition between an integer and a uint128_t value.
Definition uint128.hpp:1679
constexpr inline bool operator>(T lower, const uint128_t &other) noexcept
Compares if an integer value is greater than a uint128_t value.
Definition uint128.hpp:1849
constexpr inline bool operator<(T lower, const uint128_t &other) noexcept
Compares if an integer value is less than a uint128_t value.
Definition uint128.hpp:1833
constexpr inline uint128_t operator-(T lower, const uint128_t &value) noexcept
Performs subtraction of a uint128_t value from an integer.
Definition uint128.hpp:1692
constexpr inline uint128_t operator&(T lower, const uint128_t &value) noexcept
Performs bitwise AND operation between an integer and a uint128_t value.
Definition uint128.hpp:1744
constexpr inline uint128_t operator%(T lower, const uint128_t &value) noexcept
Calculates the remainder of division of an integer by a uint128_t value.
Definition uint128.hpp:1731
error_code
Enumeration of error codes for IP address parsing and validation.
Definition errors.hpp:52
@ no_error
Indicates the absence of any errors.
constexpr inline bool operator==(T lower, const uint128_t &other) noexcept
Checks if an integer value is equal to a uint128_t value.
Definition uint128.hpp:1783
constexpr inline bool operator>=(T lower, const uint128_t &other) noexcept
Compares if an integer value is greater than or equal to a uint128_t value.
Definition uint128.hpp:1881
constexpr inline bool operator!=(T lower, const uint128_t &other) noexcept
Checks if an integer value is not equal to a uint128_t value.
Definition uint128.hpp:1796
constexpr inline bool operator<=(T lower, const uint128_t &other) noexcept
Compares if an integer value is less than or equal to a uint128_t value.
Definition uint128.hpp:1865
constexpr inline uint128_t operator*(T lower, const uint128_t &value) noexcept
Performs multiplication between an integer and a uint128_t value.
Definition uint128.hpp:1705
constexpr inline uint128_t operator/(T lower, const uint128_t &value) noexcept
Performs division of an integer by a uint128_t value.
Definition uint128.hpp:1718