]> git.lizzy.rs Git - rust.git/blobdiff - src/libcollections/bit.rs
rollup merge of #20273: alexcrichton/second-pass-comm
[rust.git] / src / libcollections / bit.rs
index fe3267b6c35d91527e88a5c7acfd636d7ed4cba0..91dea72ec8d795e2d218581d2276f68005697c00 100644 (file)
 use core::ops::Index;
 use core::slice::{Iter, IterMut};
 use core::{u8, u32, uint};
+use bitv_set; //so meta
 
 use Vec;
 
-type Blocks<'a> = Cloned<Iter<'a, u32>>;
-type MutBlocks<'a> = IterMut<'a, u32>;
+type Blocks<'a> = Cloned<slice::Iter<'a, u32>>;
+type MutBlocks<'a> = slice::IterMut<'a, u32>;
 type MatchWords<'a> = Chain<Enumerate<Blocks<'a>>, Skip<Take<Enumerate<Repeat<u32>>>>>;
 
 fn reverse_bits(byte: u8) -> u8 {
@@ -155,6 +156,7 @@ fn match_words <'a,'b>(a: &'a Bitv, b: &'b Bitv) -> (MatchWords<'a>, MatchWords<
 /// println!("{}", bv.to_string());
 /// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
 /// ```
+#[stable]
 pub struct Bitv {
     /// Internal representation of the bit vector
     storage: Vec<u32>,
@@ -165,7 +167,7 @@ pub struct Bitv {
 // FIXME(Gankro): NopeNopeNopeNopeNope (wait for IndexGet to be a thing)
 impl Index<uint,bool> for Bitv {
     #[inline]
-    fn index<'a>(&'a self, i: &uint) -> &'a bool {
+    fn index(&self, i: &uint) -> &bool {
         if self.get(*i).expect("index out of bounds") {
             &TRUE
         } else {
@@ -248,7 +250,7 @@ fn fix_last_block(&mut self) {
     /// use std::collections::Bitv;
     /// let mut bv = Bitv::new();
     /// ```
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn new() -> Bitv {
         Bitv { storage: Vec::new(), nbits: 0 }
     }
@@ -270,7 +272,7 @@ pub fn new() -> Bitv {
     pub fn from_elem(nbits: uint, bit: bool) -> Bitv {
         let nblocks = blocks_for_bits(nbits);
         let mut bitv = Bitv {
-            storage: Vec::from_elem(nblocks, if bit { !0u32 } else { 0u32 }),
+            storage: repeat(if bit { !0u32 } else { 0u32 }).take(nblocks).collect(),
             nbits: nbits
         };
         bitv.fix_last_block();
@@ -284,7 +286,7 @@ pub fn from_elem(nbits: uint, bit: bool) -> Bitv {
     ///
     /// It is important to note that this function does not specify the
     /// *length* of the returned bitvector, but only the *capacity*.
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn with_capacity(nbits: uint) -> Bitv {
         Bitv {
             storage: Vec::with_capacity(blocks_for_bits(nbits)),
@@ -370,7 +372,7 @@ pub fn from_fn<F>(len: uint, mut f: F) -> Bitv where F: FnMut(uint) -> bool {
     /// assert_eq!(bv[1], true);
     /// ```
     #[inline]
-    #[unstable = "panic semantics are likely to change in the future"]
+    #[stable]
     pub fn get(&self, i: uint) -> Option<bool> {
         if i >= self.nbits {
             return None;
@@ -581,9 +583,9 @@ pub fn all(&self) -> bool {
     /// assert_eq!(bv.iter().filter(|x| *x).count(), 7);
     /// ```
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
-    pub fn iter<'a>(&'a self) -> Bits<'a> {
-        Bits { bitv: self, next_idx: 0, end_idx: self.nbits }
+    #[stable]
+    pub fn iter(&self) -> Iter {
+        Iter { bitv: self, next_idx: 0, end_idx: self.nbits }
     }
 
     /// Returns `true` if all bits are 0.
@@ -654,7 +656,7 @@ fn bit(bitv: &Bitv, byte: uint, bit: uint) -> u8 {
 
         let len = self.nbits/8 +
                   if self.nbits % 8 == 0 { 0 } else { 1 };
-        Vec::from_fn(len, |i|
+        range(0, len).map(|i|
             bit(self, i, 0) |
             bit(self, i, 1) |
             bit(self, i, 2) |
@@ -663,7 +665,7 @@ fn bit(bitv: &Bitv, byte: uint, bit: uint) -> u8 {
             bit(self, i, 5) |
             bit(self, i, 6) |
             bit(self, i, 7)
-        )
+        ).collect()
     }
 
     /// Deprecated: Use `iter().collect()`.
@@ -708,7 +710,7 @@ pub fn eq_vec(&self, v: &[bool]) -> bool {
     /// bv.truncate(2);
     /// assert!(bv.eq_vec(&[false, true]));
     /// ```
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn truncate(&mut self, len: uint) {
         if len < self.len() {
             self.nbits = len;
@@ -735,7 +737,7 @@ pub fn truncate(&mut self, len: uint) {
     /// assert_eq!(bv.len(), 3);
     /// assert!(bv.capacity() >= 13);
     /// ```
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn reserve(&mut self, additional: uint) {
         let desired_cap = self.len().checked_add(additional).expect("capacity overflow");
         let storage_len = self.storage.len();
@@ -765,7 +767,7 @@ pub fn reserve(&mut self, additional: uint) {
     /// assert_eq!(bv.len(), 3);
     /// assert!(bv.capacity() >= 13);
     /// ```
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn reserve_exact(&mut self, additional: uint) {
         let desired_cap = self.len().checked_add(additional).expect("capacity overflow");
         let storage_len = self.storage.len();
@@ -787,7 +789,7 @@ pub fn reserve_exact(&mut self, additional: uint) {
     /// assert!(bv.capacity() >= 10);
     /// ```
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn capacity(&self) -> uint {
         self.storage.capacity().checked_mul(u32::BITS).unwrap_or(uint::MAX)
     }
@@ -837,7 +839,7 @@ pub fn grow(&mut self, n: uint, value: bool) {
         // Allocate new words, if needed
         if new_nblocks > self.storage.len() {
             let to_add = new_nblocks - self.storage.len();
-            self.storage.grow(to_add, full_value);
+            self.storage.extend(repeat(full_value).take(to_add));
         }
 
         // Adjust internal bit count
@@ -858,7 +860,7 @@ pub fn grow(&mut self, n: uint, value: bool) {
     /// assert_eq!(bv.pop(), Some(false));
     /// assert_eq!(bv.len(), 6);
     /// ```
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn pop(&mut self) -> Option<bool> {
         if self.is_empty() {
             None
@@ -888,7 +890,7 @@ pub fn pop(&mut self) -> Option<bool> {
     /// bv.push(false);
     /// assert!(bv.eq_vec(&[true, false]));
     /// ```
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn push(&mut self, elem: bool) {
         if self.nbits % u32::BITS == 0 {
             self.storage.push(0);
@@ -900,17 +902,17 @@ pub fn push(&mut self, elem: bool) {
 
     /// Return the total number of bits in this vector
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn len(&self) -> uint { self.nbits }
 
     /// Returns true if there are no bits in this vector
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn is_empty(&self) -> bool { self.len() == 0 }
 
     /// Clears all bits in this vector.
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn clear(&mut self) {
         for w in self.storage.iter_mut() { *w = 0u32; }
     }
@@ -931,10 +933,10 @@ pub fn from_fn<F>(len: uint, f: F) -> Bitv where F: FnMut(uint) -> bool {
 #[stable]
 impl Default for Bitv {
     #[inline]
-    #[stable]
     fn default() -> Bitv { Bitv::new() }
 }
 
+#[stable]
 impl FromIterator<bool> for Bitv {
     fn from_iter<I:Iterator<bool>>(iterator: I) -> Bitv {
         let mut ret = Bitv::new();
@@ -943,6 +945,7 @@ fn from_iter<I:Iterator<bool>>(iterator: I) -> Bitv {
     }
 }
 
+#[stable]
 impl Extend<bool> for Bitv {
     #[inline]
     fn extend<I: Iterator<bool>>(&mut self, mut iterator: I) {
@@ -968,6 +971,7 @@ fn clone_from(&mut self, source: &Bitv) {
     }
 }
 
+#[stable]
 impl PartialOrd for Bitv {
     #[inline]
     fn partial_cmp(&self, other: &Bitv) -> Option<Ordering> {
@@ -975,6 +979,7 @@ fn partial_cmp(&self, other: &Bitv) -> Option<Ordering> {
     }
 }
 
+#[stable]
 impl Ord for Bitv {
     #[inline]
     fn cmp(&self, other: &Bitv) -> Ordering {
@@ -982,6 +987,7 @@ fn cmp(&self, other: &Bitv) -> Ordering {
     }
 }
 
+#[stable]
 impl fmt::Show for Bitv {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         for bit in self.iter() {
@@ -991,6 +997,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+#[stable]
 impl<S: hash::Writer> hash::Hash<S> for Bitv {
     fn hash(&self, state: &mut S) {
         self.nbits.hash(state);
@@ -1000,6 +1007,7 @@ fn hash(&self, state: &mut S) {
     }
 }
 
+#[stable]
 impl cmp::PartialEq for Bitv {
     #[inline]
     fn eq(&self, other: &Bitv) -> bool {
@@ -1010,16 +1018,20 @@ fn eq(&self, other: &Bitv) -> bool {
     }
 }
 
+#[stable]
 impl cmp::Eq for Bitv {}
 
 /// An iterator for `Bitv`.
-pub struct Bits<'a> {
+#[stable]
+#[deriving(Clone)]
+pub struct Iter<'a> {
     bitv: &'a Bitv,
     next_idx: uint,
     end_idx: uint,
 }
 
-impl<'a> Iterator<bool> for Bits<'a> {
+#[stable]
+impl<'a> Iterator<bool> for Iter<'a> {
     #[inline]
     fn next(&mut self) -> Option<bool> {
         if self.next_idx != self.end_idx {
@@ -1037,7 +1049,8 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-impl<'a> DoubleEndedIterator<bool> for Bits<'a> {
+#[stable]
+impl<'a> DoubleEndedIterator<bool> for Iter<'a> {
     #[inline]
     fn next_back(&mut self) -> Option<bool> {
         if self.next_idx != self.end_idx {
@@ -1049,9 +1062,11 @@ fn next_back(&mut self) -> Option<bool> {
     }
 }
 
-impl<'a> ExactSizeIterator<bool> for Bits<'a> {}
+#[stable]
+impl<'a> ExactSizeIterator<bool> for Iter<'a> {}
 
-impl<'a> RandomAccessIterator<bool> for Bits<'a> {
+#[stable]
+impl<'a> RandomAccessIterator<bool> for Iter<'a> {
     #[inline]
     fn indexable(&self) -> uint {
         self.end_idx - self.next_idx
@@ -1106,15 +1121,18 @@ fn idx(&mut self, index: uint) -> Option<bool> {
 /// assert!(bv[3]);
 /// ```
 #[deriving(Clone)]
+#[stable]
 pub struct BitvSet {
     bitv: Bitv,
 }
 
+#[stable]
 impl Default for BitvSet {
     #[inline]
     fn default() -> BitvSet { BitvSet::new() }
 }
 
+#[stable]
 impl FromIterator<uint> for BitvSet {
     fn from_iter<I:Iterator<uint>>(iterator: I) -> BitvSet {
         let mut ret = BitvSet::new();
@@ -1123,6 +1141,7 @@ fn from_iter<I:Iterator<uint>>(iterator: I) -> BitvSet {
     }
 }
 
+#[stable]
 impl Extend<uint> for BitvSet {
     #[inline]
     fn extend<I: Iterator<uint>>(&mut self, mut iterator: I) {
@@ -1132,6 +1151,7 @@ fn extend<I: Iterator<uint>>(&mut self, mut iterator: I) {
     }
 }
 
+#[stable]
 impl PartialOrd for BitvSet {
     #[inline]
     fn partial_cmp(&self, other: &BitvSet) -> Option<Ordering> {
@@ -1140,6 +1160,7 @@ fn partial_cmp(&self, other: &BitvSet) -> Option<Ordering> {
     }
 }
 
+#[stable]
 impl Ord for BitvSet {
     #[inline]
     fn cmp(&self, other: &BitvSet) -> Ordering {
@@ -1148,6 +1169,7 @@ fn cmp(&self, other: &BitvSet) -> Ordering {
     }
 }
 
+#[stable]
 impl cmp::PartialEq for BitvSet {
     #[inline]
     fn eq(&self, other: &BitvSet) -> bool {
@@ -1156,6 +1178,7 @@ fn eq(&self, other: &BitvSet) -> bool {
     }
 }
 
+#[stable]
 impl cmp::Eq for BitvSet {}
 
 impl BitvSet {
@@ -1169,7 +1192,7 @@ impl BitvSet {
     /// let mut s = BitvSet::new();
     /// ```
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn new() -> BitvSet {
         BitvSet { bitv: Bitv::new() }
     }
@@ -1186,7 +1209,7 @@ pub fn new() -> BitvSet {
     /// assert!(s.capacity() >= 100);
     /// ```
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn with_capacity(nbits: uint) -> BitvSet {
         let bitv = Bitv::from_elem(nbits, false);
         BitvSet::from_bitv(bitv)
@@ -1224,7 +1247,7 @@ pub fn from_bitv(bitv: Bitv) -> BitvSet {
     /// assert!(s.capacity() >= 100);
     /// ```
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn capacity(&self) -> uint {
         self.bitv.capacity()
     }
@@ -1245,7 +1268,7 @@ pub fn capacity(&self) -> uint {
     /// s.reserve_len(10);
     /// assert!(s.capacity() >= 10);
     /// ```
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn reserve_len(&mut self, len: uint) {
         let cur_len = self.bitv.len();
         if len >= cur_len {
@@ -1271,7 +1294,7 @@ pub fn reserve_len(&mut self, len: uint) {
     /// s.reserve_len_exact(10);
     /// assert!(s.capacity() >= 10);
     /// ```
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn reserve_len_exact(&mut self, len: uint) {
         let cur_len = self.bitv.len();
         if len >= cur_len {
@@ -1314,7 +1337,7 @@ pub fn into_bitv(self) -> Bitv {
     /// assert_eq!(bv[0], true);
     /// ```
     #[inline]
-    pub fn get_ref<'a>(&'a self) -> &'a Bitv {
+    pub fn get_ref(&self) -> &Bitv {
         &self.bitv
     }
 
@@ -1365,7 +1388,7 @@ fn other_op<F>(&mut self, other: &BitvSet, mut f: F) where F: FnMut(u32, u32) ->
     /// println!("new capacity: {}", s.capacity());
     /// ```
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn shrink_to_fit(&mut self) {
         let bitv = &mut self.bitv;
         // Obtain original length
@@ -1393,9 +1416,9 @@ pub fn shrink_to_fit(&mut self) {
     /// }
     /// ```
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
-    pub fn iter<'a>(&'a self) -> BitPositions<'a> {
-        BitPositions {set: self, next_idx: 0u}
+    #[stable]
+    pub fn iter(&self) -> bitv_set::Iter {
+        SetIter {set: self, next_idx: 0u}
     }
 
     /// Iterator over each u32 stored in `self` union `other`.
@@ -1415,17 +1438,17 @@ pub fn iter<'a>(&'a self) -> BitPositions<'a> {
     /// }
     /// ```
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
-    pub fn union<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
+    #[stable]
+    pub fn union<'a>(&'a self, other: &'a BitvSet) -> Union<'a> {
         fn or(w1: u32, w2: u32) -> u32 { w1 | w2 }
 
-        TwoBitPositions {
+        Union(TwoBitPositions {
             set: self,
             other: other,
             merge: or,
             current_word: 0u32,
             next_idx: 0u
-        }
+        })
     }
 
     /// Iterator over each uint stored in `self` intersect `other`.
@@ -1445,17 +1468,17 @@ fn or(w1: u32, w2: u32) -> u32 { w1 | w2 }
     /// }
     /// ```
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
-    pub fn intersection<'a>(&'a self, other: &'a BitvSet) -> Take<TwoBitPositions<'a>> {
+    #[stable]
+    pub fn intersection<'a>(&'a self, other: &'a BitvSet) -> Intersection<'a> {
         fn bitand(w1: u32, w2: u32) -> u32 { w1 & w2 }
         let min = cmp::min(self.bitv.len(), other.bitv.len());
-        TwoBitPositions {
+        Intersection(TwoBitPositions {
             set: self,
             other: other,
             merge: bitand,
             current_word: 0u32,
             next_idx: 0
-        }.take(min)
+        }.take(min))
     }
 
     /// Iterator over each uint stored in the `self` setminus `other`.
@@ -1482,17 +1505,17 @@ fn bitand(w1: u32, w2: u32) -> u32 { w1 & w2 }
     /// }
     /// ```
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
-    pub fn difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
+    #[stable]
+    pub fn difference<'a>(&'a self, other: &'a BitvSet) -> Difference<'a> {
         fn diff(w1: u32, w2: u32) -> u32 { w1 & !w2 }
 
-        TwoBitPositions {
+        Difference(TwoBitPositions {
             set: self,
             other: other,
             merge: diff,
             current_word: 0u32,
             next_idx: 0
-        }
+        })
     }
 
     /// Iterator over each u32 stored in the symmetric difference of `self` and `other`.
@@ -1513,17 +1536,17 @@ fn diff(w1: u32, w2: u32) -> u32 { w1 & !w2 }
     /// }
     /// ```
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
-    pub fn symmetric_difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
+    #[stable]
+    pub fn symmetric_difference<'a>(&'a self, other: &'a BitvSet) -> SymmetricDifference<'a> {
         fn bitxor(w1: u32, w2: u32) -> u32 { w1 ^ w2 }
 
-        TwoBitPositions {
+        SymmetricDifference(TwoBitPositions {
             set: self,
             other: other,
             merge: bitxor,
             current_word: 0u32,
             next_idx: 0
-        }
+        })
     }
 
     /// Unions in-place with the specified other bit vector.
@@ -1630,28 +1653,28 @@ pub fn symmetric_difference_with(&mut self, other: &BitvSet) {
 
     /// Return the number of set bits in this set.
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn len(&self) -> uint  {
         self.bitv.blocks().fold(0, |acc, n| acc + n.count_ones())
     }
 
     /// Returns whether there are no bits set in this set
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn is_empty(&self) -> bool {
         self.bitv.none()
     }
 
     /// Clears all bits in this set
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn clear(&mut self) {
         self.bitv.clear();
     }
 
     /// Returns `true` if this set contains the specified integer.
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn contains(&self, value: &uint) -> bool {
         let bitv = &self.bitv;
         *value < bitv.nbits && bitv[*value]
@@ -1660,14 +1683,14 @@ pub fn contains(&self, value: &uint) -> bool {
     /// Returns `true` if the set has no elements in common with `other`.
     /// This is equivalent to checking for an empty intersection.
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn is_disjoint(&self, other: &BitvSet) -> bool {
         self.intersection(other).next().is_none()
     }
 
     /// Returns `true` if the set is a subset of another.
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn is_subset(&self, other: &BitvSet) -> bool {
         let self_bitv = &self.bitv;
         let other_bitv = &other.bitv;
@@ -1681,14 +1704,14 @@ pub fn is_subset(&self, other: &BitvSet) -> bool {
 
     /// Returns `true` if the set is a superset of another.
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn is_superset(&self, other: &BitvSet) -> bool {
         other.is_subset(self)
     }
 
     /// Adds a value to the set. Returns `true` if the value was not already
     /// present in the set.
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn insert(&mut self, value: uint) -> bool {
         if self.contains(&value) {
             return false;
@@ -1706,7 +1729,7 @@ pub fn insert(&mut self, value: uint) -> bool {
 
     /// Removes a value from the set. Returns `true` if the value was
     /// present in the set.
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[stable]
     pub fn remove(&mut self, value: &uint) -> bool {
         if !self.contains(value) {
             return false;
@@ -1742,13 +1765,16 @@ fn hash(&self, state: &mut S) {
 }
 
 /// An iterator for `BitvSet`.
-pub struct BitPositions<'a> {
+#[deriving(Clone)]
+#[stable]
+pub struct SetIter<'a> {
     set: &'a BitvSet,
     next_idx: uint
 }
 
 /// An iterator combining two `BitvSet` iterators.
-pub struct TwoBitPositions<'a> {
+#[deriving(Clone)]
+struct TwoBitPositions<'a> {
     set: &'a BitvSet,
     other: &'a BitvSet,
     merge: fn(u32, u32) -> u32,
@@ -1756,7 +1782,17 @@ pub struct TwoBitPositions<'a> {
     next_idx: uint
 }
 
-impl<'a> Iterator<uint> for BitPositions<'a> {
+#[stable]
+pub struct Union<'a>(TwoBitPositions<'a>);
+#[stable]
+pub struct Intersection<'a>(Take<TwoBitPositions<'a>>);
+#[stable]
+pub struct Difference<'a>(TwoBitPositions<'a>);
+#[stable]
+pub struct SymmetricDifference<'a>(TwoBitPositions<'a>);
+
+#[stable]
+impl<'a> Iterator<uint> for SetIter<'a> {
     fn next(&mut self) -> Option<uint> {
         while self.next_idx < self.set.bitv.len() {
             let idx = self.next_idx;
@@ -1776,6 +1812,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+#[stable]
 impl<'a> Iterator<uint> for TwoBitPositions<'a> {
     fn next(&mut self) -> Option<uint> {
         while self.next_idx < self.set.bitv.len() ||
@@ -1811,8 +1848,29 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+#[stable]
+impl<'a> Iterator<uint> for Union<'a> {
+    #[inline] fn next(&mut self) -> Option<uint> { self.0.next() }
+    #[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.0.size_hint() }
+}
+
+#[stable]
+impl<'a> Iterator<uint> for Intersection<'a> {
+    #[inline] fn next(&mut self) -> Option<uint> { self.0.next() }
+    #[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.0.size_hint() }
+}
 
+#[stable]
+impl<'a> Iterator<uint> for Difference<'a> {
+    #[inline] fn next(&mut self) -> Option<uint> { self.0.next() }
+    #[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.0.size_hint() }
+}
 
+#[stable]
+impl<'a> Iterator<uint> for SymmetricDifference<'a> {
+    #[inline] fn next(&mut self) -> Option<uint> { self.0.next() }
+    #[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.0.size_hint() }
+}
 
 
 #[cfg(test)]