Skip to content

Some small changes for consistency #8452

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions src/libstd/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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::*;
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
83 changes: 46 additions & 37 deletions src/libstd/str/ascii.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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]
Expand All @@ -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,
Expand Down Expand Up @@ -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;
}
}
Expand Down
3 changes: 0 additions & 3 deletions src/libstd/nil.rs → src/libstd/unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ use prelude::*;
#[cfg(not(test))]
use num::Zero;



#[cfg(not(test))]
impl Eq for () {
#[inline]
Expand Down Expand Up @@ -54,4 +52,3 @@ impl Zero for () {
#[inline]
fn is_zero(&self) -> bool { true }
}

34 changes: 31 additions & 3 deletions src/libstd/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down Expand Up @@ -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] {
Expand All @@ -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)]
Expand Down