cython
68 строк · 2.0 Кб
1cimport cqueue
2
3
4
5cdef class Queue:
6"""A queue class for C integer values.
7
8>>> q = Queue()
9>>> q.append(5)
10>>> q.peek()
115
12>>> q.pop()
135
14"""
15cdef cqueue.Queue* _c_queue
16def __cinit__(self):
17self._c_queue = cqueue.queue_new()
18if self._c_queue is NULL:
19raise MemoryError()
20
21def __dealloc__(self):
22if self._c_queue is not NULL:
23cqueue.queue_free(self._c_queue)
24
25
26cpdef append(self, int value):
27if not cqueue.queue_push_tail(self._c_queue,
28<void*> <Py_ssize_t> value):
29raise MemoryError()
30
31# The `cpdef` feature is obviously not available for the original "extend()"
32# method, as the method signature is incompatible with Python argument
33# types (Python does not have pointers). However, we can rename
34# the C-ish "extend()" method to e.g. "extend_ints()", and write
35# a new "extend()" method that provides a suitable Python interface by
36# accepting an arbitrary Python iterable.
37
38cpdef extend(self, values):
39for value in values:
40self.append(value)
41
42
43cdef extend_ints(self, int* values, size_t count):
44cdef int value
45for value in values[:count]: # Slicing pointer to limit the iteration boundaries.
46self.append(value)
47
48
49
50cpdef int peek(self) except? -1:
51cdef int value = <Py_ssize_t> cqueue.queue_peek_head(self._c_queue)
52
53if value == 0:
54# this may mean that the queue is empty,
55# or that it happens to contain a 0 value
56if cqueue.queue_is_empty(self._c_queue):
57raise IndexError("Queue is empty")
58return value
59
60
61
62cpdef int pop(self) except? -1:
63if cqueue.queue_is_empty(self._c_queue):
64raise IndexError("Queue is empty")
65return <Py_ssize_t> cqueue.queue_pop_head(self._c_queue)
66
67def __bool__(self):
68return not cqueue.queue_is_empty(self._c_queue)
69