Skip to content

Commit

Permalink
Implement generalized object and type parameter bounds (Fixes rust-la…
Browse files Browse the repository at this point in the history
  • Loading branch information
nikomatsakis committed Aug 28, 2014
1 parent 3ee047a commit 1b487a8
Show file tree
Hide file tree
Showing 272 changed files with 6,746 additions and 3,117 deletions.
6 changes: 3 additions & 3 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ pub trait BoxAny {
}

#[stable]
impl BoxAny for Box<Any> {
impl BoxAny for Box<Any+'static> {
#[inline]
fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any+'static>> {
if self.is::<T>() {
unsafe {
// Get the raw representation of the trait object
Expand All @@ -132,7 +132,7 @@ impl<T: fmt::Show> fmt::Show for Box<T> {
}
}

impl fmt::Show for Box<Any> {
impl fmt::Show for Box<Any+'static> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("Box<Any>")
}
Expand Down
25 changes: 22 additions & 3 deletions src/libcollections/dlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,27 +49,46 @@ struct Node<T> {
value: T,
}

/// An iterator over references to the items of a `DList`.
/// Note: stage0-specific version that lacks bound on A.
#[cfg(stage0)]
pub struct Items<'a, T> {
head: &'a Link<T>,
tail: Rawlink<Node<T>>,
nelem: uint,
}

/// An iterator over references to the items of a `DList`.
#[cfg(not(stage0))]
pub struct Items<'a, T:'a> {
head: &'a Link<T>,
tail: Rawlink<Node<T>>,
nelem: uint,
}

// FIXME #11820: the &'a Option<> of the Link stops clone working.
impl<'a, T> Clone for Items<'a, T> {
fn clone(&self) -> Items<'a, T> { *self }
}

/// An iterator over mutable references to the items of a `DList`.
/// Note: stage0-specific version that lacks bound on A.
#[cfg(stage0)]
pub struct MutItems<'a, T> {
list: &'a mut DList<T>,
head: Rawlink<Node<T>>,
tail: Rawlink<Node<T>>,
nelem: uint,
}

/// A consuming iterator over the items of a `DList`.
/// An iterator over mutable references to the items of a `DList`.
#[cfg(not(stage0))]
pub struct MutItems<'a, T:'a> {
list: &'a mut DList<T>,
head: Rawlink<Node<T>>,
tail: Rawlink<Node<T>>,
nelem: uint,
}

/// An iterator over mutable references to the items of a `DList`.
#[deriving(Clone)]
pub struct MoveItems<T> {
list: DList<T>
Expand Down
9 changes: 8 additions & 1 deletion src/libcollections/priority_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,11 +515,18 @@ impl<T: Ord> PriorityQueue<T> {
}
}

/// `PriorityQueue` iterator.
/// Note: stage0-specific version that lacks bound on A.
#[cfg(stage0)]
pub struct Items <'a, T> {
iter: slice::Items<'a, T>,
}

/// `PriorityQueue` iterator.
#[cfg(not(stage0))]
pub struct Items <'a, T:'a> {
iter: slice::Items<'a, T>,
}

impl<'a, T> Iterator<&'a T> for Items<'a, T> {
#[inline]
fn next(&mut self) -> Option<(&'a T)> { self.iter.next() }
Expand Down
23 changes: 21 additions & 2 deletions src/libcollections/ringbuf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,14 +293,24 @@ impl<T> RingBuf<T> {
}
}

/// `RingBuf` iterator.
/// Note: stage0-specific version that lacks bound on A.
#[cfg(stage0)]
pub struct Items<'a, T> {
lo: uint,
index: uint,
rindex: uint,
elts: &'a [Option<T>],
}

/// `RingBuf` iterator.
#[cfg(not(stage0))]
pub struct Items<'a, T:'a> {
lo: uint,
index: uint,
rindex: uint,
elts: &'a [Option<T>],
}

impl<'a, T> Iterator<&'a T> for Items<'a, T> {
#[inline]
fn next(&mut self) -> Option<&'a T> {
Expand Down Expand Up @@ -348,13 +358,22 @@ impl<'a, T> RandomAccessIterator<&'a T> for Items<'a, T> {
}
}

/// `RingBuf` mutable iterator.
/// Note: stage0-specific version that lacks bound on A.
#[cfg(stage0)]
pub struct MutItems<'a, T> {
remaining1: &'a mut [Option<T>],
remaining2: &'a mut [Option<T>],
nelts: uint,
}

/// `RingBuf` mutable iterator.
#[cfg(not(stage0))]
pub struct MutItems<'a, T:'a> {
remaining1: &'a mut [Option<T>],
remaining2: &'a mut [Option<T>],
nelts: uint,
}

