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