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, KeyedSingletonBound};
12use crate::live_collections::singleton::SingletonBound;
13use crate::live_collections::stream::{Ordering, Retries};
14use crate::location::tick::{DeferTick, Tick};
15use crate::location::{Location, NoTick};
16use crate::nondet::NonDet;
17
18pub struct Default<T> {
22 pub(crate) collection: T,
23 pub(crate) nondet: NonDet,
24}
25
26impl<T> Default<T> {
27 pub fn new(collection: T, nondet: NonDet) -> Self {
29 Self { collection, nondet }
30 }
31}
32
33#[doc(hidden)]
35pub fn default<T>(t: T, nondet: NonDet) -> Default<T> {
36 Default::new(t, nondet)
37}
38
39pub struct Atomic<T> {
43 pub(crate) collection: T,
44 pub(crate) nondet: NonDet,
45}
46
47impl<T> Atomic<T> {
48 pub fn new(collection: T, nondet: NonDet) -> Self {
50 Self { collection, nondet }
51 }
52}
53
54pub fn atomic<T>(t: T, nondet: NonDet) -> Atomic<T> {
56 Atomic::new(t, nondet)
57}
58
59#[cfg(stageleft_runtime)]
67#[expect(
68 private_bounds,
69 reason = "only Hydro collections can implement CycleCollectionWithInitial"
70)]
71pub fn state<
72 'a,
73 S: CycleCollectionWithInitial<'a, TickCycle, Location = Tick<L>>,
74 L: Location<'a>,
75>(
76 tick: &Tick<L>,
77 initial_fn: impl FnOnce(&Tick<L>) -> S,
78) -> (TickCycleHandle<'a, S>, S) {
79 let initial = initial_fn(tick);
80 tick.cycle_with_initial(initial)
81}
82
83#[cfg(stageleft_runtime)]
88#[expect(
89 private_bounds,
90 reason = "only Hydro collections can implement CycleCollection"
91)]
92pub fn state_null<
93 'a,
94 S: CycleCollection<'a, TickCycle, Location = Tick<L>> + DeferTick,
95 L: Location<'a> + NoTick,
96>(
97 tick: &Tick<L>,
98) -> (TickCycleHandle<'a, S>, S) {
99 tick.cycle::<S>()
100}
101
102impl<'a, T, L: Location<'a>, B: Boundedness, O: Ordering, R: Retries> Slicable<'a, L>
107 for Default<crate::live_collections::Stream<T, L, B, O, R>>
108{
109 type Slice = crate::live_collections::Stream<T, Tick<L>, Bounded, O, R>;
110 type Backtrace = crate::compile::ir::backtrace::Backtrace;
111
112 fn get_location(&self) -> &L {
113 self.collection.location()
114 }
115 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
116 let out = self.collection.batch(tick, self.nondet);
117 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
118 out
119 }
120}
121
122impl<'a, T, L: Location<'a>, B: SingletonBound> Slicable<'a, L>
123 for Default<crate::live_collections::Singleton<T, L, B>>
124{
125 type Slice = crate::live_collections::Singleton<T, Tick<L>, Bounded>;
126 type Backtrace = crate::compile::ir::backtrace::Backtrace;
127
128 fn get_location(&self) -> &L {
129 self.collection.location()
130 }
131 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
132 let out = self.collection.snapshot(tick, self.nondet);
133 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
134 out
135 }
136}
137
138impl<'a, T, L: Location<'a>, B: Boundedness> Slicable<'a, L>
139 for Default<crate::live_collections::Optional<T, L, B>>
140{
141 type Slice = crate::live_collections::Optional<T, Tick<L>, Bounded>;
142 type Backtrace = crate::compile::ir::backtrace::Backtrace;
143
144 fn get_location(&self) -> &L {
145 self.collection.location()
146 }
147 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
148 let out = self.collection.snapshot(tick, self.nondet);
149 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
150 out
151 }
152}
153
154impl<'a, K, V, L: Location<'a>, B: Boundedness, O: Ordering, R: Retries> Slicable<'a, L>
155 for Default<crate::live_collections::KeyedStream<K, V, L, B, O, R>>
156{
157 type Slice = crate::live_collections::KeyedStream<K, V, Tick<L>, Bounded, O, R>;
158 type Backtrace = crate::compile::ir::backtrace::Backtrace;
159
160 fn get_location(&self) -> &L {
161 self.collection.location()
162 }
163 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
164 let out = self.collection.batch(tick, self.nondet);
165 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
166 out
167 }
168}
169
170impl<'a, K, V, L: Location<'a>, B: KeyedSingletonBound<ValueBound = Unbounded>> Slicable<'a, L>
171 for Default<crate::live_collections::KeyedSingleton<K, V, L, B>>
172{
173 type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L>, Bounded>;
174 type Backtrace = crate::compile::ir::backtrace::Backtrace;
175
176 fn get_location(&self) -> &L {
177 self.collection.location()
178 }
179 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
180 let out = self.collection.snapshot(tick, self.nondet);
181 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
182 out
183 }
184}
185
186impl<'a, K, V, L: Location<'a> + NoTick> Slicable<'a, L>
187 for Default<crate::live_collections::KeyedSingleton<K, V, L, BoundedValue>>
188{
189 type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L>, Bounded>;
190 type Backtrace = crate::compile::ir::backtrace::Backtrace;
191
192 fn get_location(&self) -> &L {
193 self.collection.location()
194 }
195 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
196 let out = self.collection.batch(tick, self.nondet);
197 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
198 out
199 }
200}
201
202impl<'a, T, L: Location<'a> + NoTick, B: Boundedness, O: Ordering, R: Retries> Slicable<'a, L>
207 for Atomic<crate::live_collections::Stream<T, crate::location::Atomic<L>, B, O, R>>
208{
209 type Slice = crate::live_collections::Stream<T, Tick<L>, Bounded, O, R>;
210 type Backtrace = crate::compile::ir::backtrace::Backtrace;
211 fn get_location(&self) -> &L {
212 &self.collection.location().tick.l
213 }
214
215 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
216 let out = self.collection.batch_atomic(tick, self.nondet);
217 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
218 out
219 }
220}
221
222impl<'a, T, L: Location<'a> + NoTick, B: SingletonBound> Slicable<'a, L>
223 for Atomic<crate::live_collections::Singleton<T, crate::location::Atomic<L>, B>>
224{
225 type Slice = crate::live_collections::Singleton<T, Tick<L>, Bounded>;
226 type Backtrace = crate::compile::ir::backtrace::Backtrace;
227 fn get_location(&self) -> &L {
228 &self.collection.location().tick.l
229 }
230
231 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
232 let out = self.collection.snapshot_atomic(tick, self.nondet);
233 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
234 out
235 }
236}
237
238impl<'a, T, L: Location<'a> + NoTick, B: Boundedness> Slicable<'a, L>
239 for Atomic<crate::live_collections::Optional<T, crate::location::Atomic<L>, B>>
240{
241 type Slice = crate::live_collections::Optional<T, Tick<L>, Bounded>;
242 type Backtrace = crate::compile::ir::backtrace::Backtrace;
243 fn get_location(&self) -> &L {
244 &self.collection.location().tick.l
245 }
246
247 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
248 let out = self.collection.snapshot_atomic(tick, self.nondet);
249 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
250 out
251 }
252}
253
254impl<'a, K, V, L: Location<'a> + NoTick, B: Boundedness, O: Ordering, R: Retries> Slicable<'a, L>
255 for Atomic<crate::live_collections::KeyedStream<K, V, crate::location::Atomic<L>, B, O, R>>
256{
257 type Slice = crate::live_collections::KeyedStream<K, V, Tick<L>, Bounded, O, R>;
258 type Backtrace = crate::compile::ir::backtrace::Backtrace;
259 fn get_location(&self) -> &L {
260 &self.collection.location().tick.l
261 }
262
263 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
264 let out = self.collection.batch_atomic(tick, self.nondet);
265 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
266 out
267 }
268}
269
270impl<'a, K, V, L: Location<'a> + NoTick, B: KeyedSingletonBound<ValueBound = Unbounded>>
271 Slicable<'a, L>
272 for Atomic<crate::live_collections::KeyedSingleton<K, V, crate::location::Atomic<L>, B>>
273{
274 type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L>, Bounded>;
275 type Backtrace = crate::compile::ir::backtrace::Backtrace;
276 fn get_location(&self) -> &L {
277 &self.collection.location().tick.l
278 }
279
280 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
281 let out = self.collection.snapshot_atomic(tick, self.nondet);
282 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
283 out
284 }
285}
286
287impl<'a, K, V, L: Location<'a> + NoTick> Slicable<'a, L>
288 for Atomic<
289 crate::live_collections::KeyedSingleton<K, V, crate::location::Atomic<L>, BoundedValue>,
290 >
291{
292 type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L>, Bounded>;
293 type Backtrace = crate::compile::ir::backtrace::Backtrace;
294 fn get_location(&self) -> &L {
295 &self.collection.location().tick.l
296 }
297
298 fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
299 let out = self.collection.batch_atomic(tick, self.nondet);
300 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
301 out
302 }
303}