Skip to content

Commit de2b23d

Browse files
IArray and IMap iterators now yields references (#66)
Fixes #60 --------- Co-authored-by: Kirill Semyonkin <[email protected]>
1 parent ff1665e commit de2b23d

File tree

2 files changed

+75
-55
lines changed

2 files changed

+75
-55
lines changed

src/array.rs

Lines changed: 27 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -110,74 +110,54 @@ impl<T: ImplicitClone + 'static, const N: usize> From<[T; N]> for IArray<T> {
110110
}
111111
}
112112

113-
/// An iterator over the elements of an `IArray`.
113+
/// An iterator over the cloned elements of an `IArray`.
114114
#[derive(Debug)]
115-
pub struct Iter<T: ImplicitClone + 'static> {
115+
pub struct IArrayIntoIter<T: ImplicitClone + 'static> {
116116
array: IArray<T>,
117117
left: usize,
118118
right: usize,
119119
}
120120

121-
impl<T: ImplicitClone + 'static> Iter<T> {
122-
fn new(array: IArray<T>) -> Self {
123-
Self {
121+
impl<T: ImplicitClone + 'static> IntoIterator for IArray<T> {
122+
type Item = T;
123+
type IntoIter = IArrayIntoIter<T>;
124+
125+
fn into_iter(self) -> <Self as IntoIterator>::IntoIter {
126+
IArrayIntoIter {
124127
left: 0,
125-
right: array.len(),
126-
array,
128+
right: self.len(),
129+
array: self,
127130
}
128131
}
129132
}
130133

131-
impl<T: ImplicitClone + 'static> Iterator for Iter<T> {
134+
impl<T: ImplicitClone + 'static> Iterator for IArrayIntoIter<T> {
132135
type Item = T;
133136

134137
fn next(&mut self) -> Option<Self::Item> {
135138
if self.left >= self.right {
136139
return None;
137140
}
138-
let item = self.array.get(self.left);
141+
let item = &self.array[self.left];
139142
self.left += 1;
140-
item
143+
Some(item.clone())
141144
}
142145
}
143146

144-
impl<T: ImplicitClone + 'static> DoubleEndedIterator for Iter<T> {
147+
impl<T: ImplicitClone + 'static> DoubleEndedIterator for IArrayIntoIter<T> {
145148
fn next_back(&mut self) -> Option<Self::Item> {
146149
if self.left >= self.right {
147150
return None;
148151
}
149152
self.right -= 1;
150-
self.array.get(self.right)
153+
Some(self.array[self.right].clone())
151154
}
152155
}
153156

154157
impl<T: ImplicitClone + 'static> IArray<T> {
155158
/// An empty array without allocation.
156159
pub const EMPTY: Self = Self::Static(&[]);
157160

158-
/// Returns a double-ended iterator over the array.
159-
///
160-
/// # Examples
161-
///
162-
/// ```
163-
/// # use implicit_clone::unsync::*;
164-
/// let x = IArray::<u8>::Static(&[1, 2, 3, 4, 5, 6]);
165-
/// let mut iter = x.iter();
166-
///
167-
/// assert_eq!(Some(1), iter.next());
168-
/// assert_eq!(Some(6), iter.next_back());
169-
/// assert_eq!(Some(5), iter.next_back());
170-
/// assert_eq!(Some(2), iter.next());
171-
/// assert_eq!(Some(3), iter.next());
172-
/// assert_eq!(Some(4), iter.next());
173-
/// assert_eq!(None, iter.next());
174-
/// assert_eq!(None, iter.next_back());
175-
/// ```
176-
#[inline]
177-
pub fn iter(&self) -> Iter<T> {
178-
Iter::new(self.clone())
179-
}
180-
181161
/// Returns the number of elements in the vector, also referred to
182162
/// as its 'length'.
183163
///
@@ -236,21 +216,21 @@ impl<T: ImplicitClone + 'static> IArray<T> {
236216
}
237217
}
238218

239-
/// Returns a clone of an element at a position or `None` if out of bounds.
219+
/// Returns a reference of an element at a position or `None` if out of bounds.
240220
///
241221
/// # Examples
242222
///
243223
/// ```
244224
/// # use implicit_clone::unsync::*;
245225
/// let v = IArray::<u8>::Static(&[10, 40, 30]);
246-
/// assert_eq!(Some(40), v.get(1));
226+
/// assert_eq!(Some(&40), v.get(1));
247227
/// assert_eq!(None, v.get(3));
248228
/// ```
249229
#[inline]
250-
pub fn get(&self, index: usize) -> Option<T> {
230+
pub fn get(&self, index: usize) -> Option<&T> {
251231
match self {
252-
Self::Static(a) => a.get(index).cloned(),
253-
Self::Rc(a) => a.get(index).cloned(),
232+
Self::Static(a) => a.get(index),
233+
Self::Rc(a) => a.get(index),
254234
}
255235
}
256236

@@ -508,4 +488,11 @@ mod test_array {
508488

509489
impl ImplicitClone for _Node {}
510490
}
491+
492+
#[test]
493+
fn into_iter() {
494+
let array = IArray::Static(&[1, 2, 3]);
495+
assert_eq!(array.iter().next().unwrap(), &1);
496+
assert_eq!(array.into_iter().next().unwrap(), 1);
497+
}
511498
}

