6#ifndef XRPL_BASICS_BASE_UINT_H_INCLUDED
7#define XRPL_BASICS_BASE_UINT_H_INCLUDED
9#include <xrpl/basics/Expected.h>
10#include <xrpl/basics/Slice.h>
11#include <xrpl/basics/contract.h>
12#include <xrpl/basics/hardened_hash.h>
13#include <xrpl/basics/partitioned_unordered_map.h>
14#include <xrpl/basics/strHex.h>
15#include <xrpl/beast/utility/Zero.h>
16#include <xrpl/beast/utility/instrumentation.h>
18#include <boost/endian/conversion.hpp>
19#include <boost/functional/hash.hpp>
30template <
class Container,
class = std::
void_t<>>
35template <
class Container>
39 decltype(std::declval<Container const>().size()),
40 decltype(std::declval<Container const>().data()),
65template <std::
size_t Bits,
class Tag =
void>
70 "The length of a base_uint in bits must be a multiple of 32.");
74 "The length of a base_uint in bits must be at least 64.");
185 auto hexCharToUInt = [](
char c,
189 if (c <
'0' || c >
'f')
202 accum |= (nibble << shift);
207 decltype(
data_) ret{};
219 while (
in != sv.
end())
222 for (
std::uint32_t shift : {4u, 0u, 12u, 8u, 20u, 16u, 28u, 24u})
224 if (
auto const result = hexCharToUInt(*
in++, shift, accum);
233 constexpr decltype(
data_)
240 Throw<std::invalid_argument>(
"invalid length for hex string");
242 Throw<std::range_error>(
"invalid hex character");
277 c.size() *
sizeof(
typename Container::value_type) ==
size(),
278 "ripple::base_uint::base_uint(Container auto) : input size match");
282 template <
class Container>
290 c.size() *
sizeof(
typename Container::value_type) ==
size(),
291 "ripple::base_uint::operator=(Container auto) : input size match");
309 if (from.size() !=
size())
317 for (
int i = 0; i <
WIDTH; i++)
327 return *
this == beast::zero;
335 for (
int i = 0; i <
WIDTH; i++)
351 ul = boost::endian::native_to_big(uHost);
360 for (
int i = 0; i <
WIDTH; i++)
369 for (
int i = 0; i <
WIDTH; i++)
378 for (
int i = 0; i <
WIDTH; i++)
388 for (
int i =
WIDTH - 1; i >= 0; --i)
390 data_[i] = boost::endian::native_to_big(
391 boost::endian::big_to_native(
data_[i]) + 1);
412 for (
int i =
WIDTH - 1; i >= 0; --i)
415 data_[i] = boost::endian::native_to_big(
416 boost::endian::big_to_native(
data_[i]) - 1);
454 for (
int i =
WIDTH; i--;)
457 boost::endian::big_to_native(b.
data_[i]);
467 template <
class Hasher>
472 h(a.data_.data(),
sizeof(a.data_));
483 [[nodiscard]]
constexpr bool
494 [[nodiscard]]
constexpr bool
523 return *
this == beast::zero;
528 return *
this != beast::zero;
542template <std::
size_t Bits,
class Tag>
557 if (ret.first == lhs.
cend())
558 return std::strong_ordering::equivalent;
560 return (*ret.first > *ret.second) ? std::strong_ordering::greater
561 : std::strong_ordering::less;
564template <std::
size_t Bits,
typename Tag>
565[[nodiscard]]
inline constexpr bool
568 return (lhs <=> rhs) == 0;
572template <std::
size_t Bits,
class Tag>
580template <std::
size_t Bits,
class Tag>
581inline constexpr base_uint<Bits, Tag>
587template <std::
size_t Bits,
class Tag>
588inline constexpr base_uint<Bits, Tag>
594template <std::
size_t Bits,
class Tag>
595inline constexpr base_uint<Bits, Tag>
601template <std::
size_t Bits,
class Tag>
602inline constexpr base_uint<Bits, Tag>
609template <std::
size_t Bits,
class Tag>
616template <std::
size_t Bits,
class Tag>
622 "For 4 bytes or less, use a native type");
626template <std::
size_t Bits,
class Tag>
644#ifndef __INTELLISENSE__
645static_assert(
sizeof(
uint128) == 128 / 8,
"There should be no padding bytes");
646static_assert(
sizeof(
uint160) == 160 / 8,
"There should be no padding bytes");
647static_assert(
sizeof(
uint192) == 192 / 8,
"There should be no padding bytes");
648static_assert(
sizeof(
uint256) == 256 / 8,
"There should be no padding bytes");
655template <std::
size_t Bits,
class Tag>
An immutable linear range of bytes.
Integers of any length that is a multiple of 32-bits.
base_uint & operator^=(base_uint const &b)
constexpr bool parseHex(char const *str)
static std::size_t constexpr bytes
const_pointer data() const
static std::optional< base_uint > fromVoidChecked(T const &from)
constexpr decltype(data_) parseFromStringViewThrows(std::string_view sv) noexcept(false)
static base_uint fromVoid(void const *data)
base_uint const operator--(int)
const_pointer const_iterator
const_iterator cbegin() const
bool parseHex(std::string const &str)
constexpr base_uint(std::string_view sv) noexcept(false)
static constexpr std::size_t size()
constexpr base_uint operator~() const
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
const_iterator end() const
const_iterator cend() const
base_uint(Container const &c)
base_uint & operator&=(base_uint const &b)
base_uint & operator+=(base_uint const &b)
constexpr int signum() const
base_uint & operator|=(base_uint const &b)
static constexpr std::size_t WIDTH
value_type const & const_reference
value_type const * const_pointer
base_uint & operator=(std::uint64_t uHost)
constexpr Expected< decltype(data_), ParseResult > parseFromStringView(std::string_view sv) noexcept
std::enable_if_t< detail::is_contiguous_container< Container >::value &&std::is_trivially_copyable< typename Container::value_type >::value, base_uint & > operator=(Container const &c)
base_uint(std::uint64_t b)
const_iterator begin() const
base_uint(void const *data, VoidHelper)
constexpr base_uint(beast::Zero)
std::array< std::uint32_t, WIDTH > data_
base_uint const operator++(int)
friend void hash_append(Hasher &h, base_uint const &a) noexcept
base_uint< Bits, Tag > & operator=(beast::Zero)
Seed functor once per construction.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::string to_short_string(base_uint< Bits, Tag > const &a)
constexpr base_uint< Bits, Tag > operator|(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
constexpr std::strong_ordering operator<=>(base_uint< Bits, Tag > const &lhs, base_uint< Bits, Tag > const &rhs)
std::ostream & operator<<(std::ostream &out, base_uint< Bits, Tag > const &u)
constexpr base_uint< Bits, Tag > operator&(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
std::string strHex(FwdIt begin, FwdIt end)
std::string to_string(base_uint< Bits, Tag > const &a)
constexpr base_uint< Bits, Tag > operator^(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
constexpr base_uint< Bits, Tag > operator+(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
constexpr bool operator==(base_uint< Bits, Tag > const &lhs, base_uint< Bits, Tag > const &rhs)
std::size_t extract(uint256 const &key)
Zero allows classes to offer efficient comparisons to zero.
is_uniquely_represented()=default
Construct from a raw pointer.