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::Location;
use crate::location::tick::{DeferTick, Tick};
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::DropConsistency>>,
L: Location<'a>,
>(
tick: &Tick<L>,
initial_fn: impl FnOnce(&Tick<L>) -> S,
) -> (TickCycleHandle<'a, S>, S) {
let initial = initial_fn(tick);
initial.location().clone().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::DropConsistency>> + DeferTick,
L: Location<'a>,
>(
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::DropConsistency> for Default<crate::live_collections::Stream<T, L, B, O, R>>
{
type Slice = crate::live_collections::Stream<T, Tick<L::DropConsistency>, Bounded, O, R>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> L::DropConsistency {
self.collection.location().drop_consistency()
}
fn slice(self, tick: &Tick<L::DropConsistency>, 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::DropConsistency>
for Default<crate::live_collections::Singleton<T, L, B>>
{
type Slice = crate::live_collections::Singleton<T, Tick<L::DropConsistency>, Bounded>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> L::DropConsistency {
self.collection.location().drop_consistency()
}
fn slice(self, tick: &Tick<L::DropConsistency>, 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::DropConsistency>
for Default<crate::live_collections::Optional<T, L, B>>
{
type Slice = crate::live_collections::Optional<T, Tick<L::DropConsistency>, Bounded>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> L::DropConsistency {
self.collection.location().drop_consistency()
}
fn slice(self, tick: &Tick<L::DropConsistency>, 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::DropConsistency>
for Default<crate::live_collections::KeyedStream<K, V, L, B, O, R>>
{
type Slice =
crate::live_collections::KeyedStream<K, V, Tick<L::DropConsistency>, Bounded, O, R>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> L::DropConsistency {
self.collection.location().drop_consistency()
}
fn slice(self, tick: &Tick<L::DropConsistency>, 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::DropConsistency>
for Default<crate::live_collections::KeyedSingleton<K, V, L, B>>
{
type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L::DropConsistency>, Bounded>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> L::DropConsistency {
self.collection.location().drop_consistency()
}
fn slice(self, tick: &Tick<L::DropConsistency>, 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>> Slicable<'a, L::DropConsistency>
for Default<crate::live_collections::KeyedSingleton<K, V, L, BoundedValue>>
{
type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L::DropConsistency>, Bounded>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> L::DropConsistency {
self.collection.location().drop_consistency()
}
fn slice(self, tick: &Tick<L::DropConsistency>, 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: Boundedness, O: Ordering, R: Retries>
Slicable<'a, L::DropConsistency>
for Atomic<crate::live_collections::Stream<T, crate::location::Atomic<L>, B, O, R>>
{
type Slice = crate::live_collections::Stream<T, Tick<L::DropConsistency>, Bounded, O, R>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> L::DropConsistency {
self.collection.location().tick.l.drop_consistency()
}
fn slice(self, tick: &Tick<L::DropConsistency>, 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>, B: SingletonBound> Slicable<'a, L::DropConsistency>
for Atomic<crate::live_collections::Singleton<T, crate::location::Atomic<L>, B>>
{
type Slice = crate::live_collections::Singleton<T, Tick<L::DropConsistency>, Bounded>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> L::DropConsistency {
self.collection.location().tick.l.drop_consistency()
}
fn slice(self, tick: &Tick<L::DropConsistency>, 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>, B: Boundedness> Slicable<'a, L::DropConsistency>
for Atomic<crate::live_collections::Optional<T, crate::location::Atomic<L>, B>>
{
type Slice = crate::live_collections::Optional<T, Tick<L::DropConsistency>, Bounded>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> L::DropConsistency {
self.collection.location().tick.l.drop_consistency()
}
fn slice(self, tick: &Tick<L::DropConsistency>, 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>, B: Boundedness, O: Ordering, R: Retries>
Slicable<'a, L::DropConsistency>
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::DropConsistency>, Bounded, O, R>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> L::DropConsistency {
self.collection.location().tick.l.drop_consistency()
}
fn slice(self, tick: &Tick<L::DropConsistency>, 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>, B: KeyedSingletonBound<ValueBound = Unbounded>>
Slicable<'a, L::DropConsistency>
for Atomic<crate::live_collections::KeyedSingleton<K, V, crate::location::Atomic<L>, B>>
{
type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L::DropConsistency>, Bounded>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> L::DropConsistency {
self.collection.location().tick.l.drop_consistency()
}
fn slice(self, tick: &Tick<L::DropConsistency>, 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>> Slicable<'a, L::DropConsistency>
for Atomic<
crate::live_collections::KeyedSingleton<K, V, crate::location::Atomic<L>, BoundedValue>,
>
{
type Slice = crate::live_collections::KeyedSingleton<K, V, Tick<L::DropConsistency>, Bounded>;
type Backtrace = crate::compile::ir::backtrace::Backtrace;
fn get_location(&self) -> L::DropConsistency {
self.collection.location().tick.l.drop_consistency()
}
fn slice(self, tick: &Tick<L::DropConsistency>, 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
}
}