1use std::alloc::Layout;
2
3use crate::object::{Keyed, WafArray, WafMap, WafObject};
4
5impl IntoIterator for WafArray {
6 type Item = WafObject;
7 type IntoIter = WafIter<Self::Item>;
8
9 fn into_iter(self) -> Self::IntoIter {
10 let array: *mut Self::Item = self.raw.array_ptr().cast();
11 let len = self.len();
12 let capacity = self.capacity();
13 std::mem::forget(self);
15 WafIter {
16 array,
17 len,
18 capacity,
19 pos: 0,
20 }
21 }
22}
23
24impl IntoIterator for Keyed<WafArray> {
25 type Item = WafObject;
26 type IntoIter = WafIter<Self::Item>;
27
28 fn into_iter(mut self) -> Self::IntoIter {
29 let arr = std::mem::take(self.value_mut());
30 arr.into_iter()
31 }
32}
33
34impl IntoIterator for WafMap {
35 type Item = Keyed<WafObject>;
36 type IntoIter = WafIter<Self::Item>;
37
38 fn into_iter(self) -> Self::IntoIter {
39 let array: *mut Keyed<WafObject> = self.raw.map_ptr().cast();
40 let len = self.len();
41 let capacity = self.capacity();
42 std::mem::forget(self);
44 WafIter {
45 array,
46 len,
47 capacity,
48 pos: 0,
49 }
50 }
51}
52
53impl IntoIterator for Keyed<WafMap> {
54 type Item = Keyed<WafObject>;
55 type IntoIter = WafIter<Self::Item>;
56
57 fn into_iter(mut self) -> Self::IntoIter {
58 let arr = std::mem::take(self.value_mut());
59 arr.into_iter()
60 }
61}
62
63pub struct WafIter<T> {
65 array: *mut T,
66 len: usize,
67 capacity: usize,
68 pos: usize,
69}
70impl<T: Default> Iterator for WafIter<T> {
71 type Item = T;
72
73 fn next(&mut self) -> Option<Self::Item> {
74 if self.pos >= self.len {
75 return None;
76 }
77
78 let obj = unsafe { &mut *self.array.add(self.pos) };
79 self.pos += 1;
80 Some(std::mem::take(obj))
81 }
82}
83impl<T> Drop for WafIter<T> {
84 fn drop(&mut self) {
85 for i in self.pos..self.len {
87 let elem = unsafe { self.array.add(i) };
88 unsafe { elem.drop_in_place() };
89 }
90 if self.capacity != 0 {
91 let layout = Layout::array::<T>(self.capacity).unwrap();
93 unsafe { std::alloc::dealloc(self.array.cast(), layout) }
94 }
95 }
96}