metac 0.0.1__py3-none-any.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.
Files changed (188) hide show
  1. metac/__init__.py +6 -0
  2. metac/array.py +402 -0
  3. metac/assignable.py +26 -0
  4. metac/autotest/__init__.py +298 -0
  5. metac/autotest/__main__.py +11 -0
  6. metac/autotest/concepts.py +772 -0
  7. metac/autotest/elements.py +241 -0
  8. metac/autotest/matrix.py +150 -0
  9. metac/autotest/template/@module@.py +10 -0
  10. metac/avl_set.py +703 -0
  11. metac/bisectable.py +86 -0
  12. metac/bit_array.py +440 -0
  13. metac/bit_vector.py +940 -0
  14. metac/btree_map.py +151 -0
  15. metac/btree_set.py +734 -0
  16. metac/chained_hash_map.py +108 -0
  17. metac/chained_hash_set.py +365 -0
  18. metac/circular_buffer.py +802 -0
  19. metac/cmake/__init__.py +75 -0
  20. metac/cmake/__main__.py +12 -0
  21. metac/container.py +119 -0
  22. metac/core.py +1489 -0
  23. metac/counter.py +712 -0
  24. metac/deque.py +440 -0
  25. metac/doc/__init__.py +73 -0
  26. metac/doc/__main__.py +11 -0
  27. metac/doc/catalog.py +387 -0
  28. metac/doc/containers.md +118 -0
  29. metac/doc/design.md +174 -0
  30. metac/doc/mainpage.md +137 -0
  31. metac/doc/template/.gitignore +12 -0
  32. metac/doc/template/@module@.py +17 -0
  33. metac/doc/template/Doxyfile +21 -0
  34. metac/doc/template/catalog.py +1 -0
  35. metac/doc/tutorial.md +166 -0
  36. metac/flat_map.py +157 -0
  37. metac/flat_multimap.py +394 -0
  38. metac/flat_multiset.py +100 -0
  39. metac/flat_set.py +58 -0
  40. metac/flat_sets.py +459 -0
  41. metac/hash.py +48 -0
  42. metac/hashed.py +33 -0
  43. metac/indexable.py +65 -0
  44. metac/insertable.py +36 -0
  45. metac/intrusive_hash_map.py +155 -0
  46. metac/intrusive_hash_set.py +409 -0
  47. metac/intrusive_option.py +80 -0
  48. metac/list.py +309 -0
  49. metac/mapping.py +460 -0
  50. metac/memory.py +60 -0
  51. metac/meson/__init__.py +63 -0
  52. metac/meson/__main__.py +12 -0
  53. metac/module.py +506 -0
  54. metac/multimap.py +566 -0
  55. metac/multimapping.py +97 -0
  56. metac/multiset.py +386 -0
  57. metac/option.py +51 -0
  58. metac/options.py +326 -0
  59. metac/ordered.py +37 -0
  60. metac/packet.py +536 -0
  61. metac/priority_queue.py +299 -0
  62. metac/project/__init__.py +63 -0
  63. metac/project/__main__.py +11 -0
  64. metac/project/cmake/__init__.py +71 -0
  65. metac/project/cmake/__main__.py +10 -0
  66. metac/project/cmake/template/.gitignore +3 -0
  67. metac/project/cmake/template/.vscode/launch.json +13 -0
  68. metac/project/cmake/template/@project@.code-workspace +12 -0
  69. metac/project/cmake/template/CMakeLists.txt +45 -0
  70. metac/project/cmake/template/CMakePresets.json +206 -0
  71. metac/project/cmake/template/cmake/MetaC.cmake +121 -0
  72. metac/project/meson/__init__.py +70 -0
  73. metac/project/meson/__main__.py +10 -0
  74. metac/project/meson/template/.gitignore +4 -0
  75. metac/project/meson/template/.vscode/launch.json +13 -0
  76. metac/project/meson/template/@project@.code-workspace +12 -0
  77. metac/project/meson/template/meson.build +110 -0
  78. metac/project/meson/template/meson.options +5 -0
  79. metac/project/scons/__init__.py +71 -0
  80. metac/project/scons/__main__.py +10 -0
  81. metac/project/scons/template/.gitignore +11 -0
  82. metac/project/scons/template/.vscode/launch.json +14 -0
  83. metac/project/scons/template/.vscode/tasks.json +28 -0
  84. metac/project/scons/template/@project@.code-workspace +12 -0
  85. metac/project/scons/template/SConstruct +55 -0
  86. metac/project/scons/template/site_scons/site_tools/metac.py +91 -0
  87. metac/properties.py +11 -0
  88. metac/queue.py +255 -0
  89. metac/random.py +176 -0
  90. metac/range.py +184 -0
  91. metac/rb_set.py +630 -0
  92. metac/record.py +205 -0
  93. metac/reference.py +216 -0
  94. metac/sample/__init__.py +41 -0
  95. metac/sample/__main__.py +12 -0
  96. metac/sample/template/@module@.c +10 -0
  97. metac/sample/template/@module@.py +15 -0
  98. metac/scaffolder.py +56 -0
  99. metac/scons/__init__.py +159 -0
  100. metac/scons/__main__.py +12 -0
  101. metac/sequential.py +35 -0
  102. metac/set.py +341 -0
  103. metac/sortable.py +127 -0
  104. metac/stack.py +240 -0
  105. metac/std.py +118 -0
  106. metac/string.py +385 -0
  107. metac/string_buffer.py +567 -0
  108. metac/test/__init__.py +269 -0
  109. metac/test/__main__.py +11 -0
  110. metac/test/avl_int2int_map.py +160 -0
  111. metac/test/btree_int2int_map.py +198 -0
  112. metac/test/chained_cstring_hash_set.py +147 -0
  113. metac/test/chained_cstring_int_hash_map.py +118 -0
  114. metac/test/chained_functional_hash_set.py +100 -0
  115. metac/test/chained_int2int_hash_map.py +154 -0
  116. metac/test/chained_int_hash_set.py +268 -0
  117. metac/test/composite_packet.py +107 -0
  118. metac/test/content_variant.py +135 -0
  119. metac/test/cstring.py +7 -0
  120. metac/test/cstring_circular_buffer.py +172 -0
  121. metac/test/cstring_deque.py +259 -0
  122. metac/test/cstring_flat_multiset.py +46 -0
  123. metac/test/cstring_priority_queue.py +48 -0
  124. metac/test/cstring_queue.py +212 -0
  125. metac/test/cstring_tiered_vector.py +65 -0
  126. metac/test/cstring_vector.py +101 -0
  127. metac/test/custom_composite.py +82 -0
  128. metac/test/custom_composite_arc.py +28 -0
  129. metac/test/derived_move.py +53 -0
  130. metac/test/flat_cstring_int_map.py +82 -0
  131. metac/test/flat_cstring_int_multimap.py +121 -0
  132. metac/test/flat_int2int_map.py +184 -0
  133. metac/test/flat_int2int_multimap.py +242 -0
  134. metac/test/functional.py +132 -0
  135. metac/test/functional_vector.py +89 -0
  136. metac/test/int_array.py +269 -0
  137. metac/test/int_avl_set.py +329 -0
  138. metac/test/int_btree_set.py +329 -0
  139. metac/test/int_circular_buffer.py +457 -0
  140. metac/test/int_deque.py +302 -0
  141. metac/test/int_flat_multiset.py +252 -0
  142. metac/test/int_flat_set.py +294 -0
  143. metac/test/int_inlined_vector.py +377 -0
  144. metac/test/int_intrusive_option.py +168 -0
  145. metac/test/int_list.py +266 -0
  146. metac/test/int_option.py +189 -0
  147. metac/test/int_packet.py +228 -0
  148. metac/test/int_priority_queue.py +113 -0
  149. metac/test/int_queue.py +274 -0
  150. metac/test/int_rb_set.py +329 -0
  151. metac/test/int_stack.py +267 -0
  152. metac/test/int_tiered_vector.py +309 -0
  153. metac/test/int_treap_set.py +362 -0
  154. metac/test/int_vector.py +306 -0
  155. metac/test/intrusive_cstring_hash_set.py +85 -0
  156. metac/test/intrusive_custom_composite_arc_hash_set.py +86 -0
  157. metac/test/intrusive_int2int_hash_map.py +102 -0
  158. metac/test/intrusive_int_hash_set.py +233 -0
  159. metac/test/intrusive_primitive_arc_hash_set.py +86 -0
  160. metac/test/minimal_composite.py +49 -0
  161. metac/test/primitive_arc.py +28 -0
  162. metac/test/primitive_raw.py +27 -0
  163. metac/test/primitive_record.py +41 -0
  164. metac/test/rb_int2int_map.py +177 -0
  165. metac/test/rb_vector_multimap.py +228 -0
  166. metac/test/string_buffer.py +136 -0
  167. metac/test/template/@module@.py +10 -0
  168. metac/test/test_bit_array.py +309 -0
  169. metac/test/test_bit_vector.py +389 -0
  170. metac/test/test_counter.py +416 -0
  171. metac/test/test_emplacement.py +292 -0
  172. metac/test/test_module.py +190 -0
  173. metac/test/test_optional.py +437 -0
  174. metac/test/test_string.py +83 -0
  175. metac/test/test_traits.py +552 -0
  176. metac/test/treap_cstring_int_hash_map.py +118 -0
  177. metac/test/treap_int2int_hash_map.py +160 -0
  178. metac/tiered_vector.py +468 -0
  179. metac/traversable.py +43 -0
  180. metac/treap_set.py +764 -0
  181. metac/tree_map.py +110 -0
  182. metac/variant.py +231 -0
  183. metac/vector.py +629 -0
  184. metac-0.0.1.dist-info/METADATA +380 -0
  185. metac-0.0.1.dist-info/RECORD +188 -0
  186. metac-0.0.1.dist-info/WHEEL +5 -0
  187. metac-0.0.1.dist-info/licenses/LICENSE +26 -0
  188. metac-0.0.1.dist-info/top_level.txt +1 -0
