diff -r ebc296bf23d1 Doc/c-api/long.rst --- a/Doc/c-api/long.rst Thu May 09 15:34:09 2013 +0300 +++ b/Doc/c-api/long.rst Sun May 12 23:39:58 2013 +0200 @@ -74,6 +74,22 @@ All integers are implemented as "long" i or *NULL* on failure. +.. c:function:: PyObject* PyLong_FromIntMax_t(intmax_t v) + + Return a new :c:type:`PyLongObject` object from a C :c:type:`intmax_t`, + or *NULL* on failure. + + .. versionadded:: 3.4 + + +.. c:function:: PyObject* PyLong_FromUintMax_t(uintmax_t v) + + Return a new :c:type:`PyLongObject` object from a C :c:type:`uintmax_t`, + or *NULL* on failure. + + .. versionadded:: 3.4 + + .. c:function:: PyObject* PyLong_FromDouble(double v) Return a new :c:type:`PyLongObject` object from the integer part of *v*, or @@ -188,6 +204,17 @@ All integers are implemented as "long" i :c:type:`Py_ssize_t`. +.. c:function:: intmax_t PyLong_AsIntMax_t(PyObject *pylong) + + Return a C :c:type:`intmax_t` representation of *pylong*. *pylong* must + be an instance of :c:type:`PyLongObject`. + + Raise :exc:`OverflowError` if the value of *pylong* is out of range for a + :c:type:`intmax_t`. + + .. versionadded:: 3.4 + + .. c:function:: unsigned long PyLong_AsUnsignedLong(PyObject *pylong) .. index:: @@ -245,6 +272,17 @@ All integers are implemented as "long" i return the reduction of that value modulo :const:`PY_ULLONG_MAX + 1`. +.. c:function:: uintmax_t PyLong_AsUintMax_t(PyObject *pylong) + + Return a C :c:type:`uintmax_t` representation of *pylong*. + *pylong* must be an instance of :c:type:`PyLongObject`. + + Raise :exc:`OverflowError` if the value of *pylong* is out of range + for an :c:type:`uintmax_t`. + + .. versionadded:: 3.4 + + .. c:function:: double PyLong_AsDouble(PyObject *pylong) Return a C :c:type:`double` representation of *pylong*. *pylong* must be diff -r ebc296bf23d1 Include/longobject.h --- a/Include/longobject.h Thu May 09 15:34:09 2013 +0300 +++ b/Include/longobject.h Sun May 12 23:39:58 2013 +0200 @@ -71,6 +71,11 @@ PyAPI_FUNC(double) PyLong_AsDouble(PyObj PyAPI_FUNC(PyObject *) PyLong_FromVoidPtr(void *); PyAPI_FUNC(void *) PyLong_AsVoidPtr(PyObject *); +PyAPI_FUNC(PyObject *) PyLong_FromIntMax_t(intmax_t); +PyAPI_FUNC(PyObject *) PyLong_FromUintMax_t(uintmax_t); +PyAPI_FUNC(intmax_t) PyLong_AsIntMax_t(PyObject *); +PyAPI_FUNC(uintmax_t) PyLong_AsUintMax_t(PyObject *); + #ifdef HAVE_LONG_LONG PyAPI_FUNC(PyObject *) PyLong_FromLongLong(PY_LONG_LONG); PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG); diff -r ebc296bf23d1 Modules/_testcapimodule.c --- a/Modules/_testcapimodule.c Thu May 09 15:34:09 2013 +0300 +++ b/Modules/_testcapimodule.c Sun May 12 23:39:58 2013 +0200 @@ -57,6 +57,8 @@ test_config(PyObject *self) #ifdef HAVE_LONG_LONG CHECK_SIZEOF(SIZEOF_LONG_LONG, PY_LONG_LONG); #endif + CHECK_SIZEOF(SIZEOF_INTMAX_T, intmax_t); + CHECK_SIZEOF(SIZEOF_UINTMAX_T, uintmax_t); #undef CHECK_SIZEOF diff -r ebc296bf23d1 Objects/longobject.c --- a/Objects/longobject.c Thu May 09 15:34:09 2013 +0300 +++ b/Objects/longobject.c Sun May 12 23:39:58 2013 +0200 @@ -1083,6 +1083,140 @@ PyLong_FromUnsignedLongLong(unsigned PY_ return (PyObject *)v; } +PyObject * +PyLong_FromIntMax_t(intmax_t ival) +{ + PyLongObject *v; + uintmax_t abs_ival; + uintmax_t t; /* unsigned so >> doesn't propagate sign bit */ + int ndigits = 0; + int negative = 0; + + CHECK_SMALL_INT(ival); + if (ival < 0) { + /* avoid signed overflow on negation; see comments + in PyLong_FromLong above. */ + abs_ival = (uintmax_t)(-1-ival) + 1; + negative = 1; + } + else { + abs_ival = (uintmax_t)ival; + } + + /* Count the number of Python digits. + We used to pick 5 ("big enough for anything"), but that's a + waste of time and space given that 5*15 = 75 bits are rarely + needed. */ + t = abs_ival; + while (t) { + ++ndigits; + t >>= PyLong_SHIFT; + } + v = _PyLong_New(ndigits); + if (v != NULL) { + digit *p = v->ob_digit; + Py_SIZE(v) = negative ? -ndigits : ndigits; + t = abs_ival; + while (t) { + *p++ = (digit)(t & PyLong_MASK); + t >>= PyLong_SHIFT; + } + } + return (PyObject *)v; +} + + +PyObject * +PyLong_FromUintMax_t(uintmax_t ival) +{ + PyLongObject *v; + uintmax_t t; + int ndigits = 0; + + if (ival < PyLong_BASE) + return PyLong_FromLong((long)ival); + /* Count the number of Python digits. */ + t = ival; + while (t) { + ++ndigits; + t >>= PyLong_SHIFT; + } + + v = _PyLong_New(ndigits); + if (v != NULL) { + digit *p = v->ob_digit; + Py_SIZE(v) = ndigits; + while (ival) { + *p++ = (digit)(ival & PyLong_MASK); + ival >>= PyLong_SHIFT; + } + } + return (PyObject *)v; +} + +intmax_t +PyLong_AsIntMax_t(PyObject *vv) +{ + PyLongObject *v; + intmax_t bytes; + int res; + + if (vv == NULL) { + PyErr_BadInternalCall(); + return -1; + } + if (!PyLong_Check(vv)) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return -1; + } + + v = (PyLongObject*)vv; + switch(Py_SIZE(v)) { + case -1: return -(sdigit)v->ob_digit[0]; + case 0: return 0; + case 1: return v->ob_digit[0]; + } + res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes, + SIZEOF_UINTMAX_T, PY_LITTLE_ENDIAN, 1); + + if (res < 0) + return (intmax_t)-1; + else + return bytes; +} + +uintmax_t +PyLong_AsUintMax_t(PyObject *vv) +{ + PyLongObject *v; + uintmax_t bytes; + int res; + + if (vv == NULL) { + PyErr_BadInternalCall(); + return (uintmax_t)-1; + } + if (!PyLong_Check(vv)) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return (uintmax_t)-1; + } + + v = (PyLongObject*)vv; + switch(Py_SIZE(v)) { + case 0: return 0; + case 1: return v->ob_digit[0]; + } + + res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes, + SIZEOF_UINTMAX_T, PY_LITTLE_ENDIAN, 0); + + if (res < 0) + return (uintmax_t)-1; + else + return bytes; +} + + /* Create a new long int object from a C Py_ssize_t. */ PyObject * diff -r ebc296bf23d1 PC/pyconfig.h --- a/PC/pyconfig.h Thu May 09 15:34:09 2013 +0300 +++ b/PC/pyconfig.h Sun May 12 23:39:58 2013 +0200 @@ -202,6 +202,14 @@ typedef _W64 int ssize_t; #endif #endif /* MS_WIN32 && !MS_WIN64 */ +/* Visual Studio 2008 and older doesn't provide stdint.h + * (don't support ISO C99) */ +typedef __int64 intmax_t; +typedef unsigned __int64 uintmax_t; + +#define SIZEOF_INTMAX_T 8 +#define SIZEOF_UINTMAX_T 8 + typedef int pid_t; #include diff -r ebc296bf23d1 configure.ac --- a/configure.ac Thu May 09 15:34:09 2013 +0300 +++ b/configure.ac Sun May 12 23:39:58 2013 +0200 @@ -1641,6 +1641,8 @@ cat >> confdefs.h <<\EOF EOF # Type availability checks +AC_TYPE_INTMAX_T +AC_TYPE_UINTMAX_T AC_TYPE_MODE_T AC_TYPE_OFF_T AC_TYPE_PID_T @@ -1687,6 +1689,8 @@ AC_CHECK_SIZEOF(double, 8) AC_CHECK_SIZEOF(fpos_t, 4) AC_CHECK_SIZEOF(size_t, 4) AC_CHECK_SIZEOF(pid_t, 4) +AC_CHECK_SIZEOF(intmax_t) +AC_CHECK_SIZEOF(uintmax_t) AC_MSG_CHECKING(for long long support) have_long_long=no