diff -r 84cef4f1999a Doc/c-api/long.rst --- a/Doc/c-api/long.rst Mon Apr 29 16:09:39 2013 -0400 +++ b/Doc/c-api/long.rst Wed May 01 00:00:40 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,15 @@ 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`. + + .. c:function:: unsigned long PyLong_AsUnsignedLong(PyObject *pylong) .. index:: @@ -245,6 +270,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 84cef4f1999a Include/longobject.h --- a/Include/longobject.h Mon Apr 29 16:09:39 2013 -0400 +++ b/Include/longobject.h Wed May 01 00:00:40 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 84cef4f1999a Objects/longobject.c --- a/Objects/longobject.c Mon Apr 29 16:09:39 2013 -0400 +++ b/Objects/longobject.c Wed May 01 00:00:40 2013 +0200 @@ -1083,6 +1083,155 @@ 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)) { + PyNumberMethods *nb; + PyObject *io; + if ((nb = vv->ob_type->tp_as_number) == NULL || + nb->nb_int == NULL) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return -1; + } + io = (*nb->nb_int) (vv); + if (io == NULL) + return -1; + if (PyLong_Check(io)) { + bytes = PyLong_AsLongLong(io); + Py_DECREF(io); + return bytes; + } + Py_DECREF(io); + PyErr_SetString(PyExc_TypeError, "integer conversion failed"); + 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)res; + else + return bytes; +} + + /* Create a new long int object from a C Py_ssize_t. */ PyObject * diff -r 84cef4f1999a configure.ac --- a/configure.ac Mon Apr 29 16:09:39 2013 -0400 +++ b/configure.ac Wed May 01 00:00:40 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