tuplez/
tuple.rs

1#[cfg(feature = "uninit")]
2use crate::uninit::*;
3#[cfg(feature = "unwrap")]
4use crate::unwrap::*;
5use crate::{fold::Foldable, foreach::Foreach, macros::*, ops::*, predicate::*, search::*};
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8#[cfg(feature = "uninit")]
9use std::mem::MaybeUninit;
10use std::{
11    ops::{
12        Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div,
13        DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
14        SubAssign,
15    },
16    pin::Pin,
17};
18use tuplez_macros::tuple_traits_impl;
19
20/// The unit type that represents tuples of zero elements.
21///
22/// Compared with [`Tuple`] type, the unit type does not implement the [`Poppable`] trait.
23///
24/// Suggestion: Use the parameterless [`tuple!`](crate::tuple!) macro to create a unit:
25///
26/// ```
27/// use tuplez::tuple;
28/// let unit = tuple!();
29/// ```
30#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
31#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
32pub struct Unit;
33
34/// The type used to represent tuples containing at least one element.
35///
36/// See [`Unit`] type which represents tuples containing no elements.
37///
38/// The [`TupleLike`] trait defines the basic methods of all [`Tuple`] types and [`Unit`] type.
39/// Check out [`TupleLike`]'s documentation page to see exactly what APIs are available.
40///
41/// # Build a tuple
42///
43/// You can create a tuple quickly and easily using the [`tuple!`](crate::tuple!) macro:
44///
45/// ```
46/// use tuplez::tuple;
47/// let tup = tuple!(1, "hello", 3.14);
48/// ```
49///
50/// Use `;` to indicate repeated elements:
51///
52/// ```
53/// use tuplez::tuple;
54/// assert_eq!(tuple!(1.0, 2;3, "3"), tuple!(1.0, 2, 2, 2, "3"));
55/// ```
56///
57/// Remember that macros do not directly evaluate expressions, so:
58///
59/// ```
60/// use tuplez::tuple;
61///
62/// let mut x = 0;
63/// assert_eq!(tuple!({x += 1; x}; 3), tuple!(1, 2, 3));
64/// ```
65///
66/// # Representation
67///
68/// Unlike [primitive tuple types](https://doc.rust-lang.org/std/primitive.tuple.html),
69/// [`Tuple`] uses a recursive form of representation:
70///
71/// ```text
72/// Primitive tuple representation:
73///     (T0, T1, T2, T3)
74/// `Tuple` representation:
75///     Tuple<T0, Tuple<T1, Tuple<T2, Tuple<T3, Unit>>>>
76/// ```
77///
78/// ... but don’t worry, in almost all cases [`Tuple`] will not take up more memory:
79///
80/// ```
81/// use std::mem::size_of;
82/// use tuplez::{Tuple, Unit};
83///
84/// assert_eq!(size_of::<(i32, f64, &str)>(),
85///     size_of::<Tuple<i32, Tuple<f64, Tuple<&str, Unit>>>>());
86/// ```
87///
88/// The advantage of using the recursive form of representation is that we can implement
89/// a variety of methods on tuples of any length, instead of only implementing these methods
90/// on tuples of length less than 12 (or 32).
91///
92/// **As a shorthand, we use `Tuple<T0, T1, ... Tn>` to represent a [`Tuple`] type containing `N+1` elements**
93/// **in the following text, please keep in mind that this is not a true [`Tuple`] representation.**
94///
95/// A [`Tuple`] can also be used as one of the elements of another [`Tuple`], without restriction.
96///
97/// # Explicit tuple types
98///
99/// In most cases, `Tuple` or `Tuple<_, _>` is sufficient to meet the syntax requirements:
100///
101/// ```
102/// # #![cfg_attr(feature = "any_array", feature(generic_const_exprs))]
103///
104/// use tuplez::Tuple;
105///
106/// let tup = Tuple::from((1, "hello", 3.14)); // or
107/// let tup: Tuple<_, _> = From::from((1, "hello", 3.14));
108/// ```
109///
110/// But sometimes, you may still need to annotate the complete tuple type explicitly.
111/// At this point, you can use the [`tuple_t!`](crate::tuple_t) macro to generate it:
112///
113/// ```
114/// use tuplez::{tuple, tuple_t};
115///
116/// let tup: tuple_t!(i32, String, f64) = Default::default();
117/// assert_eq!(tup, tuple!(0, String::new(), 0.0));
118///
119/// let unit: tuple_t!() = Default::default();
120/// assert_eq!(unit, tuple!());
121///
122/// fn use_tuple(tup: tuple_t!(i32, &dyn std::fmt::Debug, tuple_t!(String, String))) {
123///     todo!()
124/// }
125/// ```
126///
127/// Use `;` to indicate repeated types:
128///
129/// ```
130/// use tuplez::{tuple, tuple_t};
131///
132/// let tup: tuple_t!(i32, f64;3, i32) = tuple!(1, 2.0, 3.0, 4.0, 5);
133/// ```
134///
135/// Sometimes, you may want to know the exact type of a tuple variable, so that you can call an associated method
136/// of this tuple type, such as, [`Default::default()`]. However, the signature of this type can be very long
137/// and complex, and you may not want to write it out completely via [`tuple_t!`](crate::tuple_t!).
138///
139/// Here's a little trick that might help:
140///
141/// ```
142/// use tuplez::tuple;
143///
144/// fn default_by<T: Default>(_: &T) -> T {
145///     T::default()
146/// }
147///
148/// let tup = tuple!([1, 2, 3], tuple!("hello".to_string(), 3.14), 8);
149/// let tup2 = default_by(&tup);
150/// assert_eq!(tup2, tuple!([0; 3], tuple!(String::new(), 0.0), 0));
151/// ```
152///
153/// # Element access
154///
155/// There is a [`get!`](crate::get) macro that can be used to get elements,
156/// the only restriction is that the index must be an integer literal:
157///
158/// ```
159/// use tuplez::{get, tuple};
160///
161/// let tup = tuple!(1, "hello", 3.14);
162/// assert_eq!(get!(tup; 0), 1);
163/// assert_eq!(get!(tup; 1), "hello");
164/// assert_eq!(get!(tup; 2), 3.14);
165/// ```
166///
167/// This macro will be expanded to standard member access syntax:
168///
169/// ```text
170/// get!(tup; 0) => tup.0
171/// get!(tup; 1) => tup.1.0
172/// get!(tup; 2) => tup.1.1.0
173/// ```
174///
175/// ... so, here's an example of modifying elements:
176///
177/// ```
178/// use tuplez::{get, tuple};
179///
180/// fn add_one(x: &mut i32) { *x += 1; }
181///
182/// let mut tup = tuple!(1, "hello", 3.14);
183/// add_one(&mut get!(tup; 0));
184/// assert_eq!(tup, tuple!(2, "hello", 3.14));
185/// ```
186///
187/// # Push, pop, join and split
188///
189/// Any tuple can push further elements, or join another one, with no length limit.
190///
191/// ```
192/// use tuplez::{tuple, TupleLike};
193///
194/// let tup = tuple!();
195///
196/// let tup2 = tup.push(1);             // Push element to back
197/// assert_eq!(tup2, tuple!(1));
198///
199/// let tup3 = tup2.push_back("hello"); // Same as `push`, push element to back
200/// assert_eq!(tup3, tuple!(1, "hello"));
201///
202/// let tup4 = tup3.push_front(3.14);   // Push element to front
203/// assert_eq!(tup4, tuple!(3.14, 1, "hello"));
204///
205/// let tup5 = tup3.join(tup4);         // Join two tuples
206/// assert_eq!(tup5, tuple!(1, "hello", 3.14, 1, "hello"));
207/// ```
208///
209/// [`Unit`]s are not [`Poppable`], and all [`Tuple`]s are [`Poppable`]:
210///
211/// ```
212/// use tuplez::{tuple, TupleLike};
213///
214/// let tup = tuple!(1, "hello", 3.14, [1, 2, 3]);
215///
216/// let (tup2, arr) = tup.pop();        // Pop element from back
217/// assert_eq!(tup2, tuple!(1, "hello", 3.14));
218/// assert_eq!(arr, [1, 2, 3]);
219///
220/// let (tup3, pi) = tup2.pop_back();   // Same as `pop`, pop element from back
221/// assert_eq!(tup3, tuple!(1, "hello"));
222/// assert_eq!(pi, 3.14);
223///
224/// let (tup4, num) = tup3.pop_front();  // Pop element from front
225/// assert_eq!(tup4, tuple!("hello"));
226/// assert_eq!(num, 1);
227///
228/// let (unit, hello) = tup4.pop();
229/// assert_eq!(unit, tuple!());
230/// assert_eq!(hello, "hello");
231///
232/// // _ = unit.pop()                   // Error: cannot pop a `Unit`
233/// ```
234///
235/// The [`take!`](crate::take!) macro can take out an element by its index or type:
236///
237/// ```
238/// use tuplez::{take, tuple};
239///
240/// let tup = tuple!(1, "hello", 3.14, [1, 2, 3]);
241///
242/// let (element, remainder) = take!(tup; 2);
243/// assert_eq!(element, 3.14);
244/// assert_eq!(remainder, tuple!(1, "hello", [1, 2, 3]));
245///
246/// let (element, remainder) = take!(tup; &str);
247/// assert_eq!(element, "hello");
248/// assert_eq!(remainder, tuple!(1, 3.14, [1, 2, 3]));
249/// ```
250///
251/// You can use the [`split_at!`](crate::split_at) macro to split a tuple into two parts.
252/// Like the [`get!`](crate::get) macro, the index must be an integer literal:
253///
254/// ```
255/// use tuplez::{split_at, tuple};
256///
257/// let tup = tuple!(1, "hello", 3.14, [1, 2, 3]);
258///
259/// let (left, right) = split_at!(tup; 2);
260/// assert_eq!(left, tuple!(1, "hello"));
261/// assert_eq!(right, tuple!(3.14, [1, 2, 3]));
262///
263/// let (left, right) = split_at!(tup; 0);
264/// assert_eq!(left, tuple!());
265/// assert_eq!(right, tup);
266///
267/// let (left, right) = split_at!(tup; 4);
268/// assert_eq!(left, tup);
269/// assert_eq!(right, tuple!());
270/// ```
271///
272/// # Get subsequences
273///
274/// You can get a subsequence of a tuple via the [`subseq()`](TupleLike::subseq()) method:
275///
276/// ```
277/// use tuplez::{tuple, TupleLike, tuple_t};
278///
279/// let tup = tuple!(12, "hello", 24, 3.14, true);
280/// let subseq: tuple_t!(&str, bool) = tup.subseq();
281/// assert_eq!(subseq, tuple!("hello", true));
282///
283/// // Two candidates available: `(12, true)` or `(24, true)`.
284/// // let subseq: tuple_t!(i32, bool) = tup.subseq();
285///
286/// // No candidates available.
287/// // `(true, "hello")` cannot be a candidate, since its element order is
288/// // different from the supersequence.
289/// // let subseq: tuple_t!(bool, &str) = tup.subseq();
290///
291/// // Although `24` is also `i32`, but only `(12, "hello")` is a candidate.
292/// let subseq: tuple_t!(i32, &str) = tup.subseq();
293/// assert_eq!(subseq, tuple!(12, "hello"));
294///
295/// // It's OK to pick all `i32`s since there is only one candidate.
296/// let subseq: tuple_t!(i32, i32) = tup.subseq();
297/// assert_eq!(subseq, tuple!(12, 24));
298/// ```
299///
300/// You can also get a continuous subsequence via the [`con_subseq()`](TupleLike::con_subseq()),
301/// it may do somethings that [`subseq()`](TupleLike::subseq) cannot do:
302///
303/// ```
304/// use tuplez::{tuple, TupleLike, tuple_t};
305///
306/// let tup = tuple!(12, "hello", 24, true, false);
307///
308/// // For `subseq`, 4 candidates available:
309/// //      `(12, true)`,
310/// //      `(12, false)`,
311/// //      `(24, true)`,
312/// //      `(24, false)`,
313/// // so this cannot be compiled.
314/// // let subseq: tuple_t!(i32, bool) = tup.subseq();
315///
316/// // But for `con_subseq`,only `(24, true)` is a candidate.
317/// let subseq: tuple_t!(i32, bool) = tup.con_subseq();
318/// assert_eq!(subseq, tuple!(24, true));
319/// ```
320///
321/// There are also many methods about subsequence: [`subseq_ref()`](TupleLike::subseq_ref()),
322/// [`subseq_mut()`](TupleLike::subseq_mut()), [`swap_subseq()`](TupleLike::swap_subseq()),
323/// [`replace_subseq()`](TupleLike::replace_subseq()), [`con_subseq_ref()`](TupleLike::con_subseq_ref()),
324/// [`con_subseq_mut()`](TupleLike::con_subseq_mut()), [`swap_con_subseq()`](TupleLike::swap_con_subseq()),
325/// [`replace_con_subseq()`](TupleLike::replace_con_subseq()).
326/// Please refer to their own documentation.
327///
328/// # Trait implementations on [`Tuple`]
329///
330/// For `Tuple<T0, T1, ... Tn>`, when all types `T0`, `T1`, ... `Tn` implement the [`Debug`] /
331/// [`Clone`] / [`Copy`] / [`PartialEq`] / [`Eq`] / [`PartialOrd`] / [`Ord`] / [`Hash`] / [`Default`] /
332/// [`Neg`] / [`Not`] trait(s), then the `Tuple<T0, T1, ... Tn>` also implements it/them.
333///
334/// For example:
335///
336/// ```
337/// use tuplez::tuple;
338///
339/// let tup = tuple!(false, true, 26u8);            // All elements implement `Not`
340/// assert_eq!(!tup, tuple!(true, false, 229u8));   // So `Tuple` also implements `Not`
341/// ```
342///
343/// For `Tuple<T0, T1, ... Tn>` and `Tuple<U0, U1, ... Un>`, when each `Ti` implements
344/// `Trait<Ui>` if the `Trait` is [`Add`] / [`AddAssign`] / [`Sub`] / [`SubAssign`] /
345/// [`Mul`] / [`MulAssign`] / [`Div`] / [`DivAssign`] / [`Rem`] / [`RemAssign`] /
346/// [`BitAnd`] / [`BitAndAssign`] / [`BitOr`] / [`BitOrAssign`] / [`BitXor`] / [`BitXorAssign`]
347/// / [`Shl`] / [`ShlAssign`] / [`Shr`] / [`ShrAssign`],
348/// then `Tuple<T0, T1, ... Tn>` also implements `Trait<Tuple<U0, U1, ... Un>>`.
349///
350/// For example:
351///
352/// ```
353/// use tuplez::tuple;
354///
355/// let tup1 = tuple!(5, "hello ".to_string());
356/// let tup2 = tuple!(4, "world");
357/// assert_eq!(tup1 + tup2, tuple!(9, "hello world".to_string()));
358/// ```
359///
360/// If the number of elements on both sides is not equal, then the excess will be retained as is:
361///
362/// ```
363/// use tuplez::tuple;
364///
365/// let x = tuple!(10, "hello".to_string(), 3.14, vec![1, 2]);
366/// let y = tuple!(5, " world");
367/// assert_eq!(x + y, tuple!(15, "hello world".to_string(), 3.14, vec![1, 2]));
368/// ```
369///
370/// # Traverse tuples
371///
372/// You can traverse tuples by [`foreach()`](TupleLike::foreach()).
373///
374/// Call [`foreach()`](TupleLike::foreach()) on a tuple requires a mapper implementing
375/// [`Mapper`](crate::foreach::Mapper) as the parameter. Check its documentation page for examples.
376///
377/// However, here are two ways you can quickly build a mapper.
378///
379/// ## Traverse tuples by element types
380///
381/// The [`mapper!`](crate::mapper!) macro helps you build a mapper that traverses tuples according to their element types.
382///
383/// For example:
384///
385/// ```
386/// use tuplez::{mapper, tuple, TupleLike};
387///
388/// let tup = tuple!(1, "hello", 3.14).foreach(mapper! {
389///     |x: i32| -> i64 { x as i64 }
390///     |x: f32| -> String { x.to_string() }
391///     <'a> |x: &'a str| -> &'a [u8] { x.as_bytes() }
392/// });
393/// assert_eq!(tup, tuple!(1i64, b"hello" as &[u8], "3.14".to_string()));
394/// ```
395///
396/// ## Traverse tuples in order of their elements
397///
398/// You can create a new tuple with the same number of elements, whose elements are all callable objects that accepts an element
399/// and returns another value ([`FnOnce(T) -> U`](std::ops::FnOnce)), then, you can use that tuple as a mapper.
400//
401/// ```
402/// use tuplez::{tuple, TupleLike};
403///
404/// let tup = tuple!(1, 2, 3);
405/// let result = tup.foreach(
406///     tuple!(
407///         |x| x as f32,
408///         |x: i32| x.to_string(),
409///         |x: i32| Some(x),
410///     )
411/// );
412/// assert_eq!(result, tuple!(1.0, "2".to_string(), Some(3)));
413/// ```
414///
415/// # Fold tuples
416///
417/// You can fold tuples by [`fold()`](TupleLike::fold()).
418///
419/// Call [`fold()`](TupleLike::fold()) on a tuple requires a folder implementing
420/// [`Folder`](crate::fold::Folder) as the parameter. Check its documentation page for examples.
421///
422/// However, here are two ways you can quickly build a folder.
423///
424/// ## Fold tuples by element types
425///
426/// The [`folder!`](crate::folder!) macro helps you build a folder that folds tuples according to their element types.
427///
428/// For example:
429///
430/// ```
431/// use tuplez::{folder, tuple, TupleLike};
432///
433/// let tup = tuple!(Some(1), "2", Some(3.0));
434/// let result = tup.fold(
435///     folder! { String; // Type of `acc` of all closures must be the same and annotated at the front
436///         |acc, x: &str| { acc + &x.to_string() }
437///         <T: ToString> |acc, x: Option<T>| { acc + &x.unwrap().to_string() }
438///     },
439///     String::new(),
440/// );
441/// assert_eq!(result, "123".to_string());
442/// ```
443///
444/// ## Fold tuples in order of their elements
445///
446/// You can create a new tuple with the same number of elements, whose elements are all callable objects that accepts the accumulation value
447/// and an element and returns new accumulation value ([`FnOnce(Acc, T) -> Acc`](std::ops::FnOnce)), then, you can use that tuple as a folder.
448///
449/// For example:
450///
451/// ```
452/// use tuplez::{tuple, TupleLike};
453///
454/// let tup = tuple!(1, "2", 3.0);
455/// let result = tup.fold(
456///     tuple!(
457///         |acc, x| (acc + x) as f64,
458///         |acc: f64, x: &str| acc.to_string() + x,
459///         |acc: String, x| acc.parse::<i32>().unwrap() + x as i32,
460///     ),  // Type of `acc` of each closure is the return type of the previous closure.
461///     0,
462/// );
463/// assert_eq!(result, 15);
464/// ```
465///
466/// # Convert from/to primitive tuples
467///
468/// Okay, we're finally talking about the only interfaces of [`Tuple`] that limits the maximum number of elements.
469///
470/// Since Rust does not have a way to represent [primitive tuple types](https://doc.rust-lang.org/std/primitive.tuple.html) with an arbitrary number of elements,
471/// the interfaces for converting from/to primitive tuple types is only implemented for [`Tuple`]s with no more than 32 elements.
472///
473/// ```
474/// # #![cfg_attr(feature = "any_array", feature(generic_const_exprs))]
475///
476/// use tuplez::{ToPrimitive, tuple, Tuple, tuple_t};
477///
478/// let tup = tuple!(1, "hello", 3.14);
479/// let prim_tup = (1, "hello", 3.14);
480/// assert_eq!(tup.primitive(), prim_tup);
481/// assert_eq!(tup, Tuple::from(prim_tup));
482///
483/// let unit = tuple!();
484/// let prim_unit = ();
485/// assert_eq!(unit.primitive(), prim_unit);
486/// assert_eq!(unit, <tuple_t!()>::from(prim_unit));
487/// ```
488///
489/// # Convert from/to primitive arrays
490///
491/// If all elements of a tuple are of the same type, then it can be converted from/to [primitive arrays](std::array).
492///
493/// Currently tuples cannot be converted from/to primitive arrays with no limit on the number of elements,
494/// since the [generic constant expressions](https://github.com/rust-lang/rust/issues/76560) feature is still unstable yet.
495///
496/// Therefore, by default only tuples with no more than 32 elements are supported to be converted from/to primitive arrays.
497///
498/// However, if you are OK with using rustc released to nightly channel to compile codes with unstable features,
499/// you can enable the `any_array` feature, then tuplez will use unstable features to implement conversion from/to
500/// primitive arrays on tuples of any number of elements.
501///
502/// ```toml
503/// tuplez = { features = [ "any_array" ] }
504/// ```
505///
506/// For examples:
507///
508/// ```
509/// // Enable Rust's `generic_const_exprs` feature if you enable tuplez's `any_array` feature.
510/// #![cfg_attr(feature = "any_array", feature(generic_const_exprs))]
511///
512/// use tuplez::{ToArray, tuple, tuple_t};
513///
514/// assert_eq!(tuple!(1, 2, 3, 4, 5, 6).to_array(), [1, 2, 3, 4, 5, 6]);
515/// assert_eq!(<tuple_t!(i32; 4)>::from([1, 2, 3, 4]), tuple!(1, 2, 3, 4));
516///
517/// // `Unit` can be converted from/to array of any element type
518/// let _ : [i32; 0] = tuple!().to_array();
519/// let _ : [String; 0] = tuple!().to_array();
520/// let _ = <tuple_t!()>::from([3.14; 0]);
521/// let _ = <tuple_t!()>::from([""; 0]);
522/// ```
523#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
524#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
525pub struct Tuple<First, Other>(
526    /// First element.
527    pub First,
528    /// Other elements. See [representation](Tuple#representation).
529    pub Other,
530);
531
532/// Define the basic methods of tuples.
533///
534/// NOTE: Due to the limitation that Rust does not support the variadic to represent
535/// [primitive tuple types]((https://doc.rust-lang.org/std/primitive.tuple.html)) containing any number of elements,
536/// we cannot make [`TupleLike`] trait contain a method that converts tuple to the primitive tuple type.
537/// Therefore, this method is provided by the trait [`ToPrimitive`] and is only implemented for tuples with no more than 32 elements.
538pub trait TupleLike {
539    /// The type of tuple containing immutable references to all elements of the tuple.
540    type AsRefOutput<'a>: TupleLike
541    where
542        Self: 'a;
543
544    /// The type of tuple containing mutable references to all elements of the tuple.
545    type AsMutOutput<'a>: TupleLike
546    where
547        Self: 'a;
548
549    /// The type of tuple containing pointers to all elements of the tuple.
550    type AsPtrOutput: TupleLike;
551
552    /// The type of tuple containing mutable pointers to all elements of the tuple.
553    type AsMutPtrOutput: TupleLike;
554
555    /// The type of tuple containing [`Pin`]s of immutable references to all elements of the tuple.
556    type AsPinRefOutput<'a>: TupleLike
557    where
558        Self: 'a;
559
560    /// The type of tuple containing [`Pin`]s of mutable references to all elements of the tuple.
561    type AsPinMutOutput<'a>: TupleLike
562    where
563        Self: 'a;
564
565    /// The type of tuple generated by pushing an element to the front of the tuple.
566    type PushFrontOutput<T>: TupleLike;
567
568    /// The type of tuple generated by pushing an element to the back of the tuple.
569    type PushBackOutput<T>: TupleLike;
570
571    /// The type of tuple generated by reversing the tuple.
572    type RevOutput: TupleLike;
573
574    /// The type of tuple generated by joining two tuples.
575    type JoinOutput<T>: TupleLike
576    where
577        T: TupleLike;
578
579    /// The type of tuple after wrapping all elements into [`Option`](std::option::Option).
580    type ToSomeOutput: TupleLike;
581
582    /// The type of tuple after wrapping all elements into [`Result`](std::result::Result).
583    type ToOkOutput<E>: TupleLike;
584
585    /// The type of tuple after wrapping all elements into [`Tuple`].
586    type ToTupleOutput: TupleLike;
587
588    /// The type of tuple after wrapping all elements into [`MaybeUninit`].
589    #[cfg(feature = "uninit")]
590    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
591    type Uninit: TupleLike;
592
593    /// The number of elements in the tuple.
594    const LEN: usize;
595
596    /// Get the number of elements in the tuple.
597    /// MUST always return [`LEN`](TupleLike::LEN).
598    ///
599    /// # Example
600    ///
601    /// ```
602    /// use tuplez::{tuple, TupleLike};
603    /// assert_eq!(tuple!(1, "hello", 3.14).len(), 3);
604    /// ```
605    fn len(&self) -> usize {
606        Self::LEN
607    }
608
609    /// Check if tuple is empty.
610    ///
611    /// Always be `false` if tuple is [`Unit`],
612    /// and always be `true` if tuple is [`Tuple`].
613    ///
614    /// # Example
615    ///
616    /// ```
617    /// use tuplez::{tuple, TupleLike};
618    ///
619    /// assert_eq!(tuple!().is_empty(), true);
620    /// assert_eq!(tuple!(1, "hello", 3.14).is_empty(), false);
621    /// ```
622    fn is_empty(&self) -> bool {
623        Self::LEN == 0
624    }
625
626    /// Creates a “by reference” adapter for this instance.
627    ///
628    /// It will simply borrow this current tuple.
629    fn by_ref(&mut self) -> &mut Self
630    where
631        Self: Sized,
632    {
633        self
634    }
635
636    /// Convert from `tuple!(x, y, z, ...)` to `tuple!((0, x), (1, y), (2, z), ...)`.
637    ///
638    /// # Example
639    ///
640    /// ```
641    /// use tuplez::{tuple, TupleLike};
642    ///
643    /// let tup = tuple!("hello", Some([1, 2, 3]), tuple!(3.14, 12));
644    /// assert_eq!(tup.enumerate(), tuple!(
645    ///     (0, "hello"),
646    ///     (1, Some([1, 2, 3])),
647    ///     (2, tuple!(3.14, 12)),
648    /// ));
649    /// ```
650    fn enumerate(self) -> Self::EnumerateOutput
651    where
652        Self: Sized + Enumerable,
653    {
654        Enumerable::enumerate(self, 0)
655    }
656
657    /// Take out the searched element, and get the remainder of tuple.
658    ///
659    /// Add a type annotation to the searched element to let [`take()`](TupleLike::take()) know which one you want.
660    ///
661    /// **NOTE**: The type of this element must exist only once in the tuple.
662    ///
663    /// If you want to take out the element at a specific index, see [`take!`](crate::take!).
664    ///
665    /// If you want to take out the first or last element, see [`pop()`][TupleLike::pop()].
666    ///
667    /// # Example
668    ///
669    /// ```
670    /// use tuplez::{tuple, TupleLike};
671    ///
672    /// let tup = tuple!(3.14, "hello", 5, [1, 2, 3]);
673    /// let (value, remainder): (i32, _) = tup.take();      // Add type annotation for `value`
674    /// assert_eq!(value, 5);
675    /// assert_eq!(remainder, tuple!(3.14, "hello", [1, 2, 3]));
676    /// ```
677    ///
678    /// If you cannot add a type annotation, you can also use the [`take!`](crate::take!) macro:
679    ///
680    /// ```
681    /// use tuplez::{take, tuple};
682    ///
683    /// let tup = tuple!(3.14, "hello", 5, [1, 2, 3]);
684    /// let (value, remainder) = take!(tup; i32);
685    /// assert_eq!(value, 5);
686    /// assert_eq!(remainder, tuple!(3.14, "hello", [1, 2, 3]));
687    /// ```
688    fn take<T, I>(self) -> (T, Self::TakeRemainder)
689    where
690        Self: Search<T, I> + Sized,
691    {
692        Search::take(self)
693    }
694
695    /// Get an immutable reference of the searched element.
696    ///
697    /// Add a type annotation to the searched element to let [`get_ref()`](TupleLike::get_ref()) know which one you want.
698    ///
699    /// **NOTE**: The type of this element must exist only once in the tuple.
700    ///
701    /// If you want to get the element by its index, see [`get!`](crate::get!);
702    ///
703    /// # Example
704    ///
705    /// ```
706    /// use tuplez::{tuple, TupleLike};
707    ///
708    /// let tup = tuple!(3.14, "hello", 5, [1, 2, 3]);
709    /// let arr: &[i32; 3] = tup.get_ref();
710    /// assert_eq!(arr, &[1, 2, 3]);
711    /// ```
712    fn get_ref<T, I>(&self) -> &T
713    where
714        Self: Search<T, I> + Sized,
715    {
716        Search::get_ref(self)
717    }
718
719    /// Get a mutable reference of the searched element.
720    ///
721    /// Add a type annotation to the searched element to let [`get_mut()`](TupleLike::get_mut()) know which one you want.
722    ///
723    /// **NOTE**: The type of this element must exist only once in the tuple.
724    ///
725    /// If you want to get the element by its index, see [`get!`](crate::get!);
726    ///
727    /// # Example
728    ///
729    /// ```
730    /// use tuplez::{tuple, TupleLike};
731    ///
732    /// let mut tup = tuple!(3.14, "hello", 5, [1, 2, 3]);
733    /// let s: &mut &str = tup.get_mut();
734    /// *s = "world";
735    /// assert_eq!(tup, tuple!(3.14, "world", 5, [1, 2, 3]));
736    /// ```
737    fn get_mut<T, I>(&mut self) -> &mut T
738    where
739        Self: Search<T, I> + Sized,
740    {
741        Search::get_mut(self)
742    }
743
744    /// Swap a specific element of the same type with another value.
745    ///
746    /// **NOTE**: The type of this element must exist only once in the tuple.
747    ///
748    /// # Example
749    ///
750    /// ```
751    /// use tuplez::{tuple, TupleLike};
752    ///
753    /// let mut tup = tuple!(3.14, "hello", 5, [1, 2, 3]);
754    /// let mut s = "world";
755    /// tup.swap(&mut s);
756    /// assert_eq!(tup, tuple!(3.14, "world", 5, [1, 2, 3]));
757    /// assert_eq!(s, "hello");
758    /// ```
759    fn swap<T, I>(&mut self, value: &mut T)
760    where
761        Self: Search<T, I>,
762    {
763        Search::swap(self, value)
764    }
765
766    /// Replace a specific element of the same type with another value.
767    ///
768    /// Return the replaced value.
769    ///
770    /// **NOTE**: The type of this element must exist only once in the tuple.
771    ///
772    /// Hint: If you don’t want to consume the input tuple, then what you are looking
773    /// for might be [`swap()`](TupleLike::swap()).
774    ///
775    /// # Example
776    ///
777    /// ```
778    /// use tuplez::{tuple, TupleLike};
779    ///
780    /// let mut tup = tuple!(3.14, "hello", 5, [1, 2, 3]);
781    /// let s = tup.replace("world");
782    /// assert_eq!(tup, tuple!(3.14, "world", 5, [1, 2, 3]));
783    /// assert_eq!(s, "hello");
784    /// ```
785    fn replace<T, I>(&mut self, value: T) -> T
786    where
787        Self: Search<T, I>,
788    {
789        Search::replace(self, value)
790    }
791
792    /// Replace a specific element with another value that may be of a different type.
793    ///
794    /// The new element is generated a the user-defined function.
795    ///
796    /// # Example
797    ///
798    /// ```
799    /// use tuplez::{tuple, TupleLike};
800    ///
801    /// let tup = tuple!(1, 3.14, "hello", Some([1, 2, 3]));
802    /// let result = tup.map_replace(|x: f64| x.to_string());
803    /// assert_eq!(result, tuple!(1, "3.14".to_string(), "hello", Some([1, 2, 3])))
804    /// ```
805    fn map_replace<T, U, F, I>(self, f: F) -> Self::MapReplaceOutput<U>
806    where
807        Self: Search<T, I> + Sized,
808        F: FnOnce(T) -> U,
809    {
810        Search::map_replace(self, f)
811    }
812
813    // fn map_replace<T, I>(self, value: T) ->
814
815    /// Take out a subsequence.
816    ///
817    /// **NOTE**: The subsequence must have one and only one candidate in the supersequence.
818    ///
819    /// Add a type annotation to the subsequence to let [`subseq()`](TupleLike::subseq()) know.
820    ///
821    /// # Example
822    ///
823    /// ```
824    /// use tuplez::{tuple, TupleLike, tuple_t};
825    ///
826    /// let tup = tuple!(12, "hello", 24, 3.14, true);
827    /// let subseq: tuple_t!(&str, bool) = tup.subseq();
828    /// assert_eq!(subseq, tuple!("hello", true));
829    ///
830    /// // Two candidates available: `(12, true)` or `(24, true)`.
831    /// // let subseq: tuple_t!(i32, bool) = tup.subseq();
832    ///
833    /// // No candidates available.
834    /// // `(true, "hello")` cannot be a candidate, since its element order is
835    /// // different from the supersequence.
836    /// // let subseq: tuple_t!(bool, &str) = tup.subseq();
837    ///
838    /// // Although `24` is also `i32`, but only `(12, "hello")` is a candidate.
839    /// let subseq: tuple_t!(i32, &str) = tup.subseq();
840    /// assert_eq!(subseq, tuple!(12, "hello"));
841    ///
842    /// // It's OK to pick all `i32`s since there is only one candidate.
843    /// let subseq: tuple_t!(i32, i32) = tup.subseq();
844    /// assert_eq!(subseq, tuple!(12, 24));
845    /// ```
846    fn subseq<Seq, I>(self) -> Seq
847    where
848        Self: Subseq<Seq, I> + Sized,
849        Seq: TupleLike,
850    {
851        Subseq::subseq(self)
852    }
853
854    /// Similar to [`subseq()`](TupleLike::subseq()),
855    /// but all its elements are immutable references to the supersequence's elements.
856    ///
857    /// **NOTE**: The subsequence must have one and only one candidate in the supersequence.
858    ///
859    /// Rust is almost impossible to infer generic types by the return type annotation,
860    /// so you need to call it like:
861    ///
862    /// ```
863    /// use tuplez::{tuple, TupleLike, tuple_t};
864    ///
865    /// let tup = tuple!(12, "hello", vec![1, 2, 3], 24, 3.14, true);
866    /// let subseq = tup.subseq_ref::<tuple_t!(&'static str, bool), _>();
867    /// assert_eq!(subseq, tuple!(&"hello", &true));
868    /// ```
869    fn subseq_ref<Seq, I>(&self) -> Seq::AsRefOutput<'_>
870    where
871        Self: Subseq<Seq, I> + Sized,
872        Seq: TupleLike,
873    {
874        Subseq::subseq_ref(self)
875    }
876
877    /// Similar to [`subseq()`](TupleLike::subseq()),
878    /// but all its elements are mutable references to the supersequence's elements.
879    ///
880    /// **NOTE**: The subsequence must have one and only one candidate in the supersequence.
881    ///
882    /// Rust is almost impossible to infer generic types by the return type annotation,
883    /// so you need to call it like:
884    ///
885    /// ```
886    /// use tuplez::{get, tuple, TupleLike, tuple_t};
887    ///
888    /// let mut tup = tuple!(12, "hello", vec![1, 2, 3], 24, 3.14, true);
889    /// let subseq = tup.subseq_mut::<tuple_t!(&'static str, bool), _>();
890    /// *get!(subseq; 0) = "world";
891    /// *get!(subseq; 1) = false;
892    /// assert_eq!(tup, tuple!(12, "world", vec![1, 2, 3], 24, 3.14, false));
893    /// ```
894    fn subseq_mut<Seq, I>(&mut self) -> Seq::AsMutOutput<'_>
895    where
896        Self: Subseq<Seq, I> + Sized,
897        Seq: TupleLike,
898    {
899        Subseq::subseq_mut(self)
900    }
901
902    /// Swap elements with a subsequence.
903    ///
904    /// See [`subseq()`](TupleLike::subseq()) to see which inputs are subsequence.
905    ///
906    /// **NOTE**: The subsequence must have one and only one candidate in the supersequence.
907    ///
908    /// # Example
909    ///
910    /// ```
911    /// use tuplez::{tuple, TupleLike};
912    ///
913    /// let mut tup = tuple!(1, Some("hello"), 2, Some(()), 3.14, 3);
914    /// let mut tup2 = tuple!(Some("world"), 9.8);
915    /// tup.swap_subseq(&mut tup2);
916    /// assert_eq!(tup, tuple!(1, Some("world"), 2, Some(()), 9.8, 3));
917    /// assert_eq!(tup2, tuple!(Some("hello"), 3.14));
918    /// ```
919    fn swap_subseq<Seq, I>(&mut self, subseq: &mut Seq)
920    where
921        Seq: TupleLike,
922        Self: Subseq<Seq, I>,
923    {
924        Subseq::swap_subseq(self, subseq)
925    }
926
927    /// Replace elements with a subsequence.
928    ///
929    /// See [`subseq()`](TupleLike::subseq()) to see which inputs are subsequence.
930    ///
931    /// **NOTE**: The subsequence must have one and only one candidate in the supersequence.
932    ///
933    /// It returns a subsequence consisting of the replaced elements.
934    ///
935    /// Hint: If you don't want to consume the input tuple,
936    /// then what you are looking for might be [`swap_subseq()`](TupleLike::swap_subseq()).
937    ///
938    /// # Example
939    ///
940    /// ```
941    /// use tuplez::{tuple, TupleLike};
942    ///
943    /// let mut tup = tuple!(1, Some("hello"), 2, Some(()), 3.14, 3);
944    /// let replaced = tup.replace_subseq(tuple!(Some("world"), 9.8));
945    /// assert_eq!(tup, tuple!(1, Some("world"), 2, Some(()), 9.8, 3));
946    /// assert_eq!(replaced, tuple!(Some("hello"), 3.14));
947    /// ```
948    fn replace_subseq<Seq, I>(&mut self, subseq: Seq) -> Seq
949    where
950        Seq: TupleLike,
951        Self: Subseq<Seq, I>,
952    {
953        Subseq::replace_subseq(self, subseq)
954    }
955
956    /// Replace elements of specific subsequence with another sequence
957    /// that may be of different element types.
958    ///
959    /// The elements of new sequence is generated from the user-defined mapper.
960    ///
961    /// Check out [`Mapper`](crate::foreach::Mapper)’s documentation page to learn how to build a mapper.
962    ///
963    /// # Example
964    ///
965    /// ```
966    /// use std::fmt::Debug;
967    /// use tuplez::{mapper, tuple, TupleLike, tuple_t};
968    ///
969    /// let tup = tuple!(1, 3.14, "hello", [1, 2, 3]);
970    /// let result = tup.map_replace_subseq::<tuple_t!(f64, [i32; 3]), _, _>(mapper! {
971    ///     |x: f64| -> i32 { x as i32 }
972    ///     <T: Debug, const N: usize> |x: [T; N]| -> String { format!("{x:?}") }
973    /// });
974    /// assert_eq!(result, tuple!(1, 3, "hello", "[1, 2, 3]".to_string()))
975    /// ```
976    fn map_replace_subseq<Seq, F, I>(self, f: F) -> Self::MapReplaceOutput
977    where
978        Seq: TupleLike,
979        Self: SubseqMapReplace<Seq, F, I> + Sized,
980    {
981        SubseqMapReplace::map_replace_subseq(self, f)
982    }
983
984    /// Replace elements of specific subsequence with another sequence
985    /// that may be of different element types.
986    ///
987    /// Same as [`map_replace_subseq()`](TupleLike::map_replace_subseq()).
988    fn foreach_subseq<Seq, F, I>(self, f: F) -> Self::MapReplaceOutput
989    where
990        Seq: TupleLike,
991        Self: SubseqMapReplace<Seq, F, I> + Sized,
992    {
993        SubseqMapReplace::map_replace_subseq(self, f)
994    }
995
996    /// Take out a contiguous subsequence.
997    ///
998    /// Unlike [`subseq()`](TupleLike::subseq()), this method requires that all elements of the subsequence are
999    /// contiguous in the supersequence. Sometimes it can do things that [`subseq()`](TupleLike::subseq()) can't.
1000    ///
1001    /// **NOTE**: The contiguous subsequence must have one and only one candidate in the supersequence.
1002    ///
1003    /// Add a type annotation to the contiguous subsequence to let [`con_subseq()`](TupleLike::con_subseq()) know.
1004    ///
1005    /// # Example
1006    ///
1007    /// ```
1008    /// use tuplez::{tuple, TupleLike, tuple_t};
1009    ///
1010    /// let tup = tuple!(12, "hello", 24, true, false);
1011    ///
1012    /// // For `subseq`, 4 candidates available:
1013    /// //      `(12, true)`,
1014    /// //      `(12, false)`,
1015    /// //      `(24, true)`,
1016    /// //      `(24, false)`,
1017    /// // so this cannot be compiled.
1018    /// // let subseq: tuple_t!(i32, bool) = tup.subseq();
1019    ///
1020    /// // But for `con_subseq`,only `(24, true)` is a candidate.
1021    /// let subseq: tuple_t!(i32, bool) = tup.con_subseq();
1022    /// assert_eq!(subseq, tuple!(24, true));
1023    /// ```
1024    fn con_subseq<Seq, I>(self) -> Seq
1025    where
1026        Seq: TupleLike,
1027        Self: ConSubseq<Seq, I> + Sized,
1028    {
1029        ConSubseq::con_subseq(self)
1030    }
1031
1032    /// Similar to [`con_subseq()`](TupleLike::con_subseq()),
1033    /// but all its elements are immutable references to the supersequence's elements.
1034    ///
1035    /// **NOTE**: The contiguous subsequence must have one and only one candidate in the supersequence.
1036    ///
1037    /// Rust is almost impossible to infer generic types by the return type annotation,
1038    /// so you need to call it like:
1039    ///
1040    /// ```
1041    /// use tuplez::{tuple, TupleLike, tuple_t};
1042    ///
1043    /// let tup = tuple!(12, "hello", vec![1, 2, 3], 24, 3.14, 36);
1044    /// let subseq = tup.con_subseq_ref::<tuple_t!(i32, f32), _>();
1045    /// assert_eq!(subseq, tuple!(&24, &3.14));
1046    /// ```
1047    fn con_subseq_ref<Seq, I>(&self) -> Seq::AsRefOutput<'_>
1048    where
1049        Seq: TupleLike,
1050        Self: ConSubseq<Seq, I>,
1051    {
1052        ConSubseq::con_subseq_ref(self)
1053    }
1054
1055    /// Similar to [`con_subseq()`](TupleLike::con_subseq()),
1056    /// but all its elements are mutable references to the supersequence's elements.
1057    ///
1058    /// **NOTE**: The contiguous subsequence must have one and only one candidate in the supersequence.
1059    ///
1060    /// Rust is almost impossible to infer generic types by the return type annotation,
1061    /// so you need to call it like:
1062    ///
1063    /// ```
1064    /// use tuplez::{get, tuple, TupleLike, tuple_t};
1065    ///
1066    /// let mut tup = tuple!(12, "hello", vec![1, 2, 3], "world", 24, 36);
1067    /// let subseq = tup.con_subseq_mut::<tuple_t!(&'static str, i32), _>();
1068    /// *get!(subseq; 0) = "rust";
1069    /// *get!(subseq; 1) = 0;
1070    /// assert_eq!(tup, tuple!(12, "hello", vec![1, 2, 3], "rust", 0, 36));
1071    /// ```
1072    fn con_subseq_mut<Seq, I>(&mut self) -> Seq::AsMutOutput<'_>
1073    where
1074        Seq: TupleLike,
1075        Self: ConSubseq<Seq, I>,
1076    {
1077        ConSubseq::con_subseq_mut(self)
1078    }
1079
1080    /// Swap elements with a contiguous subsequence.
1081    ///
1082    /// Unlike [`swap_subseq()`](TupleLike::swap_subseq()), this method requires that all
1083    /// elements of the subsequence are contiguous in the supersequence.
1084    /// Sometimes it can do things that [`swap_subseq()`](TupleLike::swap_subseq()) can't.
1085    ///
1086    /// **NOTE**: The contiguous subsequence must have one and only one candidate in the supersequence.
1087    ///
1088    /// # Example
1089    ///
1090    /// ```
1091    /// use tuplez::{tuple, TupleLike};
1092    ///
1093    /// let mut tup = tuple!(1, Some("hello"), 2, Some(()), 3.14, 3);
1094    /// let mut tup2 = tuple!(4, None::<()>);
1095    /// tup.swap_con_subseq(&mut tup2);
1096    /// assert_eq!(tup, tuple!(1, Some("hello"), 4, None::<()>, 3.14, 3));
1097    /// assert_eq!(tup2, tuple!(2, Some(())));
1098    /// ```
1099    fn swap_con_subseq<Seq, I>(&mut self, subseq: &mut Seq)
1100    where
1101        Seq: TupleLike,
1102        Self: ConSubseq<Seq, I>,
1103    {
1104        ConSubseq::swap_con_subseq(self, subseq)
1105    }
1106
1107    /// Replace elements with a contiguous subsequence.
1108    ///
1109    /// Unlike [`replace_subseq()`](TupleLike::replace_subseq()), this method requires that
1110    /// all elements of the subsequence are contiguous in the supersequence.
1111    /// Sometimes it can do things that [`replace_subseq()`](TupleLike::replace_subseq()) can't.
1112    ///
1113    /// **NOTE**: The contiguous subsequence must have one and only one candidate in the supersequence.
1114    ///
1115    /// It returns a contiguous subsequence consisting of the replaced elements.
1116    ///
1117    /// Hint: If you don't want to consume the input tuple,
1118    /// then what you are looking for might be [`swap_con_subseq()`](TupleLike::swap_con_subseq()).
1119    ///
1120    /// # Example
1121    ///
1122    /// ```
1123    /// use tuplez::{tuple, TupleLike};
1124    ///
1125    /// let mut tup = tuple!(1, Some("hello"), 2, Some(()), 3.14, 3);
1126    /// let replaced = tup.replace_con_subseq(tuple!(4, None::<()>));
1127    /// assert_eq!(tup, tuple!(1, Some("hello"), 4, None::<()>, 3.14, 3));
1128    /// assert_eq!(replaced, tuple!(2, Some(())));
1129    /// ```
1130    fn replace_con_subseq<Seq, I>(&mut self, subseq: Seq) -> Seq
1131    where
1132        Seq: TupleLike,
1133        Self: ConSubseq<Seq, I>,
1134    {
1135        ConSubseq::replace_con_subseq(self, subseq)
1136    }
1137
1138    /// Replace elements of specific contiguous subsequence with another sequence
1139    /// that may be of different element types.
1140    ///
1141    /// The elements of new sequence is generated from the user-defined mapper.
1142    ///
1143    /// Check out [`Mapper`](crate::foreach::Mapper)’s documentation page to learn how to build a mapper.
1144    ///
1145    /// # Example
1146    ///
1147    /// ```
1148    /// use tuplez::{mapper, tuple, TupleLike, tuple_t};
1149    ///
1150    /// let tup = tuple!("1", "2", "3", true, false, true);
1151    /// let result = tup.map_replace_con_subseq::<tuple_t!(&str, bool, bool), _, _>(mapper! {
1152    ///     |x: &str| -> i32 { x.parse().unwrap() }
1153    ///     |x: bool| -> bool { !x }
1154    /// });
1155    /// assert_eq!(result, tuple!("1", "2", 3, false, true, true));
1156    /// ```
1157    fn map_replace_con_subseq<Seq, F, I>(self, f: F) -> Self::MapReplaceOutput
1158    where
1159        Seq: TupleLike,
1160        Self: ConSubseqMapReplace<Seq, F, I> + Sized,
1161    {
1162        ConSubseqMapReplace::map_replace_con_subseq(self, f)
1163    }
1164
1165    /// Replace elements of specific contiguous subsequence with another sequence
1166    /// that may be of different element types.
1167    ///
1168    /// Same as [`map_replace_con_subseq()`](TupleLike::map_replace_con_subseq()).
1169    fn foreach_con_subseq<Seq, F, I>(self, f: F) -> Self::MapReplaceOutput
1170    where
1171        Seq: TupleLike,
1172        Self: ConSubseqMapReplace<Seq, F, I> + Sized,
1173    {
1174        ConSubseqMapReplace::map_replace_con_subseq(self, f)
1175    }
1176
1177    /// In the past it was used for the functionality of [`subseq()`](TupleLike::subseq()),
1178    /// however it did not live up to its name: you actually got a subsequence not a subset while
1179    /// subsets are not required to maintain a consistent element order as the superset.
1180    ///
1181    /// Therefore, it has been deprecated. You can use [`subseq()`](TupleLike::subseq()) or
1182    /// [`con_subseq()`](TupleLike::con_subseq()) instead.
1183    #[deprecated(since = "0.10.0", note = "Use subseq() or con_subseq() instead")]
1184    fn subset<Seq, I>(self) -> Seq
1185    where
1186        Self: Subseq<Seq, I> + Sized,
1187        Seq: TupleLike,
1188    {
1189        Subseq::subseq(self)
1190    }
1191
1192    /// In the past it was used for the functionality of [`subseq_ref()`](TupleLike::subseq_ref()),
1193    /// however it did not live up to its name: you actually got a subsequence not a subset while
1194    /// subsets are not required to maintain a consistent element order as the superset.
1195    ///
1196    /// Therefore, it has been deprecated. You can use [`subseq_ref()`](TupleLike::subseq_ref()) or
1197    /// [`con_subseq_ref()`](TupleLike::con_subseq_ref()) instead.
1198    #[deprecated(
1199        since = "0.10.0",
1200        note = "Use subseq_ref() or con_subseq_ref() instead"
1201    )]
1202    fn subset_ref<Seq, I>(&self) -> Seq::AsRefOutput<'_>
1203    where
1204        Self: Subseq<Seq, I> + Sized,
1205        Seq: TupleLike,
1206    {
1207        Subseq::subseq_ref(self)
1208    }
1209
1210    /// In the past it was used for the functionality of [`subseq_mut()`](TupleLike::subseq_mut()),
1211    /// however it did not live up to its name: you actually got a subsequence not a subset while
1212    /// subsets are not required to maintain a consistent element order as the superset.
1213    ///
1214    /// Therefore, it has been deprecated. You can use [`subseq_mut()`](TupleLike::subseq_mut()) or
1215    /// [`con_subseq_mut()`](TupleLike::con_subseq_mut()) instead.
1216    #[deprecated(
1217        since = "0.10.0",
1218        note = "Use subseq_mut() or con_subseq_mut() instead"
1219    )]
1220    fn subset_mut<Seq, I>(&mut self) -> Seq::AsMutOutput<'_>
1221    where
1222        Self: Subseq<Seq, I> + Sized,
1223        Seq: TupleLike,
1224    {
1225        Subseq::subseq_mut(self)
1226    }
1227
1228    /// In the past it was used for the functionality of
1229    /// [`swap_con_subseq()`](TupleLike::swap_con_subseq()),
1230    /// but with the addition of [`swap_subseq()`](TupleLike::swap_subseq()),
1231    /// the functionality of this method becomes very unclear.
1232    ///
1233    /// Therefore, it has been deprecated. You can use [`swap()`](TupleLike::swap()),
1234    /// [`swap_subseq()`](TupleLike::swap_subseq()) or
1235    /// [`swap_con_subseq()`](TupleLike::swap_con_subseq()) instead.
1236    #[deprecated(
1237        since = "0.10.0",
1238        note = "Use swap(), swap_subseq() or swap_con_subseq() instead"
1239    )]
1240    fn swap_with<Seq, I>(&mut self, subseq: &mut Seq)
1241    where
1242        Seq: TupleLike,
1243        Self: ConSubseq<Seq, I>,
1244    {
1245        ConSubseq::swap_con_subseq(self, subseq)
1246    }
1247
1248    /// In the past it was used for the functionality of
1249    /// [`replace_con_subseq()`](TupleLike::replace_con_subseq()),
1250    /// but with the addition of [`replace_subseq()`](TupleLike::replace_subseq()),
1251    /// the functionality of this method becomes very unclear.
1252    ///
1253    /// Therefore, it has been deprecated. You can use [`replace()`](TupleLike::replace()),
1254    /// [`replace_subseq()`](TupleLike::replace_subseq()) or
1255    /// [`replace_con_subseq()`](TupleLike::replace_con_subseq()) instead.
1256    #[deprecated(
1257        since = "0.10.0",
1258        note = "Use replace(), replace_subseq() or replace_con_subseq() instead"
1259    )]
1260    fn replace_with<Seq, I>(&mut self, subseq: Seq) -> Seq
1261    where
1262        Seq: TupleLike,
1263        Self: ConSubseq<Seq, I>,
1264    {
1265        ConSubseq::replace_con_subseq(self, subseq)
1266    }
1267
1268    /// Generate a tuple containing immutable references to all elements of the tuple.
1269    ///
1270    /// # Example
1271    ///
1272    /// ```
1273    /// use tuplez::{tuple, TupleLike, tuple_t};
1274    ///
1275    /// let tup = tuple!([1, 2], "hello".to_string());
1276    /// let tup_ref: tuple_t!(&[i32; 2], &String) = tup.as_ref();
1277    /// assert_eq!(tup_ref, tuple!(&[1, 2], &String::from("hello")));
1278    /// ```
1279    fn as_ref(&self) -> Self::AsRefOutput<'_>;
1280
1281    /// Generate a tuple containing mutable reference to all elements of the tuple.
1282    ///
1283    /// # Example
1284    ///
1285    /// ```
1286    /// use tuplez::{get, tuple, TupleLike};
1287    ///
1288    /// let mut tup = tuple!(1, "hello");
1289    /// let tup_mut = tup.as_mut();
1290    /// *get!(tup_mut; 0) += 1;
1291    /// *get!(tup_mut; 1) = "world";
1292    /// assert_eq!(tup, tuple!(2, "world"));
1293    /// ```
1294    fn as_mut(&mut self) -> Self::AsMutOutput<'_>;
1295
1296    /// Generate a tuple containing pointers to all elements of the tuple.
1297    ///
1298    /// # Example
1299    ///
1300    /// ```
1301    /// use tuplez::{get, tuple, TupleLike};
1302    ///
1303    /// let tup = tuple!(1, 3.14, "hello", vec![1, 2, 3]);
1304    /// let tup_ptr = tup.as_ptr();
1305    /// let pi = unsafe { &*get!(tup_ptr; 1) };
1306    /// assert_eq!(pi, &3.14);
1307    /// ```
1308    fn as_ptr(&self) -> Self::AsPtrOutput;
1309
1310    /// Generate a tuple containing mutable pointers to all elements of the tuple.
1311    ///
1312    /// # Example
1313    ///
1314    /// ```
1315    /// use tuplez::{get, tuple, TupleLike};
1316    ///
1317    /// let mut tup = tuple!(1, 3.14, "hello", vec![1, 2, 3]);
1318    /// let tup_ptr = tup.as_mut_ptr();
1319    /// let v = unsafe { &mut *get!(tup_ptr; 3) };
1320    /// v.push(4);
1321    /// assert_eq!(v.len(), 4);
1322    /// ```
1323    fn as_mut_ptr(&mut self) -> Self::AsMutPtrOutput;
1324
1325    /// Convert from [`Pin<&Tuple<T0, T1, T2, ..>`](Pin) to `Tuple<Pin<&T0>, Pin<&T1>, Pin<&T2>, ...>`.
1326    fn as_pin_ref(self: Pin<&Self>) -> Self::AsPinRefOutput<'_>;
1327
1328    /// Convert from [`Pin<&mut Tuple<T0, T1, T2, ..>`](Pin) to `Tuple<Pin<&mut T0>, Pin<&mut T1>, Pin<&mut T2>, ...>`.
1329    fn as_pin_mut(self: Pin<&mut Self>) -> Self::AsPinMutOutput<'_>;
1330
1331    /// Convert from `&Tuple<T0, T1, T2, ...>` to `Tuple<&T0::Target, &T1::Target, &T2::Target, ..>`
1332    /// while all the elements of the tuple implement [`Deref`](std::ops::Deref).
1333    ///
1334    /// # Example
1335    ///
1336    /// ```
1337    /// use tuplez::{tuple, TupleLike};
1338    ///
1339    /// let tup = tuple!(String::from("hello"), Box::new(12), vec![1, 2, 3]);
1340    /// assert_eq!(tup.as_deref(), tuple!("hello", &12, &[1, 2, 3] as &[_]));
1341    /// ```
1342    fn as_deref(&self) -> Self::AsDerefOutput<'_>
1343    where
1344        Self: AsDeref,
1345    {
1346        AsDeref::as_deref(self)
1347    }
1348
1349    /// Convert from `&mut Tuple<T0, T1, T2, ...>` to `Tuple<&mut T0::Target, &mut T1::Target, &mut T2::Target, ..>`
1350    /// while all the elements of the tuple implement [`DerefMut`](std::ops::DerefMut).
1351    ///
1352    /// # Example
1353    ///
1354    /// ```
1355    /// use tuplez::{tuple, TupleLike, tuple_t};
1356    ///
1357    /// let mut tup = tuple!(String::from("hello"), Box::new(12), vec![1, 2, 3]);
1358    /// let _: tuple_t!(&mut str, &mut i32, &mut [i32]) = tup.as_deref_mut();
1359    /// ```
1360    fn as_deref_mut(&mut self) -> Self::AsDerefMutOutput<'_>
1361    where
1362        Self: AsDerefMut,
1363    {
1364        AsDerefMut::as_deref_mut(self)
1365    }
1366
1367    /// If the elements of the tuple are all references, clone its elements to a new tuple.
1368    ///
1369    /// # Example:
1370    ///
1371    /// ```
1372    /// use tuplez::{tuple, TupleLike};
1373    ///
1374    /// let mut string = String::from("hello");
1375    /// let tup = tuple!(&1, &mut string, &3.14);
1376    /// assert_eq!(tup.cloned(), tuple!(1, String::from("hello"), 3.14));
1377    /// ```
1378    fn cloned(&self) -> Self::ClonedOutput
1379    where
1380        Self: Cloned,
1381    {
1382        Cloned::cloned(self)
1383    }
1384
1385    /// If the elements of the tuple are all references, copy its elements to a new tuple.
1386    ///
1387    /// # Example:
1388    ///
1389    /// ```
1390    /// use tuplez::{tuple, TupleLike};
1391    ///
1392    /// let mut ch = 'c';
1393    /// let tup = tuple!(&1, &mut ch, &3.14);
1394    /// assert_eq!(tup.copied(), tuple!(1, 'c', 3.14));
1395    /// ```
1396    fn copied(&self) -> Self::CopiedOutput
1397    where
1398        Self: Copied,
1399    {
1400        Copied::copied(self)
1401    }
1402
1403    /// If the elements of the tuple are all references, clone its elements to a new tuple.
1404    ///
1405    /// Much like [`cloned()`](TupleLike::cloned()), but can work on types like `&str` or slices.
1406    ///
1407    /// # Example:
1408    ///
1409    /// ```
1410    /// use tuplez::{tuple, TupleLike};
1411    ///
1412    /// let mut arr = [1, 2, 3];
1413    /// let tup = tuple!(&1, &mut arr as &mut [i32], "hello");
1414    /// assert_eq!(tup.owned(), tuple!(1, vec![1, 2, 3], "hello".to_string()));
1415    /// ```
1416    #[cfg(any(feature = "std", feature = "alloc"))]
1417    #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
1418    fn owned(&self) -> Self::OwnedOutput
1419    where
1420        Self: Owned,
1421    {
1422        Owned::owned(self)
1423    }
1424
1425    /// Push an element to the back of the tuple.
1426    ///
1427    /// # Examples
1428    ///
1429    /// ```
1430    /// use tuplez::{tuple, TupleLike};
1431    ///
1432    /// let tup = tuple!(1, "hello", 3.14);
1433    /// let tup2 = tup.push(44);
1434    /// assert_eq!(tup2, tuple!(1, "hello", 3.14, 44));
1435    /// ```
1436    fn push<T>(self, value: T) -> Self::PushBackOutput<T>;
1437
1438    /// Push an element to the front of the tuple.
1439    ///
1440    /// # Examples
1441    ///
1442    /// ```
1443    /// use tuplez::{tuple, TupleLike};
1444    ///
1445    /// let tup = tuple!(1, "hello", 3.14);
1446    /// let tup2 = tup.push_front(44);
1447    /// assert_eq!(tup2, tuple!(44, 1, "hello", 3.14));
1448    /// ```
1449    fn push_front<T>(self, value: T) -> Self::PushFrontOutput<T>;
1450
1451    /// Push an element to the back of the tuple. Same as [`push()`](TupleLike::push()).
1452    fn push_back<T>(self, value: T) -> Self::PushBackOutput<T>;
1453
1454    /// Pop an element from the back of the tuple.
1455    ///
1456    /// Note: The [`Unit`] type is not [`Poppable`].
1457    ///
1458    /// # Examples
1459    ///
1460    /// ```
1461    /// use tuplez::{tuple, TupleLike};
1462    ///
1463    /// let tup = tuple!(1, "hello", 3.14);
1464    /// let (tup2, popped) = tup.pop();
1465    /// assert_eq!(tup2, tuple!(1, "hello"));
1466    /// assert_eq!(popped, 3.14);
1467    /// ```
1468    fn pop(self) -> (Self::PopBackOutput, Self::PopBackElement)
1469    where
1470        Self: Poppable + Sized,
1471    {
1472        Poppable::pop(self)
1473    }
1474
1475    /// Pop an element from the front of the tuple.
1476    ///
1477    /// Note: The [`Unit`] type is not [`Poppable`].
1478    ///
1479    /// # Examples
1480    ///
1481    /// ```
1482    /// use tuplez::{tuple, TupleLike};
1483    ///
1484    /// let tup = tuple!(1, "hello", 3.14);
1485    /// let (tup2, popped) = tup.pop_front();
1486    /// assert_eq!(tup2, tuple!("hello", 3.14));
1487    /// assert_eq!(popped, 1);
1488    /// ```
1489    fn pop_front(self) -> (Self::PopFrontOutput, Self::PopFrontElement)
1490    where
1491        Self: Poppable + Sized,
1492    {
1493        Poppable::pop_front(self)
1494    }
1495
1496    /// Pop an element from the back of the tuple. Same as [`pop()`](TupleLike::pop()).
1497    ///
1498    /// Note: The [`Unit`] type is not [`Poppable`].
1499    fn pop_back(self) -> (Self::PopBackOutput, Self::PopBackElement)
1500    where
1501        Self: Poppable + Sized,
1502    {
1503        Poppable::pop_back(self)
1504    }
1505
1506    /// Left rotates the elements of the tuple.
1507    ///
1508    /// # Examples
1509    ///
1510    /// ```
1511    /// use tuplez::{tuple, TupleLike};
1512    ///
1513    /// let tup = tuple!(1, "2", 3.0, 4);
1514    /// let tup2 = tup.rot_l();
1515    /// assert_eq!(tup2, tuple!("2", 3.0, 4, 1));
1516    /// ```
1517    fn rot_l(self) -> Self::RotLeftOutput
1518    where
1519        Self: Rotatable + Sized,
1520    {
1521        Rotatable::rot_l(self)
1522    }
1523
1524    /// Right rotates the elements of the tuple.
1525    ///
1526    /// # Examples
1527    ///
1528    /// ```
1529    /// use tuplez::{tuple, TupleLike};
1530    ///
1531    /// let tup = tuple!(1, "2", 3.0, 4);
1532    /// let tup2 = tup.rot_r();
1533    /// assert_eq!(tup2, tuple!(4, 1, "2", 3.0));
1534    /// ```
1535    fn rot_r(self) -> Self::RotRightOutput
1536    where
1537        Self: Rotatable + Sized,
1538    {
1539        Rotatable::rot_r(self)
1540    }
1541
1542    /// Reverse elements of the tuple.
1543    ///
1544    /// # Examples
1545    ///
1546    /// ```
1547    /// use tuplez::{tuple, TupleLike};
1548    ///
1549    /// let tup = tuple!(1, "hello", 3.14);
1550    /// let tup2 = tup.rev();
1551    /// assert_eq!(tup2, tuple!(3.14, "hello", 1));
1552    /// ```
1553    fn rev(self) -> Self::RevOutput;
1554
1555    /// Join two tuples.
1556    ///
1557    /// # Examples
1558    ///
1559    /// ```
1560    /// use tuplez::{tuple, TupleLike};
1561    ///
1562    /// let tup = tuple!(1, "hello", 3.14);
1563    /// let tup2 = tuple!(44, "world");
1564    /// let tup3 = tup.join(tup2);
1565    /// assert_eq!(tup3, tuple!(1, "hello", 3.14, 44, "world"));
1566    /// ```
1567    fn join<T>(self, value: T) -> Self::JoinOutput<T>
1568    where
1569        T: TupleLike;
1570
1571    /// Convert from `tuple!(a, b, c ...)` to `tuple!(Some(a), Some(b), Some(c) ...)`.
1572    ///
1573    /// See [`unwrap()`](TupleLike::unwrap()),
1574    /// [`unwrap_or_default()`](TupleLike::unwrap_or_default())
1575    /// or [`try_unwrap()`](TupleLike::try_unwrap()) for the opposite operation.
1576    ///
1577    /// # Example
1578    ///
1579    /// ```
1580    /// use tuplez::{tuple, TupleLike};
1581    ///
1582    /// let tup = tuple!(1, "hello", 3.14);
1583    /// assert_eq!(tup.to_some(), tuple!(Some(1), Some("hello"), Some(3.14)));
1584    /// ```
1585    fn to_some(self) -> Self::ToSomeOutput;
1586
1587    /// Convert from `tuple!(a, b, c ...)` to `tuple!(Ok(a), Ok(b), Ok(c) ...)`.
1588    ///
1589    /// Note: You need to provide the error type.
1590    ///
1591    /// See [`unwrap()`](TupleLike::unwrap()),
1592    /// [`unwrap_or_default()`](TupleLike::unwrap_or_default())
1593    /// or [`try_unwrap()`](TupleLike::try_unwrap()) for the opposite operation.
1594    ///
1595    /// # Example
1596    ///
1597    /// ```
1598    /// use tuplez::{tuple, TupleLike};
1599    ///
1600    /// let tup = tuple!(1, "hello", 3.14);
1601    /// assert_eq!(tup.to_ok::<()>(), tuple!(Ok(1), Ok("hello"), Ok(3.14)));
1602    /// ```
1603    fn to_ok<E>(self) -> Self::ToOkOutput<E>;
1604
1605    /// Convert from `tuple!(a, b, c ...)` to `tuple!(tuple!(a), tuple!(b), tuple!(c) ...)`.
1606    ///
1607    /// See [`untuple()`](TupleLike::untuple()) for the opposite operation.
1608    ///
1609    /// # Example
1610    ///
1611    /// ```
1612    /// use tuplez::{tuple, TupleLike};
1613    ///
1614    /// let tup = tuple!(1, "hello", 3.14);
1615    /// assert_eq!(tup.to_tuple(), tuple!(tuple!(1), tuple!("hello"), tuple!(3.14)));
1616    /// ```
1617    fn to_tuple(self) -> Self::ToTupleOutput;
1618
1619    /// Create a new tuple that all elements are wrapped by [`MaybeUninit`](std::mem::MaybeUninit)
1620    /// and in uninitialized states.
1621    ///
1622    /// Similar to [`MaybeUninit::uninit()`](std::mem::MaybeUninit::uninit()), dropping a tuple with uninitialized elements
1623    /// will never call elements' drop codes. It is your responsibility to make sure elements get dropped if they got initialized.
1624    ///
1625    /// # Example
1626    ///
1627    /// ```
1628    /// use std::mem::MaybeUninit;
1629    /// use tuplez::{TupleLike, tuple_t};
1630    ///
1631    /// let uninit = <tuple_t!(i32, &str, Vec<String>)>::uninit();
1632    /// let _: tuple_t!(MaybeUninit<i32>, MaybeUninit<&str>, MaybeUninit<Vec<String>>) = uninit;
1633    /// ```
1634    #[cfg(feature = "uninit")]
1635    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
1636    fn uninit() -> Self::Uninit;
1637
1638    /// Create a new tuple that all elements are wrapped by [`MaybeUninit`](std::mem::MaybeUninit)
1639    /// and in uninitialized states, with the memory being filled with `0` bytes.
1640    ///
1641    /// Similar to [`MaybeUninit::zeroed()`](std::mem::MaybeUninit::zeroed()), dropping a tuple with uninitialized elements
1642    /// will never call elements' drop codes. It is your responsibility to make sure elements get dropped if they got initialized.
1643    ///
1644    /// ```
1645    /// use std::mem::MaybeUninit;
1646    /// use tuplez::{tuple, TupleLike, tuple_t};
1647    ///
1648    /// let uninit = <tuple_t!(i32, bool, *const u8)>::zeroed();
1649    /// let tup = unsafe { uninit.uninit_assume_init() };
1650    /// assert_eq!(tup, tuple!(0, false, std::ptr::null()));
1651    /// ```
1652    #[cfg(feature = "uninit")]
1653    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
1654    fn zeroed() -> Self::Uninit;
1655
1656    /// Convert from `tuple!(a, b, c ...)` to `tuple!(MaybeUninit::new(a), MaybeUninit::new(b), MaybeUninit::new(c) ...)`.
1657    ///
1658    /// See [`uninit_assume_init()`](TupleLike::uninit_assume_init()) for the opposite operation.
1659    ///
1660    /// # Example
1661    ///
1662    /// ```
1663    /// use tuplez::{tuple, TupleLike};
1664    ///
1665    /// let uninit = tuple!(1, "hello", 3.14).to_uninit();
1666    /// let tup = unsafe { uninit.uninit_assume_init() };
1667    /// assert_eq!(tup, tuple!(1, "hello", 3.14));
1668    /// ```
1669    #[cfg(feature = "uninit")]
1670    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
1671    fn to_uninit(self) -> Self::Uninit;
1672
1673    /// Extract the values of a tuple consisting of [`MaybeUninit`](std::mem::MaybeUninit) elements.
1674    ///
1675    /// # Safety
1676    ///
1677    /// Same as [`MaybeUninit::assume_init()`](std::mem::MaybeUninit::assume_init()).
1678    ///
1679    /// # Example
1680    ///
1681    /// ```
1682    /// use tuplez::{tuple, TupleLike, tuple_t};
1683    ///
1684    /// let mut uninit = <tuple_t!(i32, bool, &str)>::uninit();
1685    /// uninit.uninit_write_one(12);
1686    /// uninit.uninit_write_one(true);
1687    /// uninit.uninit_write_one("hello");
1688    /// let tup = unsafe { uninit.uninit_assume_init() };
1689    /// assert_eq!(tup, tuple!(12, true, "hello"));
1690    /// ```
1691    #[cfg(feature = "uninit")]
1692    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
1693    unsafe fn uninit_assume_init(self) -> Self::Initialized
1694    where
1695        Self: Uninit + Sized,
1696    {
1697        Uninit::assume_init(self)
1698    }
1699
1700    /// Extract value from a specific [`MaybeUninit`](std::mem::MaybeUninit) element.
1701    ///
1702    /// # Safety
1703    ///
1704    /// Same as [`MaybeUninit::assume_init()`](std::mem::MaybeUninit::assume_init()).
1705    ///
1706    /// ```
1707    /// use std::mem::MaybeUninit;
1708    /// use tuplez::{get, tuple, TupleLike, tuple_t};
1709    ///
1710    /// let mut uninit = <tuple_t!(i32, bool, &str)>::uninit();
1711    /// uninit.uninit_write_one(12);
1712    /// let first_init = unsafe { uninit.uninit_assume_init_one::<i32, _>() };
1713    /// assert_eq!(get!(first_init; 0), 12);
1714    /// let _: tuple_t!(i32, MaybeUninit<bool>, MaybeUninit<&str>) = first_init;
1715    /// ```
1716    #[cfg(feature = "uninit")]
1717    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
1718    unsafe fn uninit_assume_init_one<T, I>(self) -> Self::MapReplaceOutput<T>
1719    where
1720        Self: Search<MaybeUninit<T>, I> + Sized,
1721    {
1722        Search::map_replace(self, |x| x.assume_init())
1723    }
1724
1725    /// Read the values of a tuple consisting of [`MaybeUninit`](std::mem::MaybeUninit) elements.
1726    ///
1727    /// # Safety
1728    ///
1729    /// Same as [`MaybeUninit::assume_init_read()`](std::mem::MaybeUninit::assume_init_read()).
1730    ///
1731    /// # Example
1732    ///
1733    /// ```
1734    /// use tuplez::{tuple, TupleLike, tuple_t};
1735    ///
1736    /// let mut uninit = <tuple_t!(i32, Option<Vec<u32>>)>::uninit();
1737    /// uninit.uninit_write_one(12);
1738    /// uninit.uninit_write_one(None);
1739    /// let tup1 = unsafe { uninit.uninit_assume_init_read() };
1740    /// // SAFETY: `i32` implements `Copy`, duplicating a `None` value is safe.
1741    /// let tup2 = unsafe { uninit.uninit_assume_init_read() };
1742    /// assert_eq!(tup1, tup2);
1743    /// ```
1744    #[cfg(feature = "uninit")]
1745    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
1746    unsafe fn uninit_assume_init_read(&self) -> Self::Initialized
1747    where
1748        Self: Uninit,
1749    {
1750        Uninit::assume_init_read(self)
1751    }
1752
1753    /// Read one value from a specific [`MaybeUninit`] element.
1754    ///
1755    /// # Safety
1756    ///
1757    /// Same as [`MaybeUninit::assume_init_read()`](std::mem::MaybeUninit::assume_init_read()).
1758    ///
1759    /// # Example
1760    ///
1761    /// ```
1762    /// use std::mem::MaybeUninit;
1763    /// use tuplez::{tuple, TupleLike};
1764    ///
1765    /// let tup = tuple!(
1766    ///     0,
1767    ///     MaybeUninit::<i32>::new(12),
1768    ///     "hello",
1769    ///     MaybeUninit::<f64>::uninit(),
1770    ///     24
1771    /// );
1772    /// let x: i32 = unsafe { tup.uninit_assume_init_read_one() };
1773    /// assert_eq!(x, 12);
1774    /// ```
1775    #[cfg(feature = "uninit")]
1776    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
1777    unsafe fn uninit_assume_init_read_one<T, I>(&self) -> T
1778    where
1779        Self: Search<MaybeUninit<T>, I>,
1780    {
1781        Search::get_ref(self).assume_init_read()
1782    }
1783
1784    /// Get immutable references to values of a tuple consisting of [`MaybeUninit`](std::mem::MaybeUninit) elements.
1785    ///
1786    /// # Safety
1787    ///
1788    /// Same as [`MaybeUninit::assume_init_ref()`](std::mem::MaybeUninit::assume_init_ref()).
1789    ///
1790    /// # Example
1791    ///
1792    /// ```
1793    /// use tuplez::{get, tuple, TupleLike, tuple_t};
1794    ///
1795    /// let mut uninit = <tuple_t!(i32, Vec<i32>)>::uninit();
1796    /// uninit.uninit_write_one(12);
1797    /// uninit.uninit_write_one(vec![1, 2, 3]);
1798    /// let tup_ref = unsafe { uninit.uninit_assume_init_ref() };
1799    /// assert_eq!(get!(tup_ref; 0), &12);
1800    /// assert_eq!(get!(tup_ref; 1), &vec![1, 2, 3]);
1801    /// unsafe { uninit.uninit_assume_init_drop(); }
1802    /// ```
1803    #[cfg(feature = "uninit")]
1804    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
1805    unsafe fn uninit_assume_init_ref(&self) -> <Self::Initialized as TupleLike>::AsRefOutput<'_>
1806    where
1807        Self: Uninit,
1808    {
1809        Uninit::assume_init_ref(self)
1810    }
1811
1812    /// Get immutable reference to value of a specific [`MaybeUninit`](std::mem::MaybeUninit) element.
1813    ///
1814    /// # Safety
1815    ///
1816    /// Same as [`MaybeUninit::assume_init_ref()`](std::mem::MaybeUninit::assume_init_ref()).
1817    ///
1818    /// # Example
1819    ///
1820    /// ```
1821    /// use std::mem::MaybeUninit;
1822    /// use tuplez::{get, tuple, TupleLike, tuple_t};
1823    ///
1824    /// let mut tup = tuple!(MaybeUninit::<Vec<i32>>::uninit(), "hello", 12);
1825    /// tup.uninit_write_one(vec![1, 2, 3]);
1826    /// let v = unsafe { tup.uninit_assume_init_ref_one::<Vec<i32>, _>() };
1827    /// assert_eq!(v, &vec![1, 2, 3]);
1828    /// unsafe { tup.uninit_assume_init_drop_one::<Vec<i32>, _>(); }
1829    /// ```
1830    #[cfg(feature = "uninit")]
1831    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
1832    unsafe fn uninit_assume_init_ref_one<T, I>(&self) -> &T
1833    where
1834        Self: Search<MaybeUninit<T>, I>,
1835    {
1836        Search::get_ref(self).assume_init_ref()
1837    }
1838
1839    /// Get mutable references to values of a tuple consisting of [`MaybeUninit`](std::mem::MaybeUninit) elements.
1840    ///
1841    /// # Safety
1842    ///
1843    /// Same as [`MaybeUninit::assume_init_mut()`](std::mem::MaybeUninit::assume_init_mut()).
1844    ///
1845    /// # Example
1846    ///
1847    /// ```
1848    /// use tuplez::{get, tuple, TupleLike, tuple_t};
1849    ///
1850    /// let mut uninit = <tuple_t!(i32, Vec<i32>)>::uninit();
1851    /// uninit.uninit_write_one(12);
1852    /// uninit.uninit_write_one(vec![1, 2, 3]);
1853    /// let tup_mut = unsafe { uninit.uninit_assume_init_mut() };
1854    /// *get!(tup_mut; 0) += 1;
1855    /// get!(tup_mut; 1).push(4);
1856    /// let tup = unsafe { uninit.uninit_assume_init() };
1857    /// assert_eq!(tup, tuple!(13, vec![1, 2, 3, 4]));
1858    /// ```
1859    #[cfg(feature = "uninit")]
1860    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
1861    unsafe fn uninit_assume_init_mut(&mut self) -> <Self::Initialized as TupleLike>::AsMutOutput<'_>
1862    where
1863        Self: Uninit,
1864    {
1865        Uninit::assume_init_mut(self)
1866    }
1867
1868    /// Get mutable reference to value of a specific [`MaybeUninit`](std::mem::MaybeUninit) element.
1869    ///
1870    /// # Safety
1871    ///
1872    /// Same as [`MaybeUninit::assume_init_mut()`](std::mem::MaybeUninit::assume_init_mut()).
1873    ///
1874    /// # Example
1875    ///
1876    /// ```
1877    /// use std::mem::MaybeUninit;
1878    /// use tuplez::{get, tuple, TupleLike, tuple_t};
1879    ///
1880    /// let mut tup = tuple!(MaybeUninit::<Vec<i32>>::uninit(), "hello", 12);
1881    /// tup.uninit_write_one(vec![1, 2, 3]);
1882    /// let v = unsafe { tup.uninit_assume_init_mut_one::<Vec<i32>, _>() };
1883    /// v.push(4);
1884    /// assert_eq!(v, &vec![1, 2, 3, 4]);
1885    /// unsafe { tup.uninit_assume_init_drop_one::<Vec<i32>, _>(); }
1886    /// ```
1887    #[cfg(feature = "uninit")]
1888    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
1889    unsafe fn uninit_assume_init_mut_one<T, I>(&mut self) -> &mut T
1890    where
1891        Self: Search<MaybeUninit<T>, I>,
1892    {
1893        Search::get_mut(self).assume_init_mut()
1894    }
1895
1896    /// Drop values in place for a tuple consisting of [`MaybeUninit`](std::mem::MaybeUninit) elements.
1897    ///
1898    /// # Safety
1899    ///
1900    /// Same as [`MaybeUninit::assume_init_drop()`](std::mem::MaybeUninit::assume_init_drop()).
1901    #[cfg(feature = "uninit")]
1902    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
1903    unsafe fn uninit_assume_init_drop(&mut self)
1904    where
1905        Self: Uninit,
1906    {
1907        Uninit::assume_init_drop(self)
1908    }
1909
1910    /// Drop value in place for a specific [`MaybeUninit`](std::mem::MaybeUninit) element.
1911    ///
1912    /// # Safety
1913    ///
1914    /// Same as [`MaybeUninit::assume_init_drop()`](std::mem::MaybeUninit::assume_init_drop()).
1915    #[cfg(feature = "uninit")]
1916    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
1917    unsafe fn uninit_assume_init_drop_one<T, I>(&mut self)
1918    where
1919        Self: Search<MaybeUninit<T>, I>,
1920    {
1921        Search::get_mut(self).assume_init_drop()
1922    }
1923
1924    /// Get points to values of a tuple consisting of [`MaybeUninit`](std::mem::MaybeUninit) elements.
1925    ///
1926    /// # Example
1927    ///
1928    /// ```
1929    /// use tuplez::{get, TupleLike, tuple_t};
1930    ///
1931    /// let mut uninit = <tuple_t!(i32, Vec<i32>)>::uninit();
1932    /// uninit.uninit_write_one(12);
1933    /// uninit.uninit_write_one(vec![1, 2, 3]);
1934    /// let v = unsafe { &*get!(uninit.uninit_as_ptr(); 1) };
1935    /// assert_eq!(v.len(), 3);
1936    /// unsafe { uninit.uninit_assume_init_drop(); }
1937    /// ```
1938    #[cfg(feature = "uninit")]
1939    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
1940    fn uninit_as_ptr(&self) -> <Self::Initialized as TupleLike>::AsPtrOutput
1941    where
1942        Self: Uninit,
1943    {
1944        Uninit::as_ptr(self)
1945    }
1946
1947    /// Get mutable points to values of a tuple consisting of [`MaybeUninit`](std::mem::MaybeUninit) elements.
1948    ///
1949    /// # Example
1950    ///
1951    /// ```
1952    /// use tuplez::{get, TupleLike, tuple_t};
1953    ///
1954    /// let mut uninit = <tuple_t!(i32, Vec<i32>)>::uninit();
1955    /// uninit.uninit_write_one(12);
1956    /// uninit.uninit_write_one(vec![1, 2, 3]);
1957    /// let v = unsafe { &mut *get!(uninit.uninit_as_mut_ptr(); 1) };
1958    /// v.push(4);
1959    /// assert_eq!(v.len(), 4);
1960    /// unsafe { uninit.uninit_assume_init_drop(); }
1961    /// ```
1962    #[cfg(feature = "uninit")]
1963    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
1964    fn uninit_as_mut_ptr(&mut self) -> <Self::Initialized as TupleLike>::AsMutPtrOutput
1965    where
1966        Self: Uninit,
1967    {
1968        Uninit::as_mut_ptr(self)
1969    }
1970
1971    /// Set value to a specific [`MaybeUninit`](std::mem::MaybeUninit) element in a tuple.
1972    ///
1973    /// **NOTE**: The type of this element must exist only once in the tuple.
1974    ///
1975    /// Similar to [`MaybeUninit::write()`](std::mem::MaybeUninit::write()),
1976    /// this overwrites any previous value without dropping it.
1977    ///
1978    /// # Example
1979    ///
1980    /// ```
1981    /// use std::mem::MaybeUninit;
1982    /// use tuplez::{tuple, TupleLike, tuple_t};
1983    ///
1984    /// let mut uninit = <tuple_t!(i32, bool, &str)>::uninit();
1985    /// uninit.uninit_write_one(12);
1986    /// uninit.uninit_write_one(true);
1987    /// uninit.uninit_write_one("hello");
1988    /// let tup = unsafe { uninit.uninit_assume_init() };
1989    /// assert_eq!(tup, tuple!(12, true, "hello"));
1990    ///
1991    /// let mut tup = tuple!(
1992    ///     0,
1993    ///     MaybeUninit::<i32>::uninit(),
1994    ///     "hello",
1995    ///     MaybeUninit::<f64>::uninit(),
1996    ///     24
1997    /// );
1998    /// let x = unsafe { tup.uninit_write_one(12) };
1999    /// assert_eq!(x, &12);
2000    /// ```
2001    #[cfg(feature = "uninit")]
2002    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
2003    fn uninit_write_one<T, I>(&mut self, value: T) -> &mut T
2004    where
2005        Self: Search<MaybeUninit<T>, I>,
2006    {
2007        Search::get_mut(self).write(value)
2008    }
2009
2010    /// Set values to a tuple consisting of [`MaybeUninit`](std::mem::MaybeUninit) elements.
2011    ///
2012    /// Similar to [`MaybeUninit::write()`](std::mem::MaybeUninit::write()),
2013    /// this overwrites any previous value without dropping it.
2014    ///
2015    /// # Example
2016    ///
2017    /// ```
2018    /// use tuplez::{tuple, TupleLike, tuple_t};
2019    ///
2020    /// let mut uninit = <tuple_t!(i32, bool, &str)>::uninit();
2021    /// uninit.uninit_write(tuple!(12, true, "hello"));
2022    /// let tup = unsafe { uninit.uninit_assume_init() };
2023    /// assert_eq!(tup, tuple!(12, true, "hello"));
2024    /// ```
2025    #[cfg(feature = "uninit")]
2026    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
2027    fn uninit_write(
2028        &mut self,
2029        init: Self::Initialized,
2030    ) -> <Self::Initialized as TupleLike>::AsMutOutput<'_>
2031    where
2032        Self: Uninit,
2033    {
2034        Uninit::write(self, init)
2035    }
2036
2037    /// Extract values of a specific subsequence consisting of [`MaybeUninit`] elements.
2038    ///
2039    /// # Safety
2040    ///
2041    /// Same as [`MaybeUninit::assume_init()`](MaybeUninit::assume_init()).
2042    ///
2043    /// # Example
2044    ///
2045    /// ```
2046    /// use std::mem::MaybeUninit;
2047    /// use tuplez::{get, tuple, TupleLike, tuple_t};
2048    ///
2049    /// let mut tup = tuple!(
2050    ///     12,
2051    ///     MaybeUninit::<i32>::zeroed(),
2052    ///     MaybeUninit::<&str>::uninit(),
2053    ///     MaybeUninit::<Vec<i32>>::uninit(),
2054    ///     false,
2055    /// );
2056    /// tup.uninit_write_one(vec![1, 2, 3]);
2057    /// let part_init = unsafe {
2058    ///     tup.uninit_assume_init_subseq::<tuple_t!(i32, Vec<i32>), _>()
2059    /// };
2060    /// assert_eq!(get!(part_init; 1), 0);
2061    /// assert_eq!(get!(part_init; 3), vec![1, 2, 3]);
2062    /// let _: tuple_t!(i32, i32, MaybeUninit<&str>, Vec<i32>, bool) = part_init;
2063    /// ```
2064    #[cfg(feature = "uninit")]
2065    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
2066    unsafe fn uninit_assume_init_subseq<Seq, I>(self) -> Self::PartiallyInitialized
2067    where
2068        Seq: TupleLike,
2069        Self: UninitSubseq<Seq, I> + Sized,
2070    {
2071        UninitSubseq::assume_init_subseq(self)
2072    }
2073
2074    /// Read the values of a specific subsequence consisting of [`MaybeUninit`] elements.
2075    ///
2076    /// # Safety
2077    ///
2078    /// Same as [`MaybeUninit::assume_init_read()`](MaybeUninit::assume_init_read()).
2079    ///
2080    /// # Example
2081    ///
2082    /// ```
2083    /// use std::mem::MaybeUninit;
2084    /// use tuplez::{tuple, TupleLike, tuple_t};
2085    ///
2086    /// let mut tup = tuple!(
2087    ///     12,
2088    ///     MaybeUninit::<i32>::zeroed(),
2089    ///     MaybeUninit::<&str>::uninit(),
2090    ///     MaybeUninit::<Vec<i32>>::uninit(),
2091    ///     false,
2092    /// );
2093    /// tup.uninit_write_one(vec![1, 2, 3]);
2094    /// let inited = unsafe {
2095    ///     tup.uninit_assume_init_read_subseq::<tuple_t!(i32, Vec<i32>), _>()
2096    /// };
2097    /// assert_eq!(inited, tuple!(0, vec![1, 2, 3]));
2098    /// ```
2099    #[cfg(feature = "uninit")]
2100    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
2101    unsafe fn uninit_assume_init_read_subseq<Seq, I>(&self) -> Seq
2102    where
2103        Seq: TupleLike,
2104        Self: UninitSubseq<Seq, I>,
2105    {
2106        UninitSubseq::assume_init_read_subseq(self)
2107    }
2108
2109    /// Get immutable references to values of a specific subsequence
2110    /// consisting of [`MaybeUninit`] elements.
2111    ///
2112    /// # Safety
2113    ///
2114    /// Same as [`MaybeUninit::assume_init_ref()`](MaybeUninit::assume_init_ref()).
2115    ///
2116    /// # Example
2117    ///
2118    /// ```
2119    /// use std::mem::MaybeUninit;
2120    /// use tuplez::{tuple, TupleLike, tuple_t};
2121    ///
2122    /// let mut tup = tuple!(
2123    ///     12,
2124    ///     MaybeUninit::<i32>::zeroed(),
2125    ///     MaybeUninit::<&str>::uninit(),
2126    ///     MaybeUninit::<Vec<i32>>::uninit(),
2127    ///     false,
2128    /// );
2129    /// tup.uninit_write_one(vec![1, 2, 3]);
2130    /// let inited_ref = unsafe {
2131    ///     tup.uninit_assume_init_ref_subseq::<tuple_t!(i32, Vec<i32>), _>()
2132    /// };
2133    /// assert_eq!(inited_ref, tuple!(&0, &vec![1, 2, 3]));
2134    /// unsafe { tup.uninit_assume_init_drop_subseq::<tuple_t!(i32, Vec<i32>), _>() };
2135    /// ```
2136    #[cfg(feature = "uninit")]
2137    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
2138    unsafe fn uninit_assume_init_ref_subseq<Seq, I>(&self) -> <Seq as TupleLike>::AsRefOutput<'_>
2139    where
2140        Seq: TupleLike,
2141        Self: UninitSubseq<Seq, I>,
2142    {
2143        UninitSubseq::assume_init_ref_subseq(self)
2144    }
2145
2146    /// Get mutable references to values of a specific subsequence
2147    /// consisting of [`MaybeUninit`] elements.
2148    ///
2149    /// # Safety
2150    ///
2151    /// Same as [`MaybeUninit::assume_init_mut()`](MaybeUninit::assume_init_mut()).
2152    ///
2153    /// # Example
2154    ///
2155    /// ```
2156    /// use std::mem::MaybeUninit;
2157    /// use tuplez::{get, tuple, TupleLike, tuple_t};
2158    ///
2159    /// let mut tup = tuple!(
2160    ///     12,
2161    ///     MaybeUninit::<i32>::zeroed(),
2162    ///     MaybeUninit::<&str>::uninit(),
2163    ///     MaybeUninit::<Vec<i32>>::uninit(),
2164    ///     false,
2165    /// );
2166    /// tup.uninit_write_one(vec![1, 2, 3]);
2167    /// let inited_mut = unsafe {
2168    ///     tup.uninit_assume_init_mut_subseq::<tuple_t!(i32, Vec<i32>), _>()
2169    /// };
2170    /// *get!(inited_mut; 0) += 1;
2171    /// get!(inited_mut; 1).push(4);
2172    /// assert_eq!(inited_mut, tuple!(&mut 1, &mut vec![1, 2, 3, 4]));
2173    /// unsafe { tup.uninit_assume_init_drop_subseq::<tuple_t!(i32, Vec<i32>), _>() };
2174    /// ```
2175    #[cfg(feature = "uninit")]
2176    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
2177    unsafe fn uninit_assume_init_mut_subseq<Seq, I>(
2178        &mut self,
2179    ) -> <Seq as TupleLike>::AsMutOutput<'_>
2180    where
2181        Seq: TupleLike,
2182        Self: UninitSubseq<Seq, I>,
2183    {
2184        UninitSubseq::assume_init_mut_subseq(self)
2185    }
2186
2187    /// Get pointers to values of a specific subsequence
2188    /// consisting of [`MaybeUninit`] elements.
2189    ///
2190    /// # Example
2191    ///
2192    /// ```
2193    /// use std::mem::MaybeUninit;
2194    /// use tuplez::{get, tuple, TupleLike, tuple_t};
2195    ///
2196    /// let mut tup = tuple!(
2197    ///     12,
2198    ///     MaybeUninit::<i32>::zeroed(),
2199    ///     MaybeUninit::<&str>::uninit(),
2200    ///     MaybeUninit::<Vec<i32>>::uninit(),
2201    ///     false,
2202    /// );
2203    /// tup.uninit_write_one(vec![1, 2, 3]);
2204    /// let inited_ptr = tup.uninit_subseq_as_ptr::<tuple_t!(i32, Vec<i32>), _>();
2205    /// unsafe {
2206    ///     assert_eq!(*get!(inited_ptr; 0), 0);
2207    ///     assert_eq!(*get!(inited_ptr; 1), vec![1, 2, 3]);
2208    ///     tup.uninit_assume_init_drop_subseq::<tuple_t!(i32, Vec<i32>), _>();
2209    /// }
2210    /// ```
2211    #[cfg(feature = "uninit")]
2212    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
2213    fn uninit_subseq_as_ptr<Seq, I>(&self) -> <Seq as TupleLike>::AsPtrOutput
2214    where
2215        Seq: TupleLike,
2216        Self: UninitSubseq<Seq, I>,
2217    {
2218        UninitSubseq::subseq_as_ptr(self)
2219    }
2220
2221    /// Get mutable pointers to values of a specific subsequence
2222    /// consisting of [`MaybeUninit`] elements.
2223    ///
2224    /// # Example
2225    ///
2226    /// ```
2227    /// use std::mem::MaybeUninit;
2228    /// use tuplez::{get, tuple, TupleLike, tuple_t};
2229    ///
2230    /// let mut tup = tuple!(
2231    ///     12,
2232    ///     MaybeUninit::<i32>::zeroed(),
2233    ///     MaybeUninit::<&str>::uninit(),
2234    ///     MaybeUninit::<Vec<i32>>::uninit(),
2235    ///     false,
2236    /// );
2237    /// tup.uninit_write_one(vec![1, 2, 3]);
2238    /// let inited_ptr = tup.uninit_subseq_as_mut_ptr::<tuple_t!(i32, Vec<i32>), _>();
2239    /// unsafe {
2240    ///     *get!(inited_ptr; 0) += 1;
2241    ///     (*get!(inited_ptr; 1)).push(4);
2242    ///     assert_eq!(*get!(inited_ptr; 0), 1);
2243    ///     assert_eq!(*get!(inited_ptr; 1), vec![1, 2, 3, 4]);
2244    ///     tup.uninit_assume_init_drop_subseq::<tuple_t!(i32, Vec<i32>), _>();
2245    /// }
2246    /// ```
2247    #[cfg(feature = "uninit")]
2248    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
2249    fn uninit_subseq_as_mut_ptr<Seq, I>(&mut self) -> <Seq as TupleLike>::AsMutPtrOutput
2250    where
2251        Seq: TupleLike,
2252        Self: UninitSubseq<Seq, I>,
2253    {
2254        UninitSubseq::subseq_as_mut_ptr(self)
2255    }
2256
2257    /// Set values to a subsequence consisting of [`MaybeUninit`](std::mem::MaybeUninit) elements.
2258    ///
2259    /// **NOTE**: The subsequence must have one and only one candidate in the supersequence.
2260    ///
2261    /// Similar to [`MaybeUninit::write()`](std::mem::MaybeUninit::write()),
2262    /// this overwrites any previous value without dropping it.
2263    ///
2264    /// # Example
2265    ///
2266    /// ```
2267    /// use tuplez::{tuple, TupleLike, tuple_t};
2268    ///
2269    /// let mut uninit = <tuple_t!(i32, bool, &str)>::uninit();
2270    /// uninit.uninit_write_one(true);
2271    /// uninit.uninit_write_subseq(tuple!(12, "hello"));
2272    /// let tup = unsafe { uninit.uninit_assume_init() };
2273    /// assert_eq!(tup, tuple!(12, true, "hello"));
2274    /// ```
2275    #[cfg(feature = "uninit")]
2276    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
2277    fn uninit_write_subseq<Seq, I>(&mut self, subseq: Seq) -> Seq::AsMutOutput<'_>
2278    where
2279        Seq: TupleLike,
2280        Self: UninitSubseq<Seq, I>,
2281    {
2282        UninitSubseq::write_subseq(self, subseq)
2283    }
2284
2285    /// Drop values in place for a subsequence consisting of [`MaybeUninit`](std::mem::MaybeUninit) elements.
2286    ///
2287    /// **NOTE**: The subsequence must have one and only one candidate in the supersequence.
2288    ///
2289    /// # Safety
2290    ///
2291    /// Same as [`MaybeUninit::assume_init_drop()`](std::mem::MaybeUninit::assume_init_drop()).
2292    #[cfg(feature = "uninit")]
2293    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
2294    unsafe fn uninit_assume_init_drop_subseq<Seq, I>(&mut self)
2295    where
2296        Seq: TupleLike,
2297        Self: UninitSubseq<Seq, I>,
2298    {
2299        UninitSubseq::assume_init_drop_subseq(self)
2300    }
2301
2302    /// Extract values of a specific contiguous subsequence consisting of [`MaybeUninit`] elements.
2303    ///
2304    /// # Safety
2305    ///
2306    /// Same as [`MaybeUninit::assume_init()`](MaybeUninit::assume_init()).
2307    ///
2308    /// # Example
2309    ///
2310    /// ```
2311    /// use std::mem::MaybeUninit;
2312    /// use tuplez::{get, tuple, TupleLike, tuple_t};
2313    ///
2314    /// let mut tup = tuple!(
2315    ///     12,
2316    ///     MaybeUninit::<i32>::zeroed(),
2317    ///     MaybeUninit::<i32>::new(13),
2318    ///     MaybeUninit::<Vec<i32>>::uninit(),
2319    ///     false,
2320    /// );
2321    /// tup.uninit_write_one(vec![1, 2, 3]);
2322    /// let part_init = unsafe {
2323    ///     tup.uninit_assume_init_con_subseq::<tuple_t!(i32, Vec<i32>), _>()
2324    /// };
2325    /// assert_eq!(get!(part_init; 2), 13);
2326    /// assert_eq!(get!(part_init; 3), vec![1, 2, 3]);
2327    /// let _: tuple_t!(i32, MaybeUninit<i32>, i32, Vec<i32>, bool) = part_init;
2328    /// ```
2329    #[cfg(feature = "uninit")]
2330    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
2331    unsafe fn uninit_assume_init_con_subseq<Seq, I>(self) -> Self::PartiallyInitialized
2332    where
2333        Seq: TupleLike,
2334        Self: UninitConSubseq<Seq, I> + Sized,
2335    {
2336        UninitConSubseq::assume_init_con_subseq(self)
2337    }
2338
2339    /// Read the values of a specific contiguous subsequence consisting of [`MaybeUninit`] elements.
2340    ///
2341    /// # Safety
2342    ///
2343    /// Same as [`MaybeUninit::assume_init_read()`](MaybeUninit::assume_init_read()).
2344    ///
2345    /// # Example
2346    ///
2347    /// ```
2348    /// use std::mem::MaybeUninit;
2349    /// use tuplez::{tuple, TupleLike, tuple_t};
2350    ///
2351    /// let mut tup = tuple!(
2352    ///     12,
2353    ///     MaybeUninit::<i32>::zeroed(),
2354    ///     MaybeUninit::<i32>::new(13),
2355    ///     MaybeUninit::<Vec<i32>>::uninit(),
2356    ///     false,
2357    /// );
2358    /// tup.uninit_write_one(vec![1, 2, 3]);
2359    /// let inited = unsafe {
2360    ///     tup.uninit_assume_init_read_con_subseq::<tuple_t!(i32, Vec<i32>), _>()
2361    /// };
2362    /// assert_eq!(inited, tuple!(13, vec![1, 2, 3]));
2363    /// ```
2364    #[cfg(feature = "uninit")]
2365    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
2366    unsafe fn uninit_assume_init_read_con_subseq<Seq, I>(&self) -> Seq
2367    where
2368        Seq: TupleLike,
2369        Self: UninitConSubseq<Seq, I>,
2370    {
2371        UninitConSubseq::assume_init_read_con_subseq(self)
2372    }
2373
2374    /// Get immutable references to values of a specific contiguous subsequence
2375    /// consisting of [`MaybeUninit`] elements.
2376    ///
2377    /// # Safety
2378    ///
2379    /// Same as [`MaybeUninit::assume_init_ref()`](MaybeUninit::assume_init_ref()).
2380    ///
2381    /// # Example
2382    ///
2383    /// ```
2384    /// use std::mem::MaybeUninit;
2385    /// use tuplez::{tuple, TupleLike, tuple_t};
2386    ///
2387    /// let mut tup = tuple!(
2388    ///     12,
2389    ///     MaybeUninit::<i32>::zeroed(),
2390    ///     MaybeUninit::<i32>::new(13),
2391    ///     MaybeUninit::<Vec<i32>>::uninit(),
2392    ///     false,
2393    /// );
2394    /// tup.uninit_write_one(vec![1, 2, 3]);
2395    /// let inited_ref = unsafe {
2396    ///     tup.uninit_assume_init_ref_con_subseq::<tuple_t!(i32, Vec<i32>), _>()
2397    /// };
2398    /// assert_eq!(inited_ref, tuple!(&13, &vec![1, 2, 3]));
2399    /// unsafe { tup.uninit_assume_init_drop_con_subseq::<tuple_t!(i32, Vec<i32>), _>() };
2400    /// ```
2401    #[cfg(feature = "uninit")]
2402    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
2403    unsafe fn uninit_assume_init_ref_con_subseq<Seq, I>(
2404        &self,
2405    ) -> <Seq as TupleLike>::AsRefOutput<'_>
2406    where
2407        Seq: TupleLike,
2408        Self: UninitConSubseq<Seq, I>,
2409    {
2410        UninitConSubseq::assume_init_ref_con_subseq(self)
2411    }
2412
2413    /// Get mutable references to values of a specific contiguous subsequence
2414    /// consisting of [`MaybeUninit`] elements.
2415    ///
2416    /// # Safety
2417    ///
2418    /// Same as [`MaybeUninit::assume_init_mut()`](MaybeUninit::assume_init_mut()).
2419    ///
2420    /// # Example
2421    ///
2422    /// ```
2423    /// use std::mem::MaybeUninit;
2424    /// use tuplez::{get, tuple, TupleLike, tuple_t};
2425    ///
2426    /// let mut tup = tuple!(
2427    ///     12,
2428    ///     MaybeUninit::<i32>::zeroed(),
2429    ///     MaybeUninit::<i32>::new(13),
2430    ///     MaybeUninit::<Vec<i32>>::uninit(),
2431    ///     false,
2432    /// );
2433    /// tup.uninit_write_one(vec![1, 2, 3]);
2434    /// let inited_mut = unsafe {
2435    ///     tup.uninit_assume_init_mut_con_subseq::<tuple_t!(i32, Vec<i32>), _>()
2436    /// };
2437    /// *get!(inited_mut; 0) += 1;
2438    /// get!(inited_mut; 1).push(4);
2439    /// assert_eq!(inited_mut, tuple!(&mut 14, &mut vec![1, 2, 3, 4]));
2440    /// unsafe { tup.uninit_assume_init_drop_con_subseq::<tuple_t!(i32, Vec<i32>), _>() };
2441    /// ```
2442    #[cfg(feature = "uninit")]
2443    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
2444    unsafe fn uninit_assume_init_mut_con_subseq<Seq, I>(
2445        &mut self,
2446    ) -> <Seq as TupleLike>::AsMutOutput<'_>
2447    where
2448        Seq: TupleLike,
2449        Self: UninitConSubseq<Seq, I>,
2450    {
2451        UninitConSubseq::assume_init_mut_con_subseq(self)
2452    }
2453    /// Get pointers to values of a specific contiguous subsequence
2454    /// consisting of [`MaybeUninit`] elements.
2455    ///
2456    /// # Example
2457    ///
2458    /// ```
2459    /// use std::mem::MaybeUninit;
2460    /// use tuplez::{get, tuple, TupleLike, tuple_t};
2461    ///
2462    /// let mut tup = tuple!(
2463    ///     12,
2464    ///     MaybeUninit::<i32>::zeroed(),
2465    ///     MaybeUninit::<i32>::new(13),
2466    ///     MaybeUninit::<Vec<i32>>::uninit(),
2467    ///     false,
2468    /// );
2469    /// tup.uninit_write_one(vec![1, 2, 3]);
2470    /// let inited_ptr = tup.uninit_con_subseq_as_ptr::<tuple_t!(i32, Vec<i32>), _>();
2471    /// unsafe {
2472    ///     assert_eq!(*get!(inited_ptr; 0), 13);
2473    ///     assert_eq!(*get!(inited_ptr; 1), vec![1, 2, 3]);
2474    ///     tup.uninit_assume_init_drop_con_subseq::<tuple_t!(i32, Vec<i32>), _>();
2475    /// }
2476    /// ```
2477    #[cfg(feature = "uninit")]
2478    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
2479    fn uninit_con_subseq_as_ptr<Seq, I>(&self) -> <Seq as TupleLike>::AsPtrOutput
2480    where
2481        Seq: TupleLike,
2482        Self: UninitConSubseq<Seq, I>,
2483    {
2484        UninitConSubseq::con_subseq_as_ptr(self)
2485    }
2486
2487    /// Get mutable pointers to values of a specific contiguous subsequence
2488    /// consisting of [`MaybeUninit`] elements.
2489    ///
2490    /// # Example
2491    ///
2492    /// ```
2493    /// use std::mem::MaybeUninit;
2494    /// use tuplez::{get, tuple, TupleLike, tuple_t};
2495    ///
2496    /// let mut tup = tuple!(
2497    ///     12,
2498    ///     MaybeUninit::<i32>::zeroed(),
2499    ///     MaybeUninit::<i32>::new(13),
2500    ///     MaybeUninit::<Vec<i32>>::uninit(),
2501    ///     false,
2502    /// );
2503    /// tup.uninit_write_one(vec![1, 2, 3]);
2504    /// let inited_ptr = tup.uninit_con_subseq_as_mut_ptr::<tuple_t!(i32, Vec<i32>), _>();
2505    /// unsafe {
2506    ///     *get!(inited_ptr; 0) += 1;
2507    ///     (*get!(inited_ptr; 1)).push(4);
2508    ///     assert_eq!(*get!(inited_ptr; 0), 14);
2509    ///     assert_eq!(*get!(inited_ptr; 1), vec![1, 2, 3, 4]);
2510    ///     tup.uninit_assume_init_drop_con_subseq::<tuple_t!(i32, Vec<i32>), _>();
2511    /// }
2512    /// ```
2513    #[cfg(feature = "uninit")]
2514    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
2515    fn uninit_con_subseq_as_mut_ptr<Seq, I>(&mut self) -> <Seq as TupleLike>::AsMutPtrOutput
2516    where
2517        Seq: TupleLike,
2518        Self: UninitConSubseq<Seq, I>,
2519    {
2520        UninitConSubseq::con_subseq_as_mut_ptr(self)
2521    }
2522
2523    /// Set values to a contiguous subsequence consisting of [`MaybeUninit`](std::mem::MaybeUninit) elements.
2524    ///
2525    /// Similar to [`MaybeUninit::write()`](std::mem::MaybeUninit::write()),
2526    /// this overwrites any previous value without dropping it.
2527    ///
2528    /// **NOTE**: The contiguous subsequence must have one and only one candidate in the supersequence.
2529    ///
2530    /// # Example
2531    ///
2532    /// ```
2533    /// use tuplez::{tuple, TupleLike, tuple_t};
2534    ///
2535    /// let mut uninit = <tuple_t!(i32, bool, &str)>::uninit();
2536    /// uninit.uninit_write_one(true);
2537    /// uninit.uninit_write_subseq(tuple!(12, "hello"));
2538    /// let tup = unsafe { uninit.uninit_assume_init() };
2539    /// assert_eq!(tup, tuple!(12, true, "hello"));
2540    /// ```
2541    #[cfg(feature = "uninit")]
2542    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
2543    fn uninit_write_con_subseq<Seq, I>(&mut self, subseq: Seq) -> Seq::AsMutOutput<'_>
2544    where
2545        Seq: TupleLike,
2546        Self: UninitConSubseq<Seq, I>,
2547    {
2548        UninitConSubseq::write_con_subseq(self, subseq)
2549    }
2550
2551    /// Drop values in place for a contiguous subsequence consisting of [`MaybeUninit`](std::mem::MaybeUninit) elements.
2552    ///
2553    /// **NOTE**: The contiguous subsequence must have one and only one candidate in the supersequence.
2554    ///
2555    /// # Safety
2556    ///
2557    /// Same as [`MaybeUninit::assume_init_drop()`](std::mem::MaybeUninit::assume_init_drop()).
2558    #[cfg(feature = "uninit")]
2559    #[cfg_attr(docsrs, doc(cfg(feature = "uninit")))]
2560    unsafe fn uninit_assume_init_drop_con_subseq<Seq, I>(&mut self)
2561    where
2562        Seq: TupleLike,
2563        Self: UninitConSubseq<Seq, I>,
2564    {
2565        UninitConSubseq::assume_init_drop_con_subseq(self)
2566    }
2567
2568    /// Untuple a tuple, whose elements are all tuples.
2569    ///
2570    /// See [`to_tuple()`](TupleLike::to_tuple()) for the opposite operation.
2571    ///
2572    /// Also called [`flatten()`](TupleLike::flatten()).
2573    ///
2574    /// # Example
2575    ///
2576    /// ```
2577    /// use tuplez::{tuple, TupleLike};
2578    ///
2579    /// let tup_tup = tuple!(tuple!(1, "hello"), tuple!(), tuple!(3.14));
2580    /// assert_eq!(tup_tup.untuple(), tuple!(1, "hello", 3.14));
2581    /// ```
2582    fn untuple(self) -> Self::UntupleOutput
2583    where
2584        Self: Untupleable + Sized,
2585    {
2586        Untupleable::untuple(self)
2587    }
2588
2589    /// Flatten one level of nesting in the tuple.
2590    ///
2591    /// Also called [`untuple()`](TupleLike::untuple()).
2592    ///
2593    /// # Example
2594    ///
2595    /// ```
2596    /// use tuplez::{tuple, TupleLike};
2597    ///
2598    /// let tup_tup = tuple!(tuple!(1, "hello"), tuple!(), tuple!(3.14));
2599    /// assert_eq!(tup_tup.flatten(), tuple!(1, "hello", 3.14));
2600    /// ```
2601    fn flatten(self) -> Self::UntupleOutput
2602    where
2603        Self: Untupleable + Sized,
2604    {
2605        Untupleable::untuple(self)
2606    }
2607
2608    /// Traverse the tuple, and collect the output of traversal into a new tuple.
2609    ///
2610    /// Check out [`Mapper`](crate::foreach::Mapper)'s documentation page to learn how to build
2611    /// a mapper that can be passed to [`foreach()`](TupleLike::foreach()).
2612    ///
2613    /// NOTE: Traverse a tuple will consume it. If this is not what you want, call [`as_ref()`](TupleLike::as_ref())
2614    /// or [`as_mut()`](TupleLike::as_mut()) to create a new tuple that references its all members before traversing.
2615    ///
2616    /// # Example
2617    ///
2618    /// ```
2619    /// use tuplez::{mapper, tuple, TupleLike};
2620    ///
2621    /// let tup = tuple!(1, "hello", 3.14).foreach(mapper! {
2622    ///     |x: i32| -> i64 { x as i64 }
2623    ///     |x: f32| -> String { x.to_string() }
2624    ///     <'a> |x: &'a str| -> &'a [u8] { x.as_bytes() }
2625    /// });
2626    /// assert_eq!(tup, tuple!(1i64, b"hello" as &[u8], "3.14".to_string()));
2627    /// ```
2628    fn foreach<F>(self, mapper: F) -> <Self as Foreach<F>>::Output
2629    where
2630        Self: Foreach<F> + Sized,
2631    {
2632        Foreach::foreach(self, mapper)
2633    }
2634
2635    /// Fold the tuple.
2636    ///
2637    /// Check out [`Folder`](crate::fold::Folder)'s documentation page to learn how to build
2638    /// a folder that can be passed to [`foreach()`](TupleLike::foreach()).
2639    ///
2640    /// NOTE: Fold a tuple will consume it. If this is not what you want, call [`as_ref()`](TupleLike::as_ref())
2641    /// or [`as_mut()`](TupleLike::as_mut()) to create a new tuple that references its all members before folding.
2642    ///
2643    /// # Example
2644    ///
2645    /// ```
2646    /// use tuplez::{folder, tuple, TupleLike};
2647    ///
2648    /// let tup = tuple!(Some(1), "2", Some(3.0));
2649    /// let result = tup.fold(
2650    ///     folder! { String; // Type of `acc` of all closures must be the same and annotated at the front
2651    ///         |acc, x: &str| { acc + &x.to_string() }
2652    ///         <T: ToString> |acc, x: Option<T>| { acc + &x.unwrap().to_string() }
2653    ///     },
2654    ///     String::new(),
2655    /// );
2656    /// assert_eq!(result, "123".to_string());
2657    /// ```
2658    fn fold<F, Acc>(self, folder: F, acc: Acc) -> <Self as Foldable<F, Acc>>::Output
2659    where
2660        Self: Foldable<F, Acc> + Sized,
2661    {
2662        Foldable::fold(self, folder, acc)
2663    }
2664
2665    /// Tests if any element of the tuple matches a predicate.
2666    ///
2667    /// Check out [`UnaryPredicate`]'s documentation page to learn how to build
2668    /// a unary predicate that can be passed to [`any()`](TupleLike::any()).
2669    ///
2670    /// [`any()`](TupleLike::any()) is short-circuiting; in other words, it will stop processing as soon as it finds a `true`,
2671    /// given that no matter what else happens, the result will also be `true`.
2672    ///
2673    /// An empty tuple returns `false`.
2674    ///
2675    /// # Example
2676    ///
2677    /// ```
2678    /// use tuplez::{tuple, TupleLike, unary_pred};
2679    ///
2680    /// let predicate = unary_pred! {
2681    ///     |x: i32| { (0..10).contains(x) },
2682    ///     |x: &str| { x.parse::<i32>().is_ok() },
2683    /// };
2684    ///
2685    /// let tup = tuple!(100, 2, "world");
2686    /// let result = tup.any(predicate);
2687    /// assert_eq!(result, true);
2688    ///
2689    /// let tup = tuple!(-1, 96, "hello");
2690    /// let result = tup.any(predicate);
2691    /// assert_eq!(result, false);
2692    /// ```
2693    fn any<Pred>(&self, predicate: Pred) -> bool
2694    where
2695        Self: TestAny<Pred>,
2696    {
2697        TestAny::any(self, predicate)
2698    }
2699
2700    /// Tests if every element of the tuple matches a predicate.
2701    ///
2702    /// Check out [`UnaryPredicate`]'s documentation page to learn how to build
2703    /// a unary predicate that can be passed to [`all()`](TupleLike::all()).
2704    ///
2705    /// [`all()`](TupleLike::all()) is short-circuiting; in other words, it will stop processing as soon as it finds a `false`,
2706    /// given that no matter what else happens, the result will also be `false`.
2707    ///
2708    /// An empty tuple returns `true`.
2709    ///
2710    /// # Example
2711    ///
2712    /// ```
2713    /// use tuplez::{tuple, TupleLike, unary_pred};
2714    ///
2715    /// let predicate = unary_pred! {
2716    ///     |x: i32| { (0..10).contains(x) },
2717    ///     |x: &str| { x.parse::<i32>().is_ok() },
2718    /// };
2719    ///
2720    /// let tup = tuple!(1, 2, "3");
2721    /// let result = tup.all(predicate);
2722    /// assert_eq!(result, true);
2723    ///
2724    /// let tup = tuple!(7, 8, "hello");
2725    /// let result = tup.all(predicate);
2726    /// assert_eq!(result, false);
2727    /// ```
2728    fn all<Pred>(&self, predicate: Pred) -> bool
2729    where
2730        Self: TestAll<Pred>,
2731    {
2732        TestAll::all(self, predicate)
2733    }
2734
2735    /// Performs dot product operation.
2736    ///
2737    /// Note: it evaluates starting from the last element.
2738    ///
2739    /// # Example
2740    ///
2741    /// ```
2742    /// use tuplez::{tuple, TupleLike};
2743    /// assert_eq!(tuple!(1, 3, -5).dot(tuple!(4, -2, -1)), 3);
2744    /// ```
2745    fn dot<T>(self, rhs: T) -> <Self as Dot<T>>::Output
2746    where
2747        Self: Dot<T> + Sized,
2748    {
2749        Dot::dot(self, rhs)
2750    }
2751
2752    /// Zip two tuples.
2753    ///
2754    /// See [`unzip()`](TupleLike::unzip()) for the opposite operation.
2755    ///
2756    /// # Example
2757    ///
2758    /// ```
2759    /// use tuplez::{tuple, TupleLike};
2760    ///
2761    /// let tup = tuple!(1, 2.0, "3").zip(tuple!("4", 5, 6.0));
2762    /// assert_eq!(tup, tuple!(tuple!(1, "4"), tuple!(2.0, 5), tuple!("3", 6.0)));
2763    /// ```
2764    fn zip<T>(self, rhs: T) -> Self::ZipOutput
2765    where
2766        Self: Zippable<T> + Sized,
2767    {
2768        Zippable::zip(self, rhs)
2769    }
2770
2771    /// Zip two tuples, but output elements are primitive tuples.
2772    ///
2773    /// See [`unzip()`](TupleLike::unzip()) for the opposite operation.
2774    ///
2775    /// # Example
2776    ///
2777    /// ```
2778    /// use tuplez::{tuple, TupleLike};
2779    ///
2780    /// let tup = tuple!(1, 2.0, "3").zip2(tuple!("4", 5, 6.0));
2781    /// assert_eq!(tup, tuple!((1, "4"), (2.0, 5), ("3", 6.0)));
2782    /// ```
2783    fn zip2<T>(self, rhs: T) -> Self::ZipOutput2
2784    where
2785        Self: Zippable<T> + Sized,
2786    {
2787        Zippable::zip2(self, rhs)
2788    }
2789
2790    /// Unzip a tuple to two tuples, if all elements of the tuple are tuples with two elements.
2791    /// Elements can be of [`Tuple`] type or primitive tuple type.
2792    ///
2793    /// See [`zip()`](TupleLike::zip()) and [`zip2()`](TupleLike::zip2()) for the opposite operation.
2794    ///
2795    /// ```
2796    /// use tuplez::{tuple, TupleLike};
2797    ///
2798    /// let tup = tuple!(
2799    ///     tuple!(1, "hello"), // A `Tuple`
2800    ///     ("world", 2.0),     // A primitive tuple
2801    /// );
2802    /// let (l, r) = tup.unzip();
2803    /// assert_eq!(l, tuple!(1, "world"));
2804    /// assert_eq!(r, tuple!("hello", 2.0));
2805    /// ```
2806    fn unzip(self) -> (Self::UnzipOutputLeft, Self::UnzipOutputRight)
2807    where
2808        Self: Unzippable + Sized,
2809    {
2810        Unzippable::unzip(self)
2811    }
2812
2813    /// If the elements of a tuple are all tuples, push an element to the back of each tuple element.
2814    ///
2815    /// See [`shrink()`](TupleLike::shrink()) for the opposite operation.
2816    ///
2817    /// # Example
2818    ///
2819    /// ```
2820    /// use tuplez::{tuple, TupleLike};
2821    ///
2822    /// let tup = tuple!(tuple!(1, "hello"), tuple!(), tuple!(3.14));
2823    /// let ext = tuple!(9.0, "8", 7);
2824    /// assert_eq!(
2825    ///     tup.extend(ext),
2826    ///     tuple!(tuple!(1, "hello", 9.0), tuple!("8"), tuple!(3.14, 7))
2827    /// );
2828    /// ```
2829    fn extend<T>(self, rhs: T) -> Self::ExtendBackOutput
2830    where
2831        Self: Extendable<T> + Sized,
2832    {
2833        Extendable::extend(self, rhs)
2834    }
2835
2836    /// If the elements of a tuple are all tuples, push an element to the front of each tuple element.
2837    ///
2838    /// See [`shrink_front()`](TupleLike::shrink_front()) for the opposite operation.
2839    ///
2840    /// # Example
2841    ///
2842    /// ```
2843    /// use tuplez::{tuple, TupleLike};
2844    ///
2845    /// let tup = tuple!(tuple!(1, "hello"), tuple!(), tuple!(3.14));
2846    /// let ext = tuple!(9.0, "8", 7);
2847    /// assert_eq!(
2848    ///     tup.extend_front(ext),
2849    ///     tuple!(tuple!(9.0, 1, "hello"), tuple!("8"), tuple!(7, 3.14))
2850    /// );
2851    /// ```
2852    fn extend_front<T>(self, rhs: T) -> Self::ExtendFrontOutput
2853    where
2854        Self: Extendable<T> + Sized,
2855    {
2856        Extendable::extend_front(self, rhs)
2857    }
2858
2859    /// If the elements of a tuple are all tuples, push an element to the front of each tuple element.
2860    /// Same as [`extend()`](TupleLike::extend()).
2861    fn extend_back<T>(self, rhs: T) -> Self::ExtendBackOutput
2862    where
2863        Self: Extendable<T> + Sized,
2864    {
2865        Extendable::extend_back(self, rhs)
2866    }
2867
2868    /// If the elements of a tuple are all tuples, pop an element from the back of each tuple element.
2869    ///
2870    /// See [`extend()`](TupleLike::extend()) for the opposite operation.
2871    ///
2872    /// # Example
2873    ///
2874    /// ```
2875    /// use tuplez::{tuple, TupleLike};
2876    ///
2877    /// let tup = tuple!(tuple!(9.0, 1, "hello"), tuple!("8"), tuple!(7, 3.14));
2878    /// let (result, popped) = tup.shrink();
2879    /// assert_eq!(result, tuple!(tuple!(9.0, 1), tuple!(), tuple!(7)));
2880    /// assert_eq!(popped, tuple!("hello", "8", 3.14));
2881    /// ```
2882    fn shrink(self) -> (Self::ShrinkBackOutput, Self::ShrinkBackElements)
2883    where
2884        Self: Shrinkable + Sized,
2885    {
2886        Shrinkable::shrink(self)
2887    }
2888
2889    /// If the elements of a tuple are all tuples, pop an element from the front of each tuple element.
2890    ///
2891    /// See [`extend_front()`](TupleLike::extend_front()) for the opposite operation.
2892    ///
2893    /// # Example
2894    ///
2895    /// ```
2896    /// use tuplez::{tuple, TupleLike};
2897    ///
2898    /// let tup = tuple!(tuple!(9.0, 1, "hello"), tuple!("8"), tuple!(7, 3.14));
2899    /// let (result, popped) = tup.shrink_front();
2900    /// assert_eq!(result, tuple!(tuple!(1, "hello"), tuple!(), tuple!(3.14)));
2901    /// assert_eq!(popped, tuple!(9.0, "8", 7));
2902    /// ```
2903    fn shrink_front(self) -> (Self::ShrinkFrontOutput, Self::ShrinkFrontElements)
2904    where
2905        Self: Shrinkable + Sized,
2906    {
2907        Shrinkable::shrink_front(self)
2908    }
2909
2910    /// If the elements of a tuple are all tuples, pop an element from the back of each tuple element.
2911    /// Same as [`shrink()`](TupleLike::shrink()).
2912    fn shrink_back(self) -> (Self::ShrinkBackOutput, Self::ShrinkBackElements)
2913    where
2914        Self: Shrinkable + Sized,
2915    {
2916        Shrinkable::shrink_back(self)
2917    }
2918
2919    /// If two tuples have the same number of elements, and their elements are both tuples,
2920    /// join their tuple elements one-to-one.
2921    ///
2922    /// NOTE: This method is not [`join()`](TupleLike::join()).
2923    ///
2924    /// # Example
2925    ///
2926    /// ```
2927    /// use tuplez::{tuple, TupleLike};
2928    ///
2929    /// let tup = tuple!(tuple!(1), tuple!(), tuple!("hello", 3.14));
2930    /// let tup2 = tuple!(tuple!(), tuple!(9, "8"), tuple!(7.0));
2931    /// let tup3 = tup.combine(tup2);
2932    /// assert_eq!(tup3, tuple!(tuple!(1), tuple!(9, "8"), tuple!("hello", 3.14, 7.0)));
2933    /// ```
2934    fn combine<T>(self, rhs: T) -> Self::CombineOutput
2935    where
2936        Self: Combinable<T> + Sized,
2937    {
2938        Combinable::combine(self, rhs)
2939    }
2940
2941    /// Replace the first N elements of the tuple with all elements of another tuple of N elements.
2942    ///
2943    /// # Example
2944    ///
2945    /// ```
2946    /// use tuplez::{tuple, TupleLike};
2947    ///
2948    /// let tup = tuple!(1, "2", 3.0, Some(4));
2949    /// let tup2 = tuple!("z", 8);
2950    /// let (output, replaced) = tup.replace_head(tup2);
2951    /// assert_eq!(output, tuple!("z", 8, 3.0, Some(4)));
2952    /// assert_eq!(replaced, tuple!(1, "2"));
2953    /// ```
2954    fn replace_head<T>(self, rhs: T) -> (Self::ReplaceOutput, Self::Replaced)
2955    where
2956        T: TupleLike,
2957        Self: HeadReplaceable<T> + Sized,
2958    {
2959        HeadReplaceable::replace_head(self, rhs)
2960    }
2961
2962    /// Replace the last N elements of the tuple with all elements of another tuple of N elements.
2963    ///
2964    /// # Example
2965    ///
2966    /// ```
2967    /// use tuplez::{tuple, TupleLike};
2968    ///
2969    /// let tup = tuple!(1, "2", 3.0, Some(4));
2970    /// let tup2 = tuple!("z", 8);
2971    /// let (output, replaced) = tup.replace_tail(tup2);
2972    /// assert_eq!(output, tuple!(1, "2", "z", 8));
2973    /// assert_eq!(replaced, tuple!(3.0, Some(4)));
2974    /// ```
2975    fn replace_tail<T, I>(self, rhs: T) -> (Self::ReplaceOutput, Self::Replaced)
2976    where
2977        T: TupleLike,
2978        Self: TailReplaceable<T, I> + Sized,
2979    {
2980        TailReplaceable::replace_tail(self, rhs)
2981    }
2982
2983    /// When all elements of the tuple implement [`Fn(T)`](std::ops::Fn) for a specific `T`,
2984    /// call them once in sequence.
2985    ///
2986    /// # Example
2987    ///
2988    /// It is required that `T` implements [`Clone`].
2989    ///
2990    /// ```
2991    /// use tuplez::{tuple, TupleLike};
2992    ///
2993    /// fn add1(x: i32) -> i32 {
2994    ///     x + 1
2995    /// }
2996    /// fn add2(x: i32) -> i32 {
2997    ///     x + 2
2998    /// }
2999    /// fn to_string(x: i32) -> String {
3000    ///     x.to_string()
3001    /// }
3002    ///
3003    /// let tup = tuple!(add1, add2, to_string).call(1);
3004    /// assert_eq!(tup, tuple!(2, 3, "1".to_string()));
3005    /// ```
3006    ///
3007    /// ...however, due to the existence of reborrowing, we can use some tricks to allow
3008    /// the mutable references to be used as parameters multiple times.
3009    ///
3010    /// ```
3011    /// use tuplez::{tuple, TupleLike};
3012    ///
3013    /// fn add1(x: &mut i32) {
3014    ///     *x += 1
3015    /// }
3016    /// fn add2(x: &mut i32) {
3017    ///     *x += 2
3018    /// }
3019    /// fn to_string(x: &mut i32) -> String {
3020    ///     x.to_string()
3021    /// }
3022    ///
3023    /// let mut x = 1;
3024    /// let tup = tuple!(add1, add2, to_string).call(&mut x);
3025    /// assert_eq!(x, 4);
3026    /// assert_eq!(tup, tuple!((), (), "4".to_string()));
3027    /// ```
3028    fn call<T, P>(&self, rhs: T) -> <Self as Callable<T, P>>::Output
3029    where
3030        Self: Callable<T, P>,
3031    {
3032        Callable::call(self, rhs)
3033    }
3034
3035    /// When all elements of the tuple implement [`FnMut(T)`](std::ops::FnMut) for a specific `T`,
3036    /// call them once in sequence.
3037    ///
3038    /// Basically the same as [`call()`](TupleLike::call()), but elements are required to implement
3039    /// [`FnMut(T)`](std::ops::FnMut) instead of [`Fn(T)`](std::ops::Fn).
3040    fn call_mut<T, P>(&mut self, rhs: T) -> <Self as MutCallable<T, P>>::Output
3041    where
3042        Self: MutCallable<T, P>,
3043    {
3044        MutCallable::call_mut(self, rhs)
3045    }
3046
3047    /// When all elements of the tuple implement [`FnOnce(T)`](std::ops::FnOnce) for a specific `T`,
3048    /// call them once in sequence.
3049    ///
3050    /// Basically the same as [`call()`](TupleLike::call()), but elements are required to implement
3051    /// [`FnOnce(T)`](std::ops::FnOnce) instead of [`Fn(T)`](std::ops::Fn).
3052    fn call_once<T, P>(self, rhs: T) -> <Self as OnceCallable<T, P>>::Output
3053    where
3054        Self: OnceCallable<T, P> + Sized,
3055    {
3056        OnceCallable::call_once(self, rhs)
3057    }
3058
3059    /// Convert from `Tuple<Wrapper0<T0>, Wrapper1<T1>, ... Wrappern<Tn>>` to `Tuple<T0, T1, ..., Tn>`,
3060    /// when all element types `Wrapper0`, `Wrapper1` ... `Wrappern` implement [`Unwrap`].
3061    ///
3062    /// Because this function may panic, its use is generally discouraged. Instead,
3063    /// use [`unwrap_or_default()`](TupleLike::unwrap_or_default()) or
3064    /// [`try_unwrap()`](TupleLike::try_unwrap()).
3065    ///
3066    /// # Panic
3067    ///
3068    /// Panic if any element does not contain a value.
3069    ///
3070    /// # Example
3071    ///
3072    /// ```
3073    /// use tuplez::{tuple, TupleLike};
3074    ///
3075    /// let tup = tuple!(Some(1), Ok::<f32, ()>(3.14), Some("hello"));
3076    /// assert_eq!(tup.unwrap(), tuple!(1, 3.14, "hello"));
3077    /// ```
3078    #[cfg(feature = "unwrap")]
3079    #[cfg_attr(docsrs, doc(cfg(feature = "unwrap")))]
3080    fn unwrap(self) -> Self::UnwrapOutput
3081    where
3082        Self: Unwrap + Sized,
3083    {
3084        Unwrap::unwrap(self)
3085    }
3086
3087    /// Check if self can be safely [`unwrap()`](TupleLike::unwrap()).
3088    ///
3089    /// # Example
3090    ///
3091    /// ```
3092    /// use tuplez::{tuple, TupleLike};
3093    ///
3094    /// assert_eq!(tuple!(Some(1), Some(3.14), Ok::<&str, ()>("hello")).has_value(), true);
3095    /// assert_eq!(tuple!(None::<i32>, Some(3.14), Err::<&str, ()>(())).has_value(), false);
3096    /// ```
3097    #[cfg(feature = "unwrap")]
3098    #[cfg_attr(docsrs, doc(cfg(feature = "unwrap")))]
3099    fn has_value(&self) -> bool
3100    where
3101        Self: Unwrap,
3102    {
3103        Unwrap::has_value(self)
3104    }
3105
3106    /// Convert from `Tuple<Wrapper0<T0>, Wrapper1<T1>, ... Wrappern<Tn>>` to `Tuple<T0, T1, ..., Tn>`,
3107    /// when all element types `Wrapper0`, `Wrapper1` ... `Wrappern` implement [`UnwrapOrDefault`].
3108    ///
3109    /// Unlike [`unwrap()`](TupleLike::unwrap()), if an element does not contain a value, use the
3110    /// default value instead of panic.
3111    ///
3112    /// # Example
3113    ///
3114    /// ```
3115    /// use tuplez::{tuple, TupleLike};
3116    ///
3117    /// let tup = tuple!(Some(1), Err::<f32, &str>("failed"), Some("hello"));
3118    /// assert_eq!(tup.unwrap_or_default(), tuple!(1, 0.0, "hello"));
3119    /// ```
3120    #[cfg(feature = "unwrap")]
3121    #[cfg_attr(docsrs, doc(cfg(feature = "unwrap")))]
3122    fn unwrap_or_default(self) -> Self::UnwrapOutput
3123    where
3124        Self: UnwrapOrDefault + Sized,
3125    {
3126        UnwrapOrDefault::unwrap_or_default(self)
3127    }
3128
3129    /// Convert from `Tuple<Wrapper0<T0>, Wrapper1<T1>, ... Wrappern<Tn>>` to `Option<Tuple<T0, T1, ..., Tn>>`,
3130    /// when all element types `Wrapper0`, `Wrapper1` ... `Wrappern` implement [`Unwrap`].
3131    ///
3132    /// # Example
3133    ///
3134    /// ```
3135    /// use tuplez::{tuple, TupleLike};
3136    ///
3137    /// let tup = tuple!(Some(1), Ok::<f32, ()>(3.14));
3138    /// assert_eq!(tup.try_unwrap(), Some(tuple!(1, 3.14)));
3139    /// let tup2 = tuple!(Some("hello"), Err::<i32, &str>("failed"));
3140    /// assert_eq!(tup2.try_unwrap(), None);
3141    /// ```
3142    #[cfg(feature = "unwrap")]
3143    #[cfg_attr(docsrs, doc(cfg(feature = "unwrap")))]
3144    fn try_unwrap(self) -> Option<Self::UnwrapOutput>
3145    where
3146        Self: Unwrap + Sized,
3147    {
3148        if Unwrap::has_value(&self) {
3149            Some(Unwrap::unwrap(self))
3150        } else {
3151            None
3152        }
3153    }
3154}
3155
3156impl TupleLike for Unit {
3157    type AsRefOutput<'a> = Unit;
3158    type AsMutOutput<'a> = Unit;
3159    type AsPtrOutput = Unit;
3160    type AsMutPtrOutput = Unit;
3161    type AsPinRefOutput<'a> = Unit;
3162    type AsPinMutOutput<'a> = Unit;
3163    type PushFrontOutput<T> = Tuple<T, Unit>;
3164    type PushBackOutput<T> = Tuple<T, Unit>;
3165    type RevOutput = Unit;
3166    type JoinOutput<T>
3167        = T
3168    where
3169        T: TupleLike;
3170    type ToSomeOutput = Unit;
3171    type ToOkOutput<E> = Unit;
3172    type ToTupleOutput = Unit;
3173    #[cfg(feature = "uninit")]
3174    type Uninit = Unit;
3175
3176    const LEN: usize = 0;
3177
3178    fn as_ref(&self) -> Self::AsRefOutput<'_> {
3179        Self
3180    }
3181
3182    fn as_mut(&mut self) -> Self::AsMutOutput<'_> {
3183        Self
3184    }
3185
3186    fn as_ptr(&self) -> Self::AsPtrOutput {
3187        Unit
3188    }
3189
3190    fn as_mut_ptr(&mut self) -> Self::AsMutPtrOutput {
3191        Unit
3192    }
3193
3194    fn as_pin_ref(self: Pin<&Self>) -> Self::AsPinRefOutput<'_> {
3195        Unit
3196    }
3197
3198    fn as_pin_mut(self: Pin<&mut Self>) -> Self::AsPinMutOutput<'_> {
3199        Unit
3200    }
3201
3202    fn push<T>(self, value: T) -> Self::PushBackOutput<T> {
3203        Tuple(value, self)
3204    }
3205
3206    fn push_front<T>(self, value: T) -> Self::PushFrontOutput<T> {
3207        Tuple(value, self)
3208    }
3209
3210    fn push_back<T>(self, value: T) -> Self::PushBackOutput<T> {
3211        Tuple(value, self)
3212    }
3213
3214    fn rev(self) -> Self::RevOutput {
3215        self
3216    }
3217
3218    fn join<T>(self, value: T) -> Self::JoinOutput<T>
3219    where
3220        T: TupleLike,
3221    {
3222        value
3223    }
3224
3225    fn to_some(self) -> Self::ToSomeOutput {
3226        self
3227    }
3228
3229    fn to_ok<E>(self) -> Self::ToOkOutput<E> {
3230        self
3231    }
3232
3233    fn to_tuple(self) -> Self::ToTupleOutput {
3234        self
3235    }
3236
3237    #[cfg(feature = "uninit")]
3238    fn uninit() -> Self::Uninit {
3239        Unit
3240    }
3241
3242    #[cfg(feature = "uninit")]
3243    fn zeroed() -> Self::Uninit {
3244        Unit
3245    }
3246
3247    #[cfg(feature = "uninit")]
3248    fn to_uninit(self) -> Self::Uninit {
3249        Unit
3250    }
3251}
3252
3253impl<First, Other> TupleLike for Tuple<First, Other>
3254where
3255    Other: TupleLike,
3256{
3257    type AsRefOutput<'a>
3258        = Tuple<&'a First, Other::AsRefOutput<'a>>
3259    where
3260        Self: 'a;
3261    type AsMutOutput<'a>
3262        = Tuple<&'a mut First, Other::AsMutOutput<'a>>
3263    where
3264        Self: 'a;
3265    type AsPtrOutput = Tuple<*const First, Other::AsPtrOutput>;
3266    type AsMutPtrOutput = Tuple<*mut First, Other::AsMutPtrOutput>;
3267    type AsPinRefOutput<'a>
3268        = Tuple<Pin<&'a First>, Other::AsPinRefOutput<'a>>
3269    where
3270        Self: 'a;
3271    type AsPinMutOutput<'a>
3272        = Tuple<Pin<&'a mut First>, Other::AsPinMutOutput<'a>>
3273    where
3274        Self: 'a;
3275    type PushFrontOutput<T> = Tuple<T, Self>;
3276    type PushBackOutput<T> = Tuple<First, Other::PushBackOutput<T>>;
3277    type RevOutput = <Other::RevOutput as TupleLike>::PushBackOutput<First>;
3278    type JoinOutput<T>
3279        = Tuple<First, Other::JoinOutput<T>>
3280    where
3281        T: TupleLike;
3282    type ToSomeOutput = Tuple<Option<First>, Other::ToSomeOutput>;
3283    type ToOkOutput<E> = Tuple<Result<First, E>, Other::ToOkOutput<E>>;
3284    type ToTupleOutput = Tuple<Tuple<First, Unit>, Other::ToTupleOutput>;
3285    #[cfg(feature = "uninit")]
3286    type Uninit = Tuple<MaybeUninit<First>, Other::Uninit>;
3287
3288    const LEN: usize = Other::LEN + 1;
3289
3290    fn as_ref(&self) -> Self::AsRefOutput<'_> {
3291        Tuple(&self.0, self.1.as_ref())
3292    }
3293
3294    fn as_mut(&mut self) -> Self::AsMutOutput<'_> {
3295        Tuple(&mut self.0, self.1.as_mut())
3296    }
3297
3298    fn as_ptr(&self) -> Self::AsPtrOutput {
3299        Tuple(&self.0, self.1.as_ptr())
3300    }
3301
3302    fn as_mut_ptr(&mut self) -> Self::AsMutPtrOutput {
3303        Tuple(&mut self.0, self.1.as_mut_ptr())
3304    }
3305
3306    fn as_pin_ref(self: Pin<&Self>) -> Self::AsPinRefOutput<'_> {
3307        let this = Pin::get_ref(self);
3308        unsafe {
3309            Tuple(
3310                Pin::new_unchecked(&this.0),
3311                Pin::new_unchecked(&this.1).as_pin_ref(),
3312            )
3313        }
3314    }
3315
3316    fn as_pin_mut(self: Pin<&mut Self>) -> Self::AsPinMutOutput<'_> {
3317        unsafe {
3318            let this = Pin::get_unchecked_mut(self);
3319            Tuple(
3320                Pin::new_unchecked(&mut this.0),
3321                Pin::new_unchecked(&mut this.1).as_pin_mut(),
3322            )
3323        }
3324    }
3325
3326    fn push<T>(self, value: T) -> Self::PushBackOutput<T> {
3327        Tuple(self.0, self.1.push(value))
3328    }
3329
3330    fn push_front<T>(self, value: T) -> Self::PushFrontOutput<T> {
3331        Tuple(value, self)
3332    }
3333
3334    fn push_back<T>(self, value: T) -> Self::PushBackOutput<T> {
3335        self.push::<T>(value)
3336    }
3337
3338    fn rev(self) -> Self::RevOutput {
3339        self.1.rev().push(self.0)
3340    }
3341
3342    fn join<T>(self, value: T) -> Self::JoinOutput<T>
3343    where
3344        T: TupleLike,
3345    {
3346        Tuple(self.0, self.1.join(value))
3347    }
3348
3349    fn to_some(self) -> Self::ToSomeOutput {
3350        Tuple(Some(self.0), self.1.to_some())
3351    }
3352
3353    fn to_ok<E>(self) -> Self::ToOkOutput<E> {
3354        Tuple(Ok(self.0), self.1.to_ok())
3355    }
3356
3357    fn to_tuple(self) -> Self::ToTupleOutput {
3358        Tuple(Tuple(self.0, Unit), self.1.to_tuple())
3359    }
3360
3361    #[cfg(feature = "uninit")]
3362    fn uninit() -> Self::Uninit {
3363        Tuple(MaybeUninit::uninit(), Other::uninit())
3364    }
3365
3366    #[cfg(feature = "uninit")]
3367    fn zeroed() -> Self::Uninit {
3368        Tuple(MaybeUninit::zeroed(), Other::zeroed())
3369    }
3370
3371    #[cfg(feature = "uninit")]
3372    fn to_uninit(self) -> Self::Uninit {
3373        Tuple(MaybeUninit::new(self.0), TupleLike::to_uninit(self.1))
3374    }
3375}
3376
3377/// A Marker trait to indicate that two tuple types have the same number of elements.
3378///
3379/// **FIXME**: Once the [`generic_const_exprs` feature](https://github.com/rust-lang/rust/issues/76560)
3380/// and the [`associated_const_equality` feature](https://github.com/rust-lang/rust/issues/92827) are
3381/// stabilized, this trait is no longer needed. Instead, we can write:
3382///
3383/// ```ignore
3384/// use tuplez::TupleLike;
3385///
3386/// fn use_tuple<T, U>(t: T, u: U)
3387/// where
3388///     T: TupleLike,
3389///     U: TupleLike<LEN = { T::LEN }>,
3390/// {
3391///     // ...
3392/// }
3393/// ```
3394///
3395/// # Example
3396///
3397/// Use with [`tuple_t!`](crate::tuple_t!) macro to constrain the number of elements of the tuple.
3398///
3399/// ```
3400/// use tuplez::{tuple, tuple_t, TupleLenEqTo, TupleLike};
3401///
3402/// fn only_accept_5_elements<T>(_: T)
3403/// where
3404///     T: TupleLenEqTo<tuple_t!((); 5)>
3405/// {
3406/// }
3407///
3408/// let tup4 = tuple!(1, 2.0, "3", 4);
3409/// // only_accept_5_elements(tup4);    // Error: the trait bound is not satisfied
3410/// let tup5 = tup4.push_back('5');
3411/// only_accept_5_elements(tup5);       // Ok
3412/// let tup6 = tup5.push_back(6.0);
3413/// // only_accept_5_elements(tup6);    // Error: the trait bound is not satisfied
3414/// ```
3415pub trait TupleLenEqTo<T: TupleLike>: TupleLike {}
3416
3417impl TupleLenEqTo<Unit> for Unit {}
3418
3419impl<First1, Other1, First2, Other2> TupleLenEqTo<Tuple<First2, Other2>> for Tuple<First1, Other1>
3420where
3421    Other1: TupleLenEqTo<Other2>,
3422    Other2: TupleLike,
3423{
3424}
3425
3426/// Convert from tuples to [primitive tuples](https://doc.rust-lang.org/std/primitive.tuple.html).
3427///
3428/// Note that due to the limitation that Rust cannot represent primitive tuple types containing any number of elements,
3429/// the trait [`ToPrimitive`] is only implemented for tuples with no more than 32 elements.
3430pub trait ToPrimitive {
3431    /// The primitive tuple type containing the same number and order of elements.
3432    type Primitive;
3433
3434    /// Convert from the tuple to the primitive tuple.
3435    ///
3436    /// # Examples
3437    ///
3438    /// ```
3439    /// use tuplez::{ToPrimitive, tuple};
3440    ///
3441    /// let tup = tuple!(1, "2", 3.0, 4);
3442    /// let prim = tup.primitive();
3443    /// assert_eq!(prim, (1, "2", 3.0, 4));
3444    /// ```
3445    fn primitive(self) -> Self::Primitive;
3446}
3447
3448/// Convert from tuples to [primitive arrays](std::array), if all elements of the tuple are of the same type.
3449///
3450/// Because the [generic constant expressions](https://github.com/rust-lang/rust/issues/76560) feature is still unstable yet,
3451/// we can only limit the maximum number of elements of the tuple that implement [`ToArray`] to 32,
3452/// just like what we did with the primitive tuples.
3453///
3454/// However, if you are OK with using rustc released to nightly channel to compile codes with unstable features,
3455/// you can enable the `any_array` feature to implement [`ToArray`] on tuples with no limit on the number of elements.
3456///
3457/// ```toml
3458/// tuplez = { features = [ "any_array" ] }
3459/// ```
3460///
3461/// Always remember: unstable features are not guaranteed by Rust and may not be available someday in the future.
3462///
3463/// Why `<T>` instead of `type Item`? Well, this is because the [`Unit`]s can be converted to any `[T; 0]`.
3464pub trait ToArray<T>: TupleLike {
3465    /// The primitive array type to generate.
3466    type Array: IntoIterator<Item = T>;
3467
3468    /// Immutable element iterator type.
3469    type Iter<'a>: Iterator<Item = &'a T>
3470    where
3471        Self::AsRefOutput<'a>: ToArray<&'a T>,
3472        Self: 'a,
3473        T: 'a;
3474
3475    /// Mutable element iterator type.
3476    type IterMut<'a>: Iterator<Item = &'a mut T>
3477    where
3478        Self::AsMutOutput<'a>: ToArray<&'a mut T>,
3479        Self: 'a,
3480        T: 'a;
3481
3482    /// Convert from the tuple to the primitive array.
3483    ///
3484    /// # Example
3485    ///
3486    /// ```
3487    /// # #![cfg_attr(feature = "any_array", feature(generic_const_exprs))]
3488    /// #
3489    /// use tuplez::{tuple, ToArray};
3490    ///
3491    /// let tup = tuple!(1, 2, 3, 4, 5, 6);
3492    /// assert_eq!(tup.to_array(), [1, 2, 3, 4, 5, 6]);
3493    /// ```
3494    fn to_array(self) -> Self::Array;
3495
3496    /// Get immutable element iterator.
3497    ///
3498    /// # Example
3499    ///
3500    /// ```
3501    /// # #![cfg_attr(feature = "any_array", feature(generic_const_exprs))]
3502    /// #
3503    /// use tuplez::{tuple, ToArray};
3504    ///
3505    /// let tup = tuple!(1, 2, 3, 4, 5, 6);
3506    /// assert_eq!(tup.iter().sum::<i32>(), 21);
3507    /// ```
3508    fn iter<'a>(&'a self) -> Self::Iter<'a>
3509    where
3510        Self::AsRefOutput<'a>: ToArray<&'a T>,
3511        Self: 'a,
3512        T: 'a;
3513
3514    /// Get mutable element iterator.
3515    ///
3516    /// # Example
3517    ///
3518    /// ```
3519    /// # #![cfg_attr(feature = "any_array", feature(generic_const_exprs))]
3520    /// #
3521    /// use tuplez::{tuple, ToArray};
3522    ///
3523    /// let mut tup = tuple!(1, 2, 3, 4, 5, 6);
3524    /// tup.iter_mut().for_each(|v| *v += 1);
3525    /// assert_eq!(tup.iter().sum::<i32>(), 27);
3526    /// ```
3527    fn iter_mut<'a>(&'a mut self) -> Self::IterMut<'a>
3528    where
3529        Self::AsMutOutput<'a>: ToArray<&'a mut T>,
3530        Self: 'a,
3531        T: 'a;
3532}
3533
3534tuple_traits_impl!(32);
3535
3536__tuple_unary_ops_impl! {
3537    Neg::neg(),
3538    Not::not(),
3539}
3540
3541__tuple_binary_ops_impl! {
3542    Add::add(),
3543    Sub::sub(),
3544    Mul::mul(),
3545    Div::div(),
3546    Rem::rem(),
3547    BitAnd::bitand(),
3548    BitOr::bitor(),
3549    BitXor::bitxor(),
3550    Shl::shl(),
3551    Shr::shr(),
3552}
3553
3554__tuple_assignment_ops_impl! {
3555    AddAssign::add_assign(),
3556    SubAssign::sub_assign(),
3557    MulAssign::mul_assign(),
3558    DivAssign::div_assign(),
3559    RemAssign::rem_assign(),
3560    BitAndAssign::bitand_assign(),
3561    BitOrAssign::bitor_assign(),
3562    BitXorAssign::bitxor_assign(),
3563    ShlAssign::shl_assign(),
3564    ShrAssign::shr_assign(),
3565}
3566
3567impl<T, Other> IntoIterator for Tuple<T, Other>
3568where
3569    Tuple<T, Other>: ToArray<T>,
3570{
3571    type Item = T;
3572    type IntoIter = <<Self as ToArray<T>>::Array as IntoIterator>::IntoIter;
3573
3574    fn into_iter(self) -> Self::IntoIter {
3575        self.to_array().into_iter()
3576    }
3577}
3578
3579impl<'a, T, Other> IntoIterator for &'a Tuple<T, Other>
3580where
3581    Tuple<T, Other>: TupleLike,
3582    <Tuple<T, Other> as TupleLike>::AsRefOutput<'a>: ToArray<&'a T>,
3583{
3584    type Item = &'a T;
3585    type IntoIter = <<<Tuple<T, Other> as TupleLike>::AsRefOutput<'a> as ToArray<&'a T>>::Array as IntoIterator>::IntoIter;
3586
3587    fn into_iter(self) -> Self::IntoIter {
3588        self.as_ref().to_array().into_iter()
3589    }
3590}
3591
3592impl<'a, T, Other> IntoIterator for &'a mut Tuple<T, Other>
3593where
3594    Tuple<T, Other>: TupleLike,
3595    <Tuple<T, Other> as TupleLike>::AsMutOutput<'a>: ToArray<&'a mut T>,
3596{
3597    type Item = &'a mut T;
3598    type IntoIter = <<<Tuple<T, Other> as TupleLike>::AsMutOutput<'a> as ToArray<&'a mut T>>::Array as IntoIterator>::IntoIter;
3599
3600    fn into_iter(self) -> Self::IntoIter {
3601        self.as_mut().to_array().into_iter()
3602    }
3603}