impl<'a, T> Iterator<&'a mut T> for MutItems<'a, T> {
#[inline]
#[allow(deprecated)] // mut_shift_ref
Expand Down
22 changes: 20 additions & 2 deletions src/libcollections/smallintmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,19 +489,37 @@ macro_rules! double_ended_iterator {
}
}

/// Forward iterator over a map.
/// Note: stage0-specific version that lacks bound on A.
#[cfg(stage0)]
pub struct Entries<'a, T> {
front: uint,
back: uint,
iter: slice::Items<'a, Option<T>>
}

/// Forward iterator over a map.
#[cfg(not(stage0))]
pub struct Entries<'a, T:'a> {
front: uint,
back: uint,
iter: slice::Items<'a, Option<T>>
}

iterator!(impl Entries -> (uint, &'a T), get_ref)
double_ended_iterator!(impl Entries -> (uint, &'a T), get_ref)

/// Note: stage0-specific version that lacks bound on A.
#[cfg(stage0)]
pub struct MutEntries<'a, T> {
front: uint,
back: uint,
iter: slice::MutItems<'a, Option<T>>
}

/// Forward iterator over the key-value pairs of a map, with the
/// values being mutable.
pub struct MutEntries<'a, T> {
#[cfg(not(stage0))]
pub struct MutEntries<'a, T:'a> {
front: uint,
back: uint,
iter: slice::MutItems<'a, Option<T>>
Expand Down
130 changes: 114 additions & 16 deletions src/libcollections/treemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,8 @@ impl<K: Ord, V> TreeMap<K, V> {
}
}

/// A lazy forward iterator over a map.
/// Note: stage0-specific version that lacks bound on A.
#[cfg(stage0)]
pub struct Entries<'a, K, V> {
stack: Vec<&'a TreeNode<K, V>>,
// See the comment on MutEntries; this is just to allow
Expand All @@ -679,13 +680,32 @@ pub struct Entries<'a, K, V> {
remaining_max: uint
}

/// Lazy backward iterator over a map.
/// Lazy forward iterator over a map
#[cfg(not(stage0))]
pub struct Entries<'a, K:'a, V:'a> {
stack: Vec<&'a TreeNode<K, V>>,
// See the comment on MutEntries; this is just to allow
// code-sharing (for this immutable-values iterator it *could* very
// well be Option<&'a TreeNode<K,V>>).
node: *const TreeNode<K, V>,
remaining_min: uint,
remaining_max: uint
}

/// Note: stage0-specific version that lacks bound on A.
#[cfg(stage0)]
pub struct RevEntries<'a, K, V> {
iter: Entries<'a, K, V>,
}

/// A lazy forward iterator over a map that allows for the mutation of
/// the values.
/// Lazy backward iterator over a map
#[cfg(not(stage0))]
pub struct RevEntries<'a, K:'a, V:'a> {
iter: Entries<'a, K, V>,
}

/// Note: stage0-specific version that lacks bound on A.
#[cfg(stage0)]
pub struct MutEntries<'a, K, V> {
stack: Vec<&'a mut TreeNode<K, V>>,
// Unfortunately, we require some unsafe-ness to get around the
Expand All @@ -712,11 +732,46 @@ pub struct MutEntries<'a, K, V> {
remaining_max: uint
}

/// Lazy backward iterator over a map.
/// Lazy forward iterator over a map that allows for the mutation of
/// the values.
#[cfg(not(stage0))]
pub struct MutEntries<'a, K:'a, V:'a> {
stack: Vec<&'a mut TreeNode<K, V>>,
// Unfortunately, we require some unsafe-ness to get around the
// fact that we would be storing a reference *into* one of the
// nodes in the stack.
//
// As far as the compiler knows, this would let us invalidate the
// reference by assigning a new value to this node's position in
// its parent, which would cause this current one to be
// deallocated so this reference would be invalid. (i.e. the
// compilers complaints are 100% correct.)
//
// However, as far as you humans reading this code know (or are
// about to know, if you haven't read far enough down yet), we are
// only reading from the TreeNode.{left,right} fields. the only
// thing that is ever mutated is the .value field (although any
// actual mutation that happens is done externally, by the
// iterator consumer). So, don't be so concerned, rustc, we've got
// it under control.
//
// (This field can legitimately be null.)
node: *mut TreeNode<K, V>,
remaining_min: uint,
remaining_max: uint
}

/// Note: stage0-specific version that lacks bound on A.
#[cfg(stage0)]
pub struct RevMutEntries<'a, K, V> {
iter: MutEntries<'a, K, V>,
}

