tuplex/
lib.rs

1//! Rust tuple extension.
2//!
3//! # Features
4//!
5//! 1. adding/removing element at front/back
6//!
7//! 2. converting heterogeneous tuples to homogeneous ones
8//!
9//! 3. checking the length bound of the given tuple in `where` clause
10//!
11//! # Examples: list operations
12//!
13//! ```
14//! use tuplex::*;
15//!
16//! let tuple = ();
17//! assert_eq!( tuple.len(), 0 );
18//!
19//! let tuple = tuple.push_front( 0 );
20//! assert_eq!( tuple, (0,) );
21//! assert_eq!( tuple.len(), 1 );
22//!
23//! let tuple = tuple.push_front( false );
24//! assert_eq!( tuple, (false,0) );
25//! assert_eq!( tuple.len(), 2 );
26//!
27//! let tuple = tuple.push_back( true );
28//! assert_eq!( tuple, (false,0,true) );
29//! assert_eq!( tuple.len(), 3 );
30//!
31//! let tuple = tuple.push_back( 1 );
32//! assert_eq!( tuple, (false,0,true,1) );
33//! assert_eq!( tuple.len(), 4 );
34//!
35//! let (front,tuple) = tuple.pop_front();
36//! assert_eq!( front, false );
37//! assert_eq!( tuple, (0,true,1) );
38//!
39//! let (back,tuple) = tuple.pop_back();
40//! assert_eq!( back, 1 );
41//! assert_eq!( tuple, (0,true) );
42//! ```
43//!
44//! # Examples: homogeneous/heterogeneous conversions
45//!
46//! ```
47//! use tuplex::*;
48//!
49//! // `into_homo_tuple()` works because i32 can be converted from i3, u16 and i32.
50//! assert_eq!( (3_i8, 7_u16, 21_i32).into_homo_tuple(), (3_i32, 7_i32, 21_i32) );
51//! ```
52//!
53//! # Examples: Length bound
54//!
55//! 3. checking the length bound of the given tuple in `where` clause
56//!
57//! ```
58//! use tuplex::*;
59//!
60//! fn foo<Val,Tag>( val: Val ) where Val: LenExceeds<[();3],Tag> {}
61//!
62//! foo((0,0,0,0));
63//! // foo((0,0,0)); // won't compile
64//!
65//! ```
66
67#![cfg_attr(not(feature = "std"), no_std)]
68#[cfg(not(feature = "std"))]
69pub extern crate alloc;
70#[cfg(not(feature = "std"))]
71use alloc::{boxed::Box, vec, vec::Vec};
72#[cfg(not(feature = "std"))]
73use core::marker::PhantomData;
74#[cfg(feature = "std")]
75use std::marker::PhantomData;
76
77/// Denotes a tuple type, the fields of which are of the same type.
78/// Up to 32 fields.
79#[macro_export]
80macro_rules! homo_tuple {
81    ($t:ty;  0) => { () };
82    ($t:ty;  1) => { ($t,) };
83    ($t:ty;  2) => { ($t,$t) };
84    ($t:ty;  3) => { ($t,$t,$t) };
85    ($t:ty;  4) => { ($t,$t,$t,$t) };
86    ($t:ty;  5) => { ($t,$t,$t,$t,$t) };
87    ($t:ty;  6) => { ($t,$t,$t,$t,$t,$t) };
88    ($t:ty;  7) => { ($t,$t,$t,$t,$t,$t,$t) };
89    ($t:ty;  8) => { ($t,$t,$t,$t,$t,$t,$t,$t) };
90    ($t:ty;  9) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t) };
91    ($t:ty; 10) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
92    ($t:ty; 11) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
93    ($t:ty; 12) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
94    ($t:ty; 13) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
95    ($t:ty; 14) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
96    ($t:ty; 15) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
97    ($t:ty; 16) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
98    ($t:ty; 17) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
99    ($t:ty; 18) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
100    ($t:ty; 19) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
101    ($t:ty; 20) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
102    ($t:ty; 21) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
103    ($t:ty; 22) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
104    ($t:ty; 23) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
105    ($t:ty; 24) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
106    ($t:ty; 25) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
107    ($t:ty; 26) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
108    ($t:ty; 27) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
109    ($t:ty; 28) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
110    ($t:ty; 29) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
111    ($t:ty; 30) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
112    ($t:ty; 31) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
113    ($t:ty; 32) => { ($t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t,$t) };
114}
115
116/// Indicate the amount of the tuple's fields.
117pub trait Len {
118    const LEN: usize;
119    fn len( &self ) -> usize;
120}
121
122macro_rules! impl_len {
123    ( $len:tt, $($index:tt $gen:ident)* ) => {
124        #[allow( unused_parens )]
125        impl<$($gen),* > Len for ($($gen,)* ) {
126            const LEN: usize = $len;
127            fn len( &self ) -> usize { $len }
128        }
129
130        impl<T> Len for [T; $len] {
131            const LEN: usize = $len;
132            fn len( &self ) -> usize { $len }
133        }
134    };
135}
136
137impl_len!( 0,      );
138impl_len!( 1, 0 T0 );
139
140macro_rules! impl_len_eq {
141    ( $len:tt, $($index:tt $gen:ident)* ) => {
142        #[allow( unused_parens )]
143        impl<$($gen),* > LenEq for ($($gen,)* ) { type Array = [();$len]; }
144    };
145}
146
147impl_len_eq!( 0,      );
148impl_len_eq!( 1, 0 T0 );
149
150/// Adds a `Front` value to the tuple, as the first field.
151pub trait PushFront<Front> {
152    type Output;
153    fn push_front( self, front: Front ) -> Self::Output;
154}
155
156macro_rules! impl_push_front {
157    ($($index:tt $gen:ident)*) => {
158        #[allow( unused_parens )]
159        impl<Front,$($gen),*> PushFront<Front> for ($($gen,)*) {
160            type Output = (Front,$($gen),*);
161            fn push_front( self, front: Front ) -> Self::Output { (front, $(self.$index),*) }
162        }
163    };
164}
165
166impl_push_front!();
167impl_push_front!( 0 T0 );
168
169/// Adds a `Back` value to the tuple, as the last field.
170pub trait PushBack<Back> {
171    type Output;
172    fn push_back( self, back: Back ) -> Self::Output;
173}
174
175macro_rules! impl_push_back {
176    ($($index:tt $gen:ident)*) => {
177        #[allow( unused_parens )]
178        impl<Back,$($gen),*> PushBack<Back> for ($($gen,)*) {
179            type Output = ($($gen,)*Back,);
180            fn push_back( self, back: Back ) -> Self::Output { ($(self.$index,)* back,) }
181        }
182    };
183}
184
185impl_push_back!();
186impl_push_back!( 0 T0 );
187
188/// Removes the first field of the tuple.
189pub trait PopFront {
190    type Remain;
191    type Front;
192    fn pop_front( self ) -> (Self::Front, Self::Remain);
193}
194
195macro_rules! impl_pop_front {
196    ($($index:tt $gen:ident)*) => {
197        #[allow( unused_parens )]
198        impl<T0$(,$gen)*> PopFront for (T0,$($gen),*) {
199            type Remain = ( ($($gen,)*) );
200            type Front = T0;
201            fn pop_front( self ) -> (Self::Front, Self::Remain) { (self.0, ($(self.$index,)*)) }
202        }
203    };
204}
205
206impl_pop_front!();
207
208/// Removes the last field of the tuple.
209pub trait PopBack {
210    type Remain;
211    type Back;
212    fn pop_back( self ) -> (Self::Back, Self::Remain);
213}
214
215macro_rules! impl_pop_back {
216    (($($index:tt $gen:ident)*) $($last_index:tt $last_gen:ident)* ) => {
217        #[allow( unused_parens )]
218        impl<$($gen,)* $($last_gen),*> PopBack for ($($gen,)* $($last_gen,)*) {
219            type Remain = ( ($($gen,)*) );
220            type Back = $($last_gen)*;
221            fn pop_back( self ) -> (Self::Back, Self::Remain) { (self.$($last_index)*, ($(self.$index,)*)) }
222        }
223    };
224}
225
226impl_pop_back!( () 0 T0 );
227
228/// Reshape the linear tuple type to a binary tree, either left associated or right associated.
229///
230/// # Examples
231///
232/// ```rust
233/// use tuplex::*;
234///
235/// let _: ((((),bool), i32), String) = <(bool, i32, String) as BinTuple>::LeftAssociated::default();
236/// let _: (bool, (i32, (String,()))) = <(bool, i32, String) as BinTuple>::RightAssociated::default();
237/// ```
238pub trait BinTuple {
239    type LeftAssociated;
240    type RightAssociated;
241}
242
243macro_rules! impl_bin_tuple {
244    ($($gen:ident)*) => {
245        impl<RemainL,RemainR,T0$(,$gen)*> BinTuple for (T0, $($gen,)*)
246            where Self   : PopFront<Remain=RemainR>
247                         + PopBack<Remain=RemainL>
248                , RemainL: BinTuple
249                , RemainR: BinTuple
250        {
251            type LeftAssociated = (<<Self as PopBack>::Remain as BinTuple>::LeftAssociated, <Self as PopBack>::Back);
252            type RightAssociated = (<Self as PopFront>::Front, <<Self as PopFront>::Remain as BinTuple>::RightAssociated);
253        }
254    };
255}
256
257impl BinTuple for () {
258    type LeftAssociated = ();
259    type RightAssociated = ();
260}
261
262impl_bin_tuple!();
263
264/// Converts a tuple from another one, the fields of which can be converted into the fields of the new tuple.
265pub trait FromTuple<Tup> {
266    fn from_tuple( tup: Tup ) -> Self;
267}
268
269macro_rules! impl_tuple_from_tuple {
270    ($($index:tt $t:ident $u:ident)*) => {
271        impl<$($t,$u),*> FromTuple<($($t,)*)> for ($($u,)*)
272            where $($t: Into<$u>),*
273        {
274            fn from_tuple( _tup: ($($t,)*) ) -> Self {
275                ( $( _tup.$index.into(), )* )
276            }
277        }
278    };
279}
280
281impl_tuple_from_tuple!(       );
282impl_tuple_from_tuple!( 0 T U );
283
284/// Converts a tuple to a new one. This is the counterpart of `FromTuple`.
285pub trait IntoTuple<Tup> {
286    fn into_tuple( self ) -> Tup;
287}
288
289impl<Src,Dest> IntoTuple<Dest> for Src
290    where Dest: FromTuple<Src>
291{
292    fn into_tuple( self ) -> Dest {
293        Dest::from_tuple( self )
294    }
295}
296
297/// Converts a heterogeneous tuple to a homogeneous one.
298pub trait IntoHomoTuple<T> {
299    type Output: HomoTuple<T>;
300    fn into_homo_tuple( self ) -> Self::Output;
301}
302
303macro_rules! impl_tuple_into_homo_tuple {
304    ($len:tt, $($index:tt $gen:ident)*) => {
305        impl<T$(,$gen)*> IntoHomoTuple<T> for ($($gen,)*)
306            where $($gen: Into<T>),*
307        {
308            type Output = homo_tuple!(T; $len);
309
310            fn into_homo_tuple( self ) -> Self::Output {
311                ( $( self.$index.into(), )* )
312            }
313        }
314    };
315}
316
317impl_tuple_into_homo_tuple!( 0,      );
318impl_tuple_into_homo_tuple!( 1, 0 T0 );
319
320/// Homogeneous Tuple's trait.
321pub trait HomoTuple<T>
322    where Self: Len
323              + IntoArray<T>
324              + IntoBoxedSlice<T>
325{
326    /// New type of tuple after fields converted into `Option`.
327    type FieldsWrapped;
328
329    /// New type of tuple after the whole tuple has been wrapped.
330    type TupleWrapped: IntoIterator<Item=T>;
331
332    /// Converts fields into `Option`.
333    fn wrap_fields( self ) -> Self::FieldsWrapped;
334
335    /// Wraps the whole tuple and get a new type.
336    fn wrap_tuple( self ) -> Self::TupleWrapped;
337
338    /// Converts the tuple into an iterater which owns the fields, by internally converting all fields into `Option`s.
339    fn wrap_into_iter( self ) -> <Self::TupleWrapped as IntoIterator>::IntoIter;
340}
341
342pub struct HTup0<T>( PhantomData<T> );
343
344pub struct HTupIter0<T>( PhantomData<T> );
345
346impl<T> Iterator for HTupIter0<T> {
347    type Item = T;
348    fn next( &mut self ) -> Option<Self::Item> { None }
349}
350
351impl<T> IntoIterator for HTup0<T> {
352    type Item = T;
353    type IntoIter = HTupIter0<T>;
354
355    fn into_iter( self ) -> Self::IntoIter {
356        HTupIter0( PhantomData )
357    }
358}
359
360impl<T> HomoTuple<T> for () {
361    type FieldsWrapped = ();
362    type TupleWrapped = HTup0<T>;
363    fn wrap_fields( self ) -> Self::FieldsWrapped { () }
364    fn wrap_tuple( self ) -> Self::TupleWrapped { HTup0( PhantomData )}
365    fn wrap_into_iter( self ) -> <Self::TupleWrapped as IntoIterator>::IntoIter { self.wrap_tuple().into_iter() }
366}
367
368macro_rules! impl_homo {
369    ($wrapper:ident $wrapper_iter:ident $len:tt, $($index:tt)* ) => {
370        impl<T> HomoTuple<T> for homo_tuple!( T; $len ) {
371            type FieldsWrapped = homo_tuple!( Option<T>; $len );
372            type TupleWrapped = $wrapper<T>;
373
374            #[allow( unused_parens )]
375            fn wrap_fields( self ) -> Self::FieldsWrapped {
376                ( $( Some( self.$index ), )* )
377            }
378
379            fn wrap_tuple( self ) -> Self::TupleWrapped {
380                $wrapper( self )
381            }
382
383            fn wrap_into_iter( self ) -> <Self::TupleWrapped as IntoIterator>::IntoIter { self.wrap_tuple().into_iter() }
384        }
385
386        pub struct $wrapper<T>( homo_tuple!( T; $len )) where homo_tuple!( T; $len ): HomoTuple<T>;
387
388        pub struct $wrapper_iter<T> {
389            tuple: <homo_tuple!( T; $len ) as HomoTuple<T>>::FieldsWrapped,
390            index: usize,
391        }
392
393        impl<T> Iterator for $wrapper_iter<T> {
394            type Item = T;
395            fn next( &mut self ) -> Option<Self::Item> {
396                let item = match self.index {
397                    $( $index => (self.tuple.$index).take(), )*
398                    _ => None,
399                };
400                self.index += 1;
401                item
402            }
403
404            fn size_hint( &self ) -> (usize, Option<usize>) {
405                let len = $len - self.index;
406                (len, Some( len ))
407            }
408        }
409
410        impl<T> ExactSizeIterator for $wrapper_iter<T> {}
411
412        impl<T> IntoIterator for $wrapper<T> {
413            type Item = T;
414            type IntoIter = $wrapper_iter<T>;
415            fn into_iter( self ) -> Self::IntoIter {
416                $wrapper_iter{ tuple: self.0.wrap_fields(), index: 0 }
417            }
418        }
419    };
420}
421
422impl_homo!( HTup1 HTupIter1 1, 0 );
423
424/// The map adapter for homogeneous tuples
425pub trait MapHomoTuple<T,U>: HomoTuple<T> + Sized {
426    type Output: HomoTuple<U> + Sized;
427    fn map_homo_tuple( self, f: impl Fn(T)->U ) -> <Self as MapHomoTuple<T,U>>::Output;
428}
429
430macro_rules! impl_map_homo_tuple {
431    ($len:tt, $($index:tt)*) => {
432        impl<T,U> MapHomoTuple<T,U> for homo_tuple!( T; $len ) {
433            type Output = homo_tuple!( U; $len );
434            fn map_homo_tuple( self, _f: impl Fn(T)->U ) -> <Self as MapHomoTuple<T,U>>::Output {
435                ( $( _f( self.$index ), )* )
436            }
437        }
438    };
439}
440
441impl_map_homo_tuple!( 0,   );
442impl_map_homo_tuple!( 1, 0 );
443
444macro_rules! impl_array_from_tuple {
445    ($len:tt, $($index:tt $gen:ident)*) => {
446        impl<T$(,$gen)*> FromTuple<($($gen,)*)> for [T; $len]
447            where $($gen: Into<T>),*
448        {
449            fn from_tuple( _tup: ($($gen,)*) ) -> Self {
450                [ $( _tup.$index.into() ),* ]
451            }
452        }
453    };
454}
455
456impl_array_from_tuple!( 0,      );
457impl_array_from_tuple!( 1, 0 T0 );
458
459/// Converts a tuple into an array, where the fields of the tuple can be converted into the same type of the array element.
460pub trait IntoArray<T> {
461    type Output: Len;
462    fn into_array( self ) -> Self::Output;
463}
464
465macro_rules! impl_tuple_into_array {
466    ($len:tt, $($index:tt $gen:ident)*) => {
467        impl<T$(,$gen)*> IntoArray<T> for ($($gen,)*)
468            where $($gen: Into<T>),*
469        {
470            type Output = [T; $len];
471
472            fn into_array( self ) -> Self::Output {
473                [ $( (self.$index).into() ),* ]
474            }
475        }
476    };
477}
478
479impl_tuple_into_array!( 0,      );
480impl_tuple_into_array!( 1, 0 T0 );
481
482/// Converts a tuple into a boxed slice, where the fields of the tuple can be converted into the same type of the slice element.
483pub trait IntoBoxedSlice<T> {
484    fn into_boxed_slice( self ) -> Box<[T]>;
485}
486
487macro_rules! impl_tuple_into_boxed_slice {
488    ($len:tt, $($index:tt $gen:ident)*) => {
489        impl<T$(,$gen)*> IntoBoxedSlice<T> for ($($gen,)*)
490            where $($gen: Into<T>),*
491        {
492            fn into_boxed_slice( self ) -> Box<[T]> {
493                Box::new([ $( (self.$index).into() ),* ])
494            }
495        }
496    };
497}
498
499impl_tuple_into_boxed_slice!( 0,      );
500impl_tuple_into_boxed_slice!( 1, 0 T0 );
501
502/// Converts a tuple into a `Vec`, where the fields of the tuple can be converted into the same type of the `Vec`'s element.
503pub trait IntoVec<T> {
504    fn into_vec( self ) -> Vec<T>;
505}
506
507macro_rules! impl_tuple_into_vec {
508    ($len:tt, $($index:tt $gen:ident)*) => {
509        impl<T$(,$gen)*> IntoVec<T> for ($($gen,)*)
510            where $(T: From<$gen>),*
511        {
512            fn into_vec( self ) -> Vec<T> {
513                vec![ $( T::from( self.$index )),* ]
514            }
515        }
516    };
517}
518
519impl_tuple_into_vec!( 0,      );
520impl_tuple_into_vec!( 1, 0 T0 );
521
522/// Marks that `Self` is a value of `T`. The purpose of this trait is for implementing `TupleOf`.
523pub trait ValueOf<T> {}
524
525/// A tuple is composed of `T` if all of its fields are values of `T`. See `ValueOf`.
526pub trait TupleOf<T> {}
527
528macro_rules! impl_tuple_of {
529    ($($t:ident)*) => {
530        impl<T,$($t),*> TupleOf<T> for ($($t,)*)
531            where $($t: ValueOf<T> ),*
532        {
533        }
534    };
535}
536
537impl_tuple_of!();
538impl_tuple_of!( T0 );
539
540/// Converts to another type. The purpose of this trait is for implementing `ConvertTuple`.
541pub trait Convert {
542    type Output;
543    fn convert( self ) -> Self::Output;
544}
545
546/// Converts a tuple to another one, where the fields of the old tuple can be `Convert`-ed into the fiedls of the new tuple. See `Convert`.
547pub trait ConvertTuple {
548    type Output;
549    fn convert_tuple( self ) -> Self::Output;
550}
551
552macro_rules! impl_convert_tuple {
553    ($($index:tt $t:ident $u:ident)*) => {
554        impl<$($t,$u),*> ConvertTuple for ($($t,)*)
555            where $($t: Convert<Output=$u>),*
556        {
557            type Output = ($($u,)*);
558            fn convert_tuple( self ) -> Self::Output {
559                ($( Convert::convert( self.$index ),)*)
560            }
561        }
562    };
563}
564
565impl_convert_tuple!();
566impl_convert_tuple!( 0 T0 U0 );
567
568pub trait Onion { type Type; }
569
570impl Onion for [(); 0] { type Type = (); }
571impl Onion for [(); 1] { type Type = ((),); }
572impl Onion for [(); 2] { type Type = (((),),); }
573impl Onion for [(); 3] { type Type = ((((),),),); }
574impl Onion for [(); 4] { type Type = (((((),),),),); }
575impl Onion for [(); 5] { type Type = ((((((),),),),),); }
576impl Onion for [(); 6] { type Type = (((((((),),),),),),); }
577impl Onion for [(); 7] { type Type = ((((((((),),),),),),),); }
578impl Onion for [(); 8] { type Type = (((((((((),),),),),),),),); }
579impl Onion for [(); 9] { type Type = ((((((((((),),),),),),),),),); }
580impl Onion for [();10] { type Type = (((((((((((),),),),),),),),),),); }
581impl Onion for [();11] { type Type = ((((((((((((),),),),),),),),),),),); }
582impl Onion for [();12] { type Type = (((((((((((((),),),),),),),),),),),),); }
583impl Onion for [();13] { type Type = ((((((((((((((),),),),),),),),),),),),),); }
584impl Onion for [();14] { type Type = (((((((((((((((),),),),),),),),),),),),),),); }
585impl Onion for [();15] { type Type = ((((((((((((((((),),),),),),),),),),),),),),),); }
586impl Onion for [();16] { type Type = (((((((((((((((((),),),),),),),),),),),),),),),),); }
587impl Onion for [();17] { type Type = ((((((((((((((((((),),),),),),),),),),),),),),),),),); }
588impl Onion for [();18] { type Type = (((((((((((((((((((),),),),),),),),),),),),),),),),),),); }
589impl Onion for [();19] { type Type = ((((((((((((((((((((),),),),),),),),),),),),),),),),),),),); }
590impl Onion for [();20] { type Type = (((((((((((((((((((((),),),),),),),),),),),),),),),),),),),),); }
591impl Onion for [();21] { type Type = ((((((((((((((((((((((),),),),),),),),),),),),),),),),),),),),),); }
592impl Onion for [();22] { type Type = (((((((((((((((((((((((),),),),),),),),),),),),),),),),),),),),),),); }
593impl Onion for [();23] { type Type = ((((((((((((((((((((((((),),),),),),),),),),),),),),),),),),),),),),),); }
594impl Onion for [();24] { type Type = (((((((((((((((((((((((((),),),),),),),),),),),),),),),),),),),),),),),),); }
595impl Onion for [();25] { type Type = ((((((((((((((((((((((((((),),),),),),),),),),),),),),),),),),),),),),),),),); }
596impl Onion for [();26] { type Type = (((((((((((((((((((((((((((),),),),),),),),),),),),),),),),),),),),),),),),),),); }
597impl Onion for [();27] { type Type = ((((((((((((((((((((((((((((),),),),),),),),),),),),),),),),),),),),),),),),),),),); }
598impl Onion for [();28] { type Type = (((((((((((((((((((((((((((((),),),),),),),),),),),),),),),),),),),),),),),),),),),),); }
599impl Onion for [();29] { type Type = ((((((((((((((((((((((((((((((),),),),),),),),),),),),),),),),),),),),),),),),),),),),),); }
600impl Onion for [();30] { type Type = (((((((((((((((((((((((((((((((),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),); }
601impl Onion for [();31] { type Type = ((((((((((((((((((((((((((((((((),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),); }
602impl Onion for [();32] { type Type = (((((((((((((((((((((((((((((((((),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),); }
603
604pub trait LenExceeds<A, O> {}
605
606impl<A,B,O> LenExceeds<A, [(); 1]> for B where A : Onion<Type=O>, B : Onion<Type=(O,)> {}
607impl<A,B,O> LenExceeds<A, [(); 2]> for B where A : Onion<Type=O>, B : Onion<Type=((O,),)> {}
608impl<A,B,O> LenExceeds<A, [(); 3]> for B where A : Onion<Type=O>, B : Onion<Type=(((O,),),)> {}
609impl<A,B,O> LenExceeds<A, [(); 4]> for B where A : Onion<Type=O>, B : Onion<Type=((((O,),),),)> {}
610impl<A,B,O> LenExceeds<A, [(); 5]> for B where A : Onion<Type=O>, B : Onion<Type=(((((O,),),),),)> {}
611impl<A,B,O> LenExceeds<A, [(); 6]> for B where A : Onion<Type=O>, B : Onion<Type=((((((O,),),),),),)> {}
612impl<A,B,O> LenExceeds<A, [(); 7]> for B where A : Onion<Type=O>, B : Onion<Type=(((((((O,),),),),),),)> {}
613impl<A,B,O> LenExceeds<A, [(); 8]> for B where A : Onion<Type=O>, B : Onion<Type=((((((((O,),),),),),),),)> {}
614impl<A,B,O> LenExceeds<A, [(); 9]> for B where A : Onion<Type=O>, B : Onion<Type=(((((((((O,),),),),),),),),)> {}
615impl<A,B,O> LenExceeds<A, [();10]> for B where A : Onion<Type=O>, B : Onion<Type=((((((((((O,),),),),),),),),),)> {}
616impl<A,B,O> LenExceeds<A, [();11]> for B where A : Onion<Type=O>, B : Onion<Type=(((((((((((O,),),),),),),),),),),)> {}
617impl<A,B,O> LenExceeds<A, [();12]> for B where A : Onion<Type=O>, B : Onion<Type=((((((((((((O,),),),),),),),),),),),)> {}
618impl<A,B,O> LenExceeds<A, [();13]> for B where A : Onion<Type=O>, B : Onion<Type=(((((((((((((O,),),),),),),),),),),),),)> {}
619impl<A,B,O> LenExceeds<A, [();14]> for B where A : Onion<Type=O>, B : Onion<Type=((((((((((((((O,),),),),),),),),),),),),),)> {}
620impl<A,B,O> LenExceeds<A, [();15]> for B where A : Onion<Type=O>, B : Onion<Type=(((((((((((((((O,),),),),),),),),),),),),),),)> {}
621impl<A,B,O> LenExceeds<A, [();16]> for B where A : Onion<Type=O>, B : Onion<Type=((((((((((((((((O,),),),),),),),),),),),),),),),)> {}
622impl<A,B,O> LenExceeds<A, [();17]> for B where A : Onion<Type=O>, B : Onion<Type=(((((((((((((((((O,),),),),),),),),),),),),),),),),)> {}
623impl<A,B,O> LenExceeds<A, [();18]> for B where A : Onion<Type=O>, B : Onion<Type=((((((((((((((((((O,),),),),),),),),),),),),),),),),),)> {}
624impl<A,B,O> LenExceeds<A, [();19]> for B where A : Onion<Type=O>, B : Onion<Type=(((((((((((((((((((O,),),),),),),),),),),),),),),),),),),)> {}
625impl<A,B,O> LenExceeds<A, [();20]> for B where A : Onion<Type=O>, B : Onion<Type=((((((((((((((((((((O,),),),),),),),),),),),),),),),),),),),)> {}
626impl<A,B,O> LenExceeds<A, [();21]> for B where A : Onion<Type=O>, B : Onion<Type=(((((((((((((((((((((O,),),),),),),),),),),),),),),),),),),),),)> {}
627impl<A,B,O> LenExceeds<A, [();22]> for B where A : Onion<Type=O>, B : Onion<Type=((((((((((((((((((((((O,),),),),),),),),),),),),),),),),),),),),),)> {}
628impl<A,B,O> LenExceeds<A, [();23]> for B where A : Onion<Type=O>, B : Onion<Type=(((((((((((((((((((((((O,),),),),),),),),),),),),),),),),),),),),),),)> {}
629impl<A,B,O> LenExceeds<A, [();24]> for B where A : Onion<Type=O>, B : Onion<Type=((((((((((((((((((((((((O,),),),),),),),),),),),),),),),),),),),),),),),)> {}
630impl<A,B,O> LenExceeds<A, [();25]> for B where A : Onion<Type=O>, B : Onion<Type=(((((((((((((((((((((((((O,),),),),),),),),),),),),),),),),),),),),),),),),)> {}
631impl<A,B,O> LenExceeds<A, [();26]> for B where A : Onion<Type=O>, B : Onion<Type=((((((((((((((((((((((((((O,),),),),),),),),),),),),),),),),),),),),),),),),),)> {}
632impl<A,B,O> LenExceeds<A, [();27]> for B where A : Onion<Type=O>, B : Onion<Type=(((((((((((((((((((((((((((O,),),),),),),),),),),),),),),),),),),),),),),),),),),)> {}
633impl<A,B,O> LenExceeds<A, [();28]> for B where A : Onion<Type=O>, B : Onion<Type=((((((((((((((((((((((((((((O,),),),),),),),),),),),),),),),),),),),),),),),),),),),)> {}
634impl<A,B,O> LenExceeds<A, [();29]> for B where A : Onion<Type=O>, B : Onion<Type=(((((((((((((((((((((((((((((O,),),),),),),),),),),),),),),),),),),),),),),),),),),),),)> {}
635impl<A,B,O> LenExceeds<A, [();30]> for B where A : Onion<Type=O>, B : Onion<Type=((((((((((((((((((((((((((((((O,),),),),),),),),),),),),),),),),),),),),),),),),),),),),),)> {}
636impl<A,B,O> LenExceeds<A, [();31]> for B where A : Onion<Type=O>, B : Onion<Type=(((((((((((((((((((((((((((((((O,),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),)> {}
637impl<A,B,O> LenExceeds<A, [();32]> for B where A : Onion<Type=O>, B : Onion<Type=((((((((((((((((((((((((((((((((O,),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),)> {}
638
639pub trait NonZeroLen<O> {}
640
641impl<T,O> NonZeroLen<O> for T where T: LenExceeds<[();0],O> {}
642
643pub trait LenEq {
644    type Array;
645}
646
647impl<A,O,Array,Tuple> LenExceeds<A,[O;0]> for Tuple
648    where Tuple : LenEq<Array=Array>
649        , Array : LenExceeds<A,O>
650{
651}
652
653macro_rules! impl_tuplex {
654    ($($len:tt $htup:ident $htup_iter:ident => ($index0:tt $t0:ident $u0:ident ($($index:tt $t:ident $u:ident)*) $($last_index:tt $tn_1:ident $un_1:ident)*))*) => {$(
655        impl_len!(                    $len, $index0 $t0     $($index $t)*    $($last_index $tn_1)*       );
656        impl_len_eq!(                 $len, $index0 $t0     $($index $t)*    $($last_index $tn_1)*       );
657        impl_push_front!(                   $index0 $t0     $($index $t)*    $($last_index $tn_1)*       );
658        impl_push_back!(                    $index0 $t0     $($index $t)*    $($last_index $tn_1)*       );
659        impl_pop_front!(                                    $($index $t)*    $($last_index $tn_1)*       );
660        impl_pop_back!(                    ($index0 $t0     $($index $t)*)   $($last_index $tn_1)*       );
661        impl_tuple_into_homo_tuple!(  $len, $index0 $t0     $($index $t)*    $($last_index $tn_1)*       );
662        impl_array_from_tuple!(       $len, $index0 $t0     $($index $t)*    $($last_index $tn_1)*       );
663        impl_tuple_into_array!(       $len, $index0 $t0     $($index $t)*    $($last_index $tn_1)*       );
664        impl_tuple_into_boxed_slice!( $len, $index0 $t0     $($index $t)*    $($last_index $tn_1)*       );
665        impl_tuple_into_vec!(         $len, $index0 $t0     $($index $t)*    $($last_index $tn_1)*       );
666        impl_bin_tuple!(                                           $($t)*                $($tn_1)*       );
667        impl_tuple_of!(                             $t0            $($t)*                $($tn_1)*       );
668        impl_convert_tuple!(                $index0 $t0 $u0 $($index $t $u)* $($last_index $tn_1 $un_1)* );
669        impl_tuple_from_tuple!(             $index0 $t0 $u0 $($index $t $u)* $($last_index $tn_1 $un_1)* );
670        impl_map_homo_tuple!(         $len, $index0         $($index   )*    $($last_index)*             );
671        impl_homo!(  $htup $htup_iter $len, $index0         $($index)*       $($last_index)*             );
672    )*};
673}
674
675impl_tuplex! {
676     2 HTup2  HTupIter2  => (0 T0 U0()1 T1 U1)
677     3 HTup3  HTupIter3  => (0 T0 U0 (1 T1 U1)2 T2 U2)
678     4 HTup4  HTupIter4  => (0 T0 U0 (1 T1 U1 2 T2 U2)3 T3 U3)
679     5 HTup5  HTupIter5  => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3)4 T4 U4)
680     6 HTup6  HTupIter6  => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4)5 T5 U5)
681     7 HTup7  HTupIter7  => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5)6 T6 U6)
682     8 HTup8  HTupIter8  => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6)7 T7 U7)
683     9 HTup9  HTupIter9  => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7)8 T8 U8)
684    10 HTup10 HTupIter10 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8)9 T9 U9)
685    11 HTup11 HTupIter11 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9)10 T10 U10)
686    12 HTup12 HTupIter12 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10)11 T11 U11)
687    13 HTup13 HTupIter13 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11)12 T12 U12)
688    14 HTup14 HTupIter14 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12)13 T13 U13)
689    15 HTup15 HTupIter15 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13)14 T14 U14)
690    16 HTup16 HTupIter16 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13 14 T14 U14)15 T15 U15)
691    17 HTup17 HTupIter17 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13 14 T14 U14 15 T15 U15)16 T16 U16)
692    18 HTup18 HTupIter18 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13 14 T14 U14 15 T15 U15 16 T16 U16)17 T17 U17)
693    19 HTup19 HTupIter19 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13 14 T14 U14 15 T15 U15 16 T16 U16 17 T17 U17)18 T18 U18)
694    20 HTup20 HTupIter20 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13 14 T14 U14 15 T15 U15 16 T16 U16 17 T17 U17 18 T18 U18)19 T19 U19)
695    21 HTup21 HTupIter21 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13 14 T14 U14 15 T15 U15 16 T16 U16 17 T17 U17 18 T18 U18 19 T19 U19)20 T20 U20)
696    22 HTup22 HTupIter22 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13 14 T14 U14 15 T15 U15 16 T16 U16 17 T17 U17 18 T18 U18 19 T19 U19 20 T20 U20)21 T21 U21)
697    23 HTup23 HTupIter23 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13 14 T14 U14 15 T15 U15 16 T16 U16 17 T17 U17 18 T18 U18 19 T19 U19 20 T20 U20 21 T21 U21)22 T22 U22)
698    24 HTup24 HTupIter24 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13 14 T14 U14 15 T15 U15 16 T16 U16 17 T17 U17 18 T18 U18 19 T19 U19 20 T20 U20 21 T21 U21 22 T22 U22)23 T23 U23)
699    25 HTup25 HTupIter25 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13 14 T14 U14 15 T15 U15 16 T16 U16 17 T17 U17 18 T18 U18 19 T19 U19 20 T20 U20 21 T21 U21 22 T22 U22 23 T23 U23)24 T24 U24)
700    26 HTup26 HTupIter26 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13 14 T14 U14 15 T15 U15 16 T16 U16 17 T17 U17 18 T18 U18 19 T19 U19 20 T20 U20 21 T21 U21 22 T22 U22 23 T23 U23 24 T24 U24)25 T25 U25)
701    27 HTup27 HTupIter27 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13 14 T14 U14 15 T15 U15 16 T16 U16 17 T17 U17 18 T18 U18 19 T19 U19 20 T20 U20 21 T21 U21 22 T22 U22 23 T23 U23 24 T24 U24 25 T25 U25)26 T26 U26)
702    28 HTup28 HTupIter28 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13 14 T14 U14 15 T15 U15 16 T16 U16 17 T17 U17 18 T18 U18 19 T19 U19 20 T20 U20 21 T21 U21 22 T22 U22 23 T23 U23 24 T24 U24 25 T25 U25 26 T26 U26)27 T27 U27)
703    29 HTup29 HTupIter29 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13 14 T14 U14 15 T15 U15 16 T16 U16 17 T17 U17 18 T18 U18 19 T19 U19 20 T20 U20 21 T21 U21 22 T22 U22 23 T23 U23 24 T24 U24 25 T25 U25 26 T26 U26 27 T27 U27)28 T28 U28)
704    30 HTup30 HTupIter30 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13 14 T14 U14 15 T15 U15 16 T16 U16 17 T17 U17 18 T18 U18 19 T19 U19 20 T20 U20 21 T21 U21 22 T22 U22 23 T23 U23 24 T24 U24 25 T25 U25 26 T26 U26 27 T27 U27 28 T28 U28)29 T29 U29)
705    31 HTup31 HTupIter31 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13 14 T14 U14 15 T15 U15 16 T16 U16 17 T17 U17 18 T18 U18 19 T19 U19 20 T20 U20 21 T21 U21 22 T22 U22 23 T23 U23 24 T24 U24 25 T25 U25 26 T26 U26 27 T27 U27 28 T28 U28 29 T29 U29)30 T30 U30)
706    32 HTup32 HTupIter32 => (0 T0 U0 (1 T1 U1 2 T2 U2 3 T3 U3 4 T4 U4 5 T5 U5 6 T6 U6 7 T7 U7 8 T8 U8 9 T9 U9 10 T10 U10 11 T11 U11 12 T12 U12 13 T13 U13 14 T14 U14 15 T15 U15 16 T16 U16 17 T17 U17 18 T18 U18 19 T19 U19 20 T20 U20 21 T21 U21 22 T22 U22 23 T23 U23 24 T24 U24 25 T25 U25 26 T26 U26 27 T27 U27 28 T28 U28 29 T29 U29 30 T30 U30)31 T31 U31)
707}
708
709#[cfg( test )]
710mod tests {
711    use super::*;
712
713    #[test]
714    fn len_works() {
715        assert_eq!( ()                 .len(), 0 );
716        assert_eq!( ("0",)             .len(), 1 );
717        assert_eq!( ("0",1)            .len(), 2 );
718        assert_eq!( ("0",1,"2")        .len(), 3 );
719        assert_eq!( ("0",1,"2",3)      .len(), 4 );
720        assert_eq!( ("0",1,"2",3,"4")  .len(), 5 );
721        assert_eq!( ("0",1,"2",3,"4",5).len(), 6 );
722    }
723
724    #[test]
725    fn push_front_works() {
726        assert_eq!( ()                 .push_front("0"), ("0",) );
727        assert_eq!( (1,)               .push_front("0"), ("0",1) );
728        assert_eq!( (1,"2")            .push_front("0"), ("0",1,"2") );
729        assert_eq!( (1,"2",3)          .push_front("0"), ("0",1,"2",3) );
730        assert_eq!( (1,"2",3,"4")      .push_front("0"), ("0",1,"2",3,"4") );
731        assert_eq!( (1,"2",3,"4",5)    .push_front("0"), ("0",1,"2",3,"4",5) );
732        assert_eq!( (1,"2",3,"4",5,"6").push_front("0"), ("0",1,"2",3,"4",5,"6") );
733    }
734
735    #[test]
736    fn push_back_works() {
737        assert_eq!( ()                 .push_back("0"), ("0",) );
738        assert_eq!( ("0",)             .push_back(1)  , ("0",1) );
739        assert_eq!( ("0",1,)           .push_back("2"), ("0",1,"2") );
740        assert_eq!( ("0",1,"2")        .push_back(3)  , ("0",1,"2",3) );
741        assert_eq!( ("0",1,"2",3)      .push_back("4"), ("0",1,"2",3,"4") );
742        assert_eq!( ("0",1,"2",3,"4")  .push_back(5)  , ("0",1,"2",3,"4",5) );
743        assert_eq!( ("0",1,"2",3,"4",5).push_back("6"), ("0",1,"2",3,"4",5,"6") );
744    }
745
746    #[test]
747    fn pop_front_works() {
748        assert_eq!( ("0",)             .pop_front(), ("0",()) );
749        assert_eq!( ("0",1)            .pop_front(), ("0",(1,)) );
750        assert_eq!( ("0",1,"2")        .pop_front(), ("0",(1,"2")) );
751        assert_eq!( ("0",1,"2",3)      .pop_front(), ("0",(1,"2",3)) );
752        assert_eq!( ("0",1,"2",3,"4")  .pop_front(), ("0",(1,"2",3,"4")) );
753        assert_eq!( ("0",1,"2",3,"4",5).pop_front(), ("0",(1,"2",3,"4",5)) );
754    }
755
756    #[test]
757    fn pop_back_works() {
758        assert_eq!( ("0",)             .pop_back(), ("0",()) );
759        assert_eq!( ("0",1)            .pop_back(), (1  ,("0",)) );
760        assert_eq!( ("0",1,"2")        .pop_back(), ("2",("0",1)) );
761        assert_eq!( ("0",1,"2",3)      .pop_back(), (3  ,("0",1,"2")) );
762        assert_eq!( ("0",1,"2",3,"4")  .pop_back(), ("4",("0",1,"2",3)) );
763        assert_eq!( ("0",1,"2",3,"4",5).pop_back(), (5  ,("0",1,"2",3,"4")) );
764    }
765
766    #[test]
767    fn bin_tuple_works() {
768        struct Test<T:BinTuple>( T, <T as BinTuple>::LeftAssociated, <T as BinTuple>::RightAssociated );
769        Test( (),            (),                         ()                         );
770        Test( (0,),          ((),0),                     (0,())                     );
771        Test( (0,1),         (((),0),1),                 (0,(1,()))                 );
772        Test( (0,1,2),       ((((),0),1),2),             (0,(1,(2,())))             );
773        Test( (0,1,2,3),     (((((),0),1),2),3),         (0,(1,(2,(3,()))))         );
774        Test( (0,1,2,3,4),   ((((((),0),1),2),3),4),     (0,(1,(2,(3,(4,())))))     );
775        Test( (0,1,2,3,4,5), (((((((),0),1),2),3),4),5), (0,(1,(2,(3,(4,(5,())))))) );
776    }
777
778    #[derive( Debug, PartialEq, Eq )]
779    struct I32( i32 );
780
781    impl From<i32> for I32 { fn from( i: i32 ) -> I32 { I32(i) }}
782
783    impl Convert for I32 {
784        type Output = i32;
785        fn convert( self ) -> i32 { self.0 }
786    }
787
788    impl Convert for i32 {
789        type Output = i32;
790        fn convert( self ) -> i32 { self }
791    }
792
793    struct Integer;
794
795    impl ValueOf<Integer> for I32 {}
796    impl ValueOf<Integer> for i32 {}
797
798    #[test]
799    fn tuple_from_tuple_works() {
800        use crate::homo_tuple;
801        assert_eq!( <homo_tuple!(I32;0)>::from_tuple( ()                           ), ()                                                 );
802        assert_eq!( <homo_tuple!(I32;1)>::from_tuple( (I32(0),)                    ), ( I32(0),)                                         );
803        assert_eq!( <homo_tuple!(I32;2)>::from_tuple( (I32(0),1)                   ), ( I32(0), I32(1), )                                );
804        assert_eq!( <homo_tuple!(I32;3)>::from_tuple( (I32(0),1,I32(2))            ), ( I32(0), I32(1), I32(2), )                        );
805        assert_eq!( <homo_tuple!(I32;4)>::from_tuple( (I32(0),1,I32(2),3)          ), ( I32(0), I32(1), I32(2), I32(3) )                 );
806        assert_eq!( <homo_tuple!(I32;5)>::from_tuple( (I32(0),1,I32(2),3,I32(4))   ), ( I32(0), I32(1), I32(2), I32(3), I32(4) )         );
807        assert_eq!( <homo_tuple!(I32;6)>::from_tuple( (I32(0),1,I32(2),3,I32(4),5) ), ( I32(0), I32(1), I32(2), I32(3), I32(4), I32(5) ) );
808    }
809
810    #[test]
811    fn tuple_into_tuple_works() {
812        use crate::{homo_tuple,IntoTuple};
813        assert_eq!( IntoTuple::<homo_tuple!(I32;0)>::into_tuple( ()                           ), ()                                                 );
814        assert_eq!( IntoTuple::<homo_tuple!(I32;1)>::into_tuple( (I32(0),)                    ), ( I32(0),)                                         );
815        assert_eq!( IntoTuple::<homo_tuple!(I32;2)>::into_tuple( (I32(0),1)                   ), ( I32(0), I32(1), )                                );
816        assert_eq!( IntoTuple::<homo_tuple!(I32;3)>::into_tuple( (I32(0),1,I32(2))            ), ( I32(0), I32(1), I32(2), )                        );
817        assert_eq!( IntoTuple::<homo_tuple!(I32;4)>::into_tuple( (I32(0),1,I32(2),3)          ), ( I32(0), I32(1), I32(2), I32(3) )                 );
818        assert_eq!( IntoTuple::<homo_tuple!(I32;5)>::into_tuple( (I32(0),1,I32(2),3,I32(4))   ), ( I32(0), I32(1), I32(2), I32(3), I32(4) )         );
819        assert_eq!( IntoTuple::<homo_tuple!(I32;6)>::into_tuple( (I32(0),1,I32(2),3,I32(4),5) ), ( I32(0), I32(1), I32(2), I32(3), I32(4), I32(5) ) );
820    }
821
822    #[test]
823    fn tuple_into_homo_tuple_works() {
824        use crate::IntoHomoTuple;
825        assert_eq!( IntoHomoTuple::<I32>::into_homo_tuple( ()                           ), ()                                                 );
826        assert_eq!( IntoHomoTuple::<I32>::into_homo_tuple( (I32(0),)                    ), ( I32(0),)                                         );
827        assert_eq!( IntoHomoTuple::<I32>::into_homo_tuple( (I32(0),1)                   ), ( I32(0), I32(1), )                                );
828        assert_eq!( IntoHomoTuple::<I32>::into_homo_tuple( (I32(0),1,I32(2))            ), ( I32(0), I32(1), I32(2), )                        );
829        assert_eq!( IntoHomoTuple::<I32>::into_homo_tuple( (I32(0),1,I32(2),3)          ), ( I32(0), I32(1), I32(2), I32(3) )                 );
830        assert_eq!( IntoHomoTuple::<I32>::into_homo_tuple( (I32(0),1,I32(2),3,I32(4))   ), ( I32(0), I32(1), I32(2), I32(3), I32(4) )         );
831        assert_eq!( IntoHomoTuple::<I32>::into_homo_tuple( (I32(0),1,I32(2),3,I32(4),5) ), ( I32(0), I32(1), I32(2), I32(3), I32(4), I32(5) ) );
832    }
833
834    #[test]
835    fn array_from_tuple_works() {
836        assert_eq!( <[I32;0]>::from_tuple( ()                           ), []                                                 );
837        assert_eq!( <[I32;1]>::from_tuple( (I32(0),)                    ), [ I32(0) ]                                         );
838        assert_eq!( <[I32;2]>::from_tuple( (I32(0),1)                   ), [ I32(0), I32(1), ]                                );
839        assert_eq!( <[I32;3]>::from_tuple( (I32(0),1,I32(2))            ), [ I32(0), I32(1), I32(2), ]                        );
840        assert_eq!( <[I32;4]>::from_tuple( (I32(0),1,I32(2),3)          ), [ I32(0), I32(1), I32(2), I32(3) ]                 );
841        assert_eq!( <[I32;5]>::from_tuple( (I32(0),1,I32(2),3,I32(4))   ), [ I32(0), I32(1), I32(2), I32(3), I32(4) ]         );
842        assert_eq!( <[I32;6]>::from_tuple( (I32(0),1,I32(2),3,I32(4),5) ), [ I32(0), I32(1), I32(2), I32(3), I32(4), I32(5) ] );
843    }
844
845    #[test]
846    fn tuple_into_array_works() {
847        assert_eq!( IntoArray::<I32>::into_array( ()                           ), []                                                 );
848        assert_eq!( IntoArray::<I32>::into_array( (I32(0),)                    ), [ I32(0) ]                                         );
849        assert_eq!( IntoArray::<I32>::into_array( (I32(0),1)                   ), [ I32(0), I32(1), ]                                );
850        assert_eq!( IntoArray::<I32>::into_array( (I32(0),1,I32(2))            ), [ I32(0), I32(1), I32(2), ]                        );
851        assert_eq!( IntoArray::<I32>::into_array( (I32(0),1,I32(2),3)          ), [ I32(0), I32(1), I32(2), I32(3) ]                 );
852        assert_eq!( IntoArray::<I32>::into_array( (I32(0),1,I32(2),3,I32(4))   ), [ I32(0), I32(1), I32(2), I32(3), I32(4) ]         );
853        assert_eq!( IntoArray::<I32>::into_array( (I32(0),1,I32(2),3,I32(4),5) ), [ I32(0), I32(1), I32(2), I32(3), I32(4), I32(5) ] );
854    }
855
856    #[test]
857    fn tuple_into_boxed_slice_works() {
858        assert_eq!( IntoBoxedSlice::<I32>::into_boxed_slice( () )                          , vec![                                                ].into_boxed_slice() );
859        assert_eq!( IntoBoxedSlice::<I32>::into_boxed_slice( (I32(0), ))                   , vec![ I32(0)                                         ].into_boxed_slice() );
860        assert_eq!( IntoBoxedSlice::<I32>::into_boxed_slice( (I32(0),1 ))                  , vec![ I32(0), I32(1),                                ].into_boxed_slice() );
861        assert_eq!( IntoBoxedSlice::<I32>::into_boxed_slice( (I32(0),1,I32(2) ))           , vec![ I32(0), I32(1), I32(2),                        ].into_boxed_slice() );
862        assert_eq!( IntoBoxedSlice::<I32>::into_boxed_slice( (I32(0),1,I32(2),3 ))         , vec![ I32(0), I32(1), I32(2), I32(3)                 ].into_boxed_slice() );
863        assert_eq!( IntoBoxedSlice::<I32>::into_boxed_slice( (I32(0),1,I32(2),3,I32(4) ))  , vec![ I32(0), I32(1), I32(2), I32(3), I32(4)         ].into_boxed_slice() );
864        assert_eq!( IntoBoxedSlice::<I32>::into_boxed_slice( (I32(0),1,I32(2),3,I32(4),5 )), vec![ I32(0), I32(1), I32(2), I32(3), I32(4), I32(5) ].into_boxed_slice() );
865    }
866
867    #[test]
868    fn tuple_of_works() {
869        struct Test<Tup:TupleOf<Integer>>( Tup );
870        Test( (I32(0),)                          );
871        Test( (I32(0), 1, )                      );
872        Test( (I32(0), 1, I32(2), )              );
873        Test( (I32(0), 1, I32(2), 3 )            );
874        Test( (I32(0), 1, I32(2), 3, I32(4) )    );
875        Test( (I32(0), 1, I32(2), 3, I32(4), 5 ) );
876    }
877
878    #[test]
879    fn convert_tuple_works() {
880        assert_eq!( ()                          .convert_tuple(), ()                   );
881        assert_eq!( (I32(0),)                   .convert_tuple(), ( 0,)                );
882        assert_eq!( (I32(0),1)                  .convert_tuple(), ( 0, 1, )            );
883        assert_eq!( (I32(0),1,I32(2))           .convert_tuple(), ( 0, 1, 2, )         );
884        assert_eq!( (I32(0),1,I32(2),3)         .convert_tuple(), ( 0, 1, 2, 3 )       );
885        assert_eq!( (I32(0),1,I32(2),3,I32(4))  .convert_tuple(), ( 0, 1, 2, 3, 4 )    );
886        assert_eq!( (I32(0),1,I32(2),3,I32(4),5).convert_tuple(), ( 0, 1, 2, 3, 4, 5 ) );
887    }
888
889    #[test]
890    fn homo_into_iter_works() {
891        let tuple = (1, 1, 2, 3, 5, 8, 13, 21);
892        let iter = tuple.wrap_into_iter();
893        assert_eq!( iter.collect::<Vec<_>>(), vec![ 1, 1, 2, 3, 5, 8, 13, 21 ]);
894    }
895
896    #[test]
897    fn len_exceeds() {
898        fn exceeds<More, Less, Tag>() where More: LenExceeds<Less,Tag> {}
899
900        macro_rules! exceeds {
901            ($($more:tt $less:tt,)*) => {$(
902                exceeds::<[();$more], [();$less], _>();
903            )*};
904        }
905
906        exceeds!{
907            1 0, 2 0, 3 0, 4 0, 5 0, 6 0, 7 0, 8 0, 9 0, 10 0, 11  0, 12  0, 13  0, 14  0, 15  0, 16  0, 17  0, 18  0, 19  0, 20  0, 21  0, 22  0, 23  0, 24  0, 25  0, 26  0, 27  0, 28  0, 29  0, 30  0, 31  0, 32  0,
908                 2 1, 3 1, 4 1, 5 1, 6 1, 7 1, 8 1, 9 1, 10 1, 11  1, 12  1, 13  1, 14  1, 15  1, 16  1, 17  1, 18  1, 19  1, 20  1, 21  1, 22  1, 23  1, 24  1, 25  1, 26  1, 27  1, 28  1, 29  1, 30  1, 31  1, 32  1,
909                      3 2, 4 2, 5 2, 6 2, 7 2, 8 2, 9 2, 10 2, 11  2, 12  2, 13  2, 14  2, 15  2, 16  2, 17  2, 18  2, 19  2, 20  2, 21  2, 22  2, 23  2, 24  2, 25  2, 26  2, 27  2, 28  2, 29  2, 30  2, 31  2, 32  2,
910                           4 3, 5 3, 6 3, 7 3, 8 3, 9 3, 10 3, 11  3, 13  3, 13  3, 14  3, 15  3, 16  3, 17  3, 18  3, 19  3, 20  3, 21  3, 22  3, 23  3, 24  3, 25  3, 26  3, 27  3, 28  3, 29  3, 30  3, 31  3, 32  3,
911                                5 4, 6 4, 7 4, 8 4, 9 4, 10 4, 11  4, 13  4, 13  4, 14  4, 15  4, 16  4, 17  4, 18  4, 19  4, 20  4, 21  4, 22  4, 23  4, 24  4, 25  4, 26  4, 27  4, 28  4, 29  4, 30  4, 31  4, 32  4,
912                                     6 5, 7 5, 8 5, 9 5, 10 5, 11  5, 13  5, 13  5, 14  5, 15  5, 16  5, 17  5, 18  5, 19  5, 20  5, 21  5, 22  5, 23  5, 24  5, 25  5, 26  5, 27  5, 28  5, 29  5, 30  5, 31  5, 32  5,
913                                          7 6, 8 6, 9 6, 10 6, 11  6, 13  6, 13  6, 14  6, 15  6, 16  6, 17  6, 18  6, 19  6, 20  6, 21  6, 22  6, 23  6, 24  6, 25  6, 26  6, 27  6, 28  6, 29  6, 30  6, 31  6, 32  6,
914                                               8 7, 9 7, 10 7, 11  7, 13  7, 13  7, 14  7, 15  7, 16  7, 17  7, 18  7, 19  7, 20  7, 21  7, 22  7, 23  7, 24  7, 25  7, 26  7, 27  7, 28  7, 29  7, 30  7, 31  7, 32  7,
915                                                    9 8, 10 8, 11  8, 13  8, 13  8, 14  8, 15  8, 16  8, 17  8, 18  8, 19  8, 20  8, 21  8, 22  8, 23  8, 24  8, 25  8, 26  8, 27  8, 28  8, 29  8, 30  8, 31  8, 32  8,
916                                                         10 9, 11  9, 13  9, 13  9, 14  9, 15  9, 16  9, 17  9, 18  9, 19  9, 20  9, 21  9, 22  9, 23  9, 24  9, 25  9, 26  9, 27  9, 28  9, 29  9, 30  9, 31  9, 32  9,
917                                                               11 10, 13 10, 13 10, 14 10, 15 10, 16 10, 17 10, 18 10, 19 10, 20 10, 21 10, 22 10, 23 10, 24 10, 25 10, 26 10, 27 10, 28 10, 29 10, 30 10, 31 10, 32 10,
918                                                                      13 11, 13 11, 14 11, 15 11, 16 11, 17 11, 18 11, 19 11, 20 11, 21 11, 22 11, 23 11, 24 11, 25 11, 26 11, 27 11, 28 11, 29 11, 30 11, 31 11, 32 11,
919                                                                             13 12, 14 12, 15 12, 16 12, 17 12, 18 12, 19 12, 20 12, 21 12, 22 12, 23 12, 24 12, 25 12, 26 12, 27 12, 28 12, 29 12, 30 12, 31 12, 32 12,
920                                                                                    14 13, 15 13, 16 13, 17 13, 18 13, 19 13, 20 13, 21 13, 22 13, 23 13, 24 13, 25 13, 26 13, 27 13, 28 13, 29 13, 30 13, 31 13, 32 13,
921                                                                                           15 14, 16 14, 17 14, 18 14, 19 14, 20 14, 21 14, 22 14, 23 14, 24 14, 25 14, 26 14, 27 14, 28 14, 29 14, 30 14, 31 14, 32 14,
922                                                                                                  16 15, 17 15, 18 15, 19 15, 20 15, 21 15, 22 15, 23 15, 24 15, 25 15, 26 15, 27 15, 28 15, 29 15, 30 15, 31 15, 32 15,
923                                                                                                         17 16, 18 16, 19 16, 20 16, 21 16, 22 16, 23 16, 24 16, 25 16, 26 16, 27 16, 28 16, 29 16, 30 16, 31 16, 32 16,
924                                                                                                                18 17, 19 17, 20 17, 21 17, 22 17, 23 17, 24 17, 25 17, 26 17, 27 17, 28 17, 29 17, 30 17, 31 17, 32 17,
925                                                                                                                       19 18, 20 18, 21 18, 22 18, 23 18, 24 18, 25 18, 26 18, 27 18, 28 18, 29 18, 30 18, 31 18, 32 18,
926                                                                                                                              20 19, 21 19, 22 19, 23 19, 24 19, 25 19, 26 19, 27 19, 28 19, 29 19, 30 19, 31 19, 32 19,
927                                                                                                                                     21 20, 22 20, 23 20, 24 20, 25 20, 26 20, 27 20, 28 20, 29 20, 30 20, 31 20, 32 20,
928                                                                                                                                            22 21, 23 21, 24 21, 25 21, 26 21, 27 21, 28 21, 29 21, 30 21, 31 21, 32 21,
929                                                                                                                                                   23 22, 24 22, 25 22, 26 22, 27 22, 28 22, 29 22, 30 22, 31 22, 32 22,
930                                                                                                                                                          24 23, 25 23, 26 23, 27 23, 28 23, 29 23, 30 23, 31 23, 32 23,
931                                                                                                                                                                 25 24, 26 24, 27 24, 28 24, 29 24, 30 24, 31 24, 32 24,
932                                                                                                                                                                        26 25, 27 25, 28 25, 29 25, 30 25, 31 25, 32 25,
933                                                                                                                                                                               27 26, 28 26, 29 26, 30 26, 31 26, 32 26,
934                                                                                                                                                                                      28 27, 29 27, 30 27, 31 27, 32 27,
935                                                                                                                                                                                             29 28, 30 28, 31 28, 32 28,
936                                                                                                                                                                                                    30 29, 31 29, 32 29,
937                                                                                                                                                                                                           31 30, 32 30,
938                                                                                                                                                                                                                  32 31,
939        }
940    }
941}