truth_values/
lib.rs

1//! Tiny, zero-dependency, zero-allocation*, `no_std` library for generating all possible
2//! combinations of `n` [`bool`]s. Useful for testing [boolean functions],
3//! verifying [logical equivalence], and generating [truth tables].
4//! _\*Optional `alloc` feature for [`Vec`] related functions._
5//!
6//! [boolean functions]: https://en.wikipedia.org/wiki/Boolean_function
7//! [logical equivalence]: https://en.wikipedia.org/wiki/Logical_equivalence
8//! [truth tables]: https://en.wikipedia.org/wiki/Truth_table
9//!
10//! # Example - `each()` and `each_const()`
11//!
12//! Consider implementing an interpreter or optimizer, and now you
13//! want to assert [logical equivalence] between expressions, e.g.
14//! asserting [De Morgan's laws]:
15//!
16//! - not (A or B)  = (not A) and (not B)
17//! - not (A and B) = (not A) or (not B)
18//!
19//! [De Morgan's laws]: https://en.wikipedia.org/wiki/De_Morgan%27s_laws
20//!
21//! Using [const generic variant](crate::each_const), i.e. where `N` is const:
22//!
23//! ```
24//! # use truth_values::each_const;
25//! each_const(|[a, b]| {
26//!     assert_eq!(!(a || b), !a && !b);
27//!     assert_eq!(!(a && b), !a || !b);
28//! });
29//! // The closure is called for each combination of 2 `bool`s, i.e.:
30//! // [false, false]
31//! // [true,  false]
32//! // [false, true]
33//! // [true,  true]
34//! ```
35//!
36//! Using [non-const generic variant](crate::each), i.e. where `n` can be dynamic:
37//!
38//! ```
39//! # use truth_values::each;
40//! each(2, |bools| match bools {
41//!     &[a, b] => {
42//!         assert_eq!(!(a || b), !a && !b);
43//!         assert_eq!(!(a && b), !a || !b);
44//!     }
45//!     _ => unreachable!(),
46//! });
47//! // The closure is called for each combination of 2 `bool`s, i.e.:
48//! // &[false, false]
49//! // &[true,  false]
50//! // &[false, true]
51//! // &[true,  true]
52//! ```
53//!
54//! # Example - `gen()` and `gen_const()`
55//!
56//! Alternatively, use [`gen()` functions](crate#functions) to obtain
57//! an [`Iterator`] for generating all combinations. This could be used
58//! to e.g. map each combination into an `Expr` for an [AST], to easily
59//! generate all `Expr` combinations to verify their evaluation.
60//!
61//! [AST]: https://en.wikipedia.org/wiki/Abstract_syntax_tree
62//!
63//! Using [const generic variant](crate::gen_const), i.e. where `N` is const:
64//!
65//! ```
66//! #[derive(PartialEq, Debug)]
67//! enum Expr {
68//!     Bool(bool),
69//!     And(Box<Self>, Box<Self>),
70//!     // ...
71//! }
72//!
73//! impl Expr {
74//!     fn and(lhs: Self, rhs: Self) -> Self {
75//!         Self::And(Box::new(lhs), Box::new(rhs))
76//!     }
77//! }
78//!
79//! let exprs = truth_values::gen_const()
80//!     .map(|[a, b]| {
81//!         Expr::and(Expr::Bool(a), Expr::Bool(b))
82//!     })
83//!     .collect::<Vec<_>>();
84//!
85//! assert_eq!(
86//!     exprs,
87//!     [
88//!         Expr::and(Expr::Bool(false), Expr::Bool(false)),
89//!         Expr::and(Expr::Bool(true),  Expr::Bool(false)),
90//!         Expr::and(Expr::Bool(false), Expr::Bool(true)),
91//!         Expr::and(Expr::Bool(true),  Expr::Bool(true)),
92//!     ]
93//! );
94//! ```
95//!
96//! Using [non-const generic variant](crate::gen_slice), i.e. where `n` can be dynamic:
97//!
98//! ```
99//! # #[derive(PartialEq, Debug)]
100//! # enum Expr {
101//! #     Bool(bool),
102//! #     And(Box<Self>, Box<Self>),
103//! # }
104//! #
105//! # impl Expr {
106//! #     fn and(lhs: Expr, rhs: Expr) -> Expr {
107//! #         Expr::And(Box::new(lhs), Box::new(rhs))
108//! #     }
109//! # }
110//! #
111//! let exprs = truth_values::gen_slice(2, |bools| {
112//!     match bools {
113//!         &[a, b] => {
114//!             Expr::and(Expr::Bool(a), Expr::Bool(b))
115//!         }
116//!         _ => unreachable!(),
117//!     }
118//! })
119//! .collect::<Vec<_>>();
120//!
121//! assert_eq!(
122//!     exprs,
123//!     [
124//!         Expr::and(Expr::Bool(false), Expr::Bool(false)),
125//!         Expr::and(Expr::Bool(true),  Expr::Bool(false)),
126//!         Expr::and(Expr::Bool(false), Expr::Bool(true)),
127//!         Expr::and(Expr::Bool(true),  Expr::Bool(true)),
128//!     ]
129//! );
130//! ```
131//!
132//! # Combinations of 1, 2, 3, 4 `bool`s
133//!
134//! <table>
135//! <tr>
136//! <td style="text-align: center;">
137//!
138//! ```
139//! # use truth_values::gen_const;
140//! gen_const::<1>()
141//! # ;
142//! ```
143//!
144//! </td>
145//! <td style="text-align: center;">
146//!
147//! ```
148//! # use truth_values::gen_const;
149//! gen_const::<2>()
150//! # ;
151//! ```
152//!
153//! </td>
154//! <td style="text-align: center;">
155//!
156//! ```
157//! # use truth_values::gen_const;
158//! gen_const::<3>()
159//! # ;
160//! ```
161//!
162//! </td>
163//! <td style="text-align: center;">
164//!
165//! ```
166//! # use truth_values::gen_const;
167//! gen_const::<4>()
168//! # ;
169//! ```
170//!
171//! </td>
172//! </tr>
173//! <tr>
174//! <td style="vertical-align: top;">
175//!
176//! ```
177//! # [
178//! [false]
179//! # ,
180//! [true]
181//! # ];
182//! ```
183//!
184//! </td>
185//! <td style="vertical-align: top;">
186//!
187//! ```
188//! # [
189//! [false, false]
190//! # ,
191//! [true,  false]
192//! # ,
193//! [false, true]
194//! # ,
195//! [true,  true]
196//! # ];
197//! ```
198//!
199//! </td>
200//! <td style="vertical-align: top;">
201//!
202//! ```
203//! # [
204//! [false, false, false]
205//! # ,
206//! [true,  false, false]
207//! # ,
208//! [false, true,  false]
209//! # ,
210//! [true,  true,  false]
211//! # ,
212//! [false, false, true]
213//! # ,
214//! [true,  false, true]
215//! # ,
216//! [false, true,  true]
217//! # ,
218//! [true,  true,  true]
219//! # ];
220//! ```
221//!
222//! </td>
223//! <td style="vertical-align: top;">
224//!
225//! ```
226//! # [
227//! [false, false, false, false]
228//! # ,
229//! [true,  false, false, false]
230//! # ,
231//! [false, true,  false, false]
232//! # ,
233//! [true,  true,  false, false]
234//! # ,
235//! [false, false, true,  false]
236//! # ,
237//! [true,  false, true,  false]
238//! # ,
239//! [false, true,  true,  false]
240//! # ,
241//! [true,  true,  true,  false]
242//! # ,
243//! [false, false, false, true]
244//! # ,
245//! [true,  false, false, true]
246//! # ,
247//! [false, true,  false, true]
248//! # ,
249//! [true,  true,  false, true]
250//! # ,
251//! [false, false, true,  true]
252//! # ,
253//! [true,  false, true,  true]
254//! # ,
255//! [false, true,  true,  true]
256//! # ,
257//! [true,  true,  true,  true]
258//! # ];
259//! ```
260//!
261//! </td>
262//! </tr>
263//! </table>
264//!
265//! # Implementation
266//!
267//! The [`gen()` functions](crate#functions) return an [`Iterator`], which
268//! additionally specializes [`size_hint()`], [`count()`], [`nth()`], [`last()`].
269//!
270//! The [`Iterator`] also implements:
271//!
272//! - [`DoubleEndedIterator`] implementing [`next_back()`] and [`nth_back()`]
273//! - [`ExactSizeIterator`] implementing [`len()`]
274//! - [`FusedIterator`]
275//!
276//! # Warning
277//!
278//! The amount of combinations is exponential!
279//! The number of combinations for `N` boolean variables is <code>2<sup>N</sup></code>.
280//! In short, **10 variables** produce **1024 combinations**, but **20 variables**
281//! produce over **1 million combinations**.
282//!
283//! _Just alone exhausting the generator for **30 variables**, i.e. over **1 billion
284//! combinations**, takes a handful of seconds on my machine._
285//!
286//! Ideally, if used to test expressions, then there will likely only be a handful of
287//! variables. However, if user input is accepted, then it might be worth guarding and
288//! limiting the number of variables.
289//!
290//! So even though up to [`MAX`] (`63`) variables for 64-bit platforms
291//! is supported, it is probably undesirable to even attempt to process
292//! that many variables.
293//!
294//! [`MAX`]: crate::MAX
295//!
296//! [`size_hint()`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.size_hint
297//! [`count()`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.count
298//! [`nth()`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.nth
299//! [`last()`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.last
300//! [`next_back()`]: https://doc.rust-lang.org/std/iter/trait.DoubleEndedIterator.html#tymethod.next_back
301//! [`nth_back()`]: https://doc.rust-lang.org/std/iter/trait.DoubleEndedIterator.html#method.nth_back
302//! [`len()`]: https://doc.rust-lang.org/std/iter/trait.ExactSizeIterator.html#method.len
303
304#![no_std]
305#![forbid(unsafe_code)]
306#![forbid(elided_lifetimes_in_paths)]
307#![cfg_attr(debug_assertions, allow(missing_docs, missing_debug_implementations,))]
308#![warn(clippy::all)]
309
310#[cfg(feature = "alloc")]
311extern crate alloc;
312
313use core::array;
314use core::iter::FusedIterator;
315use core::ops::Range;
316
317#[cfg(feature = "alloc")]
318use alloc::{vec, vec::Vec};
319
320/// Maximum number of variables supported by
321/// [`gen()` functions](crate#functions).
322///
323/// - `15` variables is supported on 16-bit targets
324/// - `31` variables is supported on 32-bit targets
325/// - `63` variables is supported on 64-bit targets
326///
327/// ```
328/// // Assuming `usize` is 64 bits, i.e. `u64`
329/// assert_eq!(truth_values::MAX, 63);
330/// ```
331///
332/// Use <code>[count]\(n)</code> to calculate how many
333/// combinations `n` variables produces.
334///
335/// See [warning notice in crate root](crate#warning).
336pub const MAX: usize = (usize::BITS - 1) as usize;
337
338/// Returns `true` if `n` variables is supported
339/// by [`gen()` functions](crate#functions), i.e.
340/// <code>n <= [MAX]</code>.
341///
342/// - `15` variables is supported on 16-bit targets
343/// - `31` variables is supported on 32-bit targets
344/// - `63` variables is supported on 64-bit targets
345///
346/// ```
347/// // Assuming `usize` is 64 bits, i.e. `u64`
348/// assert_eq!(truth_values::is_supported(63), true);
349/// assert_eq!(truth_values::is_supported(64), false);
350/// ```
351///
352/// See [warning notice in crate root](crate#warning).
353#[inline]
354pub const fn is_supported(n: usize) -> bool {
355    n <= MAX
356}
357
358/// Returns `Some` with the number of combinations that `n` variables produces.
359///
360/// Returns `None` if `n` variables would produce more than what can be represented.
361///
362/// - `1` variable produces `2` combinations
363/// - `2` variables produces `4` combinations
364/// - `3` variables produces `8` combinations
365/// - `4` variables produces `16` combinations
366/// - [`MAX`] variables produces <code>[count]\([MAX])</code> combinations
367///
368/// Use <code>[is_supported]\(n)</code> or <code>[count]\(n).is_some()</code>
369/// to check if `n` variables is supported.
370///
371/// - `15` variables is supported on 16-bit targets
372/// - `31` variables is supported on 32-bit targets
373/// - `63` variables is supported on 64-bit targets
374///
375/// See [warning notice in crate root](crate#warning).
376///
377/// # Example
378///
379/// ```
380/// # use truth_values::count;
381/// assert_eq!(count(0), Some(0));
382///
383/// assert_eq!(count(1), Some(2));
384/// assert_eq!(count(2), Some(4));
385/// assert_eq!(count(3), Some(8));
386/// assert_eq!(count(4), Some(16));
387/// assert_eq!(count(5), Some(32));
388/// assert_eq!(count(6), Some(64));
389/// assert_eq!(count(7), Some(128));
390/// assert_eq!(count(8), Some(256));
391/// assert_eq!(count(9), Some(512));
392/// assert_eq!(count(10), Some(1024));
393/// assert_eq!(count(11), Some(2048));
394/// assert_eq!(count(12), Some(4096));
395/// assert_eq!(count(13), Some(8192));
396/// assert_eq!(count(14), Some(16384));
397///
398/// assert_eq!(count(100), None);
399/// ```
400#[inline]
401pub const fn count(n: usize) -> Option<usize> {
402    if n == 0 {
403        Some(0)
404    } else if n > MAX {
405        None
406    } else {
407        let n = n as u32;
408        1_usize.checked_shl(n)
409    }
410}
411
412/// Returns an [`Iterator`] producing all possible combinations of `[bool; N]`.
413///
414/// See also [`gen()`] for non-const generic variant.
415///
416/// See also [implementation](crate#implementation) for more information
417/// about the [`Iterator`] implementation.
418///
419/// # Panics
420///
421/// Panics if `N` is larger than the [`MAX`] number of supported variables.
422/// _However, you likely have other problems, if you encounter this._
423///
424/// See also <code>[count]\(N)</code> and <code>[is_supported]\(N)</code>.
425///
426/// # Example
427///
428/// See [crate root](crate) for more examples.
429///
430/// ```
431/// let combinations = truth_values::gen_const()
432///     .map(|[a, b]| {
433///         (a, b)
434///     })
435///     .collect::<Vec<_>>();
436///
437/// assert_eq!(
438///     combinations,
439///     [
440///         (false, false),
441///         (true, false),
442///         (false, true),
443///         (true, true),
444///     ]
445/// );
446/// ```
447#[inline]
448pub fn gen_const<const N: usize>(
449) -> impl DoubleEndedIterator<Item = [bool; N]> + ExactSizeIterator + FusedIterator {
450    ConstBoolsGenerator::new()
451}
452
453/// Returns an [`Iterator`] producing all possible combinations of `n` [`bool`]s,
454/// in the form of individual [`Bools`] iterators.
455///
456/// Alternatively, use [`gen_slice()`] or [`gen_vec_slice()`]
457/// to receives `&[bool]` instead, where <code>[len()] == n</code>.
458///
459/// See also [`gen_const()`] for const generic variant.
460///
461/// See also [implementation](crate#implementation) for more information
462/// about the [`Iterator`] implementation.
463///
464/// # Panics
465///
466/// Panics if `n` is larger than the [`MAX`] number of supported variables.
467/// _However, you likely have other problems, if you encounter this._
468///
469/// See also <code>[count]\(n)</code> and <code>[is_supported]\(n)</code>.
470///
471/// # Example
472///
473/// See [crate root](crate) for more examples.
474///
475/// ```
476/// let n = 2;
477/// let combinations = truth_values::gen(n)
478///     .map(|mut bools| {
479///         (bools.next().unwrap(), bools.next().unwrap())
480///     })
481///     .collect::<Vec<_>>();
482///
483/// assert_eq!(
484///     combinations,
485///     [
486///         (false, false),
487///         (true, false),
488///         (false, true),
489///         (true, true),
490///     ]
491/// );
492/// ```
493///
494/// [len()]: slice::len
495#[inline]
496pub fn gen(n: usize) -> impl DoubleEndedIterator<Item = Bools> + ExactSizeIterator + FusedIterator {
497    BoolsGenerator::new(n)
498}
499
500/// Returns an [`Iterator`] producing `T` for each possible combinations
501/// of `n` [`bool`]s.
502///
503/// Each combination is mapped from `&[bool] -> T` using `f`,
504/// where `f` receives `&[bool]` where <code>[len()] == n</code>.
505///
506/// See also [`gen_const()`] for const generic variant.
507///
508/// See also [implementation](crate#implementation) for more information
509/// about the [`Iterator`] implementation.
510///
511/// # Memory
512///
513/// The returned [`Iterator`] stores a <code>[bool; [MAX]]</code> on the stack.
514///
515/// Alternatively, [`gen_vec_slice()`] stores a
516/// <code>[Vec]\<bool>::[with_capacity]\(n)</code>
517/// on the stack.
518///
519/// See also [`gen_with_buffer()`] for using a custom buffer.
520///
521/// # Panics
522///
523/// Panics if `n` is larger than the [`MAX`] number of supported variables.
524/// _However, you likely have other problems, if you encounter this._
525///
526/// See also <code>[count]\(n)</code> and <code>[is_supported]\(n)</code>.
527///
528/// # Example
529///
530/// See [crate root](crate) for more examples.
531///
532/// ```
533/// let n = 2;
534/// let combinations = truth_values::gen_slice(n, |bools| {
535///     match bools {
536///         &[a, b] => (a, b),
537///         _ => unreachable!(),
538///     }
539/// })
540/// .collect::<Vec<_>>();
541///
542/// assert_eq!(
543///     combinations,
544///     [
545///         (false, false),
546///         (true, false),
547///         (false, true),
548///         (true, true),
549///     ]
550/// );
551/// ```
552///
553/// [with_capacity]: Vec::with_capacity
554/// [len()]: slice::len
555#[inline]
556pub fn gen_slice<T, F>(
557    n: usize,
558    mut f: F,
559) -> impl DoubleEndedIterator<Item = T> + ExactSizeIterator + FusedIterator
560where
561    for<'a> F: FnMut(&[bool]) -> T,
562{
563    let mut bools = [false; MAX];
564    gen(n).map(move |values| {
565        let bools = values.fill_bools_into(&mut bools);
566        f(bools)
567    })
568}
569
570/// Returns an [`Iterator`] producing <code>[Vec]<[bool]></code>
571/// for each possible combinations of `n` [`bool`]s.
572///
573/// **Note:** If a <code>[Vec]<[bool]></code> is **not needed**
574/// for **each combination**, then consider using [`gen_slice()`]
575/// or [`gen_vec_slice()`] instead.
576///
577/// See also [implementation](crate#implementation) for more information
578/// about the [`Iterator`] implementation.
579///
580/// # Panics
581///
582/// Panics if `n` is larger than the [`MAX`] number of supported variables.
583/// _However, you likely have other problems, if you encounter this._
584///
585/// See also <code>[count]\(n)</code> and <code>[is_supported]\(n)</code>.
586///
587/// # Example
588///
589/// See [crate root](crate) for more examples.
590///
591/// ```
592/// let n = 2;
593/// let combinations = truth_values::gen_vec(n).collect::<Vec<_>>();
594///
595/// assert_eq!(
596///     combinations,
597///     [
598///         vec![false, false],
599///         vec![true, false],
600///         vec![false, true],
601///         vec![true, true],
602///     ]
603/// );
604/// ```
605#[cfg(feature = "alloc")]
606#[inline]
607pub fn gen_vec(
608    n: usize,
609) -> impl DoubleEndedIterator<Item = Vec<bool>> + ExactSizeIterator + FusedIterator {
610    gen(n).map(Iterator::collect)
611}
612
613/// Returns an [`Iterator`] producing `T` for each possible combinations
614/// of `n` [`bool`]s.
615///
616/// Each combination is mapped from `&[bool] -> T` using `f`,
617/// where `f` receives `&[bool]` where <code>[len()] == n</code>.
618///
619/// See also [`gen_const()`] for const generic variant.
620///
621/// See also [implementation](crate#implementation) for more information
622/// about the [`Iterator`] implementation.
623///
624/// # Memory
625///
626/// The returned [`Iterator`] stores a
627/// <code>[Vec]\<bool>::[with_capacity]\(n)</code>
628/// on the stack.
629///
630/// Alternatively, [`gen_slice()`] stores a <code>[bool; [MAX]]</code>
631/// on the stack.
632///
633/// See also [`gen_with_buffer()`] for using a custom buffer.
634///
635/// # Panics
636///
637/// Panics if `n` is larger than the [`MAX`] number of supported variables.
638/// _However, you likely have other problems, if you encounter this._
639///
640/// See also <code>[count]\(n)</code> and <code>[is_supported]\(n)</code>.
641///
642/// # Example
643///
644/// See [crate root](crate) for more examples.
645///
646/// ```
647/// let n = 2;
648/// let combinations = truth_values::gen_vec_slice(n, |bools| {
649///     match bools {
650///         &[a, b] => (a, b),
651///         _ => unreachable!(),
652///     }
653/// })
654/// .collect::<Vec<_>>();
655///
656/// assert_eq!(
657///     combinations,
658///     [
659///         (false, false),
660///         (true, false),
661///         (false, true),
662///         (true, true),
663///     ]
664/// );
665/// ```
666///
667/// [with_capacity]: Vec::with_capacity
668/// [len()]: slice::len
669#[cfg(feature = "alloc")]
670#[inline]
671pub fn gen_vec_slice<T, F>(
672    n: usize,
673    mut f: F,
674) -> impl DoubleEndedIterator<Item = T> + ExactSizeIterator + FusedIterator
675where
676    for<'a> F: FnMut(&[bool]) -> T,
677{
678    let mut bools = vec![false; n];
679    gen(n).map(move |mut values| {
680        let bools = bools.as_mut();
681        values.fill_into(bools);
682        f(bools)
683    })
684}
685
686/// Returns an [`Iterator`] producing `T` for each possible combinations
687/// of `n` [`bool`]s.
688///
689/// Each combination is mapped from `&[bool] -> T` using `f`,
690/// where `f` receives `&[bool]` where <code>[len()] == n</code>.
691///
692/// The `buffer` only needs to be as big as the largest used `n`.
693/// Whereas [`gen_slice()`] which always uses a
694/// <code>[[bool]; [MAX]]</code>.
695///
696/// See also [implementation](crate#implementation) for more information
697/// about the [`Iterator`] implementation.
698///
699/// # Panics
700///
701/// - Panics if <code>buffer.[len()] < n</code>
702/// - Panics if `n` is larger than the [`MAX`] number of supported variables.
703///   _However, you likely have other problems, if you encounter this._
704///
705/// See also <code>[count]\(n)</code> and <code>[is_supported]\(n)</code>.
706///
707/// # Example
708///
709/// See [crate root](crate) for more examples.
710///
711/// ```
712/// // buffer only needs to be as big as the largest `n`
713/// let mut buffer = [false; 5];
714///
715/// // `3 <= buffer.len()` so `buffer` can be used
716/// let n = 3;
717/// let combinations = truth_values::gen_with_buffer(n, &mut buffer, |bools| {
718///     match bools {
719///         &[a, b, c] => (a, b, c),
720///         _ => unreachable!(),
721///     }
722/// })
723/// .collect::<Vec<_>>();
724///
725/// assert_eq!(
726///     combinations,
727///     [
728///         (false, false, false),
729///         (true, false, false),
730///         (false, true, false),
731///         (true, true, false),
732///         (false, false, true),
733///         (true, false, true),
734///         (false, true, true),
735///         (true, true, true),
736///     ]
737/// );
738///
739/// // `2 <= buffer.len()` so `buffer` can be reused
740/// let n = 2;
741/// let combinations = truth_values::gen_with_buffer(n, &mut buffer, |bools| {
742///     match bools {
743///         &[a, b] => (a, b),
744///         _ => unreachable!(),
745///     }
746/// })
747/// .collect::<Vec<_>>();
748///
749/// assert_eq!(
750///     combinations,
751///     [
752///         (false, false),
753///         (true, false),
754///         (false, true),
755///         (true, true),
756///     ]
757/// );
758/// ```
759///
760/// [len()]: slice::len
761pub fn gen_with_buffer<'a, T, F>(
762    n: usize,
763    buffer: &'a mut [bool],
764    mut f: F,
765) -> impl DoubleEndedIterator<Item = T> + ExactSizeIterator + FusedIterator + 'a
766where
767    for<'b> F: FnMut(&'b [bool]) -> T + 'a,
768{
769    if n > buffer.len() {
770        panic!("buffer too small {n} > {}", buffer.len());
771    }
772    let buffer = &mut buffer[..n];
773
774    gen(n).map(move |mut values| {
775        values.fill_into(buffer);
776        f(buffer)
777    })
778}
779
780/// Shorthand for <code>[gen_const]\().[for_each]\(f)</code>.
781///
782/// See [`gen_const()`] for more information.
783///
784/// See [`each()`] for the non-const generic variant.
785///
786/// # Example
787///
788/// See [crate root](crate) for more examples.
789///
790/// ```
791/// # use truth_values::each_const;
792/// #
793/// each_const(|[a]| {
794///     println!("{a}");
795/// });
796/// // Outputs:
797/// // false
798/// // true
799///
800/// each_const(|[a, b]| {
801///     println!("{a} {b}");
802/// });
803/// // Outputs:
804/// // false false
805/// // true  false
806/// // false true
807/// // true  true
808///
809/// each_const(|[a, b, c, d]| {
810///     println!("{a} {b} {c} {d}");
811/// });
812/// // Outputs:
813/// // false false false false
814/// // true  false false false
815/// // false true  false false
816/// // true  true  false false
817/// // false false true  false
818/// // true  false true  false
819/// // false true  true  false
820/// // true  true  true  false
821/// // false false false true
822/// // true  false false true
823/// // false true  false true
824/// // true  true  false true
825/// // false false true  true
826/// // true  false true  true
827/// // false true  true  true
828/// // true  true  true  true
829/// ```
830///
831/// [for_each]: Iterator::for_each
832#[inline]
833pub fn each_const<const N: usize, F>(f: F)
834where
835    F: FnMut([bool; N]),
836{
837    gen_const::<N>().for_each(f)
838}
839
840/// Shorthand for <code>[gen_slice]\(n, f).[for_each]\(|_| ())</code>.
841///
842/// See [`gen_slice()`] for more information.
843///
844/// See [`each_const()`] for the const generic variant.
845///
846/// # Example
847///
848/// See [crate root](crate) for more examples.
849///
850/// ```
851/// # use truth_values::each;
852/// each(1, |bools| {
853///     println!("{:?}", bools);
854/// });
855/// // Outputs:
856/// // [false]
857/// // [true]
858///
859/// each(2, |bools| {
860///     println!("{:?}", bools);
861/// });
862/// // Outputs:
863/// // [false, false]
864/// // [true, false]
865/// // [false, true]
866/// // [true, true]
867///
868/// each(4, |bools| {
869///     println!("{:?}", bools);
870/// });
871/// // Outputs:
872/// // [false, false, false, false]
873/// // [true, false, false, false]
874/// // [false, true, false, false]
875/// // [true, true, false, false]
876/// // [false, false, true, false]
877/// // [true, false, true, false]
878/// // [false, true, true, false]
879/// // [true, true, true, false]
880/// // [false, false, false, true]
881/// // [true, false, false, true]
882/// // [false, true, false, true]
883/// // [true, true, false, true]
884/// // [false, false, true, true]
885/// // [true, false, true, true]
886/// // [false, true, true, true]
887/// // [true, true, true, true]
888/// ```
889///
890/// [for_each]: Iterator::for_each
891#[inline]
892pub fn each<F>(n: usize, f: F)
893where
894    for<'a> F: FnMut(&'a [bool]),
895{
896    gen_slice(n, f).for_each(drop);
897}
898
899/// Shorthand for <code>[gen_vec_slice]\(n, f).[for_each]\(|_| ())</code>.
900///
901/// See [`gen_vec_slice()`] for more information.
902///
903/// See [`each_const()`] for the const generic variant.
904///
905/// # Example
906///
907/// See [crate root](crate) for more examples.
908///
909/// ```
910/// # use truth_values::each_vec_slice;
911/// each_vec_slice(1, |bools| {
912///     println!("{:?}", bools);
913/// });
914/// // Outputs:
915/// // [false]
916/// // [true]
917///
918/// each_vec_slice(2, |bools| {
919///     println!("{:?}", bools);
920/// });
921/// // Outputs:
922/// // [false, false]
923/// // [true, false]
924/// // [false, true]
925/// // [true, true]
926///
927/// each_vec_slice(4, |bools| {
928///     println!("{:?}", bools);
929/// });
930/// // Outputs:
931/// // [false, false, false, false]
932/// // [true, false, false, false]
933/// // [false, true, false, false]
934/// // [true, true, false, false]
935/// // [false, false, true, false]
936/// // [true, false, true, false]
937/// // [false, true, true, false]
938/// // [true, true, true, false]
939/// // [false, false, false, true]
940/// // [true, false, false, true]
941/// // [false, true, false, true]
942/// // [true, true, false, true]
943/// // [false, false, true, true]
944/// // [true, false, true, true]
945/// // [false, true, true, true]
946/// // [true, true, true, true]
947/// ```
948///
949/// [for_each]: Iterator::for_each
950#[cfg(feature = "alloc")]
951#[inline]
952pub fn each_vec_slice<F>(n: usize, f: F)
953where
954    for<'a> F: FnMut(&[bool]),
955{
956    let mut bools = vec![false; n];
957    each_with_buffer(n, &mut bools, f);
958}
959
960/// Shorthand for <code>[gen_with_buffer]\(n, buffer, f).[for_each]\(|_| ())</code>.
961///
962/// See [`each_with_buffer()`] for more information.
963///
964/// # Example
965///
966/// See [crate root](crate) for more examples.
967///
968/// ```
969/// # use truth_values::each_with_buffer;
970/// #
971/// // Buffer only needs to be as big as the largest `n`
972/// let mut buffer = [false; 5];
973///
974/// each_with_buffer(1, &mut buffer, |bools| {
975///     println!("{:?}", bools);
976/// });
977/// // Outputs:
978/// // [false]
979/// // [true]
980///
981/// each_with_buffer(2, &mut buffer, |bools| {
982///     println!("{:?}", bools);
983/// });
984/// // Outputs:
985/// // [false, false]
986/// // [true, false]
987/// // [false, true]
988/// // [true, true]
989///
990/// each_with_buffer(4, &mut buffer, |bools| {
991///     println!("{:?}", bools);
992/// });
993/// // Outputs:
994/// // [false, false, false, false]
995/// // [true, false, false, false]
996/// // [false, true, false, false]
997/// // [true, true, false, false]
998/// // [false, false, true, false]
999/// // [true, false, true, false]
1000/// // [false, true, true, false]
1001/// // [true, true, true, false]
1002/// // [false, false, false, true]
1003/// // [true, false, false, true]
1004/// // [false, true, false, true]
1005/// // [true, true, false, true]
1006/// // [false, false, true, true]
1007/// // [true, false, true, true]
1008/// // [false, true, true, true]
1009/// // [true, true, true, true]
1010/// ```
1011///
1012/// [for_each]: Iterator::for_each
1013#[inline]
1014pub fn each_with_buffer<F>(n: usize, buffer: &mut [bool], f: F)
1015where
1016    for<'a> F: FnMut(&'a [bool]),
1017{
1018    gen_with_buffer(n, buffer, f).for_each(drop);
1019}
1020
1021#[derive(PartialEq, Eq, Hash, Clone, Debug)]
1022struct ConstBoolsGenerator<const N: usize> {
1023    index: Range<usize>,
1024}
1025
1026impl<const N: usize> ConstBoolsGenerator<N> {
1027    pub fn new() -> Self {
1028        struct AssertLeMax<const N: usize>;
1029        impl<const N: usize> AssertLeMax<N> {
1030            const ASSERT: () = assert!(N <= MAX, "too many variables");
1031        }
1032        #[allow(clippy::let_unit_value)]
1033        {
1034            _ = AssertLeMax::<N>::ASSERT;
1035        }
1036
1037        // Safe to unwrap otherwise the above
1038        // assert would have triggered
1039        let count = count(N).unwrap();
1040
1041        Self { index: 0..count }
1042    }
1043
1044    #[inline]
1045    fn to_bools(index: usize) -> [bool; N] {
1046        array::from_fn(|var| ((index >> var) & 1) != 0)
1047    }
1048}
1049
1050impl<const N: usize> Iterator for ConstBoolsGenerator<N> {
1051    type Item = [bool; N];
1052
1053    #[inline]
1054    fn next(&mut self) -> Option<Self::Item> {
1055        self.index.next().map(Self::to_bools)
1056    }
1057
1058    #[inline]
1059    fn size_hint(&self) -> (usize, Option<usize>) {
1060        self.index.size_hint()
1061    }
1062
1063    #[inline]
1064    fn count(self) -> usize
1065    where
1066        Self: Sized,
1067    {
1068        self.index.count()
1069    }
1070
1071    #[inline]
1072    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1073        self.index.nth(n).map(Self::to_bools)
1074    }
1075
1076    #[inline]
1077    fn last(mut self) -> Option<Self::Item>
1078    where
1079        Self: Sized,
1080    {
1081        self.next_back()
1082    }
1083
1084    #[inline]
1085    fn min(mut self) -> Option<Self::Item>
1086    where
1087        Self::Item: Ord,
1088    {
1089        self.next()
1090    }
1091
1092    #[inline]
1093    fn max(mut self) -> Option<Self::Item>
1094    where
1095        Self::Item: Ord,
1096    {
1097        self.next_back()
1098    }
1099}
1100
1101impl<const N: usize> DoubleEndedIterator for ConstBoolsGenerator<N> {
1102    #[inline]
1103    fn next_back(&mut self) -> Option<Self::Item> {
1104        self.index.next_back().map(Self::to_bools)
1105    }
1106
1107    #[inline]
1108    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1109        self.index.nth_back(n).map(Self::to_bools)
1110    }
1111}
1112
1113impl<const N: usize> ExactSizeIterator for ConstBoolsGenerator<N> {
1114    #[inline]
1115    fn len(&self) -> usize {
1116        self.index.len()
1117    }
1118}
1119
1120impl<const N: usize> FusedIterator for ConstBoolsGenerator<N> {}
1121
1122#[derive(PartialEq, Eq, Hash, Clone, Debug)]
1123struct BoolsGenerator {
1124    index: Range<usize>,
1125    /// Number of variables.
1126    n: u8,
1127}
1128
1129impl BoolsGenerator {
1130    #[inline]
1131    pub fn new(n: usize) -> Self {
1132        Self::new_checked(n).expect("too many variables")
1133    }
1134
1135    #[inline]
1136    pub fn new_checked(n: usize) -> Option<Self> {
1137        let count = count(n)?;
1138
1139        // Safe to unwrap, as even with a `u128`,
1140        // there could only be at most 127 variables,
1141        // i.e. `count()` returning at most 127 for `u128`
1142        let n = u8::try_from(n).unwrap();
1143
1144        Some(Self { n, index: 0..count })
1145    }
1146
1147    #[inline]
1148    fn to_bools(&self, index: usize) -> Bools {
1149        Bools::new(self.n, index)
1150    }
1151}
1152
1153impl Iterator for BoolsGenerator {
1154    type Item = Bools;
1155
1156    #[inline]
1157    fn next(&mut self) -> Option<Self::Item> {
1158        let index = self.index.next()?;
1159        Some(self.to_bools(index))
1160    }
1161
1162    #[inline]
1163    fn size_hint(&self) -> (usize, Option<usize>) {
1164        self.index.size_hint()
1165    }
1166
1167    #[inline]
1168    fn count(self) -> usize
1169    where
1170        Self: Sized,
1171    {
1172        self.index.count()
1173    }
1174
1175    #[inline]
1176    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1177        let index = self.index.nth(n)?;
1178        Some(self.to_bools(index))
1179    }
1180
1181    #[inline]
1182    fn last(mut self) -> Option<Self::Item>
1183    where
1184        Self: Sized,
1185    {
1186        self.next_back()
1187    }
1188}
1189
1190impl DoubleEndedIterator for BoolsGenerator {
1191    #[inline]
1192    fn next_back(&mut self) -> Option<Self::Item> {
1193        let index = self.index.next_back()?;
1194        Some(self.to_bools(index))
1195    }
1196
1197    #[inline]
1198    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1199        let index = self.index.nth_back(n)?;
1200        Some(self.to_bools(index))
1201    }
1202}
1203
1204impl ExactSizeIterator for BoolsGenerator {
1205    #[inline]
1206    fn len(&self) -> usize {
1207        self.index.len()
1208    }
1209}
1210
1211impl FusedIterator for BoolsGenerator {}
1212
1213/// An [`Iterator`] that produces exactly `n` [`bool`]s.
1214///
1215/// See [`gen()`] for more information.
1216#[derive(PartialEq, Eq, Hash, Clone, Debug)]
1217pub struct Bools {
1218    variables: Range<u8>,
1219    index: usize,
1220}
1221
1222impl Bools {
1223    #[inline]
1224    fn new(n: u8, index: usize) -> Self {
1225        Self {
1226            variables: 0..n,
1227            index,
1228        }
1229    }
1230
1231    #[inline]
1232    fn fill_into(&mut self, bools: &mut [bool]) {
1233        for (b, val) in bools.iter_mut().zip(self.by_ref()) {
1234            *b = val;
1235        }
1236    }
1237
1238    #[inline]
1239    fn fill_bools_into(mut self, bools: &mut [bool; MAX]) -> &[bool] {
1240        let n = self.variables.len();
1241
1242        // Safe as `gen()` panics if `n > MAX`
1243        let bools = &mut bools[..n];
1244
1245        // Safe to unwrap as `self` produces exactly `n` items
1246        bools.fill_with(|| self.next().unwrap());
1247
1248        bools
1249    }
1250
1251    #[inline]
1252    fn to_bool(&self, var: u8) -> bool {
1253        ((self.index >> var) & 1) != 0
1254    }
1255}
1256
1257impl Iterator for Bools {
1258    type Item = bool;
1259
1260    #[inline]
1261    fn next(&mut self) -> Option<Self::Item> {
1262        let var = self.variables.next()?;
1263        Some(self.to_bool(var))
1264    }
1265
1266    #[inline]
1267    fn size_hint(&self) -> (usize, Option<usize>) {
1268        self.variables.size_hint()
1269    }
1270
1271    #[inline]
1272    fn count(self) -> usize
1273    where
1274        Self: Sized,
1275    {
1276        self.variables.count()
1277    }
1278
1279    #[inline]
1280    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1281        let index = self.variables.nth(n)?;
1282        Some(self.to_bool(index))
1283    }
1284
1285    #[inline]
1286    fn last(mut self) -> Option<Self::Item>
1287    where
1288        Self: Sized,
1289    {
1290        self.next_back()
1291    }
1292
1293    #[inline]
1294    fn min(mut self) -> Option<Self::Item>
1295    where
1296        Self::Item: Ord,
1297    {
1298        self.next()
1299    }
1300
1301    #[inline]
1302    fn max(mut self) -> Option<Self::Item>
1303    where
1304        Self::Item: Ord,
1305    {
1306        self.next_back()
1307    }
1308}
1309
1310impl DoubleEndedIterator for Bools {
1311    #[inline]
1312    fn next_back(&mut self) -> Option<Self::Item> {
1313        let var = self.variables.next_back()?;
1314        Some(self.to_bool(var))
1315    }
1316
1317    #[inline]
1318    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1319        let var = self.variables.nth_back(n)?;
1320        Some(self.to_bool(var))
1321    }
1322}
1323
1324impl ExactSizeIterator for Bools {
1325    #[inline]
1326    fn len(&self) -> usize {
1327        self.variables.len()
1328    }
1329}
1330
1331impl FusedIterator for Bools {}
1332
1333#[cfg(test)]
1334mod tests {
1335    use alloc::boxed::Box;
1336    use alloc::vec;
1337
1338    use super::*;
1339
1340    #[test]
1341    fn test_is_supported() {
1342        for n in 0..=MAX {
1343            assert!(is_supported(n));
1344        }
1345
1346        assert!(!is_supported(MAX + 1));
1347    }
1348
1349    #[test]
1350    fn test_count() {
1351        assert_eq!(count(0), Some(0));
1352        assert_eq!(count(1), Some(2));
1353        assert_eq!(count(2), Some(4));
1354        assert_eq!(count(3), Some(8));
1355        assert_eq!(count(4), Some(16));
1356        assert_eq!(count(5), Some(32));
1357        assert_eq!(count(6), Some(64));
1358        assert_eq!(count(7), Some(128));
1359        assert_eq!(count(8), Some(256));
1360        assert_eq!(count(9), Some(512));
1361        assert_eq!(count(10), Some(1024));
1362
1363        assert_eq!(count(usize::MAX), None);
1364    }
1365
1366    #[test]
1367    fn test_count_max() {
1368        assert!(count(MAX).is_some());
1369    }
1370
1371    #[test]
1372    #[cfg_attr(not(target_pointer_width = "16"), ignore)]
1373    fn test_count_16() {
1374        assert_eq!(count(15), Some(32768));
1375        assert_eq!(count(16), None);
1376    }
1377
1378    #[test]
1379    #[cfg_attr(not(target_pointer_width = "32"), ignore)]
1380    fn test_count_32() {
1381        assert_eq!(count(31), Some(2147483648));
1382        assert_eq!(count(32), None);
1383    }
1384
1385    #[test]
1386    #[cfg_attr(not(target_pointer_width = "64"), ignore)]
1387    fn test_count_64() {
1388        assert_eq!(count(63), Some(9223372036854775808));
1389        assert_eq!(count(64), None);
1390    }
1391
1392    macro_rules! test_gen {
1393        ($test_name:ident, $n:literal $(, $($case:expr),* $(,)?)?) => {
1394            #[test]
1395            fn $test_name() {
1396                let n = $n;
1397                let mut iter = gen_vec(n);
1398
1399                let cases = &[$($($case.as_slice()),*)?];
1400
1401                assert_eq!(count(n), Some(cases.len()));
1402
1403                for (i, &case) in cases.iter().enumerate() {
1404                    assert_eq!(iter.next().as_deref(), Some(case), "index {i}");
1405                }
1406
1407                assert_eq!(iter.next(), None);
1408            }
1409        };
1410    }
1411
1412    test_gen!(test_gen_0, 0);
1413    test_gen!(test_gen_1, 1, [false], [true]);
1414    test_gen!(
1415        test_gen_2,
1416        2,
1417        [false, false],
1418        [true, false],
1419        [false, true],
1420        [true, true],
1421    );
1422    test_gen!(
1423        test_gen_3,
1424        3,
1425        [false, false, false],
1426        [true, false, false],
1427        [false, true, false],
1428        [true, true, false],
1429        [false, false, true],
1430        [true, false, true],
1431        [false, true, true],
1432        [true, true, true],
1433    );
1434    test_gen!(
1435        test_gen_4,
1436        4,
1437        [false, false, false, false],
1438        [true, false, false, false],
1439        [false, true, false, false],
1440        [true, true, false, false],
1441        [false, false, true, false],
1442        [true, false, true, false],
1443        [false, true, true, false],
1444        [true, true, true, false],
1445        [false, false, false, true],
1446        [true, false, false, true],
1447        [false, true, false, true],
1448        [true, true, false, true],
1449        [false, false, true, true],
1450        [true, false, true, true],
1451        [false, true, true, true],
1452        [true, true, true, true],
1453    );
1454
1455    #[test]
1456    fn test_gen_max_ends() {
1457        for n in 0..=MAX {
1458            let mut iter = gen(n).map(Iterator::collect::<Vec<_>>);
1459
1460            assert_eq!(count(n), Some(iter.len()));
1461
1462            if iter.len() == 0 {
1463                continue;
1464            }
1465
1466            assert_eq!(iter.next().unwrap(), vec![false; n]);
1467            assert_eq!(iter.next_back().unwrap(), vec![true; n]);
1468        }
1469    }
1470
1471    #[derive(PartialEq, Clone, Debug)]
1472    enum Expr {
1473        Bool(bool),
1474        And(Box<Self>, Box<Self>),
1475        Or(Box<Self>, Box<Self>),
1476    }
1477
1478    impl From<bool> for Expr {
1479        fn from(b: bool) -> Self {
1480            Expr::Bool(b)
1481        }
1482    }
1483
1484    fn and(lhs: impl Into<Expr>, rhs: impl Into<Expr>) -> Expr {
1485        Expr::And(Box::new(lhs.into()), Box::new(rhs.into()))
1486    }
1487
1488    fn or(lhs: impl Into<Expr>, rhs: impl Into<Expr>) -> Expr {
1489        Expr::Or(Box::new(lhs.into()), Box::new(rhs.into()))
1490    }
1491
1492    #[test]
1493    fn test_gen_const() {
1494        const N: usize = 3;
1495
1496        let exprs = gen_const::<N>()
1497            .map(|[a, b, c]| and(a, or(b, c)))
1498            .collect::<Vec<_>>();
1499
1500        assert_eq!(count(N), Some(exprs.len()));
1501
1502        let mut exprs = exprs.into_iter();
1503        assert_eq!(exprs.next().unwrap(), and(false, or(false, false)));
1504        assert_eq!(exprs.next().unwrap(), and(true, or(false, false)));
1505        assert_eq!(exprs.next().unwrap(), and(false, or(true, false)));
1506        assert_eq!(exprs.next().unwrap(), and(true, or(true, false)));
1507        assert_eq!(exprs.next().unwrap(), and(false, or(false, true)));
1508        assert_eq!(exprs.next().unwrap(), and(true, or(false, true)));
1509        assert_eq!(exprs.next().unwrap(), and(false, or(true, true)));
1510        assert_eq!(exprs.next().unwrap(), and(true, or(true, true)));
1511        assert_eq!(exprs.next(), None);
1512    }
1513
1514    #[test]
1515    fn test_gen_slice() {
1516        const N: usize = 3;
1517
1518        let exprs = gen_slice(N, |bools| and(bools[0], or(bools[1], bools[2]))).collect::<Vec<_>>();
1519
1520        assert_eq!(count(N), Some(exprs.len()));
1521
1522        let mut exprs = exprs.into_iter();
1523        assert_eq!(exprs.next().unwrap(), and(false, or(false, false)));
1524        assert_eq!(exprs.next().unwrap(), and(true, or(false, false)));
1525        assert_eq!(exprs.next().unwrap(), and(false, or(true, false)));
1526        assert_eq!(exprs.next().unwrap(), and(true, or(true, false)));
1527        assert_eq!(exprs.next().unwrap(), and(false, or(false, true)));
1528        assert_eq!(exprs.next().unwrap(), and(true, or(false, true)));
1529        assert_eq!(exprs.next().unwrap(), and(false, or(true, true)));
1530        assert_eq!(exprs.next().unwrap(), and(true, or(true, true)));
1531        assert_eq!(exprs.next(), None);
1532    }
1533
1534    #[test]
1535    fn test_gen_const_rev() {
1536        const N: usize = 3;
1537
1538        let mut combinations = gen_const::<N>().collect::<Vec<_>>();
1539        combinations.reverse();
1540
1541        let combinations2 = gen_const::<N>().rev().collect::<Vec<_>>();
1542
1543        assert_eq!(combinations, combinations2);
1544    }
1545
1546    #[test]
1547    fn test_gen_rev() {
1548        const N: usize = 3;
1549
1550        let mut combinations = gen_vec(N).collect::<Vec<_>>();
1551        combinations.reverse();
1552
1553        let combinations2 = gen_vec(N).rev().collect::<Vec<_>>();
1554
1555        assert_eq!(combinations, combinations2);
1556    }
1557
1558    #[test]
1559    fn test_each_const() {
1560        const N: usize = 3;
1561
1562        let mut iter = gen_vec(N);
1563
1564        each_const::<N, _>(|bools| {
1565            assert_eq!(bools, iter.next().unwrap().as_slice());
1566        });
1567
1568        assert_eq!(iter.next(), None);
1569    }
1570
1571    #[test]
1572    fn test_each() {
1573        const N: usize = 3;
1574
1575        let mut iter = gen_vec(N);
1576
1577        each(N, |bools| {
1578            assert_eq!(bools, iter.next().unwrap());
1579        });
1580
1581        assert_eq!(iter.next(), None);
1582    }
1583
1584    #[test]
1585    fn test_each_vec_slice() {
1586        const N: usize = 3;
1587
1588        let mut iter = gen_vec(N);
1589
1590        each_vec_slice(N, |bools| {
1591            assert_eq!(bools, iter.next().unwrap());
1592        });
1593
1594        assert_eq!(iter.next(), None);
1595    }
1596
1597    #[test]
1598    fn test_each_with_buffer() {
1599        const N: usize = 3;
1600
1601        let mut iter = gen_vec(N);
1602
1603        let mut buf = [false; N];
1604        each_with_buffer(N, &mut buf, |bools| {
1605            assert_eq!(bools, iter.next().unwrap());
1606        });
1607
1608        assert_eq!(iter.next(), None);
1609    }
1610}