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.
- pythonstl/__init__.py +64 -0
- pythonstl/_rust.cp311-win_amd64.pyd +0 -0
- pythonstl/core/__init__.py +32 -0
- pythonstl/core/base.py +51 -0
- pythonstl/core/exceptions.py +57 -0
- pythonstl/core/iterator.py +187 -0
- pythonstl/facade/__init__.py +10 -0
- pythonstl/facade/algorithms.py +331 -0
- pythonstl/facade/map.py +298 -0
- pythonstl/facade/priority_queue.py +228 -0
- pythonstl/facade/queue.py +234 -0
- pythonstl/facade/set.py +271 -0
- pythonstl/facade/stack.py +217 -0
- pythonstl/facade/vector.py +406 -0
- pythonstl/implementations/__init__.py +3 -0
- pythonstl/implementations/associative/__init__.py +6 -0
- pythonstl/implementations/associative/_map_impl.py +164 -0
- pythonstl/implementations/associative/_set_impl.py +138 -0
- pythonstl/implementations/heaps/__init__.py +5 -0
- pythonstl/implementations/heaps/_priority_queue_impl.py +118 -0
- pythonstl/implementations/linear/__init__.py +7 -0
- pythonstl/implementations/linear/_queue_impl.py +117 -0
- pythonstl/implementations/linear/_stack_impl.py +99 -0
- pythonstl/implementations/linear/_vector_impl.py +251 -0
- pythonstl-0.1.4.dist-info/METADATA +449 -0
- pythonstl-0.1.4.dist-info/RECORD +29 -0
- pythonstl-0.1.4.dist-info/WHEEL +4 -0
- pythonstl-0.1.4.dist-info/licenses/LICENSE +21 -0
- pythonstl-0.1.4.dist-info/sboms/pythonstl.cyclonedx.json +1051 -0
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Vector facade class.
|
|
3
|
+
|
|
4
|
+
This module provides the public-facing vector class that users interact with.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import TypeVar, Iterator as TypingIterator
|
|
8
|
+
from copy import deepcopy
|
|
9
|
+
from pythonstl.core.exceptions import EmptyContainerError, OutOfRangeError
|
|
10
|
+
from pythonstl.implementations.linear._vector_impl import _VectorImpl
|
|
11
|
+
from pythonstl.core.iterator import VectorIterator, VectorReverseIterator
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
from pythonstl._rust import RustVector
|
|
15
|
+
RUST_AVAILABLE = True
|
|
16
|
+
except ImportError:
|
|
17
|
+
RUST_AVAILABLE = False
|
|
18
|
+
|
|
19
|
+
T = TypeVar('T')
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class vector:
|
|
23
|
+
"""
|
|
24
|
+
A dynamic array (vector) data structure following C++ STL semantics.
|
|
25
|
+
|
|
26
|
+
This is a sequence container with dynamic size.
|
|
27
|
+
|
|
28
|
+
Example:
|
|
29
|
+
>>> from pythonstl import vector
|
|
30
|
+
>>> v = vector()
|
|
31
|
+
>>> v.push_back(10)
|
|
32
|
+
>>> v.push_back(20)
|
|
33
|
+
>>> v.at(0)
|
|
34
|
+
10
|
|
35
|
+
>>> len(v)
|
|
36
|
+
2
|
|
37
|
+
>>> 10 in v
|
|
38
|
+
True
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __init__(self, use_rust: bool = True) -> None:
|
|
42
|
+
"""
|
|
43
|
+
Initialize an empty vector.
|
|
44
|
+
|
|
45
|
+
Time Complexity:
|
|
46
|
+
O(1)
|
|
47
|
+
"""
|
|
48
|
+
if use_rust and RUST_AVAILABLE:
|
|
49
|
+
self._impl = RustVector()
|
|
50
|
+
self._is_rust = True
|
|
51
|
+
else:
|
|
52
|
+
self._impl = _VectorImpl()
|
|
53
|
+
self._is_rust = False
|
|
54
|
+
|
|
55
|
+
def push_back(self, value: T) -> None:
|
|
56
|
+
"""
|
|
57
|
+
Add an element to the end of the vector.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
value: The element to add to the vector.
|
|
61
|
+
|
|
62
|
+
Time Complexity:
|
|
63
|
+
O(1) amortized
|
|
64
|
+
"""
|
|
65
|
+
self._impl.push_back(value)
|
|
66
|
+
|
|
67
|
+
def pop_back(self) -> None:
|
|
68
|
+
"""
|
|
69
|
+
Remove the last element from the vector.
|
|
70
|
+
|
|
71
|
+
Raises:
|
|
72
|
+
EmptyContainerError: If the vector is empty.
|
|
73
|
+
|
|
74
|
+
Time Complexity:
|
|
75
|
+
O(1)
|
|
76
|
+
"""
|
|
77
|
+
if self.empty():
|
|
78
|
+
raise EmptyContainerError("vector")
|
|
79
|
+
self._impl.pop_back()
|
|
80
|
+
|
|
81
|
+
def at(self, index: int) -> T:
|
|
82
|
+
"""
|
|
83
|
+
Access element at specified index with bounds checking.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
index: The index of the element to access.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
The element at the specified index.
|
|
90
|
+
|
|
91
|
+
Raises:
|
|
92
|
+
OutOfRangeError: If index is out of bounds.
|
|
93
|
+
|
|
94
|
+
Time Complexity:
|
|
95
|
+
O(1)
|
|
96
|
+
"""
|
|
97
|
+
if index < 0 or index >= self.size():
|
|
98
|
+
raise OutOfRangeError(index, self.size())
|
|
99
|
+
return self._impl.at(index)
|
|
100
|
+
|
|
101
|
+
def insert(self, position: int, value: T) -> None:
|
|
102
|
+
"""
|
|
103
|
+
Insert an element at the specified position.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
position: The position to insert the element.
|
|
107
|
+
value: The element to insert.
|
|
108
|
+
|
|
109
|
+
Raises:
|
|
110
|
+
OutOfRangeError: If position is out of bounds.
|
|
111
|
+
|
|
112
|
+
Time Complexity:
|
|
113
|
+
O(n) where n is the number of elements after position
|
|
114
|
+
"""
|
|
115
|
+
if position < 0 or position > self.size():
|
|
116
|
+
raise OutOfRangeError(position, self.size())
|
|
117
|
+
self._impl.insert(position, value)
|
|
118
|
+
|
|
119
|
+
def erase(self, position: int) -> None:
|
|
120
|
+
"""
|
|
121
|
+
Remove the element at the specified position.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
position: The position of the element to remove.
|
|
125
|
+
|
|
126
|
+
Raises:
|
|
127
|
+
OutOfRangeError: If position is out of bounds.
|
|
128
|
+
|
|
129
|
+
Time Complexity:
|
|
130
|
+
O(n) where n is the number of elements after position
|
|
131
|
+
"""
|
|
132
|
+
if position < 0 or position >= self.size():
|
|
133
|
+
raise OutOfRangeError(position, self.size())
|
|
134
|
+
self._impl.erase(position)
|
|
135
|
+
|
|
136
|
+
def clear(self) -> None:
|
|
137
|
+
"""
|
|
138
|
+
Remove all elements from the vector.
|
|
139
|
+
|
|
140
|
+
Time Complexity:
|
|
141
|
+
O(n) where n is the number of elements
|
|
142
|
+
"""
|
|
143
|
+
self._impl.clear()
|
|
144
|
+
|
|
145
|
+
def reserve(self, new_capacity: int) -> None:
|
|
146
|
+
"""
|
|
147
|
+
Reserve capacity for the vector.
|
|
148
|
+
|
|
149
|
+
Pre-allocates memory to avoid reallocation during growth.
|
|
150
|
+
Does not change the size of the vector.
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
new_capacity: The new capacity to reserve.
|
|
154
|
+
|
|
155
|
+
Time Complexity:
|
|
156
|
+
O(1)
|
|
157
|
+
"""
|
|
158
|
+
self._impl.reserve(new_capacity)
|
|
159
|
+
|
|
160
|
+
def shrink_to_fit(self) -> None:
|
|
161
|
+
"""
|
|
162
|
+
Reduce capacity to match the current size.
|
|
163
|
+
|
|
164
|
+
Frees unused capacity to save memory.
|
|
165
|
+
|
|
166
|
+
Time Complexity:
|
|
167
|
+
O(1)
|
|
168
|
+
"""
|
|
169
|
+
self._impl.shrink_to_fit()
|
|
170
|
+
|
|
171
|
+
def begin(self) -> VectorIterator:
|
|
172
|
+
"""
|
|
173
|
+
Get iterator to the beginning of the vector.
|
|
174
|
+
|
|
175
|
+
Returns:
|
|
176
|
+
Iterator pointing to the first element.
|
|
177
|
+
|
|
178
|
+
Time Complexity:
|
|
179
|
+
O(1)
|
|
180
|
+
"""
|
|
181
|
+
data = self._impl.get_data() if self._is_rust else self._impl._data
|
|
182
|
+
return VectorIterator(data, 0)
|
|
183
|
+
|
|
184
|
+
def end(self) -> VectorIterator:
|
|
185
|
+
"""
|
|
186
|
+
Get iterator to the end of the vector.
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
Iterator pointing past the last element.
|
|
190
|
+
|
|
191
|
+
Time Complexity:
|
|
192
|
+
O(1)
|
|
193
|
+
"""
|
|
194
|
+
data = self._impl.get_data() if self._is_rust else self._impl._data
|
|
195
|
+
return VectorIterator(data, len(data))
|
|
196
|
+
|
|
197
|
+
def rbegin(self) -> VectorReverseIterator:
|
|
198
|
+
"""
|
|
199
|
+
Get reverse iterator to the end of the vector.
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
Reverse iterator pointing to the last element.
|
|
203
|
+
|
|
204
|
+
Time Complexity:
|
|
205
|
+
O(1)
|
|
206
|
+
"""
|
|
207
|
+
data = self._impl.get_data() if self._is_rust else self._impl._data
|
|
208
|
+
return VectorReverseIterator(data)
|
|
209
|
+
|
|
210
|
+
def rend(self) -> VectorReverseIterator:
|
|
211
|
+
"""
|
|
212
|
+
Get reverse iterator to the beginning of the vector.
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
Reverse iterator pointing before the first element.
|
|
216
|
+
|
|
217
|
+
Time Complexity:
|
|
218
|
+
O(1)
|
|
219
|
+
"""
|
|
220
|
+
data = self._impl.get_data() if self._is_rust else self._impl._data
|
|
221
|
+
return VectorReverseIterator(data, -1)
|
|
222
|
+
|
|
223
|
+
def size(self) -> int:
|
|
224
|
+
"""
|
|
225
|
+
Get the number of elements in the vector.
|
|
226
|
+
|
|
227
|
+
Returns:
|
|
228
|
+
The number of elements in the vector.
|
|
229
|
+
|
|
230
|
+
Time Complexity:
|
|
231
|
+
O(1)
|
|
232
|
+
"""
|
|
233
|
+
return self._impl.size()
|
|
234
|
+
|
|
235
|
+
def capacity(self) -> int:
|
|
236
|
+
"""
|
|
237
|
+
Get the current capacity of the vector.
|
|
238
|
+
|
|
239
|
+
Returns:
|
|
240
|
+
The current capacity of the vector.
|
|
241
|
+
|
|
242
|
+
Time Complexity:
|
|
243
|
+
O(1)
|
|
244
|
+
"""
|
|
245
|
+
return self._impl.capacity()
|
|
246
|
+
|
|
247
|
+
def empty(self) -> bool:
|
|
248
|
+
"""
|
|
249
|
+
Check if the vector is empty.
|
|
250
|
+
|
|
251
|
+
Returns:
|
|
252
|
+
True if the vector is empty, False otherwise.
|
|
253
|
+
|
|
254
|
+
Time Complexity:
|
|
255
|
+
O(1)
|
|
256
|
+
"""
|
|
257
|
+
return self._impl.empty()
|
|
258
|
+
|
|
259
|
+
def copy(self) -> 'vector':
|
|
260
|
+
"""
|
|
261
|
+
Create a deep copy of the vector.
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
A new vector with copied elements.
|
|
265
|
+
|
|
266
|
+
Time Complexity:
|
|
267
|
+
O(n) where n is the number of elements
|
|
268
|
+
"""
|
|
269
|
+
new_vector = vector(use_rust=self._is_rust)
|
|
270
|
+
if self._is_rust:
|
|
271
|
+
new_vector._impl.set_data(self._impl.get_data())
|
|
272
|
+
else:
|
|
273
|
+
new_vector._impl._data = self._impl._data.copy()
|
|
274
|
+
new_vector._impl._capacity = self._impl._capacity
|
|
275
|
+
return new_vector
|
|
276
|
+
|
|
277
|
+
# Python magic methods
|
|
278
|
+
|
|
279
|
+
def __len__(self) -> int:
|
|
280
|
+
"""
|
|
281
|
+
Get the number of elements (Python len() support).
|
|
282
|
+
|
|
283
|
+
Returns:
|
|
284
|
+
The number of elements in the vector.
|
|
285
|
+
"""
|
|
286
|
+
return self.size()
|
|
287
|
+
|
|
288
|
+
def __bool__(self) -> bool:
|
|
289
|
+
"""
|
|
290
|
+
Check if vector is non-empty (Python bool() support).
|
|
291
|
+
|
|
292
|
+
Returns:
|
|
293
|
+
True if vector is non-empty, False otherwise.
|
|
294
|
+
"""
|
|
295
|
+
return not self.empty()
|
|
296
|
+
|
|
297
|
+
def __contains__(self, value: T) -> bool:
|
|
298
|
+
"""
|
|
299
|
+
Check if value exists in vector (Python 'in' operator support).
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
value: The value to search for.
|
|
303
|
+
|
|
304
|
+
Returns:
|
|
305
|
+
True if value exists, False otherwise.
|
|
306
|
+
|
|
307
|
+
Time Complexity:
|
|
308
|
+
O(n) where n is the number of elements
|
|
309
|
+
"""
|
|
310
|
+
if self._is_rust:
|
|
311
|
+
return value in self._impl.get_data()
|
|
312
|
+
return value in self._impl._data
|
|
313
|
+
|
|
314
|
+
def __repr__(self) -> str:
|
|
315
|
+
"""
|
|
316
|
+
Get string representation of the vector.
|
|
317
|
+
|
|
318
|
+
Returns:
|
|
319
|
+
String representation showing all elements.
|
|
320
|
+
"""
|
|
321
|
+
if self._is_rust:
|
|
322
|
+
elements = [str(elem) for elem in self._impl.get_data()]
|
|
323
|
+
else:
|
|
324
|
+
elements = [str(elem) for elem in self._impl._data]
|
|
325
|
+
return f"vector([{', '.join(elements)}])"
|
|
326
|
+
|
|
327
|
+
def __eq__(self, other: object) -> bool:
|
|
328
|
+
"""
|
|
329
|
+
Check equality with another vector.
|
|
330
|
+
|
|
331
|
+
Args:
|
|
332
|
+
other: Another vector to compare with.
|
|
333
|
+
|
|
334
|
+
Returns:
|
|
335
|
+
True if vectors are equal, False otherwise.
|
|
336
|
+
"""
|
|
337
|
+
if not isinstance(other, vector):
|
|
338
|
+
return False
|
|
339
|
+
|
|
340
|
+
self_data = self._impl.get_data() if self._is_rust else self._impl._data
|
|
341
|
+
other_data = other._impl.get_data() if other._is_rust else other._impl._data
|
|
342
|
+
return self_data == other_data
|
|
343
|
+
|
|
344
|
+
def __lt__(self, other: 'vector') -> bool:
|
|
345
|
+
"""
|
|
346
|
+
Lexicographic less-than comparison.
|
|
347
|
+
|
|
348
|
+
Args:
|
|
349
|
+
other: Another vector to compare with.
|
|
350
|
+
|
|
351
|
+
Returns:
|
|
352
|
+
True if this vector is lexicographically less than other.
|
|
353
|
+
"""
|
|
354
|
+
self_data = self._impl.get_data() if self._is_rust else self._impl._data
|
|
355
|
+
other_data = other._impl.get_data() if other._is_rust else other._impl._data
|
|
356
|
+
|
|
357
|
+
min_size = min(len(self_data), len(other_data))
|
|
358
|
+
for i in range(min_size):
|
|
359
|
+
if self_data[i] < other_data[i]:
|
|
360
|
+
return True
|
|
361
|
+
elif self_data[i] > other_data[i]:
|
|
362
|
+
return False
|
|
363
|
+
return len(self_data) < len(other_data)
|
|
364
|
+
|
|
365
|
+
def __iter__(self) -> TypingIterator[T]:
|
|
366
|
+
"""
|
|
367
|
+
Get Python iterator for the vector.
|
|
368
|
+
|
|
369
|
+
Returns:
|
|
370
|
+
Iterator over vector elements.
|
|
371
|
+
"""
|
|
372
|
+
if self._is_rust:
|
|
373
|
+
return iter(self._impl.get_data())
|
|
374
|
+
return iter(self._impl.get_data())
|
|
375
|
+
|
|
376
|
+
def __copy__(self) -> 'vector':
|
|
377
|
+
"""
|
|
378
|
+
Support for copy.copy().
|
|
379
|
+
|
|
380
|
+
Returns:
|
|
381
|
+
A shallow copy of the vector.
|
|
382
|
+
"""
|
|
383
|
+
return self.copy()
|
|
384
|
+
|
|
385
|
+
def __deepcopy__(self, memo) -> 'vector':
|
|
386
|
+
"""
|
|
387
|
+
Support for copy.deepcopy().
|
|
388
|
+
|
|
389
|
+
Args:
|
|
390
|
+
memo: Memoization dictionary for deepcopy.
|
|
391
|
+
|
|
392
|
+
Returns:
|
|
393
|
+
A deep copy of the vector.
|
|
394
|
+
"""
|
|
395
|
+
new_vector = vector(use_rust=self._is_rust)
|
|
396
|
+
if self._is_rust:
|
|
397
|
+
new_data = deepcopy(self._impl.get_data(), memo)
|
|
398
|
+
new_vector._impl.set_data(new_data)
|
|
399
|
+
else:
|
|
400
|
+
new_vector._impl._data = deepcopy(self._impl._data, memo)
|
|
401
|
+
new_vector._impl._capacity = self._impl._capacity
|
|
402
|
+
return new_vector
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
__all__ = ['vector']
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Private implementation of Map data structure.
|
|
3
|
+
|
|
4
|
+
This module contains the internal implementation of a map (key-value pairs)
|
|
5
|
+
following C++ STL semantics. Users should not access this directly.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import TypeVar, Dict
|
|
9
|
+
from pythonstl.core.exceptions import KeyNotFoundError
|
|
10
|
+
from pythonstl.core.iterator import MapIterator
|
|
11
|
+
|
|
12
|
+
K = TypeVar('K')
|
|
13
|
+
V = TypeVar('V')
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class _MapImpl:
|
|
17
|
+
"""
|
|
18
|
+
Internal implementation of a map using Python's built-in dict.
|
|
19
|
+
|
|
20
|
+
This class should not be accessed directly by users.
|
|
21
|
+
Use the facade class `stl_map` instead.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self) -> None:
|
|
25
|
+
"""
|
|
26
|
+
Initialize an empty map.
|
|
27
|
+
|
|
28
|
+
Time Complexity:
|
|
29
|
+
O(1)
|
|
30
|
+
"""
|
|
31
|
+
self._data: Dict[K, V] = {}
|
|
32
|
+
|
|
33
|
+
def insert(self, key: K, value: V) -> None:
|
|
34
|
+
"""
|
|
35
|
+
Insert a key-value pair into the map.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
key: The key to insert.
|
|
39
|
+
value: The value associated with the key.
|
|
40
|
+
|
|
41
|
+
Note:
|
|
42
|
+
If the key already exists, the value is updated.
|
|
43
|
+
|
|
44
|
+
Time Complexity:
|
|
45
|
+
O(1) average case
|
|
46
|
+
"""
|
|
47
|
+
self._data[key] = value
|
|
48
|
+
|
|
49
|
+
def erase(self, key: K) -> None:
|
|
50
|
+
"""
|
|
51
|
+
Remove a key-value pair from the map.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
key: The key to remove.
|
|
55
|
+
|
|
56
|
+
Note:
|
|
57
|
+
Does nothing if the key is not present (matches C++ STL behavior).
|
|
58
|
+
|
|
59
|
+
Time Complexity:
|
|
60
|
+
O(1) average case
|
|
61
|
+
"""
|
|
62
|
+
self._data.pop(key, None)
|
|
63
|
+
|
|
64
|
+
def find(self, key: K) -> bool:
|
|
65
|
+
"""
|
|
66
|
+
Check if a key exists in the map.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
key: The key to search for.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
True if the key exists, False otherwise.
|
|
73
|
+
|
|
74
|
+
Time Complexity:
|
|
75
|
+
O(1) average case
|
|
76
|
+
"""
|
|
77
|
+
return key in self._data
|
|
78
|
+
|
|
79
|
+
def at(self, key: K) -> V:
|
|
80
|
+
"""
|
|
81
|
+
Access the value associated with a key.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
key: The key to access.
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
The value associated with the key.
|
|
88
|
+
|
|
89
|
+
Raises:
|
|
90
|
+
KeyNotFoundError: If the key does not exist.
|
|
91
|
+
|
|
92
|
+
Time Complexity:
|
|
93
|
+
O(1) average case
|
|
94
|
+
"""
|
|
95
|
+
if key not in self._data:
|
|
96
|
+
raise KeyNotFoundError(key)
|
|
97
|
+
return self._data[key]
|
|
98
|
+
|
|
99
|
+
def empty(self) -> bool:
|
|
100
|
+
"""
|
|
101
|
+
Check if the map is empty.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
True if the map is empty, False otherwise.
|
|
105
|
+
|
|
106
|
+
Time Complexity:
|
|
107
|
+
O(1)
|
|
108
|
+
"""
|
|
109
|
+
return len(self._data) == 0
|
|
110
|
+
|
|
111
|
+
def size(self) -> int:
|
|
112
|
+
"""
|
|
113
|
+
Get the number of key-value pairs in the map.
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
The number of key-value pairs in the map.
|
|
117
|
+
|
|
118
|
+
Time Complexity:
|
|
119
|
+
O(1)
|
|
120
|
+
"""
|
|
121
|
+
return len(self._data)
|
|
122
|
+
|
|
123
|
+
def begin(self) -> MapIterator:
|
|
124
|
+
"""
|
|
125
|
+
Get iterator to the beginning of the map.
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
Iterator pointing to the first key-value pair.
|
|
129
|
+
|
|
130
|
+
Time Complexity:
|
|
131
|
+
O(1)
|
|
132
|
+
"""
|
|
133
|
+
return MapIterator(self._data)
|
|
134
|
+
|
|
135
|
+
def end(self) -> MapIterator:
|
|
136
|
+
"""
|
|
137
|
+
Get iterator to the end of the map.
|
|
138
|
+
|
|
139
|
+
Note: In Python dicts, end() returns an exhausted iterator.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
Iterator pointing past the last key-value pair.
|
|
143
|
+
|
|
144
|
+
Time Complexity:
|
|
145
|
+
O(1)
|
|
146
|
+
"""
|
|
147
|
+
# Return an exhausted iterator
|
|
148
|
+
it = MapIterator({})
|
|
149
|
+
return it
|
|
150
|
+
|
|
151
|
+
def get_data(self) -> Dict[K, V]:
|
|
152
|
+
"""
|
|
153
|
+
Get a copy of the internal data for iteration.
|
|
154
|
+
|
|
155
|
+
Returns:
|
|
156
|
+
Copy of the internal data dict.
|
|
157
|
+
|
|
158
|
+
Time Complexity:
|
|
159
|
+
O(n) where n is the number of key-value pairs
|
|
160
|
+
"""
|
|
161
|
+
return self._data.copy()
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
__all__ = ['_MapImpl']
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Private implementation of Set data structure.
|
|
3
|
+
|
|
4
|
+
This module contains the internal implementation of a set
|
|
5
|
+
following C++ STL semantics. Users should not access this directly.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import TypeVar, Set as PySet
|
|
9
|
+
from pythonstl.core.iterator import SetIterator
|
|
10
|
+
|
|
11
|
+
T = TypeVar('T')
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class _SetImpl:
|
|
15
|
+
"""
|
|
16
|
+
Internal implementation of a set using Python's built-in set.
|
|
17
|
+
|
|
18
|
+
This class should not be accessed directly by users.
|
|
19
|
+
Use the facade class `stl_set` instead.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self) -> None:
|
|
23
|
+
"""
|
|
24
|
+
Initialize an empty set.
|
|
25
|
+
|
|
26
|
+
Time Complexity:
|
|
27
|
+
O(1)
|
|
28
|
+
"""
|
|
29
|
+
self._data: PySet[T] = set()
|
|
30
|
+
|
|
31
|
+
def insert(self, value: T) -> None:
|
|
32
|
+
"""
|
|
33
|
+
Insert an element into the set.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
value: The element to insert into the set.
|
|
37
|
+
|
|
38
|
+
Time Complexity:
|
|
39
|
+
O(1) average case
|
|
40
|
+
"""
|
|
41
|
+
self._data.add(value)
|
|
42
|
+
|
|
43
|
+
def erase(self, value: T) -> None:
|
|
44
|
+
"""
|
|
45
|
+
Remove an element from the set.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
value: The element to remove from the set.
|
|
49
|
+
|
|
50
|
+
Note:
|
|
51
|
+
Does nothing if the element is not present (matches C++ STL behavior).
|
|
52
|
+
|
|
53
|
+
Time Complexity:
|
|
54
|
+
O(1) average case
|
|
55
|
+
"""
|
|
56
|
+
self._data.discard(value)
|
|
57
|
+
|
|
58
|
+
def find(self, value: T) -> bool:
|
|
59
|
+
"""
|
|
60
|
+
Check if an element exists in the set.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
value: The element to search for.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
True if the element exists, False otherwise.
|
|
67
|
+
|
|
68
|
+
Time Complexity:
|
|
69
|
+
O(1) average case
|
|
70
|
+
"""
|
|
71
|
+
return value in self._data
|
|
72
|
+
|
|
73
|
+
def empty(self) -> bool:
|
|
74
|
+
"""
|
|
75
|
+
Check if the set is empty.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
True if the set is empty, False otherwise.
|
|
79
|
+
|
|
80
|
+
Time Complexity:
|
|
81
|
+
O(1)
|
|
82
|
+
"""
|
|
83
|
+
return len(self._data) == 0
|
|
84
|
+
|
|
85
|
+
def size(self) -> int:
|
|
86
|
+
"""
|
|
87
|
+
Get the number of elements in the set.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
The number of elements in the set.
|
|
91
|
+
|
|
92
|
+
Time Complexity:
|
|
93
|
+
O(1)
|
|
94
|
+
"""
|
|
95
|
+
return len(self._data)
|
|
96
|
+
|
|
97
|
+
def begin(self) -> SetIterator:
|
|
98
|
+
"""
|
|
99
|
+
Get iterator to the beginning of the set.
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
Iterator pointing to the first element.
|
|
103
|
+
|
|
104
|
+
Time Complexity:
|
|
105
|
+
O(1)
|
|
106
|
+
"""
|
|
107
|
+
return SetIterator(self._data)
|
|
108
|
+
|
|
109
|
+
def end(self) -> SetIterator:
|
|
110
|
+
"""
|
|
111
|
+
Get iterator to the end of the set.
|
|
112
|
+
|
|
113
|
+
Note: In Python sets, end() returns an exhausted iterator.
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
Iterator pointing past the last element.
|
|
117
|
+
|
|
118
|
+
Time Complexity:
|
|
119
|
+
O(1)
|
|
120
|
+
"""
|
|
121
|
+
# Return an exhausted iterator
|
|
122
|
+
it = SetIterator(set())
|
|
123
|
+
return it
|
|
124
|
+
|
|
125
|
+
def get_data(self) -> PySet[T]:
|
|
126
|
+
"""
|
|
127
|
+
Get a copy of the internal data for iteration.
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
Copy of the internal data set.
|
|
131
|
+
|
|
132
|
+
Time Complexity:
|
|
133
|
+
O(n) where n is the number of elements
|
|
134
|
+
"""
|
|
135
|
+
return self._data.copy()
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
__all__ = ['_SetImpl']
|