mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Add constexpr constructor for base_uint
This commit is contained in:
committed by
Nik Bougalis
parent
95426efb8a
commit
85307b29d0
@@ -1510,8 +1510,6 @@ loadByHashPostgres(uint256 const& ledgerHash, Application& app)
|
||||
static uint256
|
||||
getHashByIndexPostgres(std::uint32_t ledgerIndex, Application& app)
|
||||
{
|
||||
uint256 ret;
|
||||
|
||||
auto infos = loadLedgerInfosPostgres(ledgerIndex, app);
|
||||
assert(infos.size() <= 1);
|
||||
if (infos.size())
|
||||
|
||||
@@ -231,7 +231,6 @@ public:
|
||||
void
|
||||
gotStaleData(std::shared_ptr<protocol::TMLedgerData> packet_ptr) override
|
||||
{
|
||||
const uint256 uZero;
|
||||
Serializer s;
|
||||
try
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#ifndef RIPPLE_BASICS_BASE_UINT_H_INCLUDED
|
||||
#define RIPPLE_BASICS_BASE_UINT_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <ripple/basics/hardened_hash.h>
|
||||
#include <ripple/basics/strHex.h>
|
||||
#include <ripple/beast/utility/Zero.h>
|
||||
@@ -177,15 +178,94 @@ private:
|
||||
memcpy(data_.data(), data, bytes);
|
||||
}
|
||||
|
||||
public:
|
||||
base_uint()
|
||||
// Helper function to initialize a base_uint from a std::string_view.
|
||||
enum class ParseResult {
|
||||
okay,
|
||||
badLength,
|
||||
badChar,
|
||||
};
|
||||
|
||||
constexpr std::pair<ParseResult, decltype(data_)>
|
||||
parseFromStringView(std::string_view sv) noexcept
|
||||
{
|
||||
*this = beast::zero;
|
||||
// Local lambda that converts a single hex char to four bits and
|
||||
// ORs those bits into a uint32_t.
|
||||
auto hexCharToUInt = [](char c,
|
||||
std::uint32_t shift,
|
||||
std::uint32_t& accum) -> ParseResult {
|
||||
std::uint32_t nibble = 0xFFu;
|
||||
if (c < '0' || c > 'f')
|
||||
return ParseResult::badChar;
|
||||
|
||||
if (c >= 'a')
|
||||
nibble = static_cast<std::uint32_t>(c - 'a' + 0xA);
|
||||
else if (c >= 'A')
|
||||
nibble = static_cast<std::uint32_t>(c - 'A' + 0xA);
|
||||
else if (c <= '9')
|
||||
nibble = static_cast<std::uint32_t>(c - '0');
|
||||
|
||||
if (nibble > 0xFu)
|
||||
return ParseResult::badChar;
|
||||
|
||||
accum |= (nibble << shift);
|
||||
|
||||
return ParseResult::okay;
|
||||
};
|
||||
|
||||
std::pair<ParseResult, decltype(data_)> ret{ParseResult::okay, {}};
|
||||
|
||||
if (sv == "0")
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (sv.size() != size() * 2)
|
||||
{
|
||||
ret.first = ParseResult::badLength;
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto out = ret.second.data();
|
||||
|
||||
auto in = sv.begin();
|
||||
|
||||
while (in != sv.end())
|
||||
{
|
||||
std::uint32_t accum = {};
|
||||
for (std::uint32_t shift : {4u, 0u, 12u, 8u, 20u, 16u, 28u, 24u})
|
||||
{
|
||||
if (auto const result = hexCharToUInt(*in++, shift, accum);
|
||||
result != ParseResult::okay)
|
||||
{
|
||||
ret.first = result;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
*out++ = accum;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
base_uint(beast::Zero)
|
||||
constexpr decltype(data_)
|
||||
parseFromStringViewThrows(std::string_view sv) noexcept(false)
|
||||
{
|
||||
auto const result = parseFromStringView(sv);
|
||||
if (result.first == ParseResult::badLength)
|
||||
Throw<std::invalid_argument>("invalid length for hex string");
|
||||
|
||||
if (result.first == ParseResult::badChar)
|
||||
Throw<std::range_error>("invalid hex character");
|
||||
|
||||
return result.second;
|
||||
}
|
||||
|
||||
public:
|
||||
constexpr base_uint() : data_{}
|
||||
{
|
||||
}
|
||||
|
||||
constexpr base_uint(beast::Zero) : data_{}
|
||||
{
|
||||
*this = beast::zero;
|
||||
}
|
||||
|
||||
explicit base_uint(std::uint64_t b)
|
||||
@@ -193,6 +273,14 @@ public:
|
||||
*this = b;
|
||||
}
|
||||
|
||||
// This constructor is intended to be used at compile time since it might
|
||||
// throw at runtime. Consider declaring this constructor consteval once
|
||||
// we get to C++23.
|
||||
explicit constexpr base_uint(std::string_view sv) noexcept(false)
|
||||
: data_(parseFromStringViewThrows(sv))
|
||||
{
|
||||
}
|
||||
|
||||
template <
|
||||
class Container,
|
||||
class = std::enable_if_t<
|
||||
@@ -225,7 +313,7 @@ public:
|
||||
return base_uint(data, VoidHelper());
|
||||
}
|
||||
|
||||
int
|
||||
constexpr int
|
||||
signum() const
|
||||
{
|
||||
for (int i = 0; i < WIDTH; i++)
|
||||
@@ -380,37 +468,18 @@ public:
|
||||
@param sv A null-terminated string of hexadecimal characters
|
||||
@return true if the input was parsed properly; false otherwise.
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
[[nodiscard]] constexpr bool
|
||||
parseHex(std::string_view sv)
|
||||
{
|
||||
if (sv == "0")
|
||||
{
|
||||
zero();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sv.size() != bytes * 2)
|
||||
auto const result = parseFromStringView(sv);
|
||||
if (result.first != ParseResult::okay)
|
||||
return false;
|
||||
|
||||
auto out = data();
|
||||
|
||||
auto in = sv.begin();
|
||||
|
||||
while (in != sv.end())
|
||||
{
|
||||
auto const hi = charUnHex(*in++);
|
||||
auto const lo = charUnHex(*in++);
|
||||
|
||||
if (hi == -1 || lo == -1)
|
||||
return false;
|
||||
|
||||
*out++ = static_cast<std::uint8_t>((hi << 4) + lo);
|
||||
}
|
||||
|
||||
data_ = result.second;
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool
|
||||
[[nodiscard]] constexpr bool
|
||||
parseHex(const char* str)
|
||||
{
|
||||
return parseHex(std::string_view{str});
|
||||
|
||||
@@ -96,12 +96,8 @@ getBookBase(Book const& book)
|
||||
uint256
|
||||
getQualityNext(uint256 const& uBase)
|
||||
{
|
||||
static uint256 const nextq = []() {
|
||||
uint256 x;
|
||||
(void)x.parseHex(
|
||||
"0000000000000000000000000000000000000000000000010000000000000000");
|
||||
return x;
|
||||
}();
|
||||
static constexpr uint256 nextq(
|
||||
"0000000000000000000000000000000000000000000000010000000000000000");
|
||||
return uBase + nextq;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,11 +55,8 @@ to_string(Currency const& currency)
|
||||
if (currency == noCurrency())
|
||||
return "1";
|
||||
|
||||
static Currency const sIsoBits = []() {
|
||||
Currency c;
|
||||
(void)c.parseHex("FFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF");
|
||||
return c;
|
||||
}();
|
||||
static constexpr Currency sIsoBits(
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFF");
|
||||
|
||||
if ((currency & sIsoBits).isZero())
|
||||
{
|
||||
|
||||
@@ -56,7 +56,6 @@ SHAMap::visitNodes(std::function<bool(SHAMapTreeNode&)> const& function) const
|
||||
{
|
||||
while (pos < 16)
|
||||
{
|
||||
uint256 childHash;
|
||||
if (!node->isEmptyBranch(pos))
|
||||
{
|
||||
std::shared_ptr<SHAMapTreeNode> child =
|
||||
|
||||
Reference in New Issue
Block a user