1from libc.stdlib cimport malloc, free 2from cpython.object cimport Py_EQ, Py_NE 3 4def double_ptr_slice(x, L, int a, int b): 5 """ 6 >>> L = list(range(10)) 7 >>> double_ptr_slice(5, L, 0, 10) 8 >>> double_ptr_slice(6, L, 0, 10) 9 >>> double_ptr_slice(None, L, 0, 10) 10 >>> double_ptr_slice(0, L, 3, 7) 11 >>> double_ptr_slice(5, L, 3, 7) 12 >>> double_ptr_slice(9, L, 3, 7) 13 14 >>> double_ptr_slice(EqualsEvens(), L, 0, 10) 15 >>> double_ptr_slice(EqualsEvens(), L, 1, 10) 16 """ 17 cdef double *L_c = NULL 18 try: 19 L_c = <double*>malloc(len(L) * sizeof(double)) 20 for i, a in enumerate(L): 21 L_c[i] = L[i] 22 assert (x in L_c[:b]) == (x in L[:b]) 23 assert (x not in L_c[:b]) == (x not in L[:b]) 24 assert (x in L_c[a:b]) == (x in L[a:b]) 25 assert (x not in L_c[a:b]) == (x not in L[a:b]) 26 assert (x in L_c[a:b:2]) == (x in L[a:b:2]) 27 assert (x not in L_c[a:b:2]) == (x not in L[a:b:2]) 28 finally: 29 free(L_c) 30 31def void_ptr_slice(py_x, L, int a, int b): 32 """ 33 >>> L = list(range(10)) 34 >>> void_ptr_slice(5, L, 0, 10) 35 >>> void_ptr_slice(6, L, 0, 10) 36 >>> void_ptr_slice(None, L, 0, 10) 37 >>> void_ptr_slice(0, L, 3, 7) 38 >>> void_ptr_slice(5, L, 3, 7) 39 >>> void_ptr_slice(9, L, 3, 7) 40 """ 41 # I'm using the fact that small Python ints are cached. 42 cdef void **L_c = NULL 43 cdef void *x = <void*>py_x 44 try: 45 L_c = <void**>malloc(len(L) * sizeof(void*)) 46 for i, a in enumerate(L): 47 L_c[i] = <void*>L[i] 48 assert (x in L_c[:b]) == (py_x in L[:b]) 49 assert (x not in L_c[:b]) == (py_x not in L[:b]) 50 assert (x in L_c[a:b]) == (py_x in L[a:b]) 51 assert (x not in L_c[a:b]) == (py_x not in L[a:b]) 52 assert (x in L_c[a:b:2]) == (py_x in L[a:b:2]) 53 assert (x not in L_c[a:b:2]) == (py_x not in L[a:b:2]) 54 finally: 55 free(L_c) 56 57cdef class EqualsEvens: 58 """ 59 >>> e = EqualsEvens() 60 >>> e == 2 61 True 62 >>> e == 5 63 False 64 >>> [e == k for k in range(4)] 65 [True, False, True, False] 66 """ 67 def __richcmp__(self, other, int op): 68 if op == Py_EQ: 69 return other % 2 == 0 70 elif op == Py_NE: 71 return other % 2 == 1 72 else: 73 return False 74