use super::Slicable;
#[cfg(stageleft_runtime)]
use crate::forward_handle::{CycleCollection, CycleCollectionWithInitial};
use crate::forward_handle::{TickCycle, TickCycleHandle};
use crate::live_collections::boundedness::{Bounded, Boundedness, Unbounded};
use crate::live_collections::keyed_singleton::{BoundedValue, KeyedSingletonBound};
use crate::live_collections::singleton::SingletonBound;
use crate::live_collections::stream::{Ordering, Retries};
use crate::location::tick::{DeferTick, Tick};
use crate::location::{Location, NoTick};
use crate::nondet::NonDet;
pub struct Default<T> {
pub(crate) collection: T,
pub(crate) nondet: NonDet,
}
impl<T> Default<T> {
pub fn new(collection: T, nondet: NonDet) -> Self {
Self { collection, nondet }
}
}
#[doc(hidden)]
pub fn default<T>(t: T, nondet: NonDet) -> Default<T> {
Default::new(t, nondet)
}
pub struct Atomic<T> {
pub(crate) collection: T,
pub(crate) nondet: NonDet,
}
impl<T> Atomic<T> {
pub fn new(collection: T, nondet: NonDet) -> Self {
Self { collection, nondet }
}
}
pub fn atomic<T>(t: T, nondet: NonDet) -> Atomic<T> {
Atomic::new(t, nondet)
}
#[cfg(stageleft_runtime)]
#[expect(
private_bounds,
reason = "only Hydro collections can implement CycleCollectionWithInitial"
)]
pub fn state<
'a,
S: CycleCollectionWithInitial<'a, TickCycle, Location = Tick<L>>,
L: Location<'a>,
>(
tick: &Tick<L>,
initial_fn: impl FnOnce(&Tick<L>) -> S,
) -> (TickCycleHandle<'a, S>, S) {
let initial = initial_fn(tick);
tick.cycle_with_initial(initial)
}
#[cfg(stageleft_runtime)]
#[expect(
private_bounds,
reason = "only Hydro collections can implement CycleCollection"
)]
pub fn state_null<
'a,
S: CycleCollection<'a, TickCycle, Location = Tick<L>> + DeferTick,
L: Location<'a> + NoTick,
>(
tick: &Tick<L>,
) -> (TickCycleHandle<'a, S>, S) {
tick.cycle::<S>()
}
impl<'a, T, L: Location<'a>, B: Boundedness, O: Ordering, R: Retries> Slicable<'a, L>
for Default<crate::live_collections::Stream<T, L, B, O, R>>
{
type Slice = crate::live_collections::Stream<T, Tick<L>, Bounded, O, R>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> &L {
self.collection.location()
}
fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
let out = self.collection.batch(tick, self.nondet);
out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
out
}
}
impl<'a, T, L: Location<'a>, B: SingletonBound> Slicable<'a, L>
for Default<crate::live_collections::Singleton<T, L, B>>
{
type Slice = crate::live_collections::Singleton<T, Tick<L>, Bounded>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> &L {
self.collection.location()
}
fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
let out = self.collection.snapshot(tick, self.nondet);
out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
out
}
}
impl<'a, T, L: Location<'a>, B: Boundedness> Slicable<'a, L>
for Default<crate::live_collections::Optional<T, L, B>>
{
type Slice = crate::live_collections::Optional<T, Tick<L>, Bounded>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> &L {
self.collection.location()
}
fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
let out = self.collection.snapshot(tick, self.nondet);
out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
out
}
}
impl<'a, K, V, L: Location<'a>, B: Boundedness, O: Ordering, R: Retries> Slicable<'a, L>
for Default<crate::live_collections::KeyedStream<K, V, L, B, O, R>>
{
type Slice = crate::live_collections::KeyedStream<K, V, Tick<L>, Bounded, O, R>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> &L {
self.collection.location()
}
fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
let out = self.collection.batch(tick, self.nondet);
out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
out
}
}
impl<'a, K, V, L: Location<'a>, B: KeyedSingletonBound<ValueBound = Unbounded>> Slicable<'a, L>
for Default<crate::live_collections::KeyedSingleton<K, V, L, B>>
{
type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L>, Bounded>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> &L {
self.collection.location()
}
fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
let out = self.collection.snapshot(tick, self.nondet);
out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
out
}
}
impl<'a, K, V, L: Location<'a> + NoTick> Slicable<'a, L>
for Default<crate::live_collections::KeyedSingleton<K, V, L, BoundedValue>>
{
type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L>, Bounded>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> &L {
self.collection.location()
}
fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
let out = self.collection.batch(tick, self.nondet);
out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
out
}
}
impl<'a, T, L: Location<'a> + NoTick, B: Boundedness, O: Ordering, R: Retries> Slicable<'a, L>
for Atomic<crate::live_collections::Stream<T, crate::location::Atomic<L>, B, O, R>>
{
type Slice = crate::live_collections::Stream<T, Tick<L>, Bounded, O, R>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> &L {
&self.collection.location().tick.l
}
fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
let out = self.collection.batch_atomic(tick, self.nondet);
out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
out
}
}
impl<'a, T, L: Location<'a> + NoTick, B: SingletonBound> Slicable<'a, L>
for Atomic<crate::live_collections::Singleton<T, crate::location::Atomic<L>, B>>
{
type Slice = crate::live_collections::Singleton<T, Tick<L>, Bounded>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> &L {
&self.collection.location().tick.l
}
fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
let out = self.collection.snapshot_atomic(tick, self.nondet);
out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
out
}
}
impl<'a, T, L: Location<'a> + NoTick, B: Boundedness> Slicable<'a, L>
for Atomic<crate::live_collections::Optional<T, crate::location::Atomic<L>, B>>
{
type Slice = crate::live_collections::Optional<T, Tick<L>, Bounded>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> &L {
&self.collection.location().tick.l
}
fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
let out = self.collection.snapshot_atomic(tick, self.nondet);
out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
out
}
}
impl<'a, K, V, L: Location<'a> + NoTick, B: Boundedness, O: Ordering, R: Retries> Slicable<'a, L>
for Atomic<crate::live_collections::KeyedStream<K, V, crate::location::Atomic<L>, B, O, R>>
{
type Slice = crate::live_collections::KeyedStream<K, V, Tick<L>, Bounded, O, R>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> &L {
&self.collection.location().tick.l
}
fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
let out = self.collection.batch_atomic(tick, self.nondet);
out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
out
}
}
impl<'a, K, V, L: Location<'a> + NoTick, B: KeyedSingletonBound<ValueBound = Unbounded>>
Slicable<'a, L>
for Atomic<crate::live_collections::KeyedSingleton<K, V, crate::location::Atomic<L>, B>>
{
type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L>, Bounded>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> &L {
&self.collection.location().tick.l
}
fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
let out = self.collection.snapshot_atomic(tick, self.nondet);
out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
out
}
}
impl<'a, K, V, L: Location<'a> + NoTick> Slicable<'a, L>
for Atomic<
crate::live_collections::KeyedSingleton<K, V, crate::location::Atomic<L>, BoundedValue>,
>
{
type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L>, Bounded>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> &L {
&self.collection.location().tick.l
}
fn slice(self, tick: &Tick<L>, backtrace: Self::Backtrace) -> Self::Slice {
let out = self.collection.batch_atomic(tick, self.nondet);
out.ir_node.borrow_mut().op_metadata_mut().backtrace = backtrace;
out
}
}