]> git.lizzy.rs Git - rust.git/commitdiff
Adapt the getter macro to implement Clone, Eq and Ord for n-ary tuples
authorBrendan Zabarauskas <bjzaba@yahoo.com.au>
Sat, 18 May 2013 11:38:06 +0000 (21:38 +1000)
committerBrendan Zabarauskas <bjzaba@yahoo.com.au>
Sat, 18 May 2013 16:19:16 +0000 (02:19 +1000)
src/libcore/tuple.rs

index c872839146ab08895cf73080c19ac4d28903cf46..27632acf4e8f33eebe8e102267c05048885a1386 100644 (file)
 
 //! Operations on tuples
 
-use clone::Clone;
 use kinds::Copy;
 use vec;
 
-#[cfg(not(test))] use cmp::{Eq, Ord};
-
-pub use self::getters::*;
+pub use self::inner::*;
 
 pub trait CopyableTuple<T, U> {
     fn first(&self) -> T;
@@ -46,16 +43,6 @@ fn swap(&self) -> (U, T) {
         let (t, u) = *self;
         return (u, t);
     }
-
-}
-
-impl<T:Clone,U:Clone> Clone for (T, U) {
-    fn clone(&self) -> (T, U) {
-        let (a, b) = match *self {
-            (ref a, ref b) => (a, b)
-        };
-        (a.clone(), b.clone())
-    }
 }
 
 pub trait ImmutableTuple<T, U> {
@@ -124,158 +111,81 @@ fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] {
     }
 }
 
