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