1use crate::cmp::Ordering::{self, *};
4use crate::marker::{ConstParamTy_, StructuralPartialEq};
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 #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
27 impl<$($T: [const] PartialEq),+> const PartialEq for ($($T,)+) {
28 #[inline]
29 fn eq(&self, other: &($($T,)+)) -> bool {
30 $( ${ignore($T)} self.${index()} == other.${index()} )&&+
31 }
32 #[inline]
33 fn ne(&self, other: &($($T,)+)) -> bool {
34 $( ${ignore($T)} self.${index()} != other.${index()} )||+
35 }
36 }
37 }
38
39 maybe_tuple_doc! {
40 $($T)+ @
41 #[stable(feature = "rust1", since = "1.0.0")]
42 #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
43 impl<$($T: [const] Eq),+> const Eq for ($($T,)+)
44 {}
45 }
46
47 maybe_tuple_doc! {
48 $($T)+ @
49 #[unstable(feature = "adt_const_params", issue = "95174")]
50 #[unstable_feature_bound(unsized_const_params)]
51 impl<$($T: ConstParamTy_),+> ConstParamTy_ for ($($T,)+)
52 {}
53 }
54
55 maybe_tuple_doc! {
56 $($T)+ @
57 #[unstable(feature = "structural_match", issue = "31434")]
58 impl<$($T),+> StructuralPartialEq for ($($T,)+)
59 {}
60 }
61
62 maybe_tuple_doc! {
63 $($T)+ @
64 #[stable(feature = "rust1", since = "1.0.0")]
65 #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
66 impl<$($T: [const] PartialOrd),+> const PartialOrd for ($($T,)+)
67 {
68 #[inline]
69 fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
70 lexical_partial_cmp!($( ${ignore($T)} self.${index()}, other.${index()} ),+)
71 }
72 #[inline]
73 fn lt(&self, other: &($($T,)+)) -> bool {
74 lexical_ord!(lt, __chaining_lt, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
75 }
76 #[inline]
77 fn le(&self, other: &($($T,)+)) -> bool {
78 lexical_ord!(le, __chaining_le, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
79 }
80 #[inline]
81 fn ge(&self, other: &($($T,)+)) -> bool {
82 lexical_ord!(ge, __chaining_ge, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
83 }
84 #[inline]
85 fn gt(&self, other: &($($T,)+)) -> bool {
86 lexical_ord!(gt, __chaining_gt, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
87 }
88 #[inline]
89 fn __chaining_lt(&self, other: &($($T,)+)) -> ControlFlow<bool> {
90 lexical_chain!(__chaining_lt, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
91 }
92 #[inline]
93 fn __chaining_le(&self, other: &($($T,)+)) -> ControlFlow<bool> {
94 lexical_chain!(__chaining_le, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
95 }
96 #[inline]
97 fn __chaining_gt(&self, other: &($($T,)+)) -> ControlFlow<bool> {
98 lexical_chain!(__chaining_gt, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
99 }
100 #[inline]
101 fn __chaining_ge(&self, other: &($($T,)+)) -> ControlFlow<bool> {
102 lexical_chain!(__chaining_ge, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
103 }
104 }
105 }
106
107 maybe_tuple_doc! {
108 $($T)+ @
109 #[stable(feature = "rust1", since = "1.0.0")]
110 #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
111 impl<$($T: [const] Ord),+> const Ord for ($($T,)+)
112 {
113 #[inline]
114 fn cmp(&self, other: &($($T,)+)) -> Ordering {
115 lexical_cmp!($( ${ignore($T)} self.${index()}, other.${index()} ),+)
116 }
117 }
118 }
119
120 maybe_tuple_doc! {
121 $($T)+ @
122 #[stable(feature = "rust1", since = "1.0.0")]
123 impl<$($T: Default),+> Default for ($($T,)+) {
124 #[inline]
125 fn default() -> ($($T,)+) {
126 ($({ let x: $T = Default::default(); x},)+)
127 }
128 }
129 }
130
131 maybe_tuple_doc! {
132 $($T)+ @
133 #[stable(feature = "array_tuple_conv", since = "1.71.0")]
134 impl<T> From<[T; ${count($T)}]> for ($(${ignore($T)} T,)+) {
136 #[inline]
137 #[allow(non_snake_case)]
138 fn from(array: [T; ${count($T)}]) -> Self {
139 let [$($T,)+] = array;
140 ($($T,)+)
141 }
142 }
143 }
144
145 maybe_tuple_doc! {
146 $($T)+ @
147 #[stable(feature = "array_tuple_conv", since = "1.71.0")]
148 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);