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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
55
56
57
58
59
67
68
69
70
74
75
76
77
78
79
83
84
85
86
87
88
92
93
94
95
96
97
98
102
103
104
105
106
107
108
112
113
114
115
116
117
118
121#if IPADDRESS_ENDIAN == IPADDRESS_BIG_ENDIAN
123 : _upper(upper), _lower(lower)
133
134
135
136
137
138
139
144
145
146
147
148
149
150
155
156
157
158
159
160
161
166
167
168
169
170
171
172
177
178
179
180
181
182
183
186#if IPADDRESS_ENDIAN == IPADDRESS_BIG_ENDIAN
188 : _upper(uint64_t(int64_t(lower) >> 63)), _lower(uint64_t(lower))
198
199
200
201
202
203
204
209
210
211
212
213
214
215
220
221
222
223
224
225
226
231
232
233
234
235
236
237
239 const auto result = from_double(value);
240 _upper = result._upper;
241 _lower = result._lower;
245
246
247
248
249
250
251
256
257
258
259
260
261
262
267
268
269
270
271
272
278
279
280
281
282
283
289
290
291
292
293
294
296 internal::hash_combine<8> hasher{};
297 const auto seed = hasher(_upper);
298 const auto hash = hasher(seed + 0x9e3779b9 + _lower);
303
304
305
306
307
308
310 const auto tmp = *
this;
316
317
318
319
320
321
322
323
326 std::ostringstream ss;
344 return uint128_to_oct_str(*
this);
346 return uint128_to_hex_str(*
this);
348 return uint128_to_dec_str(*
this);
353
354
355
356
357
358
359
360
362 return internal::string_converter<
wchar_t>::convert(to_string(fmt));
366
367
368
369
370
371
372
373
375 return internal::string_converter<
char16_t>::convert(to_string(fmt));
379
380
381
382
383
384
385
386
388 return internal::string_converter<
char32_t>::convert(to_string(fmt));
391#if __cpp_char8_t >= 201811L
394
395
396
397
398
399
400
401
409
410
411
412
413
414
415
416
417
419 return str_to_uint128(str.data(), str.data() + str.length(), fmt);
423
424
425
426
427
428
429
430
431
433 return str_to_uint128(str.data(), str.data() + str.length(), fmt);
437
438
439
440
441
442
443
444
445
447 return str_to_uint128(str.data(), str.data() + str.length(), fmt);
451
452
453
454
455
456
457
458
459
461 return str_to_uint128(str.data(), str.data() + str.length(), fmt);
464#if __cpp_char8_t >= 201811L
467
468
469
470
471
472
473
474
475
483
484
485
486
487
488
489
490
491
492
493
494 template <
typename T, size_t N>
496 return str_to_uint128(str, str + N, fmt);
500
501
502
503
504
505
507 return _upper || _lower;
511
512
513
514
515
516
518 return (
unsigned long long) _lower;
522
523
524
525
526
527
529 return (
long long) _lower;
533
534
535
536
537
538
540 return (
unsigned long) _lower;
544
545
546
547
548
549
551 return (
long) _lower;
555
556
557
558
559
560
562 return (
unsigned int) _lower;
566
567
568
569
570
571
577
578
579
580
581
582
584 return (
unsigned short) _lower;
588
589
590
591
592
593
595 return (
short) _lower;
599
600
601
602
603
604
606 return (
char) _lower;
610
611
612
613
614
615
617 return (
char) _lower;
621
622
623
624
625
626
628 return (
signed char) _lower;
632
633
634
635
636
637
639 return (
long double) to_double(*
this);
643
644
645
646
647
648
650 return to_double(*
this);
654
655
656
657
658
659
661 return (
float) to_double(*
this);
665
666
667
668
669
670
671
673 *
this = *
this + other;
678
679
680
681
682
683
684
686 *
this = *
this - other;
691
692
693
694
695
696
697
699 *
this = *
this * other;
704
705
706
707
708
709
710
712 *
this = *
this / other;
717
718
719
720
721
722
723
725 *
this = *
this % other;
730
731
732
733
734
735
736
738 _upper &= other._upper;
739 _lower &= other._lower;
744
745
746
747
748
749
750
752 _upper |= other._upper;
753 _lower |= other._lower;
758
759
760
761
762
763
764
766 _upper ^= other._upper;
767 _lower ^= other._lower;
772
773
774
775
776
777
778
779
780 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
782 *
this = *
this << shift;
787
788
789
790
791
792
793
794
795 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
797 *
this = *
this >> shift;
802
803
804
805
806
807
813
814
815
816
817
818
824
825
826
827
828
829
831 return { ~_upper
, ~_lower
};
835
836
837
838
839
840
841
843 const uint64_t lower = _lower + other._lower;
844 const uint64_t carry = lower < _lower ? 1 : 0;
845 return { _upper + other._upper + carry
, lower
};
849
850
851
852
853
854
855
857 const uint64_t lower = _lower - other._lower;
858 const uint64_t borrow = lower > _lower ? 1 : 0;
859 return { _upper - other._upper - borrow
, lower
};
863
864
865
866
867
868
869
872 uint64_t upper = big_mul(_lower, other._lower, lower);
873 upper += (_upper * other._lower) + (_lower * other._upper);
874 return { upper
, lower
};
878
879
880
881
882
883
884
886 return divide(*
this, other);
890
891
892
893
894
895
896
898 const auto quotient = divide(*
this, other);
899 return *
this - quotient
* other;
903
904
905
906
907
908
909
911 return { _upper & other._upper
, _lower & other._lower
};
915
916
917
918
919
920
921
923 return { _upper | other._upper
, _lower | other._lower
};
927
928
929
930
931
932
933
935 return { _upper ^ other._upper
, _lower ^ other._lower
};
939
940
941
942
943
944
945
946
947 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
952 if (shift >= 64 && shift <= 128) {
953 return { _lower << (shift - 64), 0 };
955 if (shift < 64 && shift > 0) {
956 return { (_upper << shift) + (_lower >> (64 - shift)), _lower << shift };
962
963
964
965
966
967
968
969
970 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
975 if (shift >= 64 && shift <= 128) {
976 return { 0, _upper >> (shift - 64) };
978 if (shift < 64 && shift > 0) {
979 return { _upper >> shift, (_lower >> shift) + (_upper << (64 - shift)) };
985
986
987
988
989
990
997
998
999
1000
1001
1002
1009
1010
1011
1012
1013
1014
1022
1023
1024
1025
1026
1027
1035
1036
1037
1038
1039
1040
1042 return !_upper && !_lower;
1046
1047
1048
1049
1050
1051
1052
1054 return (_upper || _lower) && (other._upper || other._lower);
1058
1059
1060
1061
1062
1063
1064
1066 return (_upper || _lower) || (other._upper || other._lower);
1070
1071
1072
1073
1074
1075
1076
1077
1078 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1084
1085
1086
1087
1088
1089
1090
1092 return _upper == other._upper && _lower == other._lower;
1096
1097
1098
1099
1100
1101
1102
1103
1104 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1110
1111
1112
1113
1114
1115
1116
1118 return !(*
this == other);
1121#ifdef IPADDRESS_HAS_SPACESHIP_OPERATOR
1124
1125
1126
1127
1128
1129
1130
1131
1138
1139
1140
1141
1142
1143
1144
1156
1157
1158
1159
1160
1161
1162
1163
1164 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1170
1171
1172
1173
1174
1175
1176
1178 return _upper < other._upper || (_upper == other._upper && _lower < other._lower);
1182
1183
1184
1185
1186
1187
1188
1189
1190 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1196
1197
1198
1199
1200
1201
1202
1204 return other
< *
this;
1208
1209
1210
1211
1212
1213
1214
1215
1216 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1222
1223
1224
1225
1226
1227
1228
1230 return !(other
< *
this);
1234
1235
1236
1237
1238
1239
1240
1241
1242 template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1248
1249
1250
1251
1252
1253
1254
1256 return !(*
this < other);
1263 auto al = uint32_t(a);
1264 auto ah = uint32_t(a >> 32);
1265 auto bl = uint32_t(b);
1266 auto bh = uint32_t(b >> 32);
1268 uint64_t mull = uint64_t(al) * bl;
1269 uint64_t t = uint64_t(ah) * bl + (mull >> 32);
1270 uint64_t tl = uint64_t(al) * bh + uint32_t(t);
1272 lower = tl << 32 | uint32_t(mull);
1274 return uint64_t(ah) * bh + (t >> 32) + (tl >> 32);
1278 if (rhs._upper == 0) {
1279 if (rhs._lower == 0) {
1283 if (lhs._upper == 0) {
1284 return lhs._lower / rhs._lower;
1289 return rhs
== lhs ? 1 : 0;
1292 return divide_slow(lhs, rhs);
1297 uint32_t(quotient._lower),
1298 uint32_t(quotient._lower >> 32),
1299 uint32_t(quotient._upper),
1300 uint32_t(quotient._upper >> 32)
1302 int32_t left_size = 4 - int32_t(leading_zero_count(quotient)) / 32;
1305 uint32_t(divisor._lower),
1306 uint32_t(divisor._lower >> 32),
1307 uint32_t(divisor._upper),
1308 uint32_t(divisor._upper >> 32)
1310 int32_t right_size = 4 - int32_t(leading_zero_count(divisor)) / 32;
1313 int32_t bits_size = left_size - right_size + 1;
1315 assert(left_size >= 1);
1316 assert(right_size >= 1);
1317 assert(left_size >= right_size);
1319 uint32_t div_hi = right[right_size - 1];
1320 uint32_t div_lo = right_size > 1 ? right[right_size - 2] : 0;
1322 uint32_t shift = leading_zero_count(div_hi);
1323 uint32_t back_shift = 32 - shift;
1326 uint32_t div_nx = right_size > 2 ? right[right_size - 3] : 0;
1327 div_hi = (div_hi << shift) | (div_lo >> back_shift);
1328 div_lo = (div_lo << shift) | (div_nx >> back_shift);
1331 for (int32_t i = left_size; i >= right_size; --i) {
1332 int32_t n = i - right_size;
1333 uint32_t t = uint32_t(i) < uint32_t(left_size) ? left[i] : 0;
1335 uint64_t val_hi = (uint64_t(t) << 32) | left[i - 1];
1336 uint32_t val_lo = (i > 1) ? left[i - 2] : 0;
1339 uint32_t val_nx = i > 2 ? left[i - 3] : 0;
1340 val_hi = (val_hi << shift) | (val_lo >> back_shift);
1341 val_lo = (val_lo << shift) | (val_nx >> back_shift);
1344 uint64_t digit = val_hi / div_hi;
1346 if (digit > 0xFFFFFFFF) {
1350 while (divide_guess_too_big(digit, val_hi, val_lo, div_hi, div_lo)) {
1355 uint32_t carry = subtract_divisor(left + n, left_size - n, right, right_size, digit);
1358 assert(carry == t + 1);
1361 carry = add_divisor(left + n, left_size - n, right, right_size);
1368 if (uint32_t(n) < uint32_t(bits_size)) {
1369 bits[n] = uint32_t(digit);
1372 if (uint32_t(i) < uint32_t(left_size)) {
1377 return { uint64_t(bits[3]) << 32 | bits[2]
, uint64_t(bits[1]) << 32 | bits[0]
};
1381 assert(q <= 0xFFFFFFFF);
1383 uint64_t chk_hi = div_hi * q;
1384 uint64_t chk_lo = div_lo * q;
1386 chk_hi += chk_lo >> 32;
1387 chk_lo = uint32_t(chk_lo);
1389 return (chk_hi > val_hi) || (chk_hi == val_hi && chk_lo > val_lo);
1394 assert(q <= 0xFFFFFFFF);
1398 for (int32_t i = 0; i < rs; ++i) {
1399 carry += right[i] * q;
1401 auto digit = uint32_t(carry);
1404 if (left[i] < digit) {
1410 return uint32_t(carry);
1418 for (int32_t i = 0; i < rs; ++i) {
1419 uint64_t digit = left[i] + carry + right[i];
1420 left[i] = uint32_t(digit);
1421 carry = digit >> 32;
1424 return uint32_t(carry);
1428 constexpr double two_pow_128 = 340282366920938463463374607431768211456.0;
1430 if (value < 0 || std::isnan(value)) {
1434 if (value >= two_pow_128) {
1435 return uint128_t(0xFFFFFFFFFFFFFFFF
, 0xFFFFFFFFFFFFFFFF
);
1439 uint64_t bits = double_to_uint64_bits(value);
1440 uint128_t result
((bits << 12) >> 1 | 0x8000000000000000
, 0x0000000000000000
);
1441 result >>= (1023 + 128 - 1 - int32_t(bits >> 52));
1449 constexpr double two_pow_52 = 4503599627370496.0;
1450 constexpr double two_pow_76 = 75557863725914323419136.0;
1451 constexpr double two_pow_104 = 20282409603651670423947251286016.0;
1452 constexpr double two_pow_128 = 340282366920938463463374607431768211456.0;
1454 constexpr uint64_t two_pow_52_bits = 0x4330000000000000;
1455 constexpr uint64_t two_pow_76_bits = 0x44B0000000000000;
1456 constexpr uint64_t two_pow_104_bits = 0x4670000000000000;
1457 constexpr uint64_t two_pow_128_bits = 0x47F0000000000000;
1459 if (value._upper == 0) {
1460 return double(value._lower);
1463 if ((value._upper >> 24) == 0) {
1464 double lower = uint64_bits_to_double(two_pow_52_bits | ((value._lower << 12) >> 12)) - two_pow_52;
1465 double upper = uint64_bits_to_double(two_pow_104_bits | (uint64_t)(value >> 52)) - two_pow_104;
1466 return double(lower + upper);
1469 double lower = uint64_bits_to_double(two_pow_76_bits | ((uint64_t)(value >> 12) >> 12) | (value._lower & 0xFFFFFF)) - two_pow_76;
1470 double upper = uint64_bits_to_double(two_pow_128_bits | (uint64_t)(value >> 76)) - two_pow_128;
1471 return double(lower + upper);
1476 std::memcpy(&result, &bits,
sizeof(
double));
1482 std::memcpy(&result, &value,
sizeof(uint64_t));
1487 if (value._upper != 0) {
1488 for (uint32_t i = 0; i < 64; ++i) {
1489 if (value._upper & (1ULL << (63 - i))) {
1494 if (value._lower != 0) {
1495 for (uint32_t i = 0; i < 64; ++i) {
1496 if (value._lower & (1ULL << (63 - i))) {
1507 for (shift = 0; shift < 32; ++shift) {
1508 if (value & (1ULL << (31 - shift))) {
1517 std::ostringstream ss;
1520 const auto q = value
/ 10;
1521 const auto r = value
- q
* 10;
1528 auto result = ss.str();
1529 std::reverse(result.begin(), result.end());
1534 std::ostringstream ss;
1537 const auto q = value
/ 8;
1538 const auto r = value
- q
* 8;
1545 auto result = ss.str();
1546 std::reverse(result.begin(), result.end());
1551 constexpr char digits[] =
"0123456789abcdef";
1553 std::ostringstream ss;
1555 const auto q = value
/ 16;
1556 const auto r = value
- q
* 16;
1558 ss << digits[r._lower];
1563 auto result = ss.str();
1564 std::reverse(result.begin(), result.end());
1568#pragma warning(push, 3
)
1570 _Pragma(
"clang diagnostic push")
1571 _Pragma(
"clang diagnostic ignored \"-Wundefined-inline\"")
1573 template <
typename T>
1577 return oct_str_to_uint128(begin, end);
1579 return hex_str_to_uint128(begin, end);
1581 return dec_str_to_uint128(begin, end);
1585 _Pragma(
"clang diagnostic pop")
1589 template <
typename T>
1591 error_code code = error_code::no_error;
1592 uint32_t error_symbol = 0;
1594 const T* it = begin;
1596 const auto c = internal::next_char_or_error(it, end, code, error_symbol);
1597 if (code != error_code::no_error) {
1599 }
else if (c ==
'\0') {
1601 }
else if (c <
'0' || c >
'9') {
1604 result = result * 10 + (c -
'0');
1609 template <
typename T>
1611 error_code code = error_code::no_error;
1612 uint32_t error_symbol = 0;
1614 const T* it = begin;
1616 const auto c = internal::next_char_or_error(it, end, code, error_symbol);
1617 if (code != error_code::no_error) {
1619 }
else if (c ==
'\0') {
1621 }
else if (c <
'0' || c >
'7') {
1624 result = result * 8 + (c -
'0');
1629 template <
typename T>
1631 error_code code = error_code::no_error;
1632 uint32_t error_symbol = 0;
1635 const T* it = begin;
1637 const auto c = internal::next_char_or_error(it, end, code, error_symbol);
1638 if (code != error_code::no_error) {
1640 }
else if (c ==
'\0') {
1642 }
else if (c >=
'0' && c <=
'9') {
1644 }
else if (c >=
'A' && c <=
'F') {
1646 }
else if (c >=
'a' && c <=
'f') {
1651 result
= result
* 16
+ digit;
1656#if IPADDRESS_ENDIAN == IPADDRESS_BIG_ENDIAN
1670
1671
1672
1673
1674
1675
1676
1677IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1683
1684
1685
1686
1687
1688
1689
1690IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1696
1697
1698
1699
1700
1701
1702
1703IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1709
1710
1711
1712
1713
1714
1715
1716IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1722
1723
1724
1725
1726
1727
1728
1729IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1735
1736
1737
1738
1739
1740
1741
1742IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1748
1749
1750
1751
1752
1753
1754
1755IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1761
1762
1763
1764
1765
1766
1767
1768IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
1774
1775
1776
1777
1778
1779
1780
1781IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1787
1788
1789
1790
1791
1792
1793
1794IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1799#ifdef IPADDRESS_HAS_SPACESHIP_OPERATOR
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813IPADDRESS_EXPORT
template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1814IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE std::strong_ordering operator<=>(T lower,
const uint128_t& other) IPADDRESS_NOEXCEPT {
1815 return uint128_t(lower) <=> other;
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879IPADDRESS_EXPORT template <
typename T,
typename =
typename std::enable_if<std::is_integral<T>::value, T>::type>
1888#ifndef IPADDRESS_NO_OVERLOAD_STD
1892#pragma warning(push, 3
)
1893#if defined(_MSC_VER)
1894# pragma warning(disable:4996
)
1895#elif defined(__GNUC__
)
1896# pragma GCC diagnostic push
1897# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1898#elif defined(__clang__)
1899 _Pragma(
"clang diagnostic push")
1900 _Pragma(
"clang diagnostic ignored \"-Wdeprecated\"")
1903template <
typename T>
1904struct _numeric_limits_uint128 {
1905 static constexpr bool is_bounded =
true;
1906 static constexpr bool is_exact =
true;
1907 static constexpr bool is_integer =
true;
1908 static constexpr bool is_modulo =
true;
1909 static constexpr bool is_specialized =
true;
1910 static constexpr bool is_iec559 =
false;
1911 static constexpr bool is_signed =
false;
1912 static constexpr bool has_denorm_loss =
false;
1913 static constexpr bool has_infinity =
false;
1914 static constexpr bool has_quiet_NaN =
false;
1915 static constexpr bool has_signaling_NaN =
false;
1916 static constexpr bool tinyness_before =
false;
1917 static constexpr bool traps =
false;
1918 static constexpr int max_digits10 = 0;
1919 static constexpr int max_exponent = 0;
1920 static constexpr int max_exponent10 = 0;
1921 static constexpr int min_exponent = 0;
1922 static constexpr int min_exponent10 = 0;
1923 static constexpr int digits = 128;
1924 static constexpr int digits10 = 38;
1925 static constexpr int radix = 2;
1926 static constexpr std::float_denorm_style has_denorm = std::denorm_absent;
1927 static constexpr std::float_round_style round_style = std::round_toward_zero;
1934 return T(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF);
1966template <
typename T>
1967constexpr bool _numeric_limits_uint128<T>::is_bounded;
1969template <
typename T>
1970constexpr bool _numeric_limits_uint128<T>::is_exact;
1972template <
typename T>
1973constexpr bool _numeric_limits_uint128<T>::is_integer;
1975template <
typename T>
1976constexpr bool _numeric_limits_uint128<T>::is_modulo;
1978template <
typename T>
1979constexpr bool _numeric_limits_uint128<T>::is_specialized;
1981template <
typename T>
1982constexpr bool _numeric_limits_uint128<T>::is_iec559;
1984template <
typename T>
1985constexpr bool _numeric_limits_uint128<T>::is_signed;
1987template <
typename T>
1988constexpr bool _numeric_limits_uint128<T>::has_denorm_loss;
1990template <
typename T>
1991constexpr bool _numeric_limits_uint128<T>::has_infinity;
1993template <
typename T>
1994constexpr bool _numeric_limits_uint128<T>::has_quiet_NaN;
1996template <
typename T>
1997constexpr bool _numeric_limits_uint128<T>::has_signaling_NaN;
1999template <
typename T>
2000constexpr bool _numeric_limits_uint128<T>::tinyness_before;
2002template <
typename T>
2003constexpr bool _numeric_limits_uint128<T>::traps;
2005template <
typename T>
2006constexpr int _numeric_limits_uint128<T>::max_digits10;
2008template <
typename T>
2009constexpr int _numeric_limits_uint128<T>::max_exponent;
2011template <
typename T>
2012constexpr int _numeric_limits_uint128<T>::max_exponent10;
2014template <
typename T>
2015constexpr int _numeric_limits_uint128<T>::min_exponent;
2017template <
typename T>
2018constexpr int _numeric_limits_uint128<T>::min_exponent10;
2020template <
typename T>
2021constexpr int _numeric_limits_uint128<T>::digits;
2023template <
typename T>
2024constexpr int _numeric_limits_uint128<T>::digits10;
2026template <
typename T>
2027constexpr int _numeric_limits_uint128<T>::radix;
2029template <
typename T>
2030constexpr std::float_denorm_style _numeric_limits_uint128<T>::has_denorm;
2032template <
typename T>
2033constexpr std::float_round_style _numeric_limits_uint128<T>::round_style;
2035#if defined(_MSC_VER)
2036# pragma warning(default:4996
)
2037#elif defined(__GNUC__
)
2038# pragma GCC diagnostic pop
2039#elif defined(__clang__)
2040 _Pragma(
"clang diagnostic pop")
2051 return value.hash();
2056 const auto tmp = value1;
2076 if (stream.flags() & ios_base::hex) {
2078 }
else if (stream.flags() & ios_base::oct) {
2082 if (stream.flags() & ios_base::uppercase) {
2083 std::transform(str.cbegin(), str.cend(), str.begin(), [](
char c){
2084 return std::toupper(c);
2093 if (stream.flags() & ios_base::hex) {
2095 }
else if (stream.flags() & ios_base::oct) {
2098 std::basic_string<T, std::char_traits<T>, std::allocator<T>> str;
2102 value = result.value();
2104 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:830
constexpr inline uint128_t & operator++() noexcept
Pre-increment operator.
Definition uint128.hpp:991
constexpr inline uint128_t & operator-=(const uint128_t &other) noexcept
Subtraction assignment operator.
Definition uint128.hpp:685
constexpr inline uint128_t(short lower) noexcept
Constructs a uint128_t instance from a signed integer.
Definition uint128.hpp:227
constexpr inline operator char() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:616
constexpr inline uint64_t lower() const noexcept
Retrieves the lower 64 bits of the uint128_t value.
Definition uint128.hpp:273
constexpr inline operator unsigned char() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:605
constexpr inline operator unsigned short() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:583
constexpr inline uint128_t(unsigned short lower) noexcept
Constructs a uint128_t instance from an unsigned integer.
Definition uint128.hpp:173
constexpr inline uint128_t & operator|=(const uint128_t &other) noexcept
Bitwise OR assignment operator.
Definition uint128.hpp:751
constexpr inline uint128_t operator++(int) noexcept
Post-increment operator.
Definition uint128.hpp:1015
constexpr inline uint128_t operator^(const uint128_t &other) const noexcept
Bitwise XOR operator with another uint128_t instance.
Definition uint128.hpp:934
constexpr inline void swap(uint128_t &other) noexcept
Swaps the values of two uint128_t instances.
Definition uint128.hpp:309
constexpr inline uint128_t & operator>>=(T shift) noexcept
Bitwise right shift assignment operator.
Definition uint128.hpp:796
constexpr inline bool operator<(const uint128_t &other) const noexcept
Less than operator with another uint128_t instance.
Definition uint128.hpp:1177
constexpr inline uint128_t(long long lower) noexcept
Constructs a uint128_t instance from a signed integer.
Definition uint128.hpp:184
constexpr inline uint128_t operator|(const uint128_t &other) const noexcept
Bitwise OR operator with another uint128_t instance.
Definition uint128.hpp:922
constexpr inline bool operator>=(T lower) const noexcept
Greater than or equal to operator with an integral type.
Definition uint128.hpp:1243
constexpr inline bool operator>(const uint128_t &other) const noexcept
Greater than operator with another uint128_t instance.
Definition uint128.hpp:1203
format
Enumerates the string formats available for uint128_t.
Definition uint128.hpp:60
@ 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:1065
constexpr inline bool operator==(T lower) const noexcept
Equality operator with an integral type.
Definition uint128.hpp:1079
constexpr inline bool operator!=(const uint128_t &other) const noexcept
Inequality operator with another uint128_t instance.
Definition uint128.hpp:1117
constexpr inline uint128_t & operator%=(const uint128_t &other) noexcept
Remainder assignment operator.
Definition uint128.hpp:724
inline std::string to_string(format fmt=format::decimal) const
Converts the uint128_t value to a string representation.
Definition uint128.hpp:324
constexpr inline uint64_t upper() const noexcept
Retrieves the upper 64 bits of the uint128_t value.
Definition uint128.hpp:284
inline uint128_t(long double value) noexcept
Constructs a uint128_t instance from a floating-point value.
Definition uint128.hpp:252
constexpr inline operator signed char() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:627
constexpr inline operator unsigned int() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:561
constexpr inline uint128_t(unsigned long lower) noexcept
Constructs a uint128_t instance from an unsigned integer.
Definition uint128.hpp:151
constexpr inline operator int() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:572
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:418
constexpr inline bool operator&&(const uint128_t &other) const noexcept
Logical AND operator.
Definition uint128.hpp:1053
constexpr inline bool operator<=(const uint128_t &other) const noexcept
Less than or equal to operator with another uint128_t instance.
Definition uint128.hpp:1229
constexpr inline uint128_t operator+() const noexcept
Unary plus operator.
Definition uint128.hpp:808
inline std::u32string to_u32string(format fmt=format::decimal) const
Converts the uint128_t value to a string representation.
Definition uint128.hpp:387
constexpr inline uint128_t operator+(const uint128_t &other) const noexcept
Addition operator with another uint128_t instance.
Definition uint128.hpp:842
inline std::u16string to_u16string(format fmt=format::decimal) const
Converts the uint128_t value to a string representation.
Definition uint128.hpp:374
constexpr inline bool operator!() const noexcept
Logical NOT operator.
Definition uint128.hpp:1041
constexpr inline uint128_t & operator*=(const uint128_t &other) noexcept
Multiplication assignment operator.
Definition uint128.hpp:698
constexpr inline uint128_t(long lower) noexcept
Constructs a uint128_t instance from a signed integer.
Definition uint128.hpp:205
constexpr inline operator long() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:550
constexpr inline operator long long() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:528
constexpr inline uint128_t & operator^=(const uint128_t &other) noexcept
Bitwise XOR assignment operator.
Definition uint128.hpp:765
inline operator float() const noexcept
Casts the uint128_t value to a floating-point type.
Definition uint128.hpp:660
inline operator double() const noexcept
Casts the uint128_t value to a floating-point type.
Definition uint128.hpp:649
inline uint128_t(double value) noexcept
Constructs a uint128_t instance from a floating-point value.
Definition uint128.hpp:238
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:594
constexpr inline uint128_t(int lower) noexcept
Constructs a uint128_t instance from a signed integer.
Definition uint128.hpp:216
constexpr inline bool operator==(const uint128_t &other) const noexcept
Equality operator with another uint128_t instance.
Definition uint128.hpp:1091
inline operator long double() const noexcept
Casts the uint128_t value to a floating-point type.
Definition uint128.hpp:638
constexpr inline uint128_t & operator&=(const uint128_t &other) noexcept
Bitwise AND assignment operator.
Definition uint128.hpp:737
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:819
constexpr inline operator unsigned long() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:539
constexpr inline size_t hash() const noexcept
Computes the hash value of the uint128_t instance.
Definition uint128.hpp:295
constexpr inline uint128_t(unsigned int lower) noexcept
Constructs a uint128_t instance from an unsigned integer.
Definition uint128.hpp:162
constexpr inline bool operator<(T lower) const noexcept
Less than operator with an integral type.
Definition uint128.hpp:1165
constexpr inline uint128_t & operator--() noexcept
Pre-decrement operator.
Definition uint128.hpp:1003
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:495
constexpr inline operator unsigned long long() const noexcept
Casts the uint128_t value to an integral type.
Definition uint128.hpp:517
constexpr inline uint128_t operator*(const uint128_t &other) const noexcept
Multiplication operator with another uint128_t instance.
Definition uint128.hpp:870
constexpr inline uint128_t operator&(const uint128_t &other) const noexcept
Bitwise AND operator with another uint128_t instance.
Definition uint128.hpp:910
inline uint128_t(float value) noexcept
Constructs a uint128_t instance from a floating-point value.
Definition uint128.hpp:263
constexpr inline bool operator!=(T lower) const noexcept
Inequality operator with an integral type.
Definition uint128.hpp:1105
constexpr inline uint128_t & operator+=(const uint128_t &other) noexcept
Addition assignment operator.
Definition uint128.hpp:672
constexpr inline uint128_t operator-(const uint128_t &other) const noexcept
Subtraction operator with another uint128_t instance.
Definition uint128.hpp:856
constexpr inline uint128_t & operator/=(const uint128_t &other) noexcept
Division assignment operator.
Definition uint128.hpp:711
constexpr inline uint128_t operator>>(T shift) const noexcept
Bitwise right shift operator with an integral type.
Definition uint128.hpp:971
constexpr inline bool operator>=(const uint128_t &other) const noexcept
Greater than or equal to operator with another uint128_t instance.
Definition uint128.hpp:1255
constexpr inline uint128_t operator%(const uint128_t &other) const noexcept
Remainder operator with another uint128_t instance.
Definition uint128.hpp:897
constexpr inline operator bool() const noexcept
Checks if the uint128_t value is non-zero.
Definition uint128.hpp:506
constexpr inline uint128_t(uint64_t upper, uint64_t lower) noexcept
Constructs a uint128_t instance from upper and lower parts.
Definition uint128.hpp:119
constexpr inline uint128_t operator--(int) noexcept
Post-decrement operator.
Definition uint128.hpp:1028
inline std::wstring to_wstring(format fmt=format::decimal) const
Converts the uint128_t value to a string representation.
Definition uint128.hpp:361
constexpr inline uint128_t operator/(const uint128_t &other) const noexcept
Division operator with another uint128_t instance.
Definition uint128.hpp:885
constexpr inline bool operator<=(T lower) const noexcept
Less than or equal to operator with an integral type.
Definition uint128.hpp:1217
constexpr inline bool operator>(T lower) const noexcept
Greater than operator with an integral type.
Definition uint128.hpp:1191
inline std::u8string to_u8string(format fmt=format::decimal) const
Converts the uint128_t value to a string representation.
Definition uint128.hpp:402
constexpr inline uint128_t(unsigned long long lower) noexcept
Constructs a uint128_t instance from an unsigned integer.
Definition uint128.hpp:140
#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:1769
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:1756
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:1678
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:1848
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:1832
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:1691
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:1743
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:1730
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:1782
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:1880
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:1795
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:1864
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:1704
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:1717