src/map.rs

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -298,12 +298,23 @@ pub enum IMapIter<'a, K, V> {
298298
impl<'a, K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static> Iterator
299299
for IMapIter<'a, K, V>
300300
{
301-
type Item = (K, V);
301+
type Item = (&'a K, &'a V);
302302

303303
fn next(&mut self) -> Option<Self::Item> {
304304
match self {
305-
Self::Slice(it) => it.next().map(|(k, v)| (k.clone(), v.clone())),
306-
Self::Map(it) => it.next().map(|(k, v)| (k.clone(), v.clone())),
305+
Self::Slice(it) => it.next().map(|(k, v)| (k, v)),
306+
Self::Map(it) => it.next(),
307+
}
308+
}
309+
}
310+
311+
impl<'a, K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static>
312+
DoubleEndedIterator for IMapIter<'a, K, V>
313+
{
314+
fn next_back(&mut self) -> Option<Self::Item> {
315+
match self {
316+
Self::Slice(it) => it.next_back().map(|(k, v)| (k, v)),
317+
Self::Map(it) => it.next_back(),
307318
}
308319
}
309320
}
@@ -317,12 +328,23 @@ pub enum IMapKeys<'a, K, V> {
317328
impl<'a, K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static> Iterator
318329
for IMapKeys<'a, K, V>
319330
{
320-
type Item = K;
331+
type Item = &'a K;
321332

322333
fn next(&mut self) -> Option<Self::Item> {
323334
match self {
324-
Self::Slice(it) => it.next().map(|(k, _)| k.clone()),
325-
Self::Map(it) => it.next().cloned(),
335+
Self::Slice(it) => it.next().map(|(k, _)| k),
336+
Self::Map(it) => it.next(),
337+
}
338+
}
339+
}
340+
341+
impl<'a, K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static>
342+
DoubleEndedIterator for IMapKeys<'a, K, V>
343+
{
344+
fn next_back(&mut self) -> Option<Self::Item> {
345+
match self {
346+
Self::Slice(it) => it.next_back().map(|(k, _)| k),
347+
Self::Map(it) => it.next_back(),
326348
}
327349
}
328350
}
@@ -336,12 +358,23 @@ pub enum IMapValues<'a, K, V> {
336358
impl<'a, K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static> Iterator
337359
for IMapValues<'a, K, V>
338360
{
339-
type Item = V;
361+
type Item = &'a V;
340362

341363
fn next(&mut self) -> Option<Self::Item> {
342364
match self {
343-
Self::Slice(it) => it.next().map(|(_, v)| v.clone()),
344-
Self::Map(it) => it.next().cloned(),
365+
Self::Slice(it) => it.next().map(|(_, v)| v),
366+
Self::Map(it) => it.next(),
367+
}
368+
}
369+
}
370+
371+
impl<'a, K: Eq + Hash + ImplicitClone + 'static, V: PartialEq + ImplicitClone + 'static>
372+
DoubleEndedIterator for IMapValues<'a, K, V>
373+
{
374+
fn next_back(&mut self) -> Option<Self::Item> {
375+
match self {
376+
Self::Slice(it) => it.next_back().map(|(_, v)| v),
377+
Self::Map(it) => it.next_back(),
345378
}
346379
}
347380
}
@@ -413,12 +446,12 @@ mod test_map {
413446
assert_eq!(
414447
flattened_vec,
415448
[
416-
(IString::from("foo1"), 1),
417-
(IString::from("bar1"), 2),
418-
(IString::from("baz1"), 3),
419-
(IString::from("foo2"), 4),
420-
(IString::from("bar2"), 5),
421-
(IString::from("baz2"), 6),
449+
(&IString::from("foo1"), &1),
450+
(&IString::from("bar1"), &2),
451+
(&IString::from("baz1"), &3),
452+
(&IString::from("foo2"), &4),
453+
(&IString::from("bar2"), &5),
454+
(&IString::from("baz2"), &6),
422455
]
423456
);
424457
}

0 commit comments

Comments
 (0)