]> git.lizzy.rs Git - rust.git/blob - src/libcollections/string.rs
rollup merge of #19972: alexcrichton/snapshots
[rust.git] / src / libcollections / string.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10 //
11 // ignore-lexer-test FIXME #15679
12
13 //! An owned, growable string that enforces that its contents are valid UTF-8.
14
15 use core::prelude::*;
16
17 use core::borrow::{Cow, IntoCow};
18 use core::default::Default;
19 use core::fmt;
20 use core::hash;
21 use core::mem;
22 use core::ptr;
23 use core::ops;
24 // FIXME: ICE's abound if you import the `Slice` type while importing `Slice` trait
25 use core::raw::Slice as RawSlice;
26
27 use slice::CloneSliceExt;
28 use str;
29 use str::{CharRange, CowString, FromStr, StrAllocating};
30 use str::MaybeOwned::Owned;
31 use vec::{DerefVec, Vec, as_vec};
32
33 /// A growable string stored as a UTF-8 encoded buffer.
34 #[deriving(Clone, PartialOrd, Eq, Ord)]
35 #[stable]
36 pub struct String {
37     vec: Vec<u8>,
38 }
39
40 impl String {
41     /// Creates a new string buffer initialized with the empty string.
42     ///
43     /// # Examples
44     ///
45     /// ```
46     /// let mut s = String::new();
47     /// ```
48     #[inline]
49     #[stable]
50     pub fn new() -> String {
51         String {
52             vec: Vec::new(),
53         }
54     }
55
56     /// Creates a new string buffer with the given capacity.
57     /// The string will be able to hold exactly `capacity` bytes without
58     /// reallocating. If `capacity` is 0, the string will not allocate.
59     ///
60     /// # Examples
61     ///
62     /// ```
63     /// let mut s = String::with_capacity(10);
64     /// ```
65     #[inline]
66     #[stable]
67     pub fn with_capacity(capacity: uint) -> String {
68         String {
69             vec: Vec::with_capacity(capacity),
70         }
71     }
72
73     /// Creates a new string buffer from the given string.
74     ///
75     /// # Examples
76     ///
77     /// ```
78     /// let s = String::from_str("hello");
79     /// assert_eq!(s.as_slice(), "hello");
80     /// ```
81     #[inline]
82     #[experimental = "needs investigation to see if to_string() can match perf"]
83     pub fn from_str(string: &str) -> String {
84         String { vec: string.as_bytes().to_vec() }
85     }
86
87     /// Returns the vector as a string buffer, if possible, taking care not to
88     /// copy it.
89     ///
90     /// Returns `Err` with the original vector if the vector contains invalid
91     /// UTF-8.
92     ///
93     /// # Examples
94     ///
95     /// ```rust
96     /// let hello_vec = vec![104, 101, 108, 108, 111];
97     /// let s = String::from_utf8(hello_vec);
98     /// assert_eq!(s, Ok("hello".to_string()));
99     ///
100     /// let invalid_vec = vec![240, 144, 128];
101     /// let s = String::from_utf8(invalid_vec);
102     /// assert_eq!(s, Err(vec![240, 144, 128]));
103     /// ```
104     #[inline]
105     #[unstable = "error type may change"]
106     pub fn from_utf8(vec: Vec<u8>) -> Result<String, Vec<u8>> {
107         if str::is_utf8(vec.as_slice()) {
108             Ok(String { vec: vec })
109         } else {
110             Err(vec)
111         }
112     }
113
114     /// Converts a vector of bytes to a new UTF-8 string.
115     /// Any invalid UTF-8 sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
116     ///
117     /// # Examples
118     ///
119     /// ```rust
120     /// let input = b"Hello \xF0\x90\x80World";
121     /// let output = String::from_utf8_lossy(input);
122     /// assert_eq!(output.as_slice(), "Hello \u{FFFD}World");
123     /// ```
124     #[unstable = "return type may change"]
125     pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> CowString<'a> {
126         if str::is_utf8(v) {
127             return Cow::Borrowed(unsafe { mem::transmute(v) })
128         }
129
130         static TAG_CONT_U8: u8 = 128u8;
131         static REPLACEMENT: &'static [u8] = b"\xEF\xBF\xBD"; // U+FFFD in UTF-8
132         let mut i = 0;
133         let total = v.len();
134         fn unsafe_get(xs: &[u8], i: uint) -> u8 {
135             unsafe { *xs.unsafe_get(i) }
136         }
137         fn safe_get(xs: &[u8], i: uint, total: uint) -> u8 {
138             if i >= total {
139                 0
140             } else {
141                 unsafe_get(xs, i)
142             }
143         }
144
145         let mut res = String::with_capacity(total);
146
147         if i > 0 {
148             unsafe {
149                 res.as_mut_vec().push_all(v[..i])
150             };
151         }
152
153         // subseqidx is the index of the first byte of the subsequence we're looking at.
154         // It's used to copy a bunch of contiguous good codepoints at once instead of copying
155         // them one by one.
156         let mut subseqidx = 0;
157
158         while i < total {
159             let i_ = i;
160             let byte = unsafe_get(v, i);
161             i += 1;
162
163             macro_rules! error(() => ({
164                 unsafe {
165                     if subseqidx != i_ {
166                         res.as_mut_vec().push_all(v[subseqidx..i_]);
167                     }
168                     subseqidx = i;
169                     res.as_mut_vec().push_all(REPLACEMENT);
170                 }
171             }));
172
173             if byte < 128u8 {
174                 // subseqidx handles this
175             } else {
176                 let w = str::utf8_char_width(byte);
177
178                 match w {
179                     2 => {
180                         if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
181                             error!();
182                             continue;
183                         }
184                         i += 1;
185                     }
186                     3 => {
187                         match (byte, safe_get(v, i, total)) {
188                             (0xE0         , 0xA0 ... 0xBF) => (),
189                             (0xE1 ... 0xEC, 0x80 ... 0xBF) => (),
190                             (0xED         , 0x80 ... 0x9F) => (),
191                             (0xEE ... 0xEF, 0x80 ... 0xBF) => (),
192                             _ => {
193                                 error!();
194                                 continue;
195                             }
196                         }
197                         i += 1;
198                         if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
199                             error!();
200                             continue;
201                         }
202                         i += 1;
203                     }
204                     4 => {
205                         match (byte, safe_get(v, i, total)) {
206                             (0xF0         , 0x90 ... 0xBF) => (),
207                             (0xF1 ... 0xF3, 0x80 ... 0xBF) => (),
208                             (0xF4         , 0x80 ... 0x8F) => (),
209                             _ => {
210                                 error!();
211                                 continue;
212                             }
213                         }
214                         i += 1;
215                         if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
216                             error!();
217                             continue;
218                         }
219                         i += 1;
220                         if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
221                             error!();
222                             continue;
223                         }
224                         i += 1;
225                     }
226                     _ => {
227                         error!();
228                         continue;
229                     }
230                 }
231             }
232         }
233         if subseqidx < total {
234             unsafe {
235                 res.as_mut_vec().push_all(v[subseqidx..total])
236             };
237         }
238         Cow::Owned(res.into_string())
239     }
240
241     /// Decode a UTF-16 encoded vector `v` into a `String`, returning `None`
242     /// if `v` contains any invalid data.
243     ///
244     /// # Examples
245     ///
246     /// ```rust
247     /// // 𝄞music
248     /// let mut v = &mut [0xD834, 0xDD1E, 0x006d, 0x0075,
249     ///                   0x0073, 0x0069, 0x0063];
250     /// assert_eq!(String::from_utf16(v), Some("𝄞music".to_string()));
251     ///
252     /// // 𝄞mu<invalid>ic
253     /// v[4] = 0xD800;
254     /// assert_eq!(String::from_utf16(v), None);
255     /// ```
256     #[unstable = "error value in return may change"]
257     pub fn from_utf16(v: &[u16]) -> Option<String> {
258         let mut s = String::with_capacity(v.len());
259         for c in str::utf16_items(v) {
260             match c {
261                 str::ScalarValue(c) => s.push(c),
262                 str::LoneSurrogate(_) => return None
263             }
264         }
265         Some(s)
266     }
267
268     /// Decode a UTF-16 encoded vector `v` into a string, replacing
269     /// invalid data with the replacement character (U+FFFD).
270     ///
271     /// # Examples
272     ///
273     /// ```rust
274     /// // 𝄞mus<invalid>ic<invalid>
275     /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
276     ///           0x0073, 0xDD1E, 0x0069, 0x0063,
277     ///           0xD834];
278     ///
279     /// assert_eq!(String::from_utf16_lossy(v),
280     ///            "𝄞mus\u{FFFD}ic\u{FFFD}".to_string());
281     /// ```
282     #[stable]
283     pub fn from_utf16_lossy(v: &[u16]) -> String {
284         str::utf16_items(v).map(|c| c.to_char_lossy()).collect()
285     }
286
287     /// Convert a vector of `char`s to a `String`.
288     ///
289     /// # Examples
290     ///
291     /// ```rust
292     /// let chars = &['h', 'e', 'l', 'l', 'o'];
293     /// let s = String::from_chars(chars);
294     /// assert_eq!(s.as_slice(), "hello");
295     /// ```
296     #[inline]
297     #[unstable = "may be removed in favor of .collect()"]
298     pub fn from_chars(chs: &[char]) -> String {
299         chs.iter().map(|c| *c).collect()
300     }
301
302     /// Creates a new `String` from a length, capacity, and pointer.
303     ///
304     /// This is unsafe because:
305     /// * We call `Vec::from_raw_parts` to get a `Vec<u8>`;
306     /// * We assume that the `Vec` contains valid UTF-8.
307     #[inline]
308     #[unstable = "function just moved from string::raw"]
309     pub unsafe fn from_raw_parts(buf: *mut u8, length: uint, capacity: uint) -> String {
310         String {
311             vec: Vec::from_raw_parts(buf, length, capacity),
312         }
313     }
314
315     /// Creates a `String` from a null-terminated `*const u8` buffer.
316     ///
317     /// This function is unsafe because we dereference memory until we find the
318     /// NUL character, which is not guaranteed to be present. Additionally, the
319     /// slice is not checked to see whether it contains valid UTF-8
320     #[unstable = "just renamed from `mod raw`"]
321     pub unsafe fn from_raw_buf(buf: *const u8) -> String {
322         String::from_str(str::from_c_str(buf as *const i8))
323     }
324
325     /// Creates a `String` from a `*const u8` buffer of the given length.
326     ///
327     /// This function is unsafe because it blindly assumes the validity of the
328     /// pointer `buf` for `len` bytes of memory. This function will copy the
329     /// memory from `buf` into a new allocation (owned by the returned
330     /// `String`).
331     ///
332     /// This function is also unsafe because it does not validate that the
333     /// buffer is valid UTF-8 encoded data.
334     #[unstable = "just renamed from `mod raw`"]
335     pub unsafe fn from_raw_buf_len(buf: *const u8, len: uint) -> String {
336         String::from_utf8_unchecked(Vec::from_raw_buf(buf, len))
337     }
338
339     /// Converts a vector of bytes to a new `String` without checking if
340     /// it contains valid UTF-8. This is unsafe because it assumes that
341     /// the UTF-8-ness of the vector has already been validated.
342     #[inline]
343     #[unstable = "awaiting stabilization"]
344     pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String {
345         String { vec: bytes }
346     }
347
348     /// Return the underlying byte buffer, encoded as UTF-8.
349     ///
350     /// # Examples
351     ///
352     /// ```
353     /// let s = String::from_str("hello");
354     /// let bytes = s.into_bytes();
355     /// assert_eq!(bytes, vec![104, 101, 108, 108, 111]);
356     /// ```
357     #[inline]
358     #[stable]
359     pub fn into_bytes(self) -> Vec<u8> {
360         self.vec
361     }
362
363     /// Creates a string buffer by repeating a character `length` times.
364     ///
365     /// # Examples
366     ///
367     /// ```
368     /// let s = String::from_char(5, 'a');
369     /// assert_eq!(s.as_slice(), "aaaaa");
370     /// ```
371     #[inline]
372     #[unstable = "may be replaced with iterators, questionable usability, and \
373                   the name may change"]
374     pub fn from_char(length: uint, ch: char) -> String {
375         if length == 0 {
376             return String::new()
377         }
378
379         let mut buf = String::new();
380         buf.push(ch);
381         let size = buf.len() * (length - 1);
382         buf.reserve_exact(size);
383         for _ in range(1, length) {
384             buf.push(ch)
385         }
386         buf
387     }
388
389     /// Pushes the given string onto this string buffer.
390     ///
391     /// # Examples
392     ///
393     /// ```
394     /// let mut s = String::from_str("foo");
395     /// s.push_str("bar");
396     /// assert_eq!(s.as_slice(), "foobar");
397     /// ```
398     #[inline]
399     #[unstable = "extra variants of `push`, could possibly be based on iterators"]
400     pub fn push_str(&mut self, string: &str) {
401         self.vec.push_all(string.as_bytes())
402     }
403
404     /// Pushes `ch` onto the given string `count` times.
405     ///
406     /// # Examples
407     ///
408     /// ```
409     /// let mut s = String::from_str("foo");
410     /// s.grow(5, 'Z');
411     /// assert_eq!(s.as_slice(), "fooZZZZZ");
412     /// ```
413     #[inline]
414     #[unstable = "duplicate of iterator-based functionality"]
415     pub fn grow(&mut self, count: uint, ch: char) {
416         for _ in range(0, count) {
417             self.push(ch)
418         }
419     }
420
421     /// Returns the number of bytes that this string buffer can hold without reallocating.
422     ///
423     /// # Examples
424     ///
425     /// ```
426     /// let s = String::with_capacity(10);
427     /// assert!(s.capacity() >= 10);
428     /// ```
429     #[inline]
430     #[unstable = "matches collection reform specification, waiting for dust to settle"]
431     pub fn capacity(&self) -> uint {
432         self.vec.capacity()
433     }
434
435     /// Deprecated: Renamed to `reserve`.
436     #[deprecated = "Renamed to `reserve`"]
437     pub fn reserve_additional(&mut self, extra: uint) {
438         self.vec.reserve(extra)
439     }
440
441     /// Reserves capacity for at least `additional` more bytes to be inserted in the given
442     /// `String`. The collection may reserve more space to avoid frequent reallocations.
443     ///
444     /// # Panics
445     ///
446     /// Panics if the new capacity overflows `uint`.
447     ///
448     /// # Examples
449     ///
450     /// ```
451     /// let mut s = String::new();
452     /// s.reserve(10);
453     /// assert!(s.capacity() >= 10);
454     /// ```
455     #[inline]
456     #[unstable = "matches collection reform specification, waiting for dust to settle"]
457     pub fn reserve(&mut self, additional: uint) {
458         self.vec.reserve(additional)
459     }
460
461     /// Reserves the minimum capacity for exactly `additional` more bytes to be inserted in the
462     /// given `String`. Does nothing if the capacity is already sufficient.
463     ///
464     /// Note that the allocator may give the collection more space than it requests. Therefore
465     /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future
466     /// insertions are expected.
467     ///
468     /// # Panics
469     ///
470     /// Panics if the new capacity overflows `uint`.
471     ///
472     /// # Examples
473     ///
474     /// ```
475     /// let mut s = String::new();
476     /// s.reserve(10);
477     /// assert!(s.capacity() >= 10);
478     /// ```
479     #[inline]
480     #[unstable = "matches collection reform specification, waiting for dust to settle"]
481     pub fn reserve_exact(&mut self, additional: uint) {
482         self.vec.reserve_exact(additional)
483     }
484
485     /// Shrinks the capacity of this string buffer to match its length.
486     ///
487     /// # Examples
488     ///
489     /// ```
490     /// let mut s = String::from_str("foo");
491     /// s.reserve(100);
492     /// assert!(s.capacity() >= 100);
493     /// s.shrink_to_fit();
494     /// assert_eq!(s.capacity(), 3);
495     /// ```
496     #[inline]
497     #[unstable = "matches collection reform specification, waiting for dust to settle"]
498     pub fn shrink_to_fit(&mut self) {
499         self.vec.shrink_to_fit()
500     }
501
502     /// Adds the given character to the end of the string.
503     ///
504     /// # Examples
505     ///
506     /// ```
507     /// let mut s = String::from_str("abc");
508     /// s.push('1');
509     /// s.push('2');
510     /// s.push('3');
511     /// assert_eq!(s.as_slice(), "abc123");
512     /// ```
513     #[inline]
514     #[stable = "function just renamed from push_char"]
515     pub fn push(&mut self, ch: char) {
516         if (ch as u32) < 0x80 {
517             self.vec.push(ch as u8);
518             return;
519         }
520
521         let cur_len = self.len();
522         // This may use up to 4 bytes.
523         self.vec.reserve(4);
524
525         unsafe {
526             // Attempt to not use an intermediate buffer by just pushing bytes
527             // directly onto this string.
528             let slice = RawSlice {
529                 data: self.vec.as_ptr().offset(cur_len as int),
530                 len: 4,
531             };
532             let used = ch.encode_utf8(mem::transmute(slice)).unwrap_or(0);
533             self.vec.set_len(cur_len + used);
534         }
535     }
536
537     /// Works with the underlying buffer as a byte slice.
538     ///
539     /// # Examples
540     ///
541     /// ```
542     /// let s = String::from_str("hello");
543     /// let b: &[_] = &[104, 101, 108, 108, 111];
544     /// assert_eq!(s.as_bytes(), b);
545     /// ```
546     #[inline]
547     #[stable]
548     pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
549         self.vec.as_slice()
550     }
551
552     /// Shortens a string to the specified length.
553     ///
554     /// # Panics
555     ///
556     /// Panics if `new_len` > current length,
557     /// or if `new_len` is not a character boundary.
558     ///
559     /// # Examples
560     ///
561     /// ```
562     /// let mut s = String::from_str("hello");
563     /// s.truncate(2);
564     /// assert_eq!(s.as_slice(), "he");
565     /// ```
566     #[inline]
567     #[unstable = "the panic conventions for strings are under development"]
568     pub fn truncate(&mut self, new_len: uint) {
569         assert!(self.is_char_boundary(new_len));
570         self.vec.truncate(new_len)
571     }
572
573     /// Removes the last character from the string buffer and returns it.
574     /// Returns `None` if this string buffer is empty.
575     ///
576     /// # Examples
577     ///
578     /// ```
579     /// let mut s = String::from_str("foo");
580     /// assert_eq!(s.pop(), Some('o'));
581     /// assert_eq!(s.pop(), Some('o'));
582     /// assert_eq!(s.pop(), Some('f'));
583     /// assert_eq!(s.pop(), None);
584     /// ```
585     #[inline]
586     #[unstable = "this function was just renamed from pop_char"]
587     pub fn pop(&mut self) -> Option<char> {
588         let len = self.len();
589         if len == 0 {
590             return None
591         }
592
593         let CharRange {ch, next} = self.char_range_at_reverse(len);
594         unsafe {
595             self.vec.set_len(next);
596         }
597         Some(ch)
598     }
599
600     /// Removes the character from the string buffer at byte position `idx` and
601     /// returns it. Returns `None` if `idx` is out of bounds.
602     ///
603     /// # Warning
604     ///
605     /// This is an O(n) operation as it requires copying every element in the
606     /// buffer.
607     ///
608     /// # Panics
609     ///
610     /// If `idx` does not lie on a character boundary, then this function will
611     /// panic.
612     ///
613     /// # Examples
614     ///
615     /// ```
616     /// let mut s = String::from_str("foo");
617     /// assert_eq!(s.remove(0), Some('f'));
618     /// assert_eq!(s.remove(1), Some('o'));
619     /// assert_eq!(s.remove(0), Some('o'));
620     /// assert_eq!(s.remove(0), None);
621     /// ```
622     #[unstable = "the panic semantics of this function and return type \
623                   may change"]
624     pub fn remove(&mut self, idx: uint) -> Option<char> {
625         let len = self.len();
626         if idx >= len { return None }
627
628         let CharRange { ch, next } = self.char_range_at(idx);
629         unsafe {
630             ptr::copy_memory(self.vec.as_mut_ptr().offset(idx as int),
631                              self.vec.as_ptr().offset(next as int),
632                              len - next);
633             self.vec.set_len(len - (next - idx));
634         }
635         Some(ch)
636     }
637
638     /// Insert a character into the string buffer at byte position `idx`.
639     ///
640     /// # Warning
641     ///
642     /// This is an O(n) operation as it requires copying every element in the
643     /// buffer.
644     ///
645     /// # Panics
646     ///
647     /// If `idx` does not lie on a character boundary or is out of bounds, then
648     /// this function will panic.
649     #[unstable = "the panic semantics of this function are uncertain"]
650     pub fn insert(&mut self, idx: uint, ch: char) {
651         let len = self.len();
652         assert!(idx <= len);
653         assert!(self.is_char_boundary(idx));
654         self.vec.reserve(4);
655         let mut bits = [0, ..4];
656         let amt = ch.encode_utf8(&mut bits).unwrap();
657
658         unsafe {
659             ptr::copy_memory(self.vec.as_mut_ptr().offset((idx + amt) as int),
660                              self.vec.as_ptr().offset(idx as int),
661                              len - idx);
662             ptr::copy_memory(self.vec.as_mut_ptr().offset(idx as int),
663                              bits.as_ptr(),
664                              amt);
665             self.vec.set_len(len + amt);
666         }
667     }
668
669     /// Views the string buffer as a mutable sequence of bytes.
670     ///
671     /// This is unsafe because it does not check
672     /// to ensure that the resulting string will be valid UTF-8.
673     ///
674     /// # Examples
675     ///
676     /// ```
677     /// let mut s = String::from_str("hello");
678     /// unsafe {
679     ///     let vec = s.as_mut_vec();
680     ///     assert!(vec == &mut vec![104, 101, 108, 108, 111]);
681     ///     vec.reverse();
682     /// }
683     /// assert_eq!(s.as_slice(), "olleh");
684     /// ```
685     #[unstable = "the name of this method may be changed"]
686     pub unsafe fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec<u8> {
687         &mut self.vec
688     }
689
690     /// Return the number of bytes in this string.
691     ///
692     /// # Examples
693     ///
694     /// ```
695     /// let a = "foo".to_string();
696     /// assert_eq!(a.len(), 3);
697     /// ```
698     #[inline]
699     #[stable]
700     pub fn len(&self) -> uint { self.vec.len() }
701
702     /// Returns true if the string contains no bytes
703     ///
704     /// # Examples
705     ///
706     /// ```
707     /// let mut v = String::new();
708     /// assert!(v.is_empty());
709     /// v.push('a');
710     /// assert!(!v.is_empty());
711     /// ```
712     pub fn is_empty(&self) -> bool { self.len() == 0 }
713
714     /// Truncates the string, returning it to 0 length.
715     ///
716     /// # Examples
717     ///
718     /// ```
719     /// let mut s = "foo".to_string();
720     /// s.clear();
721     /// assert!(s.is_empty());
722     /// ```
723     #[inline]
724     #[stable]
725     pub fn clear(&mut self) {
726         self.vec.clear()
727     }
728 }
729
730 #[experimental = "waiting on FromIterator stabilization"]
731 impl FromIterator<char> for String {
732     fn from_iter<I:Iterator<char>>(iterator: I) -> String {
733         let mut buf = String::new();
734         buf.extend(iterator);
735         buf
736     }
737 }
738
739 #[experimental = "waiting on FromIterator stabilization"]
740 impl<'a> FromIterator<&'a str> for String {
741     fn from_iter<I:Iterator<&'a str>>(iterator: I) -> String {
742         let mut buf = String::new();
743         buf.extend(iterator);
744         buf
745     }
746 }
747
748 #[experimental = "waiting on Extend stabilization"]
749 impl Extend<char> for String {
750     fn extend<I:Iterator<char>>(&mut self, mut iterator: I) {
751         let (lower_bound, _) = iterator.size_hint();
752         self.reserve(lower_bound);
753         for ch in iterator {
754             self.push(ch)
755         }
756     }
757 }
758
759 #[experimental = "waiting on Extend stabilization"]
760 impl<'a> Extend<&'a str> for String {
761     fn extend<I: Iterator<&'a str>>(&mut self, mut iterator: I) {
762         // A guess that at least one byte per iterator element will be needed.
763         let (lower_bound, _) = iterator.size_hint();
764         self.reserve(lower_bound);
765         for s in iterator {
766             self.push_str(s)
767         }
768     }
769 }
770
771 impl PartialEq for String {
772     #[inline]
773     fn eq(&self, other: &String) -> bool { PartialEq::eq(&**self, &**other) }
774     #[inline]
775     fn ne(&self, other: &String) -> bool { PartialEq::ne(&**self, &**other) }
776 }
777
778 macro_rules! impl_eq {
779     ($lhs:ty, $rhs: ty) => {
780         impl<'a> PartialEq<$rhs> for $lhs {
781             #[inline]
782             fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
783             #[inline]
784             fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
785         }
786
787         impl<'a> PartialEq<$lhs> for $rhs {
788             #[inline]
789             fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&**self, &**other) }
790             #[inline]
791             fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&**self, &**other) }
792         }
793
794     }
795 }
796
797 impl_eq! { String, &'a str }
798 impl_eq! { CowString<'a>, String }
799
800 impl<'a, 'b> PartialEq<&'b str> for CowString<'a> {
801     #[inline]
802     fn eq(&self, other: &&'b str) -> bool { PartialEq::eq(&**self, &**other) }
803     #[inline]
804     fn ne(&self, other: &&'b str) -> bool { PartialEq::ne(&**self, &**other) }
805 }
806
807 impl<'a, 'b> PartialEq<CowString<'a>> for &'b str {
808     #[inline]
809     fn eq(&self, other: &CowString<'a>) -> bool { PartialEq::eq(&**self, &**other) }
810     #[inline]
811     fn ne(&self, other: &CowString<'a>) -> bool { PartialEq::ne(&**self, &**other) }
812 }
813
814 #[experimental = "waiting on Str stabilization"]
815 impl Str for String {
816     #[inline]
817     #[stable]
818     fn as_slice<'a>(&'a self) -> &'a str {
819         unsafe {
820             mem::transmute(self.vec.as_slice())
821         }
822     }
823 }
824
825 #[experimental = "waiting on StrAllocating stabilization"]
826 impl StrAllocating for String {
827     #[inline]
828     fn into_string(self) -> String {
829         self
830     }
831 }
832
833 #[stable]
834 impl Default for String {
835     #[stable]
836     fn default() -> String {
837         String::new()
838     }
839 }
840
841 #[experimental = "waiting on Show stabilization"]
842 impl fmt::Show for String {
843     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
844         self.as_slice().fmt(f)
845     }
846 }
847
848 #[experimental = "waiting on Hash stabilization"]
849 impl<H: hash::Writer> hash::Hash<H> for String {
850     #[inline]
851     fn hash(&self, hasher: &mut H) {
852         self.as_slice().hash(hasher)
853     }
854 }
855
856 #[allow(deprecated)]
857 #[deprecated = "Use overloaded `core::cmp::PartialEq`"]
858 impl<'a, S: Str> Equiv<S> for String {
859     #[inline]
860     fn equiv(&self, other: &S) -> bool {
861         self.as_slice() == other.as_slice()
862     }
863 }
864
865 #[experimental = "waiting on Add stabilization"]
866 impl<'a> Add<&'a str, String> for String {
867     fn add(mut self, other: &str) -> String {
868         self.push_str(other);
869         self
870     }
871 }
872
873 impl ops::Slice<uint, str> for String {
874     #[inline]
875     fn as_slice_<'a>(&'a self) -> &'a str {
876         self.as_slice()
877     }
878
879     #[inline]
880     fn slice_from_or_fail<'a>(&'a self, from: &uint) -> &'a str {
881         self[][*from..]
882     }
883
884     #[inline]
885     fn slice_to_or_fail<'a>(&'a self, to: &uint) -> &'a str {
886         self[][..*to]
887     }
888
889     #[inline]
890     fn slice_or_fail<'a>(&'a self, from: &uint, to: &uint) -> &'a str {
891         self[][*from..*to]
892     }
893 }
894
895 #[experimental = "waiting on Deref stabilization"]
896 impl ops::Deref<str> for String {
897     fn deref<'a>(&'a self) -> &'a str { self.as_slice() }
898 }
899
900 /// Wrapper type providing a `&String` reference via `Deref`.
901 #[experimental]
902 pub struct DerefString<'a> {
903     x: DerefVec<'a, u8>
904 }
905
906 impl<'a> Deref<String> for DerefString<'a> {
907     fn deref<'b>(&'b self) -> &'b String {
908         unsafe { mem::transmute(&*self.x) }
909     }
910 }
911
912 /// Convert a string slice to a wrapper type providing a `&String` reference.
913 ///
914 /// # Examples
915 ///
916 /// ```
917 /// use std::string::as_string;
918 ///
919 /// fn string_consumer(s: String) {
920 ///     assert_eq!(s, "foo".to_string());
921 /// }
922 ///
923 /// let string = as_string("foo").clone();
924 /// string_consumer(string);
925 /// ```
926 #[experimental]
927 pub fn as_string<'a>(x: &'a str) -> DerefString<'a> {
928     DerefString { x: as_vec(x.as_bytes()) }
929 }
930
931 impl FromStr for String {
932     #[inline]
933     fn from_str(s: &str) -> Option<String> {
934         Some(String::from_str(s))
935     }
936 }
937
938 /// Trait for converting a type to a string, consuming it in the process.
939 pub trait IntoString {
940     /// Consume and convert to a string.
941     fn into_string(self) -> String;
942 }
943
944 /// A generic trait for converting a value to a string
945 pub trait ToString {
946     /// Converts the value of `self` to an owned string
947     fn to_string(&self) -> String;
948 }
949
950 impl<T: fmt::Show> ToString for T {
951     fn to_string(&self) -> String {
952         let mut buf = Vec::<u8>::new();
953         let _ = format_args!(|args| fmt::write(&mut buf, args), "{}", self);
954         String::from_utf8(buf).unwrap()
955     }
956 }
957
958 impl IntoCow<'static, String, str> for String {
959     fn into_cow(self) -> CowString<'static> {
960         Cow::Owned(self)
961     }
962 }
963
964 impl<'a> IntoCow<'a, String, str> for &'a str {
965     fn into_cow(self) -> CowString<'a> {
966         Cow::Borrowed(self)
967     }
968 }
969
970 /// Unsafe operations
971 #[deprecated]
972 pub mod raw {
973     use super::String;
974     use vec::Vec;
975
976     /// Creates a new `String` from a length, capacity, and pointer.
977     ///
978     /// This is unsafe because:
979     /// * We call `Vec::from_raw_parts` to get a `Vec<u8>`;
980     /// * We assume that the `Vec` contains valid UTF-8.
981     #[inline]
982     #[deprecated = "renamed to String::from_raw_parts"]
983     pub unsafe fn from_parts(buf: *mut u8, length: uint, capacity: uint) -> String {
984         String::from_raw_parts(buf, length, capacity)
985     }
986
987     /// Creates a `String` from a `*const u8` buffer of the given length.
988     ///
989     /// This function is unsafe because of two reasons:
990     ///
991     /// * A raw pointer is dereferenced and transmuted to `&[u8]`;
992     /// * The slice is not checked to see whether it contains valid UTF-8.
993     #[deprecated = "renamed to String::from_raw_buf_len"]
994     pub unsafe fn from_buf_len(buf: *const u8, len: uint) -> String {
995         String::from_raw_buf_len(buf, len)
996     }
997
998     /// Creates a `String` from a null-terminated `*const u8` buffer.
999     ///
1000     /// This function is unsafe because we dereference memory until we find the NUL character,
1001     /// which is not guaranteed to be present. Additionally, the slice is not checked to see
1002     /// whether it contains valid UTF-8
1003     #[deprecated = "renamed to String::from_raw_buf"]
1004     pub unsafe fn from_buf(buf: *const u8) -> String {
1005         String::from_raw_buf(buf)
1006     }
1007
1008     /// Converts a vector of bytes to a new `String` without checking if
1009     /// it contains valid UTF-8. This is unsafe because it assumes that
1010     /// the UTF-8-ness of the vector has already been validated.
1011     #[inline]
1012     #[deprecated = "renamed to String::from_utf8_unchecked"]
1013     pub unsafe fn from_utf8(bytes: Vec<u8>) -> String {
1014         String::from_utf8_unchecked(bytes)
1015     }
1016 }
1017
1018 #[cfg(test)]
1019 mod tests {
1020     use prelude::*;
1021     use test::Bencher;
1022
1023     use str;
1024     use super::as_string;
1025
1026     #[test]
1027     fn test_as_string() {
1028         let x = "foo";
1029         assert_eq!(x, as_string(x).as_slice());
1030     }
1031
1032     #[test]
1033     fn test_from_str() {
1034       let owned: Option<::std::string::String> = from_str("string");
1035       assert_eq!(owned.as_ref().map(|s| s.as_slice()), Some("string"));
1036     }
1037
1038     #[test]
1039     fn test_from_utf8() {
1040         let xs = b"hello".to_vec();
1041         assert_eq!(String::from_utf8(xs), Ok(String::from_str("hello")));
1042
1043         let xs = "ศไทย中华Việt Nam".as_bytes().to_vec();
1044         assert_eq!(String::from_utf8(xs), Ok(String::from_str("ศไทย中华Việt Nam")));
1045
1046         let xs = b"hello\xFF".to_vec();
1047         assert_eq!(String::from_utf8(xs),
1048                    Err(b"hello\xFF".to_vec()));
1049     }
1050
1051     #[test]
1052     fn test_from_utf8_lossy() {
1053         let xs = b"hello";
1054         let ys: str::CowString = "hello".into_cow();
1055         assert_eq!(String::from_utf8_lossy(xs), ys);
1056
1057         let xs = "ศไทย中华Việt Nam".as_bytes();
1058         let ys: str::CowString = "ศไทย中华Việt Nam".into_cow();
1059         assert_eq!(String::from_utf8_lossy(xs), ys);
1060
1061         let xs = b"Hello\xC2 There\xFF Goodbye";
1062         assert_eq!(String::from_utf8_lossy(xs),
1063                    String::from_str("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow());
1064
1065         let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
1066         assert_eq!(String::from_utf8_lossy(xs),
1067                    String::from_str("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow());
1068
1069         let xs = b"\xF5foo\xF5\x80bar";
1070         assert_eq!(String::from_utf8_lossy(xs),
1071                    String::from_str("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow());
1072
1073         let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
1074         assert_eq!(String::from_utf8_lossy(xs),
1075                    String::from_str("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow());
1076
1077         let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
1078         assert_eq!(String::from_utf8_lossy(xs),
1079                    String::from_str("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow());
1080
1081         let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
1082         assert_eq!(String::from_utf8_lossy(xs), String::from_str("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}\
1083                                                foo\u{10000}bar").into_cow());
1084
1085         // surrogates
1086         let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
1087         assert_eq!(String::from_utf8_lossy(xs), String::from_str("\u{FFFD}\u{FFFD}\u{FFFD}foo\
1088                                                \u{FFFD}\u{FFFD}\u{FFFD}bar").into_cow());
1089     }
1090
1091     #[test]
1092     fn test_from_utf16() {
1093         let pairs =
1094             [(String::from_str("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
1095               vec![0xd800_u16, 0xdf45_u16, 0xd800_u16, 0xdf3f_u16,
1096                 0xd800_u16, 0xdf3b_u16, 0xd800_u16, 0xdf46_u16,
1097                 0xd800_u16, 0xdf39_u16, 0xd800_u16, 0xdf3b_u16,
1098                 0xd800_u16, 0xdf30_u16, 0x000a_u16]),
1099
1100              (String::from_str("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
1101               vec![0xd801_u16, 0xdc12_u16, 0xd801_u16,
1102                 0xdc49_u16, 0xd801_u16, 0xdc2e_u16, 0xd801_u16,
1103                 0xdc40_u16, 0xd801_u16, 0xdc32_u16, 0xd801_u16,
1104                 0xdc4b_u16, 0x0020_u16, 0xd801_u16, 0xdc0f_u16,
1105                 0xd801_u16, 0xdc32_u16, 0xd801_u16, 0xdc4d_u16,
1106                 0x000a_u16]),
1107
1108              (String::from_str("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
1109               vec![0xd800_u16, 0xdf00_u16, 0xd800_u16, 0xdf16_u16,
1110                 0xd800_u16, 0xdf0b_u16, 0xd800_u16, 0xdf04_u16,
1111                 0xd800_u16, 0xdf11_u16, 0xd800_u16, 0xdf09_u16,
1112                 0x00b7_u16, 0xd800_u16, 0xdf0c_u16, 0xd800_u16,
1113                 0xdf04_u16, 0xd800_u16, 0xdf15_u16, 0xd800_u16,
1114                 0xdf04_u16, 0xd800_u16, 0xdf0b_u16, 0xd800_u16,
1115                 0xdf09_u16, 0xd800_u16, 0xdf11_u16, 0x000a_u16 ]),
1116
1117              (String::from_str("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
1118               vec![0xd801_u16, 0xdc8b_u16, 0xd801_u16, 0xdc98_u16,
1119                 0xd801_u16, 0xdc88_u16, 0xd801_u16, 0xdc91_u16,
1120                 0xd801_u16, 0xdc9b_u16, 0xd801_u16, 0xdc92_u16,
1121                 0x0020_u16, 0xd801_u16, 0xdc95_u16, 0xd801_u16,
1122                 0xdc93_u16, 0x0020_u16, 0xd801_u16, 0xdc88_u16,
1123                 0xd801_u16, 0xdc9a_u16, 0xd801_u16, 0xdc8d_u16,
1124                 0x0020_u16, 0xd801_u16, 0xdc8f_u16, 0xd801_u16,
1125                 0xdc9c_u16, 0xd801_u16, 0xdc92_u16, 0xd801_u16,
1126                 0xdc96_u16, 0xd801_u16, 0xdc86_u16, 0x0020_u16,
1127                 0xd801_u16, 0xdc95_u16, 0xd801_u16, 0xdc86_u16,
1128                 0x000a_u16 ]),
1129              // Issue #12318, even-numbered non-BMP planes
1130              (String::from_str("\u{20000}"),
1131               vec![0xD840, 0xDC00])];
1132
1133         for p in pairs.iter() {
1134             let (s, u) = (*p).clone();
1135             let s_as_utf16 = s.utf16_units().collect::<Vec<u16>>();
1136             let u_as_string = String::from_utf16(u.as_slice()).unwrap();
1137
1138             assert!(str::is_utf16(u.as_slice()));
1139             assert_eq!(s_as_utf16, u);
1140
1141             assert_eq!(u_as_string, s);
1142             assert_eq!(String::from_utf16_lossy(u.as_slice()), s);
1143
1144             assert_eq!(String::from_utf16(s_as_utf16.as_slice()).unwrap(), s);
1145             assert_eq!(u_as_string.utf16_units().collect::<Vec<u16>>(), u);
1146         }
1147     }
1148
1149     #[test]
1150     fn test_utf16_invalid() {
1151         // completely positive cases tested above.
1152         // lead + eof
1153         assert_eq!(String::from_utf16(&[0xD800]), None);
1154         // lead + lead
1155         assert_eq!(String::from_utf16(&[0xD800, 0xD800]), None);
1156
1157         // isolated trail
1158         assert_eq!(String::from_utf16(&[0x0061, 0xDC00]), None);
1159
1160         // general
1161         assert_eq!(String::from_utf16(&[0xD800, 0xd801, 0xdc8b, 0xD800]), None);
1162     }
1163
1164     #[test]
1165     fn test_from_utf16_lossy() {
1166         // completely positive cases tested above.
1167         // lead + eof
1168         assert_eq!(String::from_utf16_lossy(&[0xD800]), String::from_str("\u{FFFD}"));
1169         // lead + lead
1170         assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]),
1171                    String::from_str("\u{FFFD}\u{FFFD}"));
1172
1173         // isolated trail
1174         assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]), String::from_str("a\u{FFFD}"));
1175
1176         // general
1177         assert_eq!(String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]),
1178                    String::from_str("\u{FFFD}𐒋\u{FFFD}"));
1179     }
1180
1181     #[test]
1182     fn test_from_buf_len() {
1183         unsafe {
1184             let a = vec![65u8, 65, 65, 65, 65, 65, 65, 0];
1185             assert_eq!(super::raw::from_buf_len(a.as_ptr(), 3), String::from_str("AAA"));
1186         }
1187     }
1188
1189     #[test]
1190     fn test_from_buf() {
1191         unsafe {
1192             let a = vec![65, 65, 65, 65, 65, 65, 65, 0];
1193             let b = a.as_ptr();
1194             let c = super::raw::from_buf(b);
1195             assert_eq!(c, String::from_str("AAAAAAA"));
1196         }
1197     }
1198
1199     #[test]
1200     fn test_push_bytes() {
1201         let mut s = String::from_str("ABC");
1202         unsafe {
1203             let mv = s.as_mut_vec();
1204             mv.push_all(&[b'D']);
1205         }
1206         assert_eq!(s, "ABCD");
1207     }
1208
1209     #[test]
1210     fn test_push_str() {
1211         let mut s = String::new();
1212         s.push_str("");
1213         assert_eq!(s.slice_from(0), "");
1214         s.push_str("abc");
1215         assert_eq!(s.slice_from(0), "abc");
1216         s.push_str("ประเทศไทย中华Việt Nam");
1217         assert_eq!(s.slice_from(0), "abcประเทศไทย中华Việt Nam");
1218     }
1219
1220     #[test]
1221     fn test_push() {
1222         let mut data = String::from_str("ประเทศไทย中");
1223         data.push('华');
1224         data.push('b'); // 1 byte
1225         data.push('¢'); // 2 byte
1226         data.push('€'); // 3 byte
1227         data.push('𤭢'); // 4 byte
1228         assert_eq!(data, "ประเทศไทย中华b¢€𤭢");
1229     }
1230
1231     #[test]
1232     fn test_pop() {
1233         let mut data = String::from_str("ประเทศไทย中华b¢€𤭢");
1234         assert_eq!(data.pop().unwrap(), '𤭢'); // 4 bytes
1235         assert_eq!(data.pop().unwrap(), '€'); // 3 bytes
1236         assert_eq!(data.pop().unwrap(), '¢'); // 2 bytes
1237         assert_eq!(data.pop().unwrap(), 'b'); // 1 bytes
1238         assert_eq!(data.pop().unwrap(), '华');
1239         assert_eq!(data, "ประเทศไทย中");
1240     }
1241
1242     #[test]
1243     fn test_str_truncate() {
1244         let mut s = String::from_str("12345");
1245         s.truncate(5);
1246         assert_eq!(s, "12345");
1247         s.truncate(3);
1248         assert_eq!(s, "123");
1249         s.truncate(0);
1250         assert_eq!(s, "");
1251
1252         let mut s = String::from_str("12345");
1253         let p = s.as_ptr();
1254         s.truncate(3);
1255         s.push_str("6");
1256         let p_ = s.as_ptr();
1257         assert_eq!(p_, p);
1258     }
1259
1260     #[test]
1261     #[should_fail]
1262     fn test_str_truncate_invalid_len() {
1263         let mut s = String::from_str("12345");
1264         s.truncate(6);
1265     }
1266
1267     #[test]
1268     #[should_fail]
1269     fn test_str_truncate_split_codepoint() {
1270         let mut s = String::from_str("\u{FC}"); // ü
1271         s.truncate(1);
1272     }
1273
1274     #[test]
1275     fn test_str_clear() {
1276         let mut s = String::from_str("12345");
1277         s.clear();
1278         assert_eq!(s.len(), 0);
1279         assert_eq!(s, "");
1280     }
1281
1282     #[test]
1283     fn test_str_add() {
1284         let a = String::from_str("12345");
1285         let b = a + "2";
1286         let b = b + "2";
1287         assert_eq!(b.len(), 7);
1288         assert_eq!(b, "1234522");
1289     }
1290
1291     #[test]
1292     fn remove() {
1293         let mut s = "ศไทย中华Việt Nam; foobar".to_string();;
1294         assert_eq!(s.remove(0), Some('ศ'));
1295         assert_eq!(s.len(), 33);
1296         assert_eq!(s, "ไทย中华Việt Nam; foobar");
1297         assert_eq!(s.remove(33), None);
1298         assert_eq!(s.remove(300), None);
1299         assert_eq!(s.remove(17), Some('ệ'));
1300         assert_eq!(s, "ไทย中华Vit Nam; foobar");
1301     }
1302
1303     #[test] #[should_fail]
1304     fn remove_bad() {
1305         "ศ".to_string().remove(1);
1306     }
1307
1308     #[test]
1309     fn insert() {
1310         let mut s = "foobar".to_string();
1311         s.insert(0, 'ệ');
1312         assert_eq!(s, "ệfoobar");
1313         s.insert(6, 'ย');
1314         assert_eq!(s, "ệfooยbar");
1315     }
1316
1317     #[test] #[should_fail] fn insert_bad1() { "".to_string().insert(1, 't'); }
1318     #[test] #[should_fail] fn insert_bad2() { "ệ".to_string().insert(1, 't'); }
1319
1320     #[test]
1321     fn test_slicing() {
1322         let s = "foobar".to_string();
1323         assert_eq!("foobar", s[]);
1324         assert_eq!("foo", s[..3]);
1325         assert_eq!("bar", s[3..]);
1326         assert_eq!("oob", s[1..4]);
1327     }
1328
1329     #[test]
1330     fn test_simple_types() {
1331         assert_eq!(1i.to_string(), "1");
1332         assert_eq!((-1i).to_string(), "-1");
1333         assert_eq!(200u.to_string(), "200");
1334         assert_eq!(2u8.to_string(), "2");
1335         assert_eq!(true.to_string(), "true");
1336         assert_eq!(false.to_string(), "false");
1337         assert_eq!(().to_string(), "()");
1338         assert_eq!(("hi".to_string()).to_string(), "hi");
1339     }
1340
1341     #[test]
1342     fn test_vectors() {
1343         let x: Vec<int> = vec![];
1344         assert_eq!(x.to_string(), "[]");
1345         assert_eq!((vec![1i]).to_string(), "[1]");
1346         assert_eq!((vec![1i, 2, 3]).to_string(), "[1, 2, 3]");
1347         assert!((vec![vec![], vec![1i], vec![1i, 1]]).to_string() ==
1348                "[[], [1], [1, 1]]");
1349     }
1350
1351     #[test]
1352     fn test_from_iterator() {
1353         let s = "ศไทย中华Việt Nam".to_string();
1354         let t = "ศไทย中华";
1355         let u = "Việt Nam";
1356
1357         let a: String = s.chars().collect();
1358         assert_eq!(s, a);
1359
1360         let mut b = t.to_string();
1361         b.extend(u.chars());
1362         assert_eq!(s, b);
1363
1364         let c: String = vec![t, u].into_iter().collect();
1365         assert_eq!(s, c);
1366
1367         let mut d = t.to_string();
1368         d.extend(vec![u].into_iter());
1369         assert_eq!(s, d);
1370     }
1371
1372     #[bench]
1373     fn bench_with_capacity(b: &mut Bencher) {
1374         b.iter(|| {
1375             String::with_capacity(100)
1376         });
1377     }
1378
1379     #[bench]
1380     fn bench_push_str(b: &mut Bencher) {
1381         let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1382         b.iter(|| {
1383             let mut r = String::new();
1384             r.push_str(s);
1385         });
1386     }
1387
1388     const REPETITIONS: u64 = 10_000;
1389
1390     #[bench]
1391     fn bench_push_str_one_byte(b: &mut Bencher) {
1392         b.bytes = REPETITIONS;
1393         b.iter(|| {
1394             let mut r = String::new();
1395             for _ in range(0, REPETITIONS) {
1396                 r.push_str("a")
1397             }
1398         });
1399     }
1400
1401     #[bench]
1402     fn bench_push_char_one_byte(b: &mut Bencher) {
1403         b.bytes = REPETITIONS;
1404         b.iter(|| {
1405             let mut r = String::new();
1406             for _ in range(0, REPETITIONS) {
1407                 r.push('a')
1408             }
1409         });
1410     }
1411
1412     #[bench]
1413     fn bench_push_char_two_bytes(b: &mut Bencher) {
1414         b.bytes = REPETITIONS * 2;
1415         b.iter(|| {
1416             let mut r = String::new();
1417             for _ in range(0, REPETITIONS) {
1418                 r.push('â')
1419             }
1420         });
1421     }
1422
1423     #[bench]
1424     fn from_utf8_lossy_100_ascii(b: &mut Bencher) {
1425         let s = b"Hello there, the quick brown fox jumped over the lazy dog! \
1426                   Lorem ipsum dolor sit amet, consectetur. ";
1427
1428         assert_eq!(100, s.len());
1429         b.iter(|| {
1430             let _ = String::from_utf8_lossy(s);
1431         });
1432     }
1433
1434     #[bench]
1435     fn from_utf8_lossy_100_multibyte(b: &mut Bencher) {
1436         let s = "𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰".as_bytes();
1437         assert_eq!(100, s.len());
1438         b.iter(|| {
1439             let _ = String::from_utf8_lossy(s);
1440         });
1441     }
1442
1443     #[bench]
1444     fn from_utf8_lossy_invalid(b: &mut Bencher) {
1445         let s = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
1446         b.iter(|| {
1447             let _ = String::from_utf8_lossy(s);
1448         });
1449     }
1450
1451     #[bench]
1452     fn from_utf8_lossy_100_invalid(b: &mut Bencher) {
1453         let s = Vec::from_elem(100, 0xF5u8);
1454         b.iter(|| {
1455             let _ = String::from_utf8_lossy(s.as_slice());
1456         });
1457     }
1458 }