]> git.lizzy.rs Git - rust.git/blob - src/libstd/str.rs
Remove trailing null from strings
[rust.git] / src / libstd / str.rs
1 // Copyright 2012-2013 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  * String manipulation
13  *
14  * Strings are a packed UTF-8 representation of text, stored as null
15  * terminated buffers of u8 bytes.  Strings should be indexed in bytes,
16  * for efficiency, but UTF-8 unsafe operations should be avoided.
17  */
18
19 use at_vec;
20 use cast;
21 use char;
22 use char::Char;
23 use clone::Clone;
24 use container::{Container, Mutable};
25 use iter::Times;
26 use iterator::{Iterator, FromIterator, Extendable, IteratorUtil};
27 use iterator::{Filter, AdditiveIterator, Map};
28 use iterator::{Invert, DoubleEndedIterator, DoubleEndedIteratorUtil};
29 use libc;
30 use num::Zero;
31 use option::{None, Option, Some};
32 use ptr;
33 use ptr::RawPtr;
34 use to_str::ToStr;
35 use uint;
36 #[cfg(stage0)]
37 use unstable::raw::Repr;
38 use vec;
39 use vec::{OwnedVector, OwnedCopyableVector, ImmutableVector, MutableVector};
40
41 /*
42 Section: Conditions
43 */
44
45 condition! {
46     not_utf8: (~str) -> ~str;
47 }
48
49 /*
50 Section: Creating a string
51 */
52
53 /// Convert a vector of bytes to a new UTF-8 string
54 ///
55 /// # Failure
56 ///
57 /// Raises the `not_utf8` condition if invalid UTF-8
58 pub fn from_bytes(vv: &[u8]) -> ~str {
59     use str::not_utf8::cond;
60
61     if !is_utf8(vv) {
62         let first_bad_byte = *vv.iter().find_(|&b| !is_utf8([*b])).get();
63         cond.raise(fmt!("from_bytes: input is not UTF-8; first bad byte is %u",
64                         first_bad_byte as uint))
65     } else {
66         return unsafe { raw::from_bytes(vv) }
67     }
68 }
69
70 /// Consumes a vector of bytes to create a new utf-8 string
71 ///
72 /// # Failure
73 ///
74 /// Raises the `not_utf8` condition if invalid UTF-8
75 pub fn from_bytes_owned(vv: ~[u8]) -> ~str {
76     use str::not_utf8::cond;
77
78     if !is_utf8(vv) {
79         let first_bad_byte = *vv.iter().find_(|&b| !is_utf8([*b])).get();
80         cond.raise(fmt!("from_bytes: input is not UTF-8; first bad byte is %u",
81                         first_bad_byte as uint))
82     } else {
83         return unsafe { raw::from_bytes_owned(vv) }
84     }
85 }
86
87 /// Converts a vector to a string slice without performing any allocations.
88 ///
89 /// Once the slice has been validated as utf-8, it is transmuted in-place and
90 /// returned as a '&str' instead of a '&[u8]'
91 ///
92 /// # Failure
93 ///
94 /// Fails if invalid UTF-8
95 #[cfg(stage0)]
96 pub fn from_bytes_slice<'a>(vector: &'a [u8]) -> &'a str {
97     unsafe {
98         assert!(is_utf8(vector));
99         let mut s = vector.repr();
100         s.len += 1;
101         cast::transmute(s)
102     }
103 }
104
105 /// Converts a vector to a string slice without performing any allocations.
106 ///
107 /// Once the slice has been validated as utf-8, it is transmuted in-place and
108 /// returned as a '&str' instead of a '&[u8]'
109 ///
110 /// # Failure
111 ///
112 /// Fails if invalid UTF-8
113 #[cfg(not(stage0))]
114 pub fn from_bytes_slice<'a>(v: &'a [u8]) -> &'a str {
115     assert!(is_utf8(v));
116     unsafe { cast::transmute(v) }
117 }
118
119 impl ToStr for ~str {
120     #[inline]
121     fn to_str(&self) -> ~str { self.to_owned() }
122 }
123 impl<'self> ToStr for &'self str {
124     #[inline]
125     fn to_str(&self) -> ~str { self.to_owned() }
126 }
127 impl ToStr for @str {
128     #[inline]
129     fn to_str(&self) -> ~str { self.to_owned() }
130 }
131
132 /// Convert a byte to a UTF-8 string
133 ///
134 /// # Failure
135 ///
136 /// Fails if invalid UTF-8
137 #[cfg(stage0)]
138 pub fn from_byte(b: u8) -> ~str {
139     assert!(b < 128u8);
140     unsafe { cast::transmute(~[b, 0u8]) }
141 }
142
143 /// Convert a byte to a UTF-8 string
144 ///
145 /// # Failure
146 ///
147 /// Fails if invalid UTF-8
148 #[cfg(not(stage0))]
149 pub fn from_byte(b: u8) -> ~str {
150     assert!(b < 128u8);
151     unsafe { ::cast::transmute(~[b]) }
152 }
153
154 /// Convert a char to a string
155 pub fn from_char(ch: char) -> ~str {
156     let mut buf = ~"";
157     buf.push_char(ch);
158     buf
159 }
160
161 /// Convert a vector of chars to a string
162 pub fn from_chars(chs: &[char]) -> ~str {
163     let mut buf = ~"";
164     buf.reserve(chs.len());
165     foreach ch in chs.iter() {
166         buf.push_char(*ch)
167     }
168     buf
169 }
170
171 #[doc(hidden)]
172 pub fn push_str(lhs: &mut ~str, rhs: &str) {
173     lhs.push_str(rhs)
174 }
175
176 #[allow(missing_doc)]
177 pub trait StrVector {
178     pub fn concat(&self) -> ~str;
179     pub fn connect(&self, sep: &str) -> ~str;
180 }
181
182 impl<'self, S: Str> StrVector for &'self [S] {
183     /// Concatenate a vector of strings.
184     #[cfg(stage0)]
185     pub fn concat(&self) -> ~str {
186         if self.is_empty() { return ~""; }
187
188         let len = self.iter().transform(|s| s.as_slice().len()).sum();
189
190         let mut s = with_capacity(len);
191
192         unsafe {
193             do s.as_mut_buf |buf, _| {
194                 let mut buf = buf;
195                 foreach ss in self.iter() {
196                     do ss.as_slice().as_imm_buf |ssbuf, sslen| {
197                         let sslen = sslen - 1;
198                         ptr::copy_memory(buf, ssbuf, sslen);
199                         buf = buf.offset(sslen as int);
200                     }
201                 }
202             }
203             raw::set_len(&mut s, len);
204         }
205         s
206     }
207
208     /// Concatenate a vector of strings.
209     #[cfg(not(stage0))]
210     pub fn concat(&self) -> ~str {
211         if self.is_empty() { return ~""; }
212
213         let len = self.iter().transform(|s| s.as_slice().len()).sum();
214
215         let mut s = with_capacity(len);
216
217         unsafe {
218             do s.as_mut_buf |buf, _| {
219                 let mut buf = buf;
220                 foreach ss in self.iter() {
221                     do ss.as_slice().as_imm_buf |ssbuf, sslen| {
222                         ptr::copy_memory(buf, ssbuf, sslen);
223                         buf = buf.offset(sslen as int);
224                     }
225                 }
226             }
227             raw::set_len(&mut s, len);
228         }
229         s
230     }
231
232     /// Concatenate a vector of strings, placing a given separator between each.
233     #[cfg(stage0)]
234     pub fn connect(&self, sep: &str) -> ~str {
235         if self.is_empty() { return ~""; }
236
237         // concat is faster
238         if sep.is_empty() { return self.concat(); }
239
240         // this is wrong without the guarantee that `self` is non-empty
241         let len = sep.len() * (self.len() - 1)
242             + self.iter().transform(|s| s.as_slice().len()).sum();
243         let mut s = ~"";
244         let mut first = true;
245
246         s.reserve(len);
247
248         unsafe {
249             do s.as_mut_buf |buf, _| {
250                 do sep.as_imm_buf |sepbuf, seplen| {
251                     let seplen = seplen - 1;
252                     let mut buf = cast::transmute_mut_unsafe(buf);
253                     foreach ss in self.iter() {
254                         do ss.as_slice().as_imm_buf |ssbuf, sslen| {
255                             let sslen = sslen - 1;
256                             if first {
257                                 first = false;
258                             } else {
259                                 ptr::copy_memory(buf, sepbuf, seplen);
260                                 buf = buf.offset(seplen as int);
261                             }
262                             ptr::copy_memory(buf, ssbuf, sslen);
263                             buf = buf.offset(sslen as int);
264                         }
265                     }
266                 }
267             }
268             raw::set_len(&mut s, len);
269         }
270         s
271     }
272
273     /// Concatenate a vector of strings, placing a given separator between each.
274     #[cfg(not(stage0))]
275     pub fn connect(&self, sep: &str) -> ~str {
276         if self.is_empty() { return ~""; }
277
278         // concat is faster
279         if sep.is_empty() { return self.concat(); }
280
281         // this is wrong without the guarantee that `self` is non-empty
282         let len = sep.len() * (self.len() - 1)
283             + self.iter().transform(|s| s.as_slice().len()).sum();
284         let mut s = ~"";
285         let mut first = true;
286
287         s.reserve(len);
288
289         unsafe {
290             do s.as_mut_buf |buf, _| {
291                 do sep.as_imm_buf |sepbuf, seplen| {
292                     let mut buf = buf;
293                     foreach ss in self.iter() {
294                         do ss.as_slice().as_imm_buf |ssbuf, sslen| {
295                             if first {
296                                 first = false;
297                             } else {
298                                 ptr::copy_memory(buf, sepbuf, seplen);
299                                 buf = buf.offset(seplen as int);
300                             }
301                             ptr::copy_memory(buf, ssbuf, sslen);
302                             buf = buf.offset(sslen as int);
303                         }
304                     }
305                 }
306             }
307             raw::set_len(&mut s, len);
308         }
309         s
310     }
311 }
312
313 /// Something that can be used to compare against a character
314 pub trait CharEq {
315     /// Determine if the splitter should split at the given character
316     fn matches(&self, char) -> bool;
317     /// Indicate if this is only concerned about ASCII characters,
318     /// which can allow for a faster implementation.
319     fn only_ascii(&self) -> bool;
320 }
321
322 impl CharEq for char {
323     #[inline]
324     fn matches(&self, c: char) -> bool { *self == c }
325
326     fn only_ascii(&self) -> bool { (*self as uint) < 128 }
327 }
328
329 impl<'self> CharEq for &'self fn(char) -> bool {
330     #[inline]
331     fn matches(&self, c: char) -> bool { (*self)(c) }
332
333     fn only_ascii(&self) -> bool { false }
334 }
335
336 impl CharEq for extern "Rust" fn(char) -> bool {
337     #[inline]
338     fn matches(&self, c: char) -> bool { (*self)(c) }
339
340     fn only_ascii(&self) -> bool { false }
341 }
342
343 impl<'self, C: CharEq> CharEq for &'self [C] {
344     #[inline]
345     fn matches(&self, c: char) -> bool {
346         self.iter().any(|m| m.matches(c))
347     }
348
349     fn only_ascii(&self) -> bool {
350         self.iter().all(|m| m.only_ascii())
351     }
352 }
353
354 /*
355 Section: Iterators
356 */
357
358 /// External iterator for a string's characters and their byte offsets.
359 /// Use with the `std::iterator` module.
360 #[deriving(Clone)]
361 pub struct CharOffsetIterator<'self> {
362     priv index_front: uint,
363     priv index_back: uint,
364     priv string: &'self str,
365 }
366
367 impl<'self> Iterator<(uint, char)> for CharOffsetIterator<'self> {
368     #[inline]
369     fn next(&mut self) -> Option<(uint, char)> {
370         if self.index_front < self.index_back {
371             let CharRange {ch, next} = self.string.char_range_at(self.index_front);
372             let index = self.index_front;
373             self.index_front = next;
374             Some((index, ch))
375         } else {
376             None
377         }
378     }
379 }
380
381 impl<'self> DoubleEndedIterator<(uint, char)> for CharOffsetIterator<'self> {
382     #[inline]
383     fn next_back(&mut self) -> Option<(uint, char)> {
384         if self.index_front < self.index_back {
385             let CharRange {ch, next} = self.string.char_range_at_reverse(self.index_back);
386             self.index_back = next;
387             Some((next, ch))
388         } else {
389             None
390         }
391     }
392 }
393
394 /// External iterator for a string's characters and their byte offsets in reverse order.
395 /// Use with the `std::iterator` module.
396 pub type CharOffsetRevIterator<'self> =
397     Invert<CharOffsetIterator<'self>>;
398
399 /// External iterator for a string's characters.
400 /// Use with the `std::iterator` module.
401 pub type CharIterator<'self> =
402     Map<'self, (uint, char), char, CharOffsetIterator<'self>>;
403
404 /// External iterator for a string's characters in reverse order.
405 /// Use with the `std::iterator` module.
406 pub type CharRevIterator<'self> =
407     Invert<Map<'self, (uint, char), char, CharOffsetIterator<'self>>>;
408
409 /// External iterator for a string's bytes.
410 /// Use with the `std::iterator` module.
411 pub type ByteIterator<'self> =
412     Map<'self, &'self u8, u8, vec::VecIterator<'self, u8>>;
413
414 /// External iterator for a string's bytes in reverse order.
415 /// Use with the `std::iterator` module.
416 pub type ByteRevIterator<'self> =
417     Invert<Map<'self, &'self u8, u8, vec::VecIterator<'self, u8>>>;
418
419 /// An iterator over the substrings of a string, separated by `sep`.
420 #[deriving(Clone)]
421 pub struct CharSplitIterator<'self,Sep> {
422     priv string: &'self str,
423     priv position: uint,
424     priv sep: Sep,
425     /// The number of splits remaining
426     priv count: uint,
427     /// Whether an empty string at the end is allowed
428     priv allow_trailing_empty: bool,
429     priv finished: bool,
430     priv only_ascii: bool
431 }
432
433 /// An iterator over the words of a string, separated by an sequence of whitespace
434 pub type WordIterator<'self> =
435     Filter<'self, &'self str, CharSplitIterator<'self, extern "Rust" fn(char) -> bool>>;
436
437 /// An iterator over the lines of a string, separated by either `\n` or (`\r\n`).
438 pub type AnyLineIterator<'self> =
439     Map<'self, &'self str, &'self str, CharSplitIterator<'self, char>>;
440
441 impl<'self, Sep: CharEq> Iterator<&'self str> for CharSplitIterator<'self, Sep> {
442     #[inline]
443     fn next(&mut self) -> Option<&'self str> {
444         if self.finished { return None }
445
446         let l = self.string.len();
447         let start = self.position;
448
449         if self.only_ascii {
450             // this gives a *huge* speed up for splitting on ASCII
451             // characters (e.g. '\n' or ' ')
452             while self.position < l && self.count > 0 {
453                 let byte = self.string[self.position];
454
455                 if self.sep.matches(byte as char) {
456                     let slice = unsafe { raw::slice_bytes(self.string, start, self.position) };
457                     self.position += 1;
458                     self.count -= 1;
459                     return Some(slice);
460                 }
461                 self.position += 1;
462             }
463         } else {
464             while self.position < l && self.count > 0 {
465                 let CharRange {ch, next} = self.string.char_range_at(self.position);
466
467                 if self.sep.matches(ch) {
468                     let slice = unsafe { raw::slice_bytes(self.string, start, self.position) };
469                     self.position = next;
470                     self.count -= 1;
471                     return Some(slice);
472                 }
473                 self.position = next;
474             }
475         }
476         self.finished = true;
477         if self.allow_trailing_empty || start < l {
478             Some(unsafe { raw::slice_bytes(self.string, start, l) })
479         } else {
480             None
481         }
482     }
483 }
484
485 /// An iterator over the start and end indicies of the matches of a
486 /// substring within a larger string
487 #[deriving(Clone)]
488 pub struct MatchesIndexIterator<'self> {
489     priv haystack: &'self str,
490     priv needle: &'self str,
491     priv position: uint,
492 }
493
494 /// An iterator over the substrings of a string separated by a given
495 /// search string
496 #[deriving(Clone)]
497 pub struct StrSplitIterator<'self> {
498     priv it: MatchesIndexIterator<'self>,
499     priv last_end: uint,
500     priv finished: bool
501 }
502
503 impl<'self> Iterator<(uint, uint)> for MatchesIndexIterator<'self> {
504     #[inline]
505     fn next(&mut self) -> Option<(uint, uint)> {
506         // See Issue #1932 for why this is a naive search
507         let (h_len, n_len) = (self.haystack.len(), self.needle.len());
508         let mut match_start = 0;
509         let mut match_i = 0;
510
511         while self.position < h_len {
512             if self.haystack[self.position] == self.needle[match_i] {
513                 if match_i == 0 { match_start = self.position; }
514                 match_i += 1;
515                 self.position += 1;
516
517                 if match_i == n_len {
518                     // found a match!
519                     return Some((match_start, self.position));
520                 }
521             } else {
522                 // failed match, backtrack
523                 if match_i > 0 {
524                     match_i = 0;
525                     self.position = match_start;
526                 }
527                 self.position += 1;
528             }
529         }
530         None
531     }
532 }
533
534 impl<'self> Iterator<&'self str> for StrSplitIterator<'self> {
535     #[inline]
536     fn next(&mut self) -> Option<&'self str> {
537         if self.finished { return None; }
538
539         match self.it.next() {
540             Some((from, to)) => {
541                 let ret = Some(self.it.haystack.slice(self.last_end, from));
542                 self.last_end = to;
543                 ret
544             }
545             None => {
546                 self.finished = true;
547                 Some(self.it.haystack.slice(self.last_end, self.it.haystack.len()))
548             }
549         }
550     }
551 }
552
553 /// Replace all occurrences of one string with another
554 ///
555 /// # Arguments
556 ///
557 /// * s - The string containing substrings to replace
558 /// * from - The string to replace
559 /// * to - The replacement string
560 ///
561 /// # Return value
562 ///
563 /// The original string with all occurances of `from` replaced with `to`
564 pub fn replace(s: &str, from: &str, to: &str) -> ~str {
565     let mut result = ~"";
566     let mut last_end = 0;
567     foreach (start, end) in s.matches_index_iter(from) {
568         result.push_str(unsafe{raw::slice_bytes(s, last_end, start)});
569         result.push_str(to);
570         last_end = end;
571     }
572     result.push_str(unsafe{raw::slice_bytes(s, last_end, s.len())});
573     result
574 }
575
576 /*
577 Section: Comparing strings
578 */
579
580 /// Bytewise slice equality
581 #[cfg(not(test), stage0)]
582 #[lang="str_eq"]
583 #[inline]
584 pub fn eq_slice(a: &str, b: &str) -> bool {
585     do a.as_imm_buf |ap, alen| {
586         do b.as_imm_buf |bp, blen| {
587             if (alen != blen) { false }
588             else {
589                 unsafe {
590                     libc::memcmp(ap as *libc::c_void,
591                                  bp as *libc::c_void,
592                                  (alen - 1) as libc::size_t) == 0
593                 }
594             }
595         }
596     }
597 }
598
599 /// Bytewise slice equality
600 #[cfg(not(test), not(stage0))]
601 #[lang="str_eq"]
602 #[inline]
603 pub fn eq_slice(a: &str, b: &str) -> bool {
604     do a.as_imm_buf |ap, alen| {
605         do b.as_imm_buf |bp, blen| {
606             if (alen != blen) { false }
607             else {
608                 unsafe {
609                     libc::memcmp(ap as *libc::c_void,
610                                  bp as *libc::c_void,
611                                  alen as libc::size_t) == 0
612                 }
613             }
614         }
615     }
616 }
617
618 /// Bytewise slice equality
619 #[cfg(test, stage0)]
620 #[lang="str_eq"]
621 #[inline]
622 pub fn eq_slice(a: &str, b: &str) -> bool {
623     do a.as_imm_buf |ap, alen| {
624         do b.as_imm_buf |bp, blen| {
625             if (alen != blen) { false }
626             else {
627                 unsafe {
628                     libc::memcmp(ap as *libc::c_void,
629                                  bp as *libc::c_void,
630                                  (alen - 1) as libc::size_t) == 0
631                 }
632             }
633         }
634     }
635 }
636
637 /// Bytewise slice equality
638 #[cfg(test, not(stage0))]
639 #[inline]
640 pub fn eq_slice(a: &str, b: &str) -> bool {
641     do a.as_imm_buf |ap, alen| {
642         do b.as_imm_buf |bp, blen| {
643             if (alen != blen) { false }
644             else {
645                 unsafe {
646                     libc::memcmp(ap as *libc::c_void,
647                                  bp as *libc::c_void,
648                                  alen as libc::size_t) == 0
649                 }
650             }
651         }
652     }
653 }
654
655 /// Bytewise string equality
656 #[cfg(not(test))]
657 #[lang="uniq_str_eq"]
658 #[inline]
659 pub fn eq(a: &~str, b: &~str) -> bool {
660     eq_slice(*a, *b)
661 }
662
663 #[cfg(test)]
664 #[inline]
665 pub fn eq(a: &~str, b: &~str) -> bool {
666     eq_slice(*a, *b)
667 }
668
669 /*
670 Section: Searching
671 */
672
673 // Utility used by various searching functions
674 fn match_at<'a,'b>(haystack: &'a str, needle: &'b str, at: uint) -> bool {
675     let mut i = at;
676     foreach c in needle.byte_iter() { if haystack[i] != c { return false; } i += 1u; }
677     return true;
678 }
679
680 /*
681 Section: Misc
682 */
683
684 // Return the initial codepoint accumulator for the first byte.
685 // The first byte is special, only want bottom 5 bits for width 2, 4 bits
686 // for width 3, and 3 bits for width 4
687 macro_rules! utf8_first_byte(
688     ($byte:expr, $width:expr) => (($byte & (0x7F >> $width)) as uint)
689 )
690
691 // return the value of $ch updated with continuation byte $byte
692 macro_rules! utf8_acc_cont_byte(
693     ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63u8) as uint)
694 )
695
696 /// Determines if a vector of bytes contains valid UTF-8
697 pub fn is_utf8(v: &[u8]) -> bool {
698     let mut i = 0u;
699     let total = v.len();
700     while i < total {
701         if v[i] < 128u8 {
702             i += 1u;
703         } else {
704             let w = utf8_char_width(v[i]);
705             if w == 0u { return false; }
706
707             let nexti = i + w;
708             if nexti > total { return false; }
709             // 1. Make sure the correct number of continuation bytes are present
710             // 2. Check codepoint ranges (deny overlong encodings)
711             //    2-byte encoding is for codepoints  \u0080 to  \u07ff
712             //    3-byte encoding is for codepoints  \u0800 to  \uffff
713             //    4-byte encoding is for codepoints \u10000 to \u10ffff
714
715             //    2-byte encodings are correct if the width and continuation match up
716             if v[i + 1] & 192u8 != TAG_CONT_U8 { return false; }
717             if w > 2 {
718                 let mut ch;
719                 ch = utf8_first_byte!(v[i], w);
720                 ch = utf8_acc_cont_byte!(ch, v[i + 1]);
721                 if v[i + 2] & 192u8 != TAG_CONT_U8 { return false; }
722                 ch = utf8_acc_cont_byte!(ch, v[i + 2]);
723                 if w == 3 && ch < MAX_TWO_B { return false; }
724                 if w > 3 {
725                     if v[i + 3] & 192u8 != TAG_CONT_U8 { return false; }
726                     ch = utf8_acc_cont_byte!(ch, v[i + 3]);
727                     if ch < MAX_THREE_B || ch >= MAX_UNICODE { return false; }
728                 }
729             }
730
731             i = nexti;
732         }
733     }
734     true
735 }
736
737 /// Determines if a vector of `u16` contains valid UTF-16
738 pub fn is_utf16(v: &[u16]) -> bool {
739     let len = v.len();
740     let mut i = 0u;
741     while (i < len) {
742         let u = v[i];
743
744         if  u <= 0xD7FF_u16 || u >= 0xE000_u16 {
745             i += 1u;
746
747         } else {
748             if i+1u < len { return false; }
749             let u2 = v[i+1u];
750             if u < 0xD7FF_u16 || u > 0xDBFF_u16 { return false; }
751             if u2 < 0xDC00_u16 || u2 > 0xDFFF_u16 { return false; }
752             i += 2u;
753         }
754     }
755     return true;
756 }
757
758 /// Iterates over the utf-16 characters in the specified slice, yielding each
759 /// decoded unicode character to the function provided.
760 ///
761 /// # Failures
762 ///
763 /// * Fails on invalid utf-16 data
764 pub fn utf16_chars(v: &[u16], f: &fn(char)) {
765     let len = v.len();
766     let mut i = 0u;
767     while (i < len && v[i] != 0u16) {
768         let u = v[i];
769
770         if  u <= 0xD7FF_u16 || u >= 0xE000_u16 {
771             f(u as char);
772             i += 1u;
773
774         } else {
775             let u2 = v[i+1u];
776             assert!(u >= 0xD800_u16 && u <= 0xDBFF_u16);
777             assert!(u2 >= 0xDC00_u16 && u2 <= 0xDFFF_u16);
778             let mut c = (u - 0xD800_u16) as char;
779             c = c << 10;
780             c |= (u2 - 0xDC00_u16) as char;
781             c |= 0x1_0000_u32 as char;
782             f(c);
783             i += 2u;
784         }
785     }
786 }
787
788 /// Allocates a new string from the utf-16 slice provided
789 pub fn from_utf16(v: &[u16]) -> ~str {
790     let mut buf = ~"";
791     buf.reserve(v.len());
792     utf16_chars(v, |ch| buf.push_char(ch));
793     buf
794 }
795
796 /// Allocates a new string with the specified capacity. The string returned is
797 /// the empty string, but has capacity for much more.
798 #[inline]
799 pub fn with_capacity(capacity: uint) -> ~str {
800     let mut buf = ~"";
801     buf.reserve(capacity);
802     buf
803 }
804
805 /// As char_len but for a slice of a string
806 ///
807 /// # Arguments
808 ///
809 /// * s - A valid string
810 /// * start - The position inside `s` where to start counting in bytes
811 /// * end - The position where to stop counting
812 ///
813 /// # Return value
814 ///
815 /// The number of Unicode characters in `s` between the given indices.
816 pub fn count_chars(s: &str, start: uint, end: uint) -> uint {
817     assert!(s.is_char_boundary(start));
818     assert!(s.is_char_boundary(end));
819     let mut i = start;
820     let mut len = 0u;
821     while i < end {
822         let next = s.char_range_at(i).next;
823         len += 1u;
824         i = next;
825     }
826     return len;
827 }
828
829 /// Counts the number of bytes taken by the first `n` chars in `s`
830 /// starting from `start`.
831 pub fn count_bytes<'b>(s: &'b str, start: uint, n: uint) -> uint {
832     assert!(s.is_char_boundary(start));
833     let mut end = start;
834     let mut cnt = n;
835     let l = s.len();
836     while cnt > 0u {
837         assert!(end < l);
838         let next = s.char_range_at(end).next;
839         cnt -= 1u;
840         end = next;
841     }
842     end - start
843 }
844
845 // https://tools.ietf.org/html/rfc3629
846 priv static UTF8_CHAR_WIDTH: [u8, ..256] = [
847 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
848 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1F
849 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
850 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3F
851 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
852 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5F
853 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
854 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7F
855 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
856 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9F
857 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
858 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBF
859 0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
860 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDF
861 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEF
862 4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, // 0xFF
863 ];
864
865 /// Given a first byte, determine how many bytes are in this UTF-8 character
866 pub fn utf8_char_width(b: u8) -> uint {
867     return UTF8_CHAR_WIDTH[b] as uint;
868 }
869
870 #[allow(missing_doc)]
871 pub struct CharRange {
872     ch: char,
873     next: uint
874 }
875
876 // UTF-8 tags and ranges
877 priv static TAG_CONT_U8: u8 = 128u8;
878 priv static TAG_CONT: uint = 128u;
879 priv static MAX_ONE_B: uint = 128u;
880 priv static TAG_TWO_B: uint = 192u;
881 priv static MAX_TWO_B: uint = 2048u;
882 priv static TAG_THREE_B: uint = 224u;
883 priv static MAX_THREE_B: uint = 65536u;
884 priv static TAG_FOUR_B: uint = 240u;
885 priv static MAX_UNICODE: uint = 1114112u;
886
887 /// Unsafe operations
888 pub mod raw {
889     use option::Some;
890     use cast;
891     use libc;
892     use ptr;
893     use str::is_utf8;
894     use vec;
895     use vec::MutableVector;
896     use unstable::raw::Slice;
897     #[cfg(stage0)]
898     use unstable::raw::String;
899
900     /// Create a Rust string from a *u8 buffer of the given length
901     #[cfg(stage0)]
902     pub unsafe fn from_buf_len(buf: *u8, len: uint) -> ~str {
903         let mut v: ~[u8] = vec::with_capacity(len + 1);
904         v.as_mut_buf(|vbuf, _len| {
905             ptr::copy_memory(vbuf, buf as *u8, len)
906         });
907         vec::raw::set_len(&mut v, len);
908         v.push(0u8);
909
910         assert!(is_utf8(v));
911         cast::transmute(v)
912     }
913
914     /// Create a Rust string from a *u8 buffer of the given length
915     #[cfg(not(stage0))]
916     pub unsafe fn from_buf_len(buf: *u8, len: uint) -> ~str {
917         let mut v: ~[u8] = vec::with_capacity(len);
918         do v.as_mut_buf |vbuf, _len| {
919             ptr::copy_memory(vbuf, buf as *u8, len)
920         };
921         vec::raw::set_len(&mut v, len);
922
923         assert!(is_utf8(v));
924         ::cast::transmute(v)
925     }
926
927     /// Create a Rust string from a null-terminated C string
928     pub unsafe fn from_c_str(buf: *libc::c_char) -> ~str {
929         let mut curr = buf;
930         let mut i = 0;
931         while *curr != 0 {
932             i += 1;
933             curr = ptr::offset(buf, i);
934         }
935         from_buf_len(buf as *u8, i as uint)
936     }
937
938     /// Converts a vector of bytes to a new owned string.
939     pub unsafe fn from_bytes(v: &[u8]) -> ~str {
940         do v.as_imm_buf |buf, len| {
941             from_buf_len(buf, len)
942         }
943     }
944
945     /// Converts an owned vector of bytes to a new owned string. This assumes
946     /// that the utf-8-ness of the vector has already been validated
947     #[cfg(stage0)]
948     pub unsafe fn from_bytes_owned(mut v: ~[u8]) -> ~str {
949         v.push(0u8);
950         cast::transmute(v)
951     }
952
953     /// Converts an owned vector of bytes to a new owned string. This assumes
954     /// that the utf-8-ness of the vector has already been validated
955     #[cfg(not(stage0))]
956     #[inline]
957     pub unsafe fn from_bytes_owned(v: ~[u8]) -> ~str {
958         cast::transmute(v)
959     }
960
961     /// Converts a byte to a string.
962     pub unsafe fn from_byte(u: u8) -> ~str { from_bytes([u]) }
963
964     /// Form a slice from a C string. Unsafe because the caller must ensure the
965     /// C string has the static lifetime, or else the return value may be
966     /// invalidated later.
967     #[cfg(stage0)]
968     pub unsafe fn c_str_to_static_slice(s: *libc::c_char) -> &'static str {
969         let s = s as *u8;
970         let mut curr = s;
971         let mut len = 0u;
972         while *curr != 0u8 {
973             len += 1u;
974             curr = ptr::offset(s, len as int);
975         }
976         let v = Slice { data: s, len: len + 1 };
977         assert!(is_utf8(cast::transmute(v)));
978         cast::transmute(v)
979     }
980
981     /// Form a slice from a C string. Unsafe because the caller must ensure the
982     /// C string has the static lifetime, or else the return value may be
983     /// invalidated later.
984     #[cfg(not(stage0))]
985     pub unsafe fn c_str_to_static_slice(s: *libc::c_char) -> &'static str {
986         let s = s as *u8;
987         let mut curr = s;
988         let mut len = 0u;
989         while *curr != 0u8 {
990             len += 1u;
991             curr = ptr::offset(s, len as int);
992         }
993         let v = Slice { data: s, len: len };
994         assert!(is_utf8(::cast::transmute(v)));
995         ::cast::transmute(v)
996     }
997
998     /// Takes a bytewise (not UTF-8) slice from a string.
999     ///
1000     /// Returns the substring from [`begin`..`end`).
1001     ///
1002     /// # Failure
1003     ///
1004     /// If begin is greater than end.
1005     /// If end is greater than the length of the string.
1006     #[cfg(stage0)]
1007     #[inline]
1008     pub unsafe fn slice_bytes(s: &str, begin: uint, end: uint) -> &str {
1009         do s.as_imm_buf |sbuf, n| {
1010              assert!((begin <= end));
1011              assert!((end <= n));
1012
1013              cast::transmute(Slice {
1014                  data: ptr::offset(sbuf, begin as int),
1015                  len: end - begin + 1,
1016              })
1017         }
1018     }
1019
1020     /// Takes a bytewise (not UTF-8) slice from a string.
1021     ///
1022     /// Returns the substring from [`begin`..`end`).
1023     ///
1024     /// # Failure
1025     ///
1026     /// If begin is greater than end.
1027     /// If end is greater than the length of the string.
1028     #[cfg(not(stage0))]
1029     #[inline]
1030     pub unsafe fn slice_bytes(s: &str, begin: uint, end: uint) -> &str {
1031         do s.as_imm_buf |sbuf, n| {
1032              assert!((begin <= end));
1033              assert!((end <= n));
1034
1035              cast::transmute(Slice {
1036                  data: ptr::offset(sbuf, begin as int),
1037                  len: end - begin,
1038              })
1039         }
1040     }
1041
1042     /// Appends a byte to a string. (Not UTF-8 safe).
1043     pub unsafe fn push_byte(s: &mut ~str, b: u8) {
1044         let new_len = s.len() + 1;
1045         s.reserve_at_least(new_len);
1046         do s.as_mut_buf |buf, len| {
1047             *ptr::mut_offset(buf, len as int) = b;
1048         }
1049         set_len(&mut *s, new_len);
1050     }
1051
1052     /// Appends a vector of bytes to a string. (Not UTF-8 safe).
1053     unsafe fn push_bytes(s: &mut ~str, bytes: &[u8]) {
1054         let new_len = s.len() + bytes.len();
1055         s.reserve_at_least(new_len);
1056         foreach byte in bytes.iter() { push_byte(&mut *s, *byte); }
1057     }
1058
1059     /// Removes the last byte from a string and returns it. (Not UTF-8 safe).
1060     pub unsafe fn pop_byte(s: &mut ~str) -> u8 {
1061         let len = s.len();
1062         assert!((len > 0u));
1063         let b = s[len - 1u];
1064         set_len(s, len - 1u);
1065         return b;
1066     }
1067
1068     /// Removes the first byte from a string and returns it. (Not UTF-8 safe).
1069     pub unsafe fn shift_byte(s: &mut ~str) -> u8 {
1070         let len = s.len();
1071         assert!((len > 0u));
1072         let b = s[0];
1073         *s = s.slice(1, len).to_owned();
1074         return b;
1075     }
1076
1077     /// Sets the length of the string and adds the null terminator
1078     #[cfg(stage0)]
1079     #[inline]
1080     pub unsafe fn set_len(v: &mut ~str, new_len: uint) {
1081         let v: **mut String = cast::transmute(v);
1082         let repr = *v;
1083         (*repr).fill = new_len + 1u;
1084         let null = ptr::mut_offset(&mut ((*repr).data), new_len as int);
1085         *null = 0u8;
1086     }
1087
1088     /// Sets the length of a string
1089     ///
1090     /// This will explicitly set the size of the string, without actually
1091     /// modifing its buffers, so it is up to the caller to ensure that
1092     /// the string is actually the specified size.
1093     #[cfg(not(stage0))]
1094     #[inline]
1095     pub unsafe fn set_len(s: &mut ~str, new_len: uint) {
1096         let v: &mut ~[u8] = cast::transmute(s);
1097         vec::raw::set_len(v, new_len)
1098     }
1099
1100     /// Sets the length of a string
1101     ///
1102     /// This will explicitly set the size of the string, without actually
1103     /// modifing its buffers, so it is up to the caller to ensure that
1104     /// the string is actually the specified size.
1105     #[test]
1106     fn test_from_buf_len() {
1107         unsafe {
1108             let a = ~[65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 0u8];
1109             let b = vec::raw::to_ptr(a);
1110             let c = from_buf_len(b, 3u);
1111             assert_eq!(c, ~"AAA");
1112         }
1113     }
1114
1115 }
1116
1117 /*
1118 Section: Trait implementations
1119 */
1120
1121 #[cfg(not(test))]
1122 pub mod traits {
1123     use ops::Add;
1124     use cmp::{TotalOrd, Ordering, Less, Equal, Greater, Eq, Ord, Equiv, TotalEq};
1125     use super::{Str, eq_slice};
1126     use option::{Some, None};
1127
1128     impl<'self> Add<&'self str,~str> for &'self str {
1129         #[inline]
1130         fn add(&self, rhs: & &'self str) -> ~str {
1131             let mut ret = self.to_owned();
1132             ret.push_str(*rhs);
1133             ret
1134         }
1135     }
1136
1137     impl<'self> TotalOrd for &'self str {
1138         #[inline]
1139         fn cmp(&self, other: & &'self str) -> Ordering {
1140             foreach (s_b, o_b) in self.byte_iter().zip(other.byte_iter()) {
1141                 match s_b.cmp(&o_b) {
1142                     Greater => return Greater,
1143                     Less => return Less,
1144                     Equal => ()
1145                 }
1146             }
1147
1148             self.len().cmp(&other.len())
1149         }
1150     }
1151
1152     impl TotalOrd for ~str {
1153         #[inline]
1154         fn cmp(&self, other: &~str) -> Ordering { self.as_slice().cmp(&other.as_slice()) }
1155     }
1156
1157     impl TotalOrd for @str {
1158         #[inline]
1159         fn cmp(&self, other: &@str) -> Ordering { self.as_slice().cmp(&other.as_slice()) }
1160     }
1161
1162     impl<'self> Eq for &'self str {
1163         #[inline]
1164         fn eq(&self, other: & &'self str) -> bool {
1165             eq_slice((*self), (*other))
1166         }
1167         #[inline]
1168         fn ne(&self, other: & &'self str) -> bool { !(*self).eq(other) }
1169     }
1170
1171     impl Eq for ~str {
1172         #[inline]
1173         fn eq(&self, other: &~str) -> bool {
1174             eq_slice((*self), (*other))
1175         }
1176         #[inline]
1177         fn ne(&self, other: &~str) -> bool { !(*self).eq(other) }
1178     }
1179
1180     impl Eq for @str {
1181         #[inline]
1182         fn eq(&self, other: &@str) -> bool {
1183             eq_slice((*self), (*other))
1184         }
1185         #[inline]
1186         fn ne(&self, other: &@str) -> bool { !(*self).eq(other) }
1187     }
1188
1189     impl<'self> TotalEq for &'self str {
1190         #[inline]
1191         fn equals(&self, other: & &'self str) -> bool {
1192             eq_slice((*self), (*other))
1193         }
1194     }
1195
1196     impl TotalEq for ~str {
1197         #[inline]
1198         fn equals(&self, other: &~str) -> bool {
1199             eq_slice((*self), (*other))
1200         }
1201     }
1202
1203     impl TotalEq for @str {
1204         #[inline]
1205         fn equals(&self, other: &@str) -> bool {
1206             eq_slice((*self), (*other))
1207         }
1208     }
1209
1210     impl<'self> Ord for &'self str {
1211         #[inline]
1212         fn lt(&self, other: & &'self str) -> bool { self.cmp(other) == Less }
1213         #[inline]
1214         fn le(&self, other: & &'self str) -> bool { self.cmp(other) != Greater }
1215         #[inline]
1216         fn ge(&self, other: & &'self str) -> bool { self.cmp(other) != Less }
1217         #[inline]
1218         fn gt(&self, other: & &'self str) -> bool { self.cmp(other) == Greater }
1219     }
1220
1221     impl Ord for ~str {
1222         #[inline]
1223         fn lt(&self, other: &~str) -> bool { self.cmp(other) == Less }
1224         #[inline]
1225         fn le(&self, other: &~str) -> bool { self.cmp(other) != Greater }
1226         #[inline]
1227         fn ge(&self, other: &~str) -> bool { self.cmp(other) != Less }
1228         #[inline]
1229         fn gt(&self, other: &~str) -> bool { self.cmp(other) == Greater }
1230     }
1231
1232     impl Ord for @str {
1233         #[inline]
1234         fn lt(&self, other: &@str) -> bool { self.cmp(other) == Less }
1235         #[inline]
1236         fn le(&self, other: &@str) -> bool { self.cmp(other) != Greater }
1237         #[inline]
1238         fn ge(&self, other: &@str) -> bool { self.cmp(other) != Less }
1239         #[inline]
1240         fn gt(&self, other: &@str) -> bool { self.cmp(other) == Greater }
1241     }
1242
1243     impl<'self, S: Str> Equiv<S> for &'self str {
1244         #[inline]
1245         fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
1246     }
1247
1248     impl<'self, S: Str> Equiv<S> for @str {
1249         #[inline]
1250         fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
1251     }
1252
1253     impl<'self, S: Str> Equiv<S> for ~str {
1254         #[inline]
1255         fn equiv(&self, other: &S) -> bool { eq_slice(*self, other.as_slice()) }
1256     }
1257 }
1258
1259 #[cfg(test)]
1260 pub mod traits {}
1261
1262 /// Any string that can be represented as a slice
1263 pub trait Str {
1264     /// Work with `self` as a slice.
1265     fn as_slice<'a>(&'a self) -> &'a str;
1266
1267     /// Convert `self` into a ~str.
1268     fn into_owned(self) -> ~str;
1269 }
1270
1271 impl<'self> Str for &'self str {
1272     #[inline]
1273     fn as_slice<'a>(&'a self) -> &'a str { *self }
1274
1275     #[inline]
1276     fn into_owned(self) -> ~str { self.to_owned() }
1277 }
1278
1279 impl<'self> Str for ~str {
1280     #[inline]
1281     fn as_slice<'a>(&'a self) -> &'a str {
1282         let s: &'a str = *self; s
1283     }
1284
1285     #[inline]
1286     fn into_owned(self) -> ~str { self }
1287 }
1288
1289 impl<'self> Str for @str {
1290     #[inline]
1291     fn as_slice<'a>(&'a self) -> &'a str {
1292         let s: &'a str = *self; s
1293     }
1294
1295     #[inline]
1296     fn into_owned(self) -> ~str { self.to_owned() }
1297 }
1298
1299 impl<'self> Container for &'self str {
1300     #[cfg(stage0)]
1301     #[inline]
1302     fn len(&self) -> uint {
1303         do self.as_imm_buf |_p, n| { n - 1u }
1304     }
1305
1306     #[cfg(not(stage0))]
1307     #[inline]
1308     fn len(&self) -> uint {
1309         do self.as_imm_buf |_p, n| { n }
1310     }
1311 }
1312
1313 impl Container for ~str {
1314     #[inline]
1315     fn len(&self) -> uint { self.as_slice().len() }
1316 }
1317
1318 impl Container for @str {
1319     #[inline]
1320     fn len(&self) -> uint { self.as_slice().len() }
1321 }
1322
1323 impl Mutable for ~str {
1324     /// Remove all content, make the string empty
1325     #[inline]
1326     fn clear(&mut self) {
1327         unsafe {
1328             raw::set_len(self, 0)
1329         }
1330     }
1331 }
1332
1333 #[allow(missing_doc)]
1334 pub trait StrSlice<'self> {
1335     fn contains<'a>(&self, needle: &'a str) -> bool;
1336     fn contains_char(&self, needle: char) -> bool;
1337     fn iter(&self) -> CharIterator<'self>;
1338     fn rev_iter(&self) -> CharRevIterator<'self>;
1339     fn byte_iter(&self) -> ByteIterator<'self>;
1340     fn byte_rev_iter(&self) -> ByteRevIterator<'self>;
1341     fn char_offset_iter(&self) -> CharOffsetIterator<'self>;
1342     fn char_offset_rev_iter(&self) -> CharOffsetRevIterator<'self>;
1343     fn split_iter<Sep: CharEq>(&self, sep: Sep) -> CharSplitIterator<'self, Sep>;
1344     fn splitn_iter<Sep: CharEq>(&self, sep: Sep, count: uint) -> CharSplitIterator<'self, Sep>;
1345     fn split_options_iter<Sep: CharEq>(&self, sep: Sep, count: uint, allow_trailing_empty: bool)
1346         -> CharSplitIterator<'self, Sep>;
1347     fn matches_index_iter(&self, sep: &'self str) -> MatchesIndexIterator<'self>;
1348     fn split_str_iter(&self, &'self str) -> StrSplitIterator<'self>;
1349     fn line_iter(&self) -> CharSplitIterator<'self, char>;
1350     fn any_line_iter(&self) -> AnyLineIterator<'self>;
1351     fn word_iter(&self) -> WordIterator<'self>;
1352     fn ends_with(&self, needle: &str) -> bool;
1353     fn is_whitespace(&self) -> bool;
1354     fn is_alphanumeric(&self) -> bool;
1355     fn char_len(&self) -> uint;
1356
1357     fn slice(&self, begin: uint, end: uint) -> &'self str;
1358     fn slice_from(&self, begin: uint) -> &'self str;
1359     fn slice_to(&self, end: uint) -> &'self str;
1360
1361     fn slice_chars(&self, begin: uint, end: uint) -> &'self str;
1362
1363     fn starts_with(&self, needle: &str) -> bool;
1364     fn escape_default(&self) -> ~str;
1365     fn escape_unicode(&self) -> ~str;
1366     fn trim(&self) -> &'self str;
1367     fn trim_left(&self) -> &'self str;
1368     fn trim_right(&self) -> &'self str;
1369     fn trim_chars<C: CharEq>(&self, to_trim: &C) -> &'self str;
1370     fn trim_left_chars<C: CharEq>(&self, to_trim: &C) -> &'self str;
1371     fn trim_right_chars<C: CharEq>(&self, to_trim: &C) -> &'self str;
1372     fn replace(&self, from: &str, to: &str) -> ~str;
1373     fn to_owned(&self) -> ~str;
1374     fn to_managed(&self) -> @str;
1375     fn to_utf16(&self) -> ~[u16];
1376     fn is_char_boundary(&self, index: uint) -> bool;
1377     fn char_range_at(&self, start: uint) -> CharRange;
1378     fn char_at(&self, i: uint) -> char;
1379     fn char_range_at_reverse(&self, start: uint) -> CharRange;
1380     fn char_at_reverse(&self, i: uint) -> char;
1381     fn as_bytes(&self) -> &'self [u8];
1382
1383     fn find<C: CharEq>(&self, search: C) -> Option<uint>;
1384     fn rfind<C: CharEq>(&self, search: C) -> Option<uint>;
1385     fn find_str(&self, &str) -> Option<uint>;
1386
1387     fn repeat(&self, nn: uint) -> ~str;
1388
1389     fn slice_shift_char(&self) -> (char, &'self str);
1390
1391     fn map_chars(&self, ff: &fn(char) -> char) -> ~str;
1392
1393     fn lev_distance(&self, t: &str) -> uint;
1394
1395     fn subslice_offset(&self, inner: &str) -> uint;
1396
1397     fn as_imm_buf<T>(&self, f: &fn(*u8, uint) -> T) -> T;
1398 }
1399
1400 /// Extension methods for strings
1401 impl<'self> StrSlice<'self> for &'self str {
1402     /// Returns true if one string contains another
1403     ///
1404     /// # Arguments
1405     ///
1406     /// * needle - The string to look for
1407     #[inline]
1408     fn contains<'a>(&self, needle: &'a str) -> bool {
1409         self.find_str(needle).is_some()
1410     }
1411
1412     /// Returns true if a string contains a char.
1413     ///
1414     /// # Arguments
1415     ///
1416     /// * needle - The char to look for
1417     #[inline]
1418     fn contains_char(&self, needle: char) -> bool {
1419         self.find(needle).is_some()
1420     }
1421
1422     /// An iterator over the characters of `self`. Note, this iterates
1423     /// over unicode code-points, not unicode graphemes.
1424     ///
1425     /// # Example
1426     ///
1427     /// ~~~ {.rust}
1428     /// let v: ~[char] = "abc åäö".iter().collect();
1429     /// assert_eq!(v, ~['a', 'b', 'c', ' ', 'å', 'ä', 'ö']);
1430     /// ~~~
1431     #[inline]
1432     fn iter(&self) -> CharIterator<'self> {
1433         self.char_offset_iter().transform(|(_, c)| c)
1434     }
1435
1436     /// An iterator over the characters of `self`, in reverse order.
1437     #[inline]
1438     fn rev_iter(&self) -> CharRevIterator<'self> {
1439         self.iter().invert()
1440     }
1441
1442     /// An iterator over the bytes of `self`
1443     #[inline]
1444     fn byte_iter(&self) -> ByteIterator<'self> {
1445         self.as_bytes().iter().transform(|&b| b)
1446     }
1447
1448     /// An iterator over the bytes of `self`, in reverse order
1449     #[inline]
1450     fn byte_rev_iter(&self) -> ByteRevIterator<'self> {
1451         self.byte_iter().invert()
1452     }
1453
1454     /// An iterator over the characters of `self` and their byte offsets.
1455     #[inline]
1456     fn char_offset_iter(&self) -> CharOffsetIterator<'self> {
1457         CharOffsetIterator {
1458             index_front: 0,
1459             index_back: self.len(),
1460             string: *self
1461         }
1462     }
1463
1464     /// An iterator over the characters of `self` and their byte offsets.
1465     #[inline]
1466     fn char_offset_rev_iter(&self) -> CharOffsetRevIterator<'self> {
1467         self.char_offset_iter().invert()
1468     }
1469
1470     /// An iterator over substrings of `self`, separated by characters
1471     /// matched by `sep`.
1472     ///
1473     /// # Example
1474     ///
1475     /// ~~~ {.rust}
1476     /// let v: ~[&str] = "Mary had a little lamb".split_iter(' ').collect();
1477     /// assert_eq!(v, ~["Mary", "had", "a", "little", "lamb"]);
1478     ///
1479     /// let v: ~[&str] = "abc1def2ghi".split_iter(|c: char| c.is_digit()).collect();
1480     /// assert_eq!(v, ~["abc", "def", "ghi"]);
1481     /// ~~~
1482     #[inline]
1483     fn split_iter<Sep: CharEq>(&self, sep: Sep) -> CharSplitIterator<'self, Sep> {
1484         self.split_options_iter(sep, self.len(), true)
1485     }
1486
1487     /// An iterator over substrings of `self`, separated by characters
1488     /// matched by `sep`, restricted to splitting at most `count`
1489     /// times.
1490     #[inline]
1491     fn splitn_iter<Sep: CharEq>(&self, sep: Sep, count: uint) -> CharSplitIterator<'self, Sep> {
1492         self.split_options_iter(sep, count, true)
1493     }
1494
1495     /// An iterator over substrings of `self`, separated by characters
1496     /// matched by `sep`, splitting at most `count` times, and
1497     /// possibly not including the trailing empty substring, if it
1498     /// exists.
1499     #[inline]
1500     fn split_options_iter<Sep: CharEq>(&self, sep: Sep, count: uint, allow_trailing_empty: bool)
1501         -> CharSplitIterator<'self, Sep> {
1502         let only_ascii = sep.only_ascii();
1503         CharSplitIterator {
1504             string: *self,
1505             position: 0,
1506             sep: sep,
1507             count: count,
1508             allow_trailing_empty: allow_trailing_empty,
1509             finished: false,
1510             only_ascii: only_ascii
1511         }
1512     }
1513
1514     /// An iterator over the start and end indices of each match of
1515     /// `sep` within `self`.
1516     #[inline]
1517     fn matches_index_iter(&self, sep: &'self str) -> MatchesIndexIterator<'self> {
1518         assert!(!sep.is_empty())
1519         MatchesIndexIterator {
1520             haystack: *self,
1521             needle: sep,
1522             position: 0
1523         }
1524     }
1525
1526     /// An iterator over the substrings of `self` separated by `sep`.
1527     ///
1528     /// # Example
1529     ///
1530     /// ~~~ {.rust}
1531     /// let v: ~[&str] = "abcXXXabcYYYabc".split_str_iter("abc").collect()
1532     /// assert_eq!(v, ["", "XXX", "YYY", ""]);
1533     /// ~~~
1534     #[inline]
1535     fn split_str_iter(&self, sep: &'self str) -> StrSplitIterator<'self> {
1536         StrSplitIterator {
1537             it: self.matches_index_iter(sep),
1538             last_end: 0,
1539             finished: false
1540         }
1541     }
1542
1543     /// An iterator over the lines of a string (subsequences separated
1544     /// by `\n`).
1545     #[inline]
1546     fn line_iter(&self) -> CharSplitIterator<'self, char> {
1547         self.split_options_iter('\n', self.len(), false)
1548     }
1549
1550     /// An iterator over the lines of a string, separated by either
1551     /// `\n` or (`\r\n`).
1552     fn any_line_iter(&self) -> AnyLineIterator<'self> {
1553         do self.line_iter().transform |line| {
1554             let l = line.len();
1555             if l > 0 && line[l - 1] == '\r' as u8 { line.slice(0, l - 1) }
1556             else { line }
1557         }
1558     }
1559
1560     /// An iterator over the words of a string (subsequences separated
1561     /// by any sequence of whitespace).
1562     #[inline]
1563     fn word_iter(&self) -> WordIterator<'self> {
1564         self.split_iter(char::is_whitespace).filter(|s| !s.is_empty())
1565     }
1566
1567     /// Returns true if the string contains only whitespace
1568     ///
1569     /// Whitespace characters are determined by `char::is_whitespace`
1570     #[inline]
1571     fn is_whitespace(&self) -> bool { self.iter().all(char::is_whitespace) }
1572
1573     /// Returns true if the string contains only alphanumerics
1574     ///
1575     /// Alphanumeric characters are determined by `char::is_alphanumeric`
1576     #[inline]
1577     fn is_alphanumeric(&self) -> bool { self.iter().all(char::is_alphanumeric) }
1578
1579     /// Returns the number of characters that a string holds
1580     #[inline]
1581     fn char_len(&self) -> uint { self.iter().len_() }
1582
1583     /// Returns a slice of the given string from the byte range
1584     /// [`begin`..`end`)
1585     ///
1586     /// Fails when `begin` and `end` do not point to valid characters or
1587     /// beyond the last character of the string
1588     #[inline]
1589     fn slice(&self, begin: uint, end: uint) -> &'self str {
1590         assert!(self.is_char_boundary(begin));
1591         assert!(self.is_char_boundary(end));
1592         unsafe { raw::slice_bytes(*self, begin, end) }
1593     }
1594
1595     /// Returns a slice of the string from `begin` to its end.
1596     ///
1597     /// Fails when `begin` does not point to a valid character, or is
1598     /// out of bounds.
1599     #[inline]
1600     fn slice_from(&self, begin: uint) -> &'self str {
1601         self.slice(begin, self.len())
1602     }
1603
1604     /// Returns a slice of the string from the beginning to byte
1605     /// `end`.
1606     ///
1607     /// Fails when `end` does not point to a valid character, or is
1608     /// out of bounds.
1609     #[inline]
1610     fn slice_to(&self, end: uint) -> &'self str {
1611         self.slice(0, end)
1612     }
1613
1614     /// Returns a slice of the string from the char range
1615     /// [`begin`..`end`).
1616     ///
1617     /// Fails if `begin` > `end` or the either `begin` or `end` are
1618     /// beyond the last character of the string.
1619     fn slice_chars(&self, begin: uint, end: uint) -> &'self str {
1620         assert!(begin <= end);
1621         // not sure how to use the iterators for this nicely.
1622         let mut position = 0;
1623         let mut count = 0;
1624         let l = self.len();
1625         while count < begin && position < l {
1626             position = self.char_range_at(position).next;
1627             count += 1;
1628         }
1629         if count < begin { fail!("Attempted to begin slice_chars beyond end of string") }
1630         let start_byte = position;
1631         while count < end && position < l {
1632             position = self.char_range_at(position).next;
1633             count += 1;
1634         }
1635         if count < end { fail!("Attempted to end slice_chars beyond end of string") }
1636
1637         self.slice(start_byte, position)
1638     }
1639
1640     /// Returns true if `needle` is a prefix of the string.
1641     fn starts_with<'a>(&self, needle: &'a str) -> bool {
1642         let (self_len, needle_len) = (self.len(), needle.len());
1643         if needle_len == 0u { true }
1644         else if needle_len > self_len { false }
1645         else { match_at(*self, needle, 0u) }
1646     }
1647
1648     /// Returns true if `needle` is a suffix of the string.
1649     fn ends_with(&self, needle: &str) -> bool {
1650         let (self_len, needle_len) = (self.len(), needle.len());
1651         if needle_len == 0u { true }
1652         else if needle_len > self_len { false }
1653         else { match_at(*self, needle, self_len - needle_len) }
1654     }
1655
1656     /// Escape each char in `s` with char::escape_default.
1657     fn escape_default(&self) -> ~str {
1658         let mut out: ~str = ~"";
1659         out.reserve_at_least(self.len());
1660         foreach c in self.iter() {
1661             do c.escape_default |c| {
1662                 out.push_char(c);
1663             }
1664         }
1665         out
1666     }
1667
1668     /// Escape each char in `s` with char::escape_unicode.
1669     fn escape_unicode(&self) -> ~str {
1670         let mut out: ~str = ~"";
1671         out.reserve_at_least(self.len());
1672         foreach c in self.iter() {
1673             do c.escape_unicode |c| {
1674                 out.push_char(c);
1675             }
1676         }
1677         out
1678     }
1679
1680     /// Returns a string with leading and trailing whitespace removed
1681     #[inline]
1682     fn trim(&self) -> &'self str {
1683         self.trim_left().trim_right()
1684     }
1685
1686     /// Returns a string with leading whitespace removed
1687     #[inline]
1688     fn trim_left(&self) -> &'self str {
1689         self.trim_left_chars(&char::is_whitespace)
1690     }
1691
1692     /// Returns a string with trailing whitespace removed
1693     #[inline]
1694     fn trim_right(&self) -> &'self str {
1695         self.trim_right_chars(&char::is_whitespace)
1696     }
1697
1698     /// Returns a string with characters that match `to_trim` removed.
1699     ///
1700     /// # Arguments
1701     ///
1702     /// * to_trim - a character matcher
1703     ///
1704     /// # Example
1705     ///
1706     /// ~~~ {.rust}
1707     /// assert_eq!("11foo1bar11".trim_chars(&'1'), "foo1bar")
1708     /// assert_eq!("12foo1bar12".trim_chars(& &['1', '2']), "foo1bar")
1709     /// assert_eq!("123foo1bar123".trim_chars(&|c: char| c.is_digit()), "foo1bar")
1710     /// ~~~
1711     #[inline]
1712     fn trim_chars<C: CharEq>(&self, to_trim: &C) -> &'self str {
1713         self.trim_left_chars(to_trim).trim_right_chars(to_trim)
1714     }
1715
1716     /// Returns a string with leading `chars_to_trim` removed.
1717     ///
1718     /// # Arguments
1719     ///
1720     /// * to_trim - a character matcher
1721     ///
1722     /// # Example
1723     ///
1724     /// ~~~ {.rust}
1725     /// assert_eq!("11foo1bar11".trim_left_chars(&'1'), "foo1bar11")
1726     /// assert_eq!("12foo1bar12".trim_left_chars(& &['1', '2']), "foo1bar12")
1727     /// assert_eq!("123foo1bar123".trim_left_chars(&|c: char| c.is_digit()), "foo1bar123")
1728     /// ~~~
1729     #[inline]
1730     fn trim_left_chars<C: CharEq>(&self, to_trim: &C) -> &'self str {
1731         match self.find(|c: char| !to_trim.matches(c)) {
1732             None => "",
1733             Some(first) => unsafe { raw::slice_bytes(*self, first, self.len()) }
1734         }
1735     }
1736
1737     /// Returns a string with trailing `chars_to_trim` removed.
1738     ///
1739     /// # Arguments
1740     ///
1741     /// * to_trim - a character matcher
1742     ///
1743     /// # Example
1744     ///
1745     /// ~~~ {.rust}
1746     /// assert_eq!("11foo1bar11".trim_right_chars(&'1'), "11foo1bar")
1747     /// assert_eq!("12foo1bar12".trim_right_chars(& &['1', '2']), "12foo1bar")
1748     /// assert_eq!("123foo1bar123".trim_right_chars(&|c: char| c.is_digit()), "123foo1bar")
1749     /// ~~~
1750     #[inline]
1751     fn trim_right_chars<C: CharEq>(&self, to_trim: &C) -> &'self str {
1752         match self.rfind(|c: char| !to_trim.matches(c)) {
1753             None => "",
1754             Some(last) => {
1755                 let next = self.char_range_at(last).next;
1756                 unsafe { raw::slice_bytes(*self, 0u, next) }
1757             }
1758         }
1759     }
1760
1761     /// Replace all occurrences of one string with another
1762     ///
1763     /// # Arguments
1764     ///
1765     /// * from - The string to replace
1766     /// * to - The replacement string
1767     ///
1768     /// # Return value
1769     ///
1770     /// The original string with all occurances of `from` replaced with `to`
1771     pub fn replace(&self, from: &str, to: &str) -> ~str {
1772         let mut result = ~"";
1773         let mut last_end = 0;
1774         foreach (start, end) in self.matches_index_iter(from) {
1775             result.push_str(unsafe{raw::slice_bytes(*self, last_end, start)});
1776             result.push_str(to);
1777             last_end = end;
1778         }
1779         result.push_str(unsafe{raw::slice_bytes(*self, last_end, self.len())});
1780         result
1781     }
1782
1783     /// Copy a slice into a new unique str
1784     #[cfg(stage0)]
1785     #[inline]
1786     fn to_owned(&self) -> ~str {
1787         do self.as_imm_buf |src, len| {
1788             assert!(len > 0);
1789             unsafe {
1790                 let mut v = vec::with_capacity(len);
1791
1792                 do v.as_mut_buf |dst, _| {
1793                     ptr::copy_memory(dst, src, len - 1);
1794                 }
1795                 vec::raw::set_len(&mut v, len - 1);
1796                 v.push(0u8);
1797                 ::cast::transmute(v)
1798             }
1799         }
1800     }
1801
1802     /// Copy a slice into a new unique str
1803     #[cfg(not(stage0))]
1804     #[inline]
1805     fn to_owned(&self) -> ~str {
1806         do self.as_imm_buf |src, len| {
1807             unsafe {
1808                 let mut v = vec::with_capacity(len);
1809
1810                 do v.as_mut_buf |dst, _| {
1811                     ptr::copy_memory(dst, src, len);
1812                 }
1813                 vec::raw::set_len(&mut v, len);
1814                 ::cast::transmute(v)
1815             }
1816         }
1817     }
1818
1819     #[cfg(stage0)]
1820     #[inline]
1821     fn to_managed(&self) -> @str {
1822         let v = at_vec::from_fn(self.len() + 1, |i| {
1823             if i == self.len() { 0 } else { self[i] }
1824         });
1825         unsafe { cast::transmute(v) }
1826     }
1827
1828     #[cfg(not(stage0))]
1829     #[inline]
1830     fn to_managed(&self) -> @str {
1831         unsafe {
1832             let v: *&[u8] = cast::transmute(self);
1833             cast::transmute(at_vec::to_managed(*v))
1834         }
1835     }
1836
1837     /// Converts to a vector of `u16` encoded as UTF-16.
1838     fn to_utf16(&self) -> ~[u16] {
1839         let mut u = ~[];
1840         foreach ch in self.iter() {
1841             // Arithmetic with u32 literals is easier on the eyes than chars.
1842             let mut ch = ch as u32;
1843
1844             if (ch & 0xFFFF_u32) == ch {
1845                 // The BMP falls through (assuming non-surrogate, as it
1846                 // should)
1847                 assert!(ch <= 0xD7FF_u32 || ch >= 0xE000_u32);
1848                 u.push(ch as u16)
1849             } else {
1850                 // Supplementary planes break into surrogates.
1851                 assert!(ch >= 0x1_0000_u32 && ch <= 0x10_FFFF_u32);
1852                 ch -= 0x1_0000_u32;
1853                 let w1 = 0xD800_u16 | ((ch >> 10) as u16);
1854                 let w2 = 0xDC00_u16 | ((ch as u16) & 0x3FF_u16);
1855                 u.push_all([w1, w2])
1856             }
1857         }
1858         u
1859     }
1860
1861     /// Returns false if the index points into the middle of a multi-byte
1862     /// character sequence.
1863     fn is_char_boundary(&self, index: uint) -> bool {
1864         if index == self.len() { return true; }
1865         let b = self[index];
1866         return b < 128u8 || b >= 192u8;
1867     }
1868
1869     /// Pluck a character out of a string and return the index of the next
1870     /// character.
1871     ///
1872     /// This function can be used to iterate over the unicode characters of a
1873     /// string.
1874     ///
1875     /// # Example
1876     ///
1877     /// ~~~ {.rust}
1878     /// let s = "中华Việt Nam";
1879     /// let i = 0u;
1880     /// while i < s.len() {
1881     ///     let CharRange {ch, next} = s.char_range_at(i);
1882     ///     printfln!("%u: %c", i, ch);
1883     ///     i = next;
1884     /// }
1885     /// ~~~
1886     ///
1887     /// # Example output
1888     ///
1889     /// ~~~
1890     /// 0: 中
1891     /// 3: 华
1892     /// 6: V
1893     /// 7: i
1894     /// 8: ệ
1895     /// 11: t
1896     /// 12:
1897     /// 13: N
1898     /// 14: a
1899     /// 15: m
1900     /// ~~~
1901     ///
1902     /// # Arguments
1903     ///
1904     /// * s - The string
1905     /// * i - The byte offset of the char to extract
1906     ///
1907     /// # Return value
1908     ///
1909     /// A record {ch: char, next: uint} containing the char value and the byte
1910     /// index of the next unicode character.
1911     ///
1912     /// # Failure
1913     ///
1914     /// If `i` is greater than or equal to the length of the string.
1915     /// If `i` is not the index of the beginning of a valid UTF-8 character.
1916     #[inline]
1917     fn char_range_at(&self, i: uint) -> CharRange {
1918         if (self[i] < 128u8) {
1919             return CharRange {ch: self[i] as char, next: i + 1 };
1920         }
1921
1922         // Multibyte case is a fn to allow char_range_at to inline cleanly
1923         fn multibyte_char_range_at(s: &str, i: uint) -> CharRange {
1924             let mut val = s[i] as uint;
1925             let w = UTF8_CHAR_WIDTH[val] as uint;
1926             assert!((w != 0));
1927
1928             val = utf8_first_byte!(val, w);
1929             val = utf8_acc_cont_byte!(val, s[i + 1]);
1930             if w > 2 { val = utf8_acc_cont_byte!(val, s[i + 2]); }
1931             if w > 3 { val = utf8_acc_cont_byte!(val, s[i + 3]); }
1932
1933             return CharRange {ch: val as char, next: i + w};
1934         }
1935
1936         return multibyte_char_range_at(*self, i);
1937     }
1938
1939     /// Plucks the character starting at the `i`th byte of a string
1940     #[inline]
1941     fn char_at(&self, i: uint) -> char { self.char_range_at(i).ch }
1942
1943     /// Given a byte position and a str, return the previous char and its position.
1944     ///
1945     /// This function can be used to iterate over a unicode string in reverse.
1946     ///
1947     /// Returns 0 for next index if called on start index 0.
1948     fn char_range_at_reverse(&self, start: uint) -> CharRange {
1949         let mut prev = start;
1950
1951         // while there is a previous byte == 10......
1952         while prev > 0u && self[prev - 1u] & 192u8 == TAG_CONT_U8 {
1953             prev -= 1u;
1954         }
1955
1956         // now refer to the initial byte of previous char
1957         if prev > 0u {
1958             prev -= 1u;
1959         } else {
1960             prev = 0u;
1961         }
1962
1963
1964         let ch = self.char_at(prev);
1965         return CharRange {ch:ch, next:prev};
1966     }
1967
1968     /// Plucks the character ending at the `i`th byte of a string
1969     #[inline]
1970     fn char_at_reverse(&self, i: uint) -> char {
1971         self.char_range_at_reverse(i).ch
1972     }
1973
1974     /// Work with the byte buffer of a string as a byte slice.
1975     ///
1976     /// The byte slice does not include the null terminator.
1977     #[cfg(stage0)]
1978     fn as_bytes(&self) -> &'self [u8] {
1979         unsafe {
1980             let mut slice = self.repr();
1981             slice.len -= 1;
1982             cast::transmute(slice)
1983         }
1984     }
1985
1986     /// Work with the byte buffer of a string as a byte slice.
1987     ///
1988     /// The byte slice does not include the null terminator.
1989     #[cfg(not(stage0))]
1990     fn as_bytes(&self) -> &'self [u8] {
1991         unsafe { cast::transmute(*self) }
1992     }
1993
1994     /// Returns the byte index of the first character of `self` that matches `search`
1995     ///
1996     /// # Return value
1997     ///
1998     /// `Some` containing the byte index of the last matching character
1999     /// or `None` if there is no match
2000     fn find<C: CharEq>(&self, search: C) -> Option<uint> {
2001         if search.only_ascii() {
2002             foreach (i, b) in self.byte_iter().enumerate() {
2003                 if search.matches(b as char) { return Some(i) }
2004             }
2005         } else {
2006             let mut index = 0;
2007             foreach c in self.iter() {
2008                 if search.matches(c) { return Some(index); }
2009                 index += c.len_utf8_bytes();
2010             }
2011         }
2012
2013         None
2014     }
2015
2016     /// Returns the byte index of the last character of `self` that matches `search`
2017     ///
2018     /// # Return value
2019     ///
2020     /// `Some` containing the byte index of the last matching character
2021     /// or `None` if there is no match
2022     fn rfind<C: CharEq>(&self, search: C) -> Option<uint> {
2023         let mut index = self.len();
2024         if search.only_ascii() {
2025             foreach b in self.byte_rev_iter() {
2026                 index -= 1;
2027                 if search.matches(b as char) { return Some(index); }
2028             }
2029         } else {
2030             foreach c in self.rev_iter() {
2031                 index -= c.len_utf8_bytes();
2032                 if search.matches(c) { return Some(index); }
2033             }
2034         }
2035
2036         None
2037     }
2038
2039     /// Returns the byte index of the first matching substring
2040     ///
2041     /// # Arguments
2042     ///
2043     /// * `needle` - The string to search for
2044     ///
2045     /// # Return value
2046     ///
2047     /// `Some` containing the byte index of the first matching substring
2048     /// or `None` if there is no match
2049     fn find_str(&self, needle: &str) -> Option<uint> {
2050         if needle.is_empty() {
2051             Some(0)
2052         } else {
2053             self.matches_index_iter(needle)
2054                 .next()
2055                 .map_consume(|(start, _end)| start)
2056         }
2057     }
2058
2059     /// Given a string, make a new string with repeated copies of it.
2060     #[cfg(stage0)]
2061     fn repeat(&self, nn: uint) -> ~str {
2062         do self.as_imm_buf |buf, len| {
2063             // ignore the NULL terminator
2064             let len = len - 1;
2065             let mut ret = with_capacity(nn * len);
2066
2067             unsafe {
2068                 do ret.as_mut_buf |rbuf, _len| {
2069                     let mut rbuf = rbuf;
2070
2071                     do nn.times {
2072                         ptr::copy_memory(rbuf, buf, len);
2073                         rbuf = rbuf.offset(len as int);
2074                     }
2075                 }
2076                 raw::set_len(&mut ret, nn * len);
2077             }
2078             ret
2079         }
2080     }
2081
2082     /// Given a string, make a new string with repeated copies of it.
2083     #[cfg(not(stage0))]
2084     fn repeat(&self, nn: uint) -> ~str {
2085         do self.as_imm_buf |buf, len| {
2086             let mut ret = with_capacity(nn * len);
2087
2088             unsafe {
2089                 do ret.as_mut_buf |rbuf, _len| {
2090                     let mut rbuf = rbuf;
2091
2092                     do nn.times {
2093                         ptr::copy_memory(rbuf, buf, len);
2094                         rbuf = rbuf.offset(len as int);
2095                     }
2096                 }
2097                 raw::set_len(&mut ret, nn * len);
2098             }
2099             ret
2100         }
2101     }
2102
2103     /// Retrieves the first character from a string slice and returns
2104     /// it. This does not allocate a new string; instead, it returns a
2105     /// slice that point one character beyond the character that was
2106     /// shifted.
2107     ///
2108     /// # Failure
2109     ///
2110     /// If the string does not contain any characters
2111     #[inline]
2112     fn slice_shift_char(&self) -> (char, &'self str) {
2113         let CharRange {ch, next} = self.char_range_at(0u);
2114         let next_s = unsafe { raw::slice_bytes(*self, next, self.len()) };
2115         return (ch, next_s);
2116     }
2117
2118     /// Apply a function to each character.
2119     fn map_chars(&self, ff: &fn(char) -> char) -> ~str {
2120         let mut result = with_capacity(self.len());
2121         foreach cc in self.iter() {
2122             result.push_char(ff(cc));
2123         }
2124         result
2125     }
2126
2127     /// Levenshtein Distance between two strings.
2128     fn lev_distance(&self, t: &str) -> uint {
2129         let slen = self.len();
2130         let tlen = t.len();
2131
2132         if slen == 0 { return tlen; }
2133         if tlen == 0 { return slen; }
2134
2135         let mut dcol = vec::from_fn(tlen + 1, |x| x);
2136
2137         foreach (i, sc) in self.iter().enumerate() {
2138
2139             let mut current = i;
2140             dcol[0] = current + 1;
2141
2142             foreach (j, tc) in t.iter().enumerate() {
2143
2144                 let next = dcol[j + 1];
2145
2146                 if sc == tc {
2147                     dcol[j + 1] = current;
2148                 } else {
2149                     dcol[j + 1] = ::cmp::min(current, next);
2150                     dcol[j + 1] = ::cmp::min(dcol[j + 1], dcol[j]) + 1;
2151                 }
2152
2153                 current = next;
2154             }
2155         }
2156
2157         return dcol[tlen];
2158     }
2159
2160     /// Returns the byte offset of an inner slice relative to an enclosing outer slice.
2161     ///
2162     /// Fails if `inner` is not a direct slice contained within self.
2163     ///
2164     /// # Example
2165     ///
2166     /// ~~~ {.rust}
2167     /// let string = "a\nb\nc";
2168     /// let mut lines = ~[];
2169     /// foreach line in string.line_iter() { lines.push(line) }
2170     ///
2171     /// assert!(string.subslice_offset(lines[0]) == 0); // &"a"
2172     /// assert!(string.subslice_offset(lines[1]) == 2); // &"b"
2173     /// assert!(string.subslice_offset(lines[2]) == 4); // &"c"
2174     /// ~~~
2175     #[inline]
2176     fn subslice_offset(&self, inner: &str) -> uint {
2177         do self.as_imm_buf |a, a_len| {
2178             do inner.as_imm_buf |b, b_len| {
2179                 let a_start: uint;
2180                 let a_end: uint;
2181                 let b_start: uint;
2182                 let b_end: uint;
2183                 unsafe {
2184                     a_start = cast::transmute(a); a_end = a_len + cast::transmute(a);
2185                     b_start = cast::transmute(b); b_end = b_len + cast::transmute(b);
2186                 }
2187                 assert!(a_start <= b_start);
2188                 assert!(b_end <= a_end);
2189                 b_start - a_start
2190             }
2191         }
2192     }
2193
2194     /// Work with the byte buffer and length of a slice.
2195     ///
2196     /// The given length is one byte longer than the 'official' indexable
2197     /// length of the string. This is to permit probing the byte past the
2198     /// indexable area for a null byte, as is the case in slices pointing
2199     /// to full strings, or suffixes of them.
2200     #[inline]
2201     fn as_imm_buf<T>(&self, f: &fn(*u8, uint) -> T) -> T {
2202         let v: &[u8] = unsafe { cast::transmute(*self) };
2203         v.as_imm_buf(f)
2204     }
2205 }
2206
2207 #[allow(missing_doc)]
2208 pub trait OwnedStr {
2209     fn push_str_no_overallocate(&mut self, rhs: &str);
2210     fn push_str(&mut self, rhs: &str);
2211     fn push_char(&mut self, c: char);
2212     fn pop_char(&mut self) -> char;
2213     fn shift_char(&mut self) -> char;
2214     fn unshift_char(&mut self, ch: char);
2215     fn append(self, rhs: &str) -> ~str;
2216     fn reserve(&mut self, n: uint);
2217     fn reserve_at_least(&mut self, n: uint);
2218     fn capacity(&self) -> uint;
2219     #[cfg(stage0)]
2220     fn to_bytes_with_null(self) -> ~[u8];
2221
2222     /// Work with the mutable byte buffer and length of a slice.
2223     ///
2224     /// The given length is one byte longer than the 'official' indexable
2225     /// length of the string. This is to permit probing the byte past the
2226     /// indexable area for a null byte, as is the case in slices pointing
2227     /// to full strings, or suffixes of them.
2228     ///
2229     /// Make sure any mutations to this buffer keep this string valid UTF8.
2230     fn as_mut_buf<T>(&mut self, f: &fn(*mut u8, uint) -> T) -> T;
2231 }
2232
2233 impl OwnedStr for ~str {
2234     /// Appends a string slice to the back of a string, without overallocating
2235     #[inline]
2236     fn push_str_no_overallocate(&mut self, rhs: &str) {
2237         unsafe {
2238             let llen = self.len();
2239             let rlen = rhs.len();
2240             self.reserve(llen + rlen);
2241             do self.as_imm_buf |lbuf, _llen| {
2242                 do rhs.as_imm_buf |rbuf, _rlen| {
2243                     let dst = ptr::offset(lbuf, llen as int);
2244                     let dst = cast::transmute_mut_unsafe(dst);
2245                     ptr::copy_memory(dst, rbuf, rlen);
2246                 }
2247             }
2248             raw::set_len(self, llen + rlen);
2249         }
2250     }
2251
2252     /// Appends a string slice to the back of a string
2253     #[inline]
2254     fn push_str(&mut self, rhs: &str) {
2255         unsafe {
2256             let llen = self.len();
2257             let rlen = rhs.len();
2258             self.reserve_at_least(llen + rlen);
2259             do self.as_imm_buf |lbuf, _llen| {
2260                 do rhs.as_imm_buf |rbuf, _rlen| {
2261                     let dst = ptr::offset(lbuf, llen as int);
2262                     let dst = cast::transmute_mut_unsafe(dst);
2263                     ptr::copy_memory(dst, rbuf, rlen);
2264                 }
2265             }
2266             raw::set_len(self, llen + rlen);
2267         }
2268     }
2269
2270     /// Appends a character to the back of a string
2271     #[inline]
2272     fn push_char(&mut self, c: char) {
2273         assert!((c as uint) < MAX_UNICODE); // FIXME: #7609: should be enforced on all `char`
2274         unsafe {
2275             let code = c as uint;
2276             let nb = if code < MAX_ONE_B { 1u }
2277             else if code < MAX_TWO_B { 2u }
2278             else if code < MAX_THREE_B { 3u }
2279             else { 4u };
2280             let len = self.len();
2281             let new_len = len + nb;
2282             self.reserve_at_least(new_len);
2283             let off = len as int;
2284             do self.as_mut_buf |buf, _len| {
2285                 match nb {
2286                     1u => {
2287                         *ptr::mut_offset(buf, off) = code as u8;
2288                     }
2289                     2u => {
2290                         *ptr::mut_offset(buf, off) = (code >> 6u & 31u | TAG_TWO_B) as u8;
2291                         *ptr::mut_offset(buf, off + 1) = (code & 63u | TAG_CONT) as u8;
2292                     }
2293                     3u => {
2294                         *ptr::mut_offset(buf, off) = (code >> 12u & 15u | TAG_THREE_B) as u8;
2295                         *ptr::mut_offset(buf, off + 1) = (code >> 6u & 63u | TAG_CONT) as u8;
2296                         *ptr::mut_offset(buf, off + 2) = (code & 63u | TAG_CONT) as u8;
2297                     }
2298                     4u => {
2299                         *ptr::mut_offset(buf, off) = (code >> 18u & 7u | TAG_FOUR_B) as u8;
2300                         *ptr::mut_offset(buf, off + 1) = (code >> 12u & 63u | TAG_CONT) as u8;
2301                         *ptr::mut_offset(buf, off + 2) = (code >> 6u & 63u | TAG_CONT) as u8;
2302                         *ptr::mut_offset(buf, off + 3) = (code & 63u | TAG_CONT) as u8;
2303                     }
2304                     _ => {}
2305                 }
2306             }
2307             raw::set_len(self, new_len);
2308         }
2309     }
2310
2311     /// Remove the final character from a string and return it
2312     ///
2313     /// # Failure
2314     ///
2315     /// If the string does not contain any characters
2316     fn pop_char(&mut self) -> char {
2317         let end = self.len();
2318         assert!(end > 0u);
2319         let CharRange {ch, next} = self.char_range_at_reverse(end);
2320         unsafe { raw::set_len(self, next); }
2321         return ch;
2322     }
2323
2324     /// Remove the first character from a string and return it
2325     ///
2326     /// # Failure
2327     ///
2328     /// If the string does not contain any characters
2329     fn shift_char(&mut self) -> char {
2330         let CharRange {ch, next} = self.char_range_at(0u);
2331         *self = self.slice(next, self.len()).to_owned();
2332         return ch;
2333     }
2334
2335     /// Prepend a char to a string
2336     fn unshift_char(&mut self, ch: char) {
2337         // This could be more efficient.
2338         let mut new_str = ~"";
2339         new_str.push_char(ch);
2340         new_str.push_str(*self);
2341         *self = new_str;
2342     }
2343
2344     /// Concatenate two strings together.
2345     #[inline]
2346     fn append(self, rhs: &str) -> ~str {
2347         let mut new_str = self;
2348         new_str.push_str_no_overallocate(rhs);
2349         new_str
2350     }
2351
2352     /// Reserves capacity for exactly `n` bytes in the given string, not including
2353     /// the null terminator.
2354     ///
2355     /// Assuming single-byte characters, the resulting string will be large
2356     /// enough to hold a string of length `n`. To account for the null terminator,
2357     /// the underlying buffer will have the size `n` + 1.
2358     ///
2359     /// If the capacity for `s` is already equal to or greater than the requested
2360     /// capacity, then no action is taken.
2361     ///
2362     /// # Arguments
2363     ///
2364     /// * s - A string
2365     /// * n - The number of bytes to reserve space for
2366     #[cfg(stage0)]
2367     #[inline]
2368     pub fn reserve(&mut self, n: uint) {
2369         unsafe {
2370             let v: *mut ~[u8] = cast::transmute(self);
2371             (*v).reserve(n + 1);
2372         }
2373     }
2374
2375     /// Reserves capacity for exactly `n` bytes in the given string, not including
2376     /// the null terminator.
2377     ///
2378     /// Assuming single-byte characters, the resulting string will be large
2379     /// enough to hold a string of length `n`. To account for the null terminator,
2380     /// the underlying buffer will have the size `n` + 1.
2381     ///
2382     /// If the capacity for `s` is already equal to or greater than the requested
2383     /// capacity, then no action is taken.
2384     ///
2385     /// # Arguments
2386     ///
2387     /// * s - A string
2388     /// * n - The number of bytes to reserve space for
2389     #[cfg(not(stage0))]
2390     #[inline]
2391     pub fn reserve(&mut self, n: uint) {
2392         unsafe {
2393             let v: &mut ~[u8] = cast::transmute(self);
2394             (*v).reserve(n);
2395         }
2396     }
2397
2398     /// Reserves capacity for at least `n` bytes in the given string, not including
2399     /// the null terminator.
2400     ///
2401     /// Assuming single-byte characters, the resulting string will be large
2402     /// enough to hold a string of length `n`. To account for the null terminator,
2403     /// the underlying buffer will have the size `n` + 1.
2404     ///
2405     /// This function will over-allocate in order to amortize the allocation costs
2406     /// in scenarios where the caller may need to repeatedly reserve additional
2407     /// space.
2408     ///
2409     /// If the capacity for `s` is already equal to or greater than the requested
2410     /// capacity, then no action is taken.
2411     ///
2412     /// # Arguments
2413     ///
2414     /// * s - A string
2415     /// * n - The number of bytes to reserve space for
2416     #[cfg(stage0)]
2417     #[inline]
2418     fn reserve_at_least(&mut self, n: uint) {
2419         self.reserve(uint::next_power_of_two(n + 1u) - 1u)
2420     }
2421
2422     /// Reserves capacity for at least `n` bytes in the given string.
2423     ///
2424     /// Assuming single-byte characters, the resulting string will be large
2425     /// enough to hold a string of length `n`. To account for the null terminator,
2426     /// the underlying buffer will have the size `n` + 1.
2427     ///
2428     /// This function will over-allocate in order to amortize the allocation costs
2429     /// in scenarios where the caller may need to repeatedly reserve additional
2430     /// space.
2431     ///
2432     /// If the capacity for `s` is already equal to or greater than the requested
2433     /// capacity, then no action is taken.
2434     ///
2435     /// # Arguments
2436     ///
2437     /// * s - A string
2438     /// * n - The number of bytes to reserve space for
2439     #[cfg(not(stage0))]
2440     #[inline]
2441     fn reserve_at_least(&mut self, n: uint) {
2442         self.reserve(uint::next_power_of_two(n))
2443     }
2444
2445     /// Returns the number of single-byte characters the string can hold without
2446     /// reallocating
2447     #[cfg(stage0)]
2448     fn capacity(&self) -> uint {
2449         let buf: &~[u8] = unsafe { cast::transmute(self) };
2450         let vcap = buf.capacity();
2451         assert!(vcap > 0u);
2452         vcap - 1u
2453     }
2454
2455     /// Returns the number of single-byte characters the string can hold without
2456     /// reallocating
2457     #[cfg(not(stage0))]
2458     fn capacity(&self) -> uint {
2459         unsafe {
2460             let buf: &~[u8] = cast::transmute(self);
2461             buf.capacity()
2462         }
2463     }
2464
2465     /// Convert to a vector of bytes. This does not allocate a new
2466     /// string, and includes the null terminator.
2467     #[cfg(stage0)]
2468     #[inline]
2469     fn to_bytes_with_null(self) -> ~[u8] {
2470         unsafe { cast::transmute(self) }
2471     }
2472
2473     #[inline]
2474     fn as_mut_buf<T>(&mut self, f: &fn(*mut u8, uint) -> T) -> T {
2475         let v: &mut ~[u8] = unsafe { cast::transmute(self) };
2476         v.as_mut_buf(f)
2477     }
2478 }
2479
2480 impl Clone for ~str {
2481     #[inline]
2482     fn clone(&self) -> ~str {
2483         self.to_owned()
2484     }
2485 }
2486
2487 impl Clone for @str {
2488     #[inline]
2489     fn clone(&self) -> @str {
2490         *self
2491     }
2492 }
2493
2494 impl<T: Iterator<char>> FromIterator<char, T> for ~str {
2495     #[inline]
2496     fn from_iterator(iterator: &mut T) -> ~str {
2497         let (lower, _) = iterator.size_hint();
2498         let mut buf = with_capacity(lower);
2499         buf.extend(iterator);
2500         buf
2501     }
2502 }
2503
2504 impl<T: Iterator<char>> Extendable<char, T> for ~str {
2505     #[inline]
2506     fn extend(&mut self, iterator: &mut T) {
2507         let (lower, _) = iterator.size_hint();
2508         let reserve = lower + self.len();
2509         self.reserve_at_least(reserve);
2510         foreach ch in *iterator {
2511             self.push_char(ch)
2512         }
2513     }
2514 }
2515
2516 // This works because every lifetime is a sub-lifetime of 'static
2517 impl<'self> Zero for &'self str {
2518     fn zero() -> &'self str { "" }
2519     fn is_zero(&self) -> bool { self.is_empty() }
2520 }
2521
2522 impl Zero for ~str {
2523     fn zero() -> ~str { ~"" }
2524     fn is_zero(&self) -> bool { self.len() == 0 }
2525 }
2526
2527 impl Zero for @str {
2528     fn zero() -> @str { @"" }
2529     fn is_zero(&self) -> bool { self.len() == 0 }
2530 }
2531
2532 #[cfg(test)]
2533 mod tests {
2534     use iterator::IteratorUtil;
2535     use container::Container;
2536     use option::Some;
2537     use libc::c_char;
2538     use libc;
2539     use ptr;
2540     use str::*;
2541     use vec;
2542     use vec::{ImmutableVector, CopyableVector};
2543     use cmp::{TotalOrd, Less, Equal, Greater};
2544
2545     #[test]
2546     fn test_eq() {
2547         assert!((eq(&~"", &~"")));
2548         assert!((eq(&~"foo", &~"foo")));
2549         assert!((!eq(&~"foo", &~"bar")));
2550     }
2551
2552     #[test]
2553     fn test_eq_slice() {
2554         assert!((eq_slice("foobar".slice(0, 3), "foo")));
2555         assert!((eq_slice("barfoo".slice(3, 6), "foo")));
2556         assert!((!eq_slice("foo1", "foo2")));
2557     }
2558
2559     #[test]
2560     fn test_le() {
2561         assert!("" <= "");
2562         assert!("" <= "foo");
2563         assert!("foo" <= "foo");
2564         assert!("foo" != "bar");
2565     }
2566
2567     #[test]
2568     fn test_len() {
2569         assert_eq!("".len(), 0u);
2570         assert_eq!("hello world".len(), 11u);
2571         assert_eq!("\x63".len(), 1u);
2572         assert_eq!("\xa2".len(), 2u);
2573         assert_eq!("\u03c0".len(), 2u);
2574         assert_eq!("\u2620".len(), 3u);
2575         assert_eq!("\U0001d11e".len(), 4u);
2576
2577         assert_eq!("".char_len(), 0u);
2578         assert_eq!("hello world".char_len(), 11u);
2579         assert_eq!("\x63".char_len(), 1u);
2580         assert_eq!("\xa2".char_len(), 1u);
2581         assert_eq!("\u03c0".char_len(), 1u);
2582         assert_eq!("\u2620".char_len(), 1u);
2583         assert_eq!("\U0001d11e".char_len(), 1u);
2584         assert_eq!("ประเทศไทย中华Việt Nam".char_len(), 19u);
2585     }
2586
2587     #[test]
2588     fn test_find() {
2589         assert_eq!("hello".find('l'), Some(2u));
2590         assert_eq!("hello".find(|c:char| c == 'o'), Some(4u));
2591         assert!("hello".find('x').is_none());
2592         assert!("hello".find(|c:char| c == 'x').is_none());
2593         assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30u));
2594         assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30u));
2595     }
2596
2597     #[test]
2598     fn test_rfind() {
2599         assert_eq!("hello".rfind('l'), Some(3u));
2600         assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4u));
2601         assert!("hello".rfind('x').is_none());
2602         assert!("hello".rfind(|c:char| c == 'x').is_none());
2603         assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30u));
2604         assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30u));
2605     }
2606
2607     #[test]
2608     fn test_push_str() {
2609         let mut s = ~"";
2610         s.push_str("");
2611         assert_eq!(s.slice_from(0), "");
2612         s.push_str("abc");
2613         assert_eq!(s.slice_from(0), "abc");
2614         s.push_str("ประเทศไทย中华Việt Nam");
2615         assert_eq!(s.slice_from(0), "abcประเทศไทย中华Việt Nam");
2616     }
2617
2618     #[test]
2619     fn test_append() {
2620         let mut s = ~"";
2621         s = s.append("");
2622         assert_eq!(s.slice_from(0), "");
2623         s = s.append("abc");
2624         assert_eq!(s.slice_from(0), "abc");
2625         s = s.append("ประเทศไทย中华Việt Nam");
2626         assert_eq!(s.slice_from(0), "abcประเทศไทย中华Việt Nam");
2627     }
2628
2629     #[test]
2630     fn test_pop_char() {
2631         let mut data = ~"ประเทศไทย中华";
2632         let cc = data.pop_char();
2633         assert_eq!(~"ประเทศไทย中", data);
2634         assert_eq!('华', cc);
2635     }
2636
2637     #[test]
2638     fn test_pop_char_2() {
2639         let mut data2 = ~"华";
2640         let cc2 = data2.pop_char();
2641         assert_eq!(~"", data2);
2642         assert_eq!('华', cc2);
2643     }
2644
2645     #[test]
2646     #[should_fail]
2647     #[ignore(cfg(windows))]
2648     fn test_pop_char_fail() {
2649         let mut data = ~"";
2650         let _cc3 = data.pop_char();
2651     }
2652
2653     #[test]
2654     fn test_push_char() {
2655         let mut data = ~"ประเทศไทย中";
2656         data.push_char('华');
2657         data.push_char('b'); // 1 byte
2658         data.push_char('¢'); // 2 byte
2659         data.push_char('€'); // 3 byte
2660         data.push_char('𤭢'); // 4 byte
2661         assert_eq!(~"ประเทศไทย中华b¢€𤭢", data);
2662     }
2663
2664     #[test]
2665     fn test_shift_char() {
2666         let mut data = ~"ประเทศไทย中";
2667         let cc = data.shift_char();
2668         assert_eq!(~"ระเทศไทย中", data);
2669         assert_eq!('ป', cc);
2670     }
2671
2672     #[test]
2673     fn test_unshift_char() {
2674         let mut data = ~"ประเทศไทย中";
2675         data.unshift_char('华');
2676         assert_eq!(~"华ประเทศไทย中", data);
2677     }
2678
2679     #[test]
2680     fn test_collect() {
2681         let empty = "";
2682         let s: ~str = empty.iter().collect();
2683         assert_eq!(empty, s.as_slice());
2684         let data = "ประเทศไทย中";
2685         let s: ~str = data.iter().collect();
2686         assert_eq!(data, s.as_slice());
2687     }
2688
2689     #[test]
2690     fn test_extend() {
2691         let data = ~"ประเทศไทย中";
2692         let mut cpy = data.clone();
2693         let other = "abc";
2694         let mut it = other.iter();
2695         cpy.extend(&mut it);
2696         assert_eq!(cpy, data + other);
2697     }
2698
2699     #[test]
2700     fn test_clear() {
2701         let mut empty = ~"";
2702         empty.clear();
2703         assert_eq!("", empty.as_slice());
2704         let mut data = ~"ประเทศไทย中";
2705         data.clear();
2706         assert_eq!("", data.as_slice());
2707         data.push_char('华');
2708         assert_eq!("华", data.as_slice());
2709     }
2710
2711     #[test]
2712     fn test_find_str() {
2713         // byte positions
2714         assert_eq!("".find_str(""), Some(0u));
2715         assert!("banana".find_str("apple pie").is_none());
2716
2717         let data = "abcabc";
2718         assert_eq!(data.slice(0u, 6u).find_str("ab"), Some(0u));
2719         assert_eq!(data.slice(2u, 6u).find_str("ab"), Some(3u - 2u));
2720         assert!(data.slice(2u, 4u).find_str("ab").is_none());
2721
2722         let mut data = ~"ประเทศไทย中华Việt Nam";
2723         data = data + data;
2724         assert!(data.find_str("ไท华").is_none());
2725         assert_eq!(data.slice(0u, 43u).find_str(""), Some(0u));
2726         assert_eq!(data.slice(6u, 43u).find_str(""), Some(6u - 6u));
2727
2728         assert_eq!(data.slice(0u, 43u).find_str("ประ"), Some( 0u));
2729         assert_eq!(data.slice(0u, 43u).find_str("ทศไ"), Some(12u));
2730         assert_eq!(data.slice(0u, 43u).find_str("ย中"), Some(24u));
2731         assert_eq!(data.slice(0u, 43u).find_str("iệt"), Some(34u));
2732         assert_eq!(data.slice(0u, 43u).find_str("Nam"), Some(40u));
2733
2734         assert_eq!(data.slice(43u, 86u).find_str("ประ"), Some(43u - 43u));
2735         assert_eq!(data.slice(43u, 86u).find_str("ทศไ"), Some(55u - 43u));
2736         assert_eq!(data.slice(43u, 86u).find_str("ย中"), Some(67u - 43u));
2737         assert_eq!(data.slice(43u, 86u).find_str("iệt"), Some(77u - 43u));
2738         assert_eq!(data.slice(43u, 86u).find_str("Nam"), Some(83u - 43u));
2739     }
2740
2741     #[test]
2742     fn test_slice_chars() {
2743         fn t(a: &str, b: &str, start: uint) {
2744             assert_eq!(a.slice_chars(start, start + b.char_len()), b);
2745         }
2746         t("hello", "llo", 2);
2747         t("hello", "el", 1);
2748         assert_eq!("ะเทศไท", "ประเทศไทย中华Việt Nam".slice_chars(2, 8));
2749     }
2750
2751     #[test]
2752     fn test_concat() {
2753         fn t(v: &[~str], s: &str) {
2754             assert_eq!(v.concat(), s.to_str());
2755         }
2756         t([~"you", ~"know", ~"I'm", ~"no", ~"good"], "youknowI'mnogood");
2757         let v: &[~str] = [];
2758         t(v, "");
2759         t([~"hi"], "hi");
2760     }
2761
2762     #[test]
2763     fn test_connect() {
2764         fn t(v: &[~str], sep: &str, s: &str) {
2765             assert_eq!(v.connect(sep), s.to_str());
2766         }
2767         t([~"you", ~"know", ~"I'm", ~"no", ~"good"],
2768           " ", "you know I'm no good");
2769         let v: &[~str] = [];
2770         t(v, " ", "");
2771         t([~"hi"], " ", "hi");
2772     }
2773
2774     #[test]
2775     fn test_concat_slices() {
2776         fn t(v: &[&str], s: &str) {
2777             assert_eq!(v.concat(), s.to_str());
2778         }
2779         t(["you", "know", "I'm", "no", "good"], "youknowI'mnogood");
2780         let v: &[&str] = [];
2781         t(v, "");
2782         t(["hi"], "hi");
2783     }
2784
2785     #[test]
2786     fn test_connect_slices() {
2787         fn t(v: &[&str], sep: &str, s: &str) {
2788             assert_eq!(v.connect(sep), s.to_str());
2789         }
2790         t(["you", "know", "I'm", "no", "good"],
2791           " ", "you know I'm no good");
2792         t([], " ", "");
2793         t(["hi"], " ", "hi");
2794     }
2795
2796     #[test]
2797     fn test_repeat() {
2798         assert_eq!("x".repeat(4), ~"xxxx");
2799         assert_eq!("hi".repeat(4), ~"hihihihi");
2800         assert_eq!("ไท华".repeat(3), ~"ไท华ไท华ไท华");
2801         assert_eq!("".repeat(4), ~"");
2802         assert_eq!("hi".repeat(0), ~"");
2803     }
2804
2805     #[test]
2806     fn test_unsafe_slice() {
2807         assert_eq!("ab", unsafe {raw::slice_bytes("abc", 0, 2)});
2808         assert_eq!("bc", unsafe {raw::slice_bytes("abc", 1, 3)});
2809         assert_eq!("", unsafe {raw::slice_bytes("abc", 1, 1)});
2810         fn a_million_letter_a() -> ~str {
2811             let mut i = 0;
2812             let mut rs = ~"";
2813             while i < 100000 { rs.push_str("aaaaaaaaaa"); i += 1; }
2814             rs
2815         }
2816         fn half_a_million_letter_a() -> ~str {
2817             let mut i = 0;
2818             let mut rs = ~"";
2819             while i < 100000 { rs.push_str("aaaaa"); i += 1; }
2820             rs
2821         }
2822         let letters = a_million_letter_a();
2823         assert!(half_a_million_letter_a() ==
2824             unsafe {raw::slice_bytes(letters, 0u, 500000)}.to_owned());
2825     }
2826
2827     #[test]
2828     fn test_starts_with() {
2829         assert!(("".starts_with("")));
2830         assert!(("abc".starts_with("")));
2831         assert!(("abc".starts_with("a")));
2832         assert!((!"a".starts_with("abc")));
2833         assert!((!"".starts_with("abc")));
2834     }
2835
2836     #[test]
2837     fn test_ends_with() {
2838         assert!(("".ends_with("")));
2839         assert!(("abc".ends_with("")));
2840         assert!(("abc".ends_with("c")));
2841         assert!((!"a".ends_with("abc")));
2842         assert!((!"".ends_with("abc")));
2843     }
2844
2845     #[test]
2846     fn test_is_empty() {
2847         assert!("".is_empty());
2848         assert!(!"a".is_empty());
2849     }
2850
2851     #[test]
2852     fn test_replace() {
2853         let a = "a";
2854         assert_eq!("".replace(a, "b"), ~"");
2855         assert_eq!("a".replace(a, "b"), ~"b");
2856         assert_eq!("ab".replace(a, "b"), ~"bb");
2857         let test = "test";
2858         assert!(" test test ".replace(test, "toast") ==
2859             ~" toast toast ");
2860         assert_eq!(" test test ".replace(test, ""), ~"   ");
2861     }
2862
2863     #[test]
2864     fn test_replace_2a() {
2865         let data = ~"ประเทศไทย中华";
2866         let repl = ~"دولة الكويت";
2867
2868         let a = ~"ประเ";
2869         let A = ~"دولة الكويتทศไทย中华";
2870         assert_eq!(data.replace(a, repl), A);
2871     }
2872
2873     #[test]
2874     fn test_replace_2b() {
2875         let data = ~"ประเทศไทย中华";
2876         let repl = ~"دولة الكويت";
2877
2878         let b = ~"ะเ";
2879         let B = ~"ปรدولة الكويتทศไทย中华";
2880         assert_eq!(data.replace(b,   repl), B);
2881     }
2882
2883     #[test]
2884     fn test_replace_2c() {
2885         let data = ~"ประเทศไทย中华";
2886         let repl = ~"دولة الكويت";
2887
2888         let c = ~"中华";
2889         let C = ~"ประเทศไทยدولة الكويت";
2890         assert_eq!(data.replace(c, repl), C);
2891     }
2892
2893     #[test]
2894     fn test_replace_2d() {
2895         let data = ~"ประเทศไทย中华";
2896         let repl = ~"دولة الكويت";
2897
2898         let d = ~"ไท华";
2899         assert_eq!(data.replace(d, repl), data);
2900     }
2901
2902     #[test]
2903     fn test_slice() {
2904         assert_eq!("ab", "abc".slice(0, 2));
2905         assert_eq!("bc", "abc".slice(1, 3));
2906         assert_eq!("", "abc".slice(1, 1));
2907         assert_eq!("\u65e5", "\u65e5\u672c".slice(0, 3));
2908
2909         let data = "ประเทศไทย中华";
2910         assert_eq!("ป", data.slice(0, 3));
2911         assert_eq!("ร", data.slice(3, 6));
2912         assert_eq!("", data.slice(3, 3));
2913         assert_eq!("华", data.slice(30, 33));
2914
2915         fn a_million_letter_X() -> ~str {
2916             let mut i = 0;
2917             let mut rs = ~"";
2918             while i < 100000 {
2919                 push_str(&mut rs, "华华华华华华华华华华");
2920                 i += 1;
2921             }
2922             rs
2923         }
2924         fn half_a_million_letter_X() -> ~str {
2925             let mut i = 0;
2926             let mut rs = ~"";
2927             while i < 100000 { push_str(&mut rs, "华华华华华"); i += 1; }
2928             rs
2929         }
2930         let letters = a_million_letter_X();
2931         assert!(half_a_million_letter_X() ==
2932             letters.slice(0u, 3u * 500000u).to_owned());
2933     }
2934
2935     #[test]
2936     fn test_slice_2() {
2937         let ss = "中华Việt Nam";
2938
2939         assert_eq!("华", ss.slice(3u, 6u));
2940         assert_eq!("Việt Nam", ss.slice(6u, 16u));
2941
2942         assert_eq!("ab", "abc".slice(0u, 2u));
2943         assert_eq!("bc", "abc".slice(1u, 3u));
2944         assert_eq!("", "abc".slice(1u, 1u));
2945
2946         assert_eq!("中", ss.slice(0u, 3u));
2947         assert_eq!("华V", ss.slice(3u, 7u));
2948         assert_eq!("", ss.slice(3u, 3u));
2949         /*0: 中
2950           3: 华
2951           6: V
2952           7: i
2953           8: ệ
2954          11: t
2955          12:
2956          13: N
2957          14: a
2958          15: m */
2959     }
2960
2961     #[test]
2962     #[should_fail]
2963     #[ignore(cfg(windows))]
2964     fn test_slice_fail() {
2965         "中华Việt Nam".slice(0u, 2u);
2966     }
2967
2968     #[test]
2969     fn test_slice_from() {
2970         assert_eq!("abcd".slice_from(0), "abcd");
2971         assert_eq!("abcd".slice_from(2), "cd");
2972         assert_eq!("abcd".slice_from(4), "");
2973     }
2974     #[test]
2975     fn test_slice_to() {
2976         assert_eq!("abcd".slice_to(0), "");
2977         assert_eq!("abcd".slice_to(2), "ab");
2978         assert_eq!("abcd".slice_to(4), "abcd");
2979     }
2980
2981     #[test]
2982     fn test_trim_left_chars() {
2983         let v: &[char] = &[];
2984         assert_eq!(" *** foo *** ".trim_left_chars(&v), " *** foo *** ");
2985         assert_eq!(" *** foo *** ".trim_left_chars(& &['*', ' ']), "foo *** ");
2986         assert_eq!(" ***  *** ".trim_left_chars(& &['*', ' ']), "");
2987         assert_eq!("foo *** ".trim_left_chars(& &['*', ' ']), "foo *** ");
2988
2989         assert_eq!("11foo1bar11".trim_left_chars(&'1'), "foo1bar11");
2990         assert_eq!("12foo1bar12".trim_left_chars(& &['1', '2']), "foo1bar12");
2991         assert_eq!("123foo1bar123".trim_left_chars(&|c: char| c.is_digit()), "foo1bar123");
2992     }
2993
2994     #[test]
2995     fn test_trim_right_chars() {
2996         let v: &[char] = &[];
2997         assert_eq!(" *** foo *** ".trim_right_chars(&v), " *** foo *** ");
2998         assert_eq!(" *** foo *** ".trim_right_chars(& &['*', ' ']), " *** foo");
2999         assert_eq!(" ***  *** ".trim_right_chars(& &['*', ' ']), "");
3000         assert_eq!(" *** foo".trim_right_chars(& &['*', ' ']), " *** foo");
3001
3002         assert_eq!("11foo1bar11".trim_right_chars(&'1'), "11foo1bar");
3003         assert_eq!("12foo1bar12".trim_right_chars(& &['1', '2']), "12foo1bar");
3004         assert_eq!("123foo1bar123".trim_right_chars(&|c: char| c.is_digit()), "123foo1bar");
3005     }
3006
3007     #[test]
3008     fn test_trim_chars() {
3009         let v: &[char] = &[];
3010         assert_eq!(" *** foo *** ".trim_chars(&v), " *** foo *** ");
3011         assert_eq!(" *** foo *** ".trim_chars(& &['*', ' ']), "foo");
3012         assert_eq!(" ***  *** ".trim_chars(& &['*', ' ']), "");
3013         assert_eq!("foo".trim_chars(& &['*', ' ']), "foo");
3014
3015         assert_eq!("11foo1bar11".trim_chars(&'1'), "foo1bar");
3016         assert_eq!("12foo1bar12".trim_chars(& &['1', '2']), "foo1bar");
3017         assert_eq!("123foo1bar123".trim_chars(&|c: char| c.is_digit()), "foo1bar");
3018     }
3019
3020     #[test]
3021     fn test_trim_left() {
3022         assert_eq!("".trim_left(), "");
3023         assert_eq!("a".trim_left(), "a");
3024         assert_eq!("    ".trim_left(), "");
3025         assert_eq!("     blah".trim_left(), "blah");
3026         assert_eq!("   \u3000  wut".trim_left(), "wut");
3027         assert_eq!("hey ".trim_left(), "hey ");
3028     }
3029
3030     #[test]
3031     fn test_trim_right() {
3032         assert_eq!("".trim_right(), "");
3033         assert_eq!("a".trim_right(), "a");
3034         assert_eq!("    ".trim_right(), "");
3035         assert_eq!("blah     ".trim_right(), "blah");
3036         assert_eq!("wut   \u3000  ".trim_right(), "wut");
3037         assert_eq!(" hey".trim_right(), " hey");
3038     }
3039
3040     #[test]
3041     fn test_trim() {
3042         assert_eq!("".trim(), "");
3043         assert_eq!("a".trim(), "a");
3044         assert_eq!("    ".trim(), "");
3045         assert_eq!("    blah     ".trim(), "blah");
3046         assert_eq!("\nwut   \u3000  ".trim(), "wut");
3047         assert_eq!(" hey dude ".trim(), "hey dude");
3048     }
3049
3050     #[test]
3051     fn test_is_whitespace() {
3052         assert!("".is_whitespace());
3053         assert!(" ".is_whitespace());
3054         assert!("\u2009".is_whitespace()); // Thin space
3055         assert!("  \n\t   ".is_whitespace());
3056         assert!(!"   _   ".is_whitespace());
3057     }
3058
3059     #[test]
3060     fn test_shift_byte() {
3061         let mut s = ~"ABC";
3062         let b = unsafe{raw::shift_byte(&mut s)};
3063         assert_eq!(s, ~"BC");
3064         assert_eq!(b, 65u8);
3065     }
3066
3067     #[test]
3068     fn test_pop_byte() {
3069         let mut s = ~"ABC";
3070         let b = unsafe{raw::pop_byte(&mut s)};
3071         assert_eq!(s, ~"AB");
3072         assert_eq!(b, 67u8);
3073     }
3074
3075     #[test]
3076     fn test_unsafe_from_bytes() {
3077         let a = ~[65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 65u8];
3078         let b = unsafe { raw::from_bytes(a) };
3079         assert_eq!(b, ~"AAAAAAA");
3080     }
3081
3082     #[test]
3083     fn test_from_bytes() {
3084         let ss = ~"ศไทย中华Việt Nam";
3085         let bb = ~[0xe0_u8, 0xb8_u8, 0xa8_u8,
3086                   0xe0_u8, 0xb9_u8, 0x84_u8,
3087                   0xe0_u8, 0xb8_u8, 0x97_u8,
3088                   0xe0_u8, 0xb8_u8, 0xa2_u8,
3089                   0xe4_u8, 0xb8_u8, 0xad_u8,
3090                   0xe5_u8, 0x8d_u8, 0x8e_u8,
3091                   0x56_u8, 0x69_u8, 0xe1_u8,
3092                   0xbb_u8, 0x87_u8, 0x74_u8,
3093                   0x20_u8, 0x4e_u8, 0x61_u8,
3094                   0x6d_u8];
3095
3096
3097         assert_eq!(ss, from_bytes(bb));
3098         assert_eq!(~"𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰",
3099                    from_bytes(bytes!("𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰")));
3100     }
3101
3102     #[test]
3103     fn test_is_utf8_deny_overlong() {
3104         assert!(!is_utf8([0xc0, 0x80]));
3105         assert!(!is_utf8([0xc0, 0xae]));
3106         assert!(!is_utf8([0xe0, 0x80, 0x80]));
3107         assert!(!is_utf8([0xe0, 0x80, 0xaf]));
3108         assert!(!is_utf8([0xe0, 0x81, 0x81]));
3109         assert!(!is_utf8([0xf0, 0x82, 0x82, 0xac]));
3110     }
3111
3112
3113     #[test]
3114     #[ignore(cfg(windows))]
3115     fn test_from_bytes_fail() {
3116         use str::not_utf8::cond;
3117
3118         let bb = ~[0xff_u8, 0xb8_u8, 0xa8_u8,
3119                   0xe0_u8, 0xb9_u8, 0x84_u8,
3120                   0xe0_u8, 0xb8_u8, 0x97_u8,
3121                   0xe0_u8, 0xb8_u8, 0xa2_u8,
3122                   0xe4_u8, 0xb8_u8, 0xad_u8,
3123                   0xe5_u8, 0x8d_u8, 0x8e_u8,
3124                   0x56_u8, 0x69_u8, 0xe1_u8,
3125                   0xbb_u8, 0x87_u8, 0x74_u8,
3126                   0x20_u8, 0x4e_u8, 0x61_u8,
3127                   0x6d_u8];
3128
3129         let mut error_happened = false;
3130         let _x = do cond.trap(|err| {
3131             assert_eq!(err, ~"from_bytes: input is not UTF-8; first bad byte is 255");
3132             error_happened = true;
3133             ~""
3134         }).inside {
3135             from_bytes(bb)
3136         };
3137         assert!(error_happened);
3138     }
3139
3140     #[test]
3141     fn test_raw_from_c_str() {
3142         unsafe {
3143             let a = ~[65, 65, 65, 65, 65, 65, 65, 0];
3144             let b = vec::raw::to_ptr(a);
3145             let c = raw::from_c_str(b);
3146             assert_eq!(c, ~"AAAAAAA");
3147         }
3148     }
3149
3150     #[test]
3151     fn test_as_bytes() {
3152         // no null
3153         let v = [
3154             224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
3155             184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
3156             109
3157         ];
3158         assert_eq!("".as_bytes(), &[]);
3159         assert_eq!("abc".as_bytes(), &['a' as u8, 'b' as u8, 'c' as u8]);
3160         assert_eq!("ศไทย中华Việt Nam".as_bytes(), v);
3161     }
3162
3163     #[cfg(stage0)]
3164     #[test]
3165     #[ignore(cfg(windows))]
3166     #[should_fail]
3167     fn test_as_bytes_fail() {
3168         // Don't double free. (I'm not sure if this exercises the
3169         // original problem code path anymore.)
3170         let s = ~"";
3171         let _bytes = s.as_bytes();
3172         fail!();
3173     }
3174
3175     #[cfg(stage0)]
3176     #[test]
3177     #[ignore(cfg(windows))]
3178     #[should_fail]
3179     fn test_as_bytes_fail() {
3180         // Don't double free. (I'm not sure if this exercises the
3181         // original problem code path anymore.)
3182         let s = ~"";
3183         let _bytes = s.as_bytes_with_null();
3184         fail!();
3185     }
3186
3187     #[cfg(stage0)]
3188     #[test]
3189     fn test_to_bytes_with_null() {
3190         let s = ~"ศไทย中华Việt Nam";
3191         let v = ~[
3192             224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
3193             184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
3194             109, 0
3195         ];
3196         assert_eq!((~"").to_bytes_with_null(), ~[0]);
3197         assert_eq!((~"abc").to_bytes_with_null(),
3198                    ~['a' as u8, 'b' as u8, 'c' as u8, 0]);
3199         assert_eq!(s.to_bytes_with_null(), v);
3200     }
3201
3202     #[test]
3203     #[ignore(cfg(windows))]
3204     #[should_fail]
3205     fn test_as_bytes_fail() {
3206         // Don't double free. (I'm not sure if this exercises the
3207         // original problem code path anymore.)
3208         let s = ~"";
3209         let _bytes = s.as_bytes();
3210         fail!();
3211     }
3212
3213     #[test]
3214     fn test_as_imm_buf() {
3215         do "".as_imm_buf |_, len| {
3216             assert_eq!(len, 0);
3217         }
3218
3219         do "hello".as_imm_buf |buf, len| {
3220             assert_eq!(len, 5);
3221             unsafe {
3222                 assert_eq!(*ptr::offset(buf, 0), 'h' as u8);
3223                 assert_eq!(*ptr::offset(buf, 1), 'e' as u8);
3224                 assert_eq!(*ptr::offset(buf, 2), 'l' as u8);
3225                 assert_eq!(*ptr::offset(buf, 3), 'l' as u8);
3226                 assert_eq!(*ptr::offset(buf, 4), 'o' as u8);
3227             }
3228         }
3229     }
3230
3231     #[test]
3232     fn test_subslice_offset() {
3233         let a = "kernelsprite";
3234         let b = a.slice(7, a.len());
3235         let c = a.slice(0, a.len() - 6);
3236         assert_eq!(a.subslice_offset(b), 7);
3237         assert_eq!(a.subslice_offset(c), 0);
3238
3239         let string = "a\nb\nc";
3240         let mut lines = ~[];
3241         foreach line in string.line_iter() { lines.push(line) }
3242         assert_eq!(string.subslice_offset(lines[0]), 0);
3243         assert_eq!(string.subslice_offset(lines[1]), 2);
3244         assert_eq!(string.subslice_offset(lines[2]), 4);
3245     }
3246
3247     #[test]
3248     #[should_fail]
3249     fn test_subslice_offset_2() {
3250         let a = "alchemiter";
3251         let b = "cruxtruder";
3252         a.subslice_offset(b);
3253     }
3254
3255     #[test]
3256     fn vec_str_conversions() {
3257         let s1: ~str = ~"All mimsy were the borogoves";
3258
3259         let v: ~[u8] = s1.as_bytes().to_owned();
3260         let s2: ~str = from_bytes(v);
3261         let mut i: uint = 0u;
3262         let n1: uint = s1.len();
3263         let n2: uint = v.len();
3264         assert_eq!(n1, n2);
3265         while i < n1 {
3266             let a: u8 = s1[i];
3267             let b: u8 = s2[i];
3268             debug!(a);
3269             debug!(b);
3270             assert_eq!(a, b);
3271             i += 1u;
3272         }
3273     }
3274
3275     #[test]
3276     fn test_contains() {
3277         assert!("abcde".contains("bcd"));
3278         assert!("abcde".contains("abcd"));
3279         assert!("abcde".contains("bcde"));
3280         assert!("abcde".contains(""));
3281         assert!("".contains(""));
3282         assert!(!"abcde".contains("def"));
3283         assert!(!"".contains("a"));
3284
3285         let data = ~"ประเทศไทย中华Việt Nam";
3286         assert!(data.contains("ประเ"));
3287         assert!(data.contains("ะเ"));
3288         assert!(data.contains("中华"));
3289         assert!(!data.contains("ไท华"));
3290     }
3291
3292     #[test]
3293     fn test_contains_char() {
3294         assert!("abc".contains_char('b'));
3295         assert!("a".contains_char('a'));
3296         assert!(!"abc".contains_char('d'));
3297         assert!(!"".contains_char('a'));
3298     }
3299
3300     #[test]
3301     fn test_map() {
3302         assert_eq!(~"", "".map_chars(|c| unsafe {libc::toupper(c as c_char)} as char));
3303         assert_eq!(~"YMCA", "ymca".map_chars(|c| unsafe {libc::toupper(c as c_char)} as char));
3304     }
3305
3306     #[test]
3307     fn test_utf16() {
3308         let pairs =
3309             [(~"𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n",
3310               ~[0xd800_u16, 0xdf45_u16, 0xd800_u16, 0xdf3f_u16,
3311                 0xd800_u16, 0xdf3b_u16, 0xd800_u16, 0xdf46_u16,
3312                 0xd800_u16, 0xdf39_u16, 0xd800_u16, 0xdf3b_u16,
3313                 0xd800_u16, 0xdf30_u16, 0x000a_u16]),
3314
3315              (~"𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n",
3316               ~[0xd801_u16, 0xdc12_u16, 0xd801_u16,
3317                 0xdc49_u16, 0xd801_u16, 0xdc2e_u16, 0xd801_u16,
3318                 0xdc40_u16, 0xd801_u16, 0xdc32_u16, 0xd801_u16,
3319                 0xdc4b_u16, 0x0020_u16, 0xd801_u16, 0xdc0f_u16,
3320                 0xd801_u16, 0xdc32_u16, 0xd801_u16, 0xdc4d_u16,
3321                 0x000a_u16]),
3322
3323              (~"𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n",
3324               ~[0xd800_u16, 0xdf00_u16, 0xd800_u16, 0xdf16_u16,
3325                 0xd800_u16, 0xdf0b_u16, 0xd800_u16, 0xdf04_u16,
3326                 0xd800_u16, 0xdf11_u16, 0xd800_u16, 0xdf09_u16,
3327                 0x00b7_u16, 0xd800_u16, 0xdf0c_u16, 0xd800_u16,
3328                 0xdf04_u16, 0xd800_u16, 0xdf15_u16, 0xd800_u16,
3329                 0xdf04_u16, 0xd800_u16, 0xdf0b_u16, 0xd800_u16,
3330                 0xdf09_u16, 0xd800_u16, 0xdf11_u16, 0x000a_u16 ]),
3331
3332              (~"𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n",
3333               ~[0xd801_u16, 0xdc8b_u16, 0xd801_u16, 0xdc98_u16,
3334                 0xd801_u16, 0xdc88_u16, 0xd801_u16, 0xdc91_u16,
3335                 0xd801_u16, 0xdc9b_u16, 0xd801_u16, 0xdc92_u16,
3336                 0x0020_u16, 0xd801_u16, 0xdc95_u16, 0xd801_u16,
3337                 0xdc93_u16, 0x0020_u16, 0xd801_u16, 0xdc88_u16,
3338                 0xd801_u16, 0xdc9a_u16, 0xd801_u16, 0xdc8d_u16,
3339                 0x0020_u16, 0xd801_u16, 0xdc8f_u16, 0xd801_u16,
3340                 0xdc9c_u16, 0xd801_u16, 0xdc92_u16, 0xd801_u16,
3341                 0xdc96_u16, 0xd801_u16, 0xdc86_u16, 0x0020_u16,
3342                 0xd801_u16, 0xdc95_u16, 0xd801_u16, 0xdc86_u16,
3343                 0x000a_u16 ]) ];
3344
3345         foreach p in pairs.iter() {
3346             let (s, u) = (*p).clone();
3347             assert!(s.to_utf16() == u);
3348             assert!(from_utf16(u) == s);
3349             assert!(from_utf16(s.to_utf16()) == s);
3350             assert!(from_utf16(u).to_utf16() == u);
3351         }
3352     }
3353
3354     #[test]
3355     fn test_char_at() {
3356         let s = ~"ศไทย中华Việt Nam";
3357         let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
3358         let mut pos = 0;
3359         foreach ch in v.iter() {
3360             assert!(s.char_at(pos) == *ch);
3361             pos += from_char(*ch).len();
3362         }
3363     }
3364
3365     #[test]
3366     fn test_char_at_reverse() {
3367         let s = ~"ศไทย中华Việt Nam";
3368         let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
3369         let mut pos = s.len();
3370         foreach ch in v.rev_iter() {
3371             assert!(s.char_at_reverse(pos) == *ch);
3372             pos -= from_char(*ch).len();
3373         }
3374     }
3375
3376     #[test]
3377     fn test_escape_unicode() {
3378         assert_eq!("abc".escape_unicode(), ~"\\x61\\x62\\x63");
3379         assert_eq!("a c".escape_unicode(), ~"\\x61\\x20\\x63");
3380         assert_eq!("\r\n\t".escape_unicode(), ~"\\x0d\\x0a\\x09");
3381         assert_eq!("'\"\\".escape_unicode(), ~"\\x27\\x22\\x5c");
3382         assert_eq!("\x00\x01\xfe\xff".escape_unicode(), ~"\\x00\\x01\\xfe\\xff");
3383         assert_eq!("\u0100\uffff".escape_unicode(), ~"\\u0100\\uffff");
3384         assert_eq!("\U00010000\U0010ffff".escape_unicode(), ~"\\U00010000\\U0010ffff");
3385         assert_eq!("ab\ufb00".escape_unicode(), ~"\\x61\\x62\\ufb00");
3386         assert_eq!("\U0001d4ea\r".escape_unicode(), ~"\\U0001d4ea\\x0d");
3387     }
3388
3389     #[test]
3390     fn test_escape_default() {
3391         assert_eq!("abc".escape_default(), ~"abc");
3392         assert_eq!("a c".escape_default(), ~"a c");
3393         assert_eq!("\r\n\t".escape_default(), ~"\\r\\n\\t");
3394         assert_eq!("'\"\\".escape_default(), ~"\\'\\\"\\\\");
3395         assert_eq!("\u0100\uffff".escape_default(), ~"\\u0100\\uffff");
3396         assert_eq!("\U00010000\U0010ffff".escape_default(), ~"\\U00010000\\U0010ffff");
3397         assert_eq!("ab\ufb00".escape_default(), ~"ab\\ufb00");
3398         assert_eq!("\U0001d4ea\r".escape_default(), ~"\\U0001d4ea\\r");
3399     }
3400
3401     #[test]
3402     fn test_to_managed() {
3403         assert_eq!("abc".to_managed(), @"abc");
3404         assert_eq!("abcdef".slice(1, 5).to_managed(), @"bcde");
3405     }
3406
3407     #[test]
3408     fn test_total_ord() {
3409         "1234".cmp(& &"123") == Greater;
3410         "123".cmp(& &"1234") == Less;
3411         "1234".cmp(& &"1234") == Equal;
3412         "12345555".cmp(& &"123456") == Less;
3413         "22".cmp(& &"1234") == Greater;
3414     }
3415
3416     #[test]
3417     fn test_char_range_at() {
3418         let data = ~"b¢€𤭢𤭢€¢b";
3419         assert_eq!('b', data.char_range_at(0).ch);
3420         assert_eq!('¢', data.char_range_at(1).ch);
3421         assert_eq!('€', data.char_range_at(3).ch);
3422         assert_eq!('𤭢', data.char_range_at(6).ch);
3423         assert_eq!('𤭢', data.char_range_at(10).ch);
3424         assert_eq!('€', data.char_range_at(14).ch);
3425         assert_eq!('¢', data.char_range_at(17).ch);
3426         assert_eq!('b', data.char_range_at(19).ch);
3427     }
3428
3429     #[test]
3430     fn test_char_range_at_reverse_underflow() {
3431         assert_eq!("abc".char_range_at_reverse(0).next, 0);
3432     }
3433
3434     #[test]
3435     fn test_add() {
3436         #[allow(unnecessary_allocation)];
3437         macro_rules! t (
3438             ($s1:expr, $s2:expr, $e:expr) => {
3439                 assert_eq!($s1 + $s2, $e);
3440                 assert_eq!($s1.to_owned() + $s2, $e);
3441                 assert_eq!($s1.to_managed() + $s2, $e);
3442             }
3443         );
3444
3445         t!("foo",  "bar", ~"foobar");
3446         t!("foo", @"bar", ~"foobar");
3447         t!("foo", ~"bar", ~"foobar");
3448         t!("ศไทย中",  "华Việt Nam", ~"ศไทย中华Việt Nam");
3449         t!("ศไทย中", @"华Việt Nam", ~"ศไทย中华Việt Nam");
3450         t!("ศไทย中", ~"华Việt Nam", ~"ศไทย中华Việt Nam");
3451     }
3452
3453     #[test]
3454     fn test_iterator() {
3455         use iterator::*;
3456         let s = ~"ศไทย中华Việt Nam";
3457         let v = ~['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
3458
3459         let mut pos = 0;
3460         let mut it = s.iter();
3461
3462         foreach c in it {
3463             assert_eq!(c, v[pos]);
3464             pos += 1;
3465         }
3466         assert_eq!(pos, v.len());
3467     }
3468
3469     #[test]
3470     fn test_rev_iterator() {
3471         use iterator::*;
3472         let s = ~"ศไทย中华Việt Nam";
3473         let v = ~['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
3474
3475         let mut pos = 0;
3476         let mut it = s.rev_iter();
3477
3478         foreach c in it {
3479             assert_eq!(c, v[pos]);
3480             pos += 1;
3481         }
3482         assert_eq!(pos, v.len());
3483     }
3484
3485     #[test]
3486     fn test_byte_iterator() {
3487         let s = ~"ศไทย中华Việt Nam";
3488         let v = [
3489             224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
3490             184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
3491             109
3492         ];
3493         let mut pos = 0;
3494
3495         foreach b in s.byte_iter() {
3496             assert_eq!(b, v[pos]);
3497             pos += 1;
3498         }
3499     }
3500
3501     #[test]
3502     fn test_byte_rev_iterator() {
3503         let s = ~"ศไทย中华Việt Nam";
3504         let v = [
3505             224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
3506             184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
3507             109
3508         ];
3509         let mut pos = v.len();
3510
3511         foreach b in s.byte_rev_iter() {
3512             pos -= 1;
3513             assert_eq!(b, v[pos]);
3514         }
3515     }
3516
3517     #[test]
3518     fn test_char_offset_iterator() {
3519         use iterator::*;
3520         let s = "ศไทย中华Việt Nam";
3521         let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
3522         let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
3523
3524         let mut pos = 0;
3525         let mut it = s.char_offset_iter();
3526
3527         foreach c in it {
3528             assert_eq!(c, (p[pos], v[pos]));
3529             pos += 1;
3530         }
3531         assert_eq!(pos, v.len());
3532         assert_eq!(pos, p.len());
3533     }
3534
3535     #[test]
3536     fn test_char_offset_rev_iterator() {
3537         use iterator::*;
3538         let s = "ศไทย中华Việt Nam";
3539         let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
3540         let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
3541
3542         let mut pos = 0;
3543         let mut it = s.char_offset_rev_iter();
3544
3545         foreach c in it {
3546             assert_eq!(c, (p[pos], v[pos]));
3547             pos += 1;
3548         }
3549         assert_eq!(pos, v.len());
3550         assert_eq!(pos, p.len());
3551     }
3552
3553     #[test]
3554     fn test_split_char_iterator() {
3555         let data = "\nMäry häd ä little lämb\nLittle lämb\n";
3556
3557         let split: ~[&str] = data.split_iter(' ').collect();
3558         assert_eq!(split, ~["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
3559
3560         let split: ~[&str] = data.split_iter(|c: char| c == ' ').collect();
3561         assert_eq!(split, ~["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
3562
3563         // Unicode
3564         let split: ~[&str] = data.split_iter('ä').collect();
3565         assert_eq!(split, ~["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
3566
3567         let split: ~[&str] = data.split_iter(|c: char| c == 'ä').collect();
3568         assert_eq!(split, ~["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
3569     }
3570
3571     #[test]
3572     fn test_splitn_char_iterator() {
3573         let data = "\nMäry häd ä little lämb\nLittle lämb\n";
3574
3575         let split: ~[&str] = data.splitn_iter(' ', 3).collect();
3576         assert_eq!(split, ~["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
3577
3578         let split: ~[&str] = data.splitn_iter(|c: char| c == ' ', 3).collect();
3579         assert_eq!(split, ~["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
3580
3581         // Unicode
3582         let split: ~[&str] = data.splitn_iter('ä', 3).collect();
3583         assert_eq!(split, ~["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
3584
3585         let split: ~[&str] = data.splitn_iter(|c: char| c == 'ä', 3).collect();
3586         assert_eq!(split, ~["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
3587     }
3588
3589     #[test]
3590     fn test_split_char_iterator_no_trailing() {
3591         let data = "\nMäry häd ä little lämb\nLittle lämb\n";
3592
3593         let split: ~[&str] = data.split_options_iter('\n', 1000, true).collect();
3594         assert_eq!(split, ~["", "Märy häd ä little lämb", "Little lämb", ""]);
3595
3596         let split: ~[&str] = data.split_options_iter('\n', 1000, false).collect();
3597         assert_eq!(split, ~["", "Märy häd ä little lämb", "Little lämb"]);
3598     }
3599
3600     #[test]
3601     fn test_word_iter() {
3602         let data = "\n \tMäry   häd\tä  little lämb\nLittle lämb\n";
3603         let words: ~[&str] = data.word_iter().collect();
3604         assert_eq!(words, ~["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
3605     }
3606
3607     #[test]
3608     fn test_line_iter() {
3609         let data = "\nMäry häd ä little lämb\n\nLittle lämb\n";
3610         let lines: ~[&str] = data.line_iter().collect();
3611         assert_eq!(lines, ~["", "Märy häd ä little lämb", "", "Little lämb"]);
3612
3613         let data = "\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
3614         let lines: ~[&str] = data.line_iter().collect();
3615         assert_eq!(lines, ~["", "Märy häd ä little lämb", "", "Little lämb"]);
3616     }
3617
3618     #[test]
3619     fn test_split_str_iterator() {
3620         fn t<'a>(s: &str, sep: &'a str, u: ~[&str]) {
3621             let v: ~[&str] = s.split_str_iter(sep).collect();
3622             assert_eq!(v, u);
3623         }
3624         t("--1233345--", "12345", ~["--1233345--"]);
3625         t("abc::hello::there", "::", ~["abc", "hello", "there"]);
3626         t("::hello::there", "::", ~["", "hello", "there"]);
3627         t("hello::there::", "::", ~["hello", "there", ""]);
3628         t("::hello::there::", "::", ~["", "hello", "there", ""]);
3629         t("ประเทศไทย中华Việt Nam", "中华", ~["ประเทศไทย", "Việt Nam"]);
3630         t("zzXXXzzYYYzz", "zz", ~["", "XXX", "YYY", ""]);
3631         t("zzXXXzYYYz", "XXX", ~["zz", "zYYYz"]);
3632         t(".XXX.YYY.", ".", ~["", "XXX", "YYY", ""]);
3633         t("", ".", ~[""]);
3634         t("zz", "zz", ~["",""]);
3635         t("ok", "z", ~["ok"]);
3636         t("zzz", "zz", ~["","z"]);
3637         t("zzzzz", "zz", ~["","","z"]);
3638     }
3639
3640     #[test]
3641     fn test_str_zero() {
3642         use num::Zero;
3643         fn t<S: Zero + Str>() {
3644             let s: S = Zero::zero();
3645             assert_eq!(s.as_slice(), "");
3646             assert!(s.is_zero());
3647         }
3648
3649         t::<&str>();
3650         t::<@str>();
3651         t::<~str>();
3652     }
3653
3654     #[test]
3655     fn test_str_container() {
3656         fn sum_len<S: Container>(v: &[S]) -> uint {
3657             v.iter().transform(|x| x.len()).sum()
3658         }
3659
3660         let s = ~"01234";
3661         assert_eq!(5, sum_len(["012", "", "34"]));
3662         assert_eq!(5, sum_len([@"01", @"2", @"34", @""]));
3663         assert_eq!(5, sum_len([~"01", ~"2", ~"34", ~""]));
3664         assert_eq!(5, sum_len([s.as_slice()]));
3665     }
3666 }
3667
3668 #[cfg(test)]
3669 mod bench {
3670     use extra::test::BenchHarness;
3671     use str;
3672
3673     #[bench]
3674     fn is_utf8_100_ascii(bh: &mut BenchHarness) {
3675
3676         let s = bytes!("Hello there, the quick brown fox jumped over the lazy dog! \
3677                         Lorem ipsum dolor sit amet, consectetur. ");
3678
3679         assert_eq!(100, s.len());
3680         do bh.iter {
3681             str::is_utf8(s);
3682         }
3683     }
3684
3685     #[bench]
3686     fn is_utf8_100_multibyte(bh: &mut BenchHarness) {
3687         let s = bytes!("𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰");
3688         assert_eq!(100, s.len());
3689         do bh.iter {
3690             str::is_utf8(s);
3691         }
3692     }
3693
3694     #[bench]
3695     fn map_chars_100_ascii(bh: &mut BenchHarness) {
3696         let s = "HelloHelloHelloHelloHelloHelloHelloHelloHelloHello\
3697                  HelloHelloHelloHelloHelloHelloHelloHelloHelloHello";
3698         do bh.iter {
3699             s.map_chars(|c| ((c as uint) + 1) as char);
3700         }
3701     }
3702
3703     #[bench]
3704     fn map_chars_100_multibytes(bh: &mut BenchHarness) {
3705         let s = "𐌀𐌖𐌋𐌄𐌑𐌀𐌖𐌋𐌄𐌑𐌀𐌖𐌋𐌄𐌑𐌀𐌖𐌋𐌄𐌑𐌀𐌖𐌋𐌄𐌑\
3706                  𐌀𐌖𐌋𐌄𐌑𐌀𐌖𐌋𐌄𐌑𐌀𐌖𐌋𐌄𐌑𐌀𐌖𐌋𐌄𐌑𐌀𐌖𐌋𐌄𐌑\
3707                  𐌀𐌖𐌋𐌄𐌑𐌀𐌖𐌋𐌄𐌑𐌀𐌖𐌋𐌄𐌑𐌀𐌖𐌋𐌄𐌑𐌀𐌖𐌋𐌄𐌑\
3708                  𐌀𐌖𐌋𐌄𐌑𐌀𐌖𐌋𐌄𐌑𐌀𐌖𐌋𐌄𐌑𐌀𐌖𐌋𐌄𐌑𐌀𐌖𐌋𐌄𐌑";
3709         do bh.iter {
3710             s.map_chars(|c| ((c as uint) + 1) as char);
3711         }
3712     }
3713 }