diff options
author | Mark Shannon <mark@hotpy.org> | 2023-05-21 13:45:48 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-21 13:45:48 (GMT) |
commit | 93923793f602ea9117f13bfac8cbe01a864eeb01 (patch) | |
tree | 33657460417c68e16479212566385144a0d9d30a /Include/internal/pycore_long.h | |
parent | ab71acd67b5b09926498b8c7f855bdb28ac0ec2f (diff) | |
download | cpython-93923793f602ea9117f13bfac8cbe01a864eeb01.zip cpython-93923793f602ea9117f13bfac8cbe01a864eeb01.tar.gz cpython-93923793f602ea9117f13bfac8cbe01a864eeb01.tar.bz2 |
GH-101291: Add low level, unstable API for pylong (GH-101685)
Co-authored-by: Petr Viktorin <encukou@gmail.com>
Diffstat (limited to 'Include/internal/pycore_long.h')
-rw-r--r-- | Include/internal/pycore_long.h | 35 |
1 files changed, 15 insertions, 20 deletions
diff --git a/Include/internal/pycore_long.h b/Include/internal/pycore_long.h index fe86581..64c00cb 100644 --- a/Include/internal/pycore_long.h +++ b/Include/internal/pycore_long.h @@ -118,6 +118,21 @@ PyAPI_FUNC(char*) _PyLong_FormatBytesWriter( #define SIGN_NEGATIVE 2 #define NON_SIZE_BITS 3 +/* The functions _PyLong_IsCompact and _PyLong_CompactValue are defined + * in Include/cpython/longobject.h, since they need to be inline. + * + * "Compact" values have at least one bit to spare, + * so that addition and subtraction can be performed on the values + * without risk of overflow. + * + * The inline functions need tag bits. + * For readability, rather than do `#define SIGN_MASK _PyLong_SIGN_MASK` + * we define them to the numbers in both places and then assert that + * they're the same. + */ +static_assert(SIGN_MASK == _PyLong_SIGN_MASK, "SIGN_MASK does not match _PyLong_SIGN_MASK"); +static_assert(NON_SIZE_BITS == _PyLong_NON_SIZE_BITS, "NON_SIZE_BITS does not match _PyLong_NON_SIZE_BITS"); + /* All *compact" values are guaranteed to fit into * a Py_ssize_t with at least one bit to spare. * In other words, for 64 bit machines, compact @@ -131,11 +146,6 @@ _PyLong_IsNonNegativeCompact(const PyLongObject* op) { return op->long_value.lv_tag <= (1 << NON_SIZE_BITS); } -static inline int -_PyLong_IsCompact(const PyLongObject* op) { - assert(PyLong_Check(op)); - return op->long_value.lv_tag < (2 << NON_SIZE_BITS); -} static inline int _PyLong_BothAreCompact(const PyLongObject* a, const PyLongObject* b) { @@ -144,21 +154,6 @@ _PyLong_BothAreCompact(const PyLongObject* a, const PyLongObject* b) { return (a->long_value.lv_tag | b->long_value.lv_tag) < (2 << NON_SIZE_BITS); } -/* Returns a *compact* value, iff `_PyLong_IsCompact` is true for `op`. - * - * "Compact" values have at least one bit to spare, - * so that addition and subtraction can be performed on the values - * without risk of overflow. - */ -static inline Py_ssize_t -_PyLong_CompactValue(const PyLongObject *op) -{ - assert(PyLong_Check(op)); - assert(_PyLong_IsCompact(op)); - Py_ssize_t sign = 1 - (op->long_value.lv_tag & SIGN_MASK); - return sign * (Py_ssize_t)op->long_value.ob_digit[0]; -} - static inline bool _PyLong_IsZero(const PyLongObject *op) { |