about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMarvin Löbel <loebel.marvin@gmail.com>2013-08-11 04:21:31 +0200
committerMarvin Löbel <loebel.marvin@gmail.com>2013-08-14 14:48:25 +0200
commita00becd0eb8c04dc7416a5f8a633b73c9080c65d (patch)
treecdf2407477d66dc4a275e35491e4467a9ae9533e
parent0efbb25a26d9a793ce5aa67e030b3d0bee43f5fa (diff)
downloadrust-a00becd0eb8c04dc7416a5f8a633b73c9080c65d.tar.gz
rust-a00becd0eb8c04dc7416a5f8a633b73c9080c65d.zip
Methodyfied the string ascii extionsion functions
Added into_owned() method for vectors
Added DoubleEnded Iterator impl to Option
Renamed nil.rs to unit.rs
-rw-r--r--src/libstd/option.rs11
-rw-r--r--src/libstd/std.rs2
-rw-r--r--src/libstd/str.rs2
-rw-r--r--src/libstd/str/ascii.rs83
-rw-r--r--src/libstd/unit.rs (renamed from src/libstd/nil.rs)3
-rw-r--r--src/libstd/vec.rs34
6 files changed, 88 insertions, 47 deletions
diff --git a/src/libstd/option.rs b/src/libstd/option.rs
index 04e839cf691..af4fabef78b 100644
--- a/src/libstd/option.rs
+++ b/src/libstd/option.rs
@@ -46,8 +46,8 @@ use cmp::{Eq,Ord};
 use ops::Add;
 use util;
 use num::Zero;
-use iterator::Iterator;
 use iterator;
+use iterator::{Iterator, DoubleEndedIterator};
 use str::{StrSlice, OwnedStr};
 use to_str::ToStr;
 use clone::DeepClone;
@@ -372,7 +372,7 @@ impl<T:Zero> Option<T> {
         }
     }
 
