auto merge of #5234 : pcwalton/rust/equiv, r=pcwalton

r? @nikomatsakis
This commit is contained in:
bors
2013-03-05 12:12:50 -08:00
24 changed files with 111 additions and 28 deletions
+8
View File
@@ -150,6 +150,14 @@ pub trait Ord {
(*v1).gt(v2)
}
/// The equivalence relation. Two values may be equivalent even if they are
/// of different types. The most common use case for this relation is
/// container types; e.g. it is often desirable to be able to use `&str`
/// values to look up entries in a container with `~str` keys.
pub trait Equiv<T> {
pure fn equiv(&self, other: &T) -> bool;
}
#[inline(always)]
pub pure fn min<T:Ord>(v1: T, v2: T) -> T {
if v1 < v2 { v1 } else { v2 }
+1
View File
@@ -10,6 +10,7 @@
//! Container traits
use cmp::Equiv;
use option::Option;
pub trait Container {
+50 -1
View File
@@ -13,7 +13,7 @@
/// Open addressing with linear probing.
pub mod linear {
use container::{Container, Mutable, Map, Set};
use cmp::Eq;
use cmp::{Eq, Equiv};
use hash::Hash;
use to_bytes::IterBytes;
use iter::BaseIter;
@@ -107,6 +107,15 @@ pub fn linear_map_with_capacity<K:Eq + Hash,V>(
self.bucket_for_key_with_hash(hash, k)
}
#[inline(always)]
pure fn bucket_for_key_equiv<Q:Hash + IterBytes + Equiv<K>>(
&self,
k: &Q)
-> SearchResult {
let hash = k.hash_keyed(self.k0, self.k1) as uint;
self.bucket_for_key_with_hash_equiv(hash, k)
}
#[inline(always)]
pure fn bucket_for_key_with_hash(&self,
hash: uint,
@@ -122,6 +131,24 @@ pub fn linear_map_with_capacity<K:Eq + Hash,V>(
TableFull
}
#[inline(always)]
pure fn bucket_for_key_with_hash_equiv<Q:Equiv<K>>(&self,
hash: uint,
k: &Q)
-> SearchResult {
let _ = for self.bucket_sequence(hash) |i| {
match self.buckets[i] {
Some(ref bkt) => {
if bkt.hash == hash && k.equiv(&bkt.key) {
return FoundEntry(i);
}
},
None => return FoundHole(i)
}
};
TableFull
}
/// Expand the capacity of the array to the next power of two
/// and re-insert each of the existing buckets.
#[inline(always)]
@@ -450,6 +477,28 @@ fn consume(&mut self, f: fn(K, V)) {
None => fail!(fmt!("No entry found for key: %?", k)),
}
}
/// Return true if the map contains a value for the specified key,
/// using equivalence
pure fn contains_key_equiv<Q:Hash + IterBytes + Equiv<K>>(
&self,
key: &Q)
-> bool {
match self.bucket_for_key_equiv(key) {
FoundEntry(_) => {true}
TableFull | FoundHole(_) => {false}
}
}
/// Return the value corresponding to the key in the map, using
/// equivalence
pure fn find_equiv<Q:Hash + IterBytes + Equiv<K>>(&self, k: &Q)
-> Option<&self/V> {
match self.bucket_for_key_equiv(k) {
FoundEntry(idx) => Some(self.value_for_bucket(idx)),
TableFull | FoundHole(_) => None,
}
}
}
impl<K:Hash + IterBytes + Eq,V:Eq> Eq for LinearMap<K, V> {
+7 -1
View File
@@ -20,7 +20,7 @@
use at_vec;
use cast;
use char;
use cmp::{TotalOrd, Ordering, Less, Equal, Greater};
use cmp::{Equiv, TotalOrd, Ordering, Less, Equal, Greater};
use libc;
use option::{None, Option, Some};
use ptr;
@@ -898,6 +898,12 @@ impl Ord for @str {
pure fn gt(&self, other: &@str) -> bool { gt((*self), (*other)) }
}
#[cfg(notest)]
impl Equiv<~str> for &str {
#[inline(always)]
pure fn equiv(&self, other: &~str) -> bool { eq_slice(*self, *other) }
}
/*
Section: Iterating through strings
*/
+7 -1
View File
@@ -14,7 +14,7 @@
use container::{Container, Mutable};
use cast;
use cmp::{Eq, Ord, TotalOrd, Ordering, Less, Equal, Greater};
use cmp::{Eq, Equiv, Ord, TotalOrd, Ordering, Less, Equal, Greater};
use iter::BaseIter;
use iter;
use kinds::Copy;
@@ -1572,6 +1572,12 @@ impl<T:Eq> Eq for @[T] {
pure fn ne(&self, other: &@[T]) -> bool { !(*self).eq(other) }
}
#[cfg(notest)]
impl<T:Eq> Equiv<~[T]> for &[T] {
#[inline(always)]
pure fn equiv(&self, other: &~[T]) -> bool { eq(*self, *other) }
}
// Lexicographical comparison
pure fn cmp<T: TotalOrd>(a: &[T], b: &[T]) -> Ordering {
+1 -1
View File
@@ -214,7 +214,7 @@ fn mk_pointer<AC:AstConv,RS:region_scope + Copy + Durable>(
let mut mt = ast_mt_to_mt(self, rscope, mt);
if a_seq_ty.mutbl == ast::m_mutbl ||
a_seq_ty.mutbl == ast::m_const {
mt = ty::mt { ty: mt.ty, mutbl: ast::m_mutbl };
mt = ty::mt { ty: mt.ty, mutbl: a_seq_ty.mutbl };
}
return ty::mk_evec(tcx, mt, vst);
}
+1 -1
View File
@@ -3112,7 +3112,7 @@ fn parse_trait_ref(&self) -> @trait_ref {
fn parse_trait_ref_list(&self, ket: &token::Token) -> ~[@trait_ref] {
self.parse_seq_to_before_end(
ket,
seq_sep_none(),
seq_sep_trailing_disallowed(token::BINOP(token::PLUS)),
|p| p.parse_trait_ref()
)
}
+4 -1
View File
@@ -600,8 +600,11 @@ pub fn print_item(s: @ps, &&item: @ast::item) {
print_generics(s, generics);
if traits.len() != 0u {
word(s.s, ~":");
for traits.each |trait_| {
for traits.eachi |i, trait_| {
nbsp(s);
if i != 0 {
word_space(s, ~"+");
}
print_path(s, trait_.path, false);
}
}
@@ -12,6 +12,6 @@
trait Bar { fn g() -> int; }
trait Baz { fn h() -> int; }
trait Quux: Foo Bar Baz { }
trait Quux: Foo + Bar + Baz { }
impl<T:Foo + Bar + Baz> Quux for T { }
@@ -10,7 +10,7 @@
use core::cmp::Eq;
pub trait MyNum : Add<Self,Self> Sub<Self,Self> Mul<Self,Self> Eq {
pub trait MyNum : Add<Self,Self> + Sub<Self,Self> + Mul<Self,Self> + Eq {
}
pub struct MyInt {
+9 -6
View File
@@ -10,12 +10,15 @@
use core::cmp::Eq;
trait Hahaha: Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq //~ ERROR Duplicate supertrait in trait declaration
Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq
Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq
Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq
Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq
Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq Eq {}
trait Hahaha: Eq + Eq + Eq + Eq + Eq + //~ ERROR Duplicate supertrait
Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq +
Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq +
Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq +
Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq +
Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq +
Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq +
Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq +
Eq {}
enum Lol = int;
+7
View File
@@ -0,0 +1,7 @@
fn f(_: &const [int]) {}
fn main() {
let v = [ 1, 2, 3 ];
f(v);
}
@@ -17,7 +17,7 @@
use aux::{Foo, Bar, Baz, A};
// We want to extend all Foo, Bar, Bazes to Quuxes
pub trait Quux: Foo Bar Baz { }
pub trait Quux: Foo + Bar + Baz { }
impl<T:Foo + Bar + Baz> Quux for T { }
fn f<T:Quux>(a: &T) {
+1 -1
View File
@@ -16,7 +16,7 @@ impl<T:Foo + Bar + Baz> Quux for T { }
trait Bar { fn g() -> int; }
trait Baz { fn h() -> int; }
trait Quux: Foo Bar Baz { }
trait Quux: Foo + Bar + Baz { }
struct A { x: int }
@@ -13,7 +13,7 @@
trait A { fn a(&self) -> int; }
trait B: A { fn b(&self) -> int; }
trait C: A { fn c(&self) -> int; }
trait D: B C { fn d(&self) -> int; }
trait D: B + C { fn d(&self) -> int; }
struct S { bogus: () }
+2 -2
View File
@@ -16,9 +16,9 @@
extern mod std;
use std::cmp::FuzzyEq;
pub trait NumExt: NumCast Eq Ord {}
pub trait NumExt: NumCast + Eq + Ord {}
pub trait FloatExt: NumExt FuzzyEq<Self> {}
pub trait FloatExt: NumExt + FuzzyEq<Self> {}
fn greater_than_one<T:NumExt>(n: &T) -> bool { *n > from(1) }
fn greater_than_one_float<T:FloatExt>(n: &T) -> bool { *n > from(1) }
+1 -1
View File
@@ -19,7 +19,7 @@ trait Num {
fn gt(&self, other: &Self) -> bool;
}
pub trait NumExt: Num NumCast { }
pub trait NumExt: Num + NumCast { }
fn greater_than_one<T:NumExt>(n: &T) -> bool {
n.gt(&from(1))
+1 -1
View File
@@ -11,7 +11,7 @@
use core::cmp::Ord;
use core::num::NumCast::from;
pub trait NumExt: NumCast Ord { }
pub trait NumExt: NumCast + Ord { }
fn greater_than_one<T:NumExt>(n: &T) -> bool {
*n > from(1)
+2 -2
View File
@@ -38,7 +38,7 @@ impl TypeExt for f64 {}
impl TypeExt for float {}
pub trait NumExt: TypeExt Eq Ord NumCast {}
pub trait NumExt: TypeExt + Eq + Ord + NumCast {}
impl NumExt for u8 {}
impl NumExt for u16 {}
@@ -94,7 +94,7 @@ impl IntegerExt for i64 {}
impl IntegerExt for int {}
pub trait FloatExt: NumExt FuzzyEq<Self> {}
pub trait FloatExt: NumExt + FuzzyEq<Self> {}
impl FloatExt for f32 {}
impl FloatExt for f64 {}
+1 -1
View File
@@ -11,7 +11,7 @@
use core::cmp::{Eq, Ord};
use core::num::NumCast::from;
pub trait NumExt: Eq Ord NumCast {}
pub trait NumExt: Eq + Ord + NumCast {}
impl NumExt for f32 {}
+1 -1
View File
@@ -11,7 +11,7 @@
use core::cmp::{Eq, Ord};
use core::num::NumCast::from;
pub trait NumExt: Eq NumCast {}
pub trait NumExt: Eq + NumCast {}
impl NumExt for f32 {}
impl NumExt for int {}
@@ -10,7 +10,7 @@
use core::cmp::Eq;
trait MyNum : Add<Self,Self> Sub<Self,Self> Mul<Self,Self> Eq { }
trait MyNum : Add<Self,Self> + Sub<Self,Self> + Mul<Self,Self> + Eq { }
struct MyInt { val: int }
@@ -14,7 +14,7 @@ trait MyNum {
static fn from_int(int) -> Self;
}
pub trait NumExt: MyEq MyNum { }
pub trait NumExt: MyEq + MyNum { }
struct S { v: int }
+1 -1
View File
@@ -12,7 +12,7 @@
trait Bar { fn g() -> int; }
trait Baz { fn h() -> int; }
trait Quux: Foo Bar Baz { }
trait Quux: Foo + Bar + Baz { }
struct A { x: int }