Add ptrdiff_t type to Cython.
authorRobert Bradshaw <robertwb@gmail.com>
Tue, 21 May 2013 15:53:57 +0000 (08:53 -0700)
committerRobert Bradshaw <robertwb@gmail.com>
Tue, 21 May 2013 15:53:57 +0000 (08:53 -0700)
Cython/Compiler/ExprNodes.py
Cython/Compiler/Parsing.py
Cython/Compiler/PyrexTypes.py
Cython/Utility/TypeConversion.c
tests/errors/e_subop.pyx

index 0406fad..61e827b 100755 (executable)
@@ -8895,7 +8895,7 @@ class SubNode(NumBinopNode):
         if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
             return type1
         elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
-            return PyrexTypes.c_int_type
+            return PyrexTypes.c_ptrdiff_t_type
         else:
             return NumBinopNode.compute_c_result_type(
                 self, type1, type2)
index e8cbb40..b7e07ff 100644 (file)
@@ -2264,6 +2264,7 @@ special_basic_c_types = {
     "Py_ssize_t" : (2, 0),
     "ssize_t"    : (2, 0),
     "size_t"     : (0, 0),
+    "ptrdiff_t"  : (2, 0),
 }
 
 sign_and_longness_words = ("short", "long", "signed", "unsigned")
index 07122a7..3996c84 100755 (executable)
@@ -1758,6 +1758,14 @@ class CSizeTType(CIntType):
     def sign_and_name(self):
         return "size_t"
 
+class CPtrdiffTType(CIntType):
+
+    to_py_function = "__Pyx_PyInt_FromPtrdiff_t"
+    from_py_function = "__Pyx_PyInt_AsPtrdiff_t"
+
+    def sign_and_name(self):
+        return "ptrdiff_t"
+
 
 class CFloatType(CNumericType):
 
@@ -3448,6 +3456,7 @@ c_py_hash_t_type =   CPyHashTType(RANK_LONG+0.5, SIGNED)
 c_py_ssize_t_type =  CPySSizeTType(RANK_LONG+0.5, SIGNED)
 c_ssize_t_type =     CSSizeTType(RANK_LONG+0.5, SIGNED)
 c_size_t_type =      CSizeTType(RANK_LONG+0.5, UNSIGNED)
+c_ptrdiff_t_type =   CPtrdiffTType(RANK_LONG+0.25, SIGNED)
 
 c_null_ptr_type =     CNullPtrType(c_void_type)
 c_void_ptr_type =     CPtrType(c_void_type)
@@ -3541,6 +3550,7 @@ modifiers_and_name_to_type = {
     (2,  0, "Py_ssize_t"): c_py_ssize_t_type,
     (2,  0, "ssize_t") :   c_ssize_t_type,
     (0,  0, "size_t") :    c_size_t_type,
+    (2,  0, "ptrdiff_t") : c_ptrdiff_t_type,
 
     (1,  0, "object"): py_object_type,
 }
index 92b55ef..20acbb7 100644 (file)
@@ -47,6 +47,9 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
 static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
 static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
 
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromPtrdiff_t(ptrdiff_t);
+static CYTHON_INLINE ptrdiff_t __Pyx_PyInt_AsPtrdiff_t(PyObject*);
+
 #if CYTHON_COMPILING_IN_CPYTHON
 #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
 #else
@@ -288,6 +291,27 @@ static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
    }
    return (size_t)val;
 }
+    
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromPtrdiff_t(ptrdiff_t ival) {
+    if (LONG_MIN < ival && ival <= LONG_MAX)
+        return PyInt_FromLong((long)ival);
+    else {
+        unsigned char *bytes = (unsigned char *) &ival;
+        int one = 1; int little = (int)*(unsigned char*)&one;
+        return _PyLong_FromByteArray(bytes, sizeof(ptrdiff_t), little, 0);
+    }
+}
+
+static CYTHON_INLINE ptrdiff_t __Pyx_PyInt_AsPtrdiff_t(PyObject* x) {
+    unsigned PY_LONG_LONG val = __Pyx_PyInt_AsLongLong(x);
+    if (unlikely(val != (unsigned PY_LONG_LONG)(ptrdiff_t)val)) {
+        if ((val != (unsigned PY_LONG_LONG)-1) || !PyErr_Occurred())
+            PyErr_SetString(PyExc_OverflowError,
+                            "value too large to convert to size_t");
+        return (ptrdiff_t)-1;
+    }
+    return (ptrdiff_t)val;
+}
 
 /////////////// FromPyStructUtility.proto ///////////////
 {{struct_type_decl}};
index 6594d02..d0ffd0d 100644 (file)
@@ -7,5 +7,5 @@ def f():
        ptr1 = ptr2 - ptr3 # error
 _ERRORS = u"""
 6:13: Invalid operand types for '-' (int; char *)
-7:13: Cannot assign type 'int' to 'char *'
+7:13: Cannot assign type 'ptrdiff_t' to 'char *'
 """