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,)+) {
138 #[inline]
139 #[allow(non_snake_case)]
140 fn from(array: [T; ${count($T)}]) -> Self {
141 let [$($T,)+] = array;
142 ($($T,)+)
143 }
144 }
145 }
146
147 maybe_tuple_doc! {
148 $($T)+ @
149 #[stable(feature = "array_tuple_conv", since = "1.71.0")]
150 impl<T> From<($(${ignore($T)} T,)+)> for [T; ${count($T)}] {
152 #[inline]
153 #[allow(non_snake_case)]
154 fn from(tuple: ($(${ignore($T)} T,)+)) -> Self {
155 let ($($T,)+) = tuple;
156 [$($T,)+]
157 }
158 }
159 }
160 }
161}
162
163macro_rules! maybe_tuple_doc {
166 ($a:ident @ #[$meta:meta] $item:item) => {
167 #[doc(fake_variadic)]
168 #[doc = "This trait is implemented for tuples up to twelve items long."]
169 #[$meta]
170 $item
171 };
172 ($a:ident $($rest_a:ident)+ @ #[$meta:meta] $item:item) => {
173 #[doc(hidden)]
174 #[$meta]
175 $item
176 };
177}
178
179macro_rules! lexical_ord {
187 ($rel: ident, $chain_rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {{
188 match PartialOrd::$chain_rel(&$a, &$b) {
189 Break(val) => val,
190 Continue(()) => lexical_ord!($rel, $chain_rel, $($rest_a, $rest_b),+),
191 }
192 }};
193 ($rel: ident, $chain_rel: ident, $a:expr, $b:expr) => {
194 PartialOrd::$rel(&$a, &$b)
196 };
197}
198
199macro_rules! lexical_chain {
201 ($chain_rel: ident, $a:expr, $b:expr $(,$rest_a:expr, $rest_b:expr)*) => {{
202 PartialOrd::$chain_rel(&$a, &$b)?;
203 lexical_chain!($chain_rel $(,$rest_a, $rest_b)*)
204 }};
205 ($chain_rel: ident) => {
206 Continue(())
207 };
208}
209
210macro_rules! lexical_partial_cmp {
211 ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
212 match ($a).partial_cmp(&$b) {
213 Some(Equal) => lexical_partial_cmp!($($rest_a, $rest_b),+),
214 ordering => ordering
215 }
216 };
217 ($a:expr, $b:expr) => { ($a).partial_cmp(&$b) };
218}
219
220macro_rules! lexical_cmp {
221 ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
222 match ($a).cmp(&$b) {
223 Equal => lexical_cmp!($($rest_a, $rest_b),+),
224 ordering => ordering
225 }
226 };
227 ($a:expr, $b:expr) => { ($a).cmp(&$b) };
228}
229
230tuple_impls!(E D C B A Z Y X W V U T);