/// Lazy backward iterator over a map
#[cfg(not(stage0))]
pub struct RevMutEntries<'a, K:'a, V:'a> {
iter: MutEntries<'a, K, V>,
}

/// TreeMap keys iterator.
pub type Keys<'a, K, V> =
Expand Down Expand Up @@ -885,9 +940,7 @@ fn mut_deref<K, V>(x: &mut Option<Box<TreeNode<K, V>>>)
}
}



/// A lazy forward iterator over a map that consumes the map while iterating.
/// Lazy forward iterator over a map that consumes the map while iterating
pub struct MoveEntries<K, V> {
stack: Vec<TreeNode<K, V>>,
remaining: uint
Expand Down Expand Up @@ -1322,45 +1375,90 @@ impl<T: Ord> TreeSet<T> {
}
}

/// A lazy forward iterator over a set.
/// Note: stage0-specific version that lacks bound on A.
#[cfg(stage0)]
pub struct SetItems<'a, T> {
iter: Entries<'a, T, ()>
}

/// Lazy backward iterator over a set.
/// A lazy forward iterator over a set.
#[cfg(not(stage0))]
pub struct SetItems<'a, T:'a> {
iter: Entries<'a, T, ()>
}

/// Note: stage0-specific version that lacks bound on A.
#[cfg(stage0)]
pub struct RevSetItems<'a, T> {
iter: RevEntries<'a, T, ()>
}

/// A lazy backward iterator over a set.
#[cfg(not(stage0))]
pub struct RevSetItems<'a, T:'a> {
iter: RevEntries<'a, T, ()>
}

/// A lazy forward iterator over a set that consumes the set while iterating.
pub type MoveSetItems<T> = iter::Map<'static, (T, ()), T, MoveEntries<T, ()>>;

/// A lazy iterator producing elements in the set difference (in-order).
/// Note: stage0-specific version that lacks bound on A.
#[cfg(stage0)]
pub struct DifferenceItems<'a, T> {
a: Peekable<&'a T, SetItems<'a, T>>,
b: Peekable<&'a T, SetItems<'a, T>>,
}

/// A lazy iterator producing elements in the set symmetric difference (in-order).
/// A lazy iterator producing elements in the set difference (in-order).
#[cfg(not(stage0))]
pub struct DifferenceItems<'a, T:'a> {
a: Peekable<&'a T, SetItems<'a, T>>,
b: Peekable<&'a T, SetItems<'a, T>>,
}

/// Note: stage0-specific version that lacks bound on A.
#[cfg(stage0)]
pub struct SymDifferenceItems<'a, T> {
a: Peekable<&'a T, SetItems<'a, T>>,
b: Peekable<&'a T, SetItems<'a, T>>,
}

/// A lazy iterator producing elements in the set intersection (in-order).
/// A lazy iterator producing elements in the set symmetric difference (in-order).
#[cfg(not(stage0))]
pub struct SymDifferenceItems<'a, T:'a> {
a: Peekable<&'a T, SetItems<'a, T>>,
b: Peekable<&'a T, SetItems<'a, T>>,
}

/// Note: stage0-specific version that lacks bound on A.
#[cfg(stage0)]
pub struct IntersectionItems<'a, T> {
a: Peekable<&'a T, SetItems<'a, T>>,
b: Peekable<&'a T, SetItems<'a, T>>,
}

/// A lazy iterator producing elements in the set union (in-order).
/// A lazy iterator producing elements in the set intersection (in-order).
#[cfg(not(stage0))]
pub struct IntersectionItems<'a, T:'a> {
a: Peekable<&'a T, SetItems<'a, T>>,
b: Peekable<&'a T, SetItems<'a, T>>,
}

/// Note: stage0-specific version that lacks bound on A.
#[cfg(stage0)]
pub struct UnionItems<'a, T> {
a: Peekable<&'a T, SetItems<'a, T>>,
b: Peekable<&'a T, SetItems<'a, T>>,
}

/// Compare `x` and `y`, but return `short` if x is None and `long` if y is
/// `None`.
/// A lazy iterator producing elements in the set union (in-order).
#[cfg(not(stage0))]
pub struct UnionItems<'a, T:'a> {
a: Peekable<&'a T, SetItems<'a, T>>,
b: Peekable<&'a T, SetItems<'a, T>>,
}

/// Compare `x` and `y`, but return `short` if x is None and `long` if y is None
fn cmp_opt<T: Ord>(x: Option<&T>, y: Option<&T>,
short: Ordering, long: Ordering) -> Ordering {
match (x, y) {
Expand Down
Loading

0 comments on commit 1b487a8

Please sign in to comment.