1use crate::cell::CloneFromCell;
4use crate::cmp::Ordering::{self, *};
5use crate::marker::{ConstParamTy_, StructuralPartialEq};
6use crate::ops::ControlFlow::{self, Break, Continue};
7
8macro_rules! tuple_impls {
13 ($T:ident) => {
15 tuple_impls!(@impl $T);
16 };
17 ($T:ident $( $U:ident )+) => {
19 tuple_impls!($( $U )+);
20 tuple_impls!(@impl $T $( $U )+);
21 };
22 (@impl $( $T:ident )+) => {
24 maybe_tuple_doc! {
25 $($T)+ @
26 #[stable(feature = "rust1", since = "1.0.0")]
27 #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
28 impl<$($T: [const] PartialEq),+> const PartialEq for ($($T,)+) {
29 #[inline]
30 #[ferrocene::prevalidated]
31 fn eq(&self, other: &($($T,)+)) -> bool {
32 $( ${ignore($T)} self.${index()} == other.${index()} )&&+
33 }
34 #[inline]
35 #[ferrocene::prevalidated]
36 fn ne(&self, other: &($($T,)+)) -> bool {
37 $( ${ignore($T)} self.${index()} != other.${index()} )||+
38 }
39 }
40 }
41
42 maybe_tuple_doc! {
43 $($T)+ @
44 #[stable(feature = "rust1", since = "1.0.0")]
45 #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
46 impl<$($T: [const] Eq),+> const Eq for ($($T,)+)
47 {}
48 }
49
50 maybe_tuple_doc! {
51 $($T)+ @
52 #[unstable(feature = "min_adt_const_params", issue = "154042")]
53 impl<$($T: ConstParamTy_),+> ConstParamTy_ for ($($T,)+)
54 {}
55 }
56
57 maybe_tuple_doc! {
58 $($T)+ @
59 #[unstable(feature = "structural_match", issue = "31434")]
60 impl<$($T),+> StructuralPartialEq for ($($T,)+)
61 {}
62 }
63
64 maybe_tuple_doc! {
65 $($T)+ @
66 #[stable(feature = "rust1", since = "1.0.0")]
67 #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
68 impl<$($T: [const] PartialOrd),+> const PartialOrd for ($($T,)+)
69 {
70 #[inline]
71 fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
72 lexical_partial_cmp!($( ${ignore($T)} self.${index()}, other.${index()} ),+)
73 }
74 #[inline]
75 fn lt(&self, other: &($($T,)+)) -> bool {
76 lexical_ord!(lt, __chaining_lt, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
77 }
78 #[inline]
79 fn le(&self, other: &($($T,)+)) -> bool {
80 lexical_ord!(le, __chaining_le, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
81 }
82 #[inline]
83 fn ge(&self, other: &($($T,)+)) -> bool {
84 lexical_ord!(ge, __chaining_ge, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
85 }
86 #[inline]
87 fn gt(&self, other: &($($T,)+)) -> bool {
88 lexical_ord!(gt, __chaining_gt, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
89 }
90 #[inline]
91 fn __chaining_lt(&self, other: &($($T,)+)) -> ControlFlow<bool> {
92 lexical_chain!(__chaining_lt, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
93 }
94 #[inline]
95 fn __chaining_le(&self, other: &($($T,)+)) -> ControlFlow<bool> {
96 lexical_chain!(__chaining_le, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
97 }
98 #[inline]
99 fn __chaining_gt(&self, other: &($($T,)+)) -> ControlFlow<bool> {
100 lexical_chain!(__chaining_gt, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
101 }
102 #[inline]
103 fn __chaining_ge(&self, other: &($($T,)+)) -> ControlFlow<bool> {
104 lexical_chain!(__chaining_ge, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
105 }
106 }
107 }
108
109 maybe_tuple_doc! {
110 $($T)+ @
111 #[stable(feature = "rust1", since = "1.0.0")]
112 #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
113 impl<$($T: [const] Ord),+> const 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 #[rustc_const_unstable(feature = "const_default", issue = "143894")]
126 impl<$($T: [const] Default),+> const Default for ($($T,)+) {
127 #[inline]
128 fn default() -> ($($T,)+) {
129 ($({ let x: $T = Default::default(); x},)+)
130 }
131 }
132 }
133
134 maybe_tuple_doc! {
135 $($T)+ @
136 #[stable(feature = "array_tuple_conv", since = "1.71.0")]
137 impl<T> From<[T; ${count($T)}]> for ($(${ignore($T)} T,)+) {
139 #[inline]
140 #[allow(non_snake_case)]
141 fn from(array: [T; ${count($T)}]) -> Self {
142 let [$($T,)+] = array;
143 ($($T,)+)
144 }
145 }
146 }
147
148 maybe_tuple_doc! {
149 $($T)+ @
150 #[stable(feature = "array_tuple_conv", since = "1.71.0")]
151 impl<T> From<($(${ignore($T)} T,)+)> for [T; ${count($T)}] {
153 #[inline]
154 #[allow(non_snake_case)]
155 fn from(tuple: ($(${ignore($T)} T,)+)) -> Self {
156 let ($($T,)+) = tuple;
157 [$($T,)+]
158 }
159 }
160 }
161
162 maybe_tuple_doc! {
163 $($T)+ @
164 #[unstable(feature = "cell_get_cloned", issue = "145329")]
167 unsafe impl<$($T: CloneFromCell),+> CloneFromCell for ($($T,)+)
168 {}
169 }
170 }
171}
172
173macro_rules! maybe_tuple_doc {
176 ($a:ident @ #[$meta:meta] $item:item) => {
177 #[doc(fake_variadic)]
178 #[doc = "This trait is implemented for tuples up to twelve items long."]
179 #[$meta]
180 $item
181 };
182 ($a:ident $($rest_a:ident)+ @ #[$meta:meta] $item:item) => {
183 #[doc(hidden)]
184 #[$meta]
185 $item
186 };
187}
188
189macro_rules! lexical_ord {
197 ($rel: ident, $chain_rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {{
198 match PartialOrd::$chain_rel(&$a, &$b) {
199 Break(val) => val,
200 Continue(()) => lexical_ord!($rel, $chain_rel, $($rest_a, $rest_b),+),
201 }
202 }};
203 ($rel: ident, $chain_rel: ident, $a:expr, $b:expr) => {
204 PartialOrd::$rel(&$a, &$b)
206 };
207}
208
209macro_rules! lexical_chain {
211 ($chain_rel: ident, $a:expr, $b:expr $(,$rest_a:expr, $rest_b:expr)*) => {{
212 PartialOrd::$chain_rel(&$a, &$b)?;
213 lexical_chain!($chain_rel $(,$rest_a, $rest_b)*)
214 }};
215 ($chain_rel: ident) => {
216 Continue(())
217 };
218}
219
220macro_rules! lexical_partial_cmp {
221 ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
222 match ($a).partial_cmp(&$b) {
223 Some(Equal) => lexical_partial_cmp!($($rest_a, $rest_b),+),
224 ordering => ordering
225 }
226 };
227 ($a:expr, $b:expr) => { ($a).partial_cmp(&$b) };
228}
229
230macro_rules! lexical_cmp {
231 ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
232 match ($a).cmp(&$b) {
233 Equal => lexical_cmp!($($rest_a, $rest_b),+),
234 ordering => ordering
235 }
236 };
237 ($a:expr, $b:expr) => { ($a).cmp(&$b) };
238}
239
240tuple_impls!(E D C B A Z Y X W V U T);