|  | use alloc::vec::Vec; | 
|  | use std::fmt; | 
|  | use std::iter::FusedIterator; | 
|  |  | 
|  | use super::combinations::{combinations, Combinations}; | 
|  | use crate::adaptors::checked_binomial; | 
|  | use crate::size_hint::{self, SizeHint}; | 
|  |  | 
|  | /// An iterator to iterate through the powerset of the elements from an iterator. | 
|  | /// | 
|  | /// See [`.powerset()`](crate::Itertools::powerset) for more | 
|  | /// information. | 
|  | #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] | 
|  | pub struct Powerset<I: Iterator> { | 
|  | combs: Combinations<I>, | 
|  | } | 
|  |  | 
|  | impl<I> Clone for Powerset<I> | 
|  | where | 
|  | I: Clone + Iterator, | 
|  | I::Item: Clone, | 
|  | { | 
|  | clone_fields!(combs); | 
|  | } | 
|  |  | 
|  | impl<I> fmt::Debug for Powerset<I> | 
|  | where | 
|  | I: Iterator + fmt::Debug, | 
|  | I::Item: fmt::Debug, | 
|  | { | 
|  | debug_fmt_fields!(Powerset, combs); | 
|  | } | 
|  |  | 
|  | /// Create a new `Powerset` from a clonable iterator. | 
|  | pub fn powerset<I>(src: I) -> Powerset<I> | 
|  | where | 
|  | I: Iterator, | 
|  | I::Item: Clone, | 
|  | { | 
|  | Powerset { | 
|  | combs: combinations(src, 0), | 
|  | } | 
|  | } | 
|  |  | 
|  | impl<I: Iterator> Powerset<I> { | 
|  | /// Returns true if `k` has been incremented, false otherwise. | 
|  | fn increment_k(&mut self) -> bool { | 
|  | if self.combs.k() < self.combs.n() || self.combs.k() == 0 { | 
|  | self.combs.reset(self.combs.k() + 1); | 
|  | true | 
|  | } else { | 
|  | false | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | impl<I> Iterator for Powerset<I> | 
|  | where | 
|  | I: Iterator, | 
|  | I::Item: Clone, | 
|  | { | 
|  | type Item = Vec<I::Item>; | 
|  |  | 
|  | fn next(&mut self) -> Option<Self::Item> { | 
|  | if let Some(elt) = self.combs.next() { | 
|  | Some(elt) | 
|  | } else if self.increment_k() { | 
|  | self.combs.next() | 
|  | } else { | 
|  | None | 
|  | } | 
|  | } | 
|  |  | 
|  | fn nth(&mut self, mut n: usize) -> Option<Self::Item> { | 
|  | loop { | 
|  | match self.combs.try_nth(n) { | 
|  | Ok(item) => return Some(item), | 
|  | Err(steps) => { | 
|  | if !self.increment_k() { | 
|  | return None; | 
|  | } | 
|  | n -= steps; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | fn size_hint(&self) -> SizeHint { | 
|  | let k = self.combs.k(); | 
|  | // Total bounds for source iterator. | 
|  | let (n_min, n_max) = self.combs.src().size_hint(); | 
|  | let low = remaining_for(n_min, k).unwrap_or(usize::MAX); | 
|  | let upp = n_max.and_then(|n| remaining_for(n, k)); | 
|  | size_hint::add(self.combs.size_hint(), (low, upp)) | 
|  | } | 
|  |  | 
|  | fn count(self) -> usize { | 
|  | let k = self.combs.k(); | 
|  | let (n, combs_count) = self.combs.n_and_count(); | 
|  | combs_count + remaining_for(n, k).unwrap() | 
|  | } | 
|  |  | 
|  | fn fold<B, F>(self, mut init: B, mut f: F) -> B | 
|  | where | 
|  | F: FnMut(B, Self::Item) -> B, | 
|  | { | 
|  | let mut it = self.combs; | 
|  | if it.k() == 0 { | 
|  | init = it.by_ref().fold(init, &mut f); | 
|  | it.reset(1); | 
|  | } | 
|  | init = it.by_ref().fold(init, &mut f); | 
|  | // n is now known for sure because k >= 1 and all k-combinations have been generated. | 
|  | for k in it.k() + 1..=it.n() { | 
|  | it.reset(k); | 
|  | init = it.by_ref().fold(init, &mut f); | 
|  | } | 
|  | init | 
|  | } | 
|  | } | 
|  |  | 
|  | impl<I> FusedIterator for Powerset<I> | 
|  | where | 
|  | I: Iterator, | 
|  | I::Item: Clone, | 
|  | { | 
|  | } | 
|  |  | 
|  | fn remaining_for(n: usize, k: usize) -> Option<usize> { | 
|  | (k + 1..=n).try_fold(0usize, |sum, i| sum.checked_add(checked_binomial(n, i)?)) | 
|  | } |