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 = "adt_const_params", issue = "95174")]
53 #[unstable_feature_bound(unsized_const_params)]
54 impl<$($T: ConstParamTy_),+> ConstParamTy_ for ($($T,)+)
55 {}
56 }
57
58 maybe_tuple_doc! {
59 $($T)+ @
60 #[unstable(feature = "structural_match", issue = "31434")]
61 impl<$($T),+> StructuralPartialEq for ($($T,)+)
62 {}
63 }
64
65 maybe_tuple_doc! {
66 $($T)+ @
67 #[stable(feature = "rust1", since = "1.0.0")]
68 #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
69 impl<$($T: [const] PartialOrd),+> const 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 #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
114 impl<$($T: [const] Ord),+> const Ord for ($($T,)+)
115 {
116 #[inline]
117 fn cmp(&self, other: &($($T,)+)) -> Ordering {
118 lexical_cmp!($( ${ignore($T)} self.${index()}, other.${index()} ),+)
119 }
120 }
121 }
122
123 maybe_tuple_doc! {
124 $($T)+ @
125 #[stable(feature = "rust1", since = "1.0.0")]
126 impl<$($T: Default),+> 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);