1use crate::cmp::Ordering::{self, *};
4use crate::marker::{ConstParamTy_, StructuralPartialEq, UnsizedConstParamTy};
5use crate::ops::ControlFlow::{self, 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 #[inline]
99 fn __chaining_lt(&self, other: &($($T,)+)) -> ControlFlow<bool> {
100 lexical_chain!(__chaining_lt, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
101 }
102 #[inline]
103 fn __chaining_le(&self, other: &($($T,)+)) -> ControlFlow<bool> {
104 lexical_chain!(__chaining_le, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
105 }
106 #[inline]
107 fn __chaining_gt(&self, other: &($($T,)+)) -> ControlFlow<bool> {
108 lexical_chain!(__chaining_gt, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
109 }
110 #[inline]
111 fn __chaining_ge(&self, other: &($($T,)+)) -> ControlFlow<bool> {
112 lexical_chain!(__chaining_ge, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
113 }
114 }
115 }
116
117 maybe_tuple_doc! {
118 $($T)+ @
119 #[stable(feature = "rust1", since = "1.0.0")]
120 impl<$($T: Ord),+> Ord for ($($T,)+)
121 where
122 last_type!($($T,)+): ?Sized
123 {
124 #[inline]
125 fn cmp(&self, other: &($($T,)+)) -> Ordering {
126 lexical_cmp!($( ${ignore($T)} self.${index()}, other.${index()} ),+)
127 }
128 }
129 }
130
131 maybe_tuple_doc! {
132 $($T)+ @
133 #[stable(feature = "rust1", since = "1.0.0")]
134 impl<$($T: Default),+> Default for ($($T,)+) {
135 #[inline]
136 fn default() -> ($($T,)+) {
137 ($({ let x: $T = Default::default(); x},)+)
138 }
139 }
140 }
141
142 maybe_tuple_doc! {
143 $($T)+ @
144 #[stable(feature = "array_tuple_conv", since = "1.71.0")]
145 impl<T> From<[T; ${count($T)}]> for ($(${ignore($T)} T,)+) {
146 #[inline]
147 #[allow(non_snake_case)]
148 fn from(array: [T; ${count($T)}]) -> Self {
149 let [$($T,)+] = array;
150 ($($T,)+)
151 }
152 }
153 }
154
155 maybe_tuple_doc! {
156 $($T)+ @
157 #[stable(feature = "array_tuple_conv", since = "1.71.0")]
158 impl<T> From<($(${ignore($T)} T,)+)> for [T; ${count($T)}] {
159 #[inline]
160 #[allow(non_snake_case)]
161 fn from(tuple: ($(${ignore($T)} T,)+)) -> Self {
162 let ($($T,)+) = tuple;
163 [$($T,)+]
164 }
165 }
166 }
167 }
168}
169
170macro_rules! maybe_tuple_doc {
173 ($a:ident @ #[$meta:meta] $item:item) => {
174 #[doc(fake_variadic)]
175 #[doc = "This trait is implemented for tuples up to twelve items long."]
176 #[$meta]
177 $item
178 };
179 ($a:ident $($rest_a:ident)+ @ #[$meta:meta] $item:item) => {
180 #[doc(hidden)]
181 #[$meta]
182 $item
183 };
184}
185
186macro_rules! lexical_ord {
194 ($rel: ident, $chain_rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {{
195 match PartialOrd::$chain_rel(&$a, &$b) {
196 Break(val) => val,
197 Continue(()) => lexical_ord!($rel, $chain_rel, $($rest_a, $rest_b),+),
198 }
199 }};
200 ($rel: ident, $chain_rel: ident, $a:expr, $b:expr) => {
201 PartialOrd::$rel(&$a, &$b)
203 };
204}
205
206macro_rules! lexical_chain {
208 ($chain_rel: ident, $a:expr, $b:expr $(,$rest_a:expr, $rest_b:expr)*) => {{
209 PartialOrd::$chain_rel(&$a, &$b)?;
210 lexical_chain!($chain_rel $(,$rest_a, $rest_b)*)
211 }};
212 ($chain_rel: ident) => {
213 Continue(())
214 };
215}
216
217macro_rules! lexical_partial_cmp {
218 ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
219 match ($a).partial_cmp(&$b) {
220 Some(Equal) => lexical_partial_cmp!($($rest_a, $rest_b),+),
221 ordering => ordering
222 }
223 };
224 ($a:expr, $b:expr) => { ($a).partial_cmp(&$b) };
225}
226
227macro_rules! lexical_cmp {
228 ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
229 match ($a).cmp(&$b) {
230 Equal => lexical_cmp!($($rest_a, $rest_b),+),
231 ordering => ordering
232 }
233 };
234 ($a:expr, $b:expr) => { ($a).cmp(&$b) };
235}
236
237macro_rules! last_type {
238 ($a:ident,) => { $a };
239 ($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) };
240}
241
242tuple_impls!(E D C B A Z Y X W V U T);