/src/solidity/libsolutil/Numeric.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | This file is part of solidity. |
3 | | |
4 | | solidity is free software: you can redistribute it and/or modify |
5 | | it under the terms of the GNU General Public License as published by |
6 | | the Free Software Foundation, either version 3 of the License, or |
7 | | (at your option) any later version. |
8 | | |
9 | | solidity is distributed in the hope that it will be useful, |
10 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | | GNU General Public License for more details. |
13 | | |
14 | | You should have received a copy of the GNU General Public License |
15 | | along with solidity. If not, see <http://www.gnu.org/licenses/>. |
16 | | */ |
17 | | // SPDX-License-Identifier: GPL-3.0 |
18 | | /** |
19 | | * Definition of u256 and similar types and helper functions. |
20 | | */ |
21 | | |
22 | | #pragma once |
23 | | |
24 | | #include <libsolutil/Common.h> |
25 | | #include <libsolutil/CommonData.h> |
26 | | |
27 | | #include <boost/version.hpp> |
28 | | #if (BOOST_VERSION < 106500) |
29 | | #error "Unsupported Boost version. At least 1.65 required." |
30 | | #endif |
31 | | |
32 | | // TODO: do this only conditionally as soon as a boost version with gcc 12 support is released. |
33 | | #if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12) |
34 | | #pragma GCC diagnostic push |
35 | | #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" |
36 | | #pragma GCC diagnostic ignored "-Warray-bounds" |
37 | | #pragma GCC diagnostic ignored "-Wstringop-overread" |
38 | | #pragma GCC diagnostic ignored "-Waggressive-loop-optimizations" |
39 | | #endif |
40 | | #include <boost/multiprecision/cpp_int.hpp> |
41 | | #if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12) |
42 | | #pragma GCC diagnostic pop |
43 | | #endif |
44 | | |
45 | | #include <limits> |
46 | | |
47 | | namespace solidity |
48 | | { |
49 | | |
50 | | // Numeric types. |
51 | | using bigint = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>>; |
52 | | using u256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>; |
53 | | using s256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>; |
54 | | |
55 | | /// Interprets @a _u as a two's complement signed number and returns the resulting s256. |
56 | | inline s256 u2s(u256 _u) |
57 | 0 | { |
58 | 0 | static bigint const c_end = bigint(1) << 256; |
59 | 0 | if (boost::multiprecision::bit_test(_u, 255)) |
60 | 0 | return s256(-(c_end - _u)); |
61 | 0 | else |
62 | 0 | return s256(_u); |
63 | 0 | } |
64 | | |
65 | | /// @returns the two's complement signed representation of the signed number _u. |
66 | | inline u256 s2u(s256 _u) |
67 | 52.1k | { |
68 | 52.1k | static bigint const c_end = bigint(1) << 256; |
69 | 52.1k | if (_u >= 0) |
70 | 0 | return u256(_u); |
71 | 52.1k | else |
72 | 52.1k | return u256(c_end + _u); |
73 | 52.1k | } |
74 | | |
75 | | inline u256 exp256(u256 _base, u256 _exponent) |
76 | 0 | { |
77 | 0 | using boost::multiprecision::limb_type; |
78 | 0 | u256 result = 1; |
79 | 0 | while (_exponent) |
80 | 0 | { |
81 | 0 | if (boost::multiprecision::bit_test(_exponent, 0)) |
82 | 0 | result *= _base; |
83 | 0 | _base *= _base; |
84 | 0 | _exponent >>= 1; |
85 | 0 | } |
86 | 0 | return result; |
87 | 0 | } |
88 | | |
89 | | /// Checks whether _mantissa * (X ** _exp) fits into 4096 bits, |
90 | | /// where X is given indirectly via _log2OfBase = log2(X). |
91 | | bool fitsPrecisionBaseX(bigint const& _mantissa, double _log2OfBase, uint32_t _exp); |
92 | | |
93 | | |
94 | | // Big-endian to/from host endian conversion functions. |
95 | | |
96 | | /// Converts a templated integer value to the big-endian byte-stream represented on a templated collection. |
97 | | /// The size of the collection object will be unchanged. If it is too small, it will not represent the |
98 | | /// value properly, if too big then the additional elements will be zeroed out. |
99 | | /// @a Out will typically be either std::string or bytes. |
100 | | /// @a T will typically by unsigned, u160, u256 or bigint. |
101 | | template <class T, class Out> |
102 | | inline void toBigEndian(T _val, Out& o_out) |
103 | 26.4M | { |
104 | 26.4M | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift |
105 | 106M | for (auto i = o_out.size(); i != 0; _val >>= 8, i--) |
106 | 80.1M | { |
107 | 80.1M | T v = _val & (T)0xff; |
108 | 80.1M | o_out[i - 1] = (typename Out::value_type)(uint8_t)v; |
109 | 80.1M | } |
110 | 26.4M | } void solidity::toBigEndian<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&) Line | Count | Source | 103 | 425k | { | 104 | 425k | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 105 | 6.23M | for (auto i = o_out.size(); i != 0; _val >>= 8, i--) | 106 | 5.81M | { | 107 | 5.81M | T v = _val & (T)0xff; | 108 | 5.81M | o_out[i - 1] = (typename Out::value_type)(uint8_t)v; | 109 | 5.81M | } | 110 | 425k | } |
void solidity::toBigEndian<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&) Line | Count | Source | 103 | 892 | { | 104 | 892 | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 105 | 29.4k | for (auto i = o_out.size(); i != 0; _val >>= 8, i--) | 106 | 28.5k | { | 107 | 28.5k | T v = _val & (T)0xff; | 108 | 28.5k | o_out[i - 1] = (typename Out::value_type)(uint8_t)v; | 109 | 28.5k | } | 110 | 892 | } |
void solidity::toBigEndian<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, std::__1::array<unsigned char, 32ul> >(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, std::__1::array<unsigned char, 32ul>&) Line | Count | Source | 103 | 386k | { | 104 | 386k | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 105 | 12.7M | for (auto i = o_out.size(); i != 0; _val >>= 8, i--) | 106 | 12.3M | { | 107 | 12.3M | T v = _val & (T)0xff; | 108 | 12.3M | o_out[i - 1] = (typename Out::value_type)(uint8_t)v; | 109 | 12.3M | } | 110 | 386k | } |
void solidity::toBigEndian<unsigned long, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >(unsigned long, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&) Line | Count | Source | 103 | 2.10M | { | 104 | 2.10M | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 105 | 4.20M | for (auto i = o_out.size(); i != 0; _val >>= 8, i--) | 106 | 2.10M | { | 107 | 2.10M | T v = _val & (T)0xff; | 108 | 2.10M | o_out[i - 1] = (typename Out::value_type)(uint8_t)v; | 109 | 2.10M | } | 110 | 2.10M | } |
void solidity::toBigEndian<unsigned int, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >(unsigned int, std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >&) Line | Count | Source | 103 | 92.8k | { | 104 | 92.8k | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 105 | 194k | for (auto i = o_out.size(); i != 0; _val >>= 8, i--) | 106 | 101k | { | 107 | 101k | T v = _val & (T)0xff; | 108 | 101k | o_out[i - 1] = (typename Out::value_type)(uint8_t)v; | 109 | 101k | } | 110 | 92.8k | } |
void solidity::toBigEndian<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, solidity::util::vector_ref<unsigned char> >(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, solidity::util::vector_ref<unsigned char>&) Line | Count | Source | 103 | 12.4M | { | 104 | 12.4M | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 105 | 43.1M | for (auto i = o_out.size(); i != 0; _val >>= 8, i--) | 106 | 30.6M | { | 107 | 30.6M | T v = _val & (T)0xff; | 108 | 30.6M | o_out[i - 1] = (typename Out::value_type)(uint8_t)v; | 109 | 30.6M | } | 110 | 12.4M | } |
void solidity::toBigEndian<unsigned long, solidity::util::vector_ref<unsigned char> >(unsigned long, solidity::util::vector_ref<unsigned char>&) Line | Count | Source | 103 | 10.9M | { | 104 | 10.9M | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 105 | 40.0M | for (auto i = o_out.size(); i != 0; _val >>= 8, i--) | 106 | 29.1M | { | 107 | 29.1M | T v = _val & (T)0xff; | 108 | 29.1M | o_out[i - 1] = (typename Out::value_type)(uint8_t)v; | 109 | 29.1M | } | 110 | 10.9M | } |
|
111 | | |
112 | | /// Converts a big-endian byte-stream represented on a templated collection to a templated integer value. |
113 | | /// @a In will typically be either std::string or bytes. |
114 | | /// @a T will typically by unsigned, u256 or bigint. |
115 | | template <class T, class In> |
116 | | inline T fromBigEndian(In const& _bytes) |
117 | 573k | { |
118 | 573k | T ret = (T)0; |
119 | 573k | for (auto i: _bytes) |
120 | 16.1M | ret = (T)((ret << 8) | (uint8_t)(typename std::make_unsigned<typename In::value_type>::type)i); |
121 | 573k | return ret; |
122 | 573k | } boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0> solidity::fromBigEndian<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, std::__1::array<unsigned char, 32ul> >(std::__1::array<unsigned char, 32ul> const&) Line | Count | Source | 117 | 496k | { | 118 | 496k | T ret = (T)0; | 119 | 496k | for (auto i: _bytes) | 120 | 15.8M | ret = (T)((ret << 8) | (uint8_t)(typename std::make_unsigned<typename In::value_type>::type)i); | 121 | 496k | return ret; | 122 | 496k | } |
boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<32u, 32u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0> solidity::fromBigEndian<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<32u, 32u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, std::__1::array<unsigned char, 4ul> >(std::__1::array<unsigned char, 4ul> const&) Line | Count | Source | 117 | 76.7k | { | 118 | 76.7k | T ret = (T)0; | 119 | 76.7k | for (auto i: _bytes) | 120 | 306k | ret = (T)((ret << 8) | (uint8_t)(typename std::make_unsigned<typename In::value_type>::type)i); | 121 | 76.7k | return ret; | 122 | 76.7k | } |
Unexecuted instantiation: unsigned int solidity::fromBigEndian<unsigned int, solidity::util::vector_ref<unsigned char const> >(solidity::util::vector_ref<unsigned char const> const&) |
123 | 143k | inline bytes toBigEndian(u256 _val) { bytes ret(32); toBigEndian(_val, ret); return ret; } |
124 | | |
125 | | /// Convenience function for toBigEndian. |
126 | | /// @returns a byte array just big enough to represent @a _val. |
127 | | template <class T> |
128 | | inline bytes toCompactBigEndian(T _val, unsigned _min = 0) |
129 | 2.47M | { |
130 | 2.47M | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift |
131 | 2.47M | unsigned i = 0; |
132 | 5.85M | for (T v = _val; v; ++i, v >>= 8) {} |
133 | 2.47M | bytes ret(std::max<unsigned>(_min, i), 0); |
134 | 2.47M | toBigEndian(_val, ret); |
135 | 2.47M | return ret; |
136 | 2.47M | } std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > solidity::toCompactBigEndian<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1> >(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, unsigned int) Line | Count | Source | 129 | 892 | { | 130 | 892 | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 131 | 892 | unsigned i = 0; | 132 | 29.4k | for (T v = _val; v; ++i, v >>= 8) {} | 133 | 892 | bytes ret(std::max<unsigned>(_min, i), 0); | 134 | 892 | toBigEndian(_val, ret); | 135 | 892 | return ret; | 136 | 892 | } |
std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > solidity::toCompactBigEndian<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0> >(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, unsigned int) Line | Count | Source | 129 | 282k | { | 130 | 282k | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 131 | 282k | unsigned i = 0; | 132 | 1.43M | for (T v = _val; v; ++i, v >>= 8) {} | 133 | 282k | bytes ret(std::max<unsigned>(_min, i), 0); | 134 | 282k | toBigEndian(_val, ret); | 135 | 282k | return ret; | 136 | 282k | } |
std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > solidity::toCompactBigEndian<unsigned long>(unsigned long, unsigned int) Line | Count | Source | 129 | 2.10M | { | 130 | 2.10M | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 131 | 2.10M | unsigned i = 0; | 132 | 4.20M | for (T v = _val; v; ++i, v >>= 8) {} | 133 | 2.10M | bytes ret(std::max<unsigned>(_min, i), 0); | 134 | 2.10M | toBigEndian(_val, ret); | 135 | 2.10M | return ret; | 136 | 2.10M | } |
std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > solidity::toCompactBigEndian<unsigned int>(unsigned int, unsigned int) Line | Count | Source | 129 | 92.8k | { | 130 | 92.8k | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 131 | 92.8k | unsigned i = 0; | 132 | 183k | for (T v = _val; v; ++i, v >>= 8) {} | 133 | 92.8k | bytes ret(std::max<unsigned>(_min, i), 0); | 134 | 92.8k | toBigEndian(_val, ret); | 135 | 92.8k | return ret; | 136 | 92.8k | } |
|
137 | | |
138 | | /// Convenience function for conversion of a u256 to hex |
139 | | inline std::string toHex(u256 val) |
140 | 143k | { |
141 | 143k | return util::toHex(toBigEndian(val)); |
142 | 143k | } |
143 | | |
144 | | template <class T> |
145 | | inline std::string toCompactHexWithPrefix(T _value) |
146 | 2.47M | { |
147 | 2.47M | return "0x" + util::toHex(toCompactBigEndian(_value, 1)); |
148 | 2.47M | } std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > solidity::toCompactHexWithPrefix<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0> >(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>) Line | Count | Source | 146 | 282k | { | 147 | 282k | return "0x" + util::toHex(toCompactBigEndian(_value, 1)); | 148 | 282k | } |
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > solidity::toCompactHexWithPrefix<unsigned int>(unsigned int) Line | Count | Source | 146 | 92.8k | { | 147 | 92.8k | return "0x" + util::toHex(toCompactBigEndian(_value, 1)); | 148 | 92.8k | } |
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > solidity::toCompactHexWithPrefix<unsigned long>(unsigned long) Line | Count | Source | 146 | 2.09M | { | 147 | 2.09M | return "0x" + util::toHex(toCompactBigEndian(_value, 1)); | 148 | 2.09M | } |
|
149 | | |
150 | | /// Returns decimal representation for small numbers and hex for large numbers. |
151 | | inline std::string formatNumber(bigint const& _value) |
152 | 892 | { |
153 | 892 | if (_value < 0) |
154 | 0 | return "-" + formatNumber(-_value); |
155 | 892 | if (_value > 0x1000000) |
156 | 892 | return "0x" + util::toHex(toCompactBigEndian(_value, 1)); |
157 | 0 | else |
158 | 0 | return _value.str(); |
159 | 892 | } |
160 | | |
161 | | inline std::string formatNumber(u256 const& _value) |
162 | 0 | { |
163 | 0 | if (_value > 0x1000000) |
164 | 0 | return toCompactHexWithPrefix(_value); |
165 | 0 | else |
166 | 0 | return _value.str(); |
167 | 0 | } |
168 | | |
169 | | |
170 | | // Algorithms for string and string-like collections. |
171 | | |
172 | | /// Determine bytes required to encode the given integer value. @returns 0 if @a _i is zero. |
173 | | template <class T> |
174 | | inline unsigned numberEncodingSize(T _i) |
175 | 135M | { |
176 | 135M | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift |
177 | 135M | unsigned i = 0; |
178 | 444M | for (; _i != 0; ++i, _i >>= 8) {} |
179 | 135M | return i; |
180 | 135M | } unsigned int solidity::numberEncodingSize<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1> >(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::__1::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>) Line | Count | Source | 175 | 3.18M | { | 176 | 3.18M | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 177 | 3.18M | unsigned i = 0; | 178 | 12.9M | for (; _i != 0; ++i, _i >>= 8) {} | 179 | 3.18M | return i; | 180 | 3.18M | } |
unsigned int solidity::numberEncodingSize<boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0> >(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>) Line | Count | Source | 175 | 121M | { | 176 | 121M | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 177 | 121M | unsigned i = 0; | 178 | 394M | for (; _i != 0; ++i, _i >>= 8) {} | 179 | 121M | return i; | 180 | 121M | } |
unsigned int solidity::numberEncodingSize<unsigned long>(unsigned long) Line | Count | Source | 175 | 10.8M | { | 176 | 10.8M | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 177 | 10.8M | unsigned i = 0; | 178 | 37.2M | for (; _i != 0; ++i, _i >>= 8) {} | 179 | 10.8M | return i; | 180 | 10.8M | } |
unsigned int solidity::numberEncodingSize<unsigned int>(unsigned int) Line | Count | Source | 175 | 14.4k | { | 176 | 14.4k | static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift | 177 | 14.4k | unsigned i = 0; | 178 | 46.8k | for (; _i != 0; ++i, _i >>= 8) {} | 179 | 14.4k | return i; | 180 | 14.4k | } |
|
181 | | |
182 | | } |