1use crate::cmp::Ordering::{self, *};
4use crate::marker::{ConstParamTy_, StructuralPartialEq, UnsizedConstParamTy};
5use crate::ops::ControlFlow::{Break, Continue};
6
7macro_rules! tuple_impls {
12 ($T:ident) => {
14 tuple_impls!(@impl $T);
15 };
16 ($T:ident $( $U:ident )+) => {
18 tuple_impls!($( $U )+);
19 tuple_impls!(@impl $T $( $U )+);
20 };
21 (@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 where
28 last_type!($($T,)+): ?Sized
29 {
30 #[inline]
31 fn eq(&self, other: &($($T,)+)) -> bool {
32 $( ${ignore($T)} self.${index()} == other.${index()} )&&+
33 }
34 #[inline]
35 fn ne(&self, other: &($($T,)+)) -> bool {
36 $( ${ignore($T)} self.${index()} != other.${index()} )||+
37 }
38 }
39 }
40
41 maybe_tuple_doc! {
42 $($T)+ @
43 #[stable(feature = "rust1", since = "1.0.0")]
44 impl<$($T: Eq),+> Eq for ($($T,)+)
45 where
46 last_type!($($T,)+): ?Sized
47 {}
48 }
49
50 maybe_tuple_doc! {
51 $($T)+ @
52 #[unstable(feature = "adt_const_params", issue = "95174")]
53 impl<$($T: ConstParamTy_),+> ConstParamTy_ for ($($T,)+)
54 {}
55 }
56
57 maybe_tuple_doc! {
58 $($T)+ @
59 #[unstable(feature = "unsized_const_params", issue = "95174")]
60 impl<$($T: UnsizedConstParamTy),+> UnsizedConstParamTy for ($($T,)+)
61 {}
62 }
63
64 maybe_tuple_doc! {
65 $($T)+ @
66 #[unstable(feature = "structural_match", issue = "31434")]
67 impl<$($T),+> StructuralPartialEq for ($($T,)+)
68 {}
69 }
70
71 maybe_tuple_doc! {
72 $($T)+ @
73 #[stable(feature = "rust1", since = "1.0.0")]
74 impl<$($T: PartialOrd),+> PartialOrd for ($($T,)+)
75 where
76 last_type!($($T,)+): ?Sized
77 {
78 #[inline]
79 fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
80 lexical_partial_cmp!($( ${ignore($T)} self.${index()}, other.${index()} ),+)
81 }
82 #[inline]
83 fn lt(&self, other: &($($T,)+)) -> bool {
84 lexical_ord!(lt, __chaining_lt, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
85 }
86 #[inline]
87 fn le(&self, other: &($($T,)+)) -> bool {
88 lexical_ord!(le, __chaining_le, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
89 }
90 #[inline]
91 fn ge(&self, other: &($($T,)+)) -> bool {
92 lexical_ord!(ge, __chaining_ge, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
93 }
94 #[inline]
95 fn gt(&self, other: &($($T,)+)) -> bool {
96 lexical_ord!(gt, __chaining_gt, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
97 }
98 }
99 }
100
101 maybe_tuple_doc! {
102 $($T)+ @
103 #[stable(feature = "rust1", since = "1.0.0")]
104 impl<$($T: Ord),+> Ord for ($($T,)+)
105 where
106 last_type!($($T,)+): ?Sized
107 {
108 #[inline]
109 fn cmp(&self, other: &($($T,)+)) -> Ordering {
110 lexical_cmp!($( ${ignore($T)} self.${index()}, other.${index()} ),+)
111 }
112 }
113 }
114
115 maybe_tuple_doc! {
116 $($T)+ @
117 #[stable(feature = "rust1", since = "1.0.0")]
118 impl<$($T: Default),+> Default for ($($T,)+) {
119 #[inline]
120 fn default() -> ($($T,)+) {
121 ($({ let x: $T = Default::default(); x},)+)
122 }
123 }
124 }
125
126 maybe_tuple_doc! {
127 $($T)+ @
128 #[stable(feature = "array_tuple_conv", since = "1.71.0")]
129 impl<T> From<[T; ${count($T)}]> for ($(${ignore($T)} T,)+) {
130 #[inline]
131 #[allow(non_snake_case)]
132 fn from(array: [T; ${count($T)}]) -> Self {
133 let [$($T,)+] = array;
134 ($($T,)+)
135 }
136 }
137 }
138
139 maybe_tuple_doc! {
140 $($T)+ @
141 #[stable(feature = "array_tuple_conv", since = "1.71.0")]
142 impl<T> From<($(${ignore($T)} T,)+)> for [T; ${count($T)}] {
143 #[inline]
144 #[allow(non_snake_case)]
145 fn from(tuple: ($(${ignore($T)} T,)+)) -> Self {
146 let ($($T,)+) = tuple;
147 [$($T,)+]
148 }
149 }
150 }
151 }
152}
153
154macro_rules! maybe_tuple_doc {
157 ($a:ident @ #[$meta:meta] $item:item) => {
158 #[doc(fake_variadic)]
159 #[doc = "This trait is implemented for tuples up to twelve items long."]
160 #[$meta]
161 $item
162 };
163 ($a:ident $($rest_a:ident)+ @ #[$meta:meta] $item:item) => {
164 #[doc(hidden)]
165 #[$meta]
166 $item
167 };
168}
169
170macro_rules! lexical_ord {
178 ($rel: ident, $chain_rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {{
179 match PartialOrd::$chain_rel(&$a, &$b) {
180 Break(val) => val,
181 Continue(()) => lexical_ord!($rel, $chain_rel, $($rest_a, $rest_b),+),
182 }
183 }};
184 ($rel: ident, $chain_rel: ident, $a:expr, $b:expr) => {
185 PartialOrd::$rel(&$a, &$b)
187 };
188}
189
190macro_rules! lexical_partial_cmp {
191 ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
192 match ($a).partial_cmp(&$b) {
193 Some(Equal) => lexical_partial_cmp!($($rest_a, $rest_b),+),
194 ordering => ordering
195 }
196 };
197 ($a:expr, $b:expr) => { ($a).partial_cmp(&$b) };
198}
199
200macro_rules! lexical_cmp {
201 ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
202 match ($a).cmp(&$b) {
203 Equal => lexical_cmp!($($rest_a, $rest_b),+),
204 ordering => ordering
205 }
206 };
207 ($a:expr, $b:expr) => { ($a).cmp(&$b) };
208}
209
210macro_rules! last_type {
211 ($a:ident,) => { $a };
212 ($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) };
213}
214
215tuple_impls!(E D C B A Z Y X W V U T);