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,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,3 @@
1
+ """Implementation layer for pystl data structures."""
2
+
3
+ __all__ = []
@@ -0,0 +1,6 @@
1
+ """Associative data structure implementations."""
2
+
3
+ from ._set_impl import _SetImpl
4
+ from ._map_impl import _MapImpl
5
+
6
+ __all__ = ['_SetImpl', '_MapImpl']
@@ -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']