-#[cfg(not(test))]
-impl<A:Eq> Eq for (A,) {
-    #[inline(always)]
-    fn eq(&self, other: &(A,)) -> bool {
-        match (*self) {
-            (ref self_a,) => match other {
-                &(ref other_a,) => {
-                    (*self_a).eq(other_a)
-                }
-            }
+// macro for implementing n-ary tuple functions and operations
+
+macro_rules! tuple_impls(
+    ($(
+        $name:ident {
+            $(fn $get_fn:ident -> $T:ident { $get_pattern:pat => $ret:expr })+
         }
-    }
-    #[inline(always)]
-    fn ne(&self, other: &(A,)) -> bool { !(*self).eq(other) }
-}
+    )+) => (
+        pub mod inner {
+            use clone::Clone;
+            #[cfg(not(test))] use cmp::{Eq, Ord};
 
-#[cfg(not(test))]
-impl<A:Ord> Ord for (A,) {
-    #[inline(always)]
-    fn lt(&self, other: &(A,)) -> bool {
-        match (*self) {
-            (ref self_a,) => {
-                match (*other) {
-                    (ref other_a,) => {
-                        if (*self_a).lt(other_a) { return true; }
-                        return false;
-                    }
+            $(
+                pub trait $name<$($T),+> {
+                    $(fn $get_fn<'a>(&'a self) -> &'a $T;)+
                 }
-            }
-        }
-    }
-    #[inline(always)]
-    fn le(&self, other: &(A,)) -> bool { !other.lt(&(*self)) }
-    #[inline(always)]
-    fn ge(&self, other: &(A,)) -> bool { !self.lt(other) }
-    #[inline(always)]
-    fn gt(&self, other: &(A,)) -> bool { other.lt(&(*self))  }
-}
 
-#[cfg(not(test))]
-impl<A:Eq,B:Eq> Eq for (A, B) {
-    #[inline(always)]
-    fn eq(&self, other: &(A, B)) -> bool {
-        match (*self) {
-            (ref self_a, ref self_b) => match other {
-                &(ref other_a, ref other_b) => {
-                    (*self_a).eq(other_a) && (*self_b).eq(other_b)
+                impl<$($T),+> $name<$($T),+> for ($($T),+) {
+                    $(
+                        #[inline(always)]
+                        fn $get_fn<'a>(&'a self) -> &'a $T {
+                            match *self {
+                                $get_pattern => $ret
+                            }
+                        }
+                    )+
                 }
-            }
-        }
-    }
-    #[inline(always)]
-    fn ne(&self, other: &(A, B)) -> bool { !(*self).eq(other) }
-}
 
-#[cfg(not(test))]
-impl<A:Ord,B:Ord> Ord for (A, B) {
-    #[inline(always)]
-    fn lt(&self, other: &(A, B)) -> bool {
-        match (*self) {
-            (ref self_a, ref self_b) => {
-                match (*other) {
-                    (ref other_a, ref other_b) => {
-                        if (*self_a).lt(other_a) { return true; }
-                        if (*other_a).lt(self_a) { return false; }
-                        if (*self_b).lt(other_b) { return true; }
-                        return false;
+                impl<$($T:Clone),+> Clone for ($($T),+) {
+                    fn clone(&self) -> ($($T),+) {
+                        ($(self.$get_fn().clone()),+)
                     }
                 }
-            }
-        }
-    }
-    #[inline(always)]
-    fn le(&self, other: &(A, B)) -> bool { !(*other).lt(&(*self)) }
-    #[inline(always)]
-    fn ge(&self, other: &(A, B)) -> bool { !(*self).lt(other) }
-    #[inline(always)]
-    fn gt(&self, other: &(A, B)) -> bool { (*other).lt(&(*self))  }
-}
 
-#[cfg(not(test))]
-impl<A:Eq,B:Eq,C:Eq> Eq for (A, B, C) {
-    #[inline(always)]
-    fn eq(&self, other: &(A, B, C)) -> bool {
-        match (*self) {
-            (ref self_a, ref self_b, ref self_c) => match other {
-                &(ref other_a, ref other_b, ref other_c) => {
-                    (*self_a).eq(other_a) && (*self_b).eq(other_b)
-                        && (*self_c).eq(other_c)
-                }
-            }
-        }
-    }
-    #[inline(always)]
-    fn ne(&self, other: &(A, B, C)) -> bool { !(*self).eq(other) }
-}
+                #[cfg(not(test))]
+                impl<$($T:Eq),+> Eq for ($($T),+) {
+                    #[inline(always)]
+                    fn eq(&self, other: &($($T),+)) -> bool {
+                        $(*self.$get_fn() == *other.$get_fn())&&+
+                    }
 
-#[cfg(not(test))]
-impl<A:Ord,B:Ord,C:Ord> Ord for (A, B, C) {
-    #[inline(always)]
-    fn lt(&self, other: &(A, B, C)) -> bool {
-        match (*self) {
-            (ref self_a, ref self_b, ref self_c) => {
-                match (*other) {
-                    (ref other_a, ref other_b, ref other_c) => {
-                        if (*self_a).lt(other_a) { return true; }
-                        if (*other_a).lt(self_a) { return false; }
-                        if (*self_b).lt(other_b) { return true; }
-                        if (*other_b).lt(self_b) { return false; }
-                        if (*self_c).lt(other_c) { return true; }
-                        return false;
+                    #[inline(always)]
+                    fn ne(&self, other: &($($T),+)) -> bool {
+                        !(*self == *other)
                     }
                 }
-            }
-        }
-    }
-    #[inline(always)]
-    fn le(&self, other: &(A, B, C)) -> bool { !(*other).lt(&(*self)) }
-    #[inline(always)]
-    fn ge(&self, other: &(A, B, C)) -> bool { !(*self).lt(other) }
-    #[inline(always)]
-    fn gt(&self, other: &(A, B, C)) -> bool { (*other).lt(&(*self))  }
-}
 
-// Tuple element getters
+                #[cfg(not(test))]
+                impl<$($T:Ord),+> Ord for ($($T),+) {
+                    #[inline(always)]
+                    fn lt(&self, other: &($($T),+)) -> bool {
+                        $(*self.$get_fn() < *other.$get_fn())&&+
+                    }
 
-macro_rules! tuple_getters(
-    ($(
-        $name:ident {
-            $(fn $method:ident -> $T:ident { $accessor:pat => $t:expr })+
-        }
-    )+) => (
-        pub mod getters {
-            $(pub trait $name<$($T),+> {
-                    $(fn $method<'a>(&'a self) -> &'a $T;)+
-            })+
+                    #[inline(always)]
+                    fn le(&self, other: &($($T),+)) -> bool {
+                        $(*self.$get_fn() <= *other.$get_fn())&&+
+                    }
 
-            $(impl<$($T),+> $name<$($T),+> for ($($T),+) {
-                $(
                     #[inline(always)]
-                    fn $method<'a>(&'a self) -> &'a $T {
-                        match *self {
-                            $accessor => $t
-                        }
+                    fn ge(&self, other: &($($T),+)) -> bool {
+                        $(*self.$get_fn() >= *other.$get_fn())&&+
                     }
-                )+
-            })+
+
+                    #[inline(always)]
+                    fn gt(&self, other: &($($T),+)) -> bool {
+                        $(*self.$get_fn() > *other.$get_fn())&&+
+                    }
+                }
+            )+
         }
     )
 )
 
-tuple_getters!(
+tuple_impls!(
     Tuple2 {
         fn n0 -> A { (ref a,_) => a }
         fn n1 -> B { (_,ref b) => b }