enum_iterator/
lib.rs

1// Copyright (c) 2018-2022 Stephane Raux. Distributed under the 0BSD license.
2
3//! # Overview
4//! - [📦 crates.io](https://crates.io/crates/enum-iterator)
5//! - [📖 Documentation](https://docs.rs/enum-iterator)
6//! - [âš– 0BSD license](https://spdx.org/licenses/0BSD.html)
7//!
8//! Tools to iterate over the values of a type.
9//!
10//! # Examples
11//! ```
12//! use enum_iterator::{all, cardinality, first, last, next, previous, reverse_all, Sequence};
13//!
14//! #[derive(Debug, PartialEq, Sequence)]
15//! enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
16//!
17//! assert_eq!(cardinality::<Day>(), 7);
18//! assert_eq!(all::<Day>().collect::<Vec<_>>(), [
19//!     Day::Monday,
20//!     Day::Tuesday,
21//!     Day::Wednesday,
22//!     Day::Thursday,
23//!     Day::Friday,
24//!     Day::Saturday,
25//!     Day::Sunday,
26//! ]);
27//! assert_eq!(first::<Day>(), Some(Day::Monday));
28//! assert_eq!(last::<Day>(), Some(Day::Sunday));
29//! assert_eq!(next(&Day::Tuesday), Some(Day::Wednesday));
30//! assert_eq!(previous(&Day::Wednesday), Some(Day::Tuesday));
31//! assert_eq!(reverse_all::<Day>().collect::<Vec<_>>(), [
32//!     Day::Sunday,
33//!     Day::Saturday,
34//!     Day::Friday,
35//!     Day::Thursday,
36//!     Day::Wednesday,
37//!     Day::Tuesday,
38//!     Day::Monday,
39//! ]);
40//! ```
41//!
42//! ```
43//! use enum_iterator::{cardinality, first, last, Sequence};
44//!
45//! #[derive(Debug, PartialEq, Sequence)]
46//! struct Foo {
47//!     a: bool,
48//!     b: u8,
49//! }
50//!
51//! assert_eq!(cardinality::<Foo>(), 512);
52//! assert_eq!(first::<Foo>(), Some(Foo { a: false, b: 0 }));
53//! assert_eq!(last::<Foo>(), Some(Foo { a: true, b: 255 }));
54//! ```
55//!
56//! # Rust version
57//! This crate tracks stable Rust. Minor releases may require a newer Rust version. Patch releases
58//! must not require a newer Rust version.
59//!
60//! # Contribute
61//! All contributions shall be licensed under the [0BSD license](https://spdx.org/licenses/0BSD.html).
62
63#![deny(missing_docs)]
64#![deny(warnings)]
65#![no_std]
66
67use core::{cmp::Ordering, iter::FusedIterator, ops::ControlFlow, task::Poll};
68
69pub use enum_iterator_derive::Sequence;
70
71/// Returns the cardinality (number of values) of `T`
72///
73/// # Example
74/// ```
75/// use enum_iterator::{cardinality, Sequence};
76///
77/// #[derive(Debug, PartialEq, Sequence)]
78/// enum Color { Red, Green, Blue }
79///
80/// assert_eq!(cardinality::<Color>(), 3);
81/// ```
82pub const fn cardinality<T: Sequence>() -> usize {
83    T::CARDINALITY
84}
85
86/// Returns an iterator over all values of type `T`.
87///
88/// Values are yielded in the order defined by [`Sequence::next`], starting with
89/// [`Sequence::first`].
90///
91/// # Example
92/// ```
93/// use enum_iterator::{all, Sequence};
94///
95/// #[derive(Debug, PartialEq, Sequence)]
96/// enum Color { Red, Green, Blue }
97///
98/// assert_eq!(
99///     all::<Color>().collect::<Vec<_>>(),
100///     [Color::Red, Color::Green, Color::Blue],
101/// );
102/// ```
103pub fn all<T: Sequence>() -> All<T> {
104    All(T::first())
105}
106
107/// Returns an iterator over all values of type `T` in the reverse order of [`all`].
108///
109/// # Example
110/// ```
111/// use enum_iterator::{reverse_all, Sequence};
112///
113/// #[derive(Debug, PartialEq, Sequence)]
114/// enum Color { Red, Green, Blue }
115///
116/// assert_eq!(
117///     reverse_all::<Color>().collect::<Vec<_>>(),
118///     [Color::Blue, Color::Green, Color::Red],
119/// );
120/// ```
121pub fn reverse_all<T: Sequence>() -> ReverseAll<T> {
122    ReverseAll(T::last())
123}
124
125/// Returns the next value of type `T` or `None` if this was the end.
126///
127/// Same as [`Sequence::next`].
128///
129/// # Example
130/// ```
131/// use enum_iterator::{next, Sequence};
132///
133/// #[derive(Debug, PartialEq, Sequence)]
134/// enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
135///
136/// assert_eq!(next(&Day::Friday), Some(Day::Saturday));
137/// ```
138pub fn next<T: Sequence>(x: &T) -> Option<T> {
139    x.next()
140}
141
142/// Returns the next value of type `T` or [`first()`](first) if this was the end.
143///
144/// # Example
145/// ```
146/// use enum_iterator::{next_cycle, Sequence};
147///
148/// #[derive(Debug, PartialEq, Sequence)]
149/// enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
150///
151/// assert_eq!(next_cycle(&Day::Sunday), Day::Monday);
152/// ```
153pub fn next_cycle<T: Sequence>(x: &T) -> T {
154    next(x)
155        .or_else(first)
156        .expect("Sequence::first returned None for inhabited type")
157}
158
159/// Returns the previous value of type `T` or `None` if this was the beginning.
160///
161/// Same as [`Sequence::previous`].
162///
163/// # Example
164/// ```
165/// use enum_iterator::{previous, Sequence};
166///
167/// #[derive(Debug, PartialEq, Sequence)]
168/// enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
169///
170/// assert_eq!(previous(&Day::Saturday), Some(Day::Friday));
171/// ```
172pub fn previous<T: Sequence>(x: &T) -> Option<T> {
173    x.previous()
174}
175
176/// Returns the previous value of type `T` or [`last()`](last) if this was the beginning.
177///
178/// # Example
179/// ```
180/// use enum_iterator::{previous_cycle, Sequence};
181///
182/// #[derive(Debug, PartialEq, Sequence)]
183/// enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
184///
185/// assert_eq!(previous_cycle(&Day::Monday), Day::Sunday);
186/// ```
187pub fn previous_cycle<T: Sequence>(x: &T) -> T {
188    previous(x)
189        .or_else(last)
190        .expect("Sequence::last returned None for inhabited type")
191}
192
193/// Returns the first value of type `T`.
194///
195/// Same as [`Sequence::first`].
196///
197/// # Example
198/// ```
199/// use enum_iterator::{first, Sequence};
200///
201/// #[derive(Debug, PartialEq, Sequence)]
202/// enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
203///
204/// assert_eq!(first::<Day>(), Some(Day::Monday));
205/// ```
206pub fn first<T: Sequence>() -> Option<T> {
207    T::first()
208}
209
210/// Returns the last value of type `T`.
211///
212/// Same as [`Sequence::last`].
213///
214/// # Example
215/// ```
216/// use enum_iterator::{last, Sequence};
217///
218/// #[derive(Debug, PartialEq, Sequence)]
219/// enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
220///
221/// assert_eq!(last::<Day>(), Some(Day::Sunday));
222/// ```
223pub fn last<T: Sequence>() -> Option<T> {
224    T::last()
225}
226
227/// Iterator over the values of type `T`.
228///
229/// Returned by [`all`].
230#[derive(Clone, Debug)]
231pub struct All<T>(Option<T>);
232
233impl<T: Sequence> Iterator for All<T> {
234    type Item = T;
235
236    fn next(&mut self) -> Option<T> {
237        let item = self.0.take()?;
238        self.0 = item.next();
239        Some(item)
240    }
241}
242
243impl<T: Sequence> FusedIterator for All<T> {}
244
245/// Iterator over the values of type `T` in reverse order.
246///
247/// Returned by [`reverse_all`].
248#[derive(Clone, Debug)]
249pub struct ReverseAll<T>(Option<T>);
250
251impl<T: Sequence> Iterator for ReverseAll<T> {
252    type Item = T;
253
254    fn next(&mut self) -> Option<T> {
255        let item = self.0.take()?;
256        self.0 = item.previous();
257        Some(item)
258    }
259}
260
261impl<T: Sequence> FusedIterator for ReverseAll<T> {}
262
263/// Trait to iterate over the values of a type.
264///
265/// The [crate root](crate) defines useful functions to work with types implementing `Sequence`.
266///
267/// # Derivation
268///
269/// `Sequence` can be derived for `enum` and `struct` types. Specifically, it can be derived
270/// for:
271/// - Enumerations whose variants meet one of the following criteria:
272///   - The variant does not have fields.
273///   - The variant has fields meeting all these conditions:
274///     - Every field has a type that implements `Sequence`.
275///     - Every field but the last one has a type that implements `Clone`.
276/// - Enumerations without variants.
277/// - Structures whose fields meet all these conditions:
278///     - Every field has a type that implements `Sequence`.
279///     - Every field but the last one has a type that implements `Clone`.
280/// - Unit structures (i.e. without fields).
281///
282/// The cardinality (number of values) of the type must not exceed `usize::MAX`.
283///
284/// # Laws
285///
286/// `T: Sequence` implies the following assertions:
287/// - `T::first().and_then(|x| x.previous()).is_none()`
288/// - `T::last().and_then(|x| x.next()).is_none()`
289/// - `T::first().is_none()` ⇔ `T::last().is_none()`
290/// - `std::iter::successors(T::first(), T::next)` must eventually yield `T::last()`.
291/// - If `T` is inhabited, `T::first().is_some()`.
292///
293/// If a manual implementation of `Sequence` violates any of these laws, the functions at the crate root may misbehave, including panicking.
294///
295/// # Examples
296/// ## C-like enumeration
297///
298/// ```
299/// use enum_iterator::{all, cardinality, Sequence};
300///
301/// #[derive(Clone, Copy, Debug, PartialEq, Sequence)]
302/// enum Direction { North, South, West, East }
303///
304/// assert_eq!(cardinality::<Direction>(), 4);
305/// assert_eq!(all::<Direction>().collect::<Vec<_>>(), [
306///     Direction::North,
307///     Direction::South,
308///     Direction::West,
309///     Direction::East,
310/// ]);
311/// ```
312///
313/// ## Enumeration with data
314///
315/// ```
316/// use enum_iterator::{all, cardinality, Sequence};
317///
318/// #[derive(Clone, Copy, Debug, PartialEq, Sequence)]
319/// enum Direction { North, South, West, East }
320///
321/// #[derive(Clone, Copy, Debug, PartialEq, Sequence)]
322/// enum Greeting {
323///     Hi,
324///     Bye,
325/// }
326///
327/// #[derive(Clone, Copy, Debug, PartialEq, Sequence)]
328/// enum Action {
329///     Move(Direction),
330///     Jump,
331///     Talk { greeting: Greeting, loud: bool },
332/// }
333///
334/// assert_eq!(cardinality::<Action>(), 4 + 1 + 2 * 2);
335/// assert_eq!(all::<Action>().collect::<Vec<_>>(), [
336///     Action::Move(Direction::North),
337///     Action::Move(Direction::South),
338///     Action::Move(Direction::West),
339///     Action::Move(Direction::East),
340///     Action::Jump,
341///     Action::Talk { greeting: Greeting::Hi, loud: false },
342///     Action::Talk { greeting: Greeting::Hi, loud: true },
343///     Action::Talk { greeting: Greeting::Bye, loud: false },
344///     Action::Talk { greeting: Greeting::Bye, loud: true },
345/// ]);
346/// ```
347///
348/// ## Structure
349///
350/// ```
351/// use enum_iterator::{all, cardinality, Sequence};
352///
353/// #[derive(Clone, Copy, Debug, PartialEq, Sequence)]
354/// enum Side {
355///     Left,
356///     Right,
357/// }
358///
359/// #[derive(Clone, Copy, Debug, PartialEq, Sequence)]
360/// enum LimbKind {
361///     Arm,
362///     Leg,
363/// }
364///
365/// #[derive(Debug, PartialEq, Sequence)]
366/// struct Limb {
367///     kind: LimbKind,
368///     side: Side,
369/// }
370///
371/// assert_eq!(cardinality::<Limb>(), 4);
372/// assert_eq!(all::<Limb>().collect::<Vec<_>>(), [
373///     Limb { kind: LimbKind::Arm, side: Side::Left },
374///     Limb { kind: LimbKind::Arm, side: Side::Right },
375///     Limb { kind: LimbKind::Leg, side: Side::Left },
376///     Limb { kind: LimbKind::Leg, side: Side::Right },
377/// ]);
378/// ```
379pub trait Sequence: Sized {
380    /// Number of values of type `Self`.
381    ///
382    /// # Example
383    /// ```
384    /// use enum_iterator::Sequence;
385    ///
386    /// #[derive(Sequence)]
387    /// enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
388    ///
389    /// assert_eq!(Day::CARDINALITY, 7);
390    /// ```
391    const CARDINALITY: usize;
392
393    /// Returns value following `*self` or `None` if this was the end.
394    ///
395    /// Values are yielded in the following order. Comparisons between values are based on their
396    /// relative order as yielded by `next`; an element yielded after another is considered greater.
397    ///
398    /// - For primitive types, in increasing order (same as `Ord`).
399    /// - For arrays and tuples, in lexicographic order of the sequence of their elements.
400    /// - When derived for an enumeration, in variant definition order.
401    /// - When derived for a structure, in lexicographic order of the sequence of its fields taken
402    ///   in definition order.
403    ///
404    /// The order described above is the same as `Ord` if any custom `Sequence` implementation
405    /// follows `Ord` and any enumeration has its variants defined in increasing order of
406    /// discriminant.
407    ///
408    /// # Example
409    /// ```
410    /// use enum_iterator::Sequence;
411    ///
412    /// #[derive(Debug, PartialEq, Sequence)]
413    /// enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
414    ///
415    /// assert_eq!(Day::Tuesday.next(), Some(Day::Wednesday));
416    /// ```
417    fn next(&self) -> Option<Self>;
418
419    /// Returns value preceding `*self` or `None` if this was the beginning.
420    ///
421    /// # Example
422    /// ```
423    /// use enum_iterator::Sequence;
424    ///
425    /// #[derive(Debug, PartialEq, Sequence)]
426    /// enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
427    ///
428    /// assert_eq!(Day::Wednesday.previous(), Some(Day::Tuesday));
429    /// ```
430    fn previous(&self) -> Option<Self>;
431
432    /// Returns the first value of type `Self`.
433    ///
434    /// # Example
435    /// ```
436    /// use enum_iterator::Sequence;
437    ///
438    /// #[derive(Debug, PartialEq, Sequence)]
439    /// enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
440    ///
441    /// assert_eq!(Day::first(), Some(Day::Monday));
442    /// ```
443    fn first() -> Option<Self>;
444
445    /// Returns the last value of type `Self`.
446    ///
447    /// # Example
448    /// ```
449    /// use enum_iterator::Sequence;
450    ///
451    /// #[derive(Debug, PartialEq, Sequence)]
452    /// enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
453    ///
454    /// assert_eq!(Day::last(), Some(Day::Sunday));
455    /// ```
456    fn last() -> Option<Self>;
457}
458
459impl Sequence for bool {
460    const CARDINALITY: usize = 2;
461
462    fn next(&self) -> Option<Self> {
463        (!*self).then_some(true)
464    }
465
466    fn previous(&self) -> Option<Self> {
467        (*self).then_some(false)
468    }
469
470    fn first() -> Option<Self> {
471        Some(false)
472    }
473
474    fn last() -> Option<Self> {
475        Some(true)
476    }
477}
478
479macro_rules! impl_sequence_for_int {
480    ($ty:ty) => {
481        impl Sequence for $ty {
482            const CARDINALITY: usize = 1 << <$ty>::BITS;
483
484            fn next(&self) -> Option<Self> {
485                self.checked_add(1)
486            }
487
488            fn previous(&self) -> Option<Self> {
489                self.checked_sub(1)
490            }
491
492            fn first() -> Option<Self> {
493                Some(Self::MIN)
494            }
495
496            fn last() -> Option<Self> {
497                Some(Self::MAX)
498            }
499        }
500    };
501}
502
503impl_sequence_for_int!(i8);
504impl_sequence_for_int!(u8);
505impl_sequence_for_int!(i16);
506impl_sequence_for_int!(u16);
507
508impl Sequence for () {
509    const CARDINALITY: usize = 1;
510
511    fn next(&self) -> Option<Self> {
512        None
513    }
514
515    fn previous(&self) -> Option<Self> {
516        None
517    }
518
519    fn first() -> Option<Self> {
520        Some(())
521    }
522
523    fn last() -> Option<Self> {
524        Some(())
525    }
526}
527
528impl Sequence for core::convert::Infallible {
529    const CARDINALITY: usize = 0;
530
531    fn next(&self) -> Option<Self> {
532        None
533    }
534
535    fn previous(&self) -> Option<Self> {
536        None
537    }
538
539    fn first() -> Option<Self> {
540        None
541    }
542
543    fn last() -> Option<Self> {
544        None
545    }
546}
547
548impl Sequence for Ordering {
549    const CARDINALITY: usize = 3;
550
551    fn next(&self) -> Option<Self> {
552        int_to_ordering(*self as i8 + 1)
553    }
554
555    fn previous(&self) -> Option<Self> {
556        int_to_ordering(*self as i8 - 1)
557    }
558
559    fn first() -> Option<Self> {
560        Some(Ordering::Less)
561    }
562
563    fn last() -> Option<Self> {
564        Some(Ordering::Greater)
565    }
566}
567
568fn int_to_ordering(i: i8) -> Option<Ordering> {
569    match i {
570        -1 => Some(Ordering::Less),
571        0 => Some(Ordering::Equal),
572        1 => Some(Ordering::Greater),
573        _ => None,
574    }
575}
576
577impl<T: Sequence> Sequence for Option<T> {
578    const CARDINALITY: usize = T::CARDINALITY + 1;
579
580    fn next(&self) -> Option<Self> {
581        match self {
582            None => T::first().map(Some),
583            Some(x) => x.next().map(Some),
584        }
585    }
586
587    fn previous(&self) -> Option<Self> {
588        self.as_ref().map(T::previous)
589    }
590
591    fn first() -> Option<Self> {
592        Some(None)
593    }
594
595    fn last() -> Option<Self> {
596        Some(T::last())
597    }
598}
599
600impl<T: Sequence> Sequence for Poll<T> {
601    const CARDINALITY: usize = T::CARDINALITY + 1;
602
603    fn next(&self) -> Option<Self> {
604        match self {
605            Poll::Ready(x) => x.next().map(Poll::Ready).or(Some(Poll::Pending)),
606            Poll::Pending => None,
607        }
608    }
609
610    fn previous(&self) -> Option<Self> {
611        match self {
612            Poll::Ready(x) => x.previous().map(Poll::Ready),
613            Poll::Pending => T::last().map(Poll::Ready),
614        }
615    }
616
617    fn first() -> Option<Self> {
618        T::first().map(Poll::Ready).or(Some(Poll::Pending))
619    }
620
621    fn last() -> Option<Self> {
622        Some(Poll::Pending)
623    }
624}
625
626impl<const N: usize, T: Sequence + Clone> Sequence for [T; N] {
627    const CARDINALITY: usize = {
628        let tc = T::CARDINALITY;
629        let mut c = 1;
630        let mut i = 0;
631        loop {
632            if i == N {
633                break c;
634            }
635            c *= tc;
636            i += 1;
637        }
638    };
639
640    fn next(&self) -> Option<Self> {
641        advance_for_array(self, T::first)
642    }
643
644    fn previous(&self) -> Option<Self> {
645        advance_for_array(self, T::last)
646    }
647
648    fn first() -> Option<Self> {
649        if N == 0 {
650            Some(core::array::from_fn(|_| unreachable!()))
651        } else {
652            let x = T::first()?;
653            Some(core::array::from_fn(|_| x.clone()))
654        }
655    }
656
657    fn last() -> Option<Self> {
658        if N == 0 {
659            Some(core::array::from_fn(|_| unreachable!()))
660        } else {
661            let x = T::last()?;
662            Some(core::array::from_fn(|_| x.clone()))
663        }
664    }
665}
666
667fn advance_for_array<const N: usize, T, R>(a: &[T; N], reset: R) -> Option<[T; N]>
668where
669    T: Sequence + Clone,
670    R: Fn() -> Option<T>,
671{
672    let mut a = a.clone();
673    let keep = a.iter_mut().rev().try_fold((), |_, x| match x.next() {
674        Some(new_x) => {
675            *x = new_x;
676            ControlFlow::Break(true)
677        }
678        None => match reset() {
679            Some(new_x) => {
680                *x = new_x;
681                ControlFlow::Continue(())
682            }
683            None => ControlFlow::Break(false),
684        },
685    });
686    Some(a).filter(|_| matches!(keep, ControlFlow::Break(true)))
687}
688
689macro_rules! impl_seq_advance_for_tuple {
690    (
691        $this:ident,
692        $advance:ident,
693        $reset:ident,
694        $carry:ident
695        @ $($values:expr,)*
696        @
697        @ $($placeholders:pat,)*
698    ) => {
699        Some(($($values,)*)).filter(|_| !$carry)
700    };
701    (
702        $this:ident,
703        $advance:ident,
704        $reset:ident,
705        $carry:ident
706        @ $($values:expr,)*
707        @ $ty:ident, $($types:ident,)*
708        @ $($placeholders:pat,)*
709    ) => {{
710        let (.., item, $($placeholders,)*) = $this;
711        let (x, new_carry) = if $carry {
712            match Sequence::$advance(item) {
713                Some(x) => (x, false),
714                None => (Sequence::$reset()?, true),
715            }
716        } else {
717            (item.clone(), false)
718        };
719        impl_seq_advance_for_tuple!(
720            $this,
721            $advance,
722            $reset,
723            new_carry
724            @ x, $($values,)*
725            @ $($types,)*
726            @ _, $($placeholders,)*
727        )
728    }};
729    ($this:ident, $advance:ident, $reset:ident @ $($types:ident,)*) => {{
730        let (.., item) = $this;
731        let (x, carry) = match Sequence::$advance(item) {
732            Some(x) => (x, false),
733            None => (Sequence::$reset()?, true),
734        };
735        impl_seq_advance_for_tuple!($this, $advance, $reset, carry @ x, @ $($types,)* @ _,)
736    }};
737}
738
739macro_rules! impl_sequence_for_tuple {
740    ($($types:ident,)* @ $last:ident) => {
741        impl<$($types,)* $last> Sequence for ($($types,)* $last,)
742        where
743            $($types: Sequence + Clone,)*
744            $last: Sequence,
745        {
746            const CARDINALITY: usize =
747                $(<$types as Sequence>::CARDINALITY *)* <$last as Sequence>::CARDINALITY;
748
749            fn next(&self) -> Option<Self> {
750                impl_seq_advance_for_tuple!(self, next, first @ $($types,)*)
751            }
752
753            fn previous(&self) -> Option<Self> {
754                impl_seq_advance_for_tuple!(self, previous, last @ $($types,)*)
755            }
756
757            fn first() -> Option<Self> {
758                Some((
759                    $(<$types as Sequence>::first()?,)*
760                    <$last as Sequence>::first()?,
761                ))
762            }
763
764            fn last() -> Option<Self> {
765                Some((
766                    $(<$types as Sequence>::last()?,)*
767                    <$last as Sequence>::last()?,
768                ))
769            }
770        }
771    };
772}
773
774macro_rules! impl_sequence_for_tuples {
775    ($($types:ident,)*) => {
776        impl_sequence_for_tuples!(@ $($types,)*);
777    };
778    ($($types:ident,)* @ $head:ident, $($tail:ident,)*) => {
779        impl_sequence_for_tuple!($($types,)* @ $head);
780        impl_sequence_for_tuples!($($types,)* $head, @ $($tail,)*);
781    };
782    ($($types:ident,)* @) => {};
783}
784
785impl_sequence_for_tuples!(
786    T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20,
787    T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31,
788);
789
790#[cfg(test)]
791mod tests {
792    use crate::{all, cardinality, reverse_all, Sequence};
793    use core::{cmp::Ordering, convert::Infallible, task::Poll};
794
795    fn cardinality_equals_item_count<T: Sequence>() {
796        assert_eq!(cardinality::<T>(), all::<T>().count());
797    }
798
799    #[test]
800    fn cardinality_equals_item_count_for_bool() {
801        cardinality_equals_item_count::<bool>();
802    }
803
804    #[test]
805    fn all_bool_values_are_yielded() {
806        assert!(all::<bool>().eq([false, true]));
807    }
808
809    #[test]
810    fn all_bool_values_are_yielded_in_reverse() {
811        assert!(reverse_all::<bool>().eq([true, false]));
812    }
813
814    #[test]
815    fn cardinality_equals_item_count_for_i8() {
816        cardinality_equals_item_count::<i8>();
817    }
818
819    #[test]
820    fn all_i8_values_are_yielded() {
821        assert!(all::<i8>().eq(i8::MIN..=i8::MAX));
822    }
823
824    #[test]
825    fn all_i8_values_are_yielded_in_reverse() {
826        assert!(reverse_all::<i8>().eq((i8::MIN..=i8::MAX).rev()));
827    }
828
829    #[test]
830    fn cardinality_equals_item_count_for_u8() {
831        cardinality_equals_item_count::<u8>();
832    }
833
834    #[test]
835    fn all_u8_values_are_yielded() {
836        assert!(all::<u8>().eq(u8::MIN..=u8::MAX));
837    }
838
839    #[test]
840    fn all_u8_values_are_yielded_in_reverse() {
841        assert!(reverse_all::<u8>().eq((u8::MIN..=u8::MAX).rev()));
842    }
843
844    #[test]
845    fn cardinality_equals_item_count_for_i16() {
846        cardinality_equals_item_count::<i16>();
847    }
848
849    #[test]
850    fn all_i16_values_are_yielded() {
851        assert!(all::<i16>().eq(i16::MIN..=i16::MAX));
852    }
853
854    #[test]
855    fn all_i16_values_are_yielded_in_reverse() {
856        assert!(reverse_all::<i16>().eq((i16::MIN..=i16::MAX).rev()));
857    }
858
859    #[test]
860    fn cardinality_equals_item_count_for_u16() {
861        cardinality_equals_item_count::<u16>();
862    }
863
864    #[test]
865    fn all_u16_values_are_yielded() {
866        assert!(all::<u16>().eq(u16::MIN..=u16::MAX));
867    }
868
869    #[test]
870    fn all_u16_values_are_yielded_in_reverse() {
871        assert!(reverse_all::<u16>().eq((u16::MIN..=u16::MAX).rev()));
872    }
873
874    #[test]
875    fn cardinality_equals_item_count_for_unit() {
876        cardinality_equals_item_count::<()>();
877    }
878
879    #[test]
880    fn all_unit_values_are_yielded() {
881        assert!(all::<()>().eq([()]));
882    }
883
884    #[test]
885    fn all_unit_values_are_yielded_in_reverse() {
886        assert!(reverse_all::<()>().eq([()]));
887    }
888
889    #[test]
890    fn cardinality_equals_item_count_for_infallible() {
891        cardinality_equals_item_count::<Infallible>();
892    }
893
894    #[test]
895    fn all_infallible_values_are_yielded() {
896        assert!(all::<Infallible>().next().is_none());
897    }
898
899    #[test]
900    fn all_infallible_values_are_yielded_in_reverse() {
901        assert!(reverse_all::<Infallible>().next().is_none());
902    }
903
904    #[test]
905    fn cardinality_equals_item_count_for_tuple_with_infallible() {
906        cardinality_equals_item_count::<(bool, Infallible)>();
907    }
908
909    #[test]
910    fn all_tuple_with_infallible_values_are_yielded() {
911        assert!(all::<(bool, Infallible)>().next().is_none());
912    }
913
914    #[test]
915    fn all_tuple_with_infallible_values_are_yielded_in_reverse() {
916        assert!(reverse_all::<(bool, Infallible)>().next().is_none());
917    }
918
919    #[test]
920    fn cardinality_equals_item_count_for_singleton() {
921        cardinality_equals_item_count::<(u8,)>();
922    }
923
924    #[test]
925    fn cardinality_equals_item_count_for_pair() {
926        cardinality_equals_item_count::<(u8, bool)>();
927    }
928
929    #[test]
930    fn cardinality_equals_item_count_for_triple() {
931        cardinality_equals_item_count::<(bool, u8, bool)>();
932    }
933
934    #[test]
935    fn cardinality_equals_item_count_for_option() {
936        cardinality_equals_item_count::<Option<u8>>();
937    }
938
939    #[test]
940    fn all_bool_option_items_are_yielded() {
941        assert!(all::<Option<bool>>().eq([None, Some(false), Some(true)]));
942    }
943
944    #[test]
945    fn all_bool_option_items_are_yielded_in_reverse() {
946        assert!(reverse_all::<Option<bool>>().eq([Some(true), Some(false), None]));
947    }
948
949    #[test]
950    fn all_infallible_option_items_are_yielded() {
951        assert!(all::<Option<Infallible>>().eq([None]));
952    }
953
954    #[test]
955    fn all_infallible_option_items_are_yielded_in_reverse() {
956        assert!(reverse_all::<Option<Infallible>>().eq([None]));
957    }
958
959    #[test]
960    fn cardinality_equals_item_count_for_ordering() {
961        cardinality_equals_item_count::<Ordering>();
962    }
963
964    #[test]
965    fn all_ordering_values_are_yielded() {
966        assert!(all::<Ordering>().eq([Ordering::Less, Ordering::Equal, Ordering::Greater]));
967    }
968
969    #[test]
970    fn all_ordering_values_are_yielded_in_reverse() {
971        assert!(reverse_all::<Ordering>().eq([Ordering::Greater, Ordering::Equal, Ordering::Less]));
972    }
973
974    #[test]
975    fn cardinality_equals_item_count_for_poll() {
976        cardinality_equals_item_count::<Poll<u8>>();
977    }
978
979    #[test]
980    fn all_bool_poll_items_are_yielded() {
981        assert!(all::<Poll<bool>>().eq([Poll::Ready(false), Poll::Ready(true), Poll::Pending]));
982    }
983
984    #[test]
985    fn all_bool_poll_items_are_yielded_in_reverse() {
986        assert!(reverse_all::<Poll<bool>>().eq([
987            Poll::Pending,
988            Poll::Ready(true),
989            Poll::Ready(false),
990        ]));
991    }
992
993    #[test]
994    fn all_infallible_poll_items_are_yielded() {
995        assert!(all::<Poll<Infallible>>().eq([Poll::Pending]));
996    }
997
998    #[test]
999    fn all_infallible_poll_items_are_yielded_in_reverse() {
1000        assert!(reverse_all::<Poll<Infallible>>().eq([Poll::Pending]));
1001    }
1002
1003    #[test]
1004    fn tuple_fields_vary_from_right_to_left() {
1005        assert!(all::<(Option<bool>, bool)>().eq([
1006            (None, false),
1007            (None, true),
1008            (Some(false), false),
1009            (Some(false), true),
1010            (Some(true), false),
1011            (Some(true), true),
1012        ]));
1013    }
1014
1015    #[test]
1016    fn cardinality_of_empty_array_is_one() {
1017        assert_eq!(cardinality::<[u8; 0]>(), 1);
1018    }
1019
1020    #[test]
1021    fn cardinality_equals_item_count_for_empty_array() {
1022        cardinality_equals_item_count::<[u8; 0]>();
1023    }
1024
1025    #[test]
1026    fn cardinality_equals_item_count_for_array() {
1027        cardinality_equals_item_count::<[u8; 3]>();
1028    }
1029
1030    #[test]
1031    fn array_items_vary_from_right_to_left() {
1032        assert!(all::<[Option<bool>; 2]>().eq([
1033            [None, None],
1034            [None, Some(false)],
1035            [None, Some(true)],
1036            [Some(false), None],
1037            [Some(false), Some(false)],
1038            [Some(false), Some(true)],
1039            [Some(true), None],
1040            [Some(true), Some(false)],
1041            [Some(true), Some(true)],
1042        ]));
1043    }
1044
1045    #[test]
1046    fn all_empty_array_items_are_yielded() {
1047        assert!(all::<[bool; 0]>().eq([[]]));
1048    }
1049
1050    #[test]
1051    fn cardinality_of_empty_infallible_array_is_one() {
1052        assert_eq!(cardinality::<[Infallible; 0]>(), 1);
1053    }
1054
1055    #[test]
1056    fn cardinality_of_non_empty_infallible_array_is_zero() {
1057        assert_eq!(cardinality::<[Infallible; 1]>(), 0);
1058    }
1059
1060    #[test]
1061    fn all_empty_infallible_array_items_are_yielded() {
1062        assert!(all::<[Infallible; 0]>().eq([[]]));
1063    }
1064
1065    #[test]
1066    fn all_non_empty_infallible_array_items_are_yielded() {
1067        assert!(all::<[Infallible; 1]>().next().is_none());
1068    }
1069}