poly_ops/large_ints.hpp

Concepts

template<typename T>
concept large_ints::comp_or_single_i

Matches an instance of compound_xint or a built-in integer.


template<typename T, unsigned int N, bool Signed>
concept large_ints::safe_comp_or_single_i

Matches an instance of compound_xint or a built-in integer than can cast to compound_xint<N,Signed> without loss of information.

Types

template<unsigned int N, bool Signed>
class large_ints::compound_xint

Public Types

using value_type = full_uint

Public Functions

compound_xint() noexcept = default
inline constexpr compound_xint(full_uint b) noexcept
template<comp_or_single_i T>
inline constexpr compound_xint(full_uint _hi, T _lo) noexcept
template<comp_or_single_i T>
inline explicit(detail::_int_count<Signed, std::decay_t<T>>::value > N || (detail::signed_type<T> && !Signed)) const expr compound_xint(
const T &b,
)
constexpr compound_xint(const compound_xint&) noexcept = default
constexpr compound_xint &operator=(const compound_xint&) noexcept = default
template<safe_comp_or_single_i<N, Signed> T>
inline compound_xint &operator=(const T &b) noexcept
inline compound_xint operator-() const noexcept
template<detail::builtin_number T>
explicit operator T() const noexcept
inline constexpr bool negative() const noexcept
inline explicit constexpr operator bool() const noexcept
inline constexpr operator compound_xint_ref<N>() noexcept
inline constexpr operator const_compound_xint_ref<N>() const noexcept
inline constexpr full_uint hi() const noexcept
inline constexpr full_uint &hi() noexcept
inline constexpr auto lo() const noexcept
inline constexpr auto lo() noexcept
inline constexpr full_uint operator[](unsigned int i) const noexcept
inline constexpr full_uint &operator[](unsigned int i) noexcept
inline std::size_t size() const
inline const full_uint *data() const noexcept
inline full_uint *data() noexcept
inline const full_uint *begin() const noexcept
inline full_uint *begin() noexcept
inline const full_uint *end() const noexcept
inline full_uint *end() noexcept

template<unsigned int N>
using large_ints::compound_int = compound_xint<N, true>

template<unsigned int N>
using large_ints::compound_uint = compound_xint<N, false>

template<unsigned int N, bool Const>
class large_ints::_compound_xint_ref

Public Types

using value_type = std::conditional_t<Const, const full_uint, full_uint>

Public Functions

inline explicit constexpr _compound_xint_ref(value_type *_data) noexcept
constexpr _compound_xint_ref(const _compound_xint_ref&) noexcept = default
inline constexpr _compound_xint_ref(const _compound_xint_ref<N, false> &b) noexcept
template<bool ConstB>
inline constexpr const _compound_xint_ref &operator=(
const _compound_xint_ref<N, ConstB> &b,
) const noexcept
template<typename T>
inline constexpr void set(const T &b) const noexcept
inline constexpr value_type &hi() const noexcept
inline constexpr auto lo() const noexcept
inline constexpr value_type &operator[](unsigned int i) const noexcept
inline value_type *data() const noexcept
inline value_type *begin() const noexcept
inline value_type *end() const noexcept

template<unsigned int N>
using large_ints::compound_xint_ref = _compound_xint_ref<N, false>

template<unsigned int N>
using large_ints::const_compound_xint_ref = _compound_xint_ref<N, true>

template<std::size_t Size>
using large_ints::sized_int = std::conditional_t<(Size <= sizeof(full_int)), detail::bltin_sized_int<Size>, compound_int<(Size + sizeof(full_int) - 1) / sizeof(full_int)>>

template<typename Q, typename R = Q>
struct large_ints::quot_rem

Public Members

Q quot
R rem

enum large_ints::modulo_t::value_t

Values:

enumerator truncate_v
enumerator euclid_v

template<value_t Mod>
using large_ints::modulo_t::type = std::integral_constant<value_t, Mod>

Constants

constexpr type<truncate_v> large_ints::modulo_t::truncate = {}

constexpr type<euclid_v> large_ints::modulo_t::euclid = {}

Functions

template<typename T, typename U>
auto large_ints::add(const T &a, const U &b) noexcept

template<typename T, typename U>
auto large_ints::sub(const T &a, const U &b) noexcept

template<typename T, typename U>
auto large_ints::mul(const T &a, const U &b) noexcept

Multiply a and b and return a type big enough to not overflow


template<comp_or_single_i T, comp_or_single_i U, modulo_t::value_t Mod = modulo_t::truncate_v>
auto large_ints::divmod(
const T &a,
const U &b,
modulo_t::type<Mod> = {},
) noexcept

