Skip to content

Commit a00becd

Browse files
committed
Methodyfied the string ascii extionsion functions
Added into_owned() method for vectors Added DoubleEnded Iterator impl to Option Renamed nil.rs to unit.rs
1 parent 0efbb25 commit a00becd

File tree

6 files changed

+88
-47
lines changed

6 files changed

+88
-47
lines changed

src/libstd/option.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ use cmp::{Eq,Ord};
4646
use ops::Add;
4747
use util;
4848
use num::Zero;
49-
use iterator::Iterator;
5049
use iterator;
50+
use iterator::{Iterator, DoubleEndedIterator};
5151
use str::{StrSlice, OwnedStr};
5252
use to_str::ToStr;
5353
use clone::DeepClone;
@@ -372,7 +372,7 @@ impl<T:Zero> Option<T> {
372372
}
373373
}
374374

375-
/// Returns self or `Some(zero)` (for this type)
375+
/// Returns self or `Some`-wrapped zero value
376376
#[inline]
377377
pub fn or_zero(self) -> Option<T> {
378378
match self {
@@ -407,6 +407,13 @@ impl<A> Iterator<A> for OptionIterator<A> {
407407
}
408408
}
409409

410+
impl<A> DoubleEndedIterator<A> for OptionIterator<A> {
411+
#[inline]
412+
fn next_back(&mut self) -> Option<A> {
413+
self.opt.take()
414+
}
415+
}
416+
410417
#[cfg(test)]
411418
mod tests {
412419
use super::*;

src/libstd/std.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ pub mod prelude;
110110
#[path = "num/f32.rs"] pub mod f32;
111111
#[path = "num/f64.rs"] pub mod f64;
112112

113-
pub mod nil;
113+
pub mod unit;
114114
pub mod bool;
115115
pub mod char;
116116
pub mod tuple;

src/libstd/str.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1050,7 +1050,7 @@ pub trait Str {
10501050
/// Work with `self` as a slice.
10511051
fn as_slice<'a>(&'a self) -> &'a str;
10521052
1053-
/// Convert `self` into a ~str.
1053+
/// Convert `self` into a ~str, not making a copy if possible
10541054
fn into_owned(self) -> ~str;
10551055
}
10561056

src/libstd/str/ascii.rs

+46-37
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use to_bytes::IterBytes;
2323
use option::{Some, None};
2424

2525
/// Datatype to hold one ascii character. It wraps a `u8`, with the highest bit always zero.
26-
#[deriving(Clone, Eq)]
26+
#[deriving(Clone, Eq, Ord, TotalOrd, TotalEq)]
2727
pub struct Ascii { priv chr: u8 }
2828

2929
impl Ascii {
@@ -250,21 +250,40 @@ impl ToBytesConsume for ~[Ascii] {
250250
}
251251
}
252252

253-
254-
/// Convert the string to ASCII upper case:
255-
/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
256-
/// but non-ASCII letters are unchanged.
257-
#[inline]
258-
pub fn to_ascii_upper(string: &str) -> ~str {
259-
map_bytes(string, ASCII_UPPER_MAP)
253+
/// Extension methods for ASCII-subset only operations on strings
254+
pub trait StrAsciiExt {
255+
/// Convert the string to ASCII upper case:
256+
/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
257+
/// but non-ASCII letters are unchanged.
258+
fn to_ascii_upper(&self) -> ~str;
259+
260+
/// Convert the string to ASCII lower case:
261+
/// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
262+
/// but non-ASCII letters are unchanged.
263+
fn to_ascii_lower(&self) -> ~str;
264+
265+
/// Check that two strings are an ASCII case-insensitive match.
266+
/// Same as `to_ascii_lower(a) == to_ascii_lower(b)`,
267+
/// but without allocating and copying temporary strings.
268+
fn eq_ignore_ascii_case(&self, other: &str) -> bool;
260269
}
261270

262-
/// Convert the string to ASCII lower case:
263-
/// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
264-
/// but non-ASCII letters are unchanged.
265-
#[inline]
266-
pub fn to_ascii_lower(string: &str) -> ~str {
267-
map_bytes(string, ASCII_LOWER_MAP)
271+
impl<'self> StrAsciiExt for &'self str {
272+
#[inline]
273+
fn to_ascii_upper(&self) -> ~str {
274+
map_bytes(*self, ASCII_UPPER_MAP)
275+
}
276+
277+
#[inline]
278+
fn to_ascii_lower(&self) -> ~str {
279+
map_bytes(*self, ASCII_LOWER_MAP)
280+
}
281+
282+
#[inline]
283+
fn eq_ignore_ascii_case(&self, other: &str) -> bool {
284+
self.len() == other.len() && self.as_bytes().iter().zip(other.as_bytes().iter()).all(
285+
|(byte_self, byte_other)| ASCII_LOWER_MAP[*byte_self] == ASCII_LOWER_MAP[*byte_other])
286+
}
268287
}
269288

270289
#[inline]
@@ -283,15 +302,6 @@ fn map_bytes(string: &str, map: &'static [u8]) -> ~str {
283302
result
284303
}
285304

286-
/// Check that two strings are an ASCII case-insensitive match.
287-
/// Same as `to_ascii_lower(a) == to_ascii_lower(b)`,
288-
/// but without allocating and copying temporary strings.
289-
#[inline]
290-
pub fn eq_ignore_ascii_case(a: &str, b: &str) -> bool {
291-
a.len() == b.len() && a.as_bytes().iter().zip(b.as_bytes().iter()).all(
292-
|(byte_a, byte_b)| ASCII_LOWER_MAP[*byte_a] == ASCII_LOWER_MAP[*byte_b])
293-
}
294-
295305
static ASCII_LOWER_MAP: &'static [u8] = &[
296306
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
297307
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
@@ -453,49 +463,48 @@ mod tests {
453463
454464
#[test]
455465
fn test_to_ascii_upper() {
456-
assert_eq!(to_ascii_upper("url()URL()uRl()ürl"), ~"URL()URL()URL()üRL");
457-
assert_eq!(to_ascii_upper("hıKß"), ~"HıKß");
466+
assert_eq!("url()URL()uRl()ürl".to_ascii_upper(), ~"URL()URL()URL()üRL");
467+
assert_eq!("hıKß".to_ascii_upper(), ~"HıKß");
458468
459469
let mut i = 0;
460470
while i <= 500 {
461471
let c = i as char;
462472
let upper = if 'a' <= c && c <= 'z' { c + 'A' - 'a' } else { c };
463-
assert_eq!(to_ascii_upper(from_char(i as char)), from_char(upper))
473+
assert_eq!(from_char(i as char).to_ascii_upper(), from_char(upper))
464474
i += 1;
465475
}
466476
}
467477
468478
#[test]
469479
fn test_to_ascii_lower() {
470-
assert_eq!(to_ascii_lower("url()URL()uRl()Ürl"), ~"url()url()url()Ürl");
480+
assert_eq!("url()URL()uRl()Ürl".to_ascii_lower(), ~"url()url()url()Ürl");
471481
// Dotted capital I, Kelvin sign, Sharp S.
472-
assert_eq!(to_ascii_lower("HİKß"), ~"hİKß");
482+
assert_eq!("HİKß".to_ascii_lower(), ~"hİKß");
473483
474484
let mut i = 0;
475485
while i <= 500 {
476486
let c = i as char;
477487
let lower = if 'A' <= c && c <= 'Z' { c + 'a' - 'A' } else { c };
478-
assert_eq!(to_ascii_lower(from_char(i as char)), from_char(lower))
488+
assert_eq!(from_char(i as char).to_ascii_lower(), from_char(lower))
479489
i += 1;
480490
}
481491
}
482492
483-
484493
#[test]
485494
fn test_eq_ignore_ascii_case() {
486-
assert!(eq_ignore_ascii_case("url()URL()uRl()Ürl", "url()url()url()Ürl"));
487-
assert!(!eq_ignore_ascii_case("Ürl", "ürl"));
495+
assert!("url()URL()uRl()Ürl".eq_ignore_ascii_case("url()url()url()Ürl"));
496+
assert!(!"Ürl".eq_ignore_ascii_case("ürl"));
488497
// Dotted capital I, Kelvin sign, Sharp S.
489-
assert!(eq_ignore_ascii_case("HİKß", "hİKß"));
490-
assert!(!eq_ignore_ascii_case("İ", "i"));
491-
assert!(!eq_ignore_ascii_case("", "k"));
492-
assert!(!eq_ignore_ascii_case("ß", "s"));
498+
assert!("HİKß".eq_ignore_ascii_case("hİKß"));
499+
assert!(!"İ".eq_ignore_ascii_case("i"));
500+
assert!(!"".eq_ignore_ascii_case("k"));
501+
assert!(!"ß".eq_ignore_ascii_case("s"));
493502

494503
let mut i = 0;
495504
while i <= 500 {
496505
let c = i as char;
497506
let lower = if 'A' <= c && c <= 'Z' { c + 'a' - 'A' } else { c };
498-
assert!(eq_ignore_ascii_case(from_char(i as char), from_char(lower)));
507+
assert!(from_char(i as char).eq_ignore_ascii_case(from_char(lower)));
499508
i += 1;
500509
}
501510
}

src/libstd/nil.rs renamed to src/libstd/unit.rs

-3
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ use prelude::*;
1919
#[cfg(not(test))]
2020
use num::Zero;
2121

22-
23-
2422
#[cfg(not(test))]
2523
impl Eq for () {
2624
#[inline]
@@ -54,4 +52,3 @@ impl Zero for () {
5452
#[inline]
5553
fn is_zero(&self) -> bool { true }
5654
}
57-

src/libstd/vec.rs

+31-3
Original file line numberDiff line numberDiff line change
@@ -707,14 +707,17 @@ pub trait Vector<T> {
707707
/// Work with `self` as a slice.
708708
fn as_slice<'a>(&'a self) -> &'a [T];
709709
}
710+
710711
impl<'self,T> Vector<T> for &'self [T] {
711712
#[inline(always)]
712713
fn as_slice<'a>(&'a self) -> &'a [T] { *self }
713714
}
715+
714716
impl<T> Vector<T> for ~[T] {
715717
#[inline(always)]
716718
fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v }
717719
}
720+
718721
impl<T> Vector<T> for @[T] {
719722
#[inline(always)]
720723
fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v }
@@ -748,13 +751,17 @@ impl<T> Container for ~[T] {
748751
}
749752
}
750753

751-
#[allow(missing_doc)]
754+
/// Extension methods for vector slices with copyable elements
752755
pub trait CopyableVector<T> {
756+
/// Copy `self` into a new owned vector
753757
fn to_owned(&self) -> ~[T];
758+
759+
/// Convert `self` into a owned vector, not making a copy if possible.
760+
fn into_owned(self) -> ~[T];
754761
}
755762

756-
/// Extension methods for vectors
757-
impl<'self,T:Clone> CopyableVector<T> for &'self [T] {
763+
/// Extension methods for vector slices
764+
impl<'self, T: Clone> CopyableVector<T> for &'self [T] {
758765
/// Returns a copy of `v`.
759766
#[inline]
760767
fn to_owned(&self) -> ~[T] {
@@ -764,6 +771,27 @@ impl<'self,T:Clone> CopyableVector<T> for &'self [T] {
764771
}
765772
result
766773
}
774+
775+
#[inline(always)]
776+
fn into_owned(self) -> ~[T] { self.to_owned() }
777+
}
778+
779+
/// Extension methods for owned vectors
780+
impl<T: Clone> CopyableVector<T> for ~[T] {
781+
#[inline]
782+
fn to_owned(&self) -> ~[T] { self.clone() }
783+
784+
#[inline(always)]
785+
fn into_owned(self) -> ~[T] { self }
786+
}
787+
788+
/// Extension methods for managed vectors
789+
impl<T: Clone> CopyableVector<T> for @[T] {
790+
#[inline]
791+
fn to_owned(&self) -> ~[T] { self.as_slice().to_owned() }
792+
793+
#[inline(always)]
794+
fn into_owned(self) -> ~[T] { self.to_owned() }
767795
}
768796

769797
#[allow(missing_doc)]

0 commit comments

Comments
 (0)