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}