From 167d533fe0624963cb3f836ebce06a457043c816 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Tue, 7 Jan 2014 02:09:07 +1100 Subject: [PATCH] extra::treemap: use the dummy-macro trick with items to make the iterator macro properly hygiene. Requires less repetition of `mut` or not too. --- src/libextra/treemap.rs | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index f4fd81437fc..9fe419b06d2 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -327,14 +327,12 @@ pub struct TreeMapMutRevIterator<'a, K, V> { // other macros, so this takes the `& ` token // sequence and forces their evalutation as an expression. macro_rules! addr { ($e:expr) => { $e }} +// putting an optional mut into type signatures +macro_rules! item { ($i:item) => { $i }} macro_rules! define_iterator { ($name:ident, $rev_name:ident, - // the type of the values of the treemap in the return value of - // the iterator (i.e. &V or &mut V). This is non-hygienic in the - // name of the lifetime. - value_type = $value_type:ty, // the function to go from &m Option<~TreeNode> to *m TreeNode deref = $deref:ident, @@ -343,10 +341,11 @@ macro_rules! define_iterator { // there's no support for 0-or-1 repeats. addr_mut = $($addr_mut:tt)* ) => { - // private methods on the forward iterator - impl<'a, K, V> $name<'a, K, V> { + // private methods on the forward iterator (item!() for the + // addr_mut in the next_ return value) + item!(impl<'a, K, V> $name<'a, K, V> { #[inline(always)] - fn next_(&mut self, forward: bool) -> Option<(&'a K, $value_type)> { + fn next_(&mut self, forward: bool) -> Option<(&'a K, &'a $($addr_mut)* V)> { while !self.stack.is_empty() || !self.node.is_null() { if !self.node.is_null() { let node = unsafe {addr!(& $($addr_mut)* *self.node)}; @@ -412,14 +411,14 @@ macro_rules! define_iterator { self.node = ptr::RawPtr::null(); } } - } + }) // the forward Iterator impl. - impl<'a, K, V> Iterator<(&'a K, $value_type)> for $name<'a, K, V> { + item!(impl<'a, K, V> Iterator<(&'a K, &'a $($addr_mut)* V)> for $name<'a, K, V> { /// Advance the iterator to the next node (in order) and return a /// tuple with a reference to the key and value. If there are no /// more nodes, return `None`. - fn next(&mut self) -> Option<(&'a K, $value_type)> { + fn next(&mut self) -> Option<(&'a K, &'a $($addr_mut)* V)> { self.next_(true) } @@ -427,11 +426,11 @@ macro_rules! define_iterator { fn size_hint(&self) -> (uint, Option) { (self.remaining_min, Some(self.remaining_max)) } - } + }) // the reverse Iterator impl. - impl<'a, K, V> Iterator<(&'a K, $value_type)> for $rev_name<'a, K, V> { - fn next(&mut self) -> Option<(&'a K, $value_type)> { + item!(impl<'a, K, V> Iterator<(&'a K, &'a $($addr_mut)* V)> for $rev_name<'a, K, V> { + fn next(&mut self) -> Option<(&'a K, &'a $($addr_mut)* V)> { self.iter.next_(false) } @@ -439,14 +438,13 @@ macro_rules! define_iterator { fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } - } + }) } } // end of define_iterator define_iterator! { TreeMapIterator, TreeMapRevIterator, - value_type = &'a V, deref = deref, // immutable, so no mut @@ -455,7 +453,6 @@ define_iterator! { define_iterator! { TreeMapMutIterator, TreeMapMutRevIterator, - value_type = &'a mut V, deref = mut_deref, addr_mut = mut