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 const impl<$($T: [const] PartialEq),+> PartialEq for ($($T,)+) {
29 #[inline]
30 fn eq(&self, other: &($($T,)+)) -> bool {
31 $( ${ignore($T)} self.${index()} == other.${index()} )&&+
32 }
33 #[inline]
34 fn ne(&self, other: &($($T,)+)) -> bool {
35 $( ${ignore($T)} self.${index()} != other.${index()} )||+
36 }
37 }
38 }
39
40 maybe_tuple_doc! {
41 $($T)+ @
42 #[stable(feature = "rust1", since = "1.0.0")]
43 #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
44 const impl<$($T: [const] Eq),+> Eq for ($($T,)+)
45 {}
46 }
47
48 maybe_tuple_doc! {
49 $($T)+ @
50 #[unstable(feature = "min_adt_const_params", issue = "154042")]
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 const impl<$($T: [const] PartialOrd),+> 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_less, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
75 }
76 #[inline]
77 fn le(&self, other: &($($T,)+)) -> bool {
78 lexical_ord!(le, __chaining_less, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
79 }
80 #[inline]
81 fn ge(&self, other: &($($T,)+)) -> bool {
82 lexical_ord!(ge, __chaining_greater, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
83 }
84 #[inline]
85 fn gt(&self, other: &($($T,)+)) -> bool {
86 lexical_ord!(gt, __chaining_greater, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
87 }
88 #[inline]
89 fn __chaining_less(&self, other: &($($T,)+)) -> ControlFlow<bool> {
90 lexical_chain!(__chaining_less, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
91 }
92 #[inline]
93 fn __chaining_greater(&self, other: &($($T,)+)) -> ControlFlow<bool> {
94 lexical_chain!(__chaining_greater, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
95 }
96 }
97 }
98
99 maybe_tuple_doc! {
100 $($T)+ @
101 #[stable(feature = "rust1", since = "1.0.0")]
102 #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
103 const impl<$($T: [const] Ord),+> Ord for ($($T,)+)
104 {
105 #[inline]
106 fn cmp(&self, other: &($($T,)+)) -> Ordering {
107 lexical_cmp!($( ${ignore($T)} self.${index()}, other.${index()} ),+)
108 }
109 }
110 }
111
112 maybe_tuple_doc! {
113 $($T)+ @
114 #[stable(feature = "rust1", since = "1.0.0")]
115 #[rustc_const_unstable(feature = "const_default", issue = "143894")]
116 const impl<$($T: [const] Default),+> Default for ($($T,)+) {
117 #[inline]
118 fn default() -> ($($T,)+) {
119 ($({ let x: $T = Default::default(); x},)+)
120 }
121 }
122 }
123
124 maybe_tuple_doc! {
125 $($T)+ @
126 #[stable(feature = "array_tuple_conv", since = "1.71.0")]
127 impl<T> From<[T; ${count($T)}]> for ($(${ignore($T)} T,)+) {
129 #[inline]
130 #[allow(non_snake_case)]
131 fn from(array: [T; ${count($T)}]) -> Self {
132 let [$($T,)+] = array;
133 ($($T,)+)
134 }
135 }
136 }
137
138 maybe_tuple_doc! {
139 $($T)+ @
140 #[stable(feature = "array_tuple_conv", since = "1.71.0")]
141 impl<T> From<($(${ignore($T)} T,)+)> for [T; ${count($T)}] {
143 #[inline]
144 #[allow(non_snake_case)]
145 fn from(tuple: ($(${ignore($T)} T,)+)) -> Self {
146 let ($($T,)+) = tuple;
147 [$($T,)+]
148 }
149 }
150 }
151
152 maybe_tuple_doc! {
153 $($T)+ @
154 #[unstable(feature = "cell_get_cloned", issue = "145329")]
157 unsafe impl<$($T: CloneFromCell),+> CloneFromCell for ($($T,)+)
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)* $(,)?) => {{
202 $(if let r @ Break(_) = PartialOrd::$chain_rel(&$a, &$b) {
205 return r;
206 })*
207 Continue(())
208 }};
209}
210
211macro_rules! lexical_partial_cmp {
212 ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
213 match ($a).partial_cmp(&$b) {
214 Some(Equal) => lexical_partial_cmp!($($rest_a, $rest_b),+),
215 ordering => ordering
216 }
217 };
218 ($a:expr, $b:expr) => { ($a).partial_cmp(&$b) };
219}
220
221macro_rules! lexical_cmp {
222 ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
223 match ($a).cmp(&$b) {
224 Equal => lexical_cmp!($($rest_a, $rest_b),+),
225 ordering => ordering
226 }
227 };
228 ($a:expr, $b:expr) => { ($a).cmp(&$b) };
229}
230
231tuple_impls!(E D C B A Z Y X W V U T);