id_set/
lib.rs

1//! [`IdSet`] is a bitset implementation that stores data on the stack for small sizes (elements
2//! less than 196) and keeps track of the element count.
3//!
4//! # Examples
5//!
6//! The API is generally similar to that of the bit-set crate.
7//!
8//! ```
9//! # use id_set::IdSet;
10//! #
11//! let mut set = IdSet::new();
12//! set.insert(42);
13//! assert!(set.contains(42));
14//! set.remove(42);
15//! assert_eq!(set.len(), 0);
16//! ```
17//!
18//! Additionally the [`IdIter`] struct provides iteration over the bits of any iterator over `Block`
19//! values, allowing iteration over unions, intersections, and differences of arbitrarily many sets.
20//!
21//! ```
22//! # use id_set::IdSet;
23//! #
24//! let a: IdSet = (0..15).collect();
25//! let b: IdSet = (10..20).collect();
26//! let c: IdSet = (0..5).collect();
27//!
28//! assert_eq!(a.intersection(b.union(&c)).collect::<Vec<_>>(),
29//!            a.intersection(&b).union(a.intersection(&c)).collect::<Vec<_>>());
30//! ```
31//!
32//! [`IdSet`]: struct.IdSet.html
33//! [`IdIter`]: struct.IdIter.html
34
35#![deny(missing_docs, missing_copy_implementations, missing_debug_implementations)]
36
37#[cfg(test)]
38mod tests;
39mod store;
40
41pub use store::{Iter as Blocks, IntoIter as IntoBlocks};
42
43use std::{cmp, fmt, iter, ops, usize};
44use std::iter::FromIterator;
45
46use store::BlockStore;
47
48/// The element type of the set.
49pub type Id = usize;
50
51/// The block type of the underlying representation.
52pub type Block = u32;
53
54/// The number of bits in the block type.
55pub const BITS: usize = 32;
56
57#[inline]
58fn mask(bit: usize) -> Block {
59    (1 as Block) << bit
60}
61
62/// Given n and k return the largest integer m such that m*k <= n
63#[inline]
64fn ceil_div(n: usize, k: usize) -> usize {
65    if n % k == 0 { n / k } else { n / k + 1 }
66}
67
68/// Remove the least significant bit and return its index.
69#[inline]
70fn pop_lsb(n: &mut Block) -> usize {
71    let idx = n.trailing_zeros() as usize;
72    *n &= *n - 1;
73    idx
74}
75
76/// A set of `usize` elements represented by a bit vector. Storage required is proportional to the
77/// maximum element in the set.
78pub struct IdSet {
79    blocks: BlockStore,
80    // The number of set bits in the set. Since all elements are distinct usize values, it can
81    // always fit in a usize.
82    len: usize,
83}
84
85impl IdSet {
86    #[inline]
87    /// Creates an empty `IdSet`.
88    pub fn new() -> Self {
89        IdSet {
90            blocks: BlockStore::new(),
91            len: 0,
92        }
93    }
94
95    #[inline]
96    /// Creates a `IdSet` filled with all elements from 0 to n.
97    pub fn new_filled(n: usize) -> Self {
98        let (nwords, nbits) = (n / BITS, n % BITS);
99        let blocks: BlockStore = if nbits != 0 {
100            iter::repeat(!0)
101                .take(nwords)
102                .chain(iter::once(mask(nbits) - 1))
103                .collect()
104        } else {
105            iter::repeat(!0).take(nwords).collect()
106        };
107        IdSet { blocks, len: n }
108    }
109
110    #[inline]
111    /// Creates a empty `IdSet` that can hold elements up to n before reallocating.
112    pub fn with_capacity(n: usize) -> Self {
113        IdSet {
114            blocks: BlockStore::with_capacity(ceil_div(n, BITS)),
115            len: 0,
116        }
117    }
118
119    #[cfg(test)]
120    fn from_bytes(bytes: &[Block]) -> Self {
121        let blocks = BlockStore::from_iter(bytes);
122        let len = bytes
123            .iter()
124            .map(|&word| word.count_ones() as usize)
125            .sum();
126        IdSet { blocks, len }
127    }
128
129    #[inline]
130    /// Returns the number of distinct elements in the set.
131    pub fn len(&self) -> usize {
132        self.len
133    }
134
135    #[inline]
136    /// Returns true if the set is empty.
137    pub fn is_empty(&self) -> bool {
138        self.len == 0
139    }
140
141    #[inline]
142    /// Returns capacity of the set. Inserting any elements less than this will not cause
143    /// reallocation.
144    pub fn capacity(&self) -> usize {
145        self.blocks.capacity().saturating_mul(BITS)
146    }
147
148    #[inline]
149    /// Resizes the set such that `capacity() >= cap`.
150    pub fn reserve(&mut self, cap: usize) {
151        self.blocks.reserve(ceil_div(cap, BITS));
152    }
153
154    #[inline]
155    /// Resizes the set to minimise allocated memory.
156    pub fn shrink_to_fit(&mut self) {
157        self.blocks.shrink_to_fit();
158    }
159
160    #[inline]
161    /// Removes all elements from the set.
162    pub fn clear(&mut self) {
163        self.blocks.clear();
164        self.len = 0;
165    }
166
167    #[inline]
168    /// Inserts the given element into the set, returning true if it was not already in the set.
169    pub fn insert(&mut self, id: Id) -> bool {
170        let (word, bit) = (id / BITS, id % BITS);
171        let mask = mask(bit);
172
173        if word < self.blocks.len() {
174            if (self.blocks[word] & mask) == 0 {
175                self.blocks[word] |= mask;
176                self.len += 1;
177                true
178            } else {
179                false
180            }
181        } else {
182            self.blocks.resize(word + 1);
183            self.blocks[word] = mask;
184            self.len += 1;
185            true
186        }
187    }
188
189    #[inline]
190    /// Removes the given element from the set, returning true if it was in the set.
191    pub fn remove(&mut self, id: Id) -> bool {
192        let (word, bit) = (id / BITS, id % BITS);
193        let mask = mask(bit);
194
195        if word < self.blocks.len() {
196            if (self.blocks[word] & mask) != 0 {
197                self.blocks[word] &= !mask;
198                self.len -= 1;
199                true
200            } else {
201                false
202            }
203        } else {
204            false
205        }
206    }
207
208    #[inline]
209    /// Returns true if the given element is in the set.
210    pub fn contains(&self, id: Id) -> bool {
211        let (word, bit) = (id / BITS, id % BITS);
212
213        if word < self.blocks.len() {
214            (self.blocks[word] & mask(bit)) != 0
215        } else {
216            false
217        }
218    }
219
220    #[inline]
221    /// Remove all elements that don't satisfy the predicate.
222    pub fn retain<F: FnMut(Id) -> bool>(&mut self, mut pred: F) {
223        let mut idx = 0;
224        for word in self.blocks.iter_mut() {
225            let mut block = *word;
226
227            while block != 0 {
228                let id = idx + block.trailing_zeros() as usize;
229                let mask = block - 1;
230
231                if !pred(id) {
232                    self.len -= 1;
233                    *word &= mask;
234                }
235                block &= mask;
236            }
237
238            idx += BITS;
239        }
240    }
241
242    #[inline]
243    /// Returns the underlying blocks as a slice.
244    pub fn as_blocks(&self) -> &[Block] {
245        &self.blocks
246    }
247
248    #[inline]
249    /// An iterator over all elements in increasing order.
250    pub fn iter(&self) -> Iter {
251        Iter {
252            inner: IdIter::new(self.blocks.iter()),
253            len: self.len,
254        }
255    }
256
257    #[inline]
258    /// Returns an iterator over the blocks of the underlying representation.
259    pub fn blocks(&self) -> Blocks {
260        self.blocks.iter()
261    }
262
263    #[inline]
264    /// Returns a consuming iterator over the blocks of the underlying representation.
265    pub fn into_blocks(self) -> IntoBlocks {
266        self.blocks.into_iter()
267    }
268
269    #[inline]
270    /// Takes the union of the set with another. Equivalent to `self | other`.
271    pub fn union<I>(&self, other: I) -> BlockIter<Union<Blocks, I::Blocks>>
272        where I: IntoBlockIterator
273    {
274        self | other
275    }
276
277    #[inline]
278    /// Takes the intersection of the set with another. Equivalent to `self & other`.
279    pub fn intersection<I>(&self, other: I) -> BlockIter<Intersection<Blocks, I::Blocks>>
280        where I: IntoBlockIterator
281    {
282        self & other
283    }
284
285    #[inline]
286    /// Takes the difference of the set with another. Equivalent to `self - other`.
287    pub fn difference<I>(&self, other: I) -> BlockIter<Difference<Blocks, I::Blocks>>
288        where I: IntoBlockIterator
289    {
290        self - other
291    }
292
293    #[inline]
294    /// Takes the symmetric difference of the set with another. Equivalent to `self ^ other`.
295    pub fn symmetric_difference<I>(&self,
296                                   other: I)
297                                   -> BlockIter<SymmetricDifference<Blocks, I::Blocks>>
298        where I: IntoBlockIterator
299    {
300        self ^ other
301    }
302
303    #[inline]
304    /// Consumes the set and takes the union with another.
305    pub fn into_union<I>(self, other: I) -> BlockIter<Union<IntoBlocks, I::Blocks>>
306        where I: IntoBlockIterator
307    {
308        self | other
309    }
310
311    #[inline]
312    /// Consumes the set and takes the intersection with another.
313    pub fn into_intersection<I>(self, other: I) -> BlockIter<Intersection<IntoBlocks, I::Blocks>>
314        where I: IntoBlockIterator
315    {
316        self & other
317    }
318
319    #[inline]
320    /// Consumes the set and takes the difference with another.
321    pub fn into_difference<I>(self, other: I) -> BlockIter<Difference<IntoBlocks, I::Blocks>>
322        where I: IntoBlockIterator
323    {
324        self - other
325    }
326
327    #[inline]
328    /// Consumes the set and takes the symmetric difference with another.
329    pub fn into_symmetric_difference<I>(self,
330                                        other: I)
331                                        -> BlockIter<SymmetricDifference<IntoBlocks, I::Blocks>>
332        where I: IntoBlockIterator
333    {
334        self ^ other
335    }
336
337    #[inline]
338    /// Take the union of the set inplace with another set. Equivalent to `*self |= other`.
339    pub fn inplace_union<I>(&mut self, other: I)
340        where I: IntoBlockIterator
341    {
342        *self |= other
343    }
344
345    #[inline]
346    /// Take the intersection of the set inplace with another set. Equivalent to `*self &= other`.
347    pub fn inplace_intersection<I>(&mut self, other: I)
348        where I: IntoBlockIterator
349    {
350        *self &= other
351    }
352
353    #[inline]
354    /// Take the difference of the set inplace with another set. Equivalent to `*self -= other`.
355    pub fn inplace_difference<I>(&mut self, other: I)
356        where I: IntoBlockIterator
357    {
358        *self -= other
359    }
360
361    #[inline]
362    /// Take the symmetric difference of the set inplace with another set. Equivalent to
363    /// `*self ^= other`.
364    pub fn inplace_symmetric_difference<I>(&mut self, other: I)
365        where I: IntoBlockIterator
366    {
367        *self ^= other
368    }
369
370    #[inline]
371    /// Returns true if the sets are disjoint.
372    pub fn is_disjoint(&self, other: &Self) -> bool {
373        self.len().saturating_add(other.len()) < cmp::max(self.capacity(), other.capacity()) &&
374        self.intersection(other).into_iter().count() == 0
375    }
376
377    #[inline]
378    /// Returns true if self is a superset of other.
379    pub fn is_superset(&self, other: &Self) -> bool {
380        !other.is_subset(self)
381    }
382
383    #[inline]
384    /// Returns true if self is a subset of other.
385    pub fn is_subset(&self, other: &Self) -> bool {
386        self.len() <= other.len() && self.difference(other).into_iter().count() == 0
387    }
388}
389
390impl Clone for IdSet {
391    #[inline]
392    fn clone(&self) -> Self {
393        IdSet {
394            blocks: self.blocks.clone(),
395            len: self.len,
396        }
397    }
398
399    #[inline]
400    fn clone_from(&mut self, source: &Self) {
401        self.blocks.clone_from(&source.blocks);
402        self.len = source.len;
403    }
404}
405
406impl fmt::Debug for IdSet {
407    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
408        write!(f, "{{")?;
409        let mut iter = self.iter();
410        if let Some(id) = iter.next() {
411            write!(f, "{:?}", id)?;
412            for id in iter {
413                write!(f, ", {:?}", id)?;
414            }
415        }
416        write!(f, "}}")
417    }
418}
419
420impl Default for IdSet {
421    #[inline]
422    fn default() -> Self {
423        IdSet::new()
424    }
425}
426
427impl Eq for IdSet {}
428
429impl PartialEq for IdSet {
430    fn eq(&self, other: &Self) -> bool {
431        if self.len != other.len {
432            return false;
433        }
434        let (mut lhs, mut rhs) = (self.blocks.iter(), other.blocks.iter());
435        loop {
436            match (lhs.next(), rhs.next()) {
437                (Some(l), Some(r)) => {
438                    if l != r {
439                        return false;
440                    }
441                }
442                (None, None) => return true,
443                (Some(l), None) => return l == 0 && lhs.all(|block| block == 0),
444                (None, Some(r)) => return r == 0 && rhs.all(|block| block == 0),
445            }
446        }
447    }
448}
449
450impl Extend<Id> for IdSet {
451    #[inline]
452    fn extend<I: IntoIterator<Item = Id>>(&mut self, iter: I) {
453        for id in iter {
454            self.insert(id);
455        }
456    }
457}
458
459impl FromIterator<Id> for IdSet {
460    #[inline]
461    fn from_iter<I: IntoIterator<Item = Id>>(iter: I) -> Self {
462        let mut set = IdSet::new();
463        for id in iter {
464            set.insert(id);
465        }
466        set
467    }
468}
469
470impl<'a> IntoIterator for &'a IdSet {
471    type Item = Id;
472    type IntoIter = Iter<'a>;
473
474    #[inline]
475    fn into_iter(self) -> Self::IntoIter {
476        self.iter()
477    }
478}
479
480#[derive(Clone, Debug)]
481/// An iterator over all elements in increasing order.
482pub struct Iter<'a> {
483    inner: IdIter<Blocks<'a>>,
484    len: usize,
485}
486
487impl<'a> Iterator for Iter<'a> {
488    type Item = Id;
489
490    #[inline]
491    fn next(&mut self) -> Option<Self::Item> {
492        let id = self.inner.next();
493        if id.is_some() {
494            self.len -= 1;
495        }
496        id
497    }
498
499    #[inline]
500    fn size_hint(&self) -> (usize, Option<usize>) {
501        (self.len, Some(self.len))
502    }
503}
504
505impl<'a> ExactSizeIterator for Iter<'a> {
506    #[inline]
507    fn len(&self) -> usize {
508        self.len
509    }
510}
511
512impl IntoIterator for IdSet {
513    type Item = Id;
514    type IntoIter = IntoIter;
515
516    #[inline]
517    fn into_iter(self) -> Self::IntoIter {
518        let len = self.len;
519        IntoIter {
520            inner: IdIter::new(self.blocks.into_iter()),
521            len,
522        }
523    }
524}
525
526#[derive(Clone, Debug)]
527/// A consuming iterator over all elements in increasing order.
528pub struct IntoIter {
529    inner: IdIter<IntoBlocks>,
530    len: usize,
531}
532
533impl Iterator for IntoIter {
534    type Item = Id;
535
536    #[inline]
537    fn next(&mut self) -> Option<Self::Item> {
538
539        let id = self.inner.next();
540        if id.is_some() {
541            self.len -= 1;
542        }
543        id
544    }
545
546    #[inline]
547    fn size_hint(&self) -> (usize, Option<usize>) {
548        (self.len, Some(self.len))
549    }
550}
551
552impl ExactSizeIterator for IntoIter {
553    #[inline]
554    fn len(&self) -> usize {
555        self.len
556    }
557}
558
559#[derive(Clone, Debug)]
560/// Transforms an iterator over blocks into an iterator over elements.
561pub struct IdIter<B> {
562    blocks: B,
563    word: Block,
564    idx: usize,
565}
566
567impl<B> IdIter<B>
568    where B: ExactSizeIterator<Item = Block>
569{
570    /// Creates a new iterator over elements of a block iterator.
571    pub fn new<I: IntoBlockIterator<Blocks = B>>(iter: I) -> Self {
572        let mut blocks = iter.into_block_iter().into_inner();
573        let word = blocks.next().unwrap_or(0);
574        IdIter {
575            blocks,
576            word,
577            idx: 0,
578        }
579    }
580}
581
582impl<B> Iterator for IdIter<B>
583    where B: ExactSizeIterator<Item = Block>
584{
585    type Item = Id;
586
587    #[inline]
588    fn next(&mut self) -> Option<Self::Item> {
589        while self.word == 0 {
590            match self.blocks.next() {
591                Some(word) => self.word = word,
592                None => return None,
593            }
594            self.idx += BITS;
595        }
596        Some(self.idx + pop_lsb(&mut self.word))
597    }
598
599    #[inline]
600    fn size_hint(&self) -> (usize, Option<usize>) {
601        let ones = self.word.count_ones() as usize;
602        (ones, Some(self.blocks.len().saturating_mul(BITS).saturating_add(ones)))
603    }
604}
605
606#[derive(Clone, Debug)]
607/// Represents a view into the blocks of a set or combination of sets. An iterator over the elements
608/// can be obtained with `into_iter()`.
609pub struct BlockIter<B> {
610    inner: B,
611}
612
613impl<B> BlockIter<B> {
614    /// Returns the iterator over raw blocks.
615    pub fn into_inner(self) -> B {
616        self.inner
617    }
618}
619
620impl<B> BlockIter<B>
621    where B: ExactSizeIterator<Item = Block>
622{
623    /// Creates new block iterator.
624    pub fn new(inner: B) -> Self {
625        BlockIter { inner }
626    }
627
628    #[inline]
629    /// Equivalent to `self.into_iter().collect()`.
630    pub fn collect<T>(self) -> T
631        where T: iter::FromIterator<Id>
632    {
633        self.into_iter().collect()
634    }
635
636    #[inline]
637    /// Collects the iterator into an `IdSet`.
638    pub fn into_set(self) -> IdSet {
639        let mut len = 0;
640        let blocks = self.inner.inspect(|&block| len += block.count_ones() as usize).collect();
641        IdSet {
642            blocks, len,
643        }
644    }
645
646    #[inline]
647    /// Takes the union of the blocks with another block iterator. Equivalent to `self | other`.
648    pub fn union<I>(self, other: I) -> BlockIter<Union<B, I::Blocks>>
649        where I: IntoBlockIterator
650    {
651        self | other
652    }
653
654    #[inline]
655    /// Takes the intersection of the blocks with another block iterator. Equivalent to
656    /// `self & other`.
657    pub fn intersection<I>(self, other: I) -> BlockIter<Intersection<B, I::Blocks>>
658        where I: IntoBlockIterator
659    {
660        self & other
661    }
662
663    #[inline]
664    /// Takes the difference of the blocks with another block iterator. Equivalent to
665    /// `self - other`.
666    pub fn difference<I>(self, other: I) -> BlockIter<Difference<B, I::Blocks>>
667        where I: IntoBlockIterator
668    {
669        self - other
670    }
671
672    #[inline]
673    /// Takes the symmetric difference of the blocks with another block iterator. Equivalent to
674    /// `self ^ other`.
675    pub fn symmetric_difference<I>(self, other: I) -> BlockIter<SymmetricDifference<B, I::Blocks>>
676        where I: IntoBlockIterator
677    {
678        self ^ other
679    }
680}
681
682impl<B> IntoIterator for BlockIter<B>
683    where B: ExactSizeIterator<Item = Block>
684{
685    type Item = Id;
686    type IntoIter = IdIter<B>;
687
688    fn into_iter(self) -> Self::IntoIter {
689        IdIter::new(self.inner)
690    }
691}
692
693/// Conversion into an iterator over blocks.
694pub trait IntoBlockIterator {
695    /// The raw iterator type.
696    type Blocks: ExactSizeIterator<Item = Block>;
697
698    /// Creates a block iterator.
699    fn into_block_iter(self) -> BlockIter<Self::Blocks>;
700}
701
702impl<B> IntoBlockIterator for B
703    where B: ExactSizeIterator<Item = Block>
704{
705    type Blocks = B;
706
707    fn into_block_iter(self) -> BlockIter<Self::Blocks> {
708        BlockIter { inner: self }
709    }
710}
711
712impl<B> IntoBlockIterator for BlockIter<B>
713    where B: ExactSizeIterator<Item = Block>
714{
715    type Blocks = B;
716
717    #[inline]
718    fn into_block_iter(self) -> BlockIter<Self::Blocks> {
719        self
720    }
721}
722
723impl<'a> IntoBlockIterator for &'a IdSet {
724    type Blocks = Blocks<'a>;
725
726    #[inline]
727    fn into_block_iter(self) -> BlockIter<Self::Blocks> {
728        self.blocks().into_block_iter()
729    }
730}
731
732impl IntoBlockIterator for IdSet {
733    type Blocks = IntoBlocks;
734
735    #[inline]
736    fn into_block_iter(self) -> BlockIter<Self::Blocks> {
737        self.into_blocks().into_block_iter()
738    }
739}
740
741impl<B, I> ops::BitAnd<I> for BlockIter<B>
742    where B: ExactSizeIterator<Item = Block>,
743          I: IntoBlockIterator
744{
745    type Output = BlockIter<Intersection<B, I::Blocks>>;
746
747    #[inline]
748    /// Takes the intersection of two objects.
749    fn bitand(self, other: I) -> Self::Output {
750        BlockIter {
751            inner: Intersection {
752                left: self.inner,
753                right: other.into_block_iter().inner,
754            },
755        }
756    }
757}
758
759impl<B, I> ops::BitOr<I> for BlockIter<B>
760    where B: ExactSizeIterator<Item = Block>,
761          I: IntoBlockIterator
762{
763    type Output = BlockIter<Union<B, I::Blocks>>;
764
765    #[inline]
766    /// Takes the union of two objects.
767    fn bitor(self, other: I) -> Self::Output {
768        BlockIter {
769            inner: Union {
770                left: self.inner,
771                right: other.into_block_iter().inner,
772            },
773        }
774    }
775}
776
777impl<B, I> ops::BitXor<I> for BlockIter<B>
778    where B: ExactSizeIterator<Item = Block>,
779          I: IntoBlockIterator
780{
781    type Output = BlockIter<SymmetricDifference<B, I::Blocks>>;
782
783    #[inline]
784    /// Takes the symmetric difference of two objects.
785    fn bitxor(self, other: I) -> Self::Output {
786        BlockIter {
787            inner: SymmetricDifference {
788                left: self.inner,
789                right: other.into_block_iter().inner,
790            },
791        }
792    }
793}
794
795impl<B, I> ops::Sub<I> for BlockIter<B>
796    where B: ExactSizeIterator<Item = Block>,
797          I: IntoBlockIterator
798{
799    type Output = BlockIter<Difference<B, I::Blocks>>;
800
801    #[inline]
802    /// Takes the difference of two objects.
803    fn sub(self, other: I) -> Self::Output {
804        BlockIter {
805            inner: Difference {
806                left: self.inner,
807                right: other.into_block_iter().inner,
808            },
809        }
810    }
811}
812
813impl<'a, I> ops::BitAnd<I> for &'a IdSet
814    where I: IntoBlockIterator
815{
816    type Output = BlockIter<Intersection<Blocks<'a>, I::Blocks>>;
817
818    #[inline]
819    /// Takes the intersection of two objects.
820    fn bitand(self, other: I) -> Self::Output {
821        self.into_block_iter() & other
822    }
823}
824
825impl<'a, I> ops::BitOr<I> for &'a IdSet
826    where I: IntoBlockIterator
827{
828    type Output = BlockIter<Union<Blocks<'a>, I::Blocks>>;
829
830    #[inline]
831    /// Takes the union of two objects.
832    fn bitor(self, other: I) -> Self::Output {
833        self.into_block_iter() | other
834    }
835}
836
837impl<'a, I> ops::BitXor<I> for &'a IdSet
838    where I: IntoBlockIterator
839{
840    type Output = BlockIter<SymmetricDifference<Blocks<'a>, I::Blocks>>;
841
842    #[inline]
843    /// Takes the symmetric difference of two objects.
844    fn bitxor(self, other: I) -> Self::Output {
845        self.into_block_iter() ^ other
846    }
847}
848
849impl<'a, I> ops::Sub<I> for &'a IdSet
850    where I: IntoBlockIterator
851{
852    type Output = BlockIter<Difference<Blocks<'a>, I::Blocks>>;
853
854    #[inline]
855    /// Takes the difference of two objects.
856    fn sub(self, other: I) -> Self::Output {
857        self.into_block_iter() - other
858    }
859}
860
861impl<I> ops::BitAnd<I> for IdSet
862    where I: IntoBlockIterator
863{
864    type Output = BlockIter<Intersection<IntoBlocks, I::Blocks>>;
865
866    #[inline]
867    /// Takes the intersection of two objects.
868    fn bitand(self, other: I) -> Self::Output {
869        self.into_block_iter() & other
870    }
871}
872
873impl<I> ops::BitOr<I> for IdSet
874    where I: IntoBlockIterator
875{
876    type Output = BlockIter<Union<IntoBlocks, I::Blocks>>;
877
878    #[inline]
879    /// Takes the union of two objects.
880    fn bitor(self, other: I) -> Self::Output {
881        self.into_block_iter() | other
882    }
883}
884
885impl<I> ops::BitXor<I> for IdSet
886    where I: IntoBlockIterator
887{
888    type Output = BlockIter<SymmetricDifference<IntoBlocks, I::Blocks>>;
889
890    #[inline]
891    /// Takes the symmetric difference of two objects.
892    fn bitxor(self, other: I) -> Self::Output {
893        self.into_block_iter() ^ other
894    }
895}
896
897impl<I> ops::Sub<I> for IdSet
898    where I: IntoBlockIterator
899{
900    type Output = BlockIter<Difference<IntoBlocks, I::Blocks>>;
901
902    #[inline]
903    /// Takes the difference of two objects.
904    fn sub(self, other: I) -> Self::Output {
905        self.into_block_iter() - other
906    }
907}
908
909impl<I> ops::BitAndAssign<I> for IdSet
910    where I: IntoBlockIterator
911{
912    #[inline]
913    /// Takes the inplace intersection of the set with another.
914    fn bitand_assign(&mut self, other: I) {
915        let blocks = other.into_block_iter().into_inner();
916        if blocks.len() < self.blocks.len() {
917            for block in self.blocks.drain(blocks.len()) {
918                self.len -= block.count_ones() as usize;
919            }
920        }
921        for (lblock, rblock) in self.blocks.iter_mut().zip(blocks) {
922            self.len -= (*lblock & !rblock).count_ones() as usize;
923            *lblock &= rblock;
924        }
925    }
926}
927
928impl<I> ops::BitOrAssign<I> for IdSet
929    where I: IntoBlockIterator
930{
931    #[inline]
932    /// Takes the inplace union of the set with another.
933    fn bitor_assign(&mut self, other: I) {
934        let mut blocks = other.into_block_iter().into_inner();
935        for lblock in self.blocks.iter_mut() {
936            if let Some(rblock) = blocks.next() {
937                self.len += (rblock & !*lblock).count_ones() as usize;
938                *lblock |= rblock;
939            } else {
940                return;
941            }
942        }
943        let len = &mut self.len;
944        self.blocks
945            .extend(blocks.inspect(|block| *len += block.count_ones() as usize));
946    }
947}
948
949impl<I> ops::BitXorAssign<I> for IdSet
950    where I: IntoBlockIterator
951{
952    #[inline]
953    /// Takes the inplace symmetric difference of the set with another.
954    fn bitxor_assign(&mut self, other: I) {
955        let mut blocks = other.into_block_iter().into_inner();
956        for lblock in self.blocks.iter_mut() {
957            if let Some(rblock) = blocks.next() {
958                self.len -= lblock.count_ones() as usize;
959                *lblock ^= rblock;
960                self.len += lblock.count_ones() as usize;
961            } else {
962                return;
963            }
964        }
965        let len = &mut self.len;
966        self.blocks
967            .extend(blocks.inspect(|block| *len += block.count_ones() as usize));
968    }
969}
970
971impl<I> ops::SubAssign<I> for IdSet
972    where I: IntoBlockIterator
973{
974    #[inline]
975    /// Takes the inplace difference of the set with another.
976    fn sub_assign(&mut self, other: I) {
977        for (lblock, rblock) in self.blocks
978                .iter_mut()
979                .zip(other.into_block_iter().into_inner()) {
980            self.len -= (*lblock & rblock).count_ones() as usize;
981            *lblock &= !rblock;
982        }
983    }
984}
985
986#[derive(Clone, Debug)]
987/// Takes the intersection of two block iterators.
988pub struct Intersection<L, R> {
989    left: L,
990    right: R,
991}
992
993impl<L, R> Iterator for Intersection<L, R>
994    where L: ExactSizeIterator<Item = Block>,
995          R: ExactSizeIterator<Item = Block>
996{
997    type Item = Block;
998
999    #[inline]
1000    fn next(&mut self) -> Option<Self::Item> {
1001        if let (Some(l), Some(r)) = (self.left.next(), self.right.next()) {
1002            Some(l & r)
1003        } else {
1004            None
1005        }
1006    }
1007
1008    #[inline]
1009    fn size_hint(&self) -> (usize, Option<usize>) {
1010        let len = self.len();
1011        (len, Some(len))
1012    }
1013}
1014
1015impl<L, R> ExactSizeIterator for Intersection<L, R>
1016    where L: ExactSizeIterator<Item = Block>,
1017          R: ExactSizeIterator<Item = Block>
1018{
1019    #[inline]
1020    fn len(&self) -> usize {
1021        cmp::min(self.left.len(), self.right.len())
1022    }
1023}
1024
1025#[derive(Clone, Debug)]
1026/// Takes the union of two block iterators.
1027pub struct Union<L, R> {
1028    left: L,
1029    right: R,
1030}
1031
1032impl<L, R> Iterator for Union<L, R>
1033    where L: ExactSizeIterator<Item = Block>,
1034          R: ExactSizeIterator<Item = Block>
1035{
1036    type Item = Block;
1037
1038    #[inline]
1039    fn next(&mut self) -> Option<Self::Item> {
1040        match (self.left.next(), self.right.next()) {
1041            (Some(l), Some(r)) => Some(l | r),
1042            (Some(l), None) => Some(l),
1043            (None, Some(r)) => Some(r),
1044            (None, None) => None,
1045        }
1046    }
1047
1048    #[inline]
1049    fn size_hint(&self) -> (usize, Option<usize>) {
1050        let len = self.len();
1051        (len, Some(len))
1052    }
1053}
1054
1055impl<L, R> ExactSizeIterator for Union<L, R>
1056    where L: ExactSizeIterator<Item = Block>,
1057          R: ExactSizeIterator<Item = Block>
1058{
1059    #[inline]
1060    fn len(&self) -> usize {
1061        cmp::max(self.left.len(), self.right.len())
1062    }
1063}
1064
1065#[derive(Clone, Debug)]
1066/// Takes the symmetric difference of two block iterators.
1067pub struct SymmetricDifference<L, R> {
1068    left: L,
1069    right: R,
1070}
1071
1072impl<L, R> Iterator for SymmetricDifference<L, R>
1073    where L: ExactSizeIterator<Item = Block>,
1074          R: ExactSizeIterator<Item = Block>
1075{
1076    type Item = Block;
1077
1078    #[inline]
1079    fn next(&mut self) -> Option<Self::Item> {
1080        match (self.left.next(), self.right.next()) {
1081            (Some(l), Some(r)) => Some(l ^ r),
1082            (Some(l), None) => Some(l),
1083            (None, Some(r)) => Some(r),
1084            (None, None) => None,
1085        }
1086    }
1087
1088    #[inline]
1089    fn size_hint(&self) -> (usize, Option<usize>) {
1090        let len = self.len();
1091        (len, Some(len))
1092    }
1093}
1094
1095impl<L, R> ExactSizeIterator for SymmetricDifference<L, R>
1096    where L: ExactSizeIterator<Item = Block>,
1097          R: ExactSizeIterator<Item = Block>
1098{
1099    #[inline]
1100    fn len(&self) -> usize {
1101        cmp::max(self.left.len(), self.right.len())
1102    }
1103}
1104
1105#[derive(Clone, Debug)]
1106/// Takes the difference of two block iterators.
1107pub struct Difference<L, R> {
1108    left: L,
1109    right: R,
1110}
1111
1112impl<L, R> Iterator for Difference<L, R>
1113    where L: ExactSizeIterator<Item = Block>,
1114          R: ExactSizeIterator<Item = Block>
1115{
1116    type Item = Block;
1117
1118    #[inline]
1119    fn next(&mut self) -> Option<Self::Item> {
1120        self.left
1121            .next()
1122            .map(|l| l & !self.right.next().unwrap_or(0))
1123    }
1124
1125    #[inline]
1126    fn size_hint(&self) -> (usize, Option<usize>) {
1127        let len = self.len();
1128        (len, Some(len))
1129    }
1130}
1131
1132impl<L, R> ExactSizeIterator for Difference<L, R>
1133    where L: ExactSizeIterator<Item = Block>,
1134          R: ExactSizeIterator<Item = Block>
1135{
1136    #[inline]
1137    fn len(&self) -> usize {
1138        self.left.len()
1139    }
1140}