mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-08 10:31:50 -05:00
refactor: Add consteval uint256(hex_str)
Complements uint256::FromHex() nicely in that it naturally does all error checking at compile time and so doesn't need to return an std::optional. Will be used in the following 2 commits to replace many calls to uint256S(). uint256S() calls taking C-string literals are littered throughout the codebase and executed at runtime to perform parsing unless a given optimizer was surprisingly efficient. While this may not be a hot spot, it's better hygiene in C++20 to store the parsed data blob directly in the binary, without any parsing at runtime.
This commit is contained in:
parent
1afa3c84fc
commit
b74d8d58fa
2 changed files with 30 additions and 0 deletions
|
@ -399,4 +399,11 @@ BOOST_AUTO_TEST_CASE( check_ONE )
|
|||
BOOST_CHECK_EQUAL(one, uint256::ONE);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(FromHex_vs_uint256)
|
||||
{
|
||||
auto runtime_uint{uint256::FromHex("4A5E1E4BAAB89F3A32518A88C31BC87F618f76673e2cc77ab2127b7afdeda33b").value()};
|
||||
constexpr uint256 consteval_uint{ "4a5e1e4baab89f3a32518a88c31bc87f618F76673E2CC77AB2127B7AFDEDA33B"};
|
||||
BOOST_CHECK_EQUAL(consteval_uint, runtime_uint);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
|
@ -41,6 +41,8 @@ public:
|
|||
std::copy(vch.begin(), vch.end(), m_data.begin());
|
||||
}
|
||||
|
||||
consteval explicit base_blob(std::string_view hex_str);
|
||||
|
||||
constexpr bool IsNull() const
|
||||
{
|
||||
return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) {
|
||||
|
@ -120,6 +122,26 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
template <unsigned int BITS>
|
||||
consteval base_blob<BITS>::base_blob(std::string_view hex_str)
|
||||
{
|
||||
// Non-lookup table version of HexDigit().
|
||||
auto from_hex = [](const char c) -> int8_t {
|
||||
if (c >= '0' && c <= '9') return c - '0';
|
||||
if (c >= 'a' && c <= 'f') return c - 'a' + 0xA;
|
||||
if (c >= 'A' && c <= 'F') return c - 'A' + 0xA;
|
||||
|
||||
assert(false); // Reached if ctor is called with an invalid hex digit.
|
||||
};
|
||||
|
||||
assert(hex_str.length() == m_data.size() * 2); // 2 hex digits per byte.
|
||||
auto str_it = hex_str.rbegin();
|
||||
for (auto& elem : m_data) {
|
||||
auto lo = from_hex(*(str_it++));
|
||||
elem = (from_hex(*(str_it++)) << 4) | lo;
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
/**
|
||||
* Writes the hex string (in reverse byte order) into a new uintN_t object
|
||||
|
@ -157,6 +179,7 @@ class uint256 : public base_blob<256> {
|
|||
public:
|
||||
static std::optional<uint256> FromHex(std::string_view str) { return detail::FromHex<uint256>(str); }
|
||||
constexpr uint256() = default;
|
||||
consteval explicit uint256(std::string_view hex_str) : base_blob<256>(hex_str) {}
|
||||
constexpr explicit uint256(uint8_t v) : base_blob<256>(v) {}
|
||||
constexpr explicit uint256(Span<const unsigned char> vch) : base_blob<256>(vch) {}
|
||||
static const uint256 ZERO;
|
||||
|
|
Loading…
Add table
Reference in a new issue