python_util.h

Defines

PyLong_SetSignAndDigitCount(obj, is_neg, size)
GET_OB_DIGIT(obj)
PyLong_IsNegative(obj)
PyLong_DigitCount(obj)
WHOLE_BYTES
REMAINING_BITS
REMAINING_BITS_MASK

Functions

static inline PyLongObject *PyLong_New(std::size_t python_digits)

Creation of a new PyLongObject that can be returned to Python

static inline bool python_long_is_negative(const nanobind::int_ &py_long_int)

Test if Python long integer (nb::int_) is negative

static std::vector<apy_limb_t> limb_vec_from_py_long_vec(const std::size_t count, const PyLongObject *py_long)

Convert Python limbs (of length PYLONG_BITS_IN_DIGIT) to apy_type_t limbs (of length APY_LIMB_SIZE_BITS).

static inline std::vector<apy_limb_t> python_long_to_limb_vec(const nanobind::int_ &py_long_int, std::optional<std::size_t> n_min_limbs = std::nullopt)

Python arbitrary long integer object to apy_limb_t vector. If n_min_limbs is set, at least that many limbs will be available in the result.

template<class RANDOM_ACCESS_ITERATOR>
static inline nanobind::int_ python_limb_vec_to_long(RANDOM_ACCESS_ITERATOR begin, RANDOM_ACCESS_ITERATOR end, bool vec_is_signed = false, std::optional<unsigned> bits_last_limb = std::nullopt)

Convert a limb vector (std::vector<apy_limb_t>) to a Python long integer object wrapped in a nanobind::int_.

static inline std::vector<std::size_t> python_sequence_extract_shape(const nanobind::sequence &bit_pattern_sequence)

Retrieve the shape of a, possibly nested, Python sequence of iterable object.

template<typename ...PyTypes>
static std::vector<nanobind::object> python_sequence_walk(const nanobind::sequence &py_seq)

Walk a, possibly nested, Python sequence of iterable objects and convert every Python object (of type <T>, via nb::cast<T>()) and return them in a std::vector<T>. The sequence is walked in a depth-first search manner. If any object in the sequence bit_pattern_sequence does not match <T> or another Python sequence a std::domain_error exception to be raised.