1#![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
48pub type Id = usize;
50
51pub type Block = u32;
53
54pub const BITS: usize = 32;
56
57#[inline]
58fn mask(bit: usize) -> Block {
59 (1 as Block) << bit
60}
61
62#[inline]
64fn ceil_div(n: usize, k: usize) -> usize {
65 if n % k == 0 { n / k } else { n / k + 1 }
66}
67
68#[inline]
70fn pop_lsb(n: &mut Block) -> usize {
71 let idx = n.trailing_zeros() as usize;
72 *n &= *n - 1;
73 idx
74}
75
76pub struct IdSet {
79 blocks: BlockStore,
80 len: usize,
83}
84
85impl IdSet {
86 #[inline]
87 pub fn new() -> Self {
89 IdSet {
90 blocks: BlockStore::new(),
91 len: 0,
92 }
93 }
94
95 #[inline]
96 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 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 pub fn len(&self) -> usize {
132 self.len
133 }
134
135 #[inline]
136 pub fn is_empty(&self) -> bool {
138 self.len == 0
139 }
140
141 #[inline]
142 pub fn capacity(&self) -> usize {
145 self.blocks.capacity().saturating_mul(BITS)
146 }
147
148 #[inline]
149 pub fn reserve(&mut self, cap: usize) {
151 self.blocks.reserve(ceil_div(cap, BITS));
152 }
153
154 #[inline]
155 pub fn shrink_to_fit(&mut self) {
157 self.blocks.shrink_to_fit();
158 }
159
160 #[inline]
161 pub fn clear(&mut self) {
163 self.blocks.clear();
164 self.len = 0;
165 }
166
167 #[inline]
168 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 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 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 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 pub fn as_blocks(&self) -> &[Block] {
245 &self.blocks
246 }
247
248 #[inline]
249 pub fn iter(&self) -> Iter {
251 Iter {
252 inner: IdIter::new(self.blocks.iter()),
253 len: self.len,
254 }
255 }
256
257 #[inline]
258 pub fn blocks(&self) -> Blocks {
260 self.blocks.iter()
261 }
262
263 #[inline]
264 pub fn into_blocks(self) -> IntoBlocks {
266 self.blocks.into_iter()
267 }
268
269 #[inline]
270 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 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 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 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 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 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 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 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 pub fn inplace_union<I>(&mut self, other: I)
340 where I: IntoBlockIterator
341 {
342 *self |= other
343 }
344
345 #[inline]
346 pub fn inplace_intersection<I>(&mut self, other: I)
348 where I: IntoBlockIterator
349 {
350 *self &= other
351 }
352
353 #[inline]
354 pub fn inplace_difference<I>(&mut self, other: I)
356 where I: IntoBlockIterator
357 {
358 *self -= other
359 }
360
361 #[inline]
362 pub fn inplace_symmetric_difference<I>(&mut self, other: I)
365 where I: IntoBlockIterator
366 {
367 *self ^= other
368 }
369
370 #[inline]
371 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 pub fn is_superset(&self, other: &Self) -> bool {
380 !other.is_subset(self)
381 }
382
383 #[inline]
384 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)]
481pub 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)]
527pub 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)]
560pub 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 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)]
607pub struct BlockIter<B> {
610 inner: B,
611}
612
613impl<B> BlockIter<B> {
614 pub fn into_inner(self) -> B {
616 self.inner
617 }
618}
619
620impl<B> BlockIter<B>
621 where B: ExactSizeIterator<Item = Block>
622{
623 pub fn new(inner: B) -> Self {
625 BlockIter { inner }
626 }
627
628 #[inline]
629 pub fn collect<T>(self) -> T
631 where T: iter::FromIterator<Id>
632 {
633 self.into_iter().collect()
634 }
635
636 #[inline]
637 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 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 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 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 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
693pub trait IntoBlockIterator {
695 type Blocks: ExactSizeIterator<Item = Block>;
697
698 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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)]
987pub 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)]
1026pub 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)]
1066pub 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)]
1106pub 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}