summaryrefslogtreecommitdiffstats
path: root/Include/internal/pycore_long.h
diff options
context:
space:
mode:
Diffstat (limited to 'Include/internal/pycore_long.h')
-rw-r--r--Include/internal/pycore_long.h19
1 files changed, 19 insertions, 0 deletions
diff --git a/Include/internal/pycore_long.h b/Include/internal/pycore_long.h
index 30c97b7..8c1d017 100644
--- a/Include/internal/pycore_long.h
+++ b/Include/internal/pycore_long.h
@@ -110,6 +110,25 @@ PyAPI_FUNC(char*) _PyLong_FormatBytesWriter(
int base,
int alternate);
+/* Return 1 if the argument is positive single digit int */
+static inline int
+_PyLong_IsPositiveSingleDigit(PyObject* sub) {
+ /* For a positive single digit int, the value of Py_SIZE(sub) is 0 or 1.
+
+ We perform a fast check using a single comparison by casting from int
+ to uint which casts negative numbers to large positive numbers.
+ For details see Section 14.2 "Bounds Checking" in the Agner Fog
+ optimization manual found at:
+ https://www.agner.org/optimize/optimizing_cpp.pdf
+
+ The function is not affected by -fwrapv, -fno-wrapv and -ftrapv
+ compiler options of GCC and clang
+ */
+ assert(PyLong_CheckExact(sub));
+ Py_ssize_t signed_size = Py_SIZE(sub);
+ return ((size_t)signed_size) <= 1;
+}
+
#ifdef __cplusplus
}
#endif