1use super::*;
2
3use std::{
4 mem::{
5 forget,
6 },
7 marker::{
8 Send,Sync,
9 },
10 ops::{
11 Drop,
12 },
13};
14use ptr::{
15 VoidPointer,
16};
17
18pub struct IntoIter<T>
20{
21 start: *mut T,
22 current_offset: usize,
23 sz: usize,
24}
25
26unsafe impl<T: Send> Send for IntoIter<T>{}
27unsafe impl<T: Sync> Sync for IntoIter<T>{} impl<T> IntoIter<T>
30{
31 fn current(&mut self) -> *mut T
32 {
33 unsafe {
34 self.start.offset(self.current_offset as isize)
35 }
36 }
37 fn free_if_needed(&mut self)
38 {
39 if self.start != ptr::null() && self.current_offset >= self.sz {
40 unsafe {
41 alloc::free(self.start as VoidPointer);
42 }
43 self.start = ptr::null();
44 }
45 }
46 fn drain_if_needed(&mut self)
47 {
48 if self.start != ptr::null() {
49
50 unsafe {
51 if self.current_offset<self.sz {
52 for i in self.current_offset..self.sz
53 {
54 drop(ptr::take(self.start.offset(i as isize)));
55 }
56 }
57
58 alloc::free(self.start as VoidPointer);
59 }
60 self.start = ptr::null();
61 }
62 }
63}
64
65impl<T> Drop for IntoIter<T>
66{
67 fn drop(&mut self)
68 {
69 self.drain_if_needed();
70 }
71}
72
73impl<T> Iterator for IntoIter<T>
74{
75 type Item = T;
76 fn next(&mut self) -> Option<Self::Item>
77 {
78 let output = if self.current_offset >= self.sz || self.sz == 0 {
79 None
80 } else {
81 unsafe {
82 let output = crate::ptr::take(self.current());self.current_offset+=1;
84
85 Some(output)
86 }
87 };
88 self.free_if_needed();
89 output
90 }
91}
92
93impl<T> ExactSizeIterator for IntoIter<T>
94{
95 fn len(&self) -> usize
96 {
97 self.sz
98 }
99}
100
101impl<T> IntoIterator for HeapArray<T>
102{
103 type Item = T;
104 type IntoIter = IntoIter<T>;
105
106 fn into_iter(self) -> Self::IntoIter
107 {
108 let output = Self::IntoIter {
109 start: self.ptr,
110 current_offset: 0,
111 sz: self.len(),
112 };
113 forget(self);
114 output
115 }
116}