1use super::Slicable;
7#[cfg(stageleft_runtime)]
8use crate::forward_handle::{CycleCollection, CycleCollectionWithInitial};
9use crate::forward_handle::{TickCycle, TickCycleHandle};
10use crate::live_collections::boundedness::{Bounded, Boundedness, Unbounded};
11use crate::live_collections::keyed_singleton::BoundedValue;
12use crate::live_collections::stream::{Ordering, Retries};
13use crate::location::tick::{DeferTick, Tick};
14use crate::location::{Location, NoTick};
15use crate::nondet::NonDet;
16
17pub struct Default<T> {
21 pub(crate) collection: T,
22 pub(crate) nondet: NonDet,
23}
24
25impl<T> Default<T> {
26 pub fn new(collection: T, nondet: NonDet) -> Self {
28 Self { collection, nondet }
29 }
30}
31
32#[doc(hidden)]
34pub fn default<T>(t: T, nondet: NonDet) -> Default<T> {
35 Default::new(t, nondet)
36}
37
38pub struct Atomic<T> {
42 pub(crate) collection: T,
43 pub(crate) nondet: NonDet,
44}
45
46impl<T> Atomic<T> {
47 pub fn new(collection: T, nondet: NonDet) -> Self {
49 Self { collection, nondet }
50 }
51}
52
53pub fn atomic<T>(t: T, nondet: NonDet) -> Atomic<T> {
55 Atomic::new(t, nondet)
56}
57
58#[cfg(stageleft_runtime)]
66#[expect(
67 private_bounds,
68 reason = "only Hydro collections can implement CycleCollectionWithInitial"
69)]
70pub fn state<
71 'a,
72 S: CycleCollectionWithInitial<'a, TickCycle, Location = Tick<L>>,
73 L: Location<'a> + NoTick,
74>(
75 tick: &Tick<L>,
76 initial_fn: impl FnOnce(&Tick<L>) -> S,
77) -> (TickCycleHandle<'a, S>, S) {
78 let initial = initial_fn(tick);
79 tick.cycle_with_initial(initial)
80}
81
82#[cfg(stageleft_runtime)]
87#[expect(
88 private_bounds,
89 reason = "only Hydro collections can implement CycleCollection"
90)]
91pub fn state_null<
92 'a,
93 S: CycleCollection<'a, TickCycle, Location = Tick<L>> + DeferTick,
94 L: Location<'a> + NoTick,
95>(
96 tick: &Tick<L>,
97) -> (TickCycleHandle<'a, S>, S) {
98 tick.cycle::<S>()
99}
100
101impl<'a, T, L: Location<'a>, B: Boundedness, O: Ordering, R: Retries> Slicable<'a, L>
106 for Default<crate::live_collections::Stream<T, L, B, O, R>>
107{
108 type Slice = crate::live_collections::Stream<T, Tick<L>, Bounded, O, R>;
109 type Backtrace = crate::compile::ir::backtrace::Backtrace;
110
111 fn get_location(&self) -> &L {
112 self.collection.location()
113 }
114
115 fn preferred_tick(&self) -> Option<Tick<L>> {
116 None
117 }
118
119 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
120 let out = self.collection.batch(tick, self.nondet);
121 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
122 out
123 }
124}
125
126impl<'a, T, L: Location<'a>, B: Boundedness> Slicable<'a, L>
127 for Default<crate::live_collections::Singleton<T, L, B>>
128{
129 type Slice = crate::live_collections::Singleton<T, Tick<L>, Bounded>;
130 type Backtrace = crate::compile::ir::backtrace::Backtrace;
131
132 fn get_location(&self) -> &L {
133 self.collection.location()
134 }
135
136 fn preferred_tick(&self) -> Option<Tick<L>> {
137 None
138 }
139
140 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
141 let out = self.collection.snapshot(tick, self.nondet);
142 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
143 out
144 }
145}
146
147impl<'a, T, L: Location<'a>, B: Boundedness> Slicable<'a, L>
148 for Default<crate::live_collections::Optional<T, L, B>>
149{
150 type Slice = crate::live_collections::Optional<T, Tick<L>, Bounded>;
151 type Backtrace = crate::compile::ir::backtrace::Backtrace;
152
153 fn get_location(&self) -> &L {
154 self.collection.location()
155 }
156
157 fn preferred_tick(&self) -> Option<Tick<L>> {
158 None
159 }
160
161 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
162 let out = self.collection.snapshot(tick, self.nondet);
163 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
164 out
165 }
166}
167
168impl<'a, K, V, L: Location<'a>, O: Ordering, R: Retries> Slicable<'a, L>
169 for Default<crate::live_collections::KeyedStream<K, V, L, Unbounded, O, R>>
170{
171 type Slice = crate::live_collections::KeyedStream<K, V, Tick<L>, Bounded, O, R>;
172 type Backtrace = crate::compile::ir::backtrace::Backtrace;
173
174 fn get_location(&self) -> &L {
175 self.collection.location()
176 }
177
178 fn preferred_tick(&self) -> Option<Tick<L>> {
179 None
180 }
181
182 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
183 let out = self.collection.batch(tick, self.nondet);
184 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
185 out
186 }
187}
188
189impl<'a, K, V, L: Location<'a>> Slicable<'a, L>
190 for Default<crate::live_collections::KeyedSingleton<K, V, L, Unbounded>>
191{
192 type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L>, Bounded>;
193 type Backtrace = crate::compile::ir::backtrace::Backtrace;
194
195 fn get_location(&self) -> &L {
196 self.collection.location()
197 }
198
199 fn preferred_tick(&self) -> Option<Tick<L>> {
200 None
201 }
202
203 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
204 let out = self.collection.snapshot(tick, self.nondet);
205 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
206 out
207 }
208}
209
210impl<'a, K, V, L: Location<'a> + NoTick> Slicable<'a, L>
211 for Default<crate::live_collections::KeyedSingleton<K, V, L, BoundedValue>>
212{
213 type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L>, Bounded>;
214 type Backtrace = crate::compile::ir::backtrace::Backtrace;
215
216 fn get_location(&self) -> &L {
217 self.collection.location()
218 }
219
220 fn preferred_tick(&self) -> Option<Tick<L>> {
221 None
222 }
223
224 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
225 let out = self.collection.batch(tick, self.nondet);
226 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
227 out
228 }
229}
230
231impl<'a, T, L: Location<'a> + NoTick, O: Ordering, R: Retries> Slicable<'a, L>
236 for Atomic<crate::live_collections::Stream<T, crate::location::Atomic<L>, Unbounded, O, R>>
237{
238 type Slice = crate::live_collections::Stream<T, Tick<L>, Bounded, O, R>;
239 type Backtrace = crate::compile::ir::backtrace::Backtrace;
240
241 fn preferred_tick(&self) -> Option<Tick<L>> {
242 Some(self.collection.location().tick.clone())
243 }
244
245 fn get_location(&self) -> &L {
246 panic!("Atomic location has no accessible inner location")
247 }
248
249 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
250 assert_eq!(
251 self.collection.location().tick.id(),
252 tick.id(),
253 "Mismatched tick for atomic slicing"
254 );
255
256 let out = self.collection.batch_atomic(self.nondet);
257 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
258 out
259 }
260}
261
262impl<'a, T, L: Location<'a> + NoTick> Slicable<'a, L>
263 for Atomic<crate::live_collections::Singleton<T, crate::location::Atomic<L>, Unbounded>>
264{
265 type Slice = crate::live_collections::Singleton<T, Tick<L>, Bounded>;
266 type Backtrace = crate::compile::ir::backtrace::Backtrace;
267
268 fn preferred_tick(&self) -> Option<Tick<L>> {
269 Some(self.collection.location().tick.clone())
270 }
271
272 fn get_location(&self) -> &L {
273 panic!("Atomic location has no accessible inner location")
274 }
275
276 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
277 assert_eq!(
278 self.collection.location().tick.id(),
279 tick.id(),
280 "Mismatched tick for atomic slicing"
281 );
282
283 let out = self.collection.snapshot_atomic(self.nondet);
284 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
285 out
286 }
287}
288
289impl<'a, T, L: Location<'a> + NoTick> Slicable<'a, L>
290 for Atomic<crate::live_collections::Optional<T, crate::location::Atomic<L>, Unbounded>>
291{
292 type Slice = crate::live_collections::Optional<T, Tick<L>, Bounded>;
293 type Backtrace = crate::compile::ir::backtrace::Backtrace;
294
295 fn preferred_tick(&self) -> Option<Tick<L>> {
296 Some(self.collection.location().tick.clone())
297 }
298
299 fn get_location(&self) -> &L {
300 panic!("Atomic location has no accessible inner location")
301 }
302
303 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
304 assert_eq!(
305 self.collection.location().tick.id(),
306 tick.id(),
307 "Mismatched tick for atomic slicing"
308 );
309
310 let out = self.collection.snapshot_atomic(self.nondet);
311 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
312 out
313 }
314}
315
316impl<'a, K, V, L: Location<'a> + NoTick, O: Ordering, R: Retries> Slicable<'a, L>
317 for Atomic<
318 crate::live_collections::KeyedStream<K, V, crate::location::Atomic<L>, Unbounded, O, R>,
319 >
320{
321 type Slice = crate::live_collections::KeyedStream<K, V, Tick<L>, Bounded, O, R>;
322 type Backtrace = crate::compile::ir::backtrace::Backtrace;
323
324 fn preferred_tick(&self) -> Option<Tick<L>> {
325 Some(self.collection.location().tick.clone())
326 }
327
328 fn get_location(&self) -> &L {
329 panic!("Atomic location has no accessible inner location")
330 }
331
332 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
333 assert_eq!(
334 self.collection.location().tick.id(),
335 tick.id(),
336 "Mismatched tick for atomic slicing"
337 );
338
339 let out = self.collection.batch_atomic(self.nondet);
340 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
341 out
342 }
343}
344
345impl<'a, K, V, L: Location<'a> + NoTick> Slicable<'a, L>
346 for Atomic<crate::live_collections::KeyedSingleton<K, V, crate::location::Atomic<L>, Unbounded>>
347{
348 type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L>, Bounded>;
349 type Backtrace = crate::compile::ir::backtrace::Backtrace;
350
351 fn preferred_tick(&self) -> Option<Tick<L>> {
352 Some(self.collection.location().tick.clone())
353 }
354
355 fn get_location(&self) -> &L {
356 panic!("Atomic location has no accessible inner location")
357 }
358
359 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
360 assert_eq!(
361 self.collection.location().tick.id(),
362 tick.id(),
363 "Mismatched tick for atomic slicing"
364 );
365
366 let out = self.collection.snapshot_atomic(self.nondet);
367 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
368 out
369 }
370}
371
372impl<'a, K, V, L: Location<'a> + NoTick> Slicable<'a, L>
373 for Atomic<
374 crate::live_collections::KeyedSingleton<K, V, crate::location::Atomic<L>, BoundedValue>,
375 >
376{
377 type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L>, Bounded>;
378 type Backtrace = crate::compile::ir::backtrace::Backtrace;
379
380 fn preferred_tick(&self) -> Option<Tick<L>> {
381 Some(self.collection.location().tick.clone())
382 }
383
384 fn get_location(&self) -> &L {
385 panic!("Atomic location has no accessible inner location")
386 }
387
388 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
389 assert_eq!(
390 self.collection.location().tick.id(),
391 tick.id(),
392 "Mismatched tick for atomic slicing"
393 );
394
395 let out = self.collection.batch_atomic(self.nondet);
396 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
397 out
398 }
399}