metac/__init__.py ADDED
@@ -0,0 +1,6 @@
1
+ from importlib.metadata import version, PackageNotFoundError
2
+
3
+ try:
4
+ __version__ = version(__name__)
5
+ except PackageNotFoundError:
6
+ __version__ = "dev"
metac/array.py ADDED
@@ -0,0 +1,402 @@
1
+ import metac.std as std
2
+ from metac.hash import XorRot
3
+ from metac.assignable import Assignable
4
+ from metac.sortable import Sortable
5
+ from metac.sequential import Sequential
6
+ from metac.range import DirectAccess
7
+ from metac.container import _Range
8
+ from metac.core import inout, Callable, Indirection, _StructRenderer
9
+
10
+
11
+ #
12
+ class Array(_StructRenderer, Assignable, Sortable, Sequential):
13
+
14
+ brief = "Fixed-size stack-allocated contiguous sequence container"
15
+
16
+ def __init__(self, name, element, size, *args, index=std.size_t, sorting_operations=True, hasher=XorRot(), dependencies=(), **kwargs):
17
+ self._size = int(size)
18
+ if self._size < 1:
19
+ raise ValueError(f"Array size must be at least 1, got {self._size}")
20
+ super().__init__(name, element, index, *args, sorting_operations=sorting_operations, hasher=hasher, dependencies=(*dependencies, std.assert_h, std.string_h), **kwargs)
21
+ self.range = Range(self)
22
+
23
+ @property
24
+ def constructible(self):
25
+ return True
26
+
27
+ @property
28
+ def default_constructible(self):
29
+ return self.element.default_constructible or self.element.zero_initializable
30
+
31
+ @property
32
+ def destructible(self):
33
+ return self.element.destructible
34
+
35
+ @property
36
+ def copyable(self):
37
+ return self.element.copyable
38
+
39
+ @property
40
+ def moveable(self):
41
+ return self.element.moveable
42
+
43
+ @property
44
+ def swappable(self):
45
+ return self.element.swappable
46
+
47
+ @property
48
+ def comparable(self):
49
+ return self.element.comparable
50
+
51
+ @property
52
+ def orderable(self):
53
+ return False
54
+
55
+ @property
56
+ def hashable(self):
57
+ return self.element.hashable
58
+
59
+ @property
60
+ def zero_initializable(self):
61
+ return self.element.zero_initializable
62
+
63
+ def _element(self, target, index):
64
+ return self.element.variable(f"{target}->elements[{index}]")
65
+
66
+ def _target_size(self, target):
67
+ return str(self._size)
68
+
69
+ def _render_struct(self, stream, header):
70
+ super()._render_struct(stream, header)
71
+ stream.append(f"""
72
+ struct {self.name} {{
73
+ {self.element} elements[{self._size}]; /**< @private */
74
+ }};
75
+ """)
76
+
77
+ def __setup__(self):
78
+ super().__setup__()
79
+
80
+ self.description = f"""
81
+ Fixed-size direct access sequence container holding exactly {self._size} elements.
82
+ Allocates no dynamic heap memory, storing elements inline in a contiguous C array.
83
+ Supports bidirectional element traversal via the corresponding @ref {self.range} iterator
84
+ as well as direct indexed access to its elements.
85
+
86
+ The closest C++ equivalent is [std::array<>](https://en.cppreference.com/w/cpp/container/array).
87
+ """
88
+
89
+ target_i = self.element.variable("target->elements[index]")
90
+ source_i = self.element.variable("source->elements[index]")
91
+ left_i = self.element.variable("left->elements[index]")
92
+ right_i = self.element.variable("right->elements[index]")
93
+
94
+ with self.empty as m:
95
+ m.inline_code = f"""
96
+ assert(target);
97
+ return 0;
98
+ """
99
+
100
+ with self.size as m:
101
+ m.inline_code = f"""
102
+ assert(target);
103
+ return {self._size};
104
+ """
105
+
106
+ with self.indexed as m:
107
+ m.inline_code = f"""
108
+ assert(target);
109
+ return {m.index} < {self._size};
110
+ """
111
+
112
+ with self.create as m:
113
+ if self.element.zero_initializable:
114
+ m.inline_code = f"""
115
+ assert(target);
116
+ memset(target->elements, 0, sizeof(target->elements));
117
+ """
118
+ else:
119
+ m.code = f"""
120
+ size_t index;
121
+ assert(target);
122
+ for(index = 0; index < {self._size}; ++index) {{
123
+ {self.element.create(target_i)};
124
+ }}
125
+ """
126
+
127
+ with self.method(None, "fill", {"target": inout(self), "element": self.element}, constraint=lambda: self.element.copyable, brief="Fill all array elements with a copy of the given value",
128
+ description="""
129
+ Assigns the given value to every element of the array. Previous elements are destroyed if needed.
130
+
131
+ @param[in,out] target the array to fill
132
+ @param[in] element the value to assign to every position
133
+ """) as m:
134
+ destroy_i = self.element.destroy(target_i) if self.element.destructible else ""
135
+ m.code = lambda m: f"""
136
+ size_t index;
137
+ assert(target);
138
+ for(index = 0; index < {self._size}; ++index) {{
139
+ {destroy_i};
140
+ {self.element.copy(target_i, m.element)};
141
+ }}
142
+ """
143
+
144
+ if self.destructible:
145
+ with self.destroy as m:
146
+ m.code = f"""
147
+ size_t index;
148
+ assert(target);
149
+ for(index = 0; index < {self._size}; ++index) {{
150
+ {self.element.destroy(target_i)};
151
+ }}
152
+ """
153
+
154
+ with self.copy as m:
155
+ m.code = lambda m: f"""
156
+ size_t index;
157
+ assert(target);
158
+ assert(source);
159
+ for(index = 0; index < {self._size}; ++index) {{
160
+ {self.element.copy(target_i, source_i)};
161
+ }}
162
+ """
163
+
164
+ with self.move as m:
165
+ m.code = f"""
166
+ size_t index;
167
+ assert(target);
168
+ assert(source);
169
+ for(index = 0; index < {self._size}; ++index) {{
170
+ {self.element.move(target_i, source_i)};
171
+ }}
172
+ """
173
+
174
+ with self.swap as m:
175
+ m.code = f"""
176
+ size_t index;
177
+ assert(left);
178
+ assert(right);
179
+ for(index = 0; index < {self._size}; ++index) {{
180
+ {self.element.swap(left_i, right_i)};
181
+ }}
182
+ """
183
+
184
+ with self.get as m:
185
+ result = m.result.variable("result")
186
+ slot = self.element.variable(f"target->elements[{m.index}]")
187
+ m.inline_code = lambda m: f"""
188
+ {result.definition};
189
+ assert(target);
190
+ assert({self.indexed(m.target, m.index)});
191
+ {self.element.copy(result, slot)};
192
+ return {result};
193
+ """
194
+
195
+ with self.view as m:
196
+ slot = self.element.variable(f"target->elements[{m.index}]")
197
+ m.inline_code = f"""
198
+ assert(target);
199
+ assert({self.indexed(m.target, m.index)});
200
+ return {slot.bind(m.result)};
201
+ """
202
+
203
+ with self.set as m:
204
+ slot = self.element.variable(f"target->elements[{m.index}]")
205
+ destroy_slot = self.element.destroy(slot) if self.element.destructible else ""
206
+ m.inline_code = lambda m: f"""
207
+ assert(target);
208
+ assert({self.indexed(m.target, m.index)});
209
+ {destroy_slot};
210
+ {self.element.copy(slot, m.element)};
211
+ """
212
+
213
+ with self.method(None, "emplace", {"target": inout(self), "index": self.index} | self.element.constructor_parameters,
214
+ constraint=lambda: self.element.emplaceable, brief="Construct the element at index in place",
215
+ description="""
216
+ Constructs the element in place with the forwarded parameters, associating it with
217
+ the index - the element previously held at the index is destroyed first.
218
+
219
+ @param[in,out] target the array to update
220
+ @param[in] index the index to construct the element at
221
+ """) as m:
222
+ def _emplace_code(m):
223
+ create_args = [getattr(m, name) for name in self.element.constructor_parameters]
224
+ slot = self.element.variable(f"target->elements[{m.index}]")
225
+ destroy_slot = self.element.destroy(slot) if self.element.destructible else ""
226
+ return f"""
227
+ assert(target);
228
+ assert({self.indexed(m.target, m.index)});
229
+ {destroy_slot};
230
+ {self.element.create(slot, *create_args)};
231
+ """
232
+ m.code = _emplace_code
233
+
234
+ with self.method(self.element, "front", {"target": self}, constraint=lambda: self.element.copyable,
235
+ references=(self.get,),
236
+ brief="Get a copy of the front element",
237
+ description="""
238
+ Returns a copy of the first element in the array.
239
+
240
+ @param[in] target the array to read from
241
+ @return a copy of the first element
242
+ """) as m:
243
+ m.inline_code = lambda m: f"""
244
+ assert(target);
245
+ return {self.get(m.target, 0)};
246
+ """
247
+
248
+ with self.method(self.element.view_type, ("front", "view"), {"target": self},
249
+ references=(self.view,),
250
+ brief="Get a constant view of the front element",
251
+ description="""
252
+ Returns a constant view of the first element in the array without copying it.
253
+
254
+ @param[in] target the array to read from
255
+ @return a constant view of the first element
256
+ """) as m:
257
+ m.inline_code = f"""
258
+ assert(target);
259
+ return {self.view(m.target, 0)};
260
+ """
261
+
262
+ with self.method(self.element, "back", {"target": self}, constraint=lambda: self.element.copyable,
263
+ references=(self.get,),
264
+ brief="Get a copy of the back element",
265
+ description="""
266
+ Returns a copy of the last element in the array.
267
+
268
+ @param[in] target the array to read from
269
+ @return a copy of the last element
270
+ """) as m:
271
+ m.inline_code = lambda m: f"""
272
+ assert(target);
273
+ return {self.get(m.target, self._size - 1)};
274
+ """
275
+
276
+ with self.method(self.element.view_type, ("back", "view"), {"target": self},
277
+ references=(self.view,),
278
+ brief="Get a constant view of the back element",
279
+ description="""
280
+ Returns a constant view of the last element in the array without copying it.
281
+
282
+ @param[in] target the array to read from
283
+ @return a constant view of the last element
284
+ """) as m:
285
+ m.inline_code = f"""
286
+ assert(target);
287
+ return {self.view(m.target, self._size - 1)};
288
+ """
289
+
290
+ with self.method(Indirection(self.element), "data", {"target": inout(self)}, brief="Get pointer to the underlying array",
291
+ description="""
292
+ Returns a pointer to the contiguous array storage.
293
+
294
+ @param[in,out] target the array to inspect
295
+ @return a pointer to the first element
296
+ """) as m:
297
+ m.inline_code = f"""
298
+ assert(target);
299
+ return target->elements;
300
+ """
301
+
302
+
303
+ #
304
+ class Range(_Range, DirectAccess):
305
+
306
+ brief = "Direct access range over array"
307
+
308
+ def _render_struct(self, stream, header):
309
+ super()._render_struct(stream, header)
310
+ stream.append(f"""
311
+ struct {self.name} {{
312
+ {Indirection(self.iterable, constant=True)} iterable; /**< @private */
313
+ {self.iterable.index} front, /**< @private */ back; /**< @private */
314
+ }};
315
+ """)
316
+
317
+ def __setup__(self):
318
+ super().__setup__()
319
+
320
+ with self.method(Callable.Parameter(self), "new", {"iterable": self.iterable}, brief="Create range spanning the array",
321
+ description="""
322
+ Creates a range over the array elements. The range must not outlive the array.
323
+
324
+ @param[in] iterable the array to span
325
+ @return the range covering the whole array
326
+ """) as m:
327
+ result = m.result.variable("result")
328
+ m.inline_code = f"""
329
+ {result.definition};
330
+ assert(iterable);
331
+ result.iterable = iterable;
332
+ result.front = 0;
333
+ result.back = {self.iterable._size};
334
+ return {result};
335
+ """
336
+
337
+ with self.empty as m:
338
+ m.inline_code = f"""
339
+ assert(target);
340
+ return target->front >= target->back;
341
+ """
342
+
343
+ with self.front as m:
344
+ m.inline_code = lambda: f"""
345
+ assert(target);
346
+ assert(!{self.empty(m.target)});
347
+ return {self.iterable.get("target->iterable", "target->front")};
348
+ """
349
+
350
+ with self.front_view as m:
351
+ m.inline_code = lambda: f"""
352
+ assert(target);
353
+ assert(!{self.empty(m.target)});
354
+ return {self.iterable.view("target->iterable", "target->front")};
355
+ """
356
+
357
+ with self.move_front as m:
358
+ m.inline_code = f"""
359
+ assert(target);
360
+ assert(!{self.empty(m.target)});
361
+ ++target->front;
362
+ """
363
+
364
+ with self.back as m:
365
+ m.inline_code = lambda: f"""
366
+ assert(target);
367
+ assert(!{self.empty(m.target)});
368
+ return {self.iterable.get("target->iterable", "target->back - 1")};
369
+ """
370
+
371
+ with self.back_view as m:
372
+ m.inline_code = lambda: f"""
373
+ assert(target);
374
+ assert(!{self.empty(m.target)});
375
+ return {self.iterable.view("target->iterable", "target->back - 1")};
376
+ """
377
+
378
+ with self.move_back as m:
379
+ m.inline_code = f"""
380
+ assert(target);
381
+ assert(!{self.empty(m.target)});
382
+ --target->back;
383
+ """
384
+
385
+ with self.get as m:
386
+ m.inline_code = lambda: f"""
387
+ assert(target);
388
+ return {self.iterable.get("target->iterable", "target->front + index")};
389
+ """
390
+
391
+ with self.view as m:
392
+ m.inline_code = lambda: f"""
393
+ assert(target);
394
+ return {self.iterable.view("target->iterable", "target->front + index")};
395
+ """
396
+
397
+ with self.size as m:
398
+ m.inline_code = f"""
399
+ assert(target);
400
+ assert(target->back >= target->front);
401
+ return target->back - target->front;
402
+ """
metac/assignable.py ADDED
@@ -0,0 +1,26 @@
1
+ from metac.core import inout
2
+ from metac.indexable import Indexable
3
+
4
+
5
+ # Capability mixin declaring position-addressed assignment for collections reachable
6
+ # by index - the writable half of the Indexable read protocol (assignability implies
7
+ # indexability). Multimapping mixes Indexable without Assignable since replacing "the
8
+ # element at a key" is ambiguous under duplicate keys.
9
+ class Assignable(Indexable):
10
+
11
+ def __setup__(self):
12
+ super().__setup__()
13
+
14
+ valid_index = lambda: self.index.comparable or self.index.orderable
15
+
16
+ self.method(None, "set", {"target": inout(self), "index": self.index, "element": self.element}, constraint=lambda: valid_index() and self.element.copyable, brief="Set the element at index",
17
+ description="""
18
+ Associates the element with the index - either storing it at the brand new entry
19
+ or replacing the contents of the element already held at the index in place.
20
+ The cost matches the underlying implementation: expected O(1) for hash-based and direct-indexed
21
+ containers, expected O(log n) for tree-based containers.
22
+
23
+ @param[in,out] target the collection to update
24
+ @param[in] index the index to assign the element at
25
+ @param[in] element the element to store - the element previously held at the index is destroyed
26
+ """)