pythonstl 0.1.4__cp311-cp311-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,228 @@
1
+ """
2
+ Priority Queue facade class.
3
+
4
+ This module provides the public-facing priority_queue class that users interact with.
5
+ """
6
+
7
+ from typing import TypeVar
8
+ from copy import deepcopy
9
+ from pythonstl.core.exceptions import EmptyContainerError
10
+ from pythonstl.implementations.heaps._priority_queue_impl import _PriorityQueueImpl
11
+
12
+ try:
13
+ from pythonstl._rust import RustPriorityQueue
14
+ RUST_AVAILABLE = True
15
+ except ImportError:
16
+ RUST_AVAILABLE = False
17
+
18
+ T = TypeVar('T')
19
+
20
+
21
+ class priority_queue:
22
+ """
23
+ A priority queue data structure following C++ STL semantics.
24
+
25
+ This is a container adapter that provides constant time lookup of the
26
+ largest (by default) or smallest element, at the expense of logarithmic
27
+ insertion and extraction.
28
+
29
+ Example:
30
+ >>> from pythonstl import priority_queue
31
+ >>> pq = priority_queue() # max-heap by default
32
+ >>> pq.push(10)
33
+ >>> pq.push(30)
34
+ >>> pq.push(20)
35
+ >>> pq.top()
36
+ 30
37
+ >>> len(pq)
38
+ 3
39
+ >>>
40
+ >>> pq_min = priority_queue(comparator="min") # min-heap
41
+ >>> pq_min.push(10)
42
+ >>> pq_min.push(30)
43
+ >>> pq_min.push(20)
44
+ >>> pq_min.top()
45
+ 10
46
+ """
47
+
48
+ def __init__(self, comparator: str = "max", use_rust: bool = True) -> None:
49
+ """
50
+ Initialize an empty priority queue.
51
+
52
+ Args:
53
+ comparator: Either "max" for max-heap (default, matches C++ STL)
54
+ or "min" for min-heap.
55
+
56
+ Time Complexity:
57
+ O(1)
58
+ """
59
+ if use_rust and RUST_AVAILABLE:
60
+ self._impl = RustPriorityQueue(comparator)
61
+ self._is_rust = True
62
+ else:
63
+ self._impl = _PriorityQueueImpl(comparator)
64
+ self._is_rust = False
65
+ self._comparator = comparator
66
+
67
+ def push(self, value: T) -> None:
68
+ """
69
+ Insert an element into the priority queue.
70
+
71
+ Args:
72
+ value: The element to insert.
73
+
74
+ Time Complexity:
75
+ O(log n) where n is the number of elements
76
+ """
77
+ self._impl.push(value)
78
+
79
+ def pop(self) -> None:
80
+ """
81
+ Remove the top element from the priority queue.
82
+
83
+ Raises:
84
+ EmptyContainerError: If the priority queue is empty.
85
+
86
+ Time Complexity:
87
+ O(log n) where n is the number of elements
88
+ """
89
+ if self.empty():
90
+ raise EmptyContainerError("priority_queue")
91
+ self._impl.pop()
92
+
93
+ def top(self) -> T:
94
+ """
95
+ Get the top element of the priority queue without removing it.
96
+
97
+ Returns:
98
+ The top element (highest priority for max-heap, lowest for min-heap).
99
+
100
+ Raises:
101
+ EmptyContainerError: If the priority queue is empty.
102
+
103
+ Time Complexity:
104
+ O(1)
105
+ """
106
+ if self.empty():
107
+ raise EmptyContainerError("priority_queue")
108
+ return self._impl.top()
109
+
110
+ def empty(self) -> bool:
111
+ """
112
+ Check if the priority queue is empty.
113
+
114
+ Returns:
115
+ True if the priority queue is empty, False otherwise.
116
+
117
+ Time Complexity:
118
+ O(1)
119
+ """
120
+ return self._impl.empty()
121
+
122
+ def size(self) -> int:
123
+ """
124
+ Get the number of elements in the priority queue.
125
+
126
+ Returns:
127
+ The number of elements in the priority queue.
128
+
129
+ Time Complexity:
130
+ O(1)
131
+ """
132
+ return self._impl.size()
133
+
134
+ def copy(self) -> 'priority_queue':
135
+ """
136
+ Create a deep copy of the priority queue.
137
+
138
+ Returns:
139
+ A new priority queue with copied elements.
140
+
141
+ Time Complexity:
142
+ O(n) where n is the number of elements
143
+ """
144
+ new_pq = priority_queue(self._comparator, use_rust=self._is_rust)
145
+ if self._is_rust:
146
+ new_pq._impl.set_data(self._impl.get_data())
147
+ else:
148
+ new_pq._impl._data = self._impl._data.copy()
149
+ return new_pq
150
+
151
+ # Python magic methods
152
+
153
+ def __len__(self) -> int:
154
+ """
155
+ Get the number of elements (Python len() support).
156
+
157
+ Returns:
158
+ The number of elements in the priority queue.
159
+ """
160
+ return self.size()
161
+
162
+ def __bool__(self) -> bool:
163
+ """
164
+ Check if priority queue is non-empty (Python bool() support).
165
+
166
+ Returns:
167
+ True if priority queue is non-empty, False otherwise.
168
+ """
169
+ return not self.empty()
170
+
171
+ def __repr__(self) -> str:
172
+ """
173
+ Get string representation of the priority queue.
174
+
175
+ Returns:
176
+ String representation showing heap type and size.
177
+ """
178
+ return f"priority_queue(comparator='{self._comparator}', size={self.size()})"
179
+
180
+ def __eq__(self, other: object) -> bool:
181
+ """
182
+ Check equality with another priority queue.
183
+
184
+ Args:
185
+ other: Another priority queue to compare with.
186
+
187
+ Returns:
188
+ True if priority queues are equal, False otherwise.
189
+ """
190
+ if not isinstance(other, priority_queue):
191
+ return False
192
+ if self._comparator != other._comparator:
193
+ return False
194
+
195
+ self_data = self._impl.get_data() if self._is_rust else self._impl._data
196
+ other_data = other._impl.get_data() if other._is_rust else other._impl._data
197
+ return self_data == other_data
198
+
199
+ def __copy__(self) -> 'priority_queue':
200
+ """
201
+ Support for copy.copy().
202
+
203
+ Returns:
204
+ A shallow copy of the priority queue.
205
+ """
206
+ return self.copy()
207
+
208
+ def __deepcopy__(self, memo) -> 'priority_queue':
209
+ """
210
+ Support for copy.deepcopy().
211
+
212
+ Args:
213
+ memo: Memoization dictionary for deepcopy.
214
+
215
+ Returns:
216
+ A deep copy of the priority queue.
217
+ """
218
+ new_pq = priority_queue(self._comparator, use_rust=self._is_rust)
219
+ if self._is_rust:
220
+ new_data = deepcopy(self._impl.get_data(), memo)
221
+ new_pq._impl.set_data(new_data)
222
+ else:
223
+ new_pq._impl._data = deepcopy(self._impl._data, memo)
224
+ return new_pq
225
+
226
+
227
+
228
+ __all__ = ['priority_queue']
@@ -0,0 +1,234 @@
1
+ """
2
+ Queue facade class.
3
+
4
+ This module provides the public-facing queue class that users interact with.
5
+ """
6
+
7
+ from typing import TypeVar
8
+ from copy import deepcopy
9
+ from pythonstl.core.exceptions import EmptyContainerError
10
+ from pythonstl.implementations.linear._queue_impl import _QueueImpl
11
+
12
+ try:
13
+ from pythonstl._rust import RustQueue
14
+ RUST_AVAILABLE = True
15
+ except ImportError:
16
+ RUST_AVAILABLE = False
17
+
18
+ T = TypeVar('T')
19
+
20
+
21
+ class queue:
22
+ """
23
+ A queue data structure following C++ STL semantics.
24
+
25
+ This is a FIFO (First-In-First-Out) container adapter.
26
+
27
+ Example:
28
+ >>> from pythonstl import queue
29
+ >>> q = queue()
30
+ >>> q.push(10)
31
+ >>> q.push(20)
32
+ >>> q.front()
33
+ 10
34
+ >>> len(q)
35
+ 2
36
+ >>> bool(q)
37
+ True
38
+ """
39
+
40
+ def __init__(self, use_rust: bool = True) -> None:
41
+ """
42
+ Initialize an empty queue.
43
+
44
+ Time Complexity:
45
+ O(1)
46
+ """
47
+ if use_rust and RUST_AVAILABLE:
48
+ self._impl = RustQueue()
49
+ self._is_rust = True
50
+ else:
51
+ self._impl = _QueueImpl()
52
+ self._is_rust = False
53
+
54
+ def push(self, value: T) -> None:
55
+ """
56
+ Add an element to the back of the queue.
57
+
58
+ Args:
59
+ value: The element to add to the queue.
60
+
61
+ Time Complexity:
62
+ O(1)
63
+ """
64
+ self._impl.push(value)
65
+
66
+ def pop(self) -> None:
67
+ """
68
+ Remove the front element from the queue.
69
+
70
+ Raises:
71
+ EmptyContainerError: If the queue is empty.
72
+
73
+ Time Complexity:
74
+ O(1)
75
+ """
76
+ if self.empty():
77
+ raise EmptyContainerError("queue")
78
+ self._impl.pop()
79
+
80
+ def front(self) -> T:
81
+ """
82
+ Get the front element of the queue without removing it.
83
+
84
+ Returns:
85
+ The front element of the queue.
86
+
87
+ Raises:
88
+ EmptyContainerError: If the queue is empty.
89
+
90
+ Time Complexity:
91
+ O(1)
92
+ """
93
+ if self.empty():
94
+ raise EmptyContainerError("queue")
95
+ return self._impl.front()
96
+
97
+ def back(self) -> T:
98
+ """
99
+ Get the back element of the queue without removing it.
100
+
101
+ Returns:
102
+ The back element of the queue.
103
+
104
+ Raises:
105
+ EmptyContainerError: If the queue is empty.
106
+
107
+ Time Complexity:
108
+ O(1)
109
+ """
110
+ if self.empty():
111
+ raise EmptyContainerError("queue")
112
+ return self._impl.back()
113
+
114
+ def empty(self) -> bool:
115
+ """
116
+ Check if the queue is empty.
117
+
118
+ Returns:
119
+ True if the queue is empty, False otherwise.
120
+
121
+ Time Complexity:
122
+ O(1)
123
+ """
124
+ return self._impl.empty()
125
+
126
+ def size(self) -> int:
127
+ """
128
+ Get the number of elements in the queue.
129
+
130
+ Returns:
131
+ The number of elements in the queue.
132
+
133
+ Time Complexity:
134
+ O(1)
135
+ """
136
+ return self._impl.size()
137
+
138
+ def copy(self) -> 'queue':
139
+ """
140
+ Create a deep copy of the queue.
141
+
142
+ Returns:
143
+ A new queue with copied elements.
144
+
145
+ Time Complexity:
146
+ O(n) where n is the number of elements
147
+ """
148
+ new_queue = queue(use_rust=self._is_rust)
149
+ if self._is_rust:
150
+ new_queue._impl.set_data(self._impl.get_data())
151
+ else:
152
+ new_queue._impl._data = self._impl._data.copy()
153
+ return new_queue
154
+
155
+ # Python magic methods
156
+
157
+ def __len__(self) -> int:
158
+ """
159
+ Get the number of elements (Python len() support).
160
+
161
+ Returns:
162
+ The number of elements in the queue.
163
+ """
164
+ return self.size()
165
+
166
+ def __bool__(self) -> bool:
167
+ """
168
+ Check if queue is non-empty (Python bool() support).
169
+
170
+ Returns:
171
+ True if queue is non-empty, False otherwise.
172
+ """
173
+ return not self.empty()
174
+
175
+ def __repr__(self) -> str:
176
+ """
177
+ Get string representation of the queue.
178
+
179
+ Returns:
180
+ String representation showing queue contents.
181
+ """
182
+ if self._is_rust:
183
+ elements = [str(elem) for elem in self._impl.get_data()]
184
+ else:
185
+ elements = [str(elem) for elem in self._impl._data]
186
+ return f"queue([{', '.join(elements)}])"
187
+
188
+ def __eq__(self, other: object) -> bool:
189
+ """
190
+ Check equality with another queue.
191
+
192
+ Args:
193
+ other: Another queue to compare with.
194
+
195
+ Returns:
196
+ True if queues are equal, False otherwise.
197
+ """
198
+ if not isinstance(other, queue):
199
+ return False
200
+
201
+ self_data = self._impl.get_data() if self._is_rust else self._impl._data
202
+ other_data = other._impl.get_data() if other._is_rust else other._impl._data
203
+ return self_data == other_data
204
+
205
+ def __copy__(self) -> 'queue':
206
+ """
207
+ Support for copy.copy().
208
+
209
+ Returns:
210
+ A shallow copy of the queue.
211
+ """
212
+ return self.copy()
213
+
214
+ def __deepcopy__(self, memo) -> 'queue':
215
+ """
216
+ Support for copy.deepcopy().
217
+
218
+ Args:
219
+ memo: Memoization dictionary for deepcopy.
220
+
221
+ Returns:
222
+ A deep copy of the queue.
223
+ """
224
+ new_queue = queue(use_rust=self._is_rust)
225
+ if self._is_rust:
226
+ new_data = deepcopy(self._impl.get_data(), memo)
227
+ new_queue._impl.set_data(new_data)
228
+ else:
229
+ new_queue._impl._data = deepcopy(self._impl._data, memo)
230
+ return new_queue
231
+
232
+
233
+
234
+ __all__ = ['queue']