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 #[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
161macro_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
177macro_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 PartialOrd::$rel(&$a, &$b)
194 };
195}
196
197macro_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);