|
15 | 15 | * limitations under the License.
|
16 | 16 | */
|
17 | 17 |
|
| 18 | +use std::marker::PhantomData; |
| 19 | +use std::ptr; |
| 20 | +use std::ptr::NonNull; |
18 | 21 | use std::slice;
|
19 | 22 |
|
20 | 23 | use gazebo::prelude::*;
|
21 | 24 |
|
| 25 | +use crate::vec2::Vec2; |
| 26 | + |
22 | 27 | #[derive(Clone_)]
|
23 | 28 | pub(crate) struct Iter<'a, K, V> {
|
24 | 29 | pub(crate) keys: slice::Iter<'a, K>,
|
25 |
| - pub(crate) values: slice::Iter<'a, V>, |
| 30 | + pub(crate) values: *const V, |
| 31 | + pub(crate) _marker: PhantomData<slice::Iter<'a, V>>, |
26 | 32 | }
|
27 | 33 |
|
| 34 | +unsafe impl<K: Sync, V: Sync> Sync for Iter<'_, K, V> {} |
| 35 | +unsafe impl<K: Sync, V: Sync> Send for Iter<'_, K, V> {} |
| 36 | + |
28 | 37 | impl<'a, K, V> Iterator for Iter<'a, K, V> {
|
29 | 38 | type Item = (&'a K, &'a V);
|
30 | 39 |
|
| 40 | + #[inline] |
31 | 41 | fn next(&mut self) -> Option<Self::Item> {
|
32 |
| - match (self.keys.next(), self.values.next()) { |
33 |
| - (Some(k), Some(v)) => Some((k, v)), |
34 |
| - _ => None, |
35 |
| - } |
| 42 | + let key = self.keys.next()?; |
| 43 | + let value = unsafe { &*self.values }; |
| 44 | + self.values = unsafe { self.values.add(1) }; |
| 45 | + Some((key, value)) |
36 | 46 | }
|
37 | 47 |
|
| 48 | + #[inline] |
38 | 49 | fn size_hint(&self) -> (usize, Option<usize>) {
|
39 | 50 | self.keys.size_hint()
|
40 | 51 | }
|
41 | 52 | }
|
42 | 53 |
|
43 | 54 | impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
|
| 55 | + #[inline] |
44 | 56 | fn len(&self) -> usize {
|
45 | 57 | self.keys.len()
|
46 | 58 | }
|
47 | 59 | }
|
48 | 60 |
|
49 | 61 | impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V> {
|
| 62 | + #[inline] |
50 | 63 | fn next_back(&mut self) -> Option<Self::Item> {
|
51 |
| - match (self.keys.next_back(), self.values.next_back()) { |
52 |
| - (Some(k), Some(v)) => Some((k, v)), |
53 |
| - _ => None, |
54 |
| - } |
| 64 | + let key = self.keys.next_back()?; |
| 65 | + let value = unsafe { &*self.values.add(self.keys.len()) }; |
| 66 | + Some((key, value)) |
55 | 67 | }
|
56 | 68 | }
|
57 | 69 |
|
58 | 70 | pub(crate) struct IntoIter<K, V> {
|
59 |
| - pub(crate) keys: std::vec::IntoIter<K>, |
60 |
| - pub(crate) values: std::vec::IntoIter<V>, |
| 71 | + // TODO: make NonNull |
| 72 | + pub(crate) keys_begin: *mut K, |
| 73 | + pub(crate) values_begin: *mut V, |
| 74 | + pub(crate) values_end: *mut V, |
| 75 | + pub(crate) values_ptr: NonNull<V>, |
| 76 | + pub(crate) cap: usize, |
61 | 77 | }
|
62 | 78 |
|
| 79 | +unsafe impl<K: Send, V: Send> Send for IntoIter<K, V> {} |
| 80 | +unsafe impl<K: Sync, V: Sync> Sync for IntoIter<K, V> {} |
| 81 | + |
63 | 82 | impl<K, V> Iterator for IntoIter<K, V> {
|
64 | 83 | type Item = (K, V);
|
65 | 84 |
|
| 85 | + #[inline] |
66 | 86 | fn next(&mut self) -> Option<Self::Item> {
|
67 |
| - match (self.keys.next(), self.values.next()) { |
68 |
| - (Some(k), Some(v)) => Some((k, v)), |
69 |
| - _ => None, |
| 87 | + if self.values_begin == self.values_end { |
| 88 | + None |
| 89 | + } else { |
| 90 | + unsafe { |
| 91 | + let k = ptr::read(self.keys_begin); |
| 92 | + let v = ptr::read(self.values_begin); |
| 93 | + self.keys_begin = self.keys_begin.add(1); |
| 94 | + self.values_begin = self.values_begin.add(1); |
| 95 | + Some((k, v)) |
| 96 | + } |
70 | 97 | }
|
71 | 98 | }
|
72 | 99 |
|
| 100 | + #[inline] |
73 | 101 | fn size_hint(&self) -> (usize, Option<usize>) {
|
74 |
| - self.keys.size_hint() |
| 102 | + let rem = self.len(); |
| 103 | + (rem, Some(rem)) |
| 104 | + } |
| 105 | +} |
| 106 | + |
| 107 | +impl<K, V> Drop for IntoIter<K, V> { |
| 108 | + fn drop(&mut self) { |
| 109 | + unsafe { |
| 110 | + let rem = self.len(); |
| 111 | + ptr::drop_in_place(slice::from_raw_parts_mut(self.keys_begin, rem)); |
| 112 | + ptr::drop_in_place(slice::from_raw_parts_mut(self.values_begin, rem)); |
| 113 | + Vec2::<K, V>::dealloc_impl(self.values_ptr, self.cap); |
| 114 | + } |
75 | 115 | }
|
76 | 116 | }
|
77 | 117 |
|
78 | 118 | impl<K, V> ExactSizeIterator for IntoIter<K, V> {
|
| 119 | + #[inline] |
79 | 120 | fn len(&self) -> usize {
|
80 |
| - self.keys.len() |
| 121 | + unsafe { self.values_end.offset_from(self.values_begin) as usize } |
81 | 122 | }
|
82 | 123 | }
|
83 | 124 |
|
84 | 125 | impl<K, V> DoubleEndedIterator for IntoIter<K, V> {
|
85 | 126 | fn next_back(&mut self) -> Option<Self::Item> {
|
86 |
| - match (self.keys.next_back(), self.values.next_back()) { |
87 |
| - (Some(k), Some(v)) => Some((k, v)), |
88 |
| - _ => None, |
| 127 | + if self.values_begin == self.values_end { |
| 128 | + None |
| 129 | + } else { |
| 130 | + unsafe { |
| 131 | + self.values_end = self.values_end.sub(1); |
| 132 | + let k = ptr::read(self.keys_begin.add(self.len())); |
| 133 | + let v = ptr::read(self.values_end); |
| 134 | + Some((k, v)) |
| 135 | + } |
89 | 136 | }
|
90 | 137 | }
|
91 | 138 | }
|
0 commit comments