1#[cfg(stageleft_runtime)]
7use std::marker::PhantomData;
8
9use super::Slicable;
10#[cfg(stageleft_runtime)]
11use crate::forward_handle::{CycleCollection, CycleCollectionWithInitial};
12use crate::forward_handle::{TickCycle, TickCycleHandle};
13use crate::live_collections::boundedness::{Bounded, Boundedness, Unbounded};
14use crate::live_collections::keyed_singleton::{BoundedValue, KeyedSingletonBound};
15use crate::live_collections::singleton::SingletonBound;
16use crate::live_collections::stream::{Ordering, Retries};
17use crate::location::Location;
18use crate::location::tick::{DeferTick, Tick};
19use crate::nondet::NonDet;
20
21pub struct Default<T> {
25 pub(crate) collection: T,
26 pub(crate) nondet: NonDet,
27}
28
29impl<T> Default<T> {
30 pub fn new(collection: T, nondet: NonDet) -> Self {
32 Self { collection, nondet }
33 }
34}
35
36#[doc(hidden)]
38pub fn default<T>(t: T, nondet: NonDet) -> Default<T> {
39 Default::new(t, nondet)
40}
41
42pub struct Atomic<T> {
46 pub(crate) collection: T,
47 pub(crate) nondet: NonDet,
48}
49
50impl<T> Atomic<T> {
51 pub fn new(collection: T, nondet: NonDet) -> Self {
53 Self { collection, nondet }
54 }
55}
56
57pub fn atomic<T>(t: T, nondet: NonDet) -> Atomic<T> {
59 Atomic::new(t, nondet)
60}
61
62#[cfg(stageleft_runtime)]
75pub fn state<'t, S, L>(tick: &'t Tick<L>) -> StateBuilder<'t, S, L> {
76 StateBuilder {
77 tick,
78 _phantom: PhantomData,
79 }
80}
81
82#[cfg(stageleft_runtime)]
84pub struct StateBuilder<'t, S, L> {
85 tick: &'t Tick<L>,
86 _phantom: PhantomData<fn() -> S>,
87}
88
89#[cfg(stageleft_runtime)]
90impl<'t, 'a, S, L: Location<'a>> StateBuilder<'t, S, L> {
91 #[expect(
99 private_bounds,
100 reason = "only Hydro collections can implement CycleCollectionWithInitial"
101 )]
102 pub fn build(self, initial_fn: impl FnOnce(&'t Tick<L>) -> S) -> (TickCycleHandle<'a, S>, S)
103 where
104 S: CycleCollectionWithInitial<'a, TickCycle, Location = Tick<L::DropConsistency>>,
105 {
106 let initial = initial_fn(self.tick);
107 initial.location().clone().cycle_with_initial(initial)
108 }
109}
110
111#[cfg(stageleft_runtime)]
119pub fn state_null<'t, S, L>(tick: &'t Tick<L>) -> StateNullBuilder<'t, S, L> {
120 StateNullBuilder {
121 tick,
122 _phantom: PhantomData,
123 }
124}
125
126#[cfg(stageleft_runtime)]
128pub struct StateNullBuilder<'t, S, L> {
129 tick: &'t Tick<L>,
130 _phantom: PhantomData<fn() -> S>,
131}
132
133#[cfg(stageleft_runtime)]
134impl<'t, 'a, S, L: Location<'a>> StateNullBuilder<'t, S, L> {
135 #[expect(
137 private_bounds,
138 reason = "only Hydro collections can implement CycleCollection"
139 )]
140 pub fn build(self) -> (TickCycleHandle<'a, S>, S)
141 where
142 S: CycleCollection<'a, TickCycle, Location = Tick<L::DropConsistency>> + DeferTick,
143 {
144 self.tick.cycle::<S, _>()
145 }
146}
147
148impl<'a, T, L: Location<'a>, B: Boundedness, O: Ordering, R: Retries>
156 Slicable<'a, L::DropConsistency> for Default<crate::live_collections::Stream<T, L, B, O, R>>
157{
158 type Slice = crate::live_collections::Stream<T, Tick<L::DropConsistency>, Bounded, O, R>;
159 type Backtrace = crate::compile::ir::backtrace::Backtrace;
160
161 fn get_location(&self) -> L::DropConsistency {
162 self.collection.location().drop_consistency()
163 }
164 fn slice(self, tick: &Tick<L::DropConsistency>, backtrace: Self::Backtrace) -> Self::Slice {
165 let out = self.collection.batch(tick, self.nondet);
166 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
167 out
168 }
169}
170
171impl<'a, T, L: Location<'a>, B: SingletonBound> Slicable<'a, L::DropConsistency>
172 for Default<crate::live_collections::Singleton<T, L, B>>
173{
174 type Slice = crate::live_collections::Singleton<T, Tick<L::DropConsistency>, Bounded>;
175 type Backtrace = crate::compile::ir::backtrace::Backtrace;
176
177 fn get_location(&self) -> L::DropConsistency {
178 self.collection.location().drop_consistency()
179 }
180 fn slice(self, tick: &Tick<L::DropConsistency>, backtrace: Self::Backtrace) -> Self::Slice {
181 let out = self.collection.snapshot(tick, self.nondet);
182 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
183 out
184 }
185}
186
187impl<'a, T, L: Location<'a>, B: Boundedness> Slicable<'a, L::DropConsistency>
188 for Default<crate::live_collections::Optional<T, L, B>>
189{
190 type Slice = crate::live_collections::Optional<T, Tick<L::DropConsistency>, Bounded>;
191 type Backtrace = crate::compile::ir::backtrace::Backtrace;
192
193 fn get_location(&self) -> L::DropConsistency {
194 self.collection.location().drop_consistency()
195 }
196 fn slice(self, tick: &Tick<L::DropConsistency>, backtrace: Self::Backtrace) -> Self::Slice {
197 let out = self.collection.snapshot(tick, self.nondet);
198 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
199 out
200 }
201}
202
203impl<'a, K, V, L: Location<'a>, B: Boundedness, O: Ordering, R: Retries>
204 Slicable<'a, L::DropConsistency>
205 for Default<crate::live_collections::KeyedStream<K, V, L, B, O, R>>
206{
207 type Slice =
208 crate::live_collections::KeyedStream<K, V, Tick<L::DropConsistency>, Bounded, O, R>;
209 type Backtrace = crate::compile::ir::backtrace::Backtrace;
210
211 fn get_location(&self) -> L::DropConsistency {
212 self.collection.location().drop_consistency()
213 }
214 fn slice(self, tick: &Tick<L::DropConsistency>, backtrace: Self::Backtrace) -> Self::Slice {
215 let out = self.collection.batch(tick, self.nondet);
216 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
217 out
218 }
219}
220
221impl<'a, K, V, L: Location<'a>, B: KeyedSingletonBound<ValueBound = Unbounded>>
222 Slicable<'a, L::DropConsistency>
223 for Default<crate::live_collections::KeyedSingleton<K, V, L, B>>
224{
225 type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L::DropConsistency>, Bounded>;
226 type Backtrace = crate::compile::ir::backtrace::Backtrace;
227
228 fn get_location(&self) -> L::DropConsistency {
229 self.collection.location().drop_consistency()
230 }
231 fn slice(self, tick: &Tick<L::DropConsistency>, backtrace: Self::Backtrace) -> Self::Slice {
232 let out = self.collection.snapshot(tick, self.nondet);
233 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
234 out
235 }
236}
237
238impl<'a, K, V, L: Location<'a>> Slicable<'a, L::DropConsistency>
239 for Default<crate::live_collections::KeyedSingleton<K, V, L, BoundedValue>>
240{
241 type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L::DropConsistency>, Bounded>;
242 type Backtrace = crate::compile::ir::backtrace::Backtrace;
243
244 fn get_location(&self) -> L::DropConsistency {
245 self.collection.location().drop_consistency()
246 }
247 fn slice(self, tick: &Tick<L::DropConsistency>, backtrace: Self::Backtrace) -> Self::Slice {
248 let out = self.collection.batch(tick, self.nondet);
249 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
250 out
251 }
252}
253
254impl<'a, T, L: Location<'a>, B: Boundedness, O: Ordering, R: Retries>
259 Slicable<'a, L::DropConsistency>
260 for Atomic<crate::live_collections::Stream<T, crate::location::Atomic<L>, B, O, R>>
261{
262 type Slice = crate::live_collections::Stream<T, Tick<L::DropConsistency>, Bounded, O, R>;
263 type Backtrace = crate::compile::ir::backtrace::Backtrace;
264 fn get_location(&self) -> L::DropConsistency {
265 self.collection.location().tick.l.drop_consistency()
266 }
267
268 fn slice(self, tick: &Tick<L::DropConsistency>, backtrace: Self::Backtrace) -> Self::Slice {
269 let out = self.collection.batch_atomic(tick, self.nondet);
270 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
271 out
272 }
273}
274
275impl<'a, T, L: Location<'a>, B: SingletonBound> Slicable<'a, L::DropConsistency>
276 for Atomic<crate::live_collections::Singleton<T, crate::location::Atomic<L>, B>>
277{
278 type Slice = crate::live_collections::Singleton<T, Tick<L::DropConsistency>, Bounded>;
279 type Backtrace = crate::compile::ir::backtrace::Backtrace;
280 fn get_location(&self) -> L::DropConsistency {
281 self.collection.location().tick.l.drop_consistency()
282 }
283
284 fn slice(self, tick: &Tick<L::DropConsistency>, backtrace: Self::Backtrace) -> Self::Slice {
285 let out = self.collection.snapshot_atomic(tick, self.nondet);
286 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
287 out
288 }
289}
290
291impl<'a, T, L: Location<'a>, B: Boundedness> Slicable<'a, L::DropConsistency>
292 for Atomic<crate::live_collections::Optional<T, crate::location::Atomic<L>, B>>
293{
294 type Slice = crate::live_collections::Optional<T, Tick<L::DropConsistency>, Bounded>;
295 type Backtrace = crate::compile::ir::backtrace::Backtrace;
296 fn get_location(&self) -> L::DropConsistency {
297 self.collection.location().tick.l.drop_consistency()
298 }
299
300 fn slice(self, tick: &Tick<L::DropConsistency>, backtrace: Self::Backtrace) -> Self::Slice {
301 let out = self.collection.snapshot_atomic(tick, self.nondet);
302 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
303 out
304 }
305}
306
307impl<'a, K, V, L: Location<'a>, B: Boundedness, O: Ordering, R: Retries>
308 Slicable<'a, L::DropConsistency>
309 for Atomic<crate::live_collections::KeyedStream<K, V, crate::location::Atomic<L>, B, O, R>>
310{
311 type Slice =
312 crate::live_collections::KeyedStream<K, V, Tick<L::DropConsistency>, Bounded, O, R>;
313 type Backtrace = crate::compile::ir::backtrace::Backtrace;
314 fn get_location(&self) -> L::DropConsistency {
315 self.collection.location().tick.l.drop_consistency()
316 }
317
318 fn slice(self, tick: &Tick<L::DropConsistency>, backtrace: Self::Backtrace) -> Self::Slice {
319 let out = self.collection.batch_atomic(tick, self.nondet);
320 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
321 out
322 }
323}
324
325impl<'a, K, V, L: Location<'a>, B: KeyedSingletonBound<ValueBound = Unbounded>>
326 Slicable<'a, L::DropConsistency>
327 for Atomic<crate::live_collections::KeyedSingleton<K, V, crate::location::Atomic<L>, B>>
328{
329 type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L::DropConsistency>, Bounded>;
330 type Backtrace = crate::compile::ir::backtrace::Backtrace;
331 fn get_location(&self) -> L::DropConsistency {
332 self.collection.location().tick.l.drop_consistency()
333 }
334
335 fn slice(self, tick: &Tick<L::DropConsistency>, backtrace: Self::Backtrace) -> Self::Slice {
336 let out = self.collection.snapshot_atomic(tick, self.nondet);
337 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
338 out
339 }
340}
341
342impl<'a, K, V, L: Location<'a>> Slicable<'a, L::DropConsistency>
343 for Atomic<
344 crate::live_collections::KeyedSingleton<K, V, crate::location::Atomic<L>, BoundedValue>,
345 >
346{
347 type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L::DropConsistency>, Bounded>;
348 type Backtrace = crate::compile::ir::backtrace::Backtrace;
349 fn get_location(&self) -> L::DropConsistency {
350 self.collection.location().tick.l.drop_consistency()
351 }
352
353 fn slice(self, tick: &Tick<L::DropConsistency>, backtrace: Self::Backtrace) -> Self::Slice {
354 let out = self.collection.batch_atomic(tick, self.nondet);
355 out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
356 out
357 }
358}