25 #ifndef RIPPLE_BASICS_BASE_UINT_H_INCLUDED
26 #define RIPPLE_BASICS_BASE_UINT_H_INCLUDED
28 #include <ripple/basics/Expected.h>
29 #include <ripple/basics/Slice.h>
30 #include <ripple/basics/contract.h>
31 #include <ripple/basics/hardened_hash.h>
32 #include <ripple/basics/strHex.h>
33 #include <ripple/beast/utility/Zero.h>
34 #include <boost/endian/conversion.hpp>
35 #include <boost/functional/hash.hpp>
45 template <
class Container,
class = std::
void_t<>>
50 template <
class Container>
54 decltype(std::declval<Container const>().size()),
55 decltype(std::declval<Container const>().data()),
80 template <std::
size_t Bits,
class Tag =
void>
85 "The length of a base_uint in bits must be a multiple of 32.");
89 "The length of a base_uint in bits must be at least 64.");
200 auto hexCharToUInt = [](
char c,
204 if (c < '0' || c >
'f')
217 accum |= (nibble << shift);
222 decltype(
data_) ret{};
229 if (sv.size() !=
size() * 2)
233 auto in = sv.begin();
234 while (
in != sv.end())
237 for (
std::uint32_t shift : {4u, 0u, 12u, 8u, 20u, 16u, 28u, 24u})
239 if (
auto const result = hexCharToUInt(*
in++, shift, accum);
248 constexpr decltype(
data_)
255 Throw<std::invalid_argument>(
"invalid length for hex string");
257 Throw<std::range_error>(
"invalid hex character");
291 assert(c.size() *
sizeof(
typename Container::value_type) ==
size());
295 template <
class Container>
302 assert(c.size() *
sizeof(
typename Container::value_type) ==
size());
320 if (from.size() !=
size())
328 for (
int i = 0; i <
WIDTH; i++)
338 return *
this == beast::zero;
346 for (
int i = 0; i <
WIDTH; i++)
362 ul = boost::endian::native_to_big(uHost);
371 for (
int i = 0; i <
WIDTH; i++)
380 for (
int i = 0; i <
WIDTH; i++)
389 for (
int i = 0; i <
WIDTH; i++)
399 for (
int i =
WIDTH - 1; i >= 0; --i)
401 data_[i] = boost::endian::native_to_big(
402 boost::endian::big_to_native(
data_[i]) + 1);
423 for (
int i =
WIDTH - 1; i >= 0; --i)
426 data_[i] = boost::endian::native_to_big(
427 boost::endian::big_to_native(
data_[i]) - 1);
465 for (
int i =
WIDTH; i--;)
468 boost::endian::big_to_native(b.
data_[i]);
478 template <
class Hasher>
483 h(a.data_.data(),
sizeof(a.data_));
494 [[nodiscard]] constexpr
bool
505 [[nodiscard]] constexpr
bool
533 return *
this == beast::zero;
538 return *
this != beast::zero;
551 template <std::
size_t Bits,
class Tag>
557 if (ret.first == a.
cend())
561 if (*ret.first > *ret.second)
568 template <std::
size_t Bits,
class Tag>
575 template <std::
size_t Bits,
class Tag>
582 template <std::
size_t Bits,
class Tag>
589 template <std::
size_t Bits,
class Tag>
596 template <std::
size_t Bits,
class Tag>
603 template <std::
size_t Bits,
class Tag>
611 template <std::
size_t Bits,
class Tag>
618 template <std::
size_t Bits,
class Tag>
626 template <std::
size_t Bits,
class Tag>
627 inline const base_uint<Bits, Tag>
633 template <std::
size_t Bits,
class Tag>
634 inline const base_uint<Bits, Tag>
640 template <std::
size_t Bits,
class Tag>
641 inline const base_uint<Bits, Tag>
647 template <std::
size_t Bits,
class Tag>
648 inline const base_uint<Bits, Tag>
655 template <std::
size_t Bits,
class Tag>
662 template <std::
size_t Bits,
class Tag>
669 #ifndef __INTELLISENSE__
670 static_assert(
sizeof(
uint128) == 128 / 8,
"There should be no padding bytes");
671 static_assert(
sizeof(
uint160) == 160 / 8,
"There should be no padding bytes");
672 static_assert(
sizeof(
uint256) == 256 / 8,
"There should be no padding bytes");
679 template <std::
size_t Bits,
class Tag>
bool operator>(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
const base_uint< Bits, Tag > operator|(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
const base_uint operator--(int)
friend void hash_append(Hasher &h, base_uint const &a) noexcept
Construct from a raw pointer.
An immutable linear range of bytes.
bool operator>=(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
base_uint(Container const &c)
const_pointer data() const
Unexpected(E(&)[N]) -> Unexpected< E const * >
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)
const_iterator cbegin() const
static constexpr std::size_t WIDTH
static std::optional< base_uint > fromVoidChecked(T const &from)
std::ostream & operator<<(std::ostream &os, TOffer< TIn, TOut > const &offer)
bool operator==(Manifest const &lhs, Manifest const &rhs)
constexpr static std::size_t size()
const_pointer const_iterator
constexpr Expected< decltype(data_), ParseResult > parseFromStringView(std::string_view sv) noexcept
constexpr base_uint operator~() const
bool parseHex(std::string const &str)
is_uniquely_represented()=default
Integers of any length that is a multiple of 32-bits.
value_type const & const_reference
bool operator<=(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
base_uint & operator|=(const base_uint &b)
const base_uint< Bits, Tag > operator+(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
static constexpr std::size_t bytes
std::array< std::uint32_t, WIDTH > data_
bool operator<(CanonicalTXSet::Key const &lhs, CanonicalTXSet::Key const &rhs)
int compare(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
base_uint & operator&=(const base_uint &b)
const_iterator begin() const
bool operator!=(Manifest const &lhs, Manifest const &rhs)
Zero allows classes to offer efficient comparisons to zero.
Seed functor once per construction.
constexpr int signum() const
constexpr base_uint(beast::Zero)
const base_uint< Bits, Tag > operator^(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
const base_uint< Bits, Tag > operator&(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
constexpr bool parseHex(const char *str)
base_uint(void const *data, VoidHelper)
constexpr decltype(data_) parseFromStringViewThrows(std::string_view sv) noexcept(false)
base_uint< Bits, Tag > & operator=(beast::Zero)
base_uint(std::uint64_t b)
static base_uint fromVoid(void const *data)
const_iterator end() const
base_uint & operator^=(const base_uint &b)
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
const base_uint operator++(int)
const_iterator cend() const
std::string strHex(FwdIt begin, FwdIt end)
base_uint & operator=(std::uint64_t uHost)
base_uint & operator+=(const base_uint &b)
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
value_type const * const_pointer
constexpr base_uint(std::string_view sv) noexcept(false)