1use core::{iter, marker, mem, ops, ptr};
2
3mod impls;
4
5pub struct Stack<T: ?Sized, D: ::DataBuf> {
19 _pd: marker::PhantomData<*const T>,
20 next_ofs: usize,
23 data: D,
24}
25
26impl<T: ?Sized, D: ::DataBuf> ops::Drop for Stack<T, D> {
27 fn drop(&mut self) {
28 while !self.is_empty() {
29 self.pop();
30 }
31 }
32}
33impl<T: ?Sized, D: ::DataBuf + Default> Default for Stack<T, D> {
34 fn default() -> Self {
35 Stack::new()
36 }
37}
38
39impl<T: ?Sized, D: ::DataBuf> Stack<T, D> {
40 pub fn new() -> Self
42 where
43 D: Default,
44 {
45 Self::with_buffer(D::default())
46 }
47 pub fn with_buffer(data: D) -> Self {
49 Stack {
50 _pd: marker::PhantomData,
51 next_ofs: 0,
52 data,
53 }
54 }
55
56 pub fn is_empty(&self) -> bool {
58 self.next_ofs == 0
59 }
60
61 fn meta_words() -> usize {
62 D::round_to_words(mem::size_of::<&T>() - mem::size_of::<usize>())
63 }
64
65 #[cfg(feature = "unsize")]
73 pub fn push<U: marker::Unsize<T>>(&mut self, v: U) -> Result<(), U>
74 where
75 (U, D::Inner): crate::AlignmentValid,
76 {
77 self.push_stable(v, |p| p)
78 }
79
80 pub fn push_stable<U, F: FnOnce(&U) -> &T>(&mut self, v: U, f: F) -> Result<(), U>
88 where
89 (U, D::Inner): crate::AlignmentValid,
90 {
91 <(U, D::Inner) as crate::AlignmentValid>::check();
92
93 unsafe {
95 match self.push_inner(crate::check_fat_pointer(&v, f)) {
96 Ok(pii) => {
97 ptr::write(pii.data.as_mut_ptr() as *mut U, v);
98 Ok(())
99 }
100 Err(_) => Err(v),
101 }
102 }
103 }
104
105 unsafe fn raw_at(&self, ofs: usize) -> *mut T {
106 let dar = self.data.as_ref();
107 let meta = &dar[dar.len() - ofs..];
108 let mw = Self::meta_words();
109 let (meta, data) = meta.split_at(mw);
110 super::make_fat_ptr(data.as_ptr() as *mut (), meta)
111 }
112 unsafe fn raw_at_mut(&mut self, ofs: usize) -> *mut T {
113 let dar = self.data.as_mut();
114 let ofs = dar.len() - ofs;
115 let meta = &mut dar[ofs..];
116 let mw = Self::meta_words();
117 let (meta, data) = meta.split_at_mut(mw);
118 super::make_fat_ptr(data.as_mut_ptr() as *mut (), meta)
119 }
120 fn top_raw(&self) -> Option<*mut T> {
122 if self.next_ofs == 0 {
123 None
124 } else {
125 Some(unsafe { self.raw_at(self.next_ofs) })
127 }
128 }
129 fn top_raw_mut(&mut self) -> Option<*mut T> {
131 if self.next_ofs == 0 {
132 None
133 } else {
134 Some(unsafe { self.raw_at_mut(self.next_ofs) })
136 }
137 }
138 pub fn top(&self) -> Option<&T> {
140 self.top_raw().map(|x| unsafe { &*x })
141 }
142 pub fn top_mut(&mut self) -> Option<&mut T> {
144 self.top_raw_mut().map(|x| unsafe { &mut *x })
145 }
146 pub fn pop(&mut self) {
148 if let Some(ptr) = self.top_raw_mut() {
149 assert!(self.next_ofs > 0);
150 let words = unsafe {
152 let size = mem::size_of_val(&*ptr);
153 ptr::drop_in_place(ptr);
154 D::round_to_words(size)
155 };
156 self.next_ofs -= words + Self::meta_words();
157 }
158 }
159
160 pub fn iter(&self) -> Iter<T, D> {
171 Iter(self, self.next_ofs)
172 }
173 pub fn iter_mut(&mut self) -> IterMut<T, D> {
187 IterMut(self, self.next_ofs)
188 }
189}
190
191struct PushInnerInfo<'a, DInner> {
192 data: &'a mut crate::BufSlice<DInner>,
194 meta: &'a mut crate::BufSlice<DInner>,
196 reset_slot: &'a mut usize,
198 reset_value: usize,
199}
200impl<T: ?Sized, D: ::DataBuf> Stack<T, D> {
201
202 unsafe fn push_inner(&mut self, fat_ptr: &T) -> Result<PushInnerInfo<D::Inner>, ()> {
204 let bytes = mem::size_of_val(fat_ptr);
205 let (_data_ptr, len, v) = crate::decompose_pointer(fat_ptr);
206 self.push_inner_raw(bytes, &v[..len])
207 }
208
209 unsafe fn push_inner_raw(&mut self, bytes: usize, metadata: &[usize]) -> Result<PushInnerInfo<D::Inner>, ()> {
214 assert!( D::round_to_words(mem::size_of_val(metadata)) == Self::meta_words() );
215 let words = D::round_to_words(bytes) + Self::meta_words();
216
217 let req_space = self.next_ofs + words;
218 if req_space > self.data.as_ref().len() {
220 let old_len = self.data.as_ref().len();
221 if let Ok(_) = self.data.extend(req_space) {
222 let new_len = self.data.as_ref().len();
223 self.data.as_mut().rotate_right(new_len - old_len);
224 }
225 }
226
227 if req_space <= self.data.as_ref().len() {
229 let prev_next_ofs = self.next_ofs;
231 self.next_ofs += words;
232 let len = self.data.as_ref().len();
233 let slot = &mut self.data.as_mut()[len - self.next_ofs..][..words];
234 let (meta, rv) = slot.split_at_mut(Self::meta_words());
235
236 super::store_metadata(meta, metadata);
238
239 Ok(PushInnerInfo {
241 meta,
242 data: rv,
243 reset_slot: &mut self.next_ofs,
244 reset_value: prev_next_ofs
245 })
246 } else {
247 Err(())
248 }
249 }
250}
251
252impl<D: ::DataBuf> Stack<str, D> {
253 pub fn push_str(&mut self, v: &str) -> Result<(), ()> {
261 unsafe {
262 self.push_inner(v)
263 .map(|pii| ptr::copy(v.as_bytes().as_ptr(), pii.data.as_mut_ptr() as *mut u8, v.len()))
264 }
265 }
266}
267impl<D: ::DataBuf, T: Clone> Stack<[T], D>
268where
269 (T, D::Inner): crate::AlignmentValid,
270{
271 pub fn push_cloned(&mut self, v: &[T]) -> Result<(), ()> {
279 <(T, D::Inner) as crate::AlignmentValid>::check();
280 self.push_from_iter(v.iter().cloned())
281 }
282 pub fn push_copied(&mut self, v: &[T]) -> Result<(), ()>
290 where
291 T: Copy,
292 {
293 <(T, D::Inner) as crate::AlignmentValid>::check();
294 unsafe {
296 self.push_inner(v).map(|pii| {
297 ptr::copy(
298 v.as_ptr() as *const u8,
299 pii.data.as_mut_ptr() as *mut u8,
300 mem::size_of_val(v),
301 )
302 })
303 }
304 }
305}
306impl<D: crate::DataBuf, T> Stack<[T], D>
307where
308 (T, D::Inner): crate::AlignmentValid,
309{
310 pub fn push_from_iter(&mut self, mut iter: impl ExactSizeIterator<Item=T>) -> Result<(),()> {
321 <(T, D::Inner) as crate::AlignmentValid>::check();
322 unsafe {
324 let pii = self.push_inner_raw(iter.len() * mem::size_of::<T>(), &[0])?;
325 crate::list_push_gen(pii.meta, pii.data, iter.len(), |_| iter.next().unwrap(), pii.reset_slot, pii.reset_value);
326 Ok( () )
327 }
328 }
329}
330
331pub struct Iter<'a, T: 'a + ?Sized, D: 'a + crate::DataBuf>(&'a Stack<T, D>, usize);
333impl<'a, T: 'a + ?Sized, D: 'a + crate::DataBuf> iter::Iterator for Iter<'a, T, D> {
334 type Item = &'a T;
335 fn next(&mut self) -> Option<&'a T> {
336 if self.1 == 0 {
337 None
338 } else {
339 let rv = unsafe { &*self.0.raw_at(self.1) };
341 self.1 -= Stack::<T, D>::meta_words() + D::round_to_words(mem::size_of_val(rv));
342 Some(rv)
343 }
344 }
345}
346
347pub struct IterMut<'a, T: 'a + ?Sized, D: 'a + crate::DataBuf>(&'a mut Stack<T, D>, usize);
349impl<'a, T: 'a + ?Sized, D: 'a + crate::DataBuf> iter::Iterator for IterMut<'a, T, D> {
350 type Item = &'a mut T;
351 fn next(&mut self) -> Option<&'a mut T> {
352 if self.1 == 0 {
353 None
354 } else {
355 let rv = unsafe { &mut *self.0.raw_at_mut(self.1) };
357 self.1 -= Stack::<T, D>::meta_words() + D::round_to_words(mem::size_of_val(rv));
358 Some(rv)
359 }
360 }
361}