summaryrefslogtreecommitdiffstats
path: root/Include/internal/pycore_long.h
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2023-05-21 13:45:48 (GMT)
committerGitHub <noreply@github.com>2023-05-21 13:45:48 (GMT)
commit93923793f602ea9117f13bfac8cbe01a864eeb01 (patch)
tree33657460417c68e16479212566385144a0d9d30a /Include/internal/pycore_long.h
parentab71acd67b5b09926498b8c7f855bdb28ac0ec2f (diff)
downloadcpython-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.h35
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)
{