Skip to content

Commit 167d533

Browse files
committed
extra::treemap: use the dummy-macro trick with items to make the
iterator macro properly hygiene. Requires less repetition of `mut` or not too.
1 parent 7e446af commit 167d533

File tree

1 file changed

+13
-16
lines changed

1 file changed

+13
-16
lines changed

src/libextra/treemap.rs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -327,14 +327,12 @@ pub struct TreeMapMutRevIterator<'a, K, V> {
327327
// other macros, so this takes the `& <mutability> <operand>` token
328328
// sequence and forces their evalutation as an expression.
329329
macro_rules! addr { ($e:expr) => { $e }}
330+
// putting an optional mut into type signatures
331+
macro_rules! item { ($i:item) => { $i }}
330332

331333
macro_rules! define_iterator {
332334
($name:ident,
333335
$rev_name:ident,
334-
// the type of the values of the treemap in the return value of
335-
// the iterator (i.e. &V or &mut V). This is non-hygienic in the
336-
// name of the lifetime.
337-
value_type = $value_type:ty,
338336

339337
// the function to go from &m Option<~TreeNode> to *m TreeNode
340338
deref = $deref:ident,
@@ -343,10 +341,11 @@ macro_rules! define_iterator {
343341
// there's no support for 0-or-1 repeats.
344342
addr_mut = $($addr_mut:tt)*
345343
) => {
346-
// private methods on the forward iterator
347-
impl<'a, K, V> $name<'a, K, V> {
344+
// private methods on the forward iterator (item!() for the
345+
// addr_mut in the next_ return value)
346+
item!(impl<'a, K, V> $name<'a, K, V> {
348347
#[inline(always)]
349-
fn next_(&mut self, forward: bool) -> Option<(&'a K, $value_type)> {
348+
fn next_(&mut self, forward: bool) -> Option<(&'a K, &'a $($addr_mut)* V)> {
350349
while !self.stack.is_empty() || !self.node.is_null() {
351350
if !self.node.is_null() {
352351
let node = unsafe {addr!(& $($addr_mut)* *self.node)};
@@ -412,41 +411,40 @@ macro_rules! define_iterator {
412411
self.node = ptr::RawPtr::null();
413412
}
414413
}
415-
}
414+
})
416415

417416
// the forward Iterator impl.
418-
impl<'a, K, V> Iterator<(&'a K, $value_type)> for $name<'a, K, V> {
417+
item!(impl<'a, K, V> Iterator<(&'a K, &'a $($addr_mut)* V)> for $name<'a, K, V> {
419418
/// Advance the iterator to the next node (in order) and return a
420419
/// tuple with a reference to the key and value. If there are no
421420
/// more nodes, return `None`.
422-
fn next(&mut self) -> Option<(&'a K, $value_type)> {
421+
fn next(&mut self) -> Option<(&'a K, &'a $($addr_mut)* V)> {
423422
self.next_(true)
424423
}
425424

426425
#[inline]
427426
fn size_hint(&self) -> (uint, Option<uint>) {
428427
(self.remaining_min, Some(self.remaining_max))
429428
}
430-
}
429+
})
431430

432431
// the reverse Iterator impl.
433-
impl<'a, K, V> Iterator<(&'a K, $value_type)> for $rev_name<'a, K, V> {
434-
fn next(&mut self) -> Option<(&'a K, $value_type)> {
432+
item!(impl<'a, K, V> Iterator<(&'a K, &'a $($addr_mut)* V)> for $rev_name<'a, K, V> {
433+
fn next(&mut self) -> Option<(&'a K, &'a $($addr_mut)* V)> {
435434
self.iter.next_(false)
436435
}
437436

438437
#[inline]
439438
fn size_hint(&self) -> (uint, Option<uint>) {
440439
self.iter.size_hint()
441440
}
442-
}
441+
})
443442
}
444443
} // end of define_iterator
445444

446445
define_iterator! {
447446
TreeMapIterator,
448447
TreeMapRevIterator,
449-
value_type = &'a V,
450448
deref = deref,
451449

452450
// immutable, so no mut
@@ -455,7 +453,6 @@ define_iterator! {
455453
define_iterator! {
456454
TreeMapMutIterator,
457455
TreeMapMutRevIterator,
458-
value_type = &'a mut V,
459456
deref = mut_deref,
460457

461458
addr_mut = mut

0 commit comments

Comments
 (0)