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
pythonstl/facade/set.py
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Set facade class.
|
|
3
|
+
|
|
4
|
+
This module provides the public-facing set class that users interact with.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import TypeVar, Iterator as TypingIterator
|
|
8
|
+
from copy import deepcopy
|
|
9
|
+
from pythonstl.implementations.associative._set_impl import _SetImpl
|
|
10
|
+
from pythonstl.core.iterator import SetIterator
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
from pythonstl._rust import RustSet
|
|
14
|
+
RUST_AVAILABLE = True
|
|
15
|
+
except ImportError:
|
|
16
|
+
RUST_AVAILABLE = False
|
|
17
|
+
|
|
18
|
+
T = TypeVar('T')
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class stl_set:
|
|
22
|
+
"""
|
|
23
|
+
A set data structure following C++ STL semantics.
|
|
24
|
+
|
|
25
|
+
This is an associative container that stores unique elements.
|
|
26
|
+
Named 'stl_set' to avoid conflict with Python's built-in set.
|
|
27
|
+
|
|
28
|
+
Example:
|
|
29
|
+
>>> from pythonstl import stl_set
|
|
30
|
+
>>> s = stl_set()
|
|
31
|
+
>>> s.insert(10)
|
|
32
|
+
>>> s.insert(20)
|
|
33
|
+
>>> s.find(10)
|
|
34
|
+
True
|
|
35
|
+
>>> 10 in s
|
|
36
|
+
True
|
|
37
|
+
>>> len(s)
|
|
38
|
+
2
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __init__(self, use_rust: bool = True) -> None:
|
|
42
|
+
"""
|
|
43
|
+
Initialize an empty set.
|
|
44
|
+
|
|
45
|
+
Time Complexity:
|
|
46
|
+
O(1)
|
|
47
|
+
"""
|
|
48
|
+
if use_rust and RUST_AVAILABLE:
|
|
49
|
+
self._impl = RustSet()
|
|
50
|
+
self._is_rust = True
|
|
51
|
+
else:
|
|
52
|
+
self._impl = _SetImpl()
|
|
53
|
+
self._is_rust = False
|
|
54
|
+
|
|
55
|
+
def insert(self, value: T) -> None:
|
|
56
|
+
"""
|
|
57
|
+
Insert an element into the set.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
value: The element to insert into the set.
|
|
61
|
+
|
|
62
|
+
Time Complexity:
|
|
63
|
+
O(1) average case
|
|
64
|
+
"""
|
|
65
|
+
self._impl.insert(value)
|
|
66
|
+
|
|
67
|
+
def erase(self, value: T) -> None:
|
|
68
|
+
"""
|
|
69
|
+
Remove an element from the set.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
value: The element to remove from the set.
|
|
73
|
+
|
|
74
|
+
Note:
|
|
75
|
+
Does nothing if the element is not present (matches C++ STL behavior).
|
|
76
|
+
|
|
77
|
+
Time Complexity:
|
|
78
|
+
O(1) average case
|
|
79
|
+
"""
|
|
80
|
+
self._impl.erase(value)
|
|
81
|
+
|
|
82
|
+
def find(self, value: T) -> bool:
|
|
83
|
+
"""
|
|
84
|
+
Check if an element exists in the set.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
value: The element to search for.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
True if the element exists, False otherwise.
|
|
91
|
+
|
|
92
|
+
Time Complexity:
|
|
93
|
+
O(1) average case
|
|
94
|
+
"""
|
|
95
|
+
return self._impl.find(value)
|
|
96
|
+
|
|
97
|
+
def empty(self) -> bool:
|
|
98
|
+
"""
|
|
99
|
+
Check if the set is empty.
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
True if the set is empty, False otherwise.
|
|
103
|
+
|
|
104
|
+
Time Complexity:
|
|
105
|
+
O(1)
|
|
106
|
+
"""
|
|
107
|
+
return self._impl.empty()
|
|
108
|
+
|
|
109
|
+
def size(self) -> int:
|
|
110
|
+
"""
|
|
111
|
+
Get the number of elements in the set.
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
The number of elements in the set.
|
|
115
|
+
|
|
116
|
+
Time Complexity:
|
|
117
|
+
O(1)
|
|
118
|
+
"""
|
|
119
|
+
return self._impl.size()
|
|
120
|
+
|
|
121
|
+
def begin(self) -> SetIterator:
|
|
122
|
+
"""
|
|
123
|
+
Get iterator to the beginning of the set.
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
Iterator pointing to the first element.
|
|
127
|
+
|
|
128
|
+
Time Complexity:
|
|
129
|
+
O(1)
|
|
130
|
+
"""
|
|
131
|
+
data = self._impl.get_data() if self._is_rust else self._impl._data
|
|
132
|
+
return SetIterator(data)
|
|
133
|
+
|
|
134
|
+
def end(self) -> SetIterator:
|
|
135
|
+
"""
|
|
136
|
+
Get iterator to the end of the set.
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
Iterator pointing past the last element.
|
|
140
|
+
|
|
141
|
+
Time Complexity:
|
|
142
|
+
O(1)
|
|
143
|
+
"""
|
|
144
|
+
# Return an exhausted iterator
|
|
145
|
+
return SetIterator(set())
|
|
146
|
+
|
|
147
|
+
def copy(self) -> 'stl_set':
|
|
148
|
+
"""
|
|
149
|
+
Create a deep copy of the set.
|
|
150
|
+
|
|
151
|
+
Returns:
|
|
152
|
+
A new set with copied elements.
|
|
153
|
+
|
|
154
|
+
Time Complexity:
|
|
155
|
+
O(n) where n is the number of elements
|
|
156
|
+
"""
|
|
157
|
+
new_set = stl_set(use_rust=self._is_rust)
|
|
158
|
+
if self._is_rust:
|
|
159
|
+
new_set._impl.set_data(self._impl.get_data())
|
|
160
|
+
else:
|
|
161
|
+
new_set._impl._data = self._impl._data.copy()
|
|
162
|
+
return new_set
|
|
163
|
+
|
|
164
|
+
# Python magic methods
|
|
165
|
+
|
|
166
|
+
def __len__(self) -> int:
|
|
167
|
+
"""
|
|
168
|
+
Get the number of elements (Python len() support).
|
|
169
|
+
|
|
170
|
+
Returns:
|
|
171
|
+
The number of elements in the set.
|
|
172
|
+
"""
|
|
173
|
+
return self.size()
|
|
174
|
+
|
|
175
|
+
def __bool__(self) -> bool:
|
|
176
|
+
"""
|
|
177
|
+
Check if set is non-empty (Python bool() support).
|
|
178
|
+
|
|
179
|
+
Returns:
|
|
180
|
+
True if set is non-empty, False otherwise.
|
|
181
|
+
"""
|
|
182
|
+
return not self.empty()
|
|
183
|
+
|
|
184
|
+
def __contains__(self, value: T) -> bool:
|
|
185
|
+
"""
|
|
186
|
+
Check if value exists in set (Python 'in' operator support).
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
value: The value to search for.
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
True if value exists, False otherwise.
|
|
193
|
+
|
|
194
|
+
Time Complexity:
|
|
195
|
+
O(1) average case
|
|
196
|
+
"""
|
|
197
|
+
return self.find(value)
|
|
198
|
+
|
|
199
|
+
def __repr__(self) -> str:
|
|
200
|
+
"""
|
|
201
|
+
Get string representation of the set.
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
String representation showing all elements.
|
|
205
|
+
"""
|
|
206
|
+
elements = [str(elem) for elem in self]
|
|
207
|
+
return f"stl_set({{{', '.join(elements)}}})"
|
|
208
|
+
|
|
209
|
+
def __eq__(self, other: object) -> bool:
|
|
210
|
+
"""
|
|
211
|
+
Check equality with another set.
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
other: Another set to compare with.
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
True if sets are equal, False otherwise.
|
|
218
|
+
"""
|
|
219
|
+
if not isinstance(other, stl_set):
|
|
220
|
+
return False
|
|
221
|
+
|
|
222
|
+
self_data = self._impl.get_data() if self._is_rust else self._impl._data
|
|
223
|
+
other_data = other._impl.get_data() if other._is_rust else other._impl._data
|
|
224
|
+
|
|
225
|
+
# BTreeSet elements are sorted, so direct list equality works for sorted comparison
|
|
226
|
+
if self._is_rust and other._is_rust:
|
|
227
|
+
return self_data == other_data
|
|
228
|
+
|
|
229
|
+
return set(self_data) == set(other_data)
|
|
230
|
+
|
|
231
|
+
def __iter__(self) -> TypingIterator[T]:
|
|
232
|
+
"""
|
|
233
|
+
Get Python iterator for the set.
|
|
234
|
+
|
|
235
|
+
Returns:
|
|
236
|
+
Iterator over set elements.
|
|
237
|
+
"""
|
|
238
|
+
if self._is_rust:
|
|
239
|
+
return iter(self._impl.get_data())
|
|
240
|
+
return iter(self._impl.get_data())
|
|
241
|
+
|
|
242
|
+
def __copy__(self) -> 'stl_set':
|
|
243
|
+
"""
|
|
244
|
+
Support for copy.copy().
|
|
245
|
+
|
|
246
|
+
Returns:
|
|
247
|
+
A shallow copy of the set.
|
|
248
|
+
"""
|
|
249
|
+
return self.copy()
|
|
250
|
+
|
|
251
|
+
def __deepcopy__(self, memo) -> 'stl_set':
|
|
252
|
+
"""
|
|
253
|
+
Support for copy.deepcopy().
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
memo: Memoization dictionary for deepcopy.
|
|
257
|
+
|
|
258
|
+
Returns:
|
|
259
|
+
A deep copy of the set.
|
|
260
|
+
"""
|
|
261
|
+
new_set = stl_set(use_rust=self._is_rust)
|
|
262
|
+
if self._is_rust:
|
|
263
|
+
new_data = deepcopy(self._impl.get_data(), memo)
|
|
264
|
+
new_set._impl.set_data(new_data)
|
|
265
|
+
else:
|
|
266
|
+
new_set._impl._data = deepcopy(self._impl._data, memo)
|
|
267
|
+
return new_set
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
__all__ = ['stl_set']
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Stack facade class.
|
|
3
|
+
|
|
4
|
+
This module provides the public-facing stack 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._stack_impl import _StackImpl
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
from pythonstl._rust import RustStack
|
|
14
|
+
RUST_AVAILABLE = True
|
|
15
|
+
except ImportError:
|
|
16
|
+
RUST_AVAILABLE = False
|
|
17
|
+
|
|
18
|
+
T = TypeVar('T')
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class stack:
|
|
22
|
+
"""
|
|
23
|
+
A stack data structure following C++ STL semantics.
|
|
24
|
+
|
|
25
|
+
This is a LIFO (Last-In-First-Out) container adapter.
|
|
26
|
+
|
|
27
|
+
Example:
|
|
28
|
+
>>> from pythonstl import stack
|
|
29
|
+
>>> s = stack()
|
|
30
|
+
>>> s.push(10)
|
|
31
|
+
>>> s.push(20)
|
|
32
|
+
>>> s.top()
|
|
33
|
+
20
|
|
34
|
+
>>> len(s)
|
|
35
|
+
2
|
|
36
|
+
>>> bool(s)
|
|
37
|
+
True
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
def __init__(self, use_rust: bool = True) -> None:
|
|
41
|
+
"""
|
|
42
|
+
Initialize an empty stack.
|
|
43
|
+
|
|
44
|
+
Time Complexity:
|
|
45
|
+
O(1)
|
|
46
|
+
"""
|
|
47
|
+
if use_rust and RUST_AVAILABLE:
|
|
48
|
+
self._impl = RustStack()
|
|
49
|
+
self._is_rust = True
|
|
50
|
+
else:
|
|
51
|
+
self._impl = _StackImpl()
|
|
52
|
+
self._is_rust = False
|
|
53
|
+
|
|
54
|
+
def push(self, value: T) -> None:
|
|
55
|
+
"""
|
|
56
|
+
Push an element onto the stack.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
value: The element to push onto the stack.
|
|
60
|
+
|
|
61
|
+
Time Complexity:
|
|
62
|
+
O(1) amortized
|
|
63
|
+
"""
|
|
64
|
+
self._impl.push(value)
|
|
65
|
+
|
|
66
|
+
def pop(self) -> None:
|
|
67
|
+
"""
|
|
68
|
+
Remove the top element from the stack.
|
|
69
|
+
|
|
70
|
+
Raises:
|
|
71
|
+
EmptyContainerError: If the stack is empty.
|
|
72
|
+
|
|
73
|
+
Time Complexity:
|
|
74
|
+
O(1)
|
|
75
|
+
"""
|
|
76
|
+
if self.empty():
|
|
77
|
+
raise EmptyContainerError("stack")
|
|
78
|
+
self._impl.pop()
|
|
79
|
+
|
|
80
|
+
def top(self) -> T:
|
|
81
|
+
"""
|
|
82
|
+
Get the top element of the stack without removing it.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
The top element of the stack.
|
|
86
|
+
|
|
87
|
+
Raises:
|
|
88
|
+
EmptyContainerError: If the stack is empty.
|
|
89
|
+
|
|
90
|
+
Time Complexity:
|
|
91
|
+
O(1)
|
|
92
|
+
"""
|
|
93
|
+
if self.empty():
|
|
94
|
+
raise EmptyContainerError("stack")
|
|
95
|
+
return self._impl.top()
|
|
96
|
+
|
|
97
|
+
def empty(self) -> bool:
|
|
98
|
+
"""
|
|
99
|
+
Check if the stack is empty.
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
True if the stack is empty, False otherwise.
|
|
103
|
+
|
|
104
|
+
Time Complexity:
|
|
105
|
+
O(1)
|
|
106
|
+
"""
|
|
107
|
+
return self._impl.empty()
|
|
108
|
+
|
|
109
|
+
def size(self) -> int:
|
|
110
|
+
"""
|
|
111
|
+
Get the number of elements in the stack.
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
The number of elements in the stack.
|
|
115
|
+
|
|
116
|
+
Time Complexity:
|
|
117
|
+
O(1)
|
|
118
|
+
"""
|
|
119
|
+
return self._impl.size()
|
|
120
|
+
|
|
121
|
+
def copy(self) -> 'stack':
|
|
122
|
+
"""
|
|
123
|
+
Create a deep copy of the stack.
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
A new stack with copied elements.
|
|
127
|
+
|
|
128
|
+
Time Complexity:
|
|
129
|
+
O(n) where n is the number of elements
|
|
130
|
+
"""
|
|
131
|
+
new_stack = stack(use_rust=self._is_rust)
|
|
132
|
+
if self._is_rust:
|
|
133
|
+
new_stack._impl.set_data(self._impl.get_data())
|
|
134
|
+
else:
|
|
135
|
+
new_stack._impl._data = self._impl._data.copy()
|
|
136
|
+
return new_stack
|
|
137
|
+
|
|
138
|
+
# Python magic methods
|
|
139
|
+
|
|
140
|
+
def __len__(self) -> int:
|
|
141
|
+
"""
|
|
142
|
+
Get the number of elements (Python len() support).
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
The number of elements in the stack.
|
|
146
|
+
"""
|
|
147
|
+
return self.size()
|
|
148
|
+
|
|
149
|
+
def __bool__(self) -> bool:
|
|
150
|
+
"""
|
|
151
|
+
Check if stack is non-empty (Python bool() support).
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
True if stack is non-empty, False otherwise.
|
|
155
|
+
"""
|
|
156
|
+
return not self.empty()
|
|
157
|
+
|
|
158
|
+
def __repr__(self) -> str:
|
|
159
|
+
"""
|
|
160
|
+
Get string representation of the stack.
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
String representation showing stack contents.
|
|
164
|
+
"""
|
|
165
|
+
if self._is_rust:
|
|
166
|
+
elements = [str(elem) for elem in self._impl.get_data()]
|
|
167
|
+
else:
|
|
168
|
+
elements = [str(elem) for elem in self._impl._data]
|
|
169
|
+
return f"stack([{', '.join(elements)}])"
|
|
170
|
+
|
|
171
|
+
def __eq__(self, other: object) -> bool:
|
|
172
|
+
"""
|
|
173
|
+
Check equality with another stack.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
other: Another stack to compare with.
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
True if stacks are equal, False otherwise.
|
|
180
|
+
"""
|
|
181
|
+
if not isinstance(other, stack):
|
|
182
|
+
return False
|
|
183
|
+
|
|
184
|
+
self_data = self._impl.get_data() if self._is_rust else self._impl._data
|
|
185
|
+
other_data = other._impl.get_data() if other._is_rust else other._impl._data
|
|
186
|
+
return self_data == other_data
|
|
187
|
+
|
|
188
|
+
def __copy__(self) -> 'stack':
|
|
189
|
+
"""
|
|
190
|
+
Support for copy.copy().
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
A shallow copy of the stack.
|
|
194
|
+
"""
|
|
195
|
+
return self.copy()
|
|
196
|
+
|
|
197
|
+
def __deepcopy__(self, memo) -> 'stack':
|
|
198
|
+
"""
|
|
199
|
+
Support for copy.deepcopy().
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
memo: Memoization dictionary for deepcopy.
|
|
203
|
+
|
|
204
|
+
Returns:
|
|
205
|
+
A deep copy of the stack.
|
|
206
|
+
"""
|
|
207
|
+
new_stack = stack(use_rust=self._is_rust)
|
|
208
|
+
if self._is_rust:
|
|
209
|
+
new_data = deepcopy(self._impl.get_data(), memo)
|
|
210
|
+
new_stack._impl.set_data(new_data)
|
|
211
|
+
else:
|
|
212
|
+
new_stack._impl._data = deepcopy(self._impl._data, memo)
|
|
213
|
+
return new_stack
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
__all__ = ['stack']
|