cubecl_core/frontend/container/sequence/
base.rs1use alloc::vec::Vec;
2use cubecl_ir::Scope;
3use serde::{Deserialize, Serialize};
4
5use crate::prelude::*;
6use core::ops::{Deref, Index, IndexMut};
7
8#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord)]
16pub struct Sequence<T: CubeType> {
17 values: Vec<T>,
18}
19
20impl<T: CubeType> Default for Sequence<T> {
21 fn default() -> Self {
22 Self::new()
23 }
24}
25
26impl<T: CubeType> IntoExpand for SequenceExpand<T> {
27 type Expand = Self;
28
29 fn into_expand(self, _scope: &Scope) -> Self::Expand {
30 self
31 }
32}
33
34impl<T: CubeType> IntoMut for Sequence<T> {
35 fn into_mut(self, _scope: &Scope) -> Self {
36 self
37 }
38}
39impl<T: CubeType> CubeDebug for Sequence<T> {}
40
41impl<T: CubeType<ExpandType: Clone>> DerefExpand for SequenceExpand<T> {
42 type Target = Self;
43
44 fn __expand_deref_method(&self, _: &Scope) -> Self::Target {
45 self.clone()
46 }
47}
48
49impl<T: CubeType> Sequence<T> {
50 pub fn reverse(&mut self) {
51 self.values.reverse();
52 }
53
54 pub fn reversed(&self) -> Sequence<T>
55 where
56 T: Clone,
57 {
58 Self {
59 values: self.values.iter().cloned().rev().collect(),
60 }
61 }
62}
63
64impl<T: CubeType> Sequence<T> {
65 pub fn new() -> Self {
67 Self { values: Vec::new() }
68 }
69
70 pub fn push(&mut self, value: T) {
72 self.values.push(value);
73 }
74
75 #[allow(clippy::len_without_is_empty)]
77 pub fn len(&self) -> usize {
78 self.values.len()
79 }
80
81 #[allow(clippy::should_implement_trait)]
83 pub fn index(&self, index: usize) -> &T {
84 self.values.get(index).unwrap()
85 }
86
87 #[allow(clippy::should_implement_trait)]
89 pub fn index_mut(&mut self, index: usize) -> &mut T {
90 self.values.get_mut(index).unwrap()
91 }
92
93 pub fn __expand_new(_scope: &Scope) -> SequenceExpand<T> {
95 SequenceExpand { values: Vec::new() }
96 }
97
98 #[allow(clippy::should_implement_trait)]
100 pub fn insert(&mut self, index: usize, value: T) {
101 *self.index_mut(index) = value;
102 }
103
104 pub fn __expand_push(scope: &Scope, expand: &mut SequenceExpand<T>, value: T::ExpandType) {
106 expand.__expand_push_method(scope, value)
107 }
108
109 pub fn __expand_index<'a>(
111 scope: &Scope,
112 expand: &'a SequenceExpand<T>,
113 index: NativeExpand<usize>,
114 ) -> &'a T::ExpandType {
115 expand.__expand_index_method(scope, index)
116 }
117
118 pub fn __expand_index_mut<'a>(
120 scope: &Scope,
121 expand: &'a mut SequenceExpand<T>,
122 index: NativeExpand<usize>,
123 ) -> &'a mut T::ExpandType {
124 expand.__expand_index_mut_method(scope, index)
125 }
126}
127
128impl<T: CubeType> AsRefExpand for SequenceExpand<T> {
129 fn __expand_ref_method(&self, _: &Scope) -> &Self {
130 self
131 }
132}
133impl<T: CubeType> AsMutExpand for SequenceExpand<T> {
134 fn __expand_ref_mut_method(&mut self, _: &Scope) -> &mut Self {
135 self
136 }
137}
138
139impl<T: CubeType> Index<usize> for Sequence<T> {
140 type Output = T;
141
142 fn index(&self, index: usize) -> &Self::Output {
143 self.values.index(index)
144 }
145}
146
147impl<T: CubeType> IndexMut<usize> for Sequence<T> {
148 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
149 self.values.index_mut(index)
150 }
151}
152
153impl<T: CubeType> Deref for Sequence<T> {
154 type Target = [T];
155
156 fn deref(&self) -> &Self::Target {
157 &self.values
158 }
159}
160
161impl<T: CubeType> IndexExpand<NativeExpand<usize>> for SequenceExpand<T> {
162 type Output = T::ExpandType;
163
164 fn __expand_index_method(&self, scope: &Scope, index: NativeExpand<usize>) -> &Self::Output {
165 self.__expand_index_method(scope, index)
166 }
167}
168
169impl<T: CubeType> IndexMutExpand<NativeExpand<usize>> for SequenceExpand<T> {
170 fn __expand_index_mut_method(
171 &mut self,
172 scope: &Scope,
173 index: NativeExpand<usize>,
174 ) -> &mut T::ExpandType {
175 self.__expand_index_mut_method(scope, index)
176 }
177}
178
179#[derive(Debug)]
181pub struct SequenceExpand<T: CubeType> {
182 pub(super) values: Vec<T::ExpandType>,
185}
186
187impl<T: CubeType> Iterable for SequenceExpand<T> {
188 type Item = T::ExpandType;
189
190 fn expand(self, scope: &Scope, func: impl FnMut(&Scope, <T as CubeType>::ExpandType)) {
191 self.expand_unroll(scope, func);
192 }
193
194 fn expand_unroll(
195 self,
196 scope: &Scope,
197 mut func: impl FnMut(&Scope, <T as CubeType>::ExpandType),
198 ) {
199 for elem in self {
200 func(scope, elem);
201 }
202 }
203
204 fn const_len(&self) -> Option<usize> {
205 Some(self.values.len())
206 }
207}
208
209impl<T: CubeType> IntoMut for SequenceExpand<T> {
210 fn into_mut(self, scope: &Scope) -> Self {
211 Self {
212 values: self
213 .values
214 .into_iter()
215 .map(|v| IntoMut::into_mut(v, scope))
216 .collect(),
217 }
218 }
219}
220impl<T: CubeType> CubeDebug for SequenceExpand<T> {}
221
222impl<T: CubeType<ExpandType: Clone>> Clone for SequenceExpand<T> {
223 fn clone(&self) -> Self {
224 Self {
225 values: self.values.clone(),
226 }
227 }
228}
229impl<T: CubeType> ExpandTypeClone for SequenceExpand<T> {
230 fn clone_unchecked(&self) -> Self {
231 Self {
232 values: self.values.iter().map(|it| it.clone_unchecked()).collect(),
233 }
234 }
235}
236
237impl<T: CubeType> IntoIterator for Sequence<T> {
238 type Item = T;
239
240 type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
241
242 fn into_iter(self) -> Self::IntoIter {
243 self.values.into_iter()
244 }
245}
246
247impl<T: CubeType> IntoIterator for SequenceExpand<T> {
248 type Item = T::ExpandType;
249
250 type IntoIter = <Vec<T::ExpandType> as IntoIterator>::IntoIter;
251
252 fn into_iter(self) -> Self::IntoIter {
253 self.values.into_iter()
254 }
255}
256
257impl<T: CubeType<ExpandType: Clone>> SequenceExpand<T> {
258 pub fn iter_cloned(&self) -> impl Iterator<Item = T::ExpandType> {
260 self.values.clone().into_iter()
261 }
262}
263
264impl<T: CubeType> CubeType for Sequence<T> {
265 type ExpandType = SequenceExpand<T>;
266}
267
268impl<T: CubeType> SequenceExpand<T> {
269 #[allow(clippy::len_without_is_empty)]
270 pub fn len(&self) -> usize {
271 self.values.len()
272 }
273 pub fn __expand_push_method(&mut self, _scope: &Scope, value: T::ExpandType) {
275 self.values.push(value);
276 }
277
278 pub fn __expand_insert_method(&mut self, _scope: &Scope, index: usize, value: T::ExpandType) {
280 if self.values.len() == index {
281 self.values.push(value);
282 } else {
283 self.values[index] = value;
284 }
285 }
286
287 pub fn __expand_index_method(
289 &self,
290 _scope: &Scope,
291 index: NativeExpand<usize>,
292 ) -> &T::ExpandType {
293 let index = index.constant().expect("Index must be constant").as_usize();
294 &self.values[index]
295 }
296
297 pub fn __expand_index_mut_method(
299 &mut self,
300 _scope: &Scope,
301 index: NativeExpand<usize>,
302 ) -> &mut T::ExpandType {
303 let index = index.constant().expect("Index must be constant").as_usize();
304 &mut self.values[index]
305 }
306
307 pub fn __expand_len_method(&self, _scope: &Scope) -> usize {
308 self.values.len()
309 }
310
311 pub fn __expand_reverse_method(&mut self, _scope: &Scope) {
312 self.values.reverse();
313 }
314
315 pub fn __expand_reversed_method(&self, _scope: &Scope) -> Self
316 where
317 T::ExpandType: Clone,
318 {
319 Self {
320 values: self.values.iter().cloned().rev().collect(),
321 }
322 }
323
324 pub fn __expand_clone_method(&self, _scope: &Scope) -> Self
325 where
326 T::ExpandType: Clone,
327 {
328 self.clone()
329 }
330}
331
332#[macro_export]
333macro_rules! seq {
334 ($($value: expr),*) => {
335 $crate::seq![$($value,)*]
336 };
337 ($($value: expr,)*) => {{
338 let mut seq = Sequence::new();
339 $(seq.push($value);)*
340 seq
341 }}
342}
343
344#[macro_export]
345macro_rules! __expand_seq {
346 ($scope: expr, $($value: expr),*) => {
347 $crate::__expand_seq![$scope, $($value,)*]
348 };
349 ($scope: expr, $($value: expr,)*) => {{
350 let mut seq = Sequence::__expand_new($scope);
351 $(seq.__expand_push_method($scope, $value.into());)*
352 seq
353 }}
354}