Coverage Report

Created: 2026-09-19 06:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boost/boost/charconv/detail/emulated128.hpp
Line
Count
Source
1
// Copyright 2020-2023 Daniel Lemire
2
// Copyright 2023 Matt Borland
3
// Distributed under the Boost Software License, Version 1.0.
4
// https://www.boost.org/LICENSE_1_0.txt
5
//
6
// If the architecture (e.g. Apple ARM) does not have __int128 we need to emulate it
7
8
#ifndef BOOST_CHARCONV_DETAIL_EMULATED128_HPP
9
#define BOOST_CHARCONV_DETAIL_EMULATED128_HPP
10
11
#include <boost/charconv/detail/config.hpp>
12
#include <boost/charconv/config.hpp>
13
#include <boost/core/bit.hpp>
14
#include <type_traits>
15
#include <limits>
16
#include <cstdint>
17
#include <cassert>
18
#include <cmath>
19
20
namespace boost { namespace charconv { namespace detail {
21
22
// Compilers might support built-in 128-bit integer types. However, it seems that
23
// emulating them with a pair of 64-bit integers actually produces a better code,
24
// so we avoid using those built-ins. That said, they are still useful for
25
// implementing 64-bit x 64-bit -> 128-bit multiplication.
26
27
// Memcpy-able temp class for uint128
28
struct trivial_uint128
29
{
30
    #if BOOST_CHARCONV_ENDIAN_LITTLE_BYTE
31
    std::uint64_t low;
32
    std::uint64_t high;
33
    #else
34
    std::uint64_t high;
35
    std::uint64_t low;
36
    #endif
37
};
38
39
// Macro replacement lists can not be enclosed in parentheses
40
struct uint128
41
{
42
    std::uint64_t high;
43
    std::uint64_t low;
44
45
    // Constructors
46
0
    constexpr uint128() noexcept : high {}, low {} {}
47
48
    constexpr uint128(const uint128& v) noexcept = default;
49
50
    constexpr uint128(uint128&& v) noexcept = default;
51
52
4.28M
    constexpr uint128(std::uint64_t high_, std::uint64_t low_) noexcept : high {high_}, low {low_} {}
53
54
0
    constexpr uint128(const trivial_uint128& v) noexcept : high {v.high}, low {v.low} {} // NOLINT
55
56
0
    constexpr uint128(trivial_uint128&& v) noexcept : high {v.high}, low {v.low} {} // NOLINT
57
58
0
    #define SIGNED_CONSTRUCTOR(expr) constexpr uint128(expr v) noexcept : high {v < 0 ? UINT64_MAX : UINT64_C(0)}, low {static_cast<std::uint64_t>(v)} {} // NOLINT
Unexecuted instantiation: boost::charconv::detail::uint128::uint128(char)
Unexecuted instantiation: boost::charconv::detail::uint128::uint128(signed char)
Unexecuted instantiation: boost::charconv::detail::uint128::uint128(short)
Unexecuted instantiation: boost::charconv::detail::uint128::uint128(long)
Unexecuted instantiation: boost::charconv::detail::uint128::uint128(long long)
59
0
    #define UNSIGNED_CONSTRUCTOR(expr) constexpr uint128(expr v) noexcept : high {}, low {static_cast<std::uint64_t>(v)} {} // NOLINT
Unexecuted instantiation: boost::charconv::detail::uint128::uint128(unsigned char)
Unexecuted instantiation: boost::charconv::detail::uint128::uint128(unsigned short)
Unexecuted instantiation: boost::charconv::detail::uint128::uint128(unsigned int)
Unexecuted instantiation: boost::charconv::detail::uint128::uint128(unsigned long)
Unexecuted instantiation: boost::charconv::detail::uint128::uint128(unsigned long long)
60
61
    SIGNED_CONSTRUCTOR(char)                    // NOLINT
62
    SIGNED_CONSTRUCTOR(signed char)             // NOLINT
63
    SIGNED_CONSTRUCTOR(short)                   // NOLINT
64
0
    SIGNED_CONSTRUCTOR(int)                     // NOLINT
65
    SIGNED_CONSTRUCTOR(long)                    // NOLINT
66
    SIGNED_CONSTRUCTOR(long long)               // NOLINT
67
68
    UNSIGNED_CONSTRUCTOR(unsigned char)         // NOLINT
69
    UNSIGNED_CONSTRUCTOR(unsigned short)        // NOLINT
70
    UNSIGNED_CONSTRUCTOR(unsigned)              // NOLINT
71
    UNSIGNED_CONSTRUCTOR(unsigned long)         // NOLINT
72
    UNSIGNED_CONSTRUCTOR(unsigned long long)    // NOLINT
73
74
    #ifdef BOOST_CHARCONV_HAS_INT128
75
    constexpr uint128(boost::int128_type v) noexcept :  // NOLINT : Allow implicit conversions
76
        high {static_cast<std::uint64_t>(v >> 64)},
77
0
         low {static_cast<std::uint64_t>(static_cast<boost::uint128_type>(v) & ~UINT64_C(0))} {}
78
79
    constexpr uint128(boost::uint128_type v) noexcept : // NOLINT : Allow implicit conversions
80
        high {static_cast<std::uint64_t>(v >> 64)},
81
0
         low {static_cast<std::uint64_t>(v & ~UINT64_C(0))} {}
82
    #endif
83
84
    #undef SIGNED_CONSTRUCTOR
85
    #undef UNSIGNED_CONSTRUCTOR
86
87
    // Assignment Operators
88
0
    #define SIGNED_ASSIGNMENT_OPERATOR(expr) BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &operator=(const expr& v) noexcept { high = v < 0 ? UINT64_MAX : UINT64_C(0); low = static_cast<std::uint64_t>(v); return *this; } // NOLINT
Unexecuted instantiation: boost::charconv::detail::uint128::operator=(char const&)
Unexecuted instantiation: boost::charconv::detail::uint128::operator=(signed char const&)
Unexecuted instantiation: boost::charconv::detail::uint128::operator=(short const&)
Unexecuted instantiation: boost::charconv::detail::uint128::operator=(int const&)
Unexecuted instantiation: boost::charconv::detail::uint128::operator=(long const&)
Unexecuted instantiation: boost::charconv::detail::uint128::operator=(long long const&)
89
0
    #define UNSIGNED_ASSIGNMENT_OPERATOR(expr) BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &operator=(const expr& v) noexcept { high = 0U; low = static_cast<std::uint64_t>(v); return *this; } // NOLINT
Unexecuted instantiation: boost::charconv::detail::uint128::operator=(unsigned char const&)
Unexecuted instantiation: boost::charconv::detail::uint128::operator=(unsigned short const&)
Unexecuted instantiation: boost::charconv::detail::uint128::operator=(unsigned int const&)
Unexecuted instantiation: boost::charconv::detail::uint128::operator=(unsigned long const&)
Unexecuted instantiation: boost::charconv::detail::uint128::operator=(unsigned long long const&)
90
91
    SIGNED_ASSIGNMENT_OPERATOR(char)                    // NOLINT
92
    SIGNED_ASSIGNMENT_OPERATOR(signed char)             // NOLINT
93
    SIGNED_ASSIGNMENT_OPERATOR(short)                   // NOLINT
94
    SIGNED_ASSIGNMENT_OPERATOR(int)                     // NOLINT
95
    SIGNED_ASSIGNMENT_OPERATOR(long)                    // NOLINT
96
    SIGNED_ASSIGNMENT_OPERATOR(long long)               // NOLINT
97
98
    UNSIGNED_ASSIGNMENT_OPERATOR(unsigned char)         // NOLINT
99
    UNSIGNED_ASSIGNMENT_OPERATOR(unsigned short)        // NOLINT
100
    UNSIGNED_ASSIGNMENT_OPERATOR(unsigned)              // NOLINT
101
    UNSIGNED_ASSIGNMENT_OPERATOR(unsigned long)         // NOLINT
102
    UNSIGNED_ASSIGNMENT_OPERATOR(unsigned long long)    // NOLINT
103
104
    #ifdef BOOST_CHARCONV_HAS_INT128
105
0
    BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &operator=(const boost::int128_type&  v) noexcept { *this = uint128(v); return *this; }
106
0
    BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &operator=(const boost::uint128_type& v) noexcept { *this = uint128(v); return *this; }
107
    #endif
108
109
0
    BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &operator=(const trivial_uint128& v) noexcept { this->low = v.low; this->high = v.high; return *this; }
110
111
    BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &operator=(const uint128&) noexcept;
112
113
    #undef SIGNED_ASSIGNMENT_OPERATOR
114
    #undef UNSIGNED_ASSIGNMENT_OPERATOR
115
116
    // Conversion Operators
117
0
    #define INTEGER_CONVERSION_OPERATOR(expr) explicit constexpr operator expr() const noexcept { return static_cast<expr>(low); } // NOLINT
Unexecuted instantiation: boost::charconv::detail::uint128::operator char() const
Unexecuted instantiation: boost::charconv::detail::uint128::operator signed char() const
Unexecuted instantiation: boost::charconv::detail::uint128::operator short() const
Unexecuted instantiation: boost::charconv::detail::uint128::operator int() const
Unexecuted instantiation: boost::charconv::detail::uint128::operator long() const
Unexecuted instantiation: boost::charconv::detail::uint128::operator long long() const
Unexecuted instantiation: boost::charconv::detail::uint128::operator unsigned char() const
Unexecuted instantiation: boost::charconv::detail::uint128::operator unsigned short() const
Unexecuted instantiation: boost::charconv::detail::uint128::operator unsigned int() const
Unexecuted instantiation: boost::charconv::detail::uint128::operator unsigned long() const
Unexecuted instantiation: boost::charconv::detail::uint128::operator unsigned long long() const
118
0
    #define FLOAT_CONVERSION_OPERATOR(expr) explicit operator expr() const noexcept { return std::ldexp(static_cast<expr>(high), 64) + static_cast<expr>(low); } // NOLINT
Unexecuted instantiation: boost::charconv::detail::uint128::operator float() const
Unexecuted instantiation: boost::charconv::detail::uint128::operator double() const
Unexecuted instantiation: boost::charconv::detail::uint128::operator long double() const
119
120
    INTEGER_CONVERSION_OPERATOR(char)                   // NOLINT
121
    INTEGER_CONVERSION_OPERATOR(signed char)            // NOLINT
122
    INTEGER_CONVERSION_OPERATOR(short)                  // NOLINT
123
    INTEGER_CONVERSION_OPERATOR(int)                    // NOLINT
124
    INTEGER_CONVERSION_OPERATOR(long)                   // NOLINT
125
    INTEGER_CONVERSION_OPERATOR(long long)              // NOLINT
126
    INTEGER_CONVERSION_OPERATOR(unsigned char)          // NOLINT
127
    INTEGER_CONVERSION_OPERATOR(unsigned short)         // NOLINT
128
    INTEGER_CONVERSION_OPERATOR(unsigned)               // NOLINT
129
    INTEGER_CONVERSION_OPERATOR(unsigned long)          // NOLINT
130
    INTEGER_CONVERSION_OPERATOR(unsigned long long)     // NOLINT
131
132
0
    explicit constexpr operator bool() const noexcept { return high || low; }
133
134
    #ifdef BOOST_CHARCONV_HAS_INT128
135
0
    explicit constexpr operator boost::int128_type()  const noexcept { return (static_cast<boost::int128_type>(high) << 64) + low; }
136
0
    explicit constexpr operator boost::uint128_type() const noexcept { return (static_cast<boost::uint128_type>(high) << 64) + low; }
137
    #endif
138
139
    FLOAT_CONVERSION_OPERATOR(float)        // NOLINT
140
    FLOAT_CONVERSION_OPERATOR(double)       // NOLINT
141
    FLOAT_CONVERSION_OPERATOR(long double)  // NOLINT
142
143
    #undef INTEGER_CONVERSION_OPERATOR
144
    #undef FLOAT_CONVERSION_OPERATOR
145
146
    // Unary Operators
147
    constexpr friend uint128 operator-(uint128 val) noexcept;
148
    constexpr friend uint128 operator+(uint128 val) noexcept;
149
150
    // Comparison Operators
151
152
    // Equality
153
0
    #define INTEGER_OPERATOR_EQUAL(expr) constexpr friend bool operator==(uint128 lhs, expr rhs) noexcept { return lhs.high == 0 && rhs >= 0 && lhs.low == static_cast<std::uint64_t>(rhs); } // NOLINT
Unexecuted instantiation: boost::charconv::detail::operator==(boost::charconv::detail::uint128, char)
Unexecuted instantiation: boost::charconv::detail::operator==(boost::charconv::detail::uint128, signed char)
Unexecuted instantiation: boost::charconv::detail::operator==(boost::charconv::detail::uint128, short)
Unexecuted instantiation: boost::charconv::detail::operator==(boost::charconv::detail::uint128, int)
Unexecuted instantiation: boost::charconv::detail::operator==(boost::charconv::detail::uint128, long)
Unexecuted instantiation: boost::charconv::detail::operator==(boost::charconv::detail::uint128, long long)
154
0
    #define UNSIGNED_INTEGER_OPERATOR_EQUAL(expr) constexpr friend bool operator==(uint128 lhs, expr rhs) noexcept { return lhs.high == 0 && lhs.low == static_cast<std::uint64_t>(rhs); } // NOLINT
Unexecuted instantiation: boost::charconv::detail::operator==(boost::charconv::detail::uint128, unsigned char)
Unexecuted instantiation: boost::charconv::detail::operator==(boost::charconv::detail::uint128, unsigned short)
Unexecuted instantiation: boost::charconv::detail::operator==(boost::charconv::detail::uint128, unsigned int)
Unexecuted instantiation: boost::charconv::detail::operator==(boost::charconv::detail::uint128, unsigned long)
Unexecuted instantiation: boost::charconv::detail::operator==(boost::charconv::detail::uint128, unsigned long long)
155
156
    INTEGER_OPERATOR_EQUAL(char)                        // NOLINT
157
    INTEGER_OPERATOR_EQUAL(signed char)                 // NOLINT
158
    INTEGER_OPERATOR_EQUAL(short)                       // NOLINT
159
    INTEGER_OPERATOR_EQUAL(int)                         // NOLINT
160
    INTEGER_OPERATOR_EQUAL(long)                        // NOLINT
161
    INTEGER_OPERATOR_EQUAL(long long)                   // NOLINT
162
    UNSIGNED_INTEGER_OPERATOR_EQUAL(unsigned char)      // NOLINT
163
    UNSIGNED_INTEGER_OPERATOR_EQUAL(unsigned short)     // NOLINT
164
    UNSIGNED_INTEGER_OPERATOR_EQUAL(unsigned)           // NOLINT
165
    UNSIGNED_INTEGER_OPERATOR_EQUAL(unsigned long)      // NOLINT
166
    UNSIGNED_INTEGER_OPERATOR_EQUAL(unsigned long long) // NOLINT
167
168
    #ifdef BOOST_CHARCONV_HAS_INT128
169
0
    constexpr friend bool operator==(uint128 lhs, boost::int128_type  rhs) noexcept { return lhs == uint128(rhs); }
170
0
    constexpr friend bool operator==(uint128 lhs, boost::uint128_type rhs) noexcept { return lhs == uint128(rhs); }
171
    #endif
172
173
    constexpr friend bool operator==(uint128 lhs, uint128 rhs) noexcept;
174
175
    #undef INTEGER_OPERATOR_EQUAL
176
    #undef UNSIGNED_INTEGER_OPERATOR_EQUAL
177
178
    // Inequality
179
0
    #define INTEGER_OPERATOR_NOTEQUAL(expr) constexpr friend bool operator!=(uint128 lhs, expr rhs) noexcept { return !(lhs == rhs); } // NOLINT
Unexecuted instantiation: boost::charconv::detail::operator!=(boost::charconv::detail::uint128, char)
Unexecuted instantiation: boost::charconv::detail::operator!=(boost::charconv::detail::uint128, signed char)
Unexecuted instantiation: boost::charconv::detail::operator!=(boost::charconv::detail::uint128, short)
Unexecuted instantiation: boost::charconv::detail::operator!=(boost::charconv::detail::uint128, int)
Unexecuted instantiation: boost::charconv::detail::operator!=(boost::charconv::detail::uint128, long)
Unexecuted instantiation: boost::charconv::detail::operator!=(boost::charconv::detail::uint128, long long)
Unexecuted instantiation: boost::charconv::detail::operator!=(boost::charconv::detail::uint128, unsigned char)
Unexecuted instantiation: boost::charconv::detail::operator!=(boost::charconv::detail::uint128, unsigned short)
Unexecuted instantiation: boost::charconv::detail::operator!=(boost::charconv::detail::uint128, unsigned int)
Unexecuted instantiation: boost::charconv::detail::operator!=(boost::charconv::detail::uint128, unsigned long)
Unexecuted instantiation: boost::charconv::detail::operator!=(boost::charconv::detail::uint128, unsigned long long)
180
181
    INTEGER_OPERATOR_NOTEQUAL(char)                 // NOLINT
182
    INTEGER_OPERATOR_NOTEQUAL(signed char)          // NOLINT
183
    INTEGER_OPERATOR_NOTEQUAL(short)                // NOLINT
184
    INTEGER_OPERATOR_NOTEQUAL(int)                  // NOLINT
185
    INTEGER_OPERATOR_NOTEQUAL(long)                 // NOLINT
186
    INTEGER_OPERATOR_NOTEQUAL(long long)            // NOLINT
187
    INTEGER_OPERATOR_NOTEQUAL(unsigned char)        // NOLINT
188
    INTEGER_OPERATOR_NOTEQUAL(unsigned short)       // NOLINT
189
    INTEGER_OPERATOR_NOTEQUAL(unsigned)             // NOLINT
190
    INTEGER_OPERATOR_NOTEQUAL(unsigned long)        // NOLINT
191
    INTEGER_OPERATOR_NOTEQUAL(unsigned long long)   // NOLINT
192
193
    #ifdef BOOST_CHARCONV_HAS_INT128
194
0
    constexpr friend bool operator!=(uint128 lhs, boost::int128_type  rhs) noexcept { return !(lhs == rhs); }
195
0
    constexpr friend bool operator!=(uint128 lhs, boost::uint128_type rhs) noexcept { return !(lhs == rhs); }
196
    #endif
197
198
    constexpr friend bool operator!=(uint128 lhs, uint128 rhs) noexcept;
199
200
    #undef INTEGER_OPERATOR_NOTEQUAL
201
202
    // Less than
203
0
    #define INTEGER_OPERATOR_LESS_THAN(expr) constexpr friend bool operator<(uint128 lhs, expr rhs) noexcept { return lhs.high == 0U && rhs > 0 && lhs.low < static_cast<std::uint64_t>(rhs); } // NOLINT
Unexecuted instantiation: boost::charconv::detail::operator<(boost::charconv::detail::uint128, char)
Unexecuted instantiation: boost::charconv::detail::operator<(boost::charconv::detail::uint128, signed char)
Unexecuted instantiation: boost::charconv::detail::operator<(boost::charconv::detail::uint128, short)
Unexecuted instantiation: boost::charconv::detail::operator<(boost::charconv::detail::uint128, int)
Unexecuted instantiation: boost::charconv::detail::operator<(boost::charconv::detail::uint128, long)
Unexecuted instantiation: boost::charconv::detail::operator<(boost::charconv::detail::uint128, long long)
204
0
    #define UNSIGNED_INTEGER_OPERATOR_LESS_THAN(expr) constexpr friend bool operator<(uint128 lhs, expr rhs) noexcept { return lhs.high == 0U && lhs.low < static_cast<std::uint64_t>(rhs); } // NOLINT
Unexecuted instantiation: boost::charconv::detail::operator<(boost::charconv::detail::uint128, unsigned char)
Unexecuted instantiation: boost::charconv::detail::operator<(boost::charconv::detail::uint128, unsigned short)
Unexecuted instantiation: boost::charconv::detail::operator<(boost::charconv::detail::uint128, unsigned int)
Unexecuted instantiation: boost::charconv::detail::operator<(boost::charconv::detail::uint128, unsigned long)
Unexecuted instantiation: boost::charconv::detail::operator<(boost::charconv::detail::uint128, unsigned long long)
205
206
    INTEGER_OPERATOR_LESS_THAN(char)                            // NOLINT
207
    INTEGER_OPERATOR_LESS_THAN(signed char)                     // NOLINT
208
    INTEGER_OPERATOR_LESS_THAN(short)                           // NOLINT
209
    INTEGER_OPERATOR_LESS_THAN(int)                             // NOLINT
210
    INTEGER_OPERATOR_LESS_THAN(long)                            // NOLINT
211
    INTEGER_OPERATOR_LESS_THAN(long long)                       // NOLINT
212
    UNSIGNED_INTEGER_OPERATOR_LESS_THAN(unsigned char)          // NOLINT
213
    UNSIGNED_INTEGER_OPERATOR_LESS_THAN(unsigned short)         // NOLINT
214
    UNSIGNED_INTEGER_OPERATOR_LESS_THAN(unsigned)               // NOLINT
215
    UNSIGNED_INTEGER_OPERATOR_LESS_THAN(unsigned long)          // NOLINT
216
    UNSIGNED_INTEGER_OPERATOR_LESS_THAN(unsigned long long)     // NOLINT
217
218
    #ifdef BOOST_CHARCONV_HAS_INT128
219
0
    BOOST_CHARCONV_CXX14_CONSTEXPR friend bool operator<(uint128 lhs, boost::int128_type  rhs) noexcept { return lhs < uint128(rhs); }
220
0
    BOOST_CHARCONV_CXX14_CONSTEXPR friend bool operator<(uint128 lhs, boost::uint128_type rhs) noexcept { return lhs < uint128(rhs); }
221
    #endif
222
223
    BOOST_CHARCONV_CXX14_CONSTEXPR friend bool operator<(uint128 lhs, uint128 rhs) noexcept;
224
225
    #undef INTEGER_OPERATOR_LESS_THAN
226
    #undef UNSIGNED_INTEGER_OPERATOR_LESS_THAN
227
228
    // Less than or equal to
229
0
    #define INTEGER_OPERATOR_LESS_THAN_OR_EQUAL_TO(expr) constexpr friend bool operator<=(uint128 lhs, expr rhs) noexcept { return lhs.high == 0U && rhs >= 0 && lhs.low <= static_cast<std::uint64_t>(rhs); } // NOLINT
Unexecuted instantiation: boost::charconv::detail::operator<=(boost::charconv::detail::uint128, char)
Unexecuted instantiation: boost::charconv::detail::operator<=(boost::charconv::detail::uint128, signed char)
Unexecuted instantiation: boost::charconv::detail::operator<=(boost::charconv::detail::uint128, short)
Unexecuted instantiation: boost::charconv::detail::operator<=(boost::charconv::detail::uint128, int)
Unexecuted instantiation: boost::charconv::detail::operator<=(boost::charconv::detail::uint128, long)
Unexecuted instantiation: boost::charconv::detail::operator<=(boost::charconv::detail::uint128, long long)
230
0
    #define UNSIGNED_INTEGER_OPERATOR_LESS_THAN_OR_EQUAL_TO(expr) constexpr friend bool operator<=(uint128 lhs, expr rhs) noexcept { return lhs.high == 0U && lhs.low <= static_cast<std::uint64_t>(rhs); } // NOLINT
Unexecuted instantiation: boost::charconv::detail::operator<=(boost::charconv::detail::uint128, unsigned char)
Unexecuted instantiation: boost::charconv::detail::operator<=(boost::charconv::detail::uint128, unsigned short)
Unexecuted instantiation: boost::charconv::detail::operator<=(boost::charconv::detail::uint128, unsigned int)
Unexecuted instantiation: boost::charconv::detail::operator<=(boost::charconv::detail::uint128, unsigned long)
Unexecuted instantiation: boost::charconv::detail::operator<=(boost::charconv::detail::uint128, unsigned long long)
231
232
    INTEGER_OPERATOR_LESS_THAN_OR_EQUAL_TO(char)                            // NOLINT
233
    INTEGER_OPERATOR_LESS_THAN_OR_EQUAL_TO(signed char)                     // NOLINT
234
    INTEGER_OPERATOR_LESS_THAN_OR_EQUAL_TO(short)                           // NOLINT
235
    INTEGER_OPERATOR_LESS_THAN_OR_EQUAL_TO(int)                             // NOLINT
236
    INTEGER_OPERATOR_LESS_THAN_OR_EQUAL_TO(long)                            // NOLINT
237
    INTEGER_OPERATOR_LESS_THAN_OR_EQUAL_TO(long long)                       // NOLINT
238
    UNSIGNED_INTEGER_OPERATOR_LESS_THAN_OR_EQUAL_TO(unsigned char)          // NOLINT
239
    UNSIGNED_INTEGER_OPERATOR_LESS_THAN_OR_EQUAL_TO(unsigned short)         // NOLINT
240
    UNSIGNED_INTEGER_OPERATOR_LESS_THAN_OR_EQUAL_TO(unsigned)               // NOLINT
241
    UNSIGNED_INTEGER_OPERATOR_LESS_THAN_OR_EQUAL_TO(unsigned long)          // NOLINT
242
    UNSIGNED_INTEGER_OPERATOR_LESS_THAN_OR_EQUAL_TO(unsigned long long)     // NOLINT
243
244
    #ifdef BOOST_CHARCONV_HAS_INT128
245
0
    BOOST_CHARCONV_CXX14_CONSTEXPR friend bool operator<=(uint128 lhs, boost::int128_type  rhs) noexcept { return lhs <= uint128(rhs); }
246
0
    BOOST_CHARCONV_CXX14_CONSTEXPR friend bool operator<=(uint128 lhs, boost::uint128_type rhs) noexcept { return lhs <= uint128(rhs); }
247
    #endif
248
249
    BOOST_CHARCONV_CXX14_CONSTEXPR friend bool operator<=(uint128 lhs, uint128 rhs) noexcept;
250
251
    #undef INTEGER_OPERATOR_LESS_THAN_OR_EQUAL_TO
252
    #undef UNSIGNED_INTEGER_OPERATOR_LESS_THAN_OR_EQUAL_TO
253
254
    // Greater than
255
0
    #define INTEGER_OPERATOR_GREATER_THAN(expr) constexpr friend bool operator>(uint128 lhs, expr rhs) noexcept { return lhs.high > 0U || rhs < 0 || lhs.low > static_cast<std::uint64_t>(rhs); } // NOLINT
Unexecuted instantiation: boost::charconv::detail::operator>(boost::charconv::detail::uint128, char)
Unexecuted instantiation: boost::charconv::detail::operator>(boost::charconv::detail::uint128, signed char)
Unexecuted instantiation: boost::charconv::detail::operator>(boost::charconv::detail::uint128, short)
Unexecuted instantiation: boost::charconv::detail::operator>(boost::charconv::detail::uint128, int)
Unexecuted instantiation: boost::charconv::detail::operator>(boost::charconv::detail::uint128, long)
Unexecuted instantiation: boost::charconv::detail::operator>(boost::charconv::detail::uint128, long long)
256
0
    #define UNSIGNED_INTEGER_OPERATOR_GREATER_THAN(expr) constexpr friend bool operator>(uint128 lhs, expr rhs) noexcept { return lhs.high > 0U || lhs.low > static_cast<std::uint64_t>(rhs); } // NOLINT
Unexecuted instantiation: boost::charconv::detail::operator>(boost::charconv::detail::uint128, unsigned char)
Unexecuted instantiation: boost::charconv::detail::operator>(boost::charconv::detail::uint128, unsigned short)
Unexecuted instantiation: boost::charconv::detail::operator>(boost::charconv::detail::uint128, unsigned int)
Unexecuted instantiation: boost::charconv::detail::operator>(boost::charconv::detail::uint128, unsigned long)
Unexecuted instantiation: boost::charconv::detail::operator>(boost::charconv::detail::uint128, unsigned long long)
257
258
    INTEGER_OPERATOR_GREATER_THAN(char)                             // NOLINT
259
    INTEGER_OPERATOR_GREATER_THAN(signed char)                      // NOLINT
260
    INTEGER_OPERATOR_GREATER_THAN(short)                            // NOLINT
261
    INTEGER_OPERATOR_GREATER_THAN(int)                              // NOLINT
262
    INTEGER_OPERATOR_GREATER_THAN(long)                             // NOLINT
263
    INTEGER_OPERATOR_GREATER_THAN(long long)                        // NOLINT
264
    UNSIGNED_INTEGER_OPERATOR_GREATER_THAN(unsigned char)           // NOLINT
265
    UNSIGNED_INTEGER_OPERATOR_GREATER_THAN(unsigned short)          // NOLINT
266
    UNSIGNED_INTEGER_OPERATOR_GREATER_THAN(unsigned)                // NOLINT
267
    UNSIGNED_INTEGER_OPERATOR_GREATER_THAN(unsigned long)           // NOLINT
268
    UNSIGNED_INTEGER_OPERATOR_GREATER_THAN(unsigned long long)      // NOLINT
269
270
    #ifdef BOOST_CHARCONV_HAS_INT128
271
0
    BOOST_CHARCONV_CXX14_CONSTEXPR friend bool operator>(uint128 lhs, boost::int128_type  rhs) noexcept { return lhs > uint128(rhs); }
272
0
    BOOST_CHARCONV_CXX14_CONSTEXPR friend bool operator>(uint128 lhs, boost::uint128_type rhs) noexcept { return lhs > uint128(rhs); }
273
    #endif
274
275
    BOOST_CHARCONV_CXX14_CONSTEXPR friend bool operator>(uint128 lhs, uint128 rhs) noexcept;
276
277
    #undef INTEGER_OPERATOR_GREATER_THAN
278
    #undef UNSIGNED_INTEGER_OPERATOR_GREATER_THAN
279
280
    // Greater than or equal to
281
0
    #define INTEGER_OPERATOR_GREATER_THAN_OR_EQUAL_TO(expr) constexpr friend bool operator>=(uint128 lhs, expr rhs) noexcept { return lhs.high > 0U || rhs < 0 || lhs.low >= static_cast<std::uint64_t>(rhs); } // NOLINT
Unexecuted instantiation: boost::charconv::detail::operator>=(boost::charconv::detail::uint128, char)
Unexecuted instantiation: boost::charconv::detail::operator>=(boost::charconv::detail::uint128, signed char)
Unexecuted instantiation: boost::charconv::detail::operator>=(boost::charconv::detail::uint128, short)
Unexecuted instantiation: boost::charconv::detail::operator>=(boost::charconv::detail::uint128, int)
Unexecuted instantiation: boost::charconv::detail::operator>=(boost::charconv::detail::uint128, long)
Unexecuted instantiation: boost::charconv::detail::operator>=(boost::charconv::detail::uint128, long long)
282
0
    #define UNSIGNED_INTEGER_OPERATOR_GREATER_THAN_OR_EQUAL_TO(expr) constexpr friend bool operator>=(uint128 lhs, expr rhs) noexcept { return lhs.high > 0U || lhs.low >= static_cast<std::uint64_t>(rhs); } // NOLINT
Unexecuted instantiation: boost::charconv::detail::operator>=(boost::charconv::detail::uint128, unsigned char)
Unexecuted instantiation: boost::charconv::detail::operator>=(boost::charconv::detail::uint128, unsigned short)
Unexecuted instantiation: boost::charconv::detail::operator>=(boost::charconv::detail::uint128, unsigned int)
Unexecuted instantiation: boost::charconv::detail::operator>=(boost::charconv::detail::uint128, unsigned long)
Unexecuted instantiation: boost::charconv::detail::operator>=(boost::charconv::detail::uint128, unsigned long long)
283
284
    INTEGER_OPERATOR_GREATER_THAN_OR_EQUAL_TO(char)                             // NOLINT
285
    INTEGER_OPERATOR_GREATER_THAN_OR_EQUAL_TO(signed char)                      // NOLINT
286
    INTEGER_OPERATOR_GREATER_THAN_OR_EQUAL_TO(short)                            // NOLINT
287
    INTEGER_OPERATOR_GREATER_THAN_OR_EQUAL_TO(int)                              // NOLINT
288
    INTEGER_OPERATOR_GREATER_THAN_OR_EQUAL_TO(long)                             // NOLINT
289
    INTEGER_OPERATOR_GREATER_THAN_OR_EQUAL_TO(long long)                        // NOLINT
290
    UNSIGNED_INTEGER_OPERATOR_GREATER_THAN_OR_EQUAL_TO(unsigned char)           // NOLINT
291
    UNSIGNED_INTEGER_OPERATOR_GREATER_THAN_OR_EQUAL_TO(unsigned short)          // NOLINT
292
    UNSIGNED_INTEGER_OPERATOR_GREATER_THAN_OR_EQUAL_TO(unsigned)                // NOLINT
293
    UNSIGNED_INTEGER_OPERATOR_GREATER_THAN_OR_EQUAL_TO(unsigned long)           // NOLINT
294
    UNSIGNED_INTEGER_OPERATOR_GREATER_THAN_OR_EQUAL_TO(unsigned long long)      // NOLINT
295
296
    #ifdef BOOST_CHARCONV_HAS_INT128
297
0
    BOOST_CHARCONV_CXX14_CONSTEXPR friend bool operator>=(uint128 lhs, boost::int128_type  rhs) noexcept { return lhs >= uint128(rhs); }
298
0
    BOOST_CHARCONV_CXX14_CONSTEXPR friend bool operator>=(uint128 lhs, boost::uint128_type rhs) noexcept { return lhs >= uint128(rhs); }
299
    #endif
300
301
    BOOST_CHARCONV_CXX14_CONSTEXPR friend bool operator>=(uint128 lhs, uint128 rhs) noexcept;
302
303
    #undef INTEGER_OPERATOR_GREATER_THAN_OR_EQUAL_TO
304
    #undef UNSIGNED_INTEGER_OPERATOR_GREATER_THAN_OR_EQUAL_TO
305
306
    // Binary Operators
307
308
    // Not
309
    constexpr friend uint128 operator~(uint128 v) noexcept;
310
311
    // Or
312
0
    #define INTEGER_BINARY_OPERATOR_OR(expr) constexpr friend uint128 operator|(uint128 lhs, expr rhs) noexcept { return {lhs.high, lhs.low | static_cast<std::uint64_t>(rhs)}; } // NOLINT
Unexecuted instantiation: boost::charconv::detail::operator|(boost::charconv::detail::uint128, char)
Unexecuted instantiation: boost::charconv::detail::operator|(boost::charconv::detail::uint128, signed char)
Unexecuted instantiation: boost::charconv::detail::operator|(boost::charconv::detail::uint128, short)
Unexecuted instantiation: boost::charconv::detail::operator|(boost::charconv::detail::uint128, int)
Unexecuted instantiation: boost::charconv::detail::operator|(boost::charconv::detail::uint128, long)
Unexecuted instantiation: boost::charconv::detail::operator|(boost::charconv::detail::uint128, long long)
Unexecuted instantiation: boost::charconv::detail::operator|(boost::charconv::detail::uint128, unsigned char)
Unexecuted instantiation: boost::charconv::detail::operator|(boost::charconv::detail::uint128, unsigned short)
Unexecuted instantiation: boost::charconv::detail::operator|(boost::charconv::detail::uint128, unsigned int)
Unexecuted instantiation: boost::charconv::detail::operator|(boost::charconv::detail::uint128, unsigned long)
Unexecuted instantiation: boost::charconv::detail::operator|(boost::charconv::detail::uint128, unsigned long long)
313
314
    INTEGER_BINARY_OPERATOR_OR(char)                // NOLINT
315
    INTEGER_BINARY_OPERATOR_OR(signed char)         // NOLINT
316
    INTEGER_BINARY_OPERATOR_OR(short)               // NOLINT
317
    INTEGER_BINARY_OPERATOR_OR(int)                 // NOLINT
318
    INTEGER_BINARY_OPERATOR_OR(long)                // NOLINT
319
    INTEGER_BINARY_OPERATOR_OR(long long)           // NOLINT
320
    INTEGER_BINARY_OPERATOR_OR(unsigned char)       // NOLINT
321
    INTEGER_BINARY_OPERATOR_OR(unsigned short)      // NOLINT
322
    INTEGER_BINARY_OPERATOR_OR(unsigned)            // NOLINT
323
    INTEGER_BINARY_OPERATOR_OR(unsigned long)       // NOLINT
324
    INTEGER_BINARY_OPERATOR_OR(unsigned long long)  // NOLINT
325
326
    #ifdef BOOST_CHARCONV_HAS_INT128
327
0
    constexpr friend uint128 operator|(uint128 lhs, boost::int128_type  rhs) noexcept { return lhs | uint128(rhs); }
328
0
    constexpr friend uint128 operator|(uint128 lhs, boost::uint128_type rhs) noexcept { return lhs | uint128(rhs); }
329
    #endif
330
331
    constexpr friend uint128 operator|(uint128 lhs, uint128 rhs) noexcept;
332
333
    BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &operator|=(uint128 v) noexcept;
334
335
    #undef INTEGER_BINARY_OPERATOR_OR
336
337
    // And
338
0
    #define INTEGER_BINARY_OPERATOR_AND(expr) constexpr friend uint128 operator&(uint128 lhs, expr rhs) noexcept { return {lhs.high, lhs.low & static_cast<std::uint64_t>(rhs)}; } // NOLINT
Unexecuted instantiation: boost::charconv::detail::operator&(boost::charconv::detail::uint128, char)
Unexecuted instantiation: boost::charconv::detail::operator&(boost::charconv::detail::uint128, signed char)
Unexecuted instantiation: boost::charconv::detail::operator&(boost::charconv::detail::uint128, short)
Unexecuted instantiation: boost::charconv::detail::operator&(boost::charconv::detail::uint128, int)
Unexecuted instantiation: boost::charconv::detail::operator&(boost::charconv::detail::uint128, long)
Unexecuted instantiation: boost::charconv::detail::operator&(boost::charconv::detail::uint128, long long)
Unexecuted instantiation: boost::charconv::detail::operator&(boost::charconv::detail::uint128, unsigned char)
Unexecuted instantiation: boost::charconv::detail::operator&(boost::charconv::detail::uint128, unsigned short)
Unexecuted instantiation: boost::charconv::detail::operator&(boost::charconv::detail::uint128, unsigned int)
Unexecuted instantiation: boost::charconv::detail::operator&(boost::charconv::detail::uint128, unsigned long)
Unexecuted instantiation: boost::charconv::detail::operator&(boost::charconv::detail::uint128, unsigned long long)
339
340
    INTEGER_BINARY_OPERATOR_AND(char)                   // NOLINT
341
    INTEGER_BINARY_OPERATOR_AND(signed char)            // NOLINT
342
    INTEGER_BINARY_OPERATOR_AND(short)                  // NOLINT
343
    INTEGER_BINARY_OPERATOR_AND(int)                    // NOLINT
344
    INTEGER_BINARY_OPERATOR_AND(long)                   // NOLINT
345
    INTEGER_BINARY_OPERATOR_AND(long long)              // NOLINT
346
    INTEGER_BINARY_OPERATOR_AND(unsigned char)          // NOLINT
347
    INTEGER_BINARY_OPERATOR_AND(unsigned short)         // NOLINT
348
    INTEGER_BINARY_OPERATOR_AND(unsigned)               // NOLINT
349
    INTEGER_BINARY_OPERATOR_AND(unsigned long)          // NOLINT
350
    INTEGER_BINARY_OPERATOR_AND(unsigned long long)     // NOLINT
351
352
    #ifdef BOOST_CHARCONV_HAS_INT128
353
0
    constexpr friend uint128 operator&(uint128 lhs, boost::int128_type  rhs) noexcept { return lhs & uint128(rhs); }
354
0
    constexpr friend uint128 operator&(uint128 lhs, boost::uint128_type rhs) noexcept { return lhs & uint128(rhs); }
355
    #endif
356
357
    constexpr friend uint128 operator&(uint128 lhs, uint128 rhs) noexcept;
358
359
    BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &operator&=(uint128 v) noexcept;
360
361
    #undef INTEGER_BINARY_OPERATOR_AND
362
363
    // Xor
364
0
    #define INTEGER_BINARY_OPERATOR_XOR(expr) constexpr friend uint128 operator^(uint128 lhs, expr rhs) noexcept { return {lhs.high, lhs.low ^ static_cast<std::uint64_t>(rhs)}; } // NOLINT
Unexecuted instantiation: boost::charconv::detail::operator^(boost::charconv::detail::uint128, char)
Unexecuted instantiation: boost::charconv::detail::operator^(boost::charconv::detail::uint128, signed char)
Unexecuted instantiation: boost::charconv::detail::operator^(boost::charconv::detail::uint128, short)
Unexecuted instantiation: boost::charconv::detail::operator^(boost::charconv::detail::uint128, int)
Unexecuted instantiation: boost::charconv::detail::operator^(boost::charconv::detail::uint128, long)
Unexecuted instantiation: boost::charconv::detail::operator^(boost::charconv::detail::uint128, long long)
Unexecuted instantiation: boost::charconv::detail::operator^(boost::charconv::detail::uint128, unsigned char)
Unexecuted instantiation: boost::charconv::detail::operator^(boost::charconv::detail::uint128, unsigned short)
Unexecuted instantiation: boost::charconv::detail::operator^(boost::charconv::detail::uint128, unsigned int)
Unexecuted instantiation: boost::charconv::detail::operator^(boost::charconv::detail::uint128, unsigned long)
Unexecuted instantiation: boost::charconv::detail::operator^(boost::charconv::detail::uint128, unsigned long long)
365
366
    INTEGER_BINARY_OPERATOR_XOR(char)                   // NOLINT
367
    INTEGER_BINARY_OPERATOR_XOR(signed char)            // NOLINT
368
    INTEGER_BINARY_OPERATOR_XOR(short)                  // NOLINT
369
    INTEGER_BINARY_OPERATOR_XOR(int)                    // NOLINT
370
    INTEGER_BINARY_OPERATOR_XOR(long)                   // NOLINT
371
    INTEGER_BINARY_OPERATOR_XOR(long long)              // NOLINT
372
    INTEGER_BINARY_OPERATOR_XOR(unsigned char)          // NOLINT
373
    INTEGER_BINARY_OPERATOR_XOR(unsigned short)         // NOLINT
374
    INTEGER_BINARY_OPERATOR_XOR(unsigned)               // NOLINT
375
    INTEGER_BINARY_OPERATOR_XOR(unsigned long)          // NOLINT
376
    INTEGER_BINARY_OPERATOR_XOR(unsigned long long)     // NOLINT
377
378
    #ifdef BOOST_CHARCONV_HAS_INT128
379
0
    constexpr friend uint128 operator^(uint128 lhs, boost::int128_type  rhs) noexcept { return lhs ^ uint128(rhs); }
380
0
    constexpr friend uint128 operator^(uint128 lhs, boost::uint128_type rhs) noexcept { return lhs ^ uint128(rhs); }
381
    #endif
382
383
    constexpr friend uint128 operator^(uint128 lhs, uint128 rhs) noexcept;
384
385
    BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &operator^=(uint128 v) noexcept;
386
387
    #undef INTEGER_BINARY_OPERATOR_XOR
388
389
    // Left shift
390
    #define INTEGER_BINARY_OPERATOR_LEFT_SHIFT(expr)                                            \
391
    BOOST_CHARCONV_CXX14_CONSTEXPR friend uint128 operator<<(uint128 lhs, expr rhs) noexcept    \
392
0
    {                                                                                           \
393
0
        if (rhs >= 64)                                                                          \
394
0
        {                                                                                       \
395
0
            return {lhs.low << (rhs - 64), 0};                                                  \
396
0
        }                                                                                       \
397
0
        else if (rhs == 0)                                                                      \
398
0
        {                                                                                       \
399
0
            return lhs;                                                                         \
400
0
        }                                                                                       \
401
0
                                                                                                \
402
0
        return {(lhs.high << rhs) | (lhs.low >> (64 - rhs)), lhs.low << rhs};                   \
403
0
    } // NOLINT
Unexecuted instantiation: boost::charconv::detail::operator<<(boost::charconv::detail::uint128, char)
Unexecuted instantiation: boost::charconv::detail::operator<<(boost::charconv::detail::uint128, signed char)
Unexecuted instantiation: boost::charconv::detail::operator<<(boost::charconv::detail::uint128, short)
Unexecuted instantiation: boost::charconv::detail::operator<<(boost::charconv::detail::uint128, int)
Unexecuted instantiation: boost::charconv::detail::operator<<(boost::charconv::detail::uint128, long)
Unexecuted instantiation: boost::charconv::detail::operator<<(boost::charconv::detail::uint128, long long)
Unexecuted instantiation: boost::charconv::detail::operator<<(boost::charconv::detail::uint128, unsigned char)
Unexecuted instantiation: boost::charconv::detail::operator<<(boost::charconv::detail::uint128, unsigned short)
Unexecuted instantiation: boost::charconv::detail::operator<<(boost::charconv::detail::uint128, unsigned int)
Unexecuted instantiation: boost::charconv::detail::operator<<(boost::charconv::detail::uint128, unsigned long)
Unexecuted instantiation: boost::charconv::detail::operator<<(boost::charconv::detail::uint128, unsigned long long)
404
405
    INTEGER_BINARY_OPERATOR_LEFT_SHIFT(char)                    // NOLINT
406
    INTEGER_BINARY_OPERATOR_LEFT_SHIFT(signed char)             // NOLINT
407
    INTEGER_BINARY_OPERATOR_LEFT_SHIFT(short)                   // NOLINT
408
    INTEGER_BINARY_OPERATOR_LEFT_SHIFT(int)                     // NOLINT
409
    INTEGER_BINARY_OPERATOR_LEFT_SHIFT(long)                    // NOLINT
410
    INTEGER_BINARY_OPERATOR_LEFT_SHIFT(long long)               // NOLINT
411
    INTEGER_BINARY_OPERATOR_LEFT_SHIFT(unsigned char)           // NOLINT
412
    INTEGER_BINARY_OPERATOR_LEFT_SHIFT(unsigned short)          // NOLINT
413
    INTEGER_BINARY_OPERATOR_LEFT_SHIFT(unsigned)                // NOLINT
414
    INTEGER_BINARY_OPERATOR_LEFT_SHIFT(unsigned long)           // NOLINT
415
    INTEGER_BINARY_OPERATOR_LEFT_SHIFT(unsigned long long)      // NOLINT
416
417
    #define INTEGER_BINARY_OPERATOR_EQUALS_LEFT_SHIFT(expr)                     \
418
    BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &operator<<=(expr amount) noexcept   \
419
0
    {                                                                           \
420
0
        *this = *this << amount;                                                \
421
0
        return *this;                                                           \
422
0
    } // NOLINT
Unexecuted instantiation: boost::charconv::detail::uint128::operator<<=(char)
Unexecuted instantiation: boost::charconv::detail::uint128::operator<<=(signed char)
Unexecuted instantiation: boost::charconv::detail::uint128::operator<<=(short)
Unexecuted instantiation: boost::charconv::detail::uint128::operator<<=(int)
Unexecuted instantiation: boost::charconv::detail::uint128::operator<<=(long)
Unexecuted instantiation: boost::charconv::detail::uint128::operator<<=(long long)
Unexecuted instantiation: boost::charconv::detail::uint128::operator<<=(unsigned char)
Unexecuted instantiation: boost::charconv::detail::uint128::operator<<=(unsigned short)
Unexecuted instantiation: boost::charconv::detail::uint128::operator<<=(unsigned int)
Unexecuted instantiation: boost::charconv::detail::uint128::operator<<=(unsigned long)
Unexecuted instantiation: boost::charconv::detail::uint128::operator<<=(unsigned long long)
423
424
    INTEGER_BINARY_OPERATOR_EQUALS_LEFT_SHIFT(char)                     // NOLINT
425
    INTEGER_BINARY_OPERATOR_EQUALS_LEFT_SHIFT(signed char)              // NOLINT
426
    INTEGER_BINARY_OPERATOR_EQUALS_LEFT_SHIFT(short)                    // NOLINT
427
    INTEGER_BINARY_OPERATOR_EQUALS_LEFT_SHIFT(int)                      // NOLINT
428
    INTEGER_BINARY_OPERATOR_EQUALS_LEFT_SHIFT(long)                     // NOLINT
429
    INTEGER_BINARY_OPERATOR_EQUALS_LEFT_SHIFT(long long)                // NOLINT
430
    INTEGER_BINARY_OPERATOR_EQUALS_LEFT_SHIFT(unsigned char)            // NOLINT
431
    INTEGER_BINARY_OPERATOR_EQUALS_LEFT_SHIFT(unsigned short)           // NOLINT
432
    INTEGER_BINARY_OPERATOR_EQUALS_LEFT_SHIFT(unsigned)                 // NOLINT
433
    INTEGER_BINARY_OPERATOR_EQUALS_LEFT_SHIFT(unsigned long)            // NOLINT
434
    INTEGER_BINARY_OPERATOR_EQUALS_LEFT_SHIFT(unsigned long long)       // NOLINT
435
436
    #undef INTEGER_BINARY_OPERATOR_LEFT_SHIFT
437
    #undef INTEGER_BINARY_OPERATOR_EQUALS_LEFT_SHIFT
438
439
    // Right Shift
440
    #define INTEGER_BINARY_OPERATOR_RIGHT_SHIFT(expr)                                               \
441
    BOOST_CHARCONV_CXX14_CONSTEXPR friend uint128 operator>>(uint128 lhs, expr amount) noexcept     \
442
0
    {                                                                                               \
443
0
        if (amount >= 64)                                                                           \
444
0
        {                                                                                           \
445
0
            return {0, lhs.high >> (amount - 64)};                                                  \
446
0
        }                                                                                           \
447
0
        else if (amount == 0)                                                                       \
448
0
        {                                                                                           \
449
0
            return lhs;                                                                             \
450
0
        }                                                                                           \
451
0
                                                                                                    \
452
0
        return {lhs.high >> amount, (lhs.low >> amount) | (lhs.high << (64 - amount))};             \
453
0
    } // NOLINT
Unexecuted instantiation: boost::charconv::detail::operator>>(boost::charconv::detail::uint128, char)
Unexecuted instantiation: boost::charconv::detail::operator>>(boost::charconv::detail::uint128, signed char)
Unexecuted instantiation: boost::charconv::detail::operator>>(boost::charconv::detail::uint128, short)
Unexecuted instantiation: boost::charconv::detail::operator>>(boost::charconv::detail::uint128, int)
Unexecuted instantiation: boost::charconv::detail::operator>>(boost::charconv::detail::uint128, long)
Unexecuted instantiation: boost::charconv::detail::operator>>(boost::charconv::detail::uint128, long long)
Unexecuted instantiation: boost::charconv::detail::operator>>(boost::charconv::detail::uint128, unsigned char)
Unexecuted instantiation: boost::charconv::detail::operator>>(boost::charconv::detail::uint128, unsigned short)
Unexecuted instantiation: boost::charconv::detail::operator>>(boost::charconv::detail::uint128, unsigned int)
Unexecuted instantiation: boost::charconv::detail::operator>>(boost::charconv::detail::uint128, unsigned long)
Unexecuted instantiation: boost::charconv::detail::operator>>(boost::charconv::detail::uint128, unsigned long long)
454
455
    INTEGER_BINARY_OPERATOR_RIGHT_SHIFT(char)                   // NOLINT
456
    INTEGER_BINARY_OPERATOR_RIGHT_SHIFT(signed char)            // NOLINT
457
    INTEGER_BINARY_OPERATOR_RIGHT_SHIFT(short)                  // NOLINT
458
    INTEGER_BINARY_OPERATOR_RIGHT_SHIFT(int)                    // NOLINT
459
    INTEGER_BINARY_OPERATOR_RIGHT_SHIFT(long)                   // NOLINT
460
    INTEGER_BINARY_OPERATOR_RIGHT_SHIFT(long long)              // NOLINT
461
    INTEGER_BINARY_OPERATOR_RIGHT_SHIFT(unsigned char)          // NOLINT
462
    INTEGER_BINARY_OPERATOR_RIGHT_SHIFT(unsigned short)         // NOLINT
463
    INTEGER_BINARY_OPERATOR_RIGHT_SHIFT(unsigned)               // NOLINT
464
    INTEGER_BINARY_OPERATOR_RIGHT_SHIFT(unsigned long)          // NOLINT
465
    INTEGER_BINARY_OPERATOR_RIGHT_SHIFT(unsigned long long)     // NOLINT
466
467
    #define INTEGER_BINARY_OPERATOR_EQUALS_RIGHT_SHIFT(expr)                        \
468
    BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &operator>>=(expr amount) noexcept       \
469
0
    {                                                                               \
470
0
        *this = *this >> amount;                                                    \
471
0
        return *this;                                                               \
472
0
    } // NOLINT
Unexecuted instantiation: boost::charconv::detail::uint128::operator>>=(char)
Unexecuted instantiation: boost::charconv::detail::uint128::operator>>=(signed char)
Unexecuted instantiation: boost::charconv::detail::uint128::operator>>=(short)
Unexecuted instantiation: boost::charconv::detail::uint128::operator>>=(int)
Unexecuted instantiation: boost::charconv::detail::uint128::operator>>=(long)
Unexecuted instantiation: boost::charconv::detail::uint128::operator>>=(long long)
Unexecuted instantiation: boost::charconv::detail::uint128::operator>>=(unsigned char)
Unexecuted instantiation: boost::charconv::detail::uint128::operator>>=(unsigned short)
Unexecuted instantiation: boost::charconv::detail::uint128::operator>>=(unsigned int)
Unexecuted instantiation: boost::charconv::detail::uint128::operator>>=(unsigned long)
Unexecuted instantiation: boost::charconv::detail::uint128::operator>>=(unsigned long long)
473
474
    INTEGER_BINARY_OPERATOR_EQUALS_RIGHT_SHIFT(char)                    // NOLINT
475
    INTEGER_BINARY_OPERATOR_EQUALS_RIGHT_SHIFT(signed char)             // NOLINT
476
    INTEGER_BINARY_OPERATOR_EQUALS_RIGHT_SHIFT(short)                   // NOLINT
477
    INTEGER_BINARY_OPERATOR_EQUALS_RIGHT_SHIFT(int)                     // NOLINT
478
    INTEGER_BINARY_OPERATOR_EQUALS_RIGHT_SHIFT(long)                    // NOLINT
479
    INTEGER_BINARY_OPERATOR_EQUALS_RIGHT_SHIFT(long long)               // NOLINT
480
    INTEGER_BINARY_OPERATOR_EQUALS_RIGHT_SHIFT(unsigned char)           // NOLINT
481
    INTEGER_BINARY_OPERATOR_EQUALS_RIGHT_SHIFT(unsigned short)          // NOLINT
482
    INTEGER_BINARY_OPERATOR_EQUALS_RIGHT_SHIFT(unsigned)                // NOLINT
483
    INTEGER_BINARY_OPERATOR_EQUALS_RIGHT_SHIFT(unsigned long)           // NOLINT
484
    INTEGER_BINARY_OPERATOR_EQUALS_RIGHT_SHIFT(unsigned long long)      // NOLINT
485
486
    #undef INTEGER_BINARY_OPERATOR_RIGHT_SHIFT
487
    #undef INTEGER_BINARY_OPERATOR_EQUALS_RIGHT_SHIFT
488
489
    // Arithmetic operators (Add, sub, mul, div, mod)
490
    inline uint128 &operator+=(std::uint64_t n) noexcept;
491
492
    BOOST_CHARCONV_CXX14_CONSTEXPR friend uint128 operator+(uint128 lhs, uint128 rhs) noexcept;
493
494
    BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &operator+=(uint128 v) noexcept;
495
496
    BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &operator++() noexcept;
497
498
    BOOST_CHARCONV_CXX14_CONSTEXPR const uint128 operator++(int) noexcept;
499
500
    BOOST_CHARCONV_CXX14_CONSTEXPR friend uint128 operator-(uint128 lhs, uint128 rhs) noexcept;
501
502
    BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &operator-=(uint128 v) noexcept;
503
504
    BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &operator--() noexcept;
505
506
    BOOST_CHARCONV_CXX14_CONSTEXPR const uint128 operator--(int) noexcept;
507
508
    BOOST_CHARCONV_CXX14_CONSTEXPR friend uint128 operator*(uint128 lhs, uint128 rhs) noexcept;
509
510
    BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &operator*=(uint128 v) noexcept;
511
512
    BOOST_CHARCONV_CXX14_CONSTEXPR friend uint128 operator/(uint128 lhs, uint128 rhs) noexcept;
513
514
    BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &operator/=(uint128 v) noexcept;
515
516
    BOOST_CHARCONV_CXX14_CONSTEXPR friend uint128 operator%(uint128 lhs, uint128 rhs) noexcept;
517
518
    BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &operator%=(uint128 v) noexcept;
519
520
private:
521
    BOOST_CHARCONV_CXX14_CONSTEXPR friend int high_bit(uint128 v) noexcept;
522
523
    BOOST_CHARCONV_CXX14_CONSTEXPR friend void
524
    div_impl(uint128 lhs, uint128 rhs, uint128 &quotient, uint128 &remainder) noexcept;
525
};
526
527
constexpr uint128 operator-(uint128 val) noexcept
528
0
{
529
0
    return {~val.high + static_cast<std::uint64_t>(val.low == 0), ~val.low + 1};
530
0
}
531
532
constexpr uint128 operator+(uint128 val) noexcept
533
0
{
534
0
    return val;
535
0
}
536
537
BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &uint128::operator=(const uint128& v) noexcept // NOLINT : User defined for older compilers
538
0
{
539
0
    low = v.low;
540
0
    high = v.high;
541
0
    return *this;
542
0
}
543
544
constexpr bool operator==(uint128 lhs, uint128 rhs) noexcept
545
0
{
546
0
    return lhs.high == rhs.high && lhs.low == rhs.low;
547
0
}
548
549
constexpr bool operator!=(uint128 lhs, uint128 rhs) noexcept
550
0
{
551
0
    return !(lhs == rhs);
552
0
}
553
554
BOOST_CHARCONV_CXX14_CONSTEXPR bool operator<(uint128 lhs, uint128 rhs) noexcept
555
0
{
556
0
    if (lhs.high == rhs.high)
557
0
    {
558
0
        return lhs.low < rhs.low;
559
0
    }
560
0
561
0
    return lhs.high < rhs.high;
562
0
}
563
564
BOOST_CHARCONV_CXX14_CONSTEXPR bool operator<=(uint128 lhs, uint128 rhs) noexcept
565
0
{
566
0
    return !(rhs < lhs);
567
0
}
568
569
BOOST_CHARCONV_CXX14_CONSTEXPR bool operator>(uint128 lhs, uint128 rhs) noexcept
570
0
{
571
0
    return rhs < lhs;
572
0
}
573
574
BOOST_CHARCONV_CXX14_CONSTEXPR bool operator>=(uint128 lhs, uint128 rhs) noexcept
575
0
{
576
0
    return !(lhs < rhs);
577
0
}
578
579
constexpr uint128 operator~(uint128 v) noexcept
580
0
{
581
0
    return {~v.high, ~v.low};
582
0
}
583
584
constexpr uint128 operator|(uint128 lhs, uint128 rhs) noexcept
585
0
{
586
0
    return {lhs.high | rhs.high, lhs.low | rhs.low};
587
0
}
588
589
BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &uint128::operator|=(uint128 v) noexcept
590
0
{
591
0
    *this = *this | v;
592
0
    return *this;
593
0
}
594
595
constexpr uint128 operator&(uint128 lhs, uint128 rhs) noexcept
596
0
{
597
0
    return {lhs.high & rhs.high, lhs.low & rhs.low};
598
0
}
599
600
BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &uint128::operator&=(uint128 v) noexcept
601
0
{
602
0
    *this = *this & v;
603
0
    return *this;
604
0
}
605
606
constexpr uint128 operator^(uint128 lhs, uint128 rhs) noexcept
607
0
{
608
0
    return {lhs.high ^ rhs.high, lhs.low ^ rhs.low};
609
0
}
610
611
BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &uint128::operator^=(uint128 v) noexcept
612
0
{
613
0
    *this = *this ^ v;
614
0
    return *this;
615
0
}
616
617
inline uint128 &uint128::operator+=(std::uint64_t n) noexcept
618
3.99M
{
619
3.99M
    #if BOOST_CHARCONV_HAS_BUILTIN(__builtin_addcll)
620
621
3.99M
    unsigned long long carry {};
622
3.99M
        low = __builtin_addcll(low, n, 0, &carry);
623
3.99M
        high = __builtin_addcll(high, 0, carry, &carry);
624
625
    #elif BOOST_CHARCONV_HAS_BUILTIN(__builtin_ia32_addcarryx_u64)
626
627
    unsigned long long result {};
628
        auto carry = __builtin_ia32_addcarryx_u64(0, low, n, &result);
629
        low = result;
630
        __builtin_ia32_addcarryx_u64(carry, high, 0, &result);
631
        high = result;
632
633
    #elif defined(BOOST_MSVC) && defined(_M_X64)
634
635
    auto carry = _addcarry_u64(0, low, n, &low);
636
        _addcarry_u64(carry, high, 0, &high);
637
638
    #else
639
640
    auto sum = low + n;
641
    high += (sum < low ? 1 : 0);
642
    low = sum;
643
644
    #endif
645
3.99M
    return *this;
646
3.99M
}
647
648
BOOST_CHARCONV_CXX14_CONSTEXPR uint128 operator+(uint128 lhs, uint128 rhs) noexcept
649
0
{
650
0
    const uint128 temp = {lhs.high + rhs.high, lhs.low + rhs.low};
651
652
    // Need to carry a bit into rhs
653
0
    if (temp.low < lhs.low)
654
0
    {
655
0
        return {temp.high + 1, temp.low};
656
0
    }
657
658
0
    return temp;
659
0
}
660
661
BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &uint128::operator+=(uint128 v) noexcept
662
0
{
663
0
    *this = *this + v;
664
0
    return *this;
665
0
}
666
667
BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &uint128::operator++() noexcept
668
0
{
669
0
    if (this->low == UINT64_MAX)
670
0
    {
671
0
        this->low = 0;
672
0
        ++this->high;
673
0
    }
674
0
    else
675
0
    {
676
0
        ++this->low;
677
0
    }
678
0
679
0
    return *this;
680
0
}
681
682
BOOST_CHARCONV_CXX14_CONSTEXPR const uint128 uint128::operator++(int) noexcept
683
0
{
684
0
    return ++(*this);
685
0
}
686
687
BOOST_CHARCONV_CXX14_CONSTEXPR uint128 operator-(uint128 lhs, uint128 rhs) noexcept
688
0
{
689
0
    const uint128 temp {lhs.high - rhs.high, lhs.low - rhs.low};
690
691
    // Check for carry
692
0
    if (lhs.low < rhs.low)
693
0
    {
694
0
        return {temp.high - 1, temp.low};
695
0
    }
696
697
0
    return temp;
698
0
}
699
700
BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &uint128::operator-=(uint128 v) noexcept
701
0
{
702
0
    *this = *this - v;
703
0
    return *this;
704
0
}
705
706
BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &uint128::operator--() noexcept
707
0
{
708
0
  if (this->low == 0)
709
0
  {
710
0
        this->low = UINT64_MAX;
711
0
        --this->high;
712
0
  }
713
0
    else // NOLINT
714
0
    {
715
0
        --this->low;
716
0
    }
717
0
718
0
    return *this;
719
0
}
720
721
BOOST_CHARCONV_CXX14_CONSTEXPR const uint128 uint128::operator--(int) noexcept
722
0
{
723
0
    return --(*this);
724
0
}
725
BOOST_CHARCONV_CXX14_CONSTEXPR uint128 operator*(uint128 lhs, uint128 rhs) noexcept
726
0
{
727
0
    const auto a = static_cast<std::uint64_t>(lhs.low >> 32);
728
0
    const auto b = static_cast<std::uint64_t>(lhs.low & UINT32_MAX);
729
0
    const auto c = static_cast<std::uint64_t>(rhs.low >> 32);
730
0
    const auto d = static_cast<std::uint64_t>(rhs.low & UINT32_MAX);
731
0
732
0
    uint128 result { lhs.high * rhs.low + lhs.low * rhs.high + a * c, b * d };
733
0
    result += uint128(a * d) << 32;
734
0
    result += uint128(b * c) << 32;
735
0
    return result;
736
0
}
737
738
BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &uint128::operator*=(uint128 v) noexcept
739
0
{
740
0
    *this = *this * v;
741
0
    return *this;
742
0
}
743
744
BOOST_CHARCONV_CXX14_CONSTEXPR int high_bit(uint128 v) noexcept
745
0
{
746
0
    if (v.high != 0)
747
0
    {
748
0
        return 127 - boost::core::countl_zero(v.high);
749
0
    }
750
0
    else if (v.low != 0)
751
0
    {
752
0
        return 63 - boost::core::countl_zero(v.low);
753
0
    }
754
0
755
0
    return 0;
756
0
}
757
758
// See: https://stackoverflow.com/questions/5386377/division-without-using
759
BOOST_CHARCONV_CXX14_CONSTEXPR void div_impl(uint128 lhs, uint128 rhs, uint128& quotient, uint128& remainder) noexcept
760
0
{
761
0
    constexpr uint128 one {0, 1};
762
0
763
0
    if (rhs > lhs)
764
0
    {
765
0
        quotient = 0U;
766
0
        remainder = 0U;
767
0
    }
768
0
    else if (lhs == rhs)
769
0
    {
770
0
        quotient = 1U;
771
0
        remainder = 0U;
772
0
    }
773
0
774
0
    uint128 denom = rhs;
775
0
    quotient = 0U;
776
0
777
0
    std::int32_t shift = high_bit(lhs) - high_bit(rhs);
778
0
    if (shift < 0)
779
0
    {
780
0
        shift = 32 - shift;
781
0
    }
782
0
    denom <<= shift;
783
0
784
0
    for (int i = 0; i <= shift; ++i)
785
0
    {
786
0
        quotient <<= 1;
787
0
        if (lhs >= denom)
788
0
        {
789
0
            lhs -= denom;
790
0
            quotient |= one;
791
0
        }
792
0
        denom >>= 1;
793
0
    }
794
0
795
0
    remainder = lhs;
796
0
}
797
798
BOOST_CHARCONV_CXX14_CONSTEXPR uint128 operator/(uint128 lhs, uint128 rhs) noexcept
799
0
{
800
0
    uint128 quotient {0, 0};
801
0
    uint128 remainder {0, 0};
802
0
    div_impl(lhs, rhs, quotient, remainder);
803
0
804
0
    return quotient;
805
0
}
806
807
BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &uint128::operator/=(uint128 v) noexcept
808
0
{
809
0
    *this = *this / v;
810
0
    return *this;
811
0
}
812
813
BOOST_CHARCONV_CXX14_CONSTEXPR uint128 operator%(uint128 lhs, uint128 rhs) noexcept
814
0
{
815
0
    uint128 quotient {0, 0};
816
0
    uint128 remainder {0, 0};
817
0
    div_impl(lhs, rhs, quotient, remainder);
818
0
819
0
    return remainder;
820
0
}
821
822
BOOST_CHARCONV_CXX14_CONSTEXPR uint128 &uint128::operator%=(uint128 v) noexcept
823
0
{
824
0
    *this = *this % v;
825
0
    return *this;
826
0
}
827
828
static inline std::uint64_t umul64(std::uint32_t x, std::uint32_t y) noexcept
829
0
{
830
    // __emulu is not available on ARM https://learn.microsoft.com/en-us/cpp/intrinsics/emul-emulu?view=msvc-170
831
    #if defined(BOOST_CHARCONV_HAS_MSVC_32BIT_INTRINSICS) && !defined(_M_ARM)
832
833
    return __emulu(x, y);
834
835
    #else
836
837
0
    return x * static_cast<std::uint64_t>(y);
838
839
0
    #endif
840
0
}
Unexecuted instantiation: src.cpp:boost::charconv::detail::umul64(unsigned int, unsigned int)
Unexecuted instantiation: to_chars.cpp:boost::charconv::detail::umul64(unsigned int, unsigned int)
841
842
// Get 128-bit result of multiplication of two 64-bit unsigned integers.
843
BOOST_CHARCONV_SAFEBUFFERS inline uint128 umul128(std::uint64_t x, std::uint64_t y) noexcept 
844
4.27M
{
845
4.27M
    #if defined(BOOST_CHARCONV_HAS_INT128)
846
    
847
4.27M
    auto result = static_cast<boost::uint128_type>(x) * static_cast<boost::uint128_type>(y);
848
4.27M
    return {static_cast<std::uint64_t>(result >> 64), static_cast<std::uint64_t>(result)};
849
850
    // _umul128 is x64 only https://learn.microsoft.com/en-us/cpp/intrinsics/umul128?view=msvc-170
851
    #elif defined(BOOST_CHARCONV_HAS_MSVC_64BIT_INTRINSICS) && !defined(_M_ARM64)
852
    
853
    unsigned long long high;
854
    std::uint64_t low = _umul128(x, y, &high);
855
    return {static_cast<std::uint64_t>(high), low};
856
    
857
    // https://developer.arm.com/documentation/dui0802/a/A64-General-Instructions/UMULH
858
    #elif defined(_M_ARM64) && !defined(__MINGW32__)
859
860
    std::uint64_t high = __umulh(x, y);
861
    std::uint64_t low = x * y;
862
    return {high, low};
863
864
    #else
865
    
866
    auto a = static_cast<std::uint32_t>(x >> 32);
867
    auto b = static_cast<std::uint32_t>(x);
868
    auto c = static_cast<std::uint32_t>(y >> 32);
869
    auto d = static_cast<std::uint32_t>(y);
870
871
    auto ac = umul64(a, c);
872
    auto bc = umul64(b, c);
873
    auto ad = umul64(a, d);
874
    auto bd = umul64(b, d);
875
876
    auto intermediate = (bd >> 32) + static_cast<std::uint32_t>(ad) + static_cast<std::uint32_t>(bc);
877
878
    return {ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32),
879
            (intermediate << 32) + static_cast<std::uint32_t>(bd)};
880
    
881
    #endif
882
4.27M
}
883
884
BOOST_CHARCONV_SAFEBUFFERS inline std::uint64_t umul128_upper64(std::uint64_t x, std::uint64_t y) noexcept
885
7.99M
{
886
7.99M
    #if defined(BOOST_CHARCONV_HAS_INT128)
887
    
888
7.99M
    auto result = static_cast<boost::uint128_type>(x) * static_cast<boost::uint128_type>(y);
889
7.99M
    return static_cast<std::uint64_t>(result >> 64);
890
    
891
    #elif defined(BOOST_CHARCONV_HAS_MSVC_64BIT_INTRINSICS)
892
    
893
    return __umulh(x, y);
894
    
895
    #else
896
    
897
    auto a = static_cast<std::uint32_t>(x >> 32);
898
    auto b = static_cast<std::uint32_t>(x);
899
    auto c = static_cast<std::uint32_t>(y >> 32);
900
    auto d = static_cast<std::uint32_t>(y);
901
902
    auto ac = umul64(a, c);
903
    auto bc = umul64(b, c);
904
    auto ad = umul64(a, d);
905
    auto bd = umul64(b, d);
906
907
    auto intermediate = (bd >> 32) + static_cast<std::uint32_t>(ad) + static_cast<std::uint32_t>(bc);
908
909
    return ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32);
910
    
911
    #endif
912
7.99M
}
913
914
// Get upper 128-bits of multiplication of a 64-bit unsigned integer and a 128-bit
915
// unsigned integer.
916
BOOST_CHARCONV_SAFEBUFFERS inline uint128 umul192_upper128(std::uint64_t x, uint128 y) noexcept
917
3.99M
{
918
3.99M
    auto r = umul128(x, y.high);
919
3.99M
    r += umul128_upper64(x, y.low);
920
3.99M
    return r;
921
3.99M
}
922
923
// Get upper 64-bits of multiplication of a 32-bit unsigned integer and a 64-bit
924
// unsigned integer.
925
inline std::uint64_t umul96_upper64(std::uint32_t x, std::uint64_t y) noexcept 
926
0
{
927
0
    #if defined(BOOST_CHARCONV_HAS_INT128) || defined(BOOST_CHARCONV_HAS_MSVC_64BIT_INTRINSICS)
928
    
929
0
    return umul128_upper64(static_cast<std::uint64_t>(x) << 32, y);
930
    
931
    #else
932
    
933
    auto yh = static_cast<std::uint32_t>(y >> 32);
934
    auto yl = static_cast<std::uint32_t>(y);
935
936
    auto xyh = umul64(x, yh);
937
    auto xyl = umul64(x, yl);
938
939
    return xyh + (xyl >> 32);
940
941
    #endif
942
0
}
943
944
// Get lower 128-bits of multiplication of a 64-bit unsigned integer and a 128-bit
945
// unsigned integer.
946
BOOST_CHARCONV_SAFEBUFFERS inline uint128 umul192_lower128(std::uint64_t x, uint128 y) noexcept
947
4.06k
{
948
4.06k
    auto high = x * y.high;
949
4.06k
    auto highlow = umul128(x, y.low);
950
4.06k
    return {high + highlow.high, highlow.low};
951
4.06k
}
952
953
// Get lower 64-bits of multiplication of a 32-bit unsigned integer and a 64-bit
954
// unsigned integer.
955
inline std::uint64_t umul96_lower64(std::uint32_t x, std::uint64_t y) noexcept 
956
0
{
957
0
    return x * y;
958
0
}
959
960
}}} // Namespaces
961
962
// Non-standard libraries may add specializations for library-provided types
963
namespace std {
964
965
template <>
966
struct numeric_limits<boost::charconv::detail::uint128>
967
{
968
    // Member constants
969
    BOOST_ATTRIBUTE_UNUSED static constexpr bool is_specialized = true;
970
    BOOST_ATTRIBUTE_UNUSED static constexpr bool is_signed = false;
971
    BOOST_ATTRIBUTE_UNUSED static constexpr bool is_integer = true;
972
    BOOST_ATTRIBUTE_UNUSED static constexpr bool is_exact = true;
973
    BOOST_ATTRIBUTE_UNUSED static constexpr bool has_infinity = false;
974
    BOOST_ATTRIBUTE_UNUSED static constexpr bool has_quiet_NaN = false;
975
    BOOST_ATTRIBUTE_UNUSED static constexpr bool has_signaling_NaN = false;
976
    BOOST_ATTRIBUTE_UNUSED static constexpr std::float_round_style round_style = std::round_toward_zero;
977
    BOOST_ATTRIBUTE_UNUSED static constexpr bool is_iec559 = false;
978
    BOOST_ATTRIBUTE_UNUSED static constexpr bool is_bounded = true;
979
    BOOST_ATTRIBUTE_UNUSED static constexpr bool is_modulo = true;
980
    BOOST_ATTRIBUTE_UNUSED static constexpr int digits = 128;
981
    BOOST_ATTRIBUTE_UNUSED static constexpr int digits10 = 38;
982
    BOOST_ATTRIBUTE_UNUSED static constexpr int max_digits10 = 0;
983
    BOOST_ATTRIBUTE_UNUSED static constexpr int radix = 2;
984
    BOOST_ATTRIBUTE_UNUSED static constexpr int min_exponent = 0;
985
    BOOST_ATTRIBUTE_UNUSED static constexpr int min_exponent10 = 0;
986
    BOOST_ATTRIBUTE_UNUSED static constexpr int max_exponent = 0;
987
    BOOST_ATTRIBUTE_UNUSED static constexpr int max_exponent10 = 0;
988
    BOOST_ATTRIBUTE_UNUSED static constexpr bool traps = std::numeric_limits<std::uint64_t>::traps;
989
    BOOST_ATTRIBUTE_UNUSED static constexpr bool tinyness_before = false;
990
991
    // Member functions
992
0
    BOOST_ATTRIBUTE_UNUSED static constexpr boost::charconv::detail::uint128 (min)() { return 0; }
993
0
    BOOST_ATTRIBUTE_UNUSED static constexpr boost::charconv::detail::uint128 lowest() { return 0; }
994
0
    BOOST_ATTRIBUTE_UNUSED static constexpr boost::charconv::detail::uint128 (max)() { return {UINT64_MAX, UINT64_MAX}; }
995
0
    BOOST_ATTRIBUTE_UNUSED static constexpr boost::charconv::detail::uint128 epsilon() { return 0; }
996
0
    BOOST_ATTRIBUTE_UNUSED static constexpr boost::charconv::detail::uint128 round_error() { return 0; }
997
0
    BOOST_ATTRIBUTE_UNUSED static constexpr boost::charconv::detail::uint128 infinity() { return 0; }
998
0
    BOOST_ATTRIBUTE_UNUSED static constexpr boost::charconv::detail::uint128 quiet_NaN() { return 0; }
999
0
    BOOST_ATTRIBUTE_UNUSED static constexpr boost::charconv::detail::uint128 signaling_NaN() { return 0; }
1000
0
    BOOST_ATTRIBUTE_UNUSED static constexpr boost::charconv::detail::uint128 (denorm_min)() { return 0; }
1001
};
1002
1003
} // Namespace std
1004
1005
#endif // BOOST_CHARCONV_DETAIL_EMULATED128_HPP