apytypes_util.h
¶
Defines
-
UINT64_TO_LIMB(x)¶
-
CREATE_FUNCTOR_FROM_FUNC(FUNCTOR_NAME, FUNC_NAME)¶
Macro for creating a void-specialization state-less functor
FUNCTOR_NAME
from a functionFUNC_NAME
. The void-specialization functor allows template argument deduction to be performed once its function is called. Neat!
Functions
-
static inline void apytypes_unreachable()¶
Mark code path unreachable. Allows the compiler to make further control-flow optimizations. Calling this function under any circumstance is undefined behaviour.
-
static inline std::tuple<apy_limb_t, apy_limb_t> long_mult(apy_limb_t src0, apy_limb_t src1)¶
Compute multiplication between two apy_limb_t and obtain double length result.
-
template<typename INT_TYPE>
static inline std::size_t trailing_zeros(INT_TYPE n)¶ Compute the number of trailing zeros in an integer.
-
template<typename INT_TYPE>
static inline std::size_t leading_zeros(INT_TYPE n)¶ Compute the number of leading zeros in an integer.
-
template<typename INT_TYPE>
static inline std::size_t leading_ones(INT_TYPE n)¶ Compute number of leading ones in an integer.
-
template<typename INT_TYPE>
static inline std::size_t bit_width(INT_TYPE n)¶ Compute bit-width (
ceil(log2(1 + n))
for unsignedn
) of an integern
.
-
template<typename INT_TYPE>
static inline std::size_t count_trailing_bits(INT_TYPE n)¶ Compute number of trailing bits after most significant
1
in an integer.
-
static inline std::size_t bits_to_limbs(std::size_t bits)¶
Quickly evaluate how many limbs are required to to store a
bits
bit word. Undefined behaviour whenbits
is equal to zero.
-
template<class RANDOM_ACCESS_ITERATOR>
static inline std::size_t significant_limbs(RANDOM_ACCESS_ITERATOR begin, RANDOM_ACCESS_ITERATOR end)¶ Count the number of significant limbs in unsigned limb vector.
-
template<class RANDOM_ACCESS_ITERATOR>
static inline std::size_t limb_vector_leading_zeros(RANDOM_ACCESS_ITERATOR begin, RANDOM_ACCESS_ITERATOR end)¶ Return the number of leading zeros of a limb vector.
-
template<class RANDOM_ACCESS_ITERATOR>
static inline std::size_t limb_vector_leading_ones(RANDOM_ACCESS_ITERATOR begin, RANDOM_ACCESS_ITERATOR end)¶ Return the number of leading signs of a limb vector, minus one.
-
template<typename INT_TYPE>
static inline std::size_t nibble_width(INT_TYPE x)¶ Quickly count the number of nibbles in an unsigned
apy_limb_t
-
static inline std::vector<std::uint8_t> to_nibble_list(const std::vector<apy_limb_t> &data_array, std::size_t len = 0)¶
Convert a positive arbitrary size integer array (
std::vector<apy_limb_t>
) to a nibble list. The nibble list contains least significant nibble first. Argumentlen
indicates the intended bcd length of the output. When set, no more thanresult.rend() - len
zeros will be removed.
-
static inline std::vector<apy_limb_t> from_nibble_list(const std::vector<std::uint8_t> &nibble_list)¶
Convert a nibble list into a positive integer array (
std::vector<apy_limb_t>
). The nibble list is assumed to have least significant nibble first.
-
static inline std::vector<apy_limb_t> double_dabble(std::vector<apy_limb_t> nibble_data)¶
Double-dabble algorithm for binary->BCD conversion.
-
static inline std::string bcds_to_string(const std::vector<apy_limb_t> bcds)¶
Convert a BCD limb vector into a
std::string
.
-
static inline std::vector<apy_limb_t> reverse_double_dabble(const std::vector<std::uint8_t> &bcd_list)¶
Reverse double-dabble algorithm for BCD->binary conversion.
-
static inline void bcd_limb_vec_div2(std::vector<apy_limb_t> &bcd_list)¶
Divide the number in a BCD limb vector by two.
-
static inline void bcd_limb_vec_mul2(std::vector<apy_limb_t> &bcd_list)¶
Multiply the number in a BCD limb vector by two.
-
static inline void bcd_mul2(std::vector<std::uint8_t> &bcd_list)¶
Multiply BCD vector (
std::vector<std::uint8_t>
) by two. The first element (front()
) in the vector is considered LSB.
-
static inline std::string string_trim_leading_whitespace(const std::string &str)¶
Trim a string from leading whitespace.
-
static inline std::string string_trim_trailing_whitespace(const std::string &str)¶
Trim a string from trailing whitespace.
-
static inline std::string string_trim_whitespace(const std::string &str)¶
Trim a string from leading and trailing whitespace.
-
static inline bool is_valid_decimal_numeric_string(const std::string &str)¶
Test if a string is a valid numeric decimal string.
-
static inline std::string string_trim_zeros(const std::string &str)¶
Trim a string from unnecessary leading and trailing zeros, that don’t affect numeric value of the string. This function also attaches a zero to the string if it starts with a decimal dot, and it removes the decimal dot if no digit after it affects its value (e.g., 0.00 == 0).
-
template<class RANDOM_ACCESS_ITERATOR>
static inline void limb_vector_asr(RANDOM_ACCESS_ITERATOR it_begin, RANDOM_ACCESS_ITERATOR it_end, unsigned shift_amnt)¶ Perform arithmetic right shift on a limb vector.
-
template<class RANDOM_ACCESS_ITERATOR>
static inline void limb_vector_lsr(RANDOM_ACCESS_ITERATOR it_begin, RANDOM_ACCESS_ITERATOR it_end, unsigned shift_amnt)¶ Perform logical right shift on a limb vector.
-
template<class RANDOM_ACCESS_ITERATOR>
static inline void limb_vector_lsl_inner(RANDOM_ACCESS_ITERATOR it_begin, RANDOM_ACCESS_ITERATOR it_end, unsigned int limb_skip, unsigned int limb_shift, unsigned int vec_size)¶ Perform logical left shift on a limb vector.
-
template<class RANDOM_ACCESS_ITERATOR>
static inline void limb_vector_lsl(RANDOM_ACCESS_ITERATOR it_begin, RANDOM_ACCESS_ITERATOR it_end, unsigned shift_amnt)¶ Perform logical left shift on a limb vector.
-
template<class RANDOM_ACCESS_ITERATOR>
static inline bool limb_vector_gte_pow2(RANDOM_ACCESS_ITERATOR it_begin, RANDOM_ACCESS_ITERATOR it_end, unsigned n)¶ Test if positive integer value in limb vector is greater than or equal to a non-negative power-of-two (>= 2 ^
n
for unsignedn
)
-
template<class RANDOM_ACCESS_ITERATOR1, class RANDOM_ACCESS_ITERATOR2>
static inline bool limb_vector_signed_less_than(RANDOM_ACCESS_ITERATOR1 src1, RANDOM_ACCESS_ITERATOR2 src2, std::size_t limbs)¶ Test if the (two’s complement) value of
src1
is smaller than that ofsrc2
-
template<class RANDOM_ACCESS_ITERATOR>
static inline apy_limb_t limb_vector_add_pow2(RANDOM_ACCESS_ITERATOR it_begin, RANDOM_ACCESS_ITERATOR it_end, unsigned n)¶ Add a power-of-two (2 ^
n
) onto a limb vector. Return carry out.
-
template<class RANDOM_ACCESS_ITERATOR>
static inline apy_limb_t limb_vector_sub_pow2(RANDOM_ACCESS_ITERATOR it_begin, RANDOM_ACCESS_ITERATOR it_end, unsigned n)¶ Subtract a power-of-two (2 ^
n
) from a limb vector. Return borrow.
-
static inline int bits_from_optional(std::optional<int> bits, std::optional<int> int_bits, std::optional<int> frac_bits)¶
Return the
bits
specifier from user provided optional bit specifiers. Throwsnb::value_error
if the resulting number of bits is less than or equal to zero, or if not exactly two of three bit specifiers are set.
-
static inline std::tuple<int, int> bits_from_optional_cast(std::optional<int> bits, std::optional<int> int_bits, std::optional<int> frac_bits, int current_bits, int current_int_bits)¶
Return a two-tuple of ints (
bits
,int_bits
) for a set of optional bit-specifiers used in the casting context. Throwsnanobind::value_error
if parameters do not add up, or if resultingbits
is smaller than or equal to zero.
-
template<class RANDOM_ACCESS_ITERATOR>
static inline bool limb_vector_is_negative(RANDOM_ACCESS_ITERATOR cbegin_it, RANDOM_ACCESS_ITERATOR cend_it)¶ Test if two’s complement value in a limb vector is negative.
-
template<class RANDOM_ACCESS_ITERATOR>
static inline bool limb_vector_is_zero(RANDOM_ACCESS_ITERATOR cbegin_it, RANDOM_ACCESS_ITERATOR cend_it)¶ Test if the stored value of a limb vector is zero (all limbs are zero)
-
template<class RANDOM_ACCESS_ITERATOR>
static inline bool limb_vector_or_reduce(RANDOM_ACCESS_ITERATOR cbegin_it, RANDOM_ACCESS_ITERATOR cend_it, unsigned n)¶ Reduce the first
n
bits in a limb vector over bitwiseor
. Return bool. Unconditionally Returnfalse
whenn == 0
. Undefined behaviour ifn
is greater than the number of bits in the limb vector.
-
template<class RANDOM_ACCESS_ITERATOR>
static inline bool limb_vector_test_bit(RANDOM_ACCESS_ITERATOR cbegin_it, RANDOM_ACCESS_ITERATOR cend_it, unsigned n)¶ Test if the
n
-th bit (zero indexed) is set in a limb vector. Undefined behaviour if bitn
is located outside the limb vector.
-
template<class RANDOM_ACCESS_ITERATOR>
static inline void limb_vector_set_bit(RANDOM_ACCESS_ITERATOR begin_it, RANDOM_ACCESS_ITERATOR end_it, unsigned n, bool bit)¶ Set the
n
-th bit (zero indexed) of a limb vector tobit
. Undefined behaviour if bitn
is located outside the limb vector.
-
template<class RANDOM_ACCESS_ITERATOR_IN, class RANDOM_ACCESS_ITERATOR_OUT>
static inline apy_limb_t limb_vector_negate(RANDOM_ACCESS_ITERATOR_IN cbegin_it, RANDOM_ACCESS_ITERATOR_IN cend_it, RANDOM_ACCESS_ITERATOR_OUT res_it)¶ Take the two’s complement negative value of a limb vector and place onto
res_out
-
template<class RANDOM_ACCESS_ITERATOR_IN>
static inline apy_limb_t limb_vector_negate_inplace(RANDOM_ACCESS_ITERATOR_IN cbegin_it, RANDOM_ACCESS_ITERATOR_IN cend_it)¶ Take the two’s complement negative value of a limb vector inplace.
-
template<class RANDOM_ACCESS_ITERATOR_IN, class RANDOM_ACCESS_ITERATOR_OUT>
static inline bool limb_vector_abs(RANDOM_ACCESS_ITERATOR_IN cbegin_it, RANDOM_ACCESS_ITERATOR_IN cend_it, RANDOM_ACCESS_ITERATOR_OUT res_it)¶ Take the two’s complement absolute value of a limb vector and place onto
res_out
. Returntrue
if the argument is negative
-
template<class RANDOM_ACCESS_ITERATOR>
static inline bool limb_vector_all_zeros(RANDOM_ACCESS_ITERATOR cbegin_it, RANDOM_ACCESS_ITERATOR cend_it, unsigned n = 0)¶ Test if the bits in a limb vector are all zeros starting from bit
n
(zero indexed). Bitn
is assumed to be located in the first limb.
-
template<class RANDOM_ACCESS_ITERATOR>
static inline bool limb_vector_all_ones(RANDOM_ACCESS_ITERATOR cbegin_it, RANDOM_ACCESS_ITERATOR cend_it, unsigned n = 0)¶ Test if the bits in a limb vector are all ones starting from bit
n
(zero indexed). Bitn
is assumed to be located in the first limb.
-
template<typename RANDOM_ACCESS_ITERATOR_IN, typename RANDOM_ACCESS_ITERATOR_OUT>
static inline void limb_vector_copy_sign_extend(RANDOM_ACCESS_ITERATOR_IN src_begin, RANDOM_ACCESS_ITERATOR_IN src_end, RANDOM_ACCESS_ITERATOR_OUT dst_begin, RANDOM_ACCESS_ITERATOR_OUT dst_end)¶ Copy limbs from
src
todst
and possibly sign extend the data indst
-
template<typename VECTOR_TYPE>
static inline uint64_t uint64_t_from_limb_vector(const VECTOR_TYPE &limb_vec, std::size_t n)¶ Read an unsigned 64-bit value from a limb vector. If
APY_LIMB_SIZE_BITS == 64
, this results in a normal vector read without bounds checking. IfAPY_LIMB_SIZE_BITS == 32
, the second 32-bits limb is bound-checked and the result upper 32-bits are zeroed if out-of-bounds.
-
template<typename T>
std::string tuple_string_from_vec(const std::vector<T> &vec)¶ Construct a Python tuple-literal-string from a vector of
T
. The typeT
must be convertible to string through both astd::stringstream
andfmt::format({})
.
-
static inline apy_limb_t twos_complement_overflow(apy_limb_t value, int bits)¶
-
static inline std::size_t fold_shape(std::vector<std::size_t>::const_iterator cbegin, std::vector<std::size_t>::const_iterator cend)¶
Fold a shape under multiplication.
-
static inline std::size_t fold_shape(const std::vector<std::size_t> &shape)¶
Fold a shape under multiplication.
-
static inline std::vector<std::size_t> strides_from_shape(const std::vector<std::size_t> &shape, std::size_t acc_base = 1)¶
Compute the strides from a shape.
-
template<typename RANDOM_ACCESS_ITERATOR_INOUT>
static inline void multi_limb_swap(RANDOM_ACCESS_ITERATOR_INOUT a_it, RANDOM_ACCESS_ITERATOR_INOUT b_it, std::size_t itemsize)¶ In-place multi-limb swap function.
-
template<typename RANDOM_ACCESS_ITERATOR_INOUT>
static inline void multi_limb_reverse(RANDOM_ACCESS_ITERATOR_INOUT begin_it, RANDOM_ACCESS_ITERATOR_INOUT end_it, std::size_t itemsize)¶ In-place multi-limb reverse function.
-
template<typename INT_TYPE = std::size_t, bool allow_negative_dimensions = false>
static inline std::vector<INT_TYPE> cpp_shape_from_python_shape_like(const std::variant<nanobind::tuple, nanobind::int_> &shape)¶ Create a C++ shape vector (
std::vector<INT_TYPE>
) from a Python shape object (std::variant<nanobind::tuple, nanobind::int_>
).
-
static inline std::vector<std::size_t> cpp_axes_from_python(const std::optional<std::variant<nanobind::tuple, nanobind::int_>> &python_axes, std::size_t ndim)¶
Convert a Python tuple to a unique sorted list of dimensions (smaller than
ndim
)
-
template<typename APY_ARRAY>
static inline std::tuple<std::size_t, std::size_t, std::size_t> get_conv_lengths(const std::string &mode, const APY_ARRAY &a, const APY_ARRAY &b)¶ Get the convolutional properties
len
,n_left
, andn_right
(in that order) from a string of either “full”, “same”, or “valid”. Throws ananobind::value_error
if the string is anything else.
-
CREATE_FUNCTOR_FROM_FUNC(apy_add_n_functor, apy_addition_same_length)¶
-
CREATE_FUNCTOR_FROM_FUNC(apy_sub_n_functor, apy_subtraction_same_length)¶
-
class NotImplementedException : public std::domain_error¶
Public Functions
-
inline NotImplementedException(std::optional<std::string> msg = std::nullopt)¶
-
inline NotImplementedException(std::optional<std::string> msg = std::nullopt)¶
-
struct DoubleDabbleList¶
- #include <apytypes_util.h>
Double-Dabble helper class with proporate methods for performing the double-dabble and reverse double-dabble algorithm.
Public Functions
-
inline void do_double(apy_limb_t new_bit)¶
Do one iteration of double (double-dabble)
-
inline void do_dabble()¶
Do one iteration of dabble (double-dabble)
-
inline void do_reverse_double(apy_limb_t &limb_out)¶
Do one iteration of reverse double (reverse double-dabble)
-
inline void do_reverse_dabble()¶
Do one iteration of reverse dabble (reverse double-dabble)
Public Members
-
std::vector<apy_limb_t> data = {0}¶
Public Static Attributes
-
static constexpr apy_limb_t _NIBBLE_MASK = APY_LIMB_SIZE_BITS == 64 ? 0x1111111111111111 : 0x11111111¶
Mask with a bit in every position where a nibble starts.
-
inline void do_double(apy_limb_t new_bit)¶