@@ -114,17 +114,17 @@ impl<A:Copy,B:Copy> ExtendedTupleOps<A,B> for (~[A], ~[B]) {
114
114
115
115
// macro for implementing n-ary tuple functions and operations
116
116
117
- macro_rules! tuple_impls(
117
+ macro_rules! tuple_impls {
118
118
( $(
119
119
( $cloneable_trait: ident, $immutable_trait: ident) {
120
120
$( ( $get_fn: ident, $get_ref_fn: ident) -> $T: ident {
121
121
$get_pattern: pat => $ret: expr
122
122
} ) +
123
123
}
124
- ) +) => (
124
+ ) +) => {
125
125
pub mod inner {
126
126
use clone:: Clone ;
127
- #[ cfg( not( test) ) ] use cmp:: { Eq , Ord } ;
127
+ #[ cfg( not( test) ) ] use cmp:: * ;
128
128
129
129
$(
130
130
pub trait $cloneable_trait<$( $T) ,+> {
@@ -171,11 +171,19 @@ macro_rules! tuple_impls(
171
171
}
172
172
}
173
173
174
+ #[ cfg( not( test) ) ]
175
+ impl <$( $T: TotalEq ) ,+> TotalEq for ( $( $T) ,+) {
176
+ #[ inline( always) ]
177
+ fn equals( & self , other: & ( $( $T) ,+) ) -> bool {
178
+ $( self . $get_ref_fn( ) . equals( other. $get_ref_fn( ) ) ) &&+
179
+ }
180
+ }
181
+
174
182
#[ cfg( not( test) ) ]
175
183
impl <$( $T: Ord ) ,+> Ord for ( $( $T) ,+) {
176
184
#[ inline( always) ]
177
185
fn lt( & self , other: & ( $( $T) ,+) ) -> bool {
178
- lexical_lt!( $( * self . $get_ref_fn( ) , * other. $get_ref_fn( ) ) ,+)
186
+ lexical_lt!( $( self . $get_ref_fn( ) , other. $get_ref_fn( ) ) ,+)
179
187
}
180
188
#[ inline( always) ]
181
189
fn le( & self , other: & ( $( $T) ,+) ) -> bool { !( * other) . lt( & ( * self ) ) }
@@ -184,22 +192,44 @@ macro_rules! tuple_impls(
184
192
#[ inline( always) ]
185
193
fn gt( & self , other: & ( $( $T) ,+) ) -> bool { ( * other) . lt( & ( * self ) ) }
186
194
}
195
+
196
+ #[ cfg( not( test) ) ]
197
+ impl <$( $T: TotalOrd ) ,+> TotalOrd for ( $( $T) ,+) {
198
+ #[ inline]
199
+ fn cmp( & self , other: & ( $( $T) ,+) ) -> Ordering {
200
+ lexical_cmp!( $( self . $get_ref_fn( ) , other. $get_ref_fn( ) ) ,+)
201
+ }
202
+ }
187
203
) +
188
204
}
189
- )
190
- )
191
-
192
- // Constructs an expression that performs a lexical less-than ordering.
193
- // The values are interleaved, so the macro invocation for
194
- // `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_lt!(a1, b1, a2, b2, a3, b3)`
195
- macro_rules! lexical_lt(
196
- ( $a: expr, $b: expr, $( $rest_a: expr, $rest_b: expr) ,+) => (
197
- if $a < $b { true } else { lexical_lt!( $( $rest_a, $rest_b) ,+) }
198
- ) ;
199
- ( $a: expr, $b: expr) => ( $a < $b) ;
200
- )
201
-
202
- tuple_impls ! (
205
+ }
206
+ }
207
+
208
+ // Constructs an expression that performs a lexical less-than
209
+ // ordering. The values are interleaved, so the macro invocation for
210
+ // `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_lt!(a1, b1, a2, b2,
211
+ // a3, b3)` (and similarly for `lexical_cmp`)
212
+ macro_rules! lexical_lt {
213
+ ( $a: expr, $b: expr, $( $rest_a: expr, $rest_b: expr) ,+) => {
214
+ if * $a < * $b { true }
215
+ else if !( * $b < * $a) { lexical_lt!( $( $rest_a, $rest_b) ,+) }
216
+ else { false }
217
+ } ;
218
+ ( $a: expr, $b: expr) => { * $a < * $b } ;
219
+ }
220
+
221
+ macro_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
+
231
+
232
+ tuple_impls ! {
203
233
( CloneableTuple2 , ImmutableTuple2 ) {
204
234
( n0, n0_ref) -> A { ( ref a, _) => a }
205
235
( n1, n1_ref) -> B { ( _, ref b) => b }
@@ -309,12 +339,13 @@ tuple_impls!(
309
339
( n10, n10_ref) -> K { ( _, _, _, _, _, _, _, _, _, _, ref k, _) => k }
310
340
( n11, n11_ref) -> L { ( _, _, _, _, _, _, _, _, _, _, _, ref l) => l }
311
341
}
312
- )
342
+ }
313
343
314
344
#[ cfg( test) ]
315
345
mod tests {
316
346
use super :: * ;
317
347
use clone:: Clone ;
348
+ use cmp:: * ;
318
349
319
350
#[ test]
320
351
fn test_tuple_ref ( ) {
@@ -368,4 +399,41 @@ mod tests {
368
399
assert_eq ! ( t. n10_ref( ) , & 10f32 ) ;
369
400
assert_eq ! ( t. n11_ref( ) , & 11f64 ) ;
370
401
}
402
+
403
+ #[ test]
404
+ fn test_tuple_cmp ( ) {
405
+ let small = ( 1 u, 2 u, 3 u) , big = ( 3 u, 2 u, 1 u) ;
406
+
407
+ // Eq
408
+ assert_eq ! ( small, small) ;
409
+ assert_eq ! ( big, big) ;
410
+ assert ! ( small != big) ;
411
+ assert ! ( big != small) ;
412
+
413
+ // Ord
414
+ assert ! ( small < big) ;
415
+ assert ! ( !( small < small) ) ;
416
+ assert ! ( !( big < small) ) ;
417
+ assert ! ( !( big < big) ) ;
418
+
419
+ assert ! ( small <= small) ;
420
+ assert ! ( big <= big) ;
421
+
422
+ assert ! ( big > small) ;
423
+ assert ! ( small >= small) ;
424
+ assert ! ( big >= small) ;
425
+ assert ! ( big >= big) ;
426
+
427
+ // TotalEq
428
+ assert ! ( small. equals( & small) ) ;
429
+ assert ! ( big. equals( & big) ) ;
430
+ assert ! ( !small. equals( & big) ) ;
431
+ assert ! ( !big. equals( & small) ) ;
432
+
433
+ // TotalOrd
434
+ assert_eq ! ( small. cmp( & small) , Equal ) ;
435
+ assert_eq ! ( big. cmp( & big) , Equal ) ;
436
+ assert_eq ! ( small. cmp( & big) , Less ) ;
437
+ assert_eq ! ( big. cmp( & small) , Greater ) ;
438
+ }
371
439
}
0 commit comments