use super::{indexation::Index, CubeContext, CubeType, Init};
use crate::unexpanded;
use std::{cell::RefCell, rc::Rc};
pub struct Sequence<T: CubeType> {
values: Vec<T>,
}
impl<T: CubeType> Default for Sequence<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: CubeType> Sequence<T> {
pub fn new() -> Self {
Self { values: Vec::new() }
}
pub fn push(&mut self, value: T) {
self.values.push(value);
}
#[allow(unused_variables, clippy::should_implement_trait)]
pub fn index<I: Index>(&self, index: I) -> &T {
unexpanded!();
}
pub fn __expand_new(_context: &mut CubeContext) -> SequenceExpand<T> {
SequenceExpand {
values: Rc::new(RefCell::new(Vec::new())),
}
}
pub fn __expand_push(
context: &mut CubeContext,
expand: &mut SequenceExpand<T>,
value: T::ExpandType,
) {
expand.__expand_push_method(context, value)
}
pub fn __expand_index<I: Index>(
context: &mut CubeContext,
expand: SequenceExpand<T>,
index: I,
) -> T::ExpandType {
expand.__expand_index_method(context, index)
}
}
pub struct SequenceExpand<T: CubeType> {
values: Rc<RefCell<Vec<T::ExpandType>>>,
}
impl<T: CubeType> Init for SequenceExpand<T> {
fn init(self, _context: &mut crate::prelude::CubeContext) -> Self {
self
}
}
impl<T: CubeType> Clone for SequenceExpand<T> {
fn clone(&self) -> Self {
Self {
values: self.values.clone(),
}
}
}
impl<T: CubeType> IntoIterator for Sequence<T> {
type Item = T;
type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.values.into_iter()
}
}
impl<T: CubeType> IntoIterator for SequenceExpand<T> {
type Item = T::ExpandType;
type IntoIter = <Vec<T::ExpandType> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.values.take().into_iter()
}
}
impl<T: CubeType> CubeType for Sequence<T> {
type ExpandType = SequenceExpand<T>;
}
impl<T: CubeType> SequenceExpand<T> {
pub fn __expand_push_method(&mut self, _context: &mut CubeContext, value: T::ExpandType) {
self.values.borrow_mut().push(value);
}
pub fn __expand_index_method<I: Index>(
&self,
_context: &mut CubeContext,
index: I,
) -> T::ExpandType {
let value = index.value();
let index = match value {
crate::ir::Variable::ConstantScalar(value) => match value {
crate::ir::ConstantScalarValue::Int(val, _) => val as usize,
crate::ir::ConstantScalarValue::UInt(val) => val as usize,
_ => panic!("Only integer types are supported"),
},
_ => panic!("Only constant are supported"),
};
self.values.borrow()[index].clone()
}
}