template<unsigned int Nr, typename T, typename U, modulo_t::value_t Mod = modulo_t::truncate_v, bool Signed = detail::signed_type<T> || detail::signed_type<U>>
auto large_ints::unmul(
const T &a,
const U &b,
modulo_t::type<Mod> = {},
) noexcept

“unmul” is short for un-multiply. It is like a normal division function except it assumes a/b fits inside compound_xint<Nr,Signed>.

Most of the time, this is just normal division followed by a cast, but on x86 platforms, when Nr is 1, T is equivalent to compound_xint with a size of 2 and U is equivalent to compound_xint with a size of 1, this operation only needs a single CPU instruction.


template<typename T>
auto large_ints::abs(const T &x) noexcept

template<typename T>
int large_ints::countl_zero(const T &x) noexcept

template<typename T>
auto large_ints::shift_right(const T &a, unsigned int amount) noexcept

template<typename T>
auto large_ints::shift_left(const T &a, unsigned char amount) noexcept

template<typename T, typename U, unsigned int N = detail::max_int_count<detail::signed_type<T> || detail::signed_type<U>, T, U>>
bool large_ints::eq(
const T &a,
const U &b,
) noexcept

template<typename T, typename U>
std::strong_ordering large_ints::cmp(const T &a, const U &b) noexcept

template<unsigned int N, bool Signed>
bool large_ints::negative(const compound_xint<N, Signed> &x) noexcept

template<detail::integral T>
bool large_ints::negative(T x) noexcept

template<unsigned int N, bool Signed, comp_or_single_i T>
bool large_ints::operator==(
const compound_xint<N, Signed> &a,
const T &b,
) noexcept

template<detail::integral T, unsigned int N, bool Signed>
bool large_ints::operator==(
const T &a,
const compound_xint<N, Signed> &b,
) noexcept

template<unsigned int N, bool Signed, comp_or_single_i T>
auto large_ints::operator+(
const compound_xint<N, Signed> &a,
const T &b,
) noexcept

template<detail::integral T, unsigned int N, bool Signed>
auto large_ints::operator+(
const T &a,
const compound_xint<N, Signed> &b,
) noexcept

template<unsigned int N, bool Signed, comp_or_single_i T>
auto large_ints::operator-(
const compound_xint<N, Signed> &a,
const T &b,
) noexcept

template<detail::integral T, unsigned int N, bool Signed>
auto large_ints::operator-(
const T &a,
const compound_xint<N, Signed> &b,
) noexcept

template<unsigned int N, bool Signed, comp_or_single_i T>
auto large_ints::operator*(
const compound_xint<N, Signed> &a,
const T &b,
) noexcept

template<detail::integral T, unsigned int N, bool Signed>
auto large_ints::operator*(
const T &a,
const compound_xint<N, Signed> &b,
) noexcept

template<unsigned int N, bool Signed, comp_or_single_i T>
auto large_ints::operator/(
const compound_xint<N, Signed> &a,
const T &b,
) noexcept

template<detail::integral T, unsigned int N, bool Signed>
auto large_ints::operator/(
const T &a,
const compound_xint<N, Signed> &b,
) noexcept

template<unsigned int N, bool Signed, safe_comp_or_single_i<N, Signed> T>
compound_xint<N, Signed> &large_ints::operator+=(
compound_xint<N, Signed> &a,
const T &b,
) noexcept

template<unsigned int N, bool Signed, safe_comp_or_single_i<N, Signed> T>
compound_xint<N, Signed> &large_ints::operator-=(
compound_xint<N, Signed> &a,
const T &b,
) noexcept

template<unsigned int N, bool Signed>
compound_xint<N, Signed> large_ints::operator>>(
const compound_xint<N, Signed> &a,
unsigned char amount,
) noexcept

template<unsigned int N, bool Signed>
compound_xint<N, Signed> &large_ints::operator>>=(
compound_xint<N, Signed> &a,
unsigned char amount,
) noexcept

template<unsigned int N, bool Signed>
compound_xint<N, Signed> large_ints::operator<<(
const compound_xint<N, Signed> &a,
unsigned char amount,
) noexcept

template<unsigned int N, bool Signed>
compound_xint<N, Signed> &large_ints::operator<<=(
compound_xint<N, Signed> &a,
unsigned char amount,
) noexcept

template<unsigned int N, bool Signed, comp_or_single_i T>
auto large_ints::operator<=>(
const compound_xint<N, Signed> &a,
const T &b,
) noexcept

template<char... C>
constexpr auto large_ints::operator""_compi()

Parse a hexadecimal value and return a compound_int instance with the smallest size that can fit all the digits, including Leading zeros (after the initial “0x”)