]> git.lizzy.rs Git - rust.git/blob - src/libstd/str.rs
auto merge of #13099 : FlaPer87/rust/master, r=huonw
[rust.git] / src / libstd / str.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 /*!
12
13 Unicode string manipulation (`str` type)
14
15 # Basic Usage
16
17 Rust's string type is one of the core primitive types of the language. While
18 represented by the name `str`, the name `str` is not actually a valid type in
19 Rust. Each string must also be decorated with its ownership. This means that
20 there are two common kinds of strings in Rust:
21
22 * `~str` - This is an owned string. This type obeys all of the normal semantics
23            of the `~T` types, meaning that it has one, and only one, owner. This
24            type cannot be implicitly copied, and is moved out of when passed to
25            other functions.
26
27 * `&str` - This is the borrowed string type. This type of string can only be
28            created from the other kind of string. As the name "borrowed"
29            implies, this type of string is owned elsewhere, and this string
30            cannot be moved out of.
31
32 As an example, here's a few different kinds of strings.
33
34 ```rust
35 fn main() {
36     let owned_string = ~"I am an owned string";
37     let borrowed_string1 = "This string is borrowed with the 'static lifetime";
38     let borrowed_string2: &str = owned_string;   // owned strings can be borrowed
39 }
40  ```
41
42 From the example above, you can see that Rust has 2 different kinds of string
43 literals. The owned literals correspond to the owned string types, but the
44 "borrowed literal" is actually more akin to C's concept of a static string.
45
46 When a string is declared without a `~` sigil, then the string is allocated
47 statically in the rodata of the executable/library. The string then has the
48 type `&'static str` meaning that the string is valid for the `'static`
49 lifetime, otherwise known as the lifetime of the entire program. As can be
50 inferred from the type, these static strings are not mutable.
51
52 # Mutability
53
54 Many languages have immutable strings by default, and Rust has a particular
55 flavor on this idea. As with the rest of Rust types, strings are immutable by
56 default. If a string is declared as `mut`, however, it may be mutated. This
57 works the same way as the rest of Rust's type system in the sense that if
58 there's a mutable reference to a string, there may only be one mutable reference
59 to that string. With these guarantees, strings can easily transition between
60 being mutable/immutable with the same benefits of having mutable strings in
61 other languages.
62
63 ```rust
64 let mut buf = ~"testing";
65 buf.push_char(' ');
66 buf.push_str("123");
67 assert_eq!(buf, ~"testing 123");
68  ```
69
70 # Representation
71
72 Rust's string type, `str`, is a sequence of unicode codepoints encoded as a
73 stream of UTF-8 bytes. All safely-created strings are guaranteed to be validly
74 encoded UTF-8 sequences. Additionally, strings are not null-terminated
75 and can contain null codepoints.
76
77 The actual representation of strings have direct mappings to vectors:
78
79 * `~str` is the same as `~[u8]`
80 * `&str` is the same as `&[u8]`
81
82 */
83
84 use cast;
85 use cast::transmute;
86 use char;
87 use char::Char;
88 use clone::Clone;
89 use cmp::{Eq, TotalEq, Ord, TotalOrd, Equiv, Ordering};
90 use container::{Container, Mutable};
91 use fmt;
92 use io::Writer;
93 use iter::{Iterator, FromIterator, Extendable, range};
94 use iter::{Filter, AdditiveIterator, Map};
95 use iter::{Rev, DoubleEndedIterator, ExactSize};
96 use libc;
97 use num::Saturating;
98 use option::{None, Option, Some};
99 use ptr;
100 use ptr::RawPtr;
101 use from_str::FromStr;
102 use slice;
103 use slice::{OwnedVector, OwnedCloneableVector, ImmutableVector, MutableVector};
104 use slice::{Vector};
105 use vec::Vec;
106 use default::Default;
107 use raw::Repr;
108
109 /*
110 Section: Creating a string
111 */
112
113 /// Consumes a vector of bytes to create a new utf-8 string.
114 /// Returns None if the vector contains invalid UTF-8.
115 pub fn from_utf8_owned(vv: ~[u8]) -> Option<~str> {
116     if is_utf8(vv) {
117         Some(unsafe { raw::from_utf8_owned(vv) })
118     } else {
119         None
120     }
121 }
122
123 /// Converts a vector to a string slice without performing any allocations.
124 ///
125 /// Once the slice has been validated as utf-8, it is transmuted in-place and
126 /// returned as a '&str' instead of a '&[u8]'
127 ///
128 /// Returns None if the slice is not utf-8.
129 pub fn from_utf8<'a>(v: &'a [u8]) -> Option<&'a str> {
130     if is_utf8(v) {
131         Some(unsafe { raw::from_utf8(v) })
132     } else { None }
133 }
134
135 impl FromStr for ~str {
136     #[inline]
137     fn from_str(s: &str) -> Option<~str> { Some(s.to_owned()) }
138 }
139
140 /// Convert a byte to a UTF-8 string
141 ///
142 /// # Failure
143 ///
144 /// Fails if invalid UTF-8
145 pub fn from_byte(b: u8) -> ~str {
146     assert!(b < 128u8);
147     unsafe { ::cast::transmute(~[b]) }
148 }
149
150 /// Convert a char to a string
151 pub fn from_char(ch: char) -> ~str {
152     let mut buf = ~"";
153     buf.push_char(ch);
154     buf
155 }
156
157 /// Convert a vector of chars to a string
158 pub fn from_chars(chs: &[char]) -> ~str {
159     chs.iter().map(|c| *c).collect()
160 }
161
162 #[doc(hidden)]
163 pub fn push_str(lhs: &mut ~str, rhs: &str) {
164     lhs.push_str(rhs)
165 }
166
167 /// Methods for vectors of strings
168 pub trait StrVector {
169     /// Concatenate a vector of strings.
170     fn concat(&self) -> ~str;
171
172     /// Concatenate a vector of strings, placing a given separator between each.
173     fn connect(&self, sep: &str) -> ~str;
174 }
175
176 impl<'a, S: Str> StrVector for &'a [S] {
177     fn concat(&self) -> ~str {
178         if self.is_empty() { return ~""; }
179
180         // `len` calculation may overflow but push_str but will check boundaries
181         let len = self.iter().map(|s| s.as_slice().len()).sum();
182
183         let mut result = with_capacity(len);
184
185         for s in self.iter() {
186             result.push_str(s.as_slice())
187         }
188         result
189     }
190
191     fn connect(&self, sep: &str) -> ~str {
192         if self.is_empty() { return ~""; }
193
194         // concat is faster
195         if sep.is_empty() { return self.concat(); }
196
197         // this is wrong without the guarantee that `self` is non-empty
198         // `len` calculation may overflow but push_str but will check boundaries
199         let len = sep.len() * (self.len() - 1)
200             + self.iter().map(|s| s.as_slice().len()).sum();
201         let mut result = with_capacity(len);
202         let mut first = true;
203
204         for s in self.iter() {
205             if first {
206                 first = false;
207             } else {
208                 result.push_str(sep);
209             }
210             result.push_str(s.as_slice());
211         }
212         result
213     }
214 }
215
216 impl<'a, S: Str> StrVector for Vec<S> {
217     #[inline]
218     fn concat(&self) -> ~str {
219         self.as_slice().concat()
220     }
221
222     #[inline]
223     fn connect(&self, sep: &str) -> ~str {
224         self.as_slice().connect(sep)
225     }
226 }
227
228 /// Something that can be used to compare against a character
229 pub trait CharEq {
230     /// Determine if the splitter should split at the given character
231     fn matches(&self, char) -> bool;
232     /// Indicate if this is only concerned about ASCII characters,
233     /// which can allow for a faster implementation.
234     fn only_ascii(&self) -> bool;
235 }
236
237 impl CharEq for char {
238     #[inline]
239     fn matches(&self, c: char) -> bool { *self == c }
240
241     fn only_ascii(&self) -> bool { (*self as uint) < 128 }
242 }
243
244 impl<'a> CharEq for 'a |char| -> bool {
245     #[inline]
246     fn matches(&self, c: char) -> bool { (*self)(c) }
247
248     fn only_ascii(&self) -> bool { false }
249 }
250
251 impl CharEq for extern "Rust" fn(char) -> bool {
252     #[inline]
253     fn matches(&self, c: char) -> bool { (*self)(c) }
254
255     fn only_ascii(&self) -> bool { false }
256 }
257
258 impl<'a, C: CharEq> CharEq for &'a [C] {
259     #[inline]
260     fn matches(&self, c: char) -> bool {
261         self.iter().any(|m| m.matches(c))
262     }
263
264     fn only_ascii(&self) -> bool {
265         self.iter().all(|m| m.only_ascii())
266     }
267 }
268
269 /*
270 Section: Iterators
271 */
272
273 /// External iterator for a string's characters.
274 /// Use with the `std::iter` module.
275 #[deriving(Clone)]
276 pub struct Chars<'a> {
277     /// The slice remaining to be iterated
278     priv string: &'a str,
279 }
280
281 impl<'a> Iterator<char> for Chars<'a> {
282     #[inline]
283     fn next(&mut self) -> Option<char> {
284         // Decode the next codepoint, then update
285         // the slice to be just the remaining part
286         if self.string.len() != 0 {
287             let CharRange {ch, next} = self.string.char_range_at(0);
288             unsafe {
289                 self.string = raw::slice_unchecked(self.string, next, self.string.len());
290             }
291             Some(ch)
292         } else {
293             None
294         }
295     }
296
297     #[inline]
298     fn size_hint(&self) -> (uint, Option<uint>) {
299         (self.string.len().saturating_add(3)/4, Some(self.string.len()))
300     }
301 }
302
303 impl<'a> DoubleEndedIterator<char> for Chars<'a> {
304     #[inline]
305     fn next_back(&mut self) -> Option<char> {
306         if self.string.len() != 0 {
307             let CharRange {ch, next} = self.string.char_range_at_reverse(self.string.len());
308             unsafe {
309                 self.string = raw::slice_unchecked(self.string, 0, next);
310             }
311             Some(ch)
312         } else {
313             None
314         }
315     }
316 }
317
318 /// External iterator for a string's characters and their byte offsets.
319 /// Use with the `std::iter` module.
320 #[deriving(Clone)]
321 pub struct CharOffsets<'a> {
322     /// The original string to be iterated
323     priv string: &'a str,
324     priv iter: Chars<'a>,
325 }
326
327 impl<'a> Iterator<(uint, char)> for CharOffsets<'a> {
328     #[inline]
329     fn next(&mut self) -> Option<(uint, char)> {
330         // Compute the byte offset by using the pointer offset between
331         // the original string slice and the iterator's remaining part
332         let offset = self.iter.string.as_ptr() as uint - self.string.as_ptr() as uint;
333         self.iter.next().map(|ch| (offset, ch))
334     }
335
336     #[inline]
337     fn size_hint(&self) -> (uint, Option<uint>) {
338         self.iter.size_hint()
339     }
340 }
341
342 impl<'a> DoubleEndedIterator<(uint, char)> for CharOffsets<'a> {
343     #[inline]
344     fn next_back(&mut self) -> Option<(uint, char)> {
345         self.iter.next_back().map(|ch| {
346             let offset = self.iter.string.len() +
347                     self.iter.string.as_ptr() as uint - self.string.as_ptr() as uint;
348             (offset, ch)
349         })
350     }
351 }
352
353 /// External iterator for a string's characters in reverse order.
354 /// Use with the `std::iter` module.
355 pub type RevChars<'a> = Rev<Chars<'a>>;
356
357 /// External iterator for a string's characters and their byte offsets in reverse order.
358 /// Use with the `std::iter` module.
359 pub type RevCharOffsets<'a> = Rev<CharOffsets<'a>>;
360
361 /// External iterator for a string's bytes.
362 /// Use with the `std::iter` module.
363 pub type Bytes<'a> =
364     Map<'a, &'a u8, u8, slice::Items<'a, u8>>;
365
366 /// External iterator for a string's bytes in reverse order.
367 /// Use with the `std::iter` module.
368 pub type RevBytes<'a> = Rev<Bytes<'a>>;
369
370 /// An iterator over the substrings of a string, separated by `sep`.
371 #[deriving(Clone)]
372 pub struct CharSplits<'a, Sep> {
373     /// The slice remaining to be iterated
374     priv string: &'a str,
375     priv sep: Sep,
376     /// Whether an empty string at the end is allowed
377     priv allow_trailing_empty: bool,
378     priv only_ascii: bool,
379     priv finished: bool,
380 }
381
382 /// An iterator over the substrings of a string, separated by `sep`,
383 /// starting from the back of the string.
384 pub type RevCharSplits<'a, Sep> = Rev<CharSplits<'a, Sep>>;
385
386 /// An iterator over the substrings of a string, separated by `sep`,
387 /// splitting at most `count` times.
388 #[deriving(Clone)]
389 pub struct CharSplitsN<'a, Sep> {
390     priv iter: CharSplits<'a, Sep>,
391     /// The number of splits remaining
392     priv count: uint,
393     priv invert: bool,
394 }
395
396 /// An iterator over the words of a string, separated by a sequence of whitespace
397 pub type Words<'a> =
398     Filter<'a, &'a str, CharSplits<'a, extern "Rust" fn(char) -> bool>>;
399
400 /// An iterator over the lines of a string, separated by either `\n` or (`\r\n`).
401 pub type AnyLines<'a> =
402     Map<'a, &'a str, &'a str, CharSplits<'a, char>>;
403
404 impl<'a, Sep> CharSplits<'a, Sep> {
405     #[inline]
406     fn get_end(&mut self) -> Option<&'a str> {
407         if !self.finished && (self.allow_trailing_empty || self.string.len() > 0) {
408             self.finished = true;
409             Some(self.string)
410         } else {
411             None
412         }
413     }
414 }
415
416 impl<'a, Sep: CharEq> Iterator<&'a str> for CharSplits<'a, Sep> {
417     #[inline]
418     fn next(&mut self) -> Option<&'a str> {
419         if self.finished { return None }
420
421         let mut next_split = None;
422         if self.only_ascii {
423             for (idx, byte) in self.string.bytes().enumerate() {
424                 if self.sep.matches(byte as char) && byte < 128u8 {
425                     next_split = Some((idx, idx + 1));
426                     break;
427                 }
428             }
429         } else {
430             for (idx, ch) in self.string.char_indices() {
431                 if self.sep.matches(ch) {
432                     next_split = Some((idx, self.string.char_range_at(idx).next));
433                     break;
434                 }
435             }
436         }
437         match next_split {
438             Some((a, b)) => unsafe {
439                 let elt = raw::slice_unchecked(self.string, 0, a);
440                 self.string = raw::slice_unchecked(self.string, b, self.string.len());
441                 Some(elt)
442             },
443             None => self.get_end(),
444         }
445     }
446 }
447
448 impl<'a, Sep: CharEq> DoubleEndedIterator<&'a str>
449 for CharSplits<'a, Sep> {
450     #[inline]
451     fn next_back(&mut self) -> Option<&'a str> {
452         if self.finished { return None }
453
454         if !self.allow_trailing_empty {
455             self.allow_trailing_empty = true;
456             match self.next_back() {
457                 Some(elt) if !elt.is_empty() => return Some(elt),
458                 _ => if self.finished { return None }
459             }
460         }
461         let len = self.string.len();
462         let mut next_split = None;
463
464         if self.only_ascii {
465             for (idx, byte) in self.string.bytes().enumerate().rev() {
466                 if self.sep.matches(byte as char) && byte < 128u8 {
467                     next_split = Some((idx, idx + 1));
468                     break;
469                 }
470             }
471         } else {
472             for (idx, ch) in self.string.char_indices_rev() {
473                 if self.sep.matches(ch) {
474                     next_split = Some((idx, self.string.char_range_at(idx).next));
475                     break;
476                 }
477             }
478         }
479         match next_split {
480             Some((a, b)) => unsafe {
481                 let elt = raw::slice_unchecked(self.string, b, len);
482                 self.string = raw::slice_unchecked(self.string, 0, a);
483                 Some(elt)
484             },
485             None => { self.finished = true; Some(self.string) }
486         }
487     }
488 }
489
490 impl<'a, Sep: CharEq> Iterator<&'a str> for CharSplitsN<'a, Sep> {
491     #[inline]
492     fn next(&mut self) -> Option<&'a str> {
493         if self.count != 0 {
494             self.count -= 1;
495             if self.invert { self.iter.next_back() } else { self.iter.next() }
496         } else {
497             self.iter.get_end()
498         }
499     }
500 }
501
502 /// An iterator over the start and end indices of the matches of a
503 /// substring within a larger string
504 #[deriving(Clone)]
505 pub struct MatchIndices<'a> {
506     priv haystack: &'a str,
507     priv needle: &'a str,
508     priv position: uint,
509 }
510
511 /// An iterator over the substrings of a string separated by a given
512 /// search string
513 #[deriving(Clone)]
514 pub struct StrSplits<'a> {
515     priv it: MatchIndices<'a>,
516     priv last_end: uint,
517     priv finished: bool
518 }
519
520 impl<'a> Iterator<(uint, uint)> for MatchIndices<'a> {
521     #[inline]
522     fn next(&mut self) -> Option<(uint, uint)> {
523         // See Issue #1932 for why this is a naive search
524         let (h_len, n_len) = (self.haystack.len(), self.needle.len());
525         let mut match_start = 0;
526         let mut match_i = 0;
527
528         while self.position < h_len {
529             if self.haystack[self.position] == self.needle[match_i] {
530                 if match_i == 0 { match_start = self.position; }
531                 match_i += 1;
532                 self.position += 1;
533
534                 if match_i == n_len {
535                     // found a match!
536                     return Some((match_start, self.position));
537                 }
538             } else {
539                 // failed match, backtrack
540                 if match_i > 0 {
541                     match_i = 0;
542                     self.position = match_start;
543                 }
544                 self.position += 1;
545             }
546         }
547         None
548     }
549 }
550
551 impl<'a> Iterator<&'a str> for StrSplits<'a> {
552     #[inline]
553     fn next(&mut self) -> Option<&'a str> {
554         if self.finished { return None; }
555
556         match self.it.next() {
557             Some((from, to)) => {
558                 let ret = Some(self.it.haystack.slice(self.last_end, from));
559                 self.last_end = to;
560                 ret
561             }
562             None => {
563                 self.finished = true;
564                 Some(self.it.haystack.slice(self.last_end, self.it.haystack.len()))
565             }
566         }
567     }
568 }
569
570 // Helper functions used for Unicode normalization
571 fn canonical_sort(comb: &mut [(char, u8)]) {
572     use iter::range;
573     use tuple::Tuple2;
574
575     let len = comb.len();
576     for i in range(0, len) {
577         let mut swapped = false;
578         for j in range(1, len-i) {
579             let class_a = *comb[j-1].ref1();
580             let class_b = *comb[j].ref1();
581             if class_a != 0 && class_b != 0 && class_a > class_b {
582                 comb.swap(j-1, j);
583                 swapped = true;
584             }
585         }
586         if !swapped { break; }
587     }
588 }
589
590 #[deriving(Clone)]
591 enum NormalizationForm {
592     NFD,
593     NFKD
594 }
595
596 /// External iterator for a string's normalization's characters.
597 /// Use with the `std::iter` module.
598 #[deriving(Clone)]
599 pub struct Normalizations<'a> {
600     priv kind: NormalizationForm,
601     priv iter: Chars<'a>,
602     priv buffer: ~[(char, u8)],
603     priv sorted: bool
604 }
605
606 impl<'a> Iterator<char> for Normalizations<'a> {
607     #[inline]
608     fn next(&mut self) -> Option<char> {
609         use unicode::decompose::canonical_combining_class;
610
611         match self.buffer.head() {
612             Some(&(c, 0)) => {
613                 self.sorted = false;
614                 self.buffer.shift();
615                 return Some(c);
616             }
617             Some(&(c, _)) if self.sorted => {
618                 self.buffer.shift();
619                 return Some(c);
620             }
621             _ => self.sorted = false
622         }
623
624         let decomposer = match self.kind {
625             NFD => char::decompose_canonical,
626             NFKD => char::decompose_compatible
627         };
628
629         if !self.sorted {
630             for ch in self.iter {
631                 let buffer = &mut self.buffer;
632                 let sorted = &mut self.sorted;
633                 decomposer(ch, |d| {
634                     let class = canonical_combining_class(d);
635                     if class == 0 && !*sorted {
636                         canonical_sort(*buffer);
637                         *sorted = true;
638                     }
639                     buffer.push((d, class));
640                 });
641                 if *sorted { break }
642             }
643         }
644
645         if !self.sorted {
646             canonical_sort(self.buffer);
647             self.sorted = true;
648         }
649
650         match self.buffer.shift() {
651             Some((c, 0)) => {
652                 self.sorted = false;
653                 Some(c)
654             }
655             Some((c, _)) => Some(c),
656             None => None
657         }
658     }
659
660     fn size_hint(&self) -> (uint, Option<uint>) {
661         let (lower, _) = self.iter.size_hint();
662         (lower, None)
663     }
664 }
665
666 /// Replace all occurrences of one string with another
667 ///
668 /// # Arguments
669 ///
670 /// * s - The string containing substrings to replace
671 /// * from - The string to replace
672 /// * to - The replacement string
673 ///
674 /// # Return value
675 ///
676 /// The original string with all occurances of `from` replaced with `to`
677 pub fn replace(s: &str, from: &str, to: &str) -> ~str {
678     let mut result = ~"";
679     let mut last_end = 0;
680     for (start, end) in s.match_indices(from) {
681         result.push_str(unsafe{raw::slice_bytes(s, last_end, start)});
682         result.push_str(to);
683         last_end = end;
684     }
685     result.push_str(unsafe{raw::slice_bytes(s, last_end, s.len())});
686     result
687 }
688
689 /*
690 Section: Comparing strings
691 */
692
693 // share the implementation of the lang-item vs. non-lang-item
694 // eq_slice.
695 #[inline]
696 fn eq_slice_(a: &str, b: &str) -> bool {
697     a.len() == b.len() && unsafe {
698         libc::memcmp(a.as_ptr() as *libc::c_void,
699                      b.as_ptr() as *libc::c_void,
700                      a.len() as libc::size_t) == 0
701     }
702 }
703
704 /// Bytewise slice equality
705 #[cfg(not(test))]
706 #[lang="str_eq"]
707 #[inline]
708 pub fn eq_slice(a: &str, b: &str) -> bool {
709     eq_slice_(a, b)
710 }
711
712 /// Bytewise slice equality
713 #[cfg(test)]
714 #[inline]
715 pub fn eq_slice(a: &str, b: &str) -> bool {
716     eq_slice_(a, b)
717 }
718
719 /// Bytewise string equality
720 #[cfg(not(test))]
721 #[lang="uniq_str_eq"]
722 #[inline]
723 pub fn eq(a: &~str, b: &~str) -> bool {
724     eq_slice(*a, *b)
725 }
726
727 #[cfg(test)]
728 #[inline]
729 pub fn eq(a: &~str, b: &~str) -> bool {
730     eq_slice(*a, *b)
731 }
732
733 /*
734 Section: Misc
735 */
736
737 /// Walk through `iter` checking that it's a valid UTF-8 sequence,
738 /// returning `true` in that case, or, if it is invalid, `false` with
739 /// `iter` reset such that it is pointing at the first byte in the
740 /// invalid sequence.
741 #[inline(always)]
742 fn run_utf8_validation_iterator(iter: &mut slice::Items<u8>) -> bool {
743     loop {
744         // save the current thing we're pointing at.
745         let old = *iter;
746
747         // restore the iterator we had at the start of this codepoint.
748         macro_rules! err ( () => { {*iter = old; return false} });
749         macro_rules! next ( () => {
750                 match iter.next() {
751                     Some(a) => *a,
752                     // we needed data, but there was none: error!
753                     None => err!()
754                 }
755             });
756
757         let first = match iter.next() {
758             Some(&b) => b,
759             // we're at the end of the iterator and a codepoint
760             // boundary at the same time, so this string is valid.
761             None => return true
762         };
763
764         // ASCII characters are always valid, so only large
765         // bytes need more examination.
766         if first >= 128 {
767             let w = utf8_char_width(first);
768             let second = next!();
769             // 2-byte encoding is for codepoints  \u0080 to  \u07ff
770             //        first  C2 80        last DF BF
771             // 3-byte encoding is for codepoints  \u0800 to  \uffff
772             //        first  E0 A0 80     last EF BF BF
773             //   excluding surrogates codepoints  \ud800 to  \udfff
774             //               ED A0 80 to       ED BF BF
775             // 4-byte encoding is for codepoints \u10000 to \u10ffff
776             //        first  F0 90 80 80  last F4 8F BF BF
777             //
778             // Use the UTF-8 syntax from the RFC
779             //
780             // https://tools.ietf.org/html/rfc3629
781             // UTF8-1      = %x00-7F
782             // UTF8-2      = %xC2-DF UTF8-tail
783             // UTF8-3      = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
784             //               %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
785             // UTF8-4      = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
786             //               %xF4 %x80-8F 2( UTF8-tail )
787             match w {
788                 2 => if second & 192 != TAG_CONT_U8 {err!()},
789                 3 => {
790                     match (first, second, next!() & 192) {
791                         (0xE0        , 0xA0 .. 0xBF, TAG_CONT_U8) |
792                         (0xE1 .. 0xEC, 0x80 .. 0xBF, TAG_CONT_U8) |
793                         (0xED        , 0x80 .. 0x9F, TAG_CONT_U8) |
794                         (0xEE .. 0xEF, 0x80 .. 0xBF, TAG_CONT_U8) => {}
795                         _ => err!()
796                     }
797                 }
798                 4 => {
799                     match (first, second, next!() & 192, next!() & 192) {
800                         (0xF0        , 0x90 .. 0xBF, TAG_CONT_U8, TAG_CONT_U8) |
801                         (0xF1 .. 0xF3, 0x80 .. 0xBF, TAG_CONT_U8, TAG_CONT_U8) |
802                         (0xF4        , 0x80 .. 0x8F, TAG_CONT_U8, TAG_CONT_U8) => {}
803                         _ => err!()
804                     }
805                 }
806                 _ => err!()
807             }
808         }
809     }
810 }
811
812 /// Determines if a vector of bytes contains valid UTF-8.
813 pub fn is_utf8(v: &[u8]) -> bool {
814     run_utf8_validation_iterator(&mut v.iter())
815 }
816
817 #[inline(always)]
818 fn first_non_utf8_index(v: &[u8]) -> Option<uint> {
819     let mut it = v.iter();
820
821     let ok = run_utf8_validation_iterator(&mut it);
822     if ok {
823         None
824     } else {
825         // work out how many valid bytes we've consumed
826         // (run_utf8_validation_iterator resets the iterator to just
827         // after the last good byte), which we can do because the
828         // vector iterator size_hint is exact.
829         let (remaining, _) = it.size_hint();
830         Some(v.len() - remaining)
831     }
832 }
833
834 /// Determines if a vector of `u16` contains valid UTF-16
835 pub fn is_utf16(v: &[u16]) -> bool {
836     let mut it = v.iter();
837     macro_rules! next ( ($ret:expr) => {
838             match it.next() { Some(u) => *u, None => return $ret }
839         }
840     )
841     loop {
842         let u = next!(true);
843
844         match char::from_u32(u as u32) {
845             Some(_) => {}
846             None => {
847                 let u2 = next!(false);
848                 if u < 0xD7FF || u > 0xDBFF ||
849                     u2 < 0xDC00 || u2 > 0xDFFF { return false; }
850             }
851         }
852     }
853 }
854
855 /// An iterator that decodes UTF-16 encoded codepoints from a vector
856 /// of `u16`s.
857 #[deriving(Clone)]
858 pub struct UTF16Items<'a> {
859     priv iter: slice::Items<'a, u16>
860 }
861 /// The possibilities for values decoded from a `u16` stream.
862 #[deriving(Eq, TotalEq, Clone, Show)]
863 pub enum UTF16Item {
864     /// A valid codepoint.
865     ScalarValue(char),
866     /// An invalid surrogate without its pair.
867     LoneSurrogate(u16)
868 }
869
870 impl UTF16Item {
871     /// Convert `self` to a `char`, taking `LoneSurrogate`s to the
872     /// replacement character (U+FFFD).
873     #[inline]
874     pub fn to_char_lossy(&self) -> char {
875         match *self {
876             ScalarValue(c) => c,
877             LoneSurrogate(_) => '\uFFFD'
878         }
879     }
880 }
881
882 impl<'a> Iterator<UTF16Item> for UTF16Items<'a> {
883     fn next(&mut self) -> Option<UTF16Item> {
884         let u = match self.iter.next() {
885             Some(u) => *u,
886             None => return None
887         };
888
889         if u < 0xD800 || 0xDFFF < u {
890             // not a surrogate
891             Some(ScalarValue(unsafe {cast::transmute(u as u32)}))
892         } else if u >= 0xDC00 {
893             // a trailing surrogate
894             Some(LoneSurrogate(u))
895         } else {
896             // preserve state for rewinding.
897             let old = self.iter;
898
899             let u2 = match self.iter.next() {
900                 Some(u2) => *u2,
901                 // eof
902                 None => return Some(LoneSurrogate(u))
903             };
904             if u2 < 0xDC00 || u2 > 0xDFFF {
905                 // not a trailing surrogate so we're not a valid
906                 // surrogate pair, so rewind to redecode u2 next time.
907                 self.iter = old;
908                 return Some(LoneSurrogate(u))
909             }
910
911             // all ok, so lets decode it.
912             let c = ((u - 0xD800) as u32 << 10 | (u2 - 0xDC00) as u32) + 0x1_0000;
913             Some(ScalarValue(unsafe {cast::transmute(c)}))
914         }
915     }
916
917     #[inline]
918     fn size_hint(&self) -> (uint, Option<uint>) {
919         let (low, high) = self.iter.size_hint();
920         // we could be entirely valid surrogates (2 elements per
921         // char), or entirely non-surrogates (1 element per char)
922         (low / 2, high)
923     }
924 }
925
926 /// Create an iterator over the UTF-16 encoded codepoints in `v`,
927 /// returning invalid surrogates as `LoneSurrogate`s.
928 ///
929 /// # Example
930 ///
931 /// ```rust
932 /// use std::str;
933 /// use std::str::{ScalarValue, LoneSurrogate};
934 ///
935 /// // 𝄞mus<invalid>ic<invalid>
936 /// let v = [0xD834, 0xDD1E, 0x006d, 0x0075,
937 ///          0x0073, 0xDD1E, 0x0069, 0x0063,
938 ///          0xD834];
939 ///
940 /// assert_eq!(str::utf16_items(v).collect::<~[_]>(),
941 ///            ~[ScalarValue('𝄞'),
942 ///              ScalarValue('m'), ScalarValue('u'), ScalarValue('s'),
943 ///              LoneSurrogate(0xDD1E),
944 ///              ScalarValue('i'), ScalarValue('c'),
945 ///              LoneSurrogate(0xD834)]);
946 /// ```
947 pub fn utf16_items<'a>(v: &'a [u16]) -> UTF16Items<'a> {
948     UTF16Items { iter : v.iter() }
949 }
950
951 /// Return a slice of `v` ending at (and not including) the first NUL
952 /// (0).
953 ///
954 /// # Example
955 ///
956 /// ```rust
957 /// use std::str;
958 ///
959 /// // "abcd"
960 /// let mut v = ['a' as u16, 'b' as u16, 'c' as u16, 'd' as u16];
961 /// // no NULs so no change
962 /// assert_eq!(str::truncate_utf16_at_nul(v), v.as_slice());
963 ///
964 /// // "ab\0d"
965 /// v[2] = 0;
966 /// assert_eq!(str::truncate_utf16_at_nul(v),
967 ///            &['a' as u16, 'b' as u16]);
968 /// ```
969 pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] {
970     match v.iter().position(|c| *c == 0) {
971         // don't include the 0
972         Some(i) => v.slice_to(i),
973         None => v
974     }
975 }
976
977 /// Decode a UTF-16 encoded vector `v` into a string, returning `None`
978 /// if `v` contains any invalid data.
979 ///
980 /// # Example
981 ///
982 /// ```rust
983 /// use std::str;
984 ///
985 /// // 𝄞music
986 /// let mut v = [0xD834, 0xDD1E, 0x006d, 0x0075,
987 ///              0x0073, 0x0069, 0x0063];
988 /// assert_eq!(str::from_utf16(v), Some(~"𝄞music"));
989 ///
990 /// // 𝄞mu<invalid>ic
991 /// v[4] = 0xD800;
992 /// assert_eq!(str::from_utf16(v), None);
993 /// ```
994 pub fn from_utf16(v: &[u16]) -> Option<~str> {
995     let mut s = with_capacity(v.len() / 2);
996     for c in utf16_items(v) {
997         match c {
998             ScalarValue(c) => s.push_char(c),
999             LoneSurrogate(_) => return None
1000         }
1001     }
1002     Some(s)
1003 }
1004
1005 /// Decode a UTF-16 encoded vector `v` into a string, replacing
1006 /// invalid data with the replacement character (U+FFFD).
1007 ///
1008 /// # Example
1009 /// ```rust
1010 /// use std::str;
1011 ///
1012 /// // 𝄞mus<invalid>ic<invalid>
1013 /// let v = [0xD834, 0xDD1E, 0x006d, 0x0075,
1014 ///          0x0073, 0xDD1E, 0x0069, 0x0063,
1015 ///          0xD834];
1016 ///
1017 /// assert_eq!(str::from_utf16_lossy(v),
1018 ///            ~"𝄞mus\uFFFDic\uFFFD");
1019 /// ```
1020 pub fn from_utf16_lossy(v: &[u16]) -> ~str {
1021     utf16_items(v).map(|c| c.to_char_lossy()).collect()
1022 }
1023
1024 /// Allocates a new string with the specified capacity. The string returned is
1025 /// the empty string, but has capacity for much more.
1026 #[inline]
1027 pub fn with_capacity(capacity: uint) -> ~str {
1028     unsafe {
1029         cast::transmute(slice::with_capacity::<~[u8]>(capacity))
1030     }
1031 }
1032
1033 // https://tools.ietf.org/html/rfc3629
1034 static UTF8_CHAR_WIDTH: [u8, ..256] = [
1035 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1036 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1F
1037 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1038 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3F
1039 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1040 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5F
1041 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1042 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7F
1043 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1044 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9F
1045 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1046 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBF
1047 0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
1048 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDF
1049 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEF
1050 4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, // 0xFF
1051 ];
1052
1053 /// Given a first byte, determine how many bytes are in this UTF-8 character
1054 #[inline]
1055 pub fn utf8_char_width(b: u8) -> uint {
1056     return UTF8_CHAR_WIDTH[b] as uint;
1057 }
1058
1059 /// Struct that contains a `char` and the index of the first byte of
1060 /// the next `char` in a string.  This can be used as a data structure
1061 /// for iterating over the UTF-8 bytes of a string.
1062 pub struct CharRange {
1063     /// Current `char`
1064     ch: char,
1065     /// Index of the first byte of the next `char`
1066     next: uint
1067 }
1068
1069 // Return the initial codepoint accumulator for the first byte.
1070 // The first byte is special, only want bottom 5 bits for width 2, 4 bits
1071 // for width 3, and 3 bits for width 4
1072 macro_rules! utf8_first_byte(
1073     ($byte:expr, $width:expr) => (($byte & (0x7F >> $width)) as u32)
1074 )
1075
1076 // return the value of $ch updated with continuation byte $byte
1077 macro_rules! utf8_acc_cont_byte(
1078     ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63u8) as u32)
1079 )
1080
1081 static TAG_CONT_U8: u8 = 128u8;
1082
1083 /// Converts a vector of bytes to a new utf-8 string.
1084 /// Any invalid utf-8 sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
1085 ///
1086 /// # Example
1087 ///
1088 /// ```rust
1089 /// let input = bytes!("Hello ", 0xF0, 0x90, 0x80, "World");
1090 /// let output = std::str::from_utf8_lossy(input);
1091 /// assert_eq!(output.as_slice(), "Hello \uFFFDWorld");
1092 /// ```
1093 pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> MaybeOwned<'a> {
1094     let firstbad = match first_non_utf8_index(v) {
1095         None => return Slice(unsafe { cast::transmute(v) }),
1096         Some(i) => i
1097     };
1098
1099     static REPLACEMENT: &'static [u8] = bytes!(0xEF, 0xBF, 0xBD); // U+FFFD in UTF-8
1100     let mut i = firstbad;
1101     let total = v.len();
1102     fn unsafe_get(xs: &[u8], i: uint) -> u8 {
1103         unsafe { *xs.unsafe_ref(i) }
1104     }
1105     fn safe_get(xs: &[u8], i: uint, total: uint) -> u8 {
1106         if i >= total {
1107             0
1108         } else {
1109             unsafe_get(xs, i)
1110         }
1111     }
1112     let mut res = with_capacity(total);
1113
1114     if i > 0 {
1115         unsafe { raw::push_bytes(&mut res, v.slice_to(i)) };
1116     }
1117
1118     // subseqidx is the index of the first byte of the subsequence we're looking at.
1119     // It's used to copy a bunch of contiguous good codepoints at once instead of copying
1120     // them one by one.
1121     let mut subseqidx = firstbad;
1122
1123     while i < total {
1124         let i_ = i;
1125         let byte = unsafe_get(v, i);
1126         i += 1;
1127
1128         macro_rules! error(() => ({
1129             unsafe {
1130                 if subseqidx != i_ {
1131                     raw::push_bytes(&mut res, v.slice(subseqidx, i_));
1132                 }
1133                 subseqidx = i;
1134                 raw::push_bytes(&mut res, REPLACEMENT);
1135             }
1136         }))
1137
1138         if byte < 128u8 {
1139             // subseqidx handles this
1140         } else {
1141             let w = utf8_char_width(byte);
1142
1143             match w {
1144                 2 => {
1145                     if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
1146                         error!();
1147                         continue;
1148                     }
1149                     i += 1;
1150                 }
1151                 3 => {
1152                     match (byte, safe_get(v, i, total)) {
1153                         (0xE0        , 0xA0 .. 0xBF) => (),
1154                         (0xE1 .. 0xEC, 0x80 .. 0xBF) => (),
1155                         (0xED        , 0x80 .. 0x9F) => (),
1156                         (0xEE .. 0xEF, 0x80 .. 0xBF) => (),
1157                         _ => {
1158                             error!();
1159                             continue;
1160                         }
1161                     }
1162                     i += 1;
1163                     if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
1164                         error!();
1165                         continue;
1166                     }
1167                     i += 1;
1168                 }
1169                 4 => {
1170                     match (byte, safe_get(v, i, total)) {
1171                         (0xF0        , 0x90 .. 0xBF) => (),
1172                         (0xF1 .. 0xF3, 0x80 .. 0xBF) => (),
1173                         (0xF4        , 0x80 .. 0x8F) => (),
1174                         _ => {
1175                             error!();
1176                             continue;
1177                         }
1178                     }
1179                     i += 1;
1180                     if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
1181                         error!();
1182                         continue;
1183                     }
1184                     i += 1;
1185                     if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
1186                         error!();
1187                         continue;
1188                     }
1189                     i += 1;
1190                 }
1191                 _ => {
1192                     error!();
1193                     continue;
1194                 }
1195             }
1196         }
1197     }
1198     if subseqidx < total {
1199         unsafe { raw::push_bytes(&mut res, v.slice(subseqidx, total)) };
1200     }
1201     Owned(res)
1202 }
1203
1204 /*
1205 Section: MaybeOwned
1206 */
1207
1208 /// A MaybeOwned is a string that can hold either a ~str or a &str.
1209 /// This can be useful as an optimization when an allocation is sometimes
1210 /// needed but not always.
1211 pub enum MaybeOwned<'a> {
1212     /// A borrowed string
1213     Slice(&'a str),
1214     /// An owned string
1215     Owned(~str)
1216 }
1217
1218 /// SendStr is a specialization of `MaybeOwned` to be sendable
1219 pub type SendStr = MaybeOwned<'static>;
1220
1221 impl<'a> MaybeOwned<'a> {
1222     /// Returns `true` if this `MaybeOwned` wraps an owned string
1223     #[inline]
1224     pub fn is_owned(&self) -> bool {
1225         match *self {
1226             Slice(_) => false,
1227             Owned(_) => true
1228         }
1229     }
1230
1231     /// Returns `true` if this `MaybeOwned` wraps a borrowed string
1232     #[inline]
1233     pub fn is_slice(&self) -> bool {
1234         match *self {
1235             Slice(_) => true,
1236             Owned(_) => false
1237         }
1238     }
1239 }
1240
1241 /// Trait for moving into a `MaybeOwned`
1242 pub trait IntoMaybeOwned<'a> {
1243     /// Moves self into a `MaybeOwned`
1244     fn into_maybe_owned(self) -> MaybeOwned<'a>;
1245 }
1246
1247 impl<'a> IntoMaybeOwned<'a> for ~str {
1248     #[inline]
1249     fn into_maybe_owned(self) -> MaybeOwned<'a> { Owned(self) }
1250 }
1251
1252 impl<'a> IntoMaybeOwned<'a> for &'a str {
1253     #[inline]
1254     fn into_maybe_owned(self) -> MaybeOwned<'a> { Slice(self) }
1255 }
1256
1257 impl<'a> IntoMaybeOwned<'a> for MaybeOwned<'a> {
1258     #[inline]
1259     fn into_maybe_owned(self) -> MaybeOwned<'a> { self }
1260 }
1261
1262 impl<'a> Eq for MaybeOwned<'a> {
1263     #[inline]
1264     fn eq(&self, other: &MaybeOwned) -> bool {
1265         self.as_slice().equals(&other.as_slice())
1266     }
1267 }
1268
1269 impl<'a> TotalEq for MaybeOwned<'a> {
1270     #[inline]
1271     fn equals(&self, other: &MaybeOwned) -> bool {
1272         self.as_slice().equals(&other.as_slice())
1273     }
1274 }
1275
1276 impl<'a> Ord for MaybeOwned<'a> {
1277     #[inline]
1278     fn lt(&self, other: &MaybeOwned) -> bool {
1279         self.as_slice().lt(&other.as_slice())
1280     }
1281 }
1282
1283 impl<'a> TotalOrd for MaybeOwned<'a> {
1284     #[inline]
1285     fn cmp(&self, other: &MaybeOwned) -> Ordering {
1286         self.as_slice().cmp(&other.as_slice())
1287     }
1288 }
1289
1290 impl<'a, S: Str> Equiv<S> for MaybeOwned<'a> {
1291     #[inline]
1292     fn equiv(&self, other: &S) -> bool {
1293         self.as_slice().equals(&other.as_slice())
1294     }
1295 }
1296
1297 impl<'a> Str for MaybeOwned<'a> {
1298     #[inline]
1299     fn as_slice<'b>(&'b self) -> &'b str {
1300         match *self {
1301             Slice(s) => s,
1302             Owned(ref s) => s.as_slice()
1303         }
1304     }
1305
1306     #[inline]
1307     fn into_owned(self) -> ~str {
1308         match self {
1309             Slice(s) => s.to_owned(),
1310             Owned(s) => s
1311         }
1312     }
1313 }
1314
1315 impl<'a> Container for MaybeOwned<'a> {
1316     #[inline]
1317     fn len(&self) -> uint { self.as_slice().len() }
1318 }
1319
1320 impl<'a> Clone for MaybeOwned<'a> {
1321     #[inline]
1322     fn clone(&self) -> MaybeOwned<'a> {
1323         match *self {
1324             Slice(s) => Slice(s),
1325             Owned(ref s) => Owned(s.to_owned())
1326         }
1327     }
1328 }
1329
1330 impl<'a> Default for MaybeOwned<'a> {
1331     #[inline]
1332     fn default() -> MaybeOwned<'a> { Slice("") }
1333 }
1334
1335 impl<'a, H: Writer> ::hash::Hash<H> for MaybeOwned<'a> {
1336     #[inline]
1337     fn hash(&self, hasher: &mut H) {
1338         match *self {
1339             Slice(s) => s.hash(hasher),
1340             Owned(ref s) => s.hash(hasher),
1341         }
1342     }
1343 }
1344
1345 impl<'a> fmt::Show for MaybeOwned<'a> {
1346     #[inline]
1347     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1348         match *self {
1349             Slice(ref s) => s.fmt(f),
1350             Owned(ref s) => s.fmt(f)
1351         }
1352     }
1353 }
1354
1355 /// Unsafe operations
1356 pub mod raw {
1357     use cast;
1358     use container::Container;
1359     use libc;
1360     use ptr;
1361     use ptr::RawPtr;
1362     use option::{Option, Some, None};
1363     use str::{is_utf8, OwnedStr, StrSlice};
1364     use slice;
1365     use slice::{MutableVector, ImmutableVector, OwnedVector};
1366     use raw::Slice;
1367
1368     /// Create a Rust string from a *u8 buffer of the given length
1369     pub unsafe fn from_buf_len(buf: *u8, len: uint) -> ~str {
1370         let mut v: ~[u8] = slice::with_capacity(len);
1371         ptr::copy_memory(v.as_mut_ptr(), buf, len);
1372         v.set_len(len);
1373
1374         assert!(is_utf8(v));
1375         ::cast::transmute(v)
1376     }
1377
1378     #[lang="strdup_uniq"]
1379     #[cfg(not(test))]
1380     #[inline]
1381     unsafe fn strdup_uniq(ptr: *u8, len: uint) -> ~str {
1382         from_buf_len(ptr, len)
1383     }
1384
1385     /// Create a Rust string from a null-terminated C string
1386     pub unsafe fn from_c_str(buf: *libc::c_char) -> ~str {
1387         let mut curr = buf;
1388         let mut i = 0;
1389         while *curr != 0 {
1390             i += 1;
1391             curr = buf.offset(i);
1392         }
1393         from_buf_len(buf as *u8, i as uint)
1394     }
1395
1396     /// Converts a slice of bytes to a string slice without checking
1397     /// that the string contains valid UTF-8.
1398     pub unsafe fn from_utf8<'a>(v: &'a [u8]) -> &'a str {
1399         cast::transmute(v)
1400     }
1401
1402     /// Converts an owned vector of bytes to a new owned string. This assumes
1403     /// that the utf-8-ness of the vector has already been validated
1404     #[inline]
1405     pub unsafe fn from_utf8_owned(v: ~[u8]) -> ~str {
1406         cast::transmute(v)
1407     }
1408
1409     /// Converts a byte to a string.
1410     pub unsafe fn from_byte(u: u8) -> ~str { from_utf8_owned(~[u]) }
1411
1412     /// Form a slice from a C string. Unsafe because the caller must ensure the
1413     /// C string has the static lifetime, or else the return value may be
1414     /// invalidated later.
1415     pub unsafe fn c_str_to_static_slice(s: *libc::c_char) -> &'static str {
1416         let s = s as *u8;
1417         let mut curr = s;
1418         let mut len = 0u;
1419         while *curr != 0u8 {
1420             len += 1u;
1421             curr = s.offset(len as int);
1422         }
1423         let v = Slice { data: s, len: len };
1424         assert!(is_utf8(::cast::transmute(v)));
1425         ::cast::transmute(v)
1426     }
1427
1428     /// Takes a bytewise (not UTF-8) slice from a string.
1429     ///
1430     /// Returns the substring from [`begin`..`end`).
1431     ///
1432     /// # Failure
1433     ///
1434     /// If begin is greater than end.
1435     /// If end is greater than the length of the string.
1436     #[inline]
1437     pub unsafe fn slice_bytes<'a>(s: &'a str, begin: uint, end: uint) -> &'a str {
1438         assert!(begin <= end);
1439         assert!(end <= s.len());
1440         slice_unchecked(s, begin, end)
1441     }
1442
1443     /// Takes a bytewise (not UTF-8) slice from a string.
1444     ///
1445     /// Returns the substring from [`begin`..`end`).
1446     ///
1447     /// Caller must check slice boundaries!
1448     #[inline]
1449     pub unsafe fn slice_unchecked<'a>(s: &'a str, begin: uint, end: uint) -> &'a str {
1450         cast::transmute(Slice {
1451                 data: s.as_ptr().offset(begin as int),
1452                 len: end - begin,
1453             })
1454     }
1455
1456     /// Appends a byte to a string.
1457     /// The caller must preserve the valid UTF-8 property.
1458     #[inline]
1459     pub unsafe fn push_byte(s: &mut ~str, b: u8) {
1460         as_owned_vec(s).push(b)
1461     }
1462
1463     /// Appends a vector of bytes to a string.
1464     /// The caller must preserve the valid UTF-8 property.
1465     #[inline]
1466     pub unsafe fn push_bytes(s: &mut ~str, bytes: &[u8]) {
1467         slice::bytes::push_bytes(as_owned_vec(s), bytes);
1468     }
1469
1470     /// Removes the last byte from a string and returns it.
1471     /// Returns None when an empty string is passed.
1472     /// The caller must preserve the valid UTF-8 property.
1473     pub unsafe fn pop_byte(s: &mut ~str) -> Option<u8> {
1474         let len = s.len();
1475         if len == 0u {
1476             return None;
1477         } else {
1478             let b = s[len - 1u];
1479             s.set_len(len - 1);
1480             return Some(b);
1481         }
1482     }
1483
1484     /// Removes the first byte from a string and returns it.
1485     /// Returns None when an empty string is passed.
1486     /// The caller must preserve the valid UTF-8 property.
1487     pub unsafe fn shift_byte(s: &mut ~str) -> Option<u8> {
1488         let len = s.len();
1489         if len == 0u {
1490             return None;
1491         } else {
1492             let b = s[0];
1493             *s = s.slice(1, len).to_owned();
1494             return Some(b);
1495         }
1496     }
1497
1498     /// Access the str in its vector representation.
1499     /// The caller must preserve the valid UTF-8 property when modifying.
1500     #[inline]
1501     pub unsafe fn as_owned_vec<'a>(s: &'a mut ~str) -> &'a mut ~[u8] {
1502         cast::transmute(s)
1503     }
1504
1505     /// Sets the length of a string
1506     ///
1507     /// This will explicitly set the size of the string, without actually
1508     /// modifing its buffers, so it is up to the caller to ensure that
1509     /// the string is actually the specified size.
1510     #[test]
1511     fn test_from_buf_len() {
1512         unsafe {
1513             let a = ~[65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 0u8];
1514             let b = a.as_ptr();
1515             let c = from_buf_len(b, 3u);
1516             assert_eq!(c, ~"AAA");
1517         }
1518     }
1519 }
1520
1521 /*
1522 Section: Trait implementations
1523 */
1524
1525 #[cfg(not(test))]
1526 #[allow(missing_doc)]
1527 pub mod traits {
1528     use container::Container;
1529     use cmp::{TotalOrd, Ordering, Less, Equal, Greater, Eq, Ord, Equiv, TotalEq};
1530     use iter::Iterator;
1531     use ops::Add;
1532     use option::{Some, None};
1533     use str::{Str, StrSlice, OwnedStr, eq_slice};
1534
1535     impl<'a> Add<&'a str,~str> for &'a str {
1536         #[inline]
1537         fn add(&self, rhs: & &'a str) -> ~str {
1538             let mut ret = self.to_owned();
1539             ret.push_str(*rhs);
1540             ret
1541         }
1542     }
1543
1544     impl<'a> TotalOrd for &'a str {
1545         #[inline]
1546         fn cmp(&self, other: & &'a str) -> Ordering {
1547             for (s_b, o_b) in self.bytes().zip(other.bytes()) {
1548                 match s_b.cmp(&o_b) {
1549                     Greater => return Greater,
1550                     Less => return Less,
1551                     Equal => ()
1552                 }
1553             }
1554
1555             self.len().cmp(&other.len())
1556         }
1557     }
1558
1559     impl TotalOrd for ~str {
1560         #[inline]
1561         fn cmp(&self, other: &~str) -> Ordering { self.as_slice().cmp(&other.as_slice()) }
1562     }
1563
1564     impl<'a> Eq for &'a str {
1565         #[inline]
1566         fn eq(&self, other: & &'a str) -> bool {
1567             eq_slice((*self), (*other))
1568         }
1569         #[inline]
1570         fn ne(&self, other: & &'a str) -> bool { !(*self).eq(other) }
1571     }
1572
1573     impl Eq for ~str {
1574         #[inline]
1575         fn eq(&self, other: &~str) -> bool {
1576             eq_slice((*self), (*other))
1577         }
1578     }
1579
1580     impl<'a> TotalEq for &'a str {
1581         #[inline]
1582         fn equals(&self, other: & &'a str) -> bool {
1583             eq_slice((*self), (*other))
1584         }
1585     }
1586
1587     impl TotalEq for ~str {
1588         #[inline]
1589         fn equals(&self, other: &~str) -> bool {
1590             eq_slice((*self), (*other))
1591         }
1592     }
1593
1594     impl<'a> Ord for &'a str {
1595         #[inline]
1596         fn lt(&self, other: & &'a str) -> bool { self.cmp(other) == Less }
1597     }
1598
1599     impl Ord for ~str {
1600         #[inline]
1601         fn lt(&self, other: &~str) -> bool { self.cmp(other) == Less }
1602     }
1603
1604     impl<'a, S: Str> Equiv<S> for &'a str {
1605         #[inline]
1606         fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
1607     }
1608
1609     impl<'a, S: Str> Equiv<S> for ~str {
1610         #[inline]
1611         fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
1612     }
1613 }
1614
1615 #[cfg(test)]
1616 pub mod traits {}
1617
1618 /// Any string that can be represented as a slice
1619 pub trait Str {
1620     /// Work with `self` as a slice.
1621     fn as_slice<'a>(&'a self) -> &'a str;
1622
1623     /// Convert `self` into a ~str, not making a copy if possible
1624     fn into_owned(self) -> ~str;
1625 }
1626
1627 impl<'a> Str for &'a str {
1628     #[inline]
1629     fn as_slice<'a>(&'a self) -> &'a str { *self }
1630
1631     #[inline]
1632     fn into_owned(self) -> ~str { self.to_owned() }
1633 }
1634
1635 impl<'a> Str for ~str {
1636     #[inline]
1637     fn as_slice<'a>(&'a self) -> &'a str {
1638         let s: &'a str = *self; s
1639     }
1640
1641     #[inline]
1642     fn into_owned(self) -> ~str { self }
1643 }
1644
1645 impl<'a> Container for &'a str {
1646     #[inline]
1647     fn len(&self) -> uint {
1648         self.repr().len
1649     }
1650 }
1651
1652 impl Container for ~str {
1653     #[inline]
1654     fn len(&self) -> uint { self.as_slice().len() }
1655 }
1656
1657 impl Mutable for ~str {
1658     /// Remove all content, make the string empty
1659     #[inline]
1660     fn clear(&mut self) {
1661         unsafe {
1662             self.set_len(0)
1663         }
1664     }
1665 }
1666
1667 /// Methods for string slices
1668 pub trait StrSlice<'a> {
1669     /// Returns true if one string contains another
1670     ///
1671     /// # Arguments
1672     ///
1673     /// - needle - The string to look for
1674     fn contains<'a>(&self, needle: &'a str) -> bool;
1675
1676     /// Returns true if a string contains a char.
1677     ///
1678     /// # Arguments
1679     ///
1680     /// - needle - The char to look for
1681     fn contains_char(&self, needle: char) -> bool;
1682
1683     /// An iterator over the characters of `self`. Note, this iterates
1684     /// over unicode code-points, not unicode graphemes.
1685     ///
1686     /// # Example
1687     ///
1688     /// ```rust
1689     /// let v: ~[char] = "abc åäö".chars().collect();
1690     /// assert_eq!(v, ~['a', 'b', 'c', ' ', 'å', 'ä', 'ö']);
1691     /// ```
1692     fn chars(&self) -> Chars<'a>;
1693
1694     /// An iterator over the characters of `self`, in reverse order.
1695     fn chars_rev(&self) -> RevChars<'a>;
1696
1697     /// An iterator over the bytes of `self`
1698     fn bytes(&self) -> Bytes<'a>;
1699
1700     /// An iterator over the bytes of `self`, in reverse order
1701     fn bytes_rev(&self) -> RevBytes<'a>;
1702
1703     /// An iterator over the characters of `self` and their byte offsets.
1704     fn char_indices(&self) -> CharOffsets<'a>;
1705
1706     /// An iterator over the characters of `self` and their byte offsets,
1707     /// in reverse order.
1708     fn char_indices_rev(&self) -> RevCharOffsets<'a>;
1709
1710     /// An iterator over substrings of `self`, separated by characters
1711     /// matched by `sep`.
1712     ///
1713     /// # Example
1714     ///
1715     /// ```rust
1716     /// let v: ~[&str] = "Mary had a little lamb".split(' ').collect();
1717     /// assert_eq!(v, ~["Mary", "had", "a", "little", "lamb"]);
1718     ///
1719     /// let v: ~[&str] = "abc1def2ghi".split(|c: char| c.is_digit()).collect();
1720     /// assert_eq!(v, ~["abc", "def", "ghi"]);
1721     ///
1722     /// let v: ~[&str] = "lionXXtigerXleopard".split('X').collect();
1723     /// assert_eq!(v, ~["lion", "", "tiger", "leopard"]);
1724     /// ```
1725     fn split<Sep: CharEq>(&self, sep: Sep) -> CharSplits<'a, Sep>;
1726
1727     /// An iterator over substrings of `self`, separated by characters
1728     /// matched by `sep`, restricted to splitting at most `count`
1729     /// times.
1730     ///
1731     /// # Example
1732     ///
1733     /// ```rust
1734     /// let v: ~[&str] = "Mary had a little lambda".splitn(' ', 2).collect();
1735     /// assert_eq!(v, ~["Mary", "had", "a little lambda"]);
1736     ///
1737     /// let v: ~[&str] = "abc1def2ghi".splitn(|c: char| c.is_digit(), 1).collect();
1738     /// assert_eq!(v, ~["abc", "def2ghi"]);
1739     ///
1740     /// let v: ~[&str] = "lionXXtigerXleopard".splitn('X', 2).collect();
1741     /// assert_eq!(v, ~["lion", "", "tigerXleopard"]);
1742     /// ```
1743     fn splitn<Sep: CharEq>(&self, sep: Sep, count: uint) -> CharSplitsN<'a, Sep>;
1744
1745     /// An iterator over substrings of `self`, separated by characters
1746     /// matched by `sep`.
1747     ///
1748     /// Equivalent to `split`, except that the trailing substring
1749     /// is skipped if empty (terminator semantics).
1750     ///
1751     /// # Example
1752     ///
1753     /// ```rust
1754     /// let v: ~[&str] = "A.B.".split_terminator('.').collect();
1755     /// assert_eq!(v, ~["A", "B"]);
1756     ///
1757     /// let v: ~[&str] = "A..B..".split_terminator('.').collect();
1758     /// assert_eq!(v, ~["A", "", "B", ""]);
1759     /// ```
1760     fn split_terminator<Sep: CharEq>(&self, sep: Sep) -> CharSplits<'a, Sep>;
1761
1762     /// An iterator over substrings of `self`, separated by characters
1763     /// matched by `sep`, in reverse order.
1764     ///
1765     /// # Example
1766     ///
1767     /// ```rust
1768     /// let v: ~[&str] = "Mary had a little lamb".rsplit(' ').collect();
1769     /// assert_eq!(v, ~["lamb", "little", "a", "had", "Mary"]);
1770     ///
1771     /// let v: ~[&str] = "abc1def2ghi".rsplit(|c: char| c.is_digit()).collect();
1772     /// assert_eq!(v, ~["ghi", "def", "abc"]);
1773     ///
1774     /// let v: ~[&str] = "lionXXtigerXleopard".rsplit('X').collect();
1775     /// assert_eq!(v, ~["leopard", "tiger", "", "lion"]);
1776     /// ```
1777     fn rsplit<Sep: CharEq>(&self, sep: Sep) -> RevCharSplits<'a, Sep>;
1778
1779     /// An iterator over substrings of `self`, separated by characters
1780     /// matched by `sep`, starting from the end of the string.
1781     /// Restricted to splitting at most `count` times.
1782     ///
1783     /// # Example
1784     ///
1785     /// ```rust
1786     /// let v: ~[&str] = "Mary had a little lamb".rsplitn(' ', 2).collect();
1787     /// assert_eq!(v, ~["lamb", "little", "Mary had a"]);
1788     ///
1789     /// let v: ~[&str] = "abc1def2ghi".rsplitn(|c: char| c.is_digit(), 1).collect();
1790     /// assert_eq!(v, ~["ghi", "abc1def"]);
1791     ///
1792     /// let v: ~[&str] = "lionXXtigerXleopard".rsplitn('X', 2).collect();
1793     /// assert_eq!(v, ~["leopard", "tiger", "lionX"]);
1794     /// ```
1795     fn rsplitn<Sep: CharEq>(&self, sep: Sep, count: uint) -> CharSplitsN<'a, Sep>;
1796
1797     /// An iterator over the start and end indices of the disjoint
1798     /// matches of `sep` within `self`.
1799     ///
1800     /// That is, each returned value `(start, end)` satisfies
1801     /// `self.slice(start, end) == sep`. For matches of `sep` within
1802     /// `self` that overlap, only the indicies corresponding to the
1803     /// first match are returned.
1804     ///
1805     /// # Example
1806     ///
1807     /// ```rust
1808     /// let v: ~[(uint, uint)] = "abcXXXabcYYYabc".match_indices("abc").collect();
1809     /// assert_eq!(v, ~[(0,3), (6,9), (12,15)]);
1810     ///
1811     /// let v: ~[(uint, uint)] = "1abcabc2".match_indices("abc").collect();
1812     /// assert_eq!(v, ~[(1,4), (4,7)]);
1813     ///
1814     /// let v: ~[(uint, uint)] = "ababa".match_indices("aba").collect();
1815     /// assert_eq!(v, ~[(0, 3)]); // only the first `aba`
1816     /// ```
1817     fn match_indices(&self, sep: &'a str) -> MatchIndices<'a>;
1818
1819     /// An iterator over the substrings of `self` separated by `sep`.
1820     ///
1821     /// # Example
1822     ///
1823     /// ```rust
1824     /// let v: ~[&str] = "abcXXXabcYYYabc".split_str("abc").collect();
1825     /// assert_eq!(v, ~["", "XXX", "YYY", ""]);
1826     ///
1827     /// let v: ~[&str] = "1abcabc2".split_str("abc").collect();
1828     /// assert_eq!(v, ~["1", "", "2"]);
1829     /// ```
1830     fn split_str(&self, &'a str) -> StrSplits<'a>;
1831
1832     /// An iterator over the lines of a string (subsequences separated
1833     /// by `\n`). This does not include the empty string after a
1834     /// trailing `\n`.
1835     ///
1836     /// # Example
1837     ///
1838     /// ```rust
1839     /// let four_lines = "foo\nbar\n\nbaz\n";
1840     /// let v: ~[&str] = four_lines.lines().collect();
1841     /// assert_eq!(v, ~["foo", "bar", "", "baz"]);
1842     /// ```
1843     fn lines(&self) -> CharSplits<'a, char>;
1844
1845     /// An iterator over the lines of a string, separated by either
1846     /// `\n` or `\r\n`. As with `.lines()`, this does not include an
1847     /// empty trailing line.
1848     ///
1849     /// # Example
1850     ///
1851     /// ```rust
1852     /// let four_lines = "foo\r\nbar\n\r\nbaz\n";
1853     /// let v: ~[&str] = four_lines.lines_any().collect();
1854     /// assert_eq!(v, ~["foo", "bar", "", "baz"]);
1855     /// ```
1856     fn lines_any(&self) -> AnyLines<'a>;
1857
1858     /// An iterator over the words of a string (subsequences separated
1859     /// by any sequence of whitespace). Sequences of whitespace are
1860     /// collapsed, so empty "words" are not included.
1861     ///
1862     /// # Example
1863     ///
1864     /// ```rust
1865     /// let some_words = " Mary   had\ta little  \n\t lamb";
1866     /// let v: ~[&str] = some_words.words().collect();
1867     /// assert_eq!(v, ~["Mary", "had", "a", "little", "lamb"]);
1868     /// ```
1869     fn words(&self) -> Words<'a>;
1870
1871     /// An Iterator over the string in Unicode Normalization Form D
1872     /// (canonical decomposition).
1873     fn nfd_chars(&self) -> Normalizations<'a>;
1874
1875     /// An Iterator over the string in Unicode Normalization Form KD
1876     /// (compatibility decomposition).
1877     fn nfkd_chars(&self) -> Normalizations<'a>;
1878
1879     /// Returns true if the string contains only whitespace.
1880     ///
1881     /// Whitespace characters are determined by `char::is_whitespace`.
1882     ///
1883     /// # Example
1884     ///
1885     /// ```rust
1886     /// assert!(" \t\n".is_whitespace());
1887     /// assert!("".is_whitespace());
1888     ///
1889     /// assert!( !"abc".is_whitespace());
1890     /// ```
1891     fn is_whitespace(&self) -> bool;
1892
1893     /// Returns true if the string contains only alphanumeric code
1894     /// points.
1895     ///
1896     /// Alphanumeric characters are determined by `char::is_alphanumeric`.
1897     ///
1898     /// # Example
1899     ///
1900     /// ```rust
1901     /// assert!("Löwe老虎Léopard123".is_alphanumeric());
1902     /// assert!("".is_alphanumeric());
1903     ///
1904     /// assert!( !" &*~".is_alphanumeric());
1905     /// ```
1906     fn is_alphanumeric(&self) -> bool;
1907
1908     /// Returns the number of Unicode code points (`char`) that a
1909     /// string holds.
1910     ///
1911     /// This does not perform any normalization, and is `O(n)`, since
1912     /// UTF-8 is a variable width encoding of code points.
1913     ///
1914     /// *Warning*: The number of code points in a string does not directly
1915     /// correspond to the number of visible characters or width of the
1916     /// visible text due to composing characters, and double- and
1917     /// zero-width ones.
1918     ///
1919     /// See also `.len()` for the byte length.
1920     ///
1921     /// # Example
1922     ///
1923     /// ```rust
1924     /// // composed forms of `ö` and `é`
1925     /// let c = "Löwe 老虎 Léopard"; // German, Simplified Chinese, French
1926     /// // decomposed forms of `ö` and `é`
1927     /// let d = "Lo\u0308we 老虎 Le\u0301opard";
1928     ///
1929     /// assert_eq!(c.char_len(), 15);
1930     /// assert_eq!(d.char_len(), 17);
1931     ///
1932     /// assert_eq!(c.len(), 21);
1933     /// assert_eq!(d.len(), 23);
1934     ///
1935     /// // the two strings *look* the same
1936     /// println!("{}", c);
1937     /// println!("{}", d);
1938     /// ```
1939     fn char_len(&self) -> uint;
1940
1941     /// Returns a slice of the given string from the byte range
1942     /// [`begin`..`end`).
1943     ///
1944     /// This operation is `O(1)`.
1945     ///
1946     /// Fails when `begin` and `end` do not point to valid characters
1947     /// or point beyond the last character of the string.
1948     ///
1949     /// See also `slice_to` and `slice_from` for slicing prefixes and
1950     /// suffixes of strings, and `slice_chars` for slicing based on
1951     /// code point counts.
1952     ///
1953     /// # Example
1954     ///
1955     /// ```rust
1956     /// let s = "Löwe 老虎 Léopard";
1957     /// assert_eq!(s.slice(0, 1), "L");
1958     ///
1959     /// assert_eq!(s.slice(1, 9), "öwe 老");
1960     ///
1961     /// // these will fail:
1962     /// // byte 2 lies within `ö`:
1963     /// // s.slice(2, 3);
1964     ///
1965     /// // byte 8 lies within `老`
1966     /// // s.slice(1, 8);
1967     ///
1968     /// // byte 100 is outside the string
1969     /// // s.slice(3, 100);
1970     /// ```
1971     fn slice(&self, begin: uint, end: uint) -> &'a str;
1972
1973     /// Returns a slice of the string from `begin` to its end.
1974     ///
1975     /// Equivalent to `self.slice(begin, self.len())`.
1976     ///
1977     /// Fails when `begin` does not point to a valid character, or is
1978     /// out of bounds.
1979     ///
1980     /// See also `slice`, `slice_to` and `slice_chars`.
1981     fn slice_from(&self, begin: uint) -> &'a str;
1982
1983     /// Returns a slice of the string from the beginning to byte
1984     /// `end`.
1985     ///
1986     /// Equivalent to `self.slice(0, end)`.
1987     ///
1988     /// Fails when `end` does not point to a valid character, or is
1989     /// out of bounds.
1990     ///
1991     /// See also `slice`, `slice_from` and `slice_chars`.
1992     fn slice_to(&self, end: uint) -> &'a str;
1993
1994     /// Returns a slice of the string from the character range
1995     /// [`begin`..`end`).
1996     ///
1997     /// That is, start at the `begin`-th code point of the string and
1998     /// continue to the `end`-th code point. This does not detect or
1999     /// handle edge cases such as leaving a combining character as the
2000     /// first code point of the string.
2001     ///
2002     /// Due to the design of UTF-8, this operation is `O(end)`.
2003     /// See `slice`, `slice_to` and `slice_from` for `O(1)`
2004     /// variants that use byte indices rather than code point
2005     /// indices.
2006     ///
2007     /// Fails if `begin` > `end` or the either `begin` or `end` are
2008     /// beyond the last character of the string.
2009     ///
2010     /// # Example
2011     ///
2012     /// ```rust
2013     /// let s = "Löwe 老虎 Léopard";
2014     /// assert_eq!(s.slice_chars(0, 4), "Löwe");
2015     /// assert_eq!(s.slice_chars(5, 7), "老虎");
2016     /// ```
2017     fn slice_chars(&self, begin: uint, end: uint) -> &'a str;
2018
2019     /// Returns true if `needle` is a prefix of the string.
2020     fn starts_with(&self, needle: &str) -> bool;
2021
2022     /// Returns true if `needle` is a suffix of the string.
2023     fn ends_with(&self, needle: &str) -> bool;
2024
2025     /// Escape each char in `s` with `char::escape_default`.
2026     fn escape_default(&self) -> ~str;
2027
2028     /// Escape each char in `s` with `char::escape_unicode`.
2029     fn escape_unicode(&self) -> ~str;
2030
2031     /// Returns a string with leading and trailing whitespace removed.
2032     fn trim(&self) -> &'a str;
2033
2034     /// Returns a string with leading whitespace removed.
2035     fn trim_left(&self) -> &'a str;
2036
2037     /// Returns a string with trailing whitespace removed.
2038     fn trim_right(&self) -> &'a str;
2039
2040     /// Returns a string with characters that match `to_trim` removed.
2041     ///
2042     /// # Arguments
2043     ///
2044     /// * to_trim - a character matcher
2045     ///
2046     /// # Example
2047     ///
2048     /// ```rust
2049     /// assert_eq!("11foo1bar11".trim_chars(&'1'), "foo1bar")
2050     /// assert_eq!("12foo1bar12".trim_chars(& &['1', '2']), "foo1bar")
2051     /// assert_eq!("123foo1bar123".trim_chars(&|c: char| c.is_digit()), "foo1bar")
2052     /// ```
2053     fn trim_chars<C: CharEq>(&self, to_trim: &C) -> &'a str;
2054
2055     /// Returns a string with leading `chars_to_trim` removed.
2056     ///
2057     /// # Arguments
2058     ///
2059     /// * to_trim - a character matcher
2060     ///
2061     /// # Example
2062     ///
2063     /// ```rust
2064     /// assert_eq!("11foo1bar11".trim_left_chars(&'1'), "foo1bar11")
2065     /// assert_eq!("12foo1bar12".trim_left_chars(& &['1', '2']), "foo1bar12")
2066     /// assert_eq!("123foo1bar123".trim_left_chars(&|c: char| c.is_digit()), "foo1bar123")
2067     /// ```
2068     fn trim_left_chars<C: CharEq>(&self, to_trim: &C) -> &'a str;
2069
2070     /// Returns a string with trailing `chars_to_trim` removed.
2071     ///
2072     /// # Arguments
2073     ///
2074     /// * to_trim - a character matcher
2075     ///
2076     /// # Example
2077     ///
2078     /// ```rust
2079     /// assert_eq!("11foo1bar11".trim_right_chars(&'1'), "11foo1bar")
2080     /// assert_eq!("12foo1bar12".trim_right_chars(& &['1', '2']), "12foo1bar")
2081     /// assert_eq!("123foo1bar123".trim_right_chars(&|c: char| c.is_digit()), "123foo1bar")
2082     /// ```
2083     fn trim_right_chars<C: CharEq>(&self, to_trim: &C) -> &'a str;
2084
2085     /// Replace all occurrences of one string with another.
2086     ///
2087     /// # Arguments
2088     ///
2089     /// * `from` - The string to replace
2090     /// * `to` - The replacement string
2091     ///
2092     /// # Return value
2093     ///
2094     /// The original string with all occurances of `from` replaced with `to`.
2095     ///
2096     /// # Example
2097     ///
2098     /// ```rust
2099     /// let s = ~"Do you know the muffin man,
2100     /// The muffin man, the muffin man, ...";
2101     ///
2102     /// assert_eq!(s.replace("muffin man", "little lamb"),
2103     ///            ~"Do you know the little lamb,
2104     /// The little lamb, the little lamb, ...");
2105     ///
2106     /// // not found, so no change.
2107     /// assert_eq!(s.replace("cookie monster", "little lamb"), s);
2108     /// ```
2109     fn replace(&self, from: &str, to: &str) -> ~str;
2110
2111     /// Copy a slice into a new owned str.
2112     fn to_owned(&self) -> ~str;
2113
2114     /// Converts to a vector of `u16` encoded as UTF-16.
2115     fn to_utf16(&self) -> ~[u16];
2116
2117     /// Check that `index`-th byte lies at the start and/or end of a
2118     /// UTF-8 code point sequence.
2119     ///
2120     /// The start and end of the string (when `index == self.len()`)
2121     /// are considered to be boundaries.
2122     ///
2123     /// Fails if `index` is greater than `self.len()`.
2124     ///
2125     /// # Example
2126     ///
2127     /// ```rust
2128     /// let s = "Löwe 老虎 Léopard";
2129     /// assert!(s.is_char_boundary(0));
2130     /// // start of `老`
2131     /// assert!(s.is_char_boundary(6));
2132     /// assert!(s.is_char_boundary(s.len()));
2133     ///
2134     /// // second byte of `ö`
2135     /// assert!(!s.is_char_boundary(2));
2136     ///
2137     /// // third byte of `老`
2138     /// assert!(!s.is_char_boundary(8));
2139     /// ```
2140     fn is_char_boundary(&self, index: uint) -> bool;
2141
2142     /// Pluck a character out of a string and return the index of the next
2143     /// character.
2144     ///
2145     /// This function can be used to iterate over the unicode characters of a
2146     /// string.
2147     ///
2148     /// # Example
2149     ///
2150     /// This example manually iterate through the characters of a
2151     /// string; this should normally by done by `.chars()` or
2152     /// `.char_indices`.
2153     ///
2154     /// ```rust
2155     /// use std::str::CharRange;
2156     ///
2157     /// let s = "中华Việt Nam";
2158     /// let mut i = 0u;
2159     /// while i < s.len() {
2160     ///     let CharRange {ch, next} = s.char_range_at(i);
2161     ///     println!("{}: {}", i, ch);
2162     ///     i = next;
2163     /// }
2164     /// ```
2165     ///
2166     /// ## Output
2167     ///
2168     /// ```ignore
2169     /// 0: 中
2170     /// 3: 华
2171     /// 6: V
2172     /// 7: i
2173     /// 8: ệ
2174     /// 11: t
2175     /// 12:
2176     /// 13: N
2177     /// 14: a
2178     /// 15: m
2179     /// ```
2180     ///
2181     /// # Arguments
2182     ///
2183     /// * s - The string
2184     /// * i - The byte offset of the char to extract
2185     ///
2186     /// # Return value
2187     ///
2188     /// A record {ch: char, next: uint} containing the char value and the byte
2189     /// index of the next unicode character.
2190     ///
2191     /// # Failure
2192     ///
2193     /// If `i` is greater than or equal to the length of the string.
2194     /// If `i` is not the index of the beginning of a valid UTF-8 character.
2195     fn char_range_at(&self, start: uint) -> CharRange;
2196
2197     /// Given a byte position and a str, return the previous char and its position.
2198     ///
2199     /// This function can be used to iterate over a unicode string in reverse.
2200     ///
2201     /// Returns 0 for next index if called on start index 0.
2202     fn char_range_at_reverse(&self, start: uint) -> CharRange;
2203
2204     /// Plucks the character starting at the `i`th byte of a string
2205     fn char_at(&self, i: uint) -> char;
2206
2207     /// Plucks the character ending at the `i`th byte of a string
2208     fn char_at_reverse(&self, i: uint) -> char;
2209
2210     /// Work with the byte buffer of a string as a byte slice.
2211     fn as_bytes(&self) -> &'a [u8];
2212
2213     /// Returns the byte index of the first character of `self` that
2214     /// matches `search`.
2215     ///
2216     /// # Return value
2217     ///
2218     /// `Some` containing the byte index of the last matching character
2219     /// or `None` if there is no match
2220     ///
2221     /// # Example
2222     ///
2223     /// ```rust
2224     /// let s = "Löwe 老虎 Léopard";
2225     ///
2226     /// assert_eq!(s.find('L'), Some(0));
2227     /// assert_eq!(s.find('é'), Some(14));
2228     ///
2229     /// // the first space
2230     /// assert_eq!(s.find(|c: char| c.is_whitespace()), Some(5));
2231     ///
2232     /// // neither are found
2233     /// assert_eq!(s.find(&['1', '2']), None);
2234     /// ```
2235     fn find<C: CharEq>(&self, search: C) -> Option<uint>;
2236
2237     /// Returns the byte index of the last character of `self` that
2238     /// matches `search`.
2239     ///
2240     /// # Return value
2241     ///
2242     /// `Some` containing the byte index of the last matching character
2243     /// or `None` if there is no match.
2244     ///
2245     /// # Example
2246     ///
2247     /// ```rust
2248     /// let s = "Löwe 老虎 Léopard";
2249     ///
2250     /// assert_eq!(s.rfind('L'), Some(13));
2251     /// assert_eq!(s.rfind('é'), Some(14));
2252     ///
2253     /// // the second space
2254     /// assert_eq!(s.rfind(|c: char| c.is_whitespace()), Some(12));
2255     ///
2256     /// // searches for an occurrence of either `1` or `2`, but neither are found
2257     /// assert_eq!(s.rfind(&['1', '2']), None);
2258     /// ```
2259     fn rfind<C: CharEq>(&self, search: C) -> Option<uint>;
2260
2261     /// Returns the byte index of the first matching substring
2262     ///
2263     /// # Arguments
2264     ///
2265     /// * `needle` - The string to search for
2266     ///
2267     /// # Return value
2268     ///
2269     /// `Some` containing the byte index of the first matching substring
2270     /// or `None` if there is no match.
2271     ///
2272     /// # Example
2273     ///
2274     /// ```rust
2275     /// let s = "Löwe 老虎 Léopard";
2276     ///
2277     /// assert_eq!(s.find_str("老虎 L"), Some(6));
2278     /// assert_eq!(s.find_str("muffin man"), None);
2279     /// ```
2280     fn find_str(&self, &str) -> Option<uint>;
2281
2282     /// Given a string, make a new string with repeated copies of it.
2283     fn repeat(&self, nn: uint) -> ~str;
2284
2285     /// Retrieves the first character from a string slice and returns
2286     /// it. This does not allocate a new string; instead, it returns a
2287     /// slice that point one character beyond the character that was
2288     /// shifted. If the string does not contain any characters,
2289     /// a tuple of None and an empty string is returned instead.
2290     ///
2291     /// # Example
2292     ///
2293     /// ```rust
2294     /// let s = "Löwe 老虎 Léopard";
2295     /// let (c, s1) = s.slice_shift_char();
2296     /// assert_eq!(c, Some('L'));
2297     /// assert_eq!(s1, "öwe 老虎 Léopard");
2298     ///
2299     /// let (c, s2) = s1.slice_shift_char();
2300     /// assert_eq!(c, Some('ö'));
2301     /// assert_eq!(s2, "we 老虎 Léopard");
2302     /// ```
2303     fn slice_shift_char(&self) -> (Option<char>, &'a str);
2304
2305     /// Levenshtein Distance between two strings.
2306     fn lev_distance(&self, t: &str) -> uint;
2307
2308     /// Returns the byte offset of an inner slice relative to an enclosing outer slice.
2309     ///
2310     /// Fails if `inner` is not a direct slice contained within self.
2311     ///
2312     /// # Example
2313     ///
2314     /// ```rust
2315     /// let string = "a\nb\nc";
2316     /// let lines: ~[&str] = string.lines().collect();
2317     ///
2318     /// assert!(string.subslice_offset(lines[0]) == 0); // &"a"
2319     /// assert!(string.subslice_offset(lines[1]) == 2); // &"b"
2320     /// assert!(string.subslice_offset(lines[2]) == 4); // &"c"
2321     /// ```
2322     fn subslice_offset(&self, inner: &str) -> uint;
2323
2324     /// Return an unsafe pointer to the strings buffer.
2325     ///
2326     /// The caller must ensure that the string outlives this pointer,
2327     /// and that it is not reallocated (e.g. by pushing to the
2328     /// string).
2329     fn as_ptr(&self) -> *u8;
2330 }
2331
2332 impl<'a> StrSlice<'a> for &'a str {
2333     #[inline]
2334     fn contains<'a>(&self, needle: &'a str) -> bool {
2335         self.find_str(needle).is_some()
2336     }
2337
2338     #[inline]
2339     fn contains_char(&self, needle: char) -> bool {
2340         self.find(needle).is_some()
2341     }
2342
2343     #[inline]
2344     fn chars(&self) -> Chars<'a> {
2345         Chars{string: *self}
2346     }
2347
2348     #[inline]
2349     fn chars_rev(&self) -> RevChars<'a> {
2350         self.chars().rev()
2351     }
2352
2353     #[inline]
2354     fn bytes(&self) -> Bytes<'a> {
2355         self.as_bytes().iter().map(|&b| b)
2356     }
2357
2358     #[inline]
2359     fn bytes_rev(&self) -> RevBytes<'a> {
2360         self.bytes().rev()
2361     }
2362
2363     #[inline]
2364     fn char_indices(&self) -> CharOffsets<'a> {
2365         CharOffsets{string: *self, iter: self.chars()}
2366     }
2367
2368     #[inline]
2369     fn char_indices_rev(&self) -> RevCharOffsets<'a> {
2370         self.char_indices().rev()
2371     }
2372
2373     #[inline]
2374     fn split<Sep: CharEq>(&self, sep: Sep) -> CharSplits<'a, Sep> {
2375         CharSplits {
2376             string: *self,
2377             only_ascii: sep.only_ascii(),
2378             sep: sep,
2379             allow_trailing_empty: true,
2380             finished: false,
2381         }
2382     }
2383
2384     #[inline]
2385     fn splitn<Sep: CharEq>(&self, sep: Sep, count: uint)
2386         -> CharSplitsN<'a, Sep> {
2387         CharSplitsN {
2388             iter: self.split(sep),
2389             count: count,
2390             invert: false,
2391         }
2392     }
2393
2394     #[inline]
2395     fn split_terminator<Sep: CharEq>(&self, sep: Sep)
2396         -> CharSplits<'a, Sep> {
2397         CharSplits {
2398             allow_trailing_empty: false,
2399             ..self.split(sep)
2400         }
2401     }
2402
2403     #[inline]
2404     fn rsplit<Sep: CharEq>(&self, sep: Sep) -> RevCharSplits<'a, Sep> {
2405         self.split(sep).rev()
2406     }
2407
2408     #[inline]
2409     fn rsplitn<Sep: CharEq>(&self, sep: Sep, count: uint)
2410         -> CharSplitsN<'a, Sep> {
2411         CharSplitsN {
2412             iter: self.split(sep),
2413             count: count,
2414             invert: true,
2415         }
2416     }
2417
2418     #[inline]
2419     fn match_indices(&self, sep: &'a str) -> MatchIndices<'a> {
2420         assert!(!sep.is_empty())
2421         MatchIndices {
2422             haystack: *self,
2423             needle: sep,
2424             position: 0
2425         }
2426     }
2427
2428     #[inline]
2429     fn split_str(&self, sep: &'a str) -> StrSplits<'a> {
2430         StrSplits {
2431             it: self.match_indices(sep),
2432             last_end: 0,
2433             finished: false
2434         }
2435     }
2436
2437     #[inline]
2438     fn lines(&self) -> CharSplits<'a, char> {
2439         self.split_terminator('\n')
2440     }
2441
2442     fn lines_any(&self) -> AnyLines<'a> {
2443         self.lines().map(|line| {
2444             let l = line.len();
2445             if l > 0 && line[l - 1] == '\r' as u8 { line.slice(0, l - 1) }
2446             else { line }
2447         })
2448     }
2449
2450     #[inline]
2451     fn words(&self) -> Words<'a> {
2452         self.split(char::is_whitespace).filter(|s| !s.is_empty())
2453     }
2454
2455     #[inline]
2456     fn nfd_chars(&self) -> Normalizations<'a> {
2457         Normalizations {
2458             iter: self.chars(),
2459             buffer: ~[],
2460             sorted: false,
2461             kind: NFD
2462         }
2463     }
2464
2465     #[inline]
2466     fn nfkd_chars(&self) -> Normalizations<'a> {
2467         Normalizations {
2468             iter: self.chars(),
2469             buffer: ~[],
2470             sorted: false,
2471             kind: NFKD
2472         }
2473     }
2474
2475     #[inline]
2476     fn is_whitespace(&self) -> bool { self.chars().all(char::is_whitespace) }
2477
2478     #[inline]
2479     fn is_alphanumeric(&self) -> bool { self.chars().all(char::is_alphanumeric) }
2480
2481     #[inline]
2482     fn char_len(&self) -> uint { self.chars().len() }
2483
2484     #[inline]
2485     fn slice(&self, begin: uint, end: uint) -> &'a str {
2486         assert!(self.is_char_boundary(begin) && self.is_char_boundary(end));
2487         unsafe { raw::slice_bytes(*self, begin, end) }
2488     }
2489
2490     #[inline]
2491     fn slice_from(&self, begin: uint) -> &'a str {
2492         self.slice(begin, self.len())
2493     }
2494
2495     #[inline]
2496     fn slice_to(&self, end: uint) -> &'a str {
2497         assert!(self.is_char_boundary(end));
2498         unsafe { raw::slice_bytes(*self, 0, end) }
2499     }
2500
2501     fn slice_chars(&self, begin: uint, end: uint) -> &'a str {
2502         assert!(begin <= end);
2503         let mut count = 0;
2504         let mut begin_byte = None;
2505         let mut end_byte = None;
2506
2507         // This could be even more efficient by not decoding,
2508         // only finding the char boundaries
2509         for (idx, _) in self.char_indices() {
2510             if count == begin { begin_byte = Some(idx); }
2511             if count == end { end_byte = Some(idx); break; }
2512             count += 1;
2513         }
2514         if begin_byte.is_none() && count == begin { begin_byte = Some(self.len()) }
2515         if end_byte.is_none() && count == end { end_byte = Some(self.len()) }
2516
2517         match (begin_byte, end_byte) {
2518             (None, _) => fail!("slice_chars: `begin` is beyond end of string"),
2519             (_, None) => fail!("slice_chars: `end` is beyond end of string"),
2520             (Some(a), Some(b)) => unsafe { raw::slice_bytes(*self, a, b) }
2521         }
2522     }
2523
2524     #[inline]
2525     fn starts_with<'a>(&self, needle: &'a str) -> bool {
2526         let n = needle.len();
2527         self.len() >= n && needle.as_bytes() == self.as_bytes().slice_to(n)
2528     }
2529
2530     #[inline]
2531     fn ends_with(&self, needle: &str) -> bool {
2532         let (m, n) = (self.len(), needle.len());
2533         m >= n && needle.as_bytes() == self.as_bytes().slice_from(m - n)
2534     }
2535
2536     fn escape_default(&self) -> ~str {
2537         let mut out = with_capacity(self.len());
2538         for c in self.chars() {
2539             c.escape_default(|c| out.push_char(c));
2540         }
2541         out
2542     }
2543
2544     fn escape_unicode(&self) -> ~str {
2545         let mut out = with_capacity(self.len());
2546         for c in self.chars() {
2547             c.escape_unicode(|c| out.push_char(c));
2548         }
2549         out
2550     }
2551
2552     #[inline]
2553     fn trim(&self) -> &'a str {
2554         self.trim_left().trim_right()
2555     }
2556
2557     #[inline]
2558     fn trim_left(&self) -> &'a str {
2559         self.trim_left_chars(&char::is_whitespace)
2560     }
2561
2562     #[inline]
2563     fn trim_right(&self) -> &'a str {
2564         self.trim_right_chars(&char::is_whitespace)
2565     }
2566
2567     #[inline]
2568     fn trim_chars<C: CharEq>(&self, to_trim: &C) -> &'a str {
2569         self.trim_left_chars(to_trim).trim_right_chars(to_trim)
2570     }
2571
2572     #[inline]
2573     fn trim_left_chars<C: CharEq>(&self, to_trim: &C) -> &'a str {
2574         match self.find(|c: char| !to_trim.matches(c)) {
2575             None => "",
2576             Some(first) => unsafe { raw::slice_bytes(*self, first, self.len()) }
2577         }
2578     }
2579
2580     #[inline]
2581     fn trim_right_chars<C: CharEq>(&self, to_trim: &C) -> &'a str {
2582         match self.rfind(|c: char| !to_trim.matches(c)) {
2583             None => "",
2584             Some(last) => {
2585                 let next = self.char_range_at(last).next;
2586                 unsafe { raw::slice_bytes(*self, 0u, next) }
2587             }
2588         }
2589     }
2590
2591     fn replace(&self, from: &str, to: &str) -> ~str {
2592         let mut result = ~"";
2593         let mut last_end = 0;
2594         for (start, end) in self.match_indices(from) {
2595             result.push_str(unsafe{raw::slice_bytes(*self, last_end, start)});
2596             result.push_str(to);
2597             last_end = end;
2598         }
2599         result.push_str(unsafe{raw::slice_bytes(*self, last_end, self.len())});
2600         result
2601     }
2602
2603     #[inline]
2604     fn to_owned(&self) -> ~str {
2605         let len = self.len();
2606         unsafe {
2607             let mut v = slice::with_capacity(len);
2608
2609             ptr::copy_memory(v.as_mut_ptr(), self.as_ptr(), len);
2610             v.set_len(len);
2611             ::cast::transmute(v)
2612         }
2613     }
2614
2615     fn to_utf16(&self) -> ~[u16] {
2616         let mut u = ~[];
2617         for ch in self.chars() {
2618             // Arithmetic with u32 literals is easier on the eyes than chars.
2619             let mut ch = ch as u32;
2620
2621             if (ch & 0xFFFF_u32) == ch {
2622                 // The BMP falls through (assuming non-surrogate, as it
2623                 // should)
2624                 assert!(ch <= 0xD7FF_u32 || ch >= 0xE000_u32);
2625                 u.push(ch as u16)
2626             } else {
2627                 // Supplementary planes break into surrogates.
2628                 assert!(ch >= 0x1_0000_u32 && ch <= 0x10_FFFF_u32);
2629                 ch -= 0x1_0000_u32;
2630                 let w1 = 0xD800_u16 | ((ch >> 10) as u16);
2631                 let w2 = 0xDC00_u16 | ((ch as u16) & 0x3FF_u16);
2632                 u.push_all([w1, w2])
2633             }
2634         }
2635         u
2636     }
2637
2638     #[inline]
2639     fn is_char_boundary(&self, index: uint) -> bool {
2640         if index == self.len() { return true; }
2641         let b = self[index];
2642         return b < 128u8 || b >= 192u8;
2643     }
2644
2645     #[inline]
2646     fn char_range_at(&self, i: uint) -> CharRange {
2647         if self[i] < 128u8 {
2648             return CharRange {ch: self[i] as char, next: i + 1 };
2649         }
2650
2651         // Multibyte case is a fn to allow char_range_at to inline cleanly
2652         fn multibyte_char_range_at(s: &str, i: uint) -> CharRange {
2653             let mut val = s[i] as u32;
2654             let w = UTF8_CHAR_WIDTH[val] as uint;
2655             assert!((w != 0));
2656
2657             val = utf8_first_byte!(val, w);
2658             val = utf8_acc_cont_byte!(val, s[i + 1]);
2659             if w > 2 { val = utf8_acc_cont_byte!(val, s[i + 2]); }
2660             if w > 3 { val = utf8_acc_cont_byte!(val, s[i + 3]); }
2661
2662             return CharRange {ch: unsafe { transmute(val) }, next: i + w};
2663         }
2664
2665         return multibyte_char_range_at(*self, i);
2666     }
2667
2668     #[inline]
2669     fn char_range_at_reverse(&self, start: uint) -> CharRange {
2670         let mut prev = start;
2671
2672         prev = prev.saturating_sub(1);
2673         if self[prev] < 128 { return CharRange{ch: self[prev] as char, next: prev} }
2674
2675         // Multibyte case is a fn to allow char_range_at_reverse to inline cleanly
2676         fn multibyte_char_range_at_reverse(s: &str, mut i: uint) -> CharRange {
2677             // while there is a previous byte == 10......
2678             while i > 0 && s[i] & 192u8 == TAG_CONT_U8 {
2679                 i -= 1u;
2680             }
2681
2682             let mut val = s[i] as u32;
2683             let w = UTF8_CHAR_WIDTH[val] as uint;
2684             assert!((w != 0));
2685
2686             val = utf8_first_byte!(val, w);
2687             val = utf8_acc_cont_byte!(val, s[i + 1]);
2688             if w > 2 { val = utf8_acc_cont_byte!(val, s[i + 2]); }
2689             if w > 3 { val = utf8_acc_cont_byte!(val, s[i + 3]); }
2690
2691             return CharRange {ch: unsafe { transmute(val) }, next: i};
2692         }
2693
2694         return multibyte_char_range_at_reverse(*self, prev);
2695     }
2696
2697     #[inline]
2698     fn char_at(&self, i: uint) -> char {
2699         self.char_range_at(i).ch
2700     }
2701
2702     #[inline]
2703     fn char_at_reverse(&self, i: uint) -> char {
2704         self.char_range_at_reverse(i).ch
2705     }
2706
2707     #[inline]
2708     fn as_bytes(&self) -> &'a [u8] {
2709         unsafe { cast::transmute(*self) }
2710     }
2711
2712     fn find<C: CharEq>(&self, search: C) -> Option<uint> {
2713         if search.only_ascii() {
2714             self.bytes().position(|b| search.matches(b as char))
2715         } else {
2716             for (index, c) in self.char_indices() {
2717                 if search.matches(c) { return Some(index); }
2718             }
2719             None
2720         }
2721     }
2722
2723     fn rfind<C: CharEq>(&self, search: C) -> Option<uint> {
2724         if search.only_ascii() {
2725             self.bytes().rposition(|b| search.matches(b as char))
2726         } else {
2727             for (index, c) in self.char_indices_rev() {
2728                 if search.matches(c) { return Some(index); }
2729             }
2730             None
2731         }
2732     }
2733
2734     fn find_str(&self, needle: &str) -> Option<uint> {
2735         if needle.is_empty() {
2736             Some(0)
2737         } else {
2738             self.match_indices(needle)
2739                 .next()
2740                 .map(|(start, _end)| start)
2741         }
2742     }
2743
2744     fn repeat(&self, nn: uint) -> ~str {
2745         let mut ret = with_capacity(nn * self.len());
2746         for _ in range(0, nn) {
2747             ret.push_str(*self);
2748         }
2749         ret
2750     }
2751
2752     #[inline]
2753     fn slice_shift_char(&self) -> (Option<char>, &'a str) {
2754         if self.is_empty() {
2755             return (None, *self);
2756         } else {
2757             let CharRange {ch, next} = self.char_range_at(0u);
2758             let next_s = unsafe { raw::slice_bytes(*self, next, self.len()) };
2759             return (Some(ch), next_s);
2760         }
2761     }
2762
2763     fn lev_distance(&self, t: &str) -> uint {
2764         let slen = self.len();
2765         let tlen = t.len();
2766
2767         if slen == 0 { return tlen; }
2768         if tlen == 0 { return slen; }
2769
2770         let mut dcol = slice::from_fn(tlen + 1, |x| x);
2771
2772         for (i, sc) in self.chars().enumerate() {
2773
2774             let mut current = i;
2775             dcol[0] = current + 1;
2776
2777             for (j, tc) in t.chars().enumerate() {
2778
2779                 let next = dcol[j + 1];
2780
2781                 if sc == tc {
2782                     dcol[j + 1] = current;
2783                 } else {
2784                     dcol[j + 1] = ::cmp::min(current, next);
2785                     dcol[j + 1] = ::cmp::min(dcol[j + 1], dcol[j]) + 1;
2786                 }
2787
2788                 current = next;
2789             }
2790         }
2791
2792         return dcol[tlen];
2793     }
2794
2795     fn subslice_offset(&self, inner: &str) -> uint {
2796         let a_start = self.as_ptr() as uint;
2797         let a_end = a_start + self.len();
2798         let b_start = inner.as_ptr() as uint;
2799         let b_end = b_start + inner.len();
2800
2801         assert!(a_start <= b_start);
2802         assert!(b_end <= a_end);
2803         b_start - a_start
2804     }
2805
2806     #[inline]
2807     fn as_ptr(&self) -> *u8 {
2808         self.repr().data
2809     }
2810 }
2811
2812 /// Methods for owned strings
2813 pub trait OwnedStr {
2814     /// Appends a string slice to the back of a string, without overallocating.
2815     fn push_str_no_overallocate(&mut self, rhs: &str);
2816
2817     /// Appends a string slice to the back of a string
2818     fn push_str(&mut self, rhs: &str);
2819
2820     /// Appends a character to the back of a string
2821     fn push_char(&mut self, c: char);
2822
2823     /// Remove the final character from a string and return it. Return None
2824     /// when the string is empty.
2825     fn pop_char(&mut self) -> Option<char>;
2826
2827     /// Remove the first character from a string and return it. Return None
2828     /// when the string is empty.
2829     fn shift_char(&mut self) -> Option<char>;
2830
2831     /// Prepend a char to a string
2832     fn unshift_char(&mut self, ch: char);
2833
2834     /// Insert a new sub-string at the given position in a string, in O(n + m) time
2835     /// (with n and m the lengths of the string and the substring.)
2836     /// This fails if `position` is not at a character boundary.
2837     fn insert(&mut self, position: uint, substring: &str);
2838
2839     /// Insert a char at the given position in a string, in O(n + m) time
2840     /// (with n and m the lengths of the string and the substring.)
2841     /// This fails if `position` is not at a character boundary.
2842     fn insert_char(&mut self, position: uint, ch: char);
2843
2844     /// Concatenate two strings together.
2845     fn append(self, rhs: &str) -> ~str;
2846
2847     /// Reserves capacity for exactly `n` bytes in the given string.
2848     ///
2849     /// Assuming single-byte characters, the resulting string will be large
2850     /// enough to hold a string of length `n`.
2851     ///
2852     /// If the capacity for `s` is already equal to or greater than the requested
2853     /// capacity, then no action is taken.
2854     ///
2855     /// # Arguments
2856     ///
2857     /// * s - A string
2858     /// * n - The number of bytes to reserve space for
2859     fn reserve_exact(&mut self, n: uint);
2860
2861     /// Reserves capacity for at least `n` bytes in the given string.
2862     ///
2863     /// Assuming single-byte characters, the resulting string will be large
2864     /// enough to hold a string of length `n`.
2865     ///
2866     /// This function will over-allocate in order to amortize the allocation costs
2867     /// in scenarios where the caller may need to repeatedly reserve additional
2868     /// space.
2869     ///
2870     /// If the capacity for `s` is already equal to or greater than the requested
2871     /// capacity, then no action is taken.
2872     ///
2873     /// # Arguments
2874     ///
2875     /// * s - A string
2876     /// * n - The number of bytes to reserve space for
2877     fn reserve(&mut self, n: uint);
2878
2879     /// Returns the number of single-byte characters the string can hold without
2880     /// reallocating
2881     fn capacity(&self) -> uint;
2882
2883     /// Shorten a string to the specified length (which must be <= the current length)
2884     fn truncate(&mut self, len: uint);
2885
2886     /// Consumes the string, returning the underlying byte buffer.
2887     ///
2888     /// The buffer does not have a null terminator.
2889     fn into_bytes(self) -> ~[u8];
2890
2891     /// Sets the length of a string
2892     ///
2893     /// This will explicitly set the size of the string, without actually
2894     /// modifying its buffers, so it is up to the caller to ensure that
2895     /// the string is actually the specified size.
2896     unsafe fn set_len(&mut self, new_len: uint);
2897 }
2898
2899 impl OwnedStr for ~str {
2900     #[inline]
2901     fn push_str_no_overallocate(&mut self, rhs: &str) {
2902         let new_cap = self.len() + rhs.len();
2903         self.reserve_exact(new_cap);
2904         self.push_str(rhs);
2905     }
2906
2907     #[inline]
2908     fn push_str(&mut self, rhs: &str) {
2909         unsafe {
2910             raw::push_bytes(self, rhs.as_bytes());
2911         }
2912     }
2913
2914     #[inline]
2915     fn push_char(&mut self, c: char) {
2916         let cur_len = self.len();
2917         // may use up to 4 bytes.
2918         unsafe {
2919             let v = raw::as_owned_vec(self);
2920             v.reserve_additional(4);
2921
2922             // Attempt to not use an intermediate buffer by just pushing bytes
2923             // directly onto this string.
2924             let write_ptr = v.as_mut_ptr().offset(cur_len as int);
2925             let used = slice::raw::mut_buf_as_slice(write_ptr, 4, |slc| c.encode_utf8(slc));
2926
2927             v.set_len(cur_len + used);
2928         }
2929     }
2930
2931     #[inline]
2932     fn pop_char(&mut self) -> Option<char> {
2933         let end = self.len();
2934         if end == 0u {
2935             return None;
2936         } else {
2937             let CharRange {ch, next} = self.char_range_at_reverse(end);
2938             unsafe { self.set_len(next); }
2939             return Some(ch);
2940         }
2941     }
2942
2943     #[inline]
2944     fn shift_char(&mut self) -> Option<char> {
2945         if self.is_empty() {
2946             return None;
2947         } else {
2948             let CharRange {ch, next} = self.char_range_at(0u);
2949             *self = self.slice(next, self.len()).to_owned();
2950             return Some(ch);
2951         }
2952     }
2953
2954     #[inline]
2955     fn unshift_char(&mut self, ch: char) {
2956         // This could be more efficient.
2957         let mut new_str = ~"";
2958         new_str.push_char(ch);
2959         new_str.push_str(*self);
2960         *self = new_str;
2961     }
2962
2963     #[inline]
2964     fn insert(&mut self, position: uint, substring: &str) {
2965         // This could be more efficient.
2966         let mut new_str = self.slice_to(position).to_owned();
2967         new_str.push_str(substring);
2968         new_str.push_str(self.slice_from(position));
2969         *self = new_str;
2970     }
2971
2972     #[inline]
2973     fn insert_char(&mut self, position: uint, ch: char) {
2974         // This could be more efficient.
2975         let mut new_str = self.slice_to(position).to_owned();
2976         new_str.push_char(ch);
2977         new_str.push_str(self.slice_from(position));
2978         *self = new_str;
2979     }
2980
2981     #[inline]
2982     fn append(self, rhs: &str) -> ~str {
2983         let mut new_str = self;
2984         new_str.push_str_no_overallocate(rhs);
2985         new_str
2986     }
2987
2988     #[inline]
2989     fn reserve_exact(&mut self, n: uint) {
2990         unsafe {
2991             raw::as_owned_vec(self).reserve_exact(n)
2992         }
2993     }
2994
2995     #[inline]
2996     fn reserve(&mut self, n: uint) {
2997         unsafe {
2998             raw::as_owned_vec(self).reserve(n)
2999         }
3000     }
3001
3002     #[inline]
3003     fn capacity(&self) -> uint {
3004         unsafe {
3005             let buf: &~[u8] = cast::transmute(self);
3006             buf.capacity()
3007         }
3008     }
3009
3010     #[inline]
3011     fn truncate(&mut self, len: uint) {
3012         assert!(len <= self.len());
3013         assert!(self.is_char_boundary(len));
3014         unsafe { self.set_len(len); }
3015     }
3016
3017     #[inline]
3018     fn into_bytes(self) -> ~[u8] {
3019         unsafe { cast::transmute(self) }
3020     }
3021
3022     #[inline]
3023     unsafe fn set_len(&mut self, new_len: uint) {
3024         raw::as_owned_vec(self).set_len(new_len)
3025     }
3026 }
3027
3028 impl Clone for ~str {
3029     #[inline]
3030     fn clone(&self) -> ~str {
3031         self.to_owned()
3032     }
3033 }
3034
3035 impl FromIterator<char> for ~str {
3036     #[inline]
3037     fn from_iterator<T: Iterator<char>>(iterator: &mut T) -> ~str {
3038         let (lower, _) = iterator.size_hint();
3039         let mut buf = with_capacity(lower);
3040         buf.extend(iterator);
3041         buf
3042     }
3043 }
3044
3045 impl Extendable<char> for ~str {
3046     #[inline]
3047     fn extend<T: Iterator<char>>(&mut self, iterator: &mut T) {
3048         let (lower, _) = iterator.size_hint();
3049         let reserve = lower + self.len();
3050         self.reserve(reserve);
3051         for ch in *iterator {
3052             self.push_char(ch)
3053         }
3054     }
3055 }
3056
3057 // This works because every lifetime is a sub-lifetime of 'static
3058 impl<'a> Default for &'a str {
3059     fn default() -> &'a str { "" }
3060 }
3061
3062 impl Default for ~str {
3063     fn default() -> ~str { ~"" }
3064 }
3065
3066 #[cfg(test)]
3067 mod tests {
3068     use iter::AdditiveIterator;
3069     use default::Default;
3070     use prelude::*;
3071     use str::*;
3072
3073     #[test]
3074     fn test_eq() {
3075         assert!((eq(&~"", &~"")));
3076         assert!((eq(&~"foo", &~"foo")));
3077         assert!((!eq(&~"foo", &~"bar")));
3078     }
3079
3080     #[test]
3081     fn test_eq_slice() {
3082         assert!((eq_slice("foobar".slice(0, 3), "foo")));
3083         assert!((eq_slice("barfoo".slice(3, 6), "foo")));
3084         assert!((!eq_slice("foo1", "foo2")));
3085     }
3086
3087     #[test]
3088     fn test_le() {
3089         assert!("" <= "");
3090         assert!("" <= "foo");
3091         assert!("foo" <= "foo");
3092         assert!("foo" != "bar");
3093     }
3094
3095     #[test]
3096     fn test_len() {
3097         assert_eq!("".len(), 0u);
3098         assert_eq!("hello world".len(), 11u);
3099         assert_eq!("\x63".len(), 1u);
3100         assert_eq!("\xa2".len(), 2u);
3101         assert_eq!("\u03c0".len(), 2u);
3102         assert_eq!("\u2620".len(), 3u);
3103         assert_eq!("\U0001d11e".len(), 4u);
3104
3105         assert_eq!("".char_len(), 0u);
3106         assert_eq!("hello world".char_len(), 11u);
3107         assert_eq!("\x63".char_len(), 1u);
3108         assert_eq!("\xa2".char_len(), 1u);
3109         assert_eq!("\u03c0".char_len(), 1u);
3110         assert_eq!("\u2620".char_len(), 1u);
3111         assert_eq!("\U0001d11e".char_len(), 1u);
3112         assert_eq!("ประเทศไทย中华Việt Nam".char_len(), 19u);
3113     }
3114
3115     #[test]
3116     fn test_find() {
3117         assert_eq!("hello".find('l'), Some(2u));
3118         assert_eq!("hello".find(|c:char| c == 'o'), Some(4u));
3119         assert!("hello".find('x').is_none());
3120         assert!("hello".find(|c:char| c == 'x').is_none());
3121         assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30u));
3122         assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30u));
3123     }
3124
3125     #[test]
3126     fn test_rfind() {
3127         assert_eq!("hello".rfind('l'), Some(3u));
3128         assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4u));
3129         assert!("hello".rfind('x').is_none());
3130         assert!("hello".rfind(|c:char| c == 'x').is_none());
3131         assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30u));
3132         assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30u));
3133     }
3134
3135     #[test]
3136     fn test_push_str() {
3137         let mut s = ~"";
3138         s.push_str("");
3139         assert_eq!(s.slice_from(0), "");
3140         s.push_str("abc");
3141         assert_eq!(s.slice_from(0), "abc");
3142         s.push_str("ประเทศไทย中华Việt Nam");
3143         assert_eq!(s.slice_from(0), "abcประเทศไทย中华Việt Nam");
3144     }
3145
3146     #[test]
3147     fn test_append() {
3148         let mut s = ~"";
3149         s = s.append("");
3150         assert_eq!(s.slice_from(0), "");
3151         s = s.append("abc");
3152         assert_eq!(s.slice_from(0), "abc");
3153         s = s.append("ประเทศไทย中华Việt Nam");
3154         assert_eq!(s.slice_from(0), "abcประเทศไทย中华Việt Nam");
3155     }
3156
3157     #[test]
3158     fn test_pop_char() {
3159         let mut data = ~"ประเทศไทย中华";
3160         let cc = data.pop_char();
3161         assert_eq!(~"ประเทศไทย中", data);
3162         assert_eq!(Some('华'), cc);
3163     }
3164
3165     #[test]
3166     fn test_pop_char_2() {
3167         let mut data2 = ~"华";
3168         let cc2 = data2.pop_char();
3169         assert_eq!(~"", data2);
3170         assert_eq!(Some('华'), cc2);
3171     }
3172
3173     #[test]
3174     fn test_pop_char_empty() {
3175         let mut data = ~"";
3176         let cc3 = data.pop_char();
3177         assert_eq!(~"", data);
3178         assert_eq!(None, cc3);
3179     }
3180
3181     #[test]
3182     fn test_push_char() {
3183         let mut data = ~"ประเทศไทย中";
3184         data.push_char('华');
3185         data.push_char('b'); // 1 byte
3186         data.push_char('¢'); // 2 byte
3187         data.push_char('€'); // 3 byte
3188         data.push_char('𤭢'); // 4 byte
3189         assert_eq!(~"ประเทศไทย中华b¢€𤭢", data);
3190     }
3191
3192     #[test]
3193     fn test_shift_char() {
3194         let mut data = ~"ประเทศไทย中";
3195         let cc = data.shift_char();
3196         assert_eq!(~"ระเทศไทย中", data);
3197         assert_eq!(Some('ป'), cc);
3198     }
3199
3200     #[test]
3201     fn test_unshift_char() {
3202         let mut data = ~"ประเทศไทย中";
3203         data.unshift_char('华');
3204         assert_eq!(~"华ประเทศไทย中", data);
3205     }
3206
3207     #[test]
3208     fn test_insert_char() {
3209         let mut data = ~"ประเทศไทย中";
3210         data.insert_char(15, '华');
3211         assert_eq!(~"ประเท华ศไทย中", data);
3212     }
3213
3214     #[test]
3215     fn test_insert() {
3216         let mut data = ~"ประเทศไทย中";
3217         data.insert(15, "华中");
3218         assert_eq!(~"ประเท华中ศไทย中", data);
3219     }
3220
3221     #[test]
3222     fn test_collect() {
3223         let empty = ~"";
3224         let s: ~str = empty.chars().collect();
3225         assert_eq!(empty, s);
3226         let data = ~"ประเทศไทย中";
3227         let s: ~str = data.chars().collect();
3228         assert_eq!(data, s);
3229     }
3230
3231     #[test]
3232     fn test_extend() {
3233         let data = ~"ประเทศไทย中";
3234         let mut cpy = data.clone();
3235         let other = "abc";
3236         let mut it = other.chars();
3237         cpy.extend(&mut it);
3238         assert_eq!(cpy, data + other);
3239     }
3240
3241     #[test]
3242     fn test_clear() {
3243         let mut empty = ~"";
3244         empty.clear();
3245         assert_eq!("", empty.as_slice());
3246         let mut data = ~"ประเทศไทย中";
3247         data.clear();
3248         assert_eq!("", data.as_slice());
3249         data.push_char('华');
3250         assert_eq!("华", data.as_slice());
3251     }
3252
3253     #[test]
3254     fn test_into_bytes() {
3255         let data = ~"asdf";
3256         let buf = data.into_bytes();
3257         assert_eq!(bytes!("asdf"), buf.as_slice());
3258     }
3259
3260     #[test]
3261     fn test_find_str() {
3262         // byte positions
3263         assert_eq!("".find_str(""), Some(0u));
3264         assert!("banana".find_str("apple pie").is_none());
3265
3266         let data = "abcabc";
3267         assert_eq!(data.slice(0u, 6u).find_str("ab"), Some(0u));
3268         assert_eq!(data.slice(2u, 6u).find_str("ab"), Some(3u - 2u));
3269         assert!(data.slice(2u, 4u).find_str("ab").is_none());
3270
3271         let mut data = ~"ประเทศไทย中华Việt Nam";
3272         data = data + data;
3273         assert!(data.find_str("ไท华").is_none());
3274         assert_eq!(data.slice(0u, 43u).find_str(""), Some(0u));
3275         assert_eq!(data.slice(6u, 43u).find_str(""), Some(6u - 6u));
3276
3277         assert_eq!(data.slice(0u, 43u).find_str("ประ"), Some( 0u));
3278         assert_eq!(data.slice(0u, 43u).find_str("ทศไ"), Some(12u));
3279         assert_eq!(data.slice(0u, 43u).find_str("ย中"), Some(24u));
3280         assert_eq!(data.slice(0u, 43u).find_str("iệt"), Some(34u));
3281         assert_eq!(data.slice(0u, 43u).find_str("Nam"), Some(40u));
3282
3283         assert_eq!(data.slice(43u, 86u).find_str("ประ"), Some(43u - 43u));
3284         assert_eq!(data.slice(43u, 86u).find_str("ทศไ"), Some(55u - 43u));
3285         assert_eq!(data.slice(43u, 86u).find_str("ย中"), Some(67u - 43u));
3286         assert_eq!(data.slice(43u, 86u).find_str("iệt"), Some(77u - 43u));
3287         assert_eq!(data.slice(43u, 86u).find_str("Nam"), Some(83u - 43u));
3288     }
3289
3290     #[test]
3291     fn test_slice_chars() {
3292         fn t(a: &str, b: &str, start: uint) {
3293             assert_eq!(a.slice_chars(start, start + b.char_len()), b);
3294         }
3295         t("", "", 0);
3296         t("hello", "llo", 2);
3297         t("hello", "el", 1);
3298         t("αβλ", "β", 1);
3299         t("αβλ", "", 3);
3300         assert_eq!("ะเทศไท", "ประเทศไทย中华Việt Nam".slice_chars(2, 8));
3301     }
3302
3303     #[test]
3304     fn test_concat() {
3305         fn t(v: &[~str], s: &str) {
3306             assert_eq!(v.concat(), s.to_str());
3307         }
3308         t([~"you", ~"know", ~"I'm", ~"no", ~"good"], "youknowI'mnogood");
3309         let v: &[~str] = [];
3310         t(v, "");
3311         t([~"hi"], "hi");
3312     }
3313
3314     #[test]
3315     fn test_connect() {
3316         fn t(v: &[~str], sep: &str, s: &str) {
3317             assert_eq!(v.connect(sep), s.to_str());
3318         }
3319         t([~"you", ~"know", ~"I'm", ~"no", ~"good"],
3320           " ", "you know I'm no good");
3321         let v: &[~str] = [];
3322         t(v, " ", "");
3323         t([~"hi"], " ", "hi");
3324     }
3325
3326     #[test]
3327     fn test_concat_slices() {
3328         fn t(v: &[&str], s: &str) {
3329             assert_eq!(v.concat(), s.to_str());
3330         }
3331         t(["you", "know", "I'm", "no", "good"], "youknowI'mnogood");
3332         let v: &[&str] = [];
3333         t(v, "");
3334         t(["hi"], "hi");
3335     }
3336
3337     #[test]
3338     fn test_connect_slices() {
3339         fn t(v: &[&str], sep: &str, s: &str) {
3340             assert_eq!(v.connect(sep), s.to_str());
3341         }
3342         t(["you", "know", "I'm", "no", "good"],
3343           " ", "you know I'm no good");
3344         t([], " ", "");
3345         t(["hi"], " ", "hi");
3346     }
3347
3348     #[test]
3349     fn test_repeat() {
3350         assert_eq!("x".repeat(4), ~"xxxx");
3351         assert_eq!("hi".repeat(4), ~"hihihihi");
3352         assert_eq!("ไท华".repeat(3), ~"ไท华ไท华ไท华");
3353         assert_eq!("".repeat(4), ~"");
3354         assert_eq!("hi".repeat(0), ~"");
3355     }
3356
3357     #[test]
3358     fn test_unsafe_slice() {
3359         assert_eq!("ab", unsafe {raw::slice_bytes("abc", 0, 2)});
3360         assert_eq!("bc", unsafe {raw::slice_bytes("abc", 1, 3)});
3361         assert_eq!("", unsafe {raw::slice_bytes("abc", 1, 1)});
3362         fn a_million_letter_a() -> ~str {
3363             let mut i = 0;
3364             let mut rs = ~"";
3365             while i < 100000 { rs.push_str("aaaaaaaaaa"); i += 1; }
3366             rs
3367         }
3368         fn half_a_million_letter_a() -> ~str {
3369             let mut i = 0;
3370             let mut rs = ~"";
3371             while i < 100000 { rs.push_str("aaaaa"); i += 1; }
3372             rs
3373         }
3374         let letters = a_million_letter_a();
3375         assert!(half_a_million_letter_a() ==
3376             unsafe {raw::slice_bytes(letters, 0u, 500000)}.to_owned());
3377     }
3378
3379     #[test]
3380     fn test_starts_with() {
3381         assert!(("".starts_with("")));
3382         assert!(("abc".starts_with("")));
3383         assert!(("abc".starts_with("a")));
3384         assert!((!"a".starts_with("abc")));
3385         assert!((!"".starts_with("abc")));
3386         assert!((!"ödd".starts_with("-")));
3387         assert!(("ödd".starts_with("öd")));
3388     }
3389
3390     #[test]
3391     fn test_ends_with() {
3392         assert!(("".ends_with("")));
3393         assert!(("abc".ends_with("")));
3394         assert!(("abc".ends_with("c")));
3395         assert!((!"a".ends_with("abc")));
3396         assert!((!"".ends_with("abc")));
3397         assert!((!"ddö".ends_with("-")));
3398         assert!(("ddö".ends_with("dö")));
3399     }
3400
3401     #[test]
3402     fn test_is_empty() {
3403         assert!("".is_empty());
3404         assert!(!"a".is_empty());
3405     }
3406
3407     #[test]
3408     fn test_replace() {
3409         let a = "a";
3410         assert_eq!("".replace(a, "b"), ~"");
3411         assert_eq!("a".replace(a, "b"), ~"b");
3412         assert_eq!("ab".replace(a, "b"), ~"bb");
3413         let test = "test";
3414         assert!(" test test ".replace(test, "toast") ==
3415             ~" toast toast ");
3416         assert_eq!(" test test ".replace(test, ""), ~"   ");
3417     }
3418
3419     #[test]
3420     fn test_replace_2a() {
3421         let data = ~"ประเทศไทย中华";
3422         let repl = ~"دولة الكويت";
3423
3424         let a = ~"ประเ";
3425         let a2 = ~"دولة الكويتทศไทย中华";
3426         assert_eq!(data.replace(a, repl), a2);
3427     }
3428
3429     #[test]
3430     fn test_replace_2b() {
3431         let data = ~"ประเทศไทย中华";
3432         let repl = ~"دولة الكويت";
3433
3434         let b = ~"ะเ";
3435         let b2 = ~"ปรدولة الكويتทศไทย中华";
3436         assert_eq!(data.replace(b, repl), b2);
3437     }
3438
3439     #[test]
3440     fn test_replace_2c() {
3441         let data = ~"ประเทศไทย中华";
3442         let repl = ~"دولة الكويت";
3443
3444         let c = ~"中华";
3445         let c2 = ~"ประเทศไทยدولة الكويت";
3446         assert_eq!(data.replace(c, repl), c2);
3447     }
3448
3449     #[test]
3450     fn test_replace_2d() {
3451         let data = ~"ประเทศไทย中华";
3452         let repl = ~"دولة الكويت";
3453
3454         let d = ~"ไท华";
3455         assert_eq!(data.replace(d, repl), data);
3456     }
3457
3458     #[test]
3459     fn test_slice() {
3460         assert_eq!("ab", "abc".slice(0, 2));
3461         assert_eq!("bc", "abc".slice(1, 3));
3462         assert_eq!("", "abc".slice(1, 1));
3463         assert_eq!("\u65e5", "\u65e5\u672c".slice(0, 3));
3464
3465         let data = "ประเทศไทย中华";
3466         assert_eq!("ป", data.slice(0, 3));
3467         assert_eq!("ร", data.slice(3, 6));
3468         assert_eq!("", data.slice(3, 3));
3469         assert_eq!("华", data.slice(30, 33));
3470
3471         fn a_million_letter_X() -> ~str {
3472             let mut i = 0;
3473             let mut rs = ~"";
3474             while i < 100000 {
3475                 push_str(&mut rs, "华华华华华华华华华华");
3476                 i += 1;
3477             }
3478             rs
3479         }
3480         fn half_a_million_letter_X() -> ~str {
3481             let mut i = 0;
3482             let mut rs = ~"";
3483             while i < 100000 { push_str(&mut rs, "华华华华华"); i += 1; }
3484             rs
3485         }
3486         let letters = a_million_letter_X();
3487         assert!(half_a_million_letter_X() ==
3488             letters.slice(0u, 3u * 500000u).to_owned());
3489     }
3490
3491     #[test]
3492     fn test_slice_2() {
3493         let ss = "中华Việt Nam";
3494
3495         assert_eq!("华", ss.slice(3u, 6u));
3496         assert_eq!("Việt Nam", ss.slice(6u, 16u));
3497
3498         assert_eq!("ab", "abc".slice(0u, 2u));
3499         assert_eq!("bc", "abc".slice(1u, 3u));
3500         assert_eq!("", "abc".slice(1u, 1u));
3501
3502         assert_eq!("中", ss.slice(0u, 3u));
3503         assert_eq!("华V", ss.slice(3u, 7u));
3504         assert_eq!("", ss.slice(3u, 3u));
3505         /*0: 中
3506           3: 华
3507           6: V
3508           7: i
3509           8: ệ
3510          11: t
3511          12:
3512          13: N
3513          14: a
3514          15: m */
3515     }
3516
3517     #[test]
3518     #[should_fail]
3519     fn test_slice_fail() {
3520         "中华Việt Nam".slice(0u, 2u);
3521     }
3522
3523     #[test]
3524     fn test_slice_from() {
3525         assert_eq!("abcd".slice_from(0), "abcd");
3526         assert_eq!("abcd".slice_from(2), "cd");
3527         assert_eq!("abcd".slice_from(4), "");
3528     }
3529     #[test]
3530     fn test_slice_to() {
3531         assert_eq!("abcd".slice_to(0), "");
3532         assert_eq!("abcd".slice_to(2), "ab");
3533         assert_eq!("abcd".slice_to(4), "abcd");
3534     }
3535
3536     #[test]
3537     fn test_trim_left_chars() {
3538         let v: &[char] = &[];
3539         assert_eq!(" *** foo *** ".trim_left_chars(&v), " *** foo *** ");
3540         assert_eq!(" *** foo *** ".trim_left_chars(& &['*', ' ']), "foo *** ");
3541         assert_eq!(" ***  *** ".trim_left_chars(& &['*', ' ']), "");
3542         assert_eq!("foo *** ".trim_left_chars(& &['*', ' ']), "foo *** ");
3543
3544         assert_eq!("11foo1bar11".trim_left_chars(&'1'), "foo1bar11");
3545         assert_eq!("12foo1bar12".trim_left_chars(& &['1', '2']), "foo1bar12");
3546         assert_eq!("123foo1bar123".trim_left_chars(&|c: char| c.is_digit()), "foo1bar123");
3547     }
3548
3549     #[test]
3550     fn test_trim_right_chars() {
3551         let v: &[char] = &[];
3552         assert_eq!(" *** foo *** ".trim_right_chars(&v), " *** foo *** ");
3553         assert_eq!(" *** foo *** ".trim_right_chars(& &['*', ' ']), " *** foo");
3554         assert_eq!(" ***  *** ".trim_right_chars(& &['*', ' ']), "");
3555         assert_eq!(" *** foo".trim_right_chars(& &['*', ' ']), " *** foo");
3556
3557         assert_eq!("11foo1bar11".trim_right_chars(&'1'), "11foo1bar");
3558         assert_eq!("12foo1bar12".trim_right_chars(& &['1', '2']), "12foo1bar");
3559         assert_eq!("123foo1bar123".trim_right_chars(&|c: char| c.is_digit()), "123foo1bar");
3560     }
3561
3562     #[test]
3563     fn test_trim_chars() {
3564         let v: &[char] = &[];
3565         assert_eq!(" *** foo *** ".trim_chars(&v), " *** foo *** ");
3566         assert_eq!(" *** foo *** ".trim_chars(& &['*', ' ']), "foo");
3567         assert_eq!(" ***  *** ".trim_chars(& &['*', ' ']), "");
3568         assert_eq!("foo".trim_chars(& &['*', ' ']), "foo");
3569
3570         assert_eq!("11foo1bar11".trim_chars(&'1'), "foo1bar");
3571         assert_eq!("12foo1bar12".trim_chars(& &['1', '2']), "foo1bar");
3572         assert_eq!("123foo1bar123".trim_chars(&|c: char| c.is_digit()), "foo1bar");
3573     }
3574
3575     #[test]
3576     fn test_trim_left() {
3577         assert_eq!("".trim_left(), "");
3578         assert_eq!("a".trim_left(), "a");
3579         assert_eq!("    ".trim_left(), "");
3580         assert_eq!("     blah".trim_left(), "blah");
3581         assert_eq!("   \u3000  wut".trim_left(), "wut");
3582         assert_eq!("hey ".trim_left(), "hey ");
3583     }
3584
3585     #[test]
3586     fn test_trim_right() {
3587         assert_eq!("".trim_right(), "");
3588         assert_eq!("a".trim_right(), "a");
3589         assert_eq!("    ".trim_right(), "");
3590         assert_eq!("blah     ".trim_right(), "blah");
3591         assert_eq!("wut   \u3000  ".trim_right(), "wut");
3592         assert_eq!(" hey".trim_right(), " hey");
3593     }
3594
3595     #[test]
3596     fn test_trim() {
3597         assert_eq!("".trim(), "");
3598         assert_eq!("a".trim(), "a");
3599         assert_eq!("    ".trim(), "");
3600         assert_eq!("    blah     ".trim(), "blah");
3601         assert_eq!("\nwut   \u3000  ".trim(), "wut");
3602         assert_eq!(" hey dude ".trim(), "hey dude");
3603     }
3604
3605     #[test]
3606     fn test_is_whitespace() {
3607         assert!("".is_whitespace());
3608         assert!(" ".is_whitespace());
3609         assert!("\u2009".is_whitespace()); // Thin space
3610         assert!("  \n\t   ".is_whitespace());
3611         assert!(!"   _   ".is_whitespace());
3612     }
3613
3614     #[test]
3615     fn test_slice_shift_char() {
3616         let data = "ประเทศไทย中";
3617         assert_eq!(data.slice_shift_char(), (Some('ป'), "ระเทศไทย中"));
3618     }
3619
3620     #[test]
3621     fn test_slice_shift_char_2() {
3622         let empty = "";
3623         assert_eq!(empty.slice_shift_char(), (None, ""));
3624     }
3625
3626     #[test]
3627     fn test_push_byte() {
3628         let mut s = ~"ABC";
3629         unsafe{raw::push_byte(&mut s, 'D' as u8)};
3630         assert_eq!(s, ~"ABCD");
3631     }
3632
3633     #[test]
3634     fn test_shift_byte() {
3635         let mut s = ~"ABC";
3636         let b = unsafe{raw::shift_byte(&mut s)};
3637         assert_eq!(s, ~"BC");
3638         assert_eq!(b, Some(65u8));
3639     }
3640
3641     #[test]
3642     fn test_pop_byte() {
3643         let mut s = ~"ABC";
3644         let b = unsafe{raw::pop_byte(&mut s)};
3645         assert_eq!(s, ~"AB");
3646         assert_eq!(b, Some(67u8));
3647     }
3648
3649     #[test]
3650     fn test_is_utf8() {
3651         // deny overlong encodings
3652         assert!(!is_utf8([0xc0, 0x80]));
3653         assert!(!is_utf8([0xc0, 0xae]));
3654         assert!(!is_utf8([0xe0, 0x80, 0x80]));
3655         assert!(!is_utf8([0xe0, 0x80, 0xaf]));
3656         assert!(!is_utf8([0xe0, 0x81, 0x81]));
3657         assert!(!is_utf8([0xf0, 0x82, 0x82, 0xac]));
3658         assert!(!is_utf8([0xf4, 0x90, 0x80, 0x80]));
3659
3660         // deny surrogates
3661         assert!(!is_utf8([0xED, 0xA0, 0x80]));
3662         assert!(!is_utf8([0xED, 0xBF, 0xBF]));
3663
3664         assert!(is_utf8([0xC2, 0x80]));
3665         assert!(is_utf8([0xDF, 0xBF]));
3666         assert!(is_utf8([0xE0, 0xA0, 0x80]));
3667         assert!(is_utf8([0xED, 0x9F, 0xBF]));
3668         assert!(is_utf8([0xEE, 0x80, 0x80]));
3669         assert!(is_utf8([0xEF, 0xBF, 0xBF]));
3670         assert!(is_utf8([0xF0, 0x90, 0x80, 0x80]));
3671         assert!(is_utf8([0xF4, 0x8F, 0xBF, 0xBF]));
3672     }
3673
3674     #[test]
3675     fn test_is_utf16() {
3676         macro_rules! pos ( ($($e:expr),*) => { { $(assert!(is_utf16($e));)* } });
3677
3678         // non-surrogates
3679         pos!([0x0000],
3680              [0x0001, 0x0002],
3681              [0xD7FF],
3682              [0xE000]);
3683
3684         // surrogate pairs (randomly generated with Python 3's
3685         // .encode('utf-16be'))
3686         pos!([0xdb54, 0xdf16, 0xd880, 0xdee0, 0xdb6a, 0xdd45],
3687              [0xd91f, 0xdeb1, 0xdb31, 0xdd84, 0xd8e2, 0xde14],
3688              [0xdb9f, 0xdc26, 0xdb6f, 0xde58, 0xd850, 0xdfae]);
3689
3690         // mixtures (also random)
3691         pos!([0xd921, 0xdcc2, 0x002d, 0x004d, 0xdb32, 0xdf65],
3692              [0xdb45, 0xdd2d, 0x006a, 0xdacd, 0xddfe, 0x0006],
3693              [0x0067, 0xd8ff, 0xddb7, 0x000f, 0xd900, 0xdc80]);
3694
3695         // negative tests
3696         macro_rules! neg ( ($($e:expr),*) => { { $(assert!(!is_utf16($e));)* } });
3697
3698         neg!(
3699             // surrogate + regular unit
3700             [0xdb45, 0x0000],
3701             // surrogate + lead surrogate
3702             [0xd900, 0xd900],
3703             // unterminated surrogate
3704             [0xd8ff],
3705             // trail surrogate without a lead
3706             [0xddb7]);
3707
3708         // random byte sequences that Python 3's .decode('utf-16be')
3709         // failed on
3710         neg!([0x5b3d, 0x0141, 0xde9e, 0x8fdc, 0xc6e7],
3711              [0xdf5a, 0x82a5, 0x62b9, 0xb447, 0x92f3],
3712              [0xda4e, 0x42bc, 0x4462, 0xee98, 0xc2ca],
3713              [0xbe00, 0xb04a, 0x6ecb, 0xdd89, 0xe278],
3714              [0x0465, 0xab56, 0xdbb6, 0xa893, 0x665e],
3715              [0x6b7f, 0x0a19, 0x40f4, 0xa657, 0xdcc5],
3716              [0x9b50, 0xda5e, 0x24ec, 0x03ad, 0x6dee],
3717              [0x8d17, 0xcaa7, 0xf4ae, 0xdf6e, 0xbed7],
3718              [0xdaee, 0x2584, 0x7d30, 0xa626, 0x121a],
3719              [0xd956, 0x4b43, 0x7570, 0xccd6, 0x4f4a],
3720              [0x9dcf, 0x1b49, 0x4ba5, 0xfce9, 0xdffe],
3721              [0x6572, 0xce53, 0xb05a, 0xf6af, 0xdacf],
3722              [0x1b90, 0x728c, 0x9906, 0xdb68, 0xf46e],
3723              [0x1606, 0xbeca, 0xbe76, 0x860f, 0xdfa5],
3724              [0x8b4f, 0xde7a, 0xd220, 0x9fac, 0x2b6f],
3725              [0xb8fe, 0xebbe, 0xda32, 0x1a5f, 0x8b8b],
3726              [0x934b, 0x8956, 0xc434, 0x1881, 0xddf7],
3727              [0x5a95, 0x13fc, 0xf116, 0xd89b, 0x93f9],
3728              [0xd640, 0x71f1, 0xdd7d, 0x77eb, 0x1cd8],
3729              [0x348b, 0xaef0, 0xdb2c, 0xebf1, 0x1282],
3730              [0x50d7, 0xd824, 0x5010, 0xb369, 0x22ea]);
3731     }
3732
3733     #[test]
3734     fn test_raw_from_c_str() {
3735         unsafe {
3736             let a = ~[65, 65, 65, 65, 65, 65, 65, 0];
3737             let b = a.as_ptr();
3738             let c = raw::from_c_str(b);
3739             assert_eq!(c, ~"AAAAAAA");
3740         }
3741     }
3742
3743     #[test]
3744     fn test_as_bytes() {
3745         // no null
3746         let v = [
3747             224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
3748             184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
3749             109
3750         ];
3751         assert_eq!("".as_bytes(), &[]);
3752         assert_eq!("abc".as_bytes(), &['a' as u8, 'b' as u8, 'c' as u8]);
3753         assert_eq!("ศไทย中华Việt Nam".as_bytes(), v.as_slice());
3754     }
3755
3756     #[test]
3757     #[should_fail]
3758     fn test_as_bytes_fail() {
3759         // Don't double free. (I'm not sure if this exercises the
3760         // original problem code path anymore.)
3761         let s = ~"";
3762         let _bytes = s.as_bytes();
3763         fail!();
3764     }
3765
3766     #[test]
3767     fn test_as_ptr() {
3768         let buf = "hello".as_ptr();
3769         unsafe {
3770             assert_eq!(*buf.offset(0), 'h' as u8);
3771             assert_eq!(*buf.offset(1), 'e' as u8);
3772             assert_eq!(*buf.offset(2), 'l' as u8);
3773             assert_eq!(*buf.offset(3), 'l' as u8);
3774             assert_eq!(*buf.offset(4), 'o' as u8);
3775         }
3776     }
3777
3778     #[test]
3779     fn test_subslice_offset() {
3780         let a = "kernelsprite";
3781         let b = a.slice(7, a.len());
3782         let c = a.slice(0, a.len() - 6);
3783         assert_eq!(a.subslice_offset(b), 7);
3784         assert_eq!(a.subslice_offset(c), 0);
3785
3786         let string = "a\nb\nc";
3787         let mut lines = ~[];
3788         for line in string.lines() { lines.push(line) }
3789         assert_eq!(string.subslice_offset(lines[0]), 0);
3790         assert_eq!(string.subslice_offset(lines[1]), 2);
3791         assert_eq!(string.subslice_offset(lines[2]), 4);
3792     }
3793
3794     #[test]
3795     #[should_fail]
3796     fn test_subslice_offset_2() {
3797         let a = "alchemiter";
3798         let b = "cruxtruder";
3799         a.subslice_offset(b);
3800     }
3801
3802     #[test]
3803     fn vec_str_conversions() {
3804         let s1: ~str = ~"All mimsy were the borogoves";
3805
3806         let v: ~[u8] = s1.as_bytes().to_owned();
3807         let s2: ~str = from_utf8(v).unwrap().to_owned();
3808         let mut i: uint = 0u;
3809         let n1: uint = s1.len();
3810         let n2: uint = v.len();
3811         assert_eq!(n1, n2);
3812         while i < n1 {
3813             let a: u8 = s1[i];
3814             let b: u8 = s2[i];
3815             debug!("{}", a);
3816             debug!("{}", b);
3817             assert_eq!(a, b);
3818             i += 1u;
3819         }
3820     }
3821
3822     #[test]
3823     fn test_contains() {
3824         assert!("abcde".contains("bcd"));
3825         assert!("abcde".contains("abcd"));
3826         assert!("abcde".contains("bcde"));
3827         assert!("abcde".contains(""));
3828         assert!("".contains(""));
3829         assert!(!"abcde".contains("def"));
3830         assert!(!"".contains("a"));
3831
3832         let data = ~"ประเทศไทย中华Việt Nam";
3833         assert!(data.contains("ประเ"));
3834         assert!(data.contains("ะเ"));
3835         assert!(data.contains("中华"));
3836         assert!(!data.contains("ไท华"));
3837     }
3838
3839     #[test]
3840     fn test_contains_char() {
3841         assert!("abc".contains_char('b'));
3842         assert!("a".contains_char('a'));
3843         assert!(!"abc".contains_char('d'));
3844         assert!(!"".contains_char('a'));
3845     }
3846
3847     #[test]
3848     fn test_utf16() {
3849         let pairs =
3850             [(~"𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n",
3851               ~[0xd800_u16, 0xdf45_u16, 0xd800_u16, 0xdf3f_u16,
3852                 0xd800_u16, 0xdf3b_u16, 0xd800_u16, 0xdf46_u16,
3853                 0xd800_u16, 0xdf39_u16, 0xd800_u16, 0xdf3b_u16,
3854                 0xd800_u16, 0xdf30_u16, 0x000a_u16]),
3855
3856              (~"𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n",
3857               ~[0xd801_u16, 0xdc12_u16, 0xd801_u16,
3858                 0xdc49_u16, 0xd801_u16, 0xdc2e_u16, 0xd801_u16,
3859                 0xdc40_u16, 0xd801_u16, 0xdc32_u16, 0xd801_u16,
3860                 0xdc4b_u16, 0x0020_u16, 0xd801_u16, 0xdc0f_u16,
3861                 0xd801_u16, 0xdc32_u16, 0xd801_u16, 0xdc4d_u16,
3862                 0x000a_u16]),
3863
3864              (~"𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n",
3865               ~[0xd800_u16, 0xdf00_u16, 0xd800_u16, 0xdf16_u16,
3866                 0xd800_u16, 0xdf0b_u16, 0xd800_u16, 0xdf04_u16,
3867                 0xd800_u16, 0xdf11_u16, 0xd800_u16, 0xdf09_u16,
3868                 0x00b7_u16, 0xd800_u16, 0xdf0c_u16, 0xd800_u16,
3869                 0xdf04_u16, 0xd800_u16, 0xdf15_u16, 0xd800_u16,
3870                 0xdf04_u16, 0xd800_u16, 0xdf0b_u16, 0xd800_u16,
3871                 0xdf09_u16, 0xd800_u16, 0xdf11_u16, 0x000a_u16 ]),
3872
3873              (~"𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n",
3874               ~[0xd801_u16, 0xdc8b_u16, 0xd801_u16, 0xdc98_u16,
3875                 0xd801_u16, 0xdc88_u16, 0xd801_u16, 0xdc91_u16,
3876                 0xd801_u16, 0xdc9b_u16, 0xd801_u16, 0xdc92_u16,
3877                 0x0020_u16, 0xd801_u16, 0xdc95_u16, 0xd801_u16,
3878                 0xdc93_u16, 0x0020_u16, 0xd801_u16, 0xdc88_u16,
3879                 0xd801_u16, 0xdc9a_u16, 0xd801_u16, 0xdc8d_u16,
3880                 0x0020_u16, 0xd801_u16, 0xdc8f_u16, 0xd801_u16,
3881                 0xdc9c_u16, 0xd801_u16, 0xdc92_u16, 0xd801_u16,
3882                 0xdc96_u16, 0xd801_u16, 0xdc86_u16, 0x0020_u16,
3883                 0xd801_u16, 0xdc95_u16, 0xd801_u16, 0xdc86_u16,
3884                 0x000a_u16 ]),
3885              // Issue #12318, even-numbered non-BMP planes
3886              (~"\U00020000",
3887               ~[0xD840, 0xDC00])];
3888
3889         for p in pairs.iter() {
3890             let (s, u) = (*p).clone();
3891             assert!(is_utf16(u));
3892             assert_eq!(s.to_utf16(), u);
3893
3894             assert_eq!(from_utf16(u).unwrap(), s);
3895             assert_eq!(from_utf16_lossy(u), s);
3896
3897             assert_eq!(from_utf16(s.to_utf16()).unwrap(), s);
3898             assert_eq!(from_utf16(u).unwrap().to_utf16(), u);
3899         }
3900     }
3901
3902     #[test]
3903     fn test_utf16_invalid() {
3904         // completely positive cases tested above.
3905         // lead + eof
3906         assert_eq!(from_utf16([0xD800]), None);
3907         // lead + lead
3908         assert_eq!(from_utf16([0xD800, 0xD800]), None);
3909
3910         // isolated trail
3911         assert_eq!(from_utf16([0x0061, 0xDC00]), None);
3912
3913         // general
3914         assert_eq!(from_utf16([0xD800, 0xd801, 0xdc8b, 0xD800]), None);
3915     }
3916
3917     #[test]
3918     fn test_utf16_lossy() {
3919         // completely positive cases tested above.
3920         // lead + eof
3921         assert_eq!(from_utf16_lossy([0xD800]), ~"\uFFFD");
3922         // lead + lead
3923         assert_eq!(from_utf16_lossy([0xD800, 0xD800]), ~"\uFFFD\uFFFD");
3924
3925         // isolated trail
3926         assert_eq!(from_utf16_lossy([0x0061, 0xDC00]), ~"a\uFFFD");
3927
3928         // general
3929         assert_eq!(from_utf16_lossy([0xD800, 0xd801, 0xdc8b, 0xD800]), ~"\uFFFD𐒋\uFFFD");
3930     }
3931
3932     #[test]
3933     fn test_truncate_utf16_at_nul() {
3934         let v = [];
3935         assert_eq!(truncate_utf16_at_nul(v), &[]);
3936
3937         let v = [0, 2, 3];
3938         assert_eq!(truncate_utf16_at_nul(v), &[]);
3939
3940         let v = [1, 0, 3];
3941         assert_eq!(truncate_utf16_at_nul(v), &[1]);
3942
3943         let v = [1, 2, 0];
3944         assert_eq!(truncate_utf16_at_nul(v), &[1, 2]);
3945
3946         let v = [1, 2, 3];
3947         assert_eq!(truncate_utf16_at_nul(v), &[1, 2, 3]);
3948     }
3949
3950     #[test]
3951     fn test_char_at() {
3952         let s = ~"ศไทย中华Việt Nam";
3953         let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
3954         let mut pos = 0;
3955         for ch in v.iter() {
3956             assert!(s.char_at(pos) == *ch);
3957             pos += from_char(*ch).len();
3958         }
3959     }
3960
3961     #[test]
3962     fn test_char_at_reverse() {
3963         let s = ~"ศไทย中华Việt Nam";
3964         let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
3965         let mut pos = s.len();
3966         for ch in v.rev_iter() {
3967             assert!(s.char_at_reverse(pos) == *ch);
3968             pos -= from_char(*ch).len();
3969         }
3970     }
3971
3972     #[test]
3973     fn test_escape_unicode() {
3974         assert_eq!("abc".escape_unicode(), ~"\\x61\\x62\\x63");
3975         assert_eq!("a c".escape_unicode(), ~"\\x61\\x20\\x63");
3976         assert_eq!("\r\n\t".escape_unicode(), ~"\\x0d\\x0a\\x09");
3977         assert_eq!("'\"\\".escape_unicode(), ~"\\x27\\x22\\x5c");
3978         assert_eq!("\x00\x01\xfe\xff".escape_unicode(), ~"\\x00\\x01\\xfe\\xff");
3979         assert_eq!("\u0100\uffff".escape_unicode(), ~"\\u0100\\uffff");
3980         assert_eq!("\U00010000\U0010ffff".escape_unicode(), ~"\\U00010000\\U0010ffff");
3981         assert_eq!("ab\ufb00".escape_unicode(), ~"\\x61\\x62\\ufb00");
3982         assert_eq!("\U0001d4ea\r".escape_unicode(), ~"\\U0001d4ea\\x0d");
3983     }
3984
3985     #[test]
3986     fn test_escape_default() {
3987         assert_eq!("abc".escape_default(), ~"abc");
3988         assert_eq!("a c".escape_default(), ~"a c");
3989         assert_eq!("\r\n\t".escape_default(), ~"\\r\\n\\t");
3990         assert_eq!("'\"\\".escape_default(), ~"\\'\\\"\\\\");
3991         assert_eq!("\u0100\uffff".escape_default(), ~"\\u0100\\uffff");
3992         assert_eq!("\U00010000\U0010ffff".escape_default(), ~"\\U00010000\\U0010ffff");
3993         assert_eq!("ab\ufb00".escape_default(), ~"ab\\ufb00");
3994         assert_eq!("\U0001d4ea\r".escape_default(), ~"\\U0001d4ea\\r");
3995     }
3996
3997     #[test]
3998     fn test_total_ord() {
3999         "1234".cmp(& &"123") == Greater;
4000         "123".cmp(& &"1234") == Less;
4001         "1234".cmp(& &"1234") == Equal;
4002         "12345555".cmp(& &"123456") == Less;
4003         "22".cmp(& &"1234") == Greater;
4004     }
4005
4006     #[test]
4007     fn test_char_range_at() {
4008         let data = ~"b¢€𤭢𤭢€¢b";
4009         assert_eq!('b', data.char_range_at(0).ch);
4010         assert_eq!('¢', data.char_range_at(1).ch);
4011         assert_eq!('€', data.char_range_at(3).ch);
4012         assert_eq!('𤭢', data.char_range_at(6).ch);
4013         assert_eq!('𤭢', data.char_range_at(10).ch);
4014         assert_eq!('€', data.char_range_at(14).ch);
4015         assert_eq!('¢', data.char_range_at(17).ch);
4016         assert_eq!('b', data.char_range_at(19).ch);
4017     }
4018
4019     #[test]
4020     fn test_char_range_at_reverse_underflow() {
4021         assert_eq!("abc".char_range_at_reverse(0).next, 0);
4022     }
4023
4024     #[test]
4025     fn test_add() {
4026         #[allow(unnecessary_allocation)];
4027         macro_rules! t (
4028             ($s1:expr, $s2:expr, $e:expr) => { {
4029                 let s1 = $s1;
4030                 let s2 = $s2;
4031                 let e = $e;
4032                 assert_eq!(s1 + s2, e.to_owned());
4033                 assert_eq!(s1.to_owned() + s2, e.to_owned());
4034             } }
4035         );
4036
4037         t!("foo",  "bar", "foobar");
4038         t!("foo", ~"bar", "foobar");
4039         t!("ศไทย中",  "华Việt Nam", "ศไทย中华Việt Nam");
4040         t!("ศไทย中", ~"华Việt Nam", "ศไทย中华Việt Nam");
4041     }
4042
4043     #[test]
4044     fn test_iterator() {
4045         use iter::*;
4046         let s = ~"ศไทย中华Việt Nam";
4047         let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
4048
4049         let mut pos = 0;
4050         let mut it = s.chars();
4051
4052         for c in it {
4053             assert_eq!(c, v[pos]);
4054             pos += 1;
4055         }
4056         assert_eq!(pos, v.len());
4057     }
4058
4059     #[test]
4060     fn test_rev_iterator() {
4061         use iter::*;
4062         let s = ~"ศไทย中华Việt Nam";
4063         let v = ~['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
4064
4065         let mut pos = 0;
4066         let mut it = s.chars_rev();
4067
4068         for c in it {
4069             assert_eq!(c, v[pos]);
4070             pos += 1;
4071         }
4072         assert_eq!(pos, v.len());
4073     }
4074
4075     #[test]
4076     fn test_iterator_clone() {
4077         let s = "ศไทย中华Việt Nam";
4078         let mut it = s.chars();
4079         it.next();
4080         assert!(it.zip(it.clone()).all(|(x,y)| x == y));
4081     }
4082
4083     #[test]
4084     fn test_bytesator() {
4085         let s = ~"ศไทย中华Việt Nam";
4086         let v = [
4087             224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
4088             184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
4089             109
4090         ];
4091         let mut pos = 0;
4092
4093         for b in s.bytes() {
4094             assert_eq!(b, v[pos]);
4095             pos += 1;
4096         }
4097     }
4098
4099     #[test]
4100     fn test_bytes_revator() {
4101         let s = ~"ศไทย中华Việt Nam";
4102         let v = [
4103             224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
4104             184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
4105             109
4106         ];
4107         let mut pos = v.len();
4108
4109         for b in s.bytes_rev() {
4110             pos -= 1;
4111             assert_eq!(b, v[pos]);
4112         }
4113     }
4114
4115     #[test]
4116     fn test_char_indicesator() {
4117         use iter::*;
4118         let s = "ศไทย中华Việt Nam";
4119         let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
4120         let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
4121
4122         let mut pos = 0;
4123         let mut it = s.char_indices();
4124
4125         for c in it {
4126             assert_eq!(c, (p[pos], v[pos]));
4127             pos += 1;
4128         }
4129         assert_eq!(pos, v.len());
4130         assert_eq!(pos, p.len());
4131     }
4132
4133     #[test]
4134     fn test_char_indices_revator() {
4135         use iter::*;
4136         let s = "ศไทย中华Việt Nam";
4137         let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
4138         let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
4139
4140         let mut pos = 0;
4141         let mut it = s.char_indices_rev();
4142
4143         for c in it {
4144             assert_eq!(c, (p[pos], v[pos]));
4145             pos += 1;
4146         }
4147         assert_eq!(pos, v.len());
4148         assert_eq!(pos, p.len());
4149     }
4150
4151     #[test]
4152     fn test_split_char_iterator() {
4153         let data = "\nMäry häd ä little lämb\nLittle lämb\n";
4154
4155         let split: ~[&str] = data.split(' ').collect();
4156         assert_eq!( split, ~["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
4157
4158         let mut rsplit: ~[&str] = data.rsplit(' ').collect();
4159         rsplit.reverse();
4160         assert_eq!(rsplit, ~["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
4161
4162         let split: ~[&str] = data.split(|c: char| c == ' ').collect();
4163         assert_eq!( split, ~["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
4164
4165         let mut rsplit: ~[&str] = data.rsplit(|c: char| c == ' ').collect();
4166         rsplit.reverse();
4167         assert_eq!(rsplit, ~["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
4168
4169         // Unicode
4170         let split: ~[&str] = data.split('ä').collect();
4171         assert_eq!( split, ~["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
4172
4173         let mut rsplit: ~[&str] = data.rsplit('ä').collect();
4174         rsplit.reverse();
4175         assert_eq!(rsplit, ~["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
4176
4177         let split: ~[&str] = data.split(|c: char| c == 'ä').collect();
4178         assert_eq!( split, ~["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
4179
4180         let mut rsplit: ~[&str] = data.rsplit(|c: char| c == 'ä').collect();
4181         rsplit.reverse();
4182         assert_eq!(rsplit, ~["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
4183     }
4184
4185     #[test]
4186     fn test_splitn_char_iterator() {
4187         let data = "\nMäry häd ä little lämb\nLittle lämb\n";
4188
4189         let split: ~[&str] = data.splitn(' ', 3).collect();
4190         assert_eq!(split, ~["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
4191
4192         let split: ~[&str] = data.splitn(|c: char| c == ' ', 3).collect();
4193         assert_eq!(split, ~["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
4194
4195         // Unicode
4196         let split: ~[&str] = data.splitn('ä', 3).collect();
4197         assert_eq!(split, ~["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
4198
4199         let split: ~[&str] = data.splitn(|c: char| c == 'ä', 3).collect();
4200         assert_eq!(split, ~["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
4201     }
4202
4203     #[test]
4204     fn test_rsplitn_char_iterator() {
4205         let data = "\nMäry häd ä little lämb\nLittle lämb\n";
4206
4207         let mut split: ~[&str] = data.rsplitn(' ', 3).collect();
4208         split.reverse();
4209         assert_eq!(split, ~["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
4210
4211         let mut split: ~[&str] = data.rsplitn(|c: char| c == ' ', 3).collect();
4212         split.reverse();
4213         assert_eq!(split, ~["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
4214
4215         // Unicode
4216         let mut split: ~[&str] = data.rsplitn('ä', 3).collect();
4217         split.reverse();
4218         assert_eq!(split, ~["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
4219
4220         let mut split: ~[&str] = data.rsplitn(|c: char| c == 'ä', 3).collect();
4221         split.reverse();
4222         assert_eq!(split, ~["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
4223     }
4224
4225     #[test]
4226     fn test_split_char_iterator_no_trailing() {
4227         let data = "\nMäry häd ä little lämb\nLittle lämb\n";
4228
4229         let split: ~[&str] = data.split('\n').collect();
4230         assert_eq!(split, ~["", "Märy häd ä little lämb", "Little lämb", ""]);
4231
4232         let split: ~[&str] = data.split_terminator('\n').collect();
4233         assert_eq!(split, ~["", "Märy häd ä little lämb", "Little lämb"]);
4234     }
4235
4236     #[test]
4237     fn test_rev_split_char_iterator_no_trailing() {
4238         let data = "\nMäry häd ä little lämb\nLittle lämb\n";
4239
4240         let mut split: ~[&str] = data.split('\n').rev().collect();
4241         split.reverse();
4242         assert_eq!(split, ~["", "Märy häd ä little lämb", "Little lämb", ""]);
4243
4244         let mut split: ~[&str] = data.split_terminator('\n').rev().collect();
4245         split.reverse();
4246         assert_eq!(split, ~["", "Märy häd ä little lämb", "Little lämb"]);
4247     }
4248
4249     #[test]
4250     fn test_words() {
4251         let data = "\n \tMäry   häd\tä  little lämb\nLittle lämb\n";
4252         let words: ~[&str] = data.words().collect();
4253         assert_eq!(words, ~["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
4254     }
4255
4256     #[test]
4257     fn test_nfd_chars() {
4258         assert_eq!("abc".nfd_chars().collect::<~str>(), ~"abc");
4259         assert_eq!("\u1e0b\u01c4".nfd_chars().collect::<~str>(), ~"d\u0307\u01c4");
4260         assert_eq!("\u2026".nfd_chars().collect::<~str>(), ~"\u2026");
4261         assert_eq!("\u2126".nfd_chars().collect::<~str>(), ~"\u03a9");
4262         assert_eq!("\u1e0b\u0323".nfd_chars().collect::<~str>(), ~"d\u0323\u0307");
4263         assert_eq!("\u1e0d\u0307".nfd_chars().collect::<~str>(), ~"d\u0323\u0307");
4264         assert_eq!("a\u0301".nfd_chars().collect::<~str>(), ~"a\u0301");
4265         assert_eq!("\u0301a".nfd_chars().collect::<~str>(), ~"\u0301a");
4266         assert_eq!("\ud4db".nfd_chars().collect::<~str>(), ~"\u1111\u1171\u11b6");
4267         assert_eq!("\uac1c".nfd_chars().collect::<~str>(), ~"\u1100\u1162");
4268     }
4269
4270     #[test]
4271     fn test_nfkd_chars() {
4272         assert_eq!("abc".nfkd_chars().collect::<~str>(), ~"abc");
4273         assert_eq!("\u1e0b\u01c4".nfkd_chars().collect::<~str>(), ~"d\u0307DZ\u030c");
4274         assert_eq!("\u2026".nfkd_chars().collect::<~str>(), ~"...");
4275         assert_eq!("\u2126".nfkd_chars().collect::<~str>(), ~"\u03a9");
4276         assert_eq!("\u1e0b\u0323".nfkd_chars().collect::<~str>(), ~"d\u0323\u0307");
4277         assert_eq!("\u1e0d\u0307".nfkd_chars().collect::<~str>(), ~"d\u0323\u0307");
4278         assert_eq!("a\u0301".nfkd_chars().collect::<~str>(), ~"a\u0301");
4279         assert_eq!("\u0301a".nfkd_chars().collect::<~str>(), ~"\u0301a");
4280         assert_eq!("\ud4db".nfkd_chars().collect::<~str>(), ~"\u1111\u1171\u11b6");
4281         assert_eq!("\uac1c".nfkd_chars().collect::<~str>(), ~"\u1100\u1162");
4282     }
4283
4284     #[test]
4285     fn test_lines() {
4286         let data = "\nMäry häd ä little lämb\n\nLittle lämb\n";
4287         let lines: ~[&str] = data.lines().collect();
4288         assert_eq!(lines, ~["", "Märy häd ä little lämb", "", "Little lämb"]);
4289
4290         let data = "\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
4291         let lines: ~[&str] = data.lines().collect();
4292         assert_eq!(lines, ~["", "Märy häd ä little lämb", "", "Little lämb"]);
4293     }
4294
4295     #[test]
4296     fn test_split_strator() {
4297         fn t<'a>(s: &str, sep: &'a str, u: ~[&str]) {
4298             let v: ~[&str] = s.split_str(sep).collect();
4299             assert_eq!(v, u);
4300         }
4301         t("--1233345--", "12345", ~["--1233345--"]);
4302         t("abc::hello::there", "::", ~["abc", "hello", "there"]);
4303         t("::hello::there", "::", ~["", "hello", "there"]);
4304         t("hello::there::", "::", ~["hello", "there", ""]);
4305         t("::hello::there::", "::", ~["", "hello", "there", ""]);
4306         t("ประเทศไทย中华Việt Nam", "中华", ~["ประเทศไทย", "Việt Nam"]);
4307         t("zzXXXzzYYYzz", "zz", ~["", "XXX", "YYY", ""]);
4308         t("zzXXXzYYYz", "XXX", ~["zz", "zYYYz"]);
4309         t(".XXX.YYY.", ".", ~["", "XXX", "YYY", ""]);
4310         t("", ".", ~[""]);
4311         t("zz", "zz", ~["",""]);
4312         t("ok", "z", ~["ok"]);
4313         t("zzz", "zz", ~["","z"]);
4314         t("zzzzz", "zz", ~["","","z"]);
4315     }
4316
4317     #[test]
4318     fn test_str_default() {
4319         use default::Default;
4320         fn t<S: Default + Str>() {
4321             let s: S = Default::default();
4322             assert_eq!(s.as_slice(), "");
4323         }
4324
4325         t::<&str>();
4326         t::<~str>();
4327     }
4328
4329     #[test]
4330     fn test_str_container() {
4331         fn sum_len<S: Container>(v: &[S]) -> uint {
4332             v.iter().map(|x| x.len()).sum()
4333         }
4334
4335         let s = ~"01234";
4336         assert_eq!(5, sum_len(["012", "", "34"]));
4337         assert_eq!(5, sum_len([~"01", ~"2", ~"34", ~""]));
4338         assert_eq!(5, sum_len([s.as_slice()]));
4339     }
4340
4341     #[test]
4342     fn test_str_truncate() {
4343         let mut s = ~"12345";
4344         s.truncate(5);
4345         assert_eq!(s.as_slice(), "12345");
4346         s.truncate(3);
4347         assert_eq!(s.as_slice(), "123");
4348         s.truncate(0);
4349         assert_eq!(s.as_slice(), "");
4350
4351         let mut s = ~"12345";
4352         let p = s.as_ptr();
4353         s.truncate(3);
4354         s.push_str("6");
4355         let p_ = s.as_ptr();
4356         assert_eq!(p_, p);
4357     }
4358
4359     #[test]
4360     #[should_fail]
4361     fn test_str_truncate_invalid_len() {
4362         let mut s = ~"12345";
4363         s.truncate(6);
4364     }
4365
4366     #[test]
4367     #[should_fail]
4368     fn test_str_truncate_split_codepoint() {
4369         let mut s = ~"\u00FC"; // ü
4370         s.truncate(1);
4371     }
4372
4373     #[test]
4374     fn test_str_from_utf8() {
4375         let xs = bytes!("hello");
4376         assert_eq!(from_utf8(xs), Some("hello"));
4377
4378         let xs = bytes!("ศไทย中华Việt Nam");
4379         assert_eq!(from_utf8(xs), Some("ศไทย中华Việt Nam"));
4380
4381         let xs = bytes!("hello", 0xff);
4382         assert_eq!(from_utf8(xs), None);
4383     }
4384
4385     #[test]
4386     fn test_str_from_utf8_owned() {
4387         let xs = bytes!("hello").to_owned();
4388         assert_eq!(from_utf8_owned(xs), Some(~"hello"));
4389
4390         let xs = bytes!("ศไทย中华Việt Nam").to_owned();
4391         assert_eq!(from_utf8_owned(xs), Some(~"ศไทย中华Việt Nam"));
4392
4393         let xs = bytes!("hello", 0xff).to_owned();
4394         assert_eq!(from_utf8_owned(xs), None);
4395     }
4396
4397     #[test]
4398     fn test_str_from_utf8_lossy() {
4399         let xs = bytes!("hello");
4400         assert_eq!(from_utf8_lossy(xs), Slice("hello"));
4401
4402         let xs = bytes!("ศไทย中华Việt Nam");
4403         assert_eq!(from_utf8_lossy(xs), Slice("ศไทย中华Việt Nam"));
4404
4405         let xs = bytes!("Hello", 0xC2, " There", 0xFF, " Goodbye");
4406         assert_eq!(from_utf8_lossy(xs), Owned(~"Hello\uFFFD There\uFFFD Goodbye"));
4407
4408         let xs = bytes!("Hello", 0xC0, 0x80, " There", 0xE6, 0x83, " Goodbye");
4409         assert_eq!(from_utf8_lossy(xs), Owned(~"Hello\uFFFD\uFFFD There\uFFFD Goodbye"));
4410
4411         let xs = bytes!(0xF5, "foo", 0xF5, 0x80, "bar");
4412         assert_eq!(from_utf8_lossy(xs), Owned(~"\uFFFDfoo\uFFFD\uFFFDbar"));
4413
4414         let xs = bytes!(0xF1, "foo", 0xF1, 0x80, "bar", 0xF1, 0x80, 0x80, "baz");
4415         assert_eq!(from_utf8_lossy(xs), Owned(~"\uFFFDfoo\uFFFDbar\uFFFDbaz"));
4416
4417         let xs = bytes!(0xF4, "foo", 0xF4, 0x80, "bar", 0xF4, 0xBF, "baz");
4418         assert_eq!(from_utf8_lossy(xs), Owned(~"\uFFFDfoo\uFFFDbar\uFFFD\uFFFDbaz"));
4419
4420         let xs = bytes!(0xF0, 0x80, 0x80, 0x80, "foo", 0xF0, 0x90, 0x80, 0x80, "bar");
4421         assert_eq!(from_utf8_lossy(xs), Owned(~"\uFFFD\uFFFD\uFFFD\uFFFDfoo\U00010000bar"));
4422
4423         // surrogates
4424         let xs = bytes!(0xED, 0xA0, 0x80, "foo", 0xED, 0xBF, 0xBF, "bar");
4425         assert_eq!(from_utf8_lossy(xs), Owned(~"\uFFFD\uFFFD\uFFFDfoo\uFFFD\uFFFD\uFFFDbar"));
4426     }
4427
4428     #[test]
4429     fn test_from_str() {
4430       let owned: Option<~str> = from_str(&"string");
4431       assert_eq!(owned, Some(~"string"));
4432     }
4433
4434     #[test]
4435     fn test_maybe_owned_traits() {
4436         let s = Slice("abcde");
4437         assert_eq!(s.len(), 5);
4438         assert_eq!(s.as_slice(), "abcde");
4439         assert_eq!(s.to_str(), ~"abcde");
4440         assert_eq!(format!("{}", s), ~"abcde");
4441         assert!(s.lt(&Owned(~"bcdef")));
4442         assert_eq!(Slice(""), Default::default());
4443
4444         let o = Owned(~"abcde");
4445         assert_eq!(o.len(), 5);
4446         assert_eq!(o.as_slice(), "abcde");
4447         assert_eq!(o.to_str(), ~"abcde");
4448         assert_eq!(format!("{}", o), ~"abcde");
4449         assert!(o.lt(&Slice("bcdef")));
4450         assert_eq!(Owned(~""), Default::default());
4451
4452         assert!(s.cmp(&o) == Equal);
4453         assert!(s.equals(&o));
4454         assert!(s.equiv(&o));
4455
4456         assert!(o.cmp(&s) == Equal);
4457         assert!(o.equals(&s));
4458         assert!(o.equiv(&s));
4459     }
4460
4461     #[test]
4462     fn test_maybe_owned_methods() {
4463         let s = Slice("abcde");
4464         assert!(s.is_slice());
4465         assert!(!s.is_owned());
4466
4467         let o = Owned(~"abcde");
4468         assert!(!o.is_slice());
4469         assert!(o.is_owned());
4470     }
4471
4472     #[test]
4473     fn test_maybe_owned_clone() {
4474         assert_eq!(Owned(~"abcde"), Slice("abcde").clone());
4475         assert_eq!(Owned(~"abcde"), Owned(~"abcde").clone());
4476         assert_eq!(Slice("abcde"), Slice("abcde").clone());
4477         assert_eq!(Slice("abcde"), Owned(~"abcde").clone());
4478     }
4479
4480     #[test]
4481     fn test_maybe_owned_into_owned() {
4482         assert_eq!(Slice("abcde").into_owned(), ~"abcde");
4483         assert_eq!(Owned(~"abcde").into_owned(), ~"abcde");
4484     }
4485
4486     #[test]
4487     fn test_into_maybe_owned() {
4488         assert_eq!("abcde".into_maybe_owned(), Slice("abcde"));
4489         assert_eq!((~"abcde").into_maybe_owned(), Slice("abcde"));
4490         assert_eq!("abcde".into_maybe_owned(), Owned(~"abcde"));
4491         assert_eq!((~"abcde").into_maybe_owned(), Owned(~"abcde"));
4492     }
4493 }
4494
4495 #[cfg(test)]
4496 mod bench {
4497     extern crate test;
4498     use self::test::BenchHarness;
4499     use super::*;
4500     use prelude::*;
4501
4502     #[bench]
4503     fn char_iterator(bh: &mut BenchHarness) {
4504         let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
4505         let len = s.char_len();
4506
4507         bh.iter(|| assert_eq!(s.chars().len(), len));
4508     }
4509
4510     #[bench]
4511     fn char_iterator_ascii(bh: &mut BenchHarness) {
4512         let s = "Mary had a little lamb, Little lamb
4513         Mary had a little lamb, Little lamb
4514         Mary had a little lamb, Little lamb
4515         Mary had a little lamb, Little lamb
4516         Mary had a little lamb, Little lamb
4517         Mary had a little lamb, Little lamb";
4518         let len = s.char_len();
4519
4520         bh.iter(|| assert_eq!(s.chars().len(), len));
4521     }
4522
4523     #[bench]
4524     fn char_iterator_rev(bh: &mut BenchHarness) {
4525         let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
4526         let len = s.char_len();
4527
4528         bh.iter(|| assert_eq!(s.chars_rev().len(), len));
4529     }
4530
4531     #[bench]
4532     fn char_indicesator(bh: &mut BenchHarness) {
4533         let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
4534         let len = s.char_len();
4535
4536         bh.iter(|| assert_eq!(s.char_indices().len(), len));
4537     }
4538
4539     #[bench]
4540     fn char_indicesator_rev(bh: &mut BenchHarness) {
4541         let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
4542         let len = s.char_len();
4543
4544         bh.iter(|| assert_eq!(s.char_indices_rev().len(), len));
4545     }
4546
4547     #[bench]
4548     fn split_unicode_ascii(bh: &mut BenchHarness) {
4549         let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
4550
4551         bh.iter(|| assert_eq!(s.split('V').len(), 3));
4552     }
4553
4554     #[bench]
4555     fn split_unicode_not_ascii(bh: &mut BenchHarness) {
4556         struct NotAscii(char);
4557         impl CharEq for NotAscii {
4558             fn matches(&self, c: char) -> bool {
4559                 let NotAscii(cc) = *self;
4560                 cc == c
4561             }
4562             fn only_ascii(&self) -> bool { false }
4563         }
4564         let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
4565
4566         bh.iter(|| assert_eq!(s.split(NotAscii('V')).len(), 3));
4567     }
4568
4569
4570     #[bench]
4571     fn split_ascii(bh: &mut BenchHarness) {
4572         let s = "Mary had a little lamb, Little lamb, little-lamb.";
4573         let len = s.split(' ').len();
4574
4575         bh.iter(|| assert_eq!(s.split(' ').len(), len));
4576     }
4577
4578     #[bench]
4579     fn split_not_ascii(bh: &mut BenchHarness) {
4580         struct NotAscii(char);
4581         impl CharEq for NotAscii {
4582             #[inline]
4583             fn matches(&self, c: char) -> bool {
4584                 let NotAscii(cc) = *self;
4585                 cc == c
4586             }
4587             fn only_ascii(&self) -> bool { false }
4588         }
4589         let s = "Mary had a little lamb, Little lamb, little-lamb.";
4590         let len = s.split(' ').len();
4591
4592         bh.iter(|| assert_eq!(s.split(NotAscii(' ')).len(), len));
4593     }
4594
4595     #[bench]
4596     fn split_extern_fn(bh: &mut BenchHarness) {
4597         let s = "Mary had a little lamb, Little lamb, little-lamb.";
4598         let len = s.split(' ').len();
4599         fn pred(c: char) -> bool { c == ' ' }
4600
4601         bh.iter(|| assert_eq!(s.split(pred).len(), len));
4602     }
4603
4604     #[bench]
4605     fn split_closure(bh: &mut BenchHarness) {
4606         let s = "Mary had a little lamb, Little lamb, little-lamb.";
4607         let len = s.split(' ').len();
4608
4609         bh.iter(|| assert_eq!(s.split(|c: char| c == ' ').len(), len));
4610     }
4611
4612     #[bench]
4613     fn split_slice(bh: &mut BenchHarness) {
4614         let s = "Mary had a little lamb, Little lamb, little-lamb.";
4615         let len = s.split(' ').len();
4616
4617         bh.iter(|| assert_eq!(s.split(&[' ']).len(), len));
4618     }
4619
4620     #[bench]
4621     fn is_utf8_100_ascii(bh: &mut BenchHarness) {
4622
4623         let s = bytes!("Hello there, the quick brown fox jumped over the lazy dog! \
4624                         Lorem ipsum dolor sit amet, consectetur. ");
4625
4626         assert_eq!(100, s.len());
4627         bh.iter(|| {
4628             is_utf8(s)
4629         });
4630     }
4631
4632     #[bench]
4633     fn is_utf8_100_multibyte(bh: &mut BenchHarness) {
4634         let s = bytes!("𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰");
4635         assert_eq!(100, s.len());
4636         bh.iter(|| {
4637             is_utf8(s)
4638         });
4639     }
4640
4641     #[bench]
4642     fn from_utf8_lossy_100_ascii(bh: &mut BenchHarness) {
4643         let s = bytes!("Hello there, the quick brown fox jumped over the lazy dog! \
4644                         Lorem ipsum dolor sit amet, consectetur. ");
4645
4646         assert_eq!(100, s.len());
4647         bh.iter(|| {
4648             let _ = from_utf8_lossy(s);
4649         });
4650     }
4651
4652     #[bench]
4653     fn from_utf8_lossy_100_multibyte(bh: &mut BenchHarness) {
4654         let s = bytes!("𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰");
4655         assert_eq!(100, s.len());
4656         bh.iter(|| {
4657             let _ = from_utf8_lossy(s);
4658         });
4659     }
4660
4661     #[bench]
4662     fn from_utf8_lossy_invalid(bh: &mut BenchHarness) {
4663         let s = bytes!("Hello", 0xC0, 0x80, " There", 0xE6, 0x83, " Goodbye");
4664         bh.iter(|| {
4665             let _ = from_utf8_lossy(s);
4666         });
4667     }
4668
4669     #[bench]
4670     fn from_utf8_lossy_100_invalid(bh: &mut BenchHarness) {
4671         let s = ::slice::from_elem(100, 0xF5u8);
4672         bh.iter(|| {
4673             let _ = from_utf8_lossy(s);
4674         });
4675     }
4676
4677     #[bench]
4678     fn bench_with_capacity(bh: &mut BenchHarness) {
4679         bh.iter(|| {
4680             with_capacity(100)
4681         });
4682     }
4683
4684     #[bench]
4685     fn bench_push_str(bh: &mut BenchHarness) {
4686         let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
4687         bh.iter(|| {
4688             let mut r = ~"";
4689             r.push_str(s);
4690         });
4691     }
4692
4693     #[bench]
4694     fn bench_connect(bh: &mut BenchHarness) {
4695         let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
4696         let sep = "→";
4697         let v = [s, s, s, s, s, s, s, s, s, s];
4698         bh.iter(|| {
4699             assert_eq!(v.connect(sep).len(), s.len() * 10 + sep.len() * 9);
4700         })
4701     }
4702 }