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