-    /// Returns self or `Some(zero)` (for this type)
+    /// Returns self or `Some`-wrapped zero value
     #[inline]
     pub fn or_zero(self) -> Option<T> {
         match self {
@@ -407,6 +407,13 @@ impl<A> Iterator<A> for OptionIterator<A> {
     }
 }
 
+impl<A> DoubleEndedIterator<A> for OptionIterator<A> {
+    #[inline]
+    fn next_back(&mut self) -> Option<A> {
+        self.opt.take()
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/src/libstd/std.rs b/src/libstd/std.rs
index c4bd0a6d043..9370e7b0e84 100644
--- a/src/libstd/std.rs
+++ b/src/libstd/std.rs
@@ -110,7 +110,7 @@ pub mod prelude;
 #[path = "num/f32.rs"]   pub mod f32;
 #[path = "num/f64.rs"]   pub mod f64;
 
-pub mod nil;
+pub mod unit;
 pub mod bool;
 pub mod char;
 pub mod tuple;
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index b8e61536941..9148767851f 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -1050,7 +1050,7 @@ pub trait Str {
     /// Work with `self` as a slice.
     fn as_slice<'a>(&'a self) -> &'a str;
 
-    /// Convert `self` into a ~str.
+    /// Convert `self` into a ~str, not making a copy if possible
     fn into_owned(self) -> ~str;
 }
 
diff --git a/src/libstd/str/ascii.rs b/src/libstd/str/ascii.rs
index 701d5738815..e0068f5e53e 100644
--- a/src/libstd/str/ascii.rs
+++ b/src/libstd/str/ascii.rs
@@ -23,7 +23,7 @@ use to_bytes::IterBytes;
 use option::{Some, None};
 
 /// Datatype to hold one ascii character. It wraps a `u8`, with the highest bit always zero.
-#[deriving(Clone, Eq)]
+#[deriving(Clone, Eq, Ord, TotalOrd, TotalEq)]
 pub struct Ascii { priv chr: u8 }
 
 impl Ascii {
@@ -250,21 +250,40 @@ impl ToBytesConsume for ~[Ascii] {
     }
 }
 
-
-/// Convert the string to ASCII upper case:
-/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
-/// but non-ASCII letters are unchanged.
-#[inline]
-pub fn to_ascii_upper(string: &str) -> ~str {
-    map_bytes(string, ASCII_UPPER_MAP)
+/// Extension methods for ASCII-subset only operations on strings
+pub trait StrAsciiExt {
+    /// Convert the string to ASCII upper case:
+    /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
+    /// but non-ASCII letters are unchanged.
+    fn to_ascii_upper(&self) -> ~str;
+
+    /// Convert the string to ASCII lower case:
+    /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
+    /// but non-ASCII letters are unchanged.
+    fn to_ascii_lower(&self) -> ~str;
+
+    /// Check that two strings are an ASCII case-insensitive match.
+    /// Same as `to_ascii_lower(a) == to_ascii_lower(b)`,
+    /// but without allocating and copying temporary strings.
+    fn eq_ignore_ascii_case(&self, other: &str) -> bool;
 }
 
-/// Convert the string to ASCII lower case:
-/// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
-/// but non-ASCII letters are unchanged.
-#[inline]
-pub fn to_ascii_lower(string: &str) -> ~str {
-    map_bytes(string, ASCII_LOWER_MAP)
+impl<'self> StrAsciiExt for &'self str {
+    #[inline]
+    fn to_ascii_upper(&self) -> ~str {
+        map_bytes(*self, ASCII_UPPER_MAP)
+    }
+
+    #[inline]
+    fn to_ascii_lower(&self) -> ~str {
+        map_bytes(*self, ASCII_LOWER_MAP)
+    }
+
+    #[inline]
+    fn eq_ignore_ascii_case(&self, other: &str) -> bool {
+        self.len() == other.len() && self.as_bytes().iter().zip(other.as_bytes().iter()).all(
+            |(byte_self, byte_other)| ASCII_LOWER_MAP[*byte_self] == ASCII_LOWER_MAP[*byte_other])
+    }
 }
 
 #[inline]
@@ -283,15 +302,6 @@ fn map_bytes(string: &str, map: &'static [u8]) -> ~str {
     result
 }
 
-/// Check that two strings are an ASCII case-insensitive match.
-/// Same as `to_ascii_lower(a) == to_ascii_lower(b)`,
-/// but without allocating and copying temporary strings.
-#[inline]
-pub fn eq_ignore_ascii_case(a: &str, b: &str) -> bool {
-    a.len() == b.len() && a.as_bytes().iter().zip(b.as_bytes().iter()).all(
-        |(byte_a, byte_b)| ASCII_LOWER_MAP[*byte_a] == ASCII_LOWER_MAP[*byte_b])
-}
-
 static ASCII_LOWER_MAP: &'static [u8] = &[
     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
@@ -453,49 +463,48 @@ mod tests {
 
     #[test]
     fn test_to_ascii_upper() {
-        assert_eq!(to_ascii_upper("url()URL()uRl()ürl"), ~"URL()URL()URL()üRL");
-        assert_eq!(to_ascii_upper("hıKß"), ~"HıKß");
+        assert_eq!("url()URL()uRl()ürl".to_ascii_upper(), ~"URL()URL()URL()üRL");
+        assert_eq!("hıKß".to_ascii_upper(), ~"HıKß");
 
         let mut i = 0;
         while i <= 500 {
             let c = i as char;
             let upper = if 'a' <= c && c <= 'z' { c + 'A' - 'a' } else { c };
-            assert_eq!(to_ascii_upper(from_char(i as char)), from_char(upper))
+            assert_eq!(from_char(i as char).to_ascii_upper(), from_char(upper))
             i += 1;
         }
     }
 
     #[test]
     fn test_to_ascii_lower() {
-        assert_eq!(to_ascii_lower("url()URL()uRl()Ürl"), ~"url()url()url()Ürl");
+        assert_eq!("url()URL()uRl()Ürl".to_ascii_lower(), ~"url()url()url()Ürl");
         // Dotted capital I, Kelvin sign, Sharp S.
-        assert_eq!(to_ascii_lower("HİKß"), ~"hİKß");
+        assert_eq!("HİKß".to_ascii_lower(), ~"hİKß");
 
         let mut i = 0;
         while i <= 500 {
             let c = i as char;
             let lower = if 'A' <= c && c <= 'Z' { c + 'a' - 'A' } else { c };
-            assert_eq!(to_ascii_lower(from_char(i as char)), from_char(lower))
+            assert_eq!(from_char(i as char).to_ascii_lower(), from_char(lower))
             i += 1;
         }
     }
 
-
     #[test]
     fn test_eq_ignore_ascii_case() {
-        assert!(eq_ignore_ascii_case("url()URL()uRl()Ürl", "url()url()url()Ürl"));
-        assert!(!eq_ignore_ascii_case("Ürl", "ürl"));
+        assert!("url()URL()uRl()Ürl".eq_ignore_ascii_case("url()url()url()Ürl"));
+        assert!(!"Ürl".eq_ignore_ascii_case("ürl"));
         // Dotted capital I, Kelvin sign, Sharp S.
-        assert!(eq_ignore_ascii_case("HİKß", "hİKß"));
-        assert!(!eq_ignore_ascii_case("İ", "i"));
-        assert!(!eq_ignore_ascii_case("K", "k"));
-        assert!(!eq_ignore_ascii_case("ß", "s"));
+        assert!("HİKß".eq_ignore_ascii_case("hİKß"));
+        assert!(!"İ".eq_ignore_ascii_case("i"));
+        assert!(!"K".eq_ignore_ascii_case("k"));
+        assert!(!"ß".eq_ignore_ascii_case("s"));
 
         let mut i = 0;
         while i <= 500 {
             let c = i as char;
             let lower = if 'A' <= c && c <= 'Z' { c + 'a' - 'A' } else { c };
-            assert!(eq_ignore_ascii_case(from_char(i as char), from_char(lower)));
+            assert!(from_char(i as char).eq_ignore_ascii_case(from_char(lower)));
             i += 1;
         }
     }
diff --git a/src/libstd/nil.rs b/src/libstd/unit.rs
index d2e9cf9ae7e..82f14e4c8d7 100644
--- a/src/libstd/nil.rs
+++ b/src/libstd/unit.rs
@@ -19,8 +19,6 @@ use prelude::*;
 #[cfg(not(test))]
 use num::Zero;
 
-
-
 #[cfg(not(test))]
 impl Eq for () {
     #[inline]
@@ -54,4 +52,3 @@ impl Zero for () {
     #[inline]
     fn is_zero(&self) -> bool { true }
 }
-
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 27e09d85479..6d27c43def8 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -707,14 +707,17 @@ pub trait Vector<T> {
     /// Work with `self` as a slice.
     fn as_slice<'a>(&'a self) -> &'a [T];
 }
+
 impl<'self,T> Vector<T> for &'self [T] {
     #[inline(always)]
     fn as_slice<'a>(&'a self) -> &'a [T] { *self }
 }
+
 impl<T> Vector<T> for ~[T] {
     #[inline(always)]
     fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v }
 }
+
 impl<T> Vector<T> for @[T] {
     #[inline(always)]
     fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v }
@@ -748,13 +751,17 @@ impl<T> Container for ~[T] {
     }
 }
 
-#[allow(missing_doc)]
+/// Extension methods for vector slices with copyable elements
 pub trait CopyableVector<T> {
+    /// Copy `self` into a new owned vector
     fn to_owned(&self) -> ~[T];
+
+    /// Convert `self` into a owned vector, not making a copy if possible.
+    fn into_owned(self) -> ~[T];
 }
 
-/// Extension methods for vectors
-impl<'self,T:Clone> CopyableVector<T> for &'self [T] {
+/// Extension methods for vector slices
+impl<'self, T: Clone> CopyableVector<T> for &'self [T] {
     /// Returns a copy of `v`.
     #[inline]
     fn to_owned(&self) -> ~[T] {
@@ -764,6 +771,27 @@ impl<'self,T:Clone> CopyableVector<T> for &'self [T] {
         }
         result
     }
+
+    #[inline(always)]
+    fn into_owned(self) -> ~[T] { self.to_owned() }
+}
+
+/// Extension methods for owned vectors
+impl<T: Clone> CopyableVector<T> for ~[T] {
+    #[inline]
+    fn to_owned(&self) -> ~[T] { self.clone() }
+
+    #[inline(always)]
+    fn into_owned(self) -> ~[T] { self }
+}
+
+/// Extension methods for managed vectors
+impl<T: Clone> CopyableVector<T> for @[T] {
+    #[inline]
+    fn to_owned(&self) -> ~[T] { self.as_slice().to_owned() }
+
+    #[inline(always)]
+    fn into_owned(self) -> ~[T] { self.to_owned() }
 }
 
 #[allow(missing_doc)]