8#include <xrpl/basics/Slice.h>
9#include <xrpl/basics/contract.h>
10#include <xrpl/basics/hardened_hash.h>
11#include <xrpl/basics/partitioned_unordered_map.h>
12#include <xrpl/basics/strHex.h>
13#include <xrpl/beast/utility/Zero.h>
14#include <xrpl/beast/utility/instrumentation.h>
16#include <boost/endian/conversion.hpp>
17#include <boost/functional/hash.hpp>
29template <
class Container,
class = std::
void_t<>>
34template <
class Container>
38 decltype(std::declval<Container const>().size()),
39 decltype(std::declval<Container const>().data()),
69template <std::
size_t Bits,
class Tag =
void>
72 static_assert((Bits % 32) == 0,
"The length of a base_uint in bits must be a multiple of 32.");
74 static_assert(Bits >= 64,
"The length of a base_uint in bits must be at least 64.");
110 [[nodiscard]] const_pointer
180 constexpr std::expected<
decltype(data_), ParseResult>
187 if (c <
'0' || c >
'f')
188 return ParseResult::BadChar;
204 return ParseResult::BadChar;
206 accum |= (nibble << shift);
208 return ParseResult::Okay;
211 decltype(
data_) ret{};
222 auto in = sv.
begin();
223 while (in != sv.
end())
226 for (
std::uint32_t const shift : {4u, 0u, 12u, 8u, 20u, 16u, 28u, 24u})
228 if (
auto const result = hexCharToUInt(*in++, shift, accum);
229 result != ParseResult::Okay)
237 constexpr decltype(data_)
243 if (result.error() == ParseResult::BadLength)
284 "This constructor is not intended to be used and will be soon removed. "
285 "Use base_uint::fromRaw instead.");
298 c.size() *
sizeof(
typename Container::value_type) ==
size(),
299 "xrpl::BaseUInt::fromRaw(Container auto) : input size match");
304 template <
class Container>
312 c.size() *
sizeof(
typename Container::value_type) ==
size(),
313 "xrpl::BaseUInt::operator=(Container auto) : input size match");
331 if (from.size() !=
size())
336 [[nodiscard]]
constexpr int
339 for (
int i = 0; i <
kWidth; i++)
351 return *
this == beast::kZero;
359 for (
int i = 0; i <
kWidth; i++)
368 *
this = beast::kZero;
377 ul = boost::endian::native_to_big(uHost);
386 for (
int i = 0; i <
kWidth; i++)
395 for (
int i = 0; i <
kWidth; i++)
404 for (
int i = 0; i <
kWidth; i++)
414 for (
int i =
kWidth - 1; i >= 0; --i)
416 data_[i] = boost::endian::native_to_big(boost::endian::big_to_native(
data_[i]) + 1);
437 for (
int i =
kWidth - 1; i >= 0; --i)
440 data_[i] = boost::endian::native_to_big(boost::endian::big_to_native(
data_[i]) - 1);
478 for (
int i =
kWidth - 1; i >= 0; i--)
481 boost::endian::big_to_native(b.
data_[i]);
490 template <
class Hasher>
495 h(a.data_.data(),
sizeof(a.data_));
506 [[nodiscard]]
constexpr bool
517 [[nodiscard]]
constexpr bool
546 return *
this == beast::kZero;
551 return *
this != beast::kZero;
556 *
this = beast::kZero;
565template <std::
size_t Bits,
class Tag>
580 if (ret.first == lhs.
cend())
581 return std::strong_ordering::equivalent;
583 return (*ret.first > *ret.second) ? std::strong_ordering::greater : std::strong_ordering::less;
586template <std::
size_t Bits,
typename Tag>
587[[nodiscard]]
constexpr bool
590 return (lhs <=> rhs) == 0;
594template <std::
size_t Bits,
class Tag>
602template <std::
size_t Bits,
class Tag>
603constexpr BaseUInt<Bits, Tag>
609template <std::
size_t Bits,
class Tag>
610constexpr BaseUInt<Bits, Tag>
616template <std::
size_t Bits,
class Tag>
617constexpr BaseUInt<Bits, Tag>
623template <std::
size_t Bits,
class Tag>
624constexpr BaseUInt<Bits, Tag>
631template <std::
size_t Bits,
class Tag>
638template <std::
size_t Bits,
class Tag>
646template <std::
size_t Bits,
class Tag>
664#ifndef __INTELLISENSE__
665static_assert(
sizeof(
uint128) == 128 / 8,
"There should be no padding bytes");
666static_assert(
sizeof(
uint160) == 160 / 8,
"There should be no padding bytes");
667static_assert(
sizeof(
uint192) == 192 / 8,
"There should be no padding bytes");
668static_assert(
sizeof(
uint256) == 256 / 8,
"There should be no padding bytes");
675template <std::
size_t Bits,
class Tag>
Integers of any length that is a multiple of 32-bits.
static BaseUInt fromRaw(Container const &c)
std::reverse_iterator< iterator > reverse_iterator
BaseUInt(std::uint64_t b)
std::ptrdiff_t difference_type
static BaseUInt fromVoid(void const *data)
const_iterator cend() const
constexpr BaseUInt(std::string_view sv) noexcept(false)
BaseUInt & operator&=(BaseUInt const &b)
bool parseHex(std::string const &str)
constexpr int signum() const
BaseUInt & operator+=(BaseUInt const &b)
constexpr bool parseHex(char const *str)
value_type const * const_pointer
const_iterator begin() const
constexpr decltype(data_) parseFromStringViewThrows(std::string_view sv) noexcept(false)
std::reverse_iterator< const_iterator > const_reverse_iterator
constexpr std::expected< decltype(data_), ParseResult > parseFromStringView(std::string_view sv) noexcept
BaseUInt & operator|=(BaseUInt const &b)
const_pointer data() const
static constexpr std::size_t kWidth
BaseUInt< Bits, Tag > & operator=(beast::Zero)
std::array< std::uint32_t, kWidth > data_
constexpr BaseUInt(beast::Zero)
HardenedHash<> hasher
Value hashing function.
BaseUInt(void const *data, VoidHelper)
friend void hash_append(Hasher &h, BaseUInt const &a) noexcept
const_pointer const_iterator
BaseUInt & operator^=(BaseUInt const &b)
std::enable_if_t< detail::IsContiguousContainer< Container >::value &&std::is_trivially_copyable_v< typename Container::value_type >, BaseUInt & > operator=(Container const &c)
constexpr BaseUInt operator~() const
static constexpr std::size_t kBytes
static std::optional< BaseUInt > fromVoidChecked(T const &from)
const_iterator end() const
BaseUInt & operator=(std::uint64_t uHost)
static constexpr std::size_t size()
value_type const & const_reference
BaseUInt(Container const &c)
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
const_iterator cbegin() const
Seed functor once per construction.
An immutable linear range of bytes.
T is_trivially_copyable_v
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
constexpr BaseUInt< Bits, Tag > operator+(BaseUInt< Bits, Tag > const &a, BaseUInt< Bits, Tag > const &b)
constexpr BaseUInt< Bits, Tag > operator^(BaseUInt< Bits, Tag > const &a, BaseUInt< Bits, Tag > const &b)
std::size_t extract(uint256 const &key)
constexpr BaseUInt< Bits, Tag > operator&(BaseUInt< Bits, Tag > const &a, BaseUInt< Bits, Tag > const &b)
constexpr bool operator==(BaseUInt< Bits, Tag > const &lhs, BaseUInt< Bits, Tag > const &rhs)
std::string strHex(FwdIt begin, FwdIt end)
constexpr BaseUInt< Bits, Tag > operator|(BaseUInt< Bits, Tag > const &a, BaseUInt< Bits, Tag > const &b)
std::ostream & operator<<(std::ostream &out, BaseUInt< Bits, Tag > const &u)
std::string to_string(BaseUInt< Bits, Tag > const &a)
Dir::ConstIterator const_iterator
std::string toShortString(BaseUInt< Bits, Tag > const &a)
constexpr std::strong_ordering operator<=>(BaseUInt< Bits, Tag > const &lhs, BaseUInt< Bits, Tag > const &rhs)
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
IsUniquelyRepresented()=default
Zero allows classes to offer efficient comparisons to zero.