mdarray/expr/
into_expr.rs1use core::fmt::{Debug, Formatter, Result};
2use core::mem::ManuallyDrop;
3use core::ptr;
4
5use crate::buffer::Buffer;
6use crate::expr::expression::Expression;
7use crate::expr::iter::Iter;
8use crate::slice::Slice;
9
10pub struct IntoExpr<T, B: Buffer<Item = ManuallyDrop<T>>> {
12 buffer: B,
13 index: usize,
14}
15
16impl<T, B: Buffer<Item = ManuallyDrop<T>>> IntoExpr<T, B> {
17 #[inline]
19 pub fn new(buffer: B) -> Self {
20 Self { buffer, index: 0 }
21 }
22}
23
24impl<T, B: Buffer<Item = ManuallyDrop<T>>> AsMut<Slice<T, B::Shape>> for IntoExpr<T, B> {
25 #[inline]
26 fn as_mut(&mut self) -> &mut Slice<T, B::Shape> {
27 debug_assert!(self.index == 0, "expression in use");
28
29 unsafe {
30 &mut *(self.buffer.as_mut_slice() as *mut Slice<ManuallyDrop<T>, B::Shape>
31 as *mut Slice<T, B::Shape>)
32 }
33 }
34}
35
36impl<T, B: Buffer<Item = ManuallyDrop<T>>> AsRef<Slice<T, B::Shape>> for IntoExpr<T, B> {
37 #[inline]
38 fn as_ref(&self) -> &Slice<T, B::Shape> {
39 debug_assert!(self.index == 0, "expression in use");
40
41 unsafe {
42 &*(self.buffer.as_slice() as *const Slice<ManuallyDrop<T>, B::Shape>
43 as *const Slice<T, B::Shape>)
44 }
45 }
46}
47
48impl<T, B: Buffer<Item = ManuallyDrop<T>> + Clone> Clone for IntoExpr<T, B> {
49 #[inline]
50 fn clone(&self) -> Self {
51 assert!(self.index == 0, "expression in use");
52
53 Self { buffer: self.buffer.clone(), index: 0 }
54 }
55
56 #[inline]
57 fn clone_from(&mut self, source: &Self) {
58 assert!(self.index == 0 && source.index == 0, "expression in use");
59
60 self.buffer.clone_from(&source.buffer);
61 }
62}
63
64impl<T: Debug, B: Buffer<Item = ManuallyDrop<T>>> Debug for IntoExpr<T, B> {
65 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
66 f.debug_tuple("IntoExpr").field(&self.as_ref()).finish()
67 }
68}
69
70impl<T, B: Buffer<Item = ManuallyDrop<T>> + Default> Default for IntoExpr<T, B> {
71 #[inline]
72 fn default() -> Self {
73 Self { buffer: Default::default(), index: 0 }
74 }
75}
76
77impl<T, B: Buffer<Item = ManuallyDrop<T>>> Drop for IntoExpr<T, B> {
78 #[inline]
79 fn drop(&mut self) {
80 unsafe {
81 let ptr = self.buffer.as_mut_slice().as_mut_ptr().add(self.index) as *mut T;
82 let len = self.buffer.as_slice().len() - self.index;
83
84 ptr::slice_from_raw_parts_mut(ptr, len).drop_in_place();
85 }
86 }
87}
88
89impl<T, B: Buffer<Item = ManuallyDrop<T>>> Expression for IntoExpr<T, B> {
90 type Shape = B::Shape;
91
92 const IS_REPEATABLE: bool = false;
93
94 #[inline]
95 fn shape(&self) -> &B::Shape {
96 self.buffer.as_slice().shape()
97 }
98
99 #[inline]
100 unsafe fn get_unchecked(&mut self, _: usize) -> T {
101 debug_assert!(self.index < self.buffer.as_slice().len(), "index out of bounds");
102
103 self.index += 1; unsafe {
106 ManuallyDrop::take(&mut *self.buffer.as_mut_slice().as_mut_ptr().add(self.index - 1))
107 }
108 }
109
110 #[inline]
111 fn inner_rank(&self) -> usize {
112 usize::MAX
113 }
114
115 #[inline]
116 unsafe fn reset_dim(&mut self, _: usize, _: usize) {}
117
118 #[inline]
119 unsafe fn step_dim(&mut self, _: usize) {}
120}
121
122impl<T, B: Buffer<Item = ManuallyDrop<T>>> IntoIterator for IntoExpr<T, B> {
123 type Item = T;
124 type IntoIter = Iter<Self>;
125
126 #[inline]
127 fn into_iter(self) -> Iter<Self> {
128 Iter::new(self)
129 }
130}