core/
tuple.rs

1// See core/src/primitive_docs.rs for documentation.
2
3use crate::cmp::Ordering::{self, *};
4use crate::marker::{ConstParamTy_, StructuralPartialEq, UnsizedConstParamTy};
5use crate::ops::ControlFlow::{self, Break, Continue};
6
7// Recursive macro for implementing n-ary tuple functions and operations
8//
9// Also provides implementations for tuples with lesser arity. For example, tuple_impls!(A B C)
10// will implement everything for (A, B, C), (A, B) and (A,).
11macro_rules! tuple_impls {
12    // Stopping criteria (1-ary tuple)
13    ($T:ident) => {
14        tuple_impls!(@impl $T);
15    };
16    // Running criteria (n-ary tuple, with n >= 2)
17    ($T:ident $( $U:ident )+) => {
18        tuple_impls!($( $U )+);
19        tuple_impls!(@impl $T $( $U )+);
20    };
21    // "Private" internal implementation
22    (@impl $( $T:ident )+) => {
23        maybe_tuple_doc! {
24            $($T)+ @
25            #[stable(feature = "rust1", since = "1.0.0")]
26            impl<$($T: PartialEq),+> PartialEq for ($($T,)+) {
27                #[inline]
28                fn eq(&self, other: &($($T,)+)) -> bool {
29                    $( ${ignore($T)} self.${index()} == other.${index()} )&&+
30                }
31                #[inline]
32                fn ne(&self, other: &($($T,)+)) -> bool {
33                    $( ${ignore($T)} self.${index()} != other.${index()} )||+
34                }
35            }
36        }
37
38        maybe_tuple_doc! {
39            $($T)+ @
40            #[stable(feature = "rust1", since = "1.0.0")]
41            impl<$($T: Eq),+> Eq for ($($T,)+)
42            {}
43        }
44
45        maybe_tuple_doc! {
46            $($T)+ @
47            #[unstable(feature = "adt_const_params", issue = "95174")]
48            impl<$($T: ConstParamTy_),+> ConstParamTy_ for ($($T,)+)
49            {}
50        }
51
52        maybe_tuple_doc! {
53            $($T)+ @
54            #[unstable(feature = "unsized_const_params", issue = "95174")]
55            impl<$($T: UnsizedConstParamTy),+> UnsizedConstParamTy for ($($T,)+)
56            {}
57        }
58
59        maybe_tuple_doc! {
60            $($T)+ @
61            #[unstable(feature = "structural_match", issue = "31434")]
62            impl<$($T),+> StructuralPartialEq for ($($T,)+)
63            {}
64        }
65
66        maybe_tuple_doc! {
67            $($T)+ @
68            #[stable(feature = "rust1", since = "1.0.0")]
69            impl<$($T: PartialOrd),+> PartialOrd for ($($T,)+)
70            {
71                #[inline]
72                fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
73                    lexical_partial_cmp!($( ${ignore($T)} self.${index()}, other.${index()} ),+)
74                }
75                #[inline]
76                fn lt(&self, other: &($($T,)+)) -> bool {
77                    lexical_ord!(lt, __chaining_lt, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
78                }
79                #[inline]
80                fn le(&self, other: &($($T,)+)) -> bool {
81                    lexical_ord!(le, __chaining_le, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
82                }
83                #[inline]
84                fn ge(&self, other: &($($T,)+)) -> bool {
85                    lexical_ord!(ge, __chaining_ge, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
86                }
87                #[inline]
88                fn gt(&self, other: &($($T,)+)) -> bool {
89                    lexical_ord!(gt, __chaining_gt, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
90                }
91                #[inline]
92                fn __chaining_lt(&self, other: &($($T,)+)) -> ControlFlow<bool> {
93                    lexical_chain!(__chaining_lt, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
94                }
95                #[inline]
96                fn __chaining_le(&self, other: &($($T,)+)) -> ControlFlow<bool> {
97                    lexical_chain!(__chaining_le, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
98                }
99                #[inline]
100                fn __chaining_gt(&self, other: &($($T,)+)) -> ControlFlow<bool> {
101                    lexical_chain!(__chaining_gt, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
102                }
103                #[inline]
104                fn __chaining_ge(&self, other: &($($T,)+)) -> ControlFlow<bool> {
105                    lexical_chain!(__chaining_ge, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
106                }
107            }
108        }
109
110        maybe_tuple_doc! {
111            $($T)+ @
112            #[stable(feature = "rust1", since = "1.0.0")]
113            impl<$($T: Ord),+> Ord for ($($T,)+)
114            {
115                #[inline]
116                fn cmp(&self, other: &($($T,)+)) -> Ordering {
117                    lexical_cmp!($( ${ignore($T)} self.${index()}, other.${index()} ),+)
118                }
119            }
120        }
121
122        maybe_tuple_doc! {
123            $($T)+ @
124            #[stable(feature = "rust1", since = "1.0.0")]
125            impl<$($T: Default),+> Default for ($($T,)+) {
126                #[inline]
127                fn default() -> ($($T,)+) {
128                    ($({ let x: $T = Default::default(); x},)+)
129                }
130            }
131        }
132
133        maybe_tuple_doc! {
134            $($T)+ @
135            #[stable(feature = "array_tuple_conv", since = "1.71.0")]
136            impl<T> From<[T; ${count($T)}]> for ($(${ignore($T)} T,)+) {
137                #[inline]
138                #[allow(non_snake_case)]
139                fn from(array: [T; ${count($T)}]) -> Self {
140                    let [$($T,)+] = array;
141                    ($($T,)+)
142                }
143            }
144        }
145
146        maybe_tuple_doc! {
147            $($T)+ @
148            #[stable(feature = "array_tuple_conv", since = "1.71.0")]
149            impl<T> From<($(${ignore($T)} T,)+)> for [T; ${count($T)}] {
150                #[inline]
151                #[allow(non_snake_case)]
152                fn from(tuple: ($(${ignore($T)} T,)+)) -> Self {
153                    let ($($T,)+) = tuple;
154                    [$($T,)+]
155                }
156            }
157        }
158    }
159}
160
161// If this is a unary tuple, it adds a doc comment.
162// Otherwise, it hides the docs entirely.
163macro_rules! maybe_tuple_doc {
164    ($a:ident @ #[$meta:meta] $item:item) => {
165        #[doc(fake_variadic)]
166        #[doc = "This trait is implemented for tuples up to twelve items long."]
167        #[$meta]
168        $item
169    };
170    ($a:ident $($rest_a:ident)+ @ #[$meta:meta] $item:item) => {
171        #[doc(hidden)]
172        #[$meta]
173        $item
174    };
175}
176
177// Constructs an expression that performs a lexical ordering using method `$rel`.
178// The values are interleaved, so the macro invocation for
179// `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_ord!(lt, opt_is_lt, a1, b1,
180// a2, b2, a3, b3)` (and similarly for `lexical_cmp`)
181//
182// `$chain_rel` is the chaining method from `PartialOrd` to use for all but the
183// final value, to produce better results for simple primitives.
184macro_rules! lexical_ord {
185    ($rel: ident, $chain_rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {{
186        match PartialOrd::$chain_rel(&$a, &$b) {
187            Break(val) => val,
188            Continue(()) => lexical_ord!($rel, $chain_rel, $($rest_a, $rest_b),+),
189        }
190    }};
191    ($rel: ident, $chain_rel: ident, $a:expr, $b:expr) => {
192        // Use the specific method for the last element
193        PartialOrd::$rel(&$a, &$b)
194    };
195}
196
197// Same parameter interleaving as `lexical_ord` above
198macro_rules! lexical_chain {
199    ($chain_rel: ident, $a:expr, $b:expr $(,$rest_a:expr, $rest_b:expr)*) => {{
200        PartialOrd::$chain_rel(&$a, &$b)?;
201        lexical_chain!($chain_rel $(,$rest_a, $rest_b)*)
202    }};
203    ($chain_rel: ident) => {
204        Continue(())
205    };
206}
207
208macro_rules! lexical_partial_cmp {
209    ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
210        match ($a).partial_cmp(&$b) {
211            Some(Equal) => lexical_partial_cmp!($($rest_a, $rest_b),+),
212            ordering => ordering
213        }
214    };
215    ($a:expr, $b:expr) => { ($a).partial_cmp(&$b) };
216}
217
218macro_rules! lexical_cmp {
219    ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
220        match ($a).cmp(&$b) {
221            Equal => lexical_cmp!($($rest_a, $rest_b),+),
222            ordering => ordering
223        }
224    };
225    ($a:expr, $b:expr) => { ($a).cmp(&$b) };
226}
227
228tuple_impls!(E D C B A Z Y X W V U T);
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy