Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  string.rs   Sprache: unbekannt

 
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A UTF-8 encoded, growable string.
//!
//! This module contains the [`String`] type and several error types that may
//! result from working with [`String`]s.
//!
//! This module is a fork of the [`std::string`] module, that uses a bump allocator.
//!
//! [`std::string`]: https://doc.rust-lang.org/std/string/index.html
//!
//! # Examples
//!
//! You can create a new [`String`] from a string literal with [`String::from_str_in`]:
//!
//! ```
//! use bumpalo::{Bump, collections::String};
//!
//! let b = Bump::new();
//!
//! let s = String::from_str_in("world", &b);
//! ```
//!
//! [`String`]: struct.String.html
//! [`String::from_str_in`]: struct.String.html#method.from_str_in
//!
//! If you have a vector of valid UTF-8 bytes, you can make a [`String`] out of
//! it. You can do the reverse too.
//!
//! ```
//! use bumpalo::{Bump, collections::String};
//!
//! let b = Bump::new();
//!
//! let sparkle_heart = bumpalo::vec![in &b; 240, 159, 146, 150];
//!
//! // We know these bytes are valid, so we'll use `unwrap()`.
//! let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();
//!
//! assert_eq!("��", sparkle_heart);
//!
//! let bytes = sparkle_heart.into_bytes();
//!
//! assert_eq!(bytes, [240, 159, 146, 150]);
//! ```

use crate::collections::str::lossy;
use crate::collections::vec::Vec;
use crate::Bump;
use core::borrow::{Borrow, BorrowMut};
use core::char::decode_utf16;
use core::fmt;
use core::hash;
use core::iter::FusedIterator;
use core::mem;
use core::ops::Bound::{Excluded, Included, Unbounded};
use core::ops::{self, Add, AddAssign, Index, IndexMut, RangeBounds};
use core::ptr;
use core::str::{self, Chars, Utf8Error};
use core_alloc::borrow::Cow;

/// Like the [`format!`] macro, but for creating [`bumpalo::collections::String`]s.
///
/// [`format!`]: https://doc.rust-lang.org/std/macro.format.html
/// [`bumpalo::collections::String`]: collections/string/struct.String.html
///
/// # Examples
///
/// ```
/// use bumpalo::Bump;
///
/// let b = Bump::new();
///
/// let who = "World";
/// let s = bumpalo::format!(in &b, "Hello, {}!", who);
/// assert_eq!(s, "Hello, World!")
/// ```
#[macro_export]
macro_rules! format {
    ( in $bump:expr, $fmt:expr, $($args:expr),* ) => {{
        use $crate::core_alloc::fmt::Write;
        let bump = $bump;
        let mut s = $crate::collections::String::new_in(bump);
        let _ = write!(&mut s, $fmt, $($args),*);
        s
    }};

    ( in $bump:expr, $fmt:expr, $($args:expr,)* ) => {
        $crate::format!(in $bump, $fmt, $($args),*)
    };
}

/// A UTF-8 encoded, growable string.
///
/// The `String` type is the most common string type that has ownership over the
/// contents of the string. It has a close relationship with its borrowed
/// counterpart, the primitive [`str`].
///
/// [`str`]: https://doc.rust-lang.org/std/primitive.str.html
///
/// # Examples
///
/// You can create a `String` from a literal string with [`String::from_str_in`]:
///
/// ```
/// use bumpalo::{Bump, collections::String};
///
/// let b = Bump::new();
///
/// let hello = String::from_str_in("Hello, world!", &b);
/// ```
///
/// You can append a [`char`] to a `String` with the [`push`] method, and
/// append a [`&str`] with the [`push_str`] method:
///
/// ```
/// use bumpalo::{Bump, collections::String};
///
/// let b = Bump::new();
///
/// let mut hello = String::from_str_in("Hello, ", &b);
///
/// hello.push('w');
/// hello.push_str("orld!");
/// ```
///
/// [`char`]: https://doc.rust-lang.org/std/primitive.char.html
/// [`push`]: #method.push
/// [`push_str`]: #method.push_str
///
/// If you have a vector of UTF-8 bytes, you can create a `String` from it with
/// the [`from_utf8`] method:
///
/// ```
/// use bumpalo::{Bump, collections::String};
///
/// let b = Bump::new();
///
/// // some bytes, in a vector
/// let sparkle_heart = bumpalo::vec![in &b; 240, 159, 146, 150];
///
/// // We know these bytes are valid, so we'll use `unwrap()`.
/// let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();
///
/// assert_eq!("��", sparkle_heart);
/// ```
///
/// [`from_utf8`]: #method.from_utf8
///
/// # Deref
///
/// `String`s implement <code>[`Deref`]<Target = [`str`]></code>, and so inherit all of [`str`]'s
/// methods. In addition, this means that you can pass a `String` to a
/// function which takes a [`&str`] by using an ampersand (`&`):
///
/// ```
/// use bumpalo::{Bump, collections::String};
///
/// let b = Bump::new();
///
/// fn takes_str(s: &str) { }
///
/// let s = String::from_str_in("Hello", &b);
///
/// takes_str(&s);
/// ```
///
/// This will create a [`&str`] from the `String` and pass it in. This
/// conversion is very inexpensive, and so generally, functions will accept
/// [`&str`]s as arguments unless they need a `String` for some specific
/// reason.
///
/// In certain cases Rust doesn't have enough information to make this
/// conversion, known as [`Deref`] coercion. In the following example a string
/// slice [`&'a str`][`&str`] implements the trait `TraitExample`, and the function
/// `example_func` takes anything that implements the trait. In this case Rust
/// would need to make two implicit conversions, which Rust doesn't have the
/// means to do. For that reason, the following example will not compile.
///
/// ```compile_fail,E0277
/// use bumpalo::{Bump, collections::String};
///
/// trait TraitExample {}
///
/// impl<'a> TraitExample for &'a str {}
///
/// fn example_func<A: TraitExample>(example_arg: A) {}
///
/// let b = Bump::new();
/// let example_string = String::from_str_in("example_string", &b);
/// example_func(&example_string);
/// ```
///
/// There are two options that would work instead. The first would be to
/// change the line `example_func(&example_string);` to
/// `example_func(example_string.as_str());`, using the method [`as_str()`]
/// to explicitly extract the string slice containing the string. The second
/// way changes `example_func(&example_string);` to
/// `example_func(&*example_string);`. In this case we are dereferencing a
/// `String` to a [`str`][`&str`], then referencing the [`str`][`&str`] back to
/// [`&str`]. The second way is more idiomatic, however both work to do the
/// conversion explicitly rather than relying on the implicit conversion.
///
/// # Representation
///
/// A `String` is made up of three components: a pointer to some bytes, a
/// length, and a capacity. The pointer points to an internal buffer `String`
/// uses to store its data. The length is the number of bytes currently stored
/// in the buffer, and the capacity is the size of the buffer in bytes. As such,
/// the length will always be less than or equal to the capacity.
///
/// This buffer is always stored on the heap.
///
/// You can look at these with the [`as_ptr`], [`len`], and [`capacity`]
/// methods:
///
/// ```
/// use bumpalo::{Bump, collections::String};
/// use std::mem;
///
/// let b = Bump::new();
///
/// let mut story = String::from_str_in("Once upon a time...", &b);
///
/// let ptr = story.as_mut_ptr();
/// let len = story.len();
/// let capacity = story.capacity();
///
/// // story has nineteen bytes
/// assert_eq!(19, len);
///
/// // Now that we have our parts, we throw the story away.
/// mem::forget(story);
///
/// // We can re-build a String out of ptr, len, and capacity. This is all
/// // unsafe because we are responsible for making sure the components are
/// // valid:
/// let s = unsafe { String::from_raw_parts_in(ptr, len, capacity, &b) } ;
///
/// assert_eq!(String::from_str_in("Once upon a time...", &b), s);
/// ```
///
/// [`as_ptr`]: https://doc.rust-lang.org/std/primitive.str.html#method.as_ptr
/// [`len`]: #method.len
/// [`capacity`]: #method.capacity
///
/// If a `String` has enough capacity, adding elements to it will not
/// re-allocate. For example, consider this program:
///
/// ```
/// use bumpalo::{Bump, collections::String};
///
/// let b = Bump::new();
///
/// let mut s = String::new_in(&b);
///
/// println!("{}", s.capacity());
///
/// for _ in 0..5 {
///     s.push_str("hello");
///     println!("{}", s.capacity());
/// }
/// ```
///
/// This will output the following:
///
/// ```text
/// 0
/// 5
/// 10
/// 20
/// 20
/// 40
/// ```
///
/// At first, we have no memory allocated at all, but as we append to the
/// string, it increases its capacity appropriately. If we instead use the
/// [`with_capacity_in`] method to allocate the correct capacity initially:
///
/// ```
/// use bumpalo::{Bump, collections::String};
///
/// let b = Bump::new();
///
/// let mut s = String::with_capacity_in(25, &b);
///
/// println!("{}", s.capacity());
///
/// for _ in 0..5 {
///     s.push_str("hello");
///     println!("{}", s.capacity());
/// }
/// ```
///
/// [`with_capacity_in`]: #method.with_capacity_in
///
/// We end up with a different output:
///
/// ```text
/// 25
/// 25
/// 25
/// 25
/// 25
/// 25
/// ```
///
/// Here, there's no need to allocate more memory inside the loop.
///
/// [`&str`]: https://doc.rust-lang.org/std/primitive.str.html
/// [`Deref`]: https://doc.rust-lang.org/std/ops/trait.Deref.html
/// [`as_str()`]: struct.String.html#method.as_str
#[derive(PartialOrd, Eq, Ord)]
pub struct String<'bump> {
    vec: Vec<'bump, u8>,
}

/// A possible error value when converting a `String` from a UTF-8 byte vector.
///
/// This type is the error type for the [`from_utf8`] method on [`String`]. It
/// is designed in such a way to carefully avoid reallocations: the
/// [`into_bytes`] method will give back the byte vector that was used in the
/// conversion attempt.
///
/// [`from_utf8`]: struct.String.html#method.from_utf8
/// [`String`]: struct.String.html
/// [`into_bytes`]: struct.FromUtf8Error.html#method.into_bytes
///
/// The [`Utf8Error`] type provided by [`std::str`] represents an error that may
/// occur when converting a slice of [`u8`]s to a [`&str`]. In this sense, it's
/// an analogue to `FromUtf8Error`, and you can get one from a `FromUtf8Error`
/// through the [`utf8_error`] method.
///
/// [`Utf8Error`]: https://doc.rust-lang.org/std/str/struct.Utf8Error.html
/// [`std::str`]: https://doc.rust-lang.org/std/str/index.html
/// [`u8`]: https://doc.rust-lang.org/std/primitive.u8.html
/// [`&str`]: https://doc.rust-lang.org/std/primitive.str.html
/// [`utf8_error`]: #method.utf8_error
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use bumpalo::{Bump, collections::String};
///
/// let b = Bump::new();
///
/// // some invalid bytes, in a vector
/// let bytes = bumpalo::vec![in &b; 0, 159];
///
/// let value = String::from_utf8(bytes);
///
/// assert!(value.is_err());
/// assert_eq!(bumpalo::vec![in &b; 0, 159], value.unwrap_err().into_bytes());
/// ```
#[derive(Debug)]
pub struct FromUtf8Error<'bump> {
    bytes: Vec<'bump, u8>,
    error: Utf8Error,
}

/// A possible error value when converting a `String` from a UTF-16 byte slice.
///
/// This type is the error type for the [`from_utf16_in`] method on [`String`].
///
/// [`from_utf16_in`]: struct.String.html#method.from_utf16_in
/// [`String`]: struct.String.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use bumpalo::{Bump, collections::String};
///
/// let b = Bump::new();
///
/// // ��mu<invalid>ic
/// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075, 0xD800, 0x0069, 0x0063];
///
/// assert!(String::from_utf16_in(v, &b).is_err());
/// ```
#[derive(Debug)]
pub struct FromUtf16Error(());

impl<'bump> String<'bump> {
    /// Creates a new empty `String`.
    ///
    /// Given that the `String` is empty, this will not allocate any initial
    /// buffer. While that means that this initial operation is very
    /// inexpensive, it may cause excessive allocation later when you add
    /// data. If you have an idea of how much data the `String` will hold,
    /// consider the [`with_capacity_in`] method to prevent excessive
    /// re-allocation.
    ///
    /// [`with_capacity_in`]: #method.with_capacity_in
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let s = String::new_in(&b);
    /// ```
    #[inline]
    pub fn new_in(bump: &'bump Bump) -> String<'bump> {
        String {
            vec: Vec::new_in(bump),
        }
    }

    /// Creates a new empty `String` with a particular capacity.
    ///
    /// `String`s have an internal buffer to hold their data. The capacity is
    /// the length of that buffer, and can be queried with the [`capacity`]
    /// method. This method creates an empty `String`, but one with an initial
    /// buffer that can hold `capacity` bytes. This is useful when you may be
    /// appending a bunch of data to the `String`, reducing the number of
    /// reallocations it needs to do.
    ///
    /// [`capacity`]: #method.capacity
    ///
    /// If the given capacity is `0`, no allocation will occur, and this method
    /// is identical to the [`new_in`] method.
    ///
    /// [`new_in`]: #method.new
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut s = String::with_capacity_in(10, &b);
    ///
    /// // The String contains no chars, even though it has capacity for more
    /// assert_eq!(s.len(), 0);
    ///
    /// // These are all done without reallocating...
    /// let cap = s.capacity();
    /// for _ in 0..10 {
    ///     s.push('a');
    /// }
    ///
    /// assert_eq!(s.capacity(), cap);
    ///
    /// // ...but this may make the vector reallocate
    /// s.push('a');
    /// ```
    #[inline]
    pub fn with_capacity_in(capacity: usize, bump: &'bump Bump) -> String<'bump> {
        String {
            vec: Vec::with_capacity_in(capacity, bump),
        }
    }

    /// Converts a vector of bytes to a `String`.
    ///
    /// A string (`String`) is made of bytes ([`u8`]), and a vector of bytes
    /// ([`Vec<u8>`]) is made of bytes, so this function converts between the
    /// two. Not all byte slices are valid `String`s, however: `String`
    /// requires that it is valid UTF-8. `from_utf8()` checks to ensure that
    /// the bytes are valid UTF-8, and then does the conversion.
    ///
    /// If you are sure that the byte slice is valid UTF-8, and you don't want
    /// to incur the overhead of the validity check, there is an unsafe version
    /// of this function, [`from_utf8_unchecked`], which has the same behavior
    /// but skips the check.
    ///
    /// This method will take care to not copy the vector, for efficiency's
    /// sake.
    ///
    /// If you need a [`&str`] instead of a `String`, consider
    /// [`str::from_utf8`].
    ///
    /// The inverse of this method is [`into_bytes`].
    ///
    /// # Errors
    ///
    /// Returns [`Err`] if the slice is not UTF-8 with a description as to why the
    /// provided bytes are not UTF-8. The vector you moved in is also included.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// // some bytes, in a vector
    /// let sparkle_heart = bumpalo::vec![in &b; 240, 159, 146, 150];
    ///
    /// // We know these bytes are valid, so we'll use `unwrap()`.
    /// let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();
    ///
    /// assert_eq!("��", sparkle_heart);
    /// ```
    ///
    /// Incorrect bytes:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// // some invalid bytes, in a vector
    /// let sparkle_heart = bumpalo::vec![in &b; 0, 159, 146, 150];
    ///
    /// assert!(String::from_utf8(sparkle_heart).is_err());
    /// ```
    ///
    /// See the docs for [`FromUtf8Error`] for more details on what you can do
    /// with this error.
    ///
    /// [`from_utf8_unchecked`]: struct.String.html#method.from_utf8_unchecked
    /// [`&str`]: https://doc.rust-lang.org/std/primitive.str.html
    /// [`u8`]: https://doc.rust-lang.org/std/primitive.u8.html
    /// [`Vec<u8>`]: ../vec/struct.Vec.html
    /// [`str::from_utf8`]: https://doc.rust-lang.org/std/str/fn.from_utf8.html
    /// [`into_bytes`]: struct.String.html#method.into_bytes
    /// [`FromUtf8Error`]: struct.FromUtf8Error.html
    /// [`Err`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Err
    #[inline]
    pub fn from_utf8(vec: Vec<'bump, u8>) -> Result<String<'bump>, FromUtf8Error<'bump>> {
        match str::from_utf8(&vec) {
            Ok(..) => Ok(String { vec }),
            Err(e) => Err(FromUtf8Error {
                bytes: vec,
                error: e,
            }),
        }
    }

    /// Converts a slice of bytes to a string, including invalid characters.
    ///
    /// Strings are made of bytes ([`u8`]), and a slice of bytes
    /// ([`&[u8]`][slice]) is made of bytes, so this function converts
    /// between the two. Not all byte slices are valid strings, however: strings
    /// are required to be valid UTF-8. During this conversion,
    /// `from_utf8_lossy_in()` will replace any invalid UTF-8 sequences with
    /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD], which looks like this: �
    ///
    /// [`u8`]: https://doc.rust-lang.org/std/primitive.u8.html
    /// [slice]: https://doc.rust-lang.org/std/primitive.slice.html
    /// [U+FFFD]: https://doc.rust-lang.org/std/char/constant.REPLACEMENT_CHARACTER.html
    ///
    /// If you are sure that the byte slice is valid UTF-8, and you don't want
    /// to incur the overhead of the conversion, there is an unsafe version
    /// of this function, [`from_utf8_unchecked`], which has the same behavior
    /// but skips the checks.
    ///
    /// [`from_utf8_unchecked`]: struct.String.html#method.from_utf8_unchecked
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{collections::String, Bump, vec};
    ///
    /// let b = Bump::new();
    ///
    /// // some bytes, in a vector
    /// let sparkle_heart = bumpalo::vec![in &b; 240, 159, 146, 150];
    ///
    /// let sparkle_heart = String::from_utf8_lossy_in(&sparkle_heart, &b);
    ///
    /// assert_eq!("��", sparkle_heart);
    /// ```
    ///
    /// Incorrect bytes:
    ///
    /// ```
    /// use bumpalo::{collections::String, Bump, vec};
    ///
    /// let b = Bump::new();
    ///
    /// // some invalid bytes
    /// let input = b"Hello \xF0\x90\x80World";
    /// let output = String::from_utf8_lossy_in(input, &b);
    ///
    /// assert_eq!("Hello �World", output);
    /// ```
    pub fn from_utf8_lossy_in(v: &[u8], bump: &'bump Bump) -> String<'bump> {
        let mut iter = lossy::Utf8Lossy::from_bytes(v).chunks();

        let (first_valid, first_broken) = if let Some(chunk) = iter.next() {
            let lossy::Utf8LossyChunk { valid, broken } = chunk;
            if valid.len() == v.len() {
                debug_assert!(broken.is_empty());
                unsafe {
                    return String::from_utf8_unchecked(Vec::from_iter_in(v.iter().cloned(), bump));
                }
            }
            (valid, broken)
        } else {
            return String::from_str_in("", bump);
        };

        const REPLACEMENT: &str = "\u{FFFD}";

        let mut res = String::with_capacity_in(v.len(), bump);
        res.push_str(first_valid);
        if !first_broken.is_empty() {
            res.push_str(REPLACEMENT);
        }

        for lossy::Utf8LossyChunk { valid, broken } in iter {
            res.push_str(valid);
            if !broken.is_empty() {
                res.push_str(REPLACEMENT);
            }
        }

        res
    }

    /// Decode a UTF-16 encoded slice `v` into a `String`, returning [`Err`]
    /// if `v` contains any invalid data.
    ///
    /// [`Err`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Err
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// // ��music
    /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075, 0x0073, 0x0069, 0x0063];
    /// assert_eq!(String::from_str_in("��music", &b), String::from_utf16_in(v, &b).unwrap());
    ///
    /// // ��mu<invalid>ic
    /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075, 0xD800, 0x0069, 0x0063];
    /// assert!(String::from_utf16_in(v, &b).is_err());
    /// ```
    pub fn from_utf16_in(v: &[u16], bump: &'bump Bump) -> Result<String<'bump>, FromUtf16Error> {
        let mut ret = String::with_capacity_in(v.len(), bump);
        for c in decode_utf16(v.iter().cloned()) {
            if let Ok(c) = c {
                ret.push(c);
            } else {
                return Err(FromUtf16Error(()));
            }
        }
        Ok(ret)
    }

    /// Construct a new `String<'bump>` from a string slice.
    ///
    /// # Examples
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let s = String::from_str_in("hello", &b);
    /// assert_eq!(s, "hello");
    /// ```
    pub fn from_str_in(s: &str, bump: &'bump Bump) -> String<'bump> {
        let len = s.len();
        let mut t = String::with_capacity_in(len, bump);
        // SAFETY:
        // * `src` is valid for reads of `s.len()` bytes by virtue of being an allocated `&str`.
        // * `dst` is valid for writes of `s.len()` bytes as `String::with_capacity_in(s.len(), bump)`
        //   above guarantees that.
        // * Alignment is not relevant as `u8` has no alignment requirements.
        // * Source and destination ranges cannot overlap as we just reserved the destination
        //   range from the bump.
        unsafe { ptr::copy_nonoverlapping(s.as_ptr(), t.vec.as_mut_ptr(), len) };
        // SAFETY: We reserved sufficent capacity for the string above.
        // The elements at `0..len` were initialized by `copy_nonoverlapping` above.
        unsafe { t.vec.set_len(len) };
        t
    }

    /// Construct a new `String<'bump>` from an iterator of `char`s.
    ///
    /// # Examples
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let s = String::from_iter_in(['h', 'e', 'l', 'l', 'o'].iter().cloned(), &b);
    /// assert_eq!(s, "hello");
    /// ```
    pub fn from_iter_in<I: IntoIterator<Item = char>>(iter: I, bump: &'bump Bump) -> String<'bump> {
        let mut s = String::new_in(bump);
        for c in iter {
            s.push(c);
        }
        s
    }

    /// Creates a new `String` from a length, capacity, and pointer.
    ///
    /// # Safety
    ///
    /// This is highly unsafe, due to the number of invariants that aren't
    /// checked:
    ///
    /// * The memory at `ptr` needs to have been previously allocated by the
    ///   same allocator the standard library uses.
    /// * `length` needs to be less than or equal to `capacity`.
    /// * `capacity` needs to be the correct value.
    ///
    /// Violating these may cause problems like corrupting the allocator's
    /// internal data structures.
    ///
    /// The ownership of `ptr` is effectively transferred to the
    /// `String` which may then deallocate, reallocate or change the
    /// contents of memory pointed to by the pointer at will. Ensure
    /// that nothing else uses the pointer after calling this
    /// function.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    /// use std::mem;
    ///
    /// let b = Bump::new();
    ///
    /// unsafe {
    ///     let mut s = String::from_str_in("hello", &b);
    ///     let ptr = s.as_mut_ptr();
    ///     let len = s.len();
    ///     let capacity = s.capacity();
    ///
    ///     mem::forget(s);
    ///
    ///     let s = String::from_raw_parts_in(ptr, len, capacity, &b);
    ///
    ///     assert_eq!(s, "hello");
    /// }
    /// ```
    #[inline]
    pub unsafe fn from_raw_parts_in(
        buf: *mut u8,
        length: usize,
        capacity: usize,
        bump: &'bump Bump,
    ) -> String<'bump> {
        String {
            vec: Vec::from_raw_parts_in(buf, length, capacity, bump),
        }
    }

    /// Converts a vector of bytes to a `String` without checking that the
    /// string contains valid UTF-8.
    ///
    /// See the safe version, [`from_utf8`], for more details.
    ///
    /// [`from_utf8`]: struct.String.html#method.from_utf8
    ///
    /// # Safety
    ///
    /// This function is unsafe because it does not check that the bytes passed
    /// to it are valid UTF-8. If this constraint is violated, it may cause
    /// memory unsafety issues with future users of the `String`,
    /// as it is assumed that `String`s are valid UTF-8.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// // some bytes, in a vector
    /// let sparkle_heart = bumpalo::vec![in &b; 240, 159, 146, 150];
    ///
    /// let sparkle_heart = unsafe {
    ///     String::from_utf8_unchecked(sparkle_heart)
    /// };
    ///
    /// assert_eq!("��", sparkle_heart);
    /// ```
    #[inline]
    pub unsafe fn from_utf8_unchecked(bytes: Vec<'bump, u8>) -> String<'bump> {
        String { vec: bytes }
    }

    /// Returns a shared reference to the allocator backing this `String`.
    ///
    /// # Examples
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// // uses the same allocator as the provided `String`
    /// fn copy_string<'bump>(s: &String<'bump>) -> &'bump str {
    ///     s.bump().alloc_str(s.as_str())
    /// }
    /// ```
    #[inline]
    #[must_use]
    pub fn bump(&self) -> &'bump Bump {
        self.vec.bump()
    }

    /// Converts a `String` into a byte vector.
    ///
    /// This consumes the `String`, so we do not need to copy its contents.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let s = String::from_str_in("hello", &b);
    ///
    /// assert_eq!(s.into_bytes(), [104, 101, 108, 108, 111]);
    /// ```
    #[inline]
    pub fn into_bytes(self) -> Vec<'bump, u8> {
        self.vec
    }

    /// Convert this `String<'bump>` into a `&'bump str`. This is analogous to
    /// [`std::string::String::into_boxed_str`][into_boxed_str].
    ///
    /// [into_boxed_str]: https://doc.rust-lang.org/std/string/struct.String.html#method.into_boxed_str
    ///
    /// # Example
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let s = String::from_str_in("foo", &b);
    ///
    /// assert_eq!(s.into_bump_str(), "foo");
    /// ```
    pub fn into_bump_str(self) -> &'bump str {
        let s = unsafe {
            let s = self.as_str();
            mem::transmute(s)
        };
        mem::forget(self);
        s
    }

    /// Extracts a string slice containing the entire `String`.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let s = String::from_str_in("foo", &b);
    ///
    /// assert_eq!("foo", s.as_str());
    /// ```
    #[inline]
    pub fn as_str(&self) -> &str {
        self
    }

    /// Converts a `String` into a mutable string slice.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut s = String::from_str_in("foobar", &b);
    /// let s_mut_str = s.as_mut_str();
    ///
    /// s_mut_str.make_ascii_uppercase();
    ///
    /// assert_eq!("FOOBAR", s_mut_str);
    /// ```
    #[inline]
    pub fn as_mut_str(&mut self) -> &mut str {
        self
    }

    /// Appends a given string slice onto the end of this `String`.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut s = String::from_str_in("foo", &b);
    ///
    /// s.push_str("bar");
    ///
    /// assert_eq!("foobar", s);
    /// ```
    #[inline]
    pub fn push_str(&mut self, string: &str) {
        self.vec.extend_from_slice_copy(string.as_bytes())
    }

    /// Returns this `String`'s capacity, in bytes.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let s = String::with_capacity_in(10, &b);
    ///
    /// assert!(s.capacity() >= 10);
    /// ```
    #[inline]
    pub fn capacity(&self) -> usize {
        self.vec.capacity()
    }

    /// Ensures that this `String`'s capacity is at least `additional` bytes
    /// larger than its length.
    ///
    /// The capacity may be increased by more than `additional` bytes if it
    /// chooses, to prevent frequent reallocations.
    ///
    /// If you do not want this "at least" behavior, see the [`reserve_exact`]
    /// method.
    ///
    /// # Panics
    ///
    /// Panics if the new capacity overflows [`usize`].
    ///
    /// [`reserve_exact`]: struct.String.html#method.reserve_exact
    /// [`usize`]: https://doc.rust-lang.org/std/primitive.usize.html
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut s = String::new_in(&b);
    ///
    /// s.reserve(10);
    ///
    /// assert!(s.capacity() >= 10);
    /// ```
    ///
    /// This may not actually increase the capacity:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut s = String::with_capacity_in(10, &b);
    /// s.push('a');
    /// s.push('b');
    ///
    /// // s now has a length of 2 and a capacity of 10
    /// assert_eq!(2, s.len());
    /// assert_eq!(10, s.capacity());
    ///
    /// // Since we already have an extra 8 capacity, calling this...
    /// s.reserve(8);
    ///
    /// // ... doesn't actually increase.
    /// assert_eq!(10, s.capacity());
    /// ```
    #[inline]
    pub fn reserve(&mut self, additional: usize) {
        self.vec.reserve(additional)
    }

    /// Ensures that this `String`'s capacity is `additional` bytes
    /// larger than its length.
    ///
    /// Consider using the [`reserve`] method unless you absolutely know
    /// better than the allocator.
    ///
    /// [`reserve`]: #method.reserve
    ///
    /// # Panics
    ///
    /// Panics if the new capacity overflows `usize`.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut s = String::new_in(&b);
    ///
    /// s.reserve_exact(10);
    ///
    /// assert!(s.capacity() >= 10);
    /// ```
    ///
    /// This may not actually increase the capacity:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut s = String::with_capacity_in(10, &b);
    /// s.push('a');
    /// s.push('b');
    ///
    /// // s now has a length of 2 and a capacity of 10
    /// assert_eq!(2, s.len());
    /// assert_eq!(10, s.capacity());
    ///
    /// // Since we already have an extra 8 capacity, calling this...
    /// s.reserve_exact(8);
    ///
    /// // ... doesn't actually increase.
    /// assert_eq!(10, s.capacity());
    /// ```
    #[inline]
    pub fn reserve_exact(&mut self, additional: usize) {
        self.vec.reserve_exact(additional)
    }

    /// Shrinks the capacity of this `String` to match its length.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut s = String::from_str_in("foo", &b);
    ///
    /// s.reserve(100);
    /// assert!(s.capacity() >= 100);
    ///
    /// s.shrink_to_fit();
    /// assert_eq!(3, s.capacity());
    /// ```
    #[inline]
    pub fn shrink_to_fit(&mut self) {
        self.vec.shrink_to_fit()
    }

    /// Appends the given [`char`] to the end of this `String`.
    ///
    /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut s = String::from_str_in("abc", &b);
    ///
    /// s.push('1');
    /// s.push('2');
    /// s.push('3');
    ///
    /// assert_eq!("abc123", s);
    /// ```
    #[inline]
    pub fn push(&mut self, ch: char) {
        match ch.len_utf8() {
            1 => self.vec.push(ch as u8),
            _ => self
                .vec
                .extend_from_slice(ch.encode_utf8(&mut [0; 4]).as_bytes()),
        }
    }

    /// Returns a byte slice of this `String`'s contents.
    ///
    /// The inverse of this method is [`from_utf8`].
    ///
    /// [`from_utf8`]: #method.from_utf8
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let s = String::from_str_in("hello", &b);
    ///
    /// assert_eq!(&[104, 101, 108, 108, 111], s.as_bytes());
    /// ```
    #[inline]
    pub fn as_bytes(&self) -> &[u8] {
        &self.vec
    }

    /// Shortens this `String` to the specified length.
    ///
    /// If `new_len` is greater than the string's current length, this has no
    /// effect.
    ///
    /// Note that this method has no effect on the allocated capacity
    /// of the string.
    ///
    /// # Panics
    ///
    /// Panics if `new_len` does not lie on a [`char`] boundary.
    ///
    /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut s = String::from_str_in("hello", &b);
    ///
    /// s.truncate(2);
    ///
    /// assert_eq!("he", s);
    /// ```
    #[inline]
    pub fn truncate(&mut self, new_len: usize) {
        if new_len <= self.len() {
            assert!(self.is_char_boundary(new_len));
            self.vec.truncate(new_len)
        }
    }

    /// Removes the last character from the string buffer and returns it.
    ///
    /// Returns [`None`] if this `String` is empty.
    ///
    /// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut s = String::from_str_in("foo", &b);
    ///
    /// assert_eq!(s.pop(), Some('o'));
    /// assert_eq!(s.pop(), Some('o'));
    /// assert_eq!(s.pop(), Some('f'));
    ///
    /// assert_eq!(s.pop(), None);
    /// ```
    #[inline]
    pub fn pop(&mut self) -> Option<char> {
        let ch = self.chars().rev().next()?;
        let newlen = self.len() - ch.len_utf8();
        unsafe {
            self.vec.set_len(newlen);
        }
        Some(ch)
    }

    /// Removes a [`char`] from this `String` at a byte position and returns it.
    ///
    /// This is an `O(n)` operation, as it requires copying every element in the
    /// buffer.
    ///
    /// # Panics
    ///
    /// Panics if `idx` is larger than or equal to the `String`'s length,
    /// or if it does not lie on a [`char`] boundary.
    ///
    /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut s = String::from_str_in("foo", &b);
    ///
    /// assert_eq!(s.remove(0), 'f');
    /// assert_eq!(s.remove(1), 'o');
    /// assert_eq!(s.remove(0), 'o');
    /// ```
    #[inline]
    pub fn remove(&mut self, idx: usize) -> char {
        let ch = match self[idx..].chars().next() {
            Some(ch) => ch,
            None => panic!("cannot remove a char from the end of a string"),
        };

        let next = idx + ch.len_utf8();
        let len = self.len();
        unsafe {
            ptr::copy(
                self.vec.as_ptr().add(next),
                self.vec.as_mut_ptr().add(idx),
                len - next,
            );
            self.vec.set_len(len - (next - idx));
        }
        ch
    }

    /// Retains only the characters specified by the predicate.
    ///
    /// In other words, remove all characters `c` such that `f(c)` returns `false`.
    /// This method operates in place and preserves the order of the retained
    /// characters.
    ///
    /// # Examples
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut s = String::from_str_in("f_o_ob_ar", &b);
    ///
    /// s.retain(|c| c != '_');
    ///
    /// assert_eq!(s, "foobar");
    /// ```
    #[inline]
    pub fn retain<F>(&mut self, mut f: F)
    where
        F: FnMut(char) -> bool,
    {
        let len = self.len();
        let mut del_bytes = 0;
        let mut idx = 0;

        while idx < len {
            let ch = unsafe { self.get_unchecked(idx..len).chars().next().unwrap() };
            let ch_len = ch.len_utf8();

            if !f(ch) {
                del_bytes += ch_len;
            } else if del_bytes > 0 {
                unsafe {
                    ptr::copy(
                        self.vec.as_ptr().add(idx),
                        self.vec.as_mut_ptr().add(idx - del_bytes),
                        ch_len,
                    );
                }
            }

            // Point idx to the next char
            idx += ch_len;
        }

        if del_bytes > 0 {
            unsafe {
                self.vec.set_len(len - del_bytes);
            }
        }
    }

    /// Inserts a character into this `String` at a byte position.
    ///
    /// This is an `O(n)` operation as it requires copying every element in the
    /// buffer.
    ///
    /// # Panics
    ///
    /// Panics if `idx` is larger than the `String`'s length, or if it does not
    /// lie on a [`char`] boundary.
    ///
    /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut s = String::with_capacity_in(3, &b);
    ///
    /// s.insert(0, 'f');
    /// s.insert(1, 'o');
    /// s.insert(2, 'o');
    ///
    /// assert_eq!("foo", s);
    /// ```
    #[inline]
    pub fn insert(&mut self, idx: usize, ch: char) {
        assert!(self.is_char_boundary(idx));
        let mut bits = [0; 4];
        let bits = ch.encode_utf8(&mut bits).as_bytes();

        unsafe {
            self.insert_bytes(idx, bits);
        }
    }

    unsafe fn insert_bytes(&mut self, idx: usize, bytes: &[u8]) {
        let len = self.len();
        let amt = bytes.len();
        self.vec.reserve(amt);

        ptr::copy(
            self.vec.as_ptr().add(idx),
            self.vec.as_mut_ptr().add(idx + amt),
            len - idx,
        );
        ptr::copy(bytes.as_ptr(), self.vec.as_mut_ptr().add(idx), amt);
        self.vec.set_len(len + amt);
    }

    /// Inserts a string slice into this `String` at a byte position.
    ///
    /// This is an `O(n)` operation as it requires copying every element in the
    /// buffer.
    ///
    /// # Panics
    ///
    /// Panics if `idx` is larger than the `String`'s length, or if it does not
    /// lie on a [`char`] boundary.
    ///
    /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut s = String::from_str_in("bar", &b);
    ///
    /// s.insert_str(0, "foo");
    ///
    /// assert_eq!("foobar", s);
    /// ```
    #[inline]
    pub fn insert_str(&mut self, idx: usize, string: &str) {
        assert!(self.is_char_boundary(idx));

        unsafe {
            self.insert_bytes(idx, string.as_bytes());
        }
    }

    /// Returns a mutable reference to the contents of this `String`.
    ///
    /// # Safety
    ///
    /// This function is unsafe because the returned `&mut Vec` allows writing
    /// bytes which are not valid UTF-8. If this constraint is violated, using
    /// the original `String` after dropping the `&mut Vec` may violate memory
    /// safety, as it is assumed that `String`s are valid UTF-8.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut s = String::from_str_in("hello", &b);
    ///
    /// unsafe {
    ///     let vec = s.as_mut_vec();
    ///     assert_eq!(vec, &[104, 101, 108, 108, 111]);
    ///
    ///     vec.reverse();
    /// }
    /// assert_eq!(s, "olleh");
    /// ```
    #[inline]
    pub unsafe fn as_mut_vec(&mut self) -> &mut Vec<'bump, u8> {
        &mut self.vec
    }

    /// Returns the length of this `String`, in bytes.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let a = String::from_str_in("foo", &b);
    ///
    /// assert_eq!(a.len(), 3);
    /// ```
    #[inline]
    pub fn len(&self) -> usize {
        self.vec.len()
    }

    /// Returns `true` if this `String` has a length of zero.
    ///
    /// Returns `false` otherwise.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut v = String::new_in(&b);
    /// assert!(v.is_empty());
    ///
    /// v.push('a');
    /// assert!(!v.is_empty());
    /// ```
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Splits the string into two at the given index.
    ///
    /// Returns a newly allocated `String`. `self` contains bytes `[0, at)`, and
    /// the returned `String` contains bytes `[at, len)`. `at` must be on the
    /// boundary of a UTF-8 code point.
    ///
    /// Note that the capacity of `self` does not change.
    ///
    /// # Panics
    ///
    /// Panics if `at` is not on a UTF-8 code point boundary, or if it is beyond the last
    /// code point of the string.
    ///
    /// # Examples
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut hello = String::from_str_in("Hello, World!", &b);
    /// let world = hello.split_off(7);
    /// assert_eq!(hello, "Hello, ");
    /// assert_eq!(world, "World!");
    /// ```
    #[inline]
    pub fn split_off(&mut self, at: usize) -> String<'bump> {
        assert!(self.is_char_boundary(at));
        let other = self.vec.split_off(at);
        unsafe { String::from_utf8_unchecked(other) }
    }

    /// Truncates this `String`, removing all contents.
    ///
    /// While this means the `String` will have a length of zero, it does not
    /// touch its capacity.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut s = String::from_str_in("foo", &b);
    ///
    /// s.clear();
    ///
    /// assert!(s.is_empty());
    /// assert_eq!(0, s.len());
    /// assert_eq!(3, s.capacity());
    /// ```
    #[inline]
    pub fn clear(&mut self) {
        self.vec.clear()
    }

    /// Creates a draining iterator that removes the specified range in the `String`
    /// and yields the removed `chars`.
    ///
    /// Note: The element range is removed even if the iterator is not
    /// consumed until the end.
    ///
    /// # Panics
    ///
    /// Panics if the starting point or end point do not lie on a [`char`]
    /// boundary, or if they're out of bounds.
    ///
    /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut s = String::from_str_in("α is alpha, β is beta", &b);
    /// let beta_offset = s.find('β').unwrap_or(s.len());
    ///
    /// // Remove the range up until the β from the string
    /// let t = String::from_iter_in(s.drain(..beta_offset), &b);
    /// assert_eq!(t, "α is alpha, ");
    /// assert_eq!(s, "β is beta");
    ///
    /// // A full range clears the string
    /// drop(s.drain(..));
    /// assert_eq!(s, "");
    /// ```
    pub fn drain<'a, R>(&'a mut self, range: R) -> Drain<'a, 'bump>
    where
        R: RangeBounds<usize>,
    {
        // Memory safety
        //
        // The String version of Drain does not have the memory safety issues
        // of the vector version. The data is just plain bytes.
        // Because the range removal happens in Drop, if the Drain iterator is leaked,
        // the removal will not happen.
        let len = self.len();
        let start = match range.start_bound() {
            Included(&n) => n,
            Excluded(&n) => n + 1,
            Unbounded => 0,
        };
        let end = match range.end_bound() {
            Included(&n) => n + 1,
            Excluded(&n) => n,
            Unbounded => len,
        };

        // Take out two simultaneous borrows. The &mut String won't be accessed
        // until iteration is over, in Drop.
        let self_ptr = self as *mut _;
        // slicing does the appropriate bounds checks
        let chars_iter = self[start..end].chars();

        Drain {
            start,
            end,
            iter: chars_iter,
            string: self_ptr,
        }
    }

    /// Removes the specified range in the string,
    /// and replaces it with the given string.
    /// The given string doesn't need to be the same length as the range.
    ///
    /// # Panics
    ///
    /// Panics if the starting point or end point do not lie on a [`char`]
    /// boundary, or if they're out of bounds.
    ///
    /// [`char`]: https://doc.rust-lang.org/std/primitive.char.html
    /// [`Vec::splice`]: ../vec/struct.Vec.html#method.splice
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// let mut s = String::from_str_in("α is alpha, β is beta", &b);
    /// let beta_offset = s.find('β').unwrap_or(s.len());
    ///
    /// // Replace the range up until the β from the string
    /// s.replace_range(..beta_offset, "Α is capital alpha; ");
    /// assert_eq!(s, "Α is capital alpha; β is beta");
    /// ```
    pub fn replace_range<R>(&mut self, range: R, replace_with: &str)
    where
        R: RangeBounds<usize>,
    {
        // Memory safety
        //
        // Replace_range does not have the memory safety issues of a vector Splice.
        // of the vector version. The data is just plain bytes.

        match range.start_bound() {
            Included(&n) => assert!(self.is_char_boundary(n)),
            Excluded(&n) => assert!(self.is_char_boundary(n + 1)),
            Unbounded => {}
        };
        match range.end_bound() {
            Included(&n) => assert!(self.is_char_boundary(n + 1)),
            Excluded(&n) => assert!(self.is_char_boundary(n)),
            Unbounded => {}
        };

        unsafe { self.as_mut_vec() }.splice(range, replace_with.bytes());
    }
}

impl<'bump> FromUtf8Error<'bump> {
    /// Returns a slice of bytes that were attempted to convert to a `String`.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// // some invalid bytes, in a vector
    /// let bytes = bumpalo::vec![in &b; 0, 159];
    ///
    /// let value = String::from_utf8(bytes);
    ///
    /// assert_eq!(&[0, 159], value.unwrap_err().as_bytes());
    /// ```
    pub fn as_bytes(&self) -> &[u8] {
        &self.bytes[..]
    }

    /// Returns the bytes that were attempted to convert to a `String`.
    ///
    /// This method is carefully constructed to avoid allocation. It will
    /// consume the error, moving out the bytes, so that a copy of the bytes
    /// does not need to be made.
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// // some invalid bytes, in a vector
    /// let bytes = bumpalo::vec![in &b; 0, 159];
    ///
    /// let value = String::from_utf8(bytes);
    ///
    /// assert_eq!(bumpalo::vec![in &b; 0, 159], value.unwrap_err().into_bytes());
    /// ```
    pub fn into_bytes(self) -> Vec<'bump, u8> {
        self.bytes
    }

    /// Fetch a `Utf8Error` to get more details about the conversion failure.
    ///
    /// The [`Utf8Error`] type provided by [`std::str`] represents an error that may
    /// occur when converting a slice of [`u8`]s to a [`&str`]. In this sense, it's
    /// an analogue to `FromUtf8Error`. See its documentation for more details
    /// on using it.
    ///
    /// [`Utf8Error`]: https://doc.rust-lang.org/std/str/struct.Utf8Error.html
    /// [`std::str`]: https://doc.rust-lang.org/std/str/index.html
    /// [`u8`]: https://doc.rust-lang.org/std/primitive.u8.html
    /// [`&str`]: https://doc.rust-lang.org/std/primitive.str.html
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use bumpalo::{Bump, collections::String};
    ///
    /// let b = Bump::new();
    ///
    /// // some invalid bytes, in a vector
    /// let bytes = bumpalo::vec![in &b; 0, 159];
    ///
    /// let error = String::from_utf8(bytes).unwrap_err().utf8_error();
    ///
    /// // the first byte is invalid here
    /// assert_eq!(1, error.valid_up_to());
    /// ```
    pub fn utf8_error(&self) -> Utf8Error {
        self.error
    }
}

impl<'bump> fmt::Display for FromUtf8Error<'bump> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&self.error, f)
    }
}

impl fmt::Display for FromUtf16Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt("invalid utf-16: lone surrogate found", f)
    }
}

impl<'bump> Clone for String<'bump> {
    fn clone(&self) -> Self {
        String {
            vec: self.vec.clone(),
        }
    }

    fn clone_from(&mut self, source: &Self) {
        self.vec.clone_from(&source.vec);
    }
}

impl<'bump> Extend<char> for String<'bump> {
    fn extend<I: IntoIterator<Item = char>>(&mut self, iter: I) {
        let iterator = iter.into_iter();
        let (lower_bound, _) = iterator.size_hint();
        self.reserve(lower_bound);
        for ch in iterator {
            self.push(ch)
        }
    }
}

impl<'a, 'bump> Extend<&'a char> for String<'bump> {
    fn extend<I: IntoIterator<Item = &'a char>>(&mut self, iter: I) {
        self.extend(iter.into_iter().cloned());
    }
}

impl<'a, 'bump> Extend<&'a str> for String<'bump> {
    fn extend<I: IntoIterator<Item = &'a str>>(&mut self, iter: I) {
        for s in iter {
            self.push_str(s)
        }
    }
}

impl<'bump> Extend<String<'bump>> for String<'bump> {
    fn extend<I: IntoIterator<Item = String<'bump>>>(&mut self, iter: I) {
        for s in iter {
            self.push_str(&s)
        }
    }
}

impl<'bump> Extend<core_alloc::string::String> for String<'bump> {
    fn extend<I: IntoIterator<Item = core_alloc::string::String>>(&mut self, iter: I) {
        for s in iter {
            self.push_str(&s)
        }
    }
}

impl<'a, 'bump> Extend<Cow<'a, str>> for String<'bump> {
    fn extend<I: IntoIterator<Item = Cow<'a, str>>>(&mut self, iter: I) {
        for s in iter {
            self.push_str(&s)
        }
    }
}

impl<'bump> PartialEq for String<'bump> {
    #[inline]
    fn eq(&self, other: &String) -> bool {
        PartialEq::eq(&self[..], &other[..])
    }
}

macro_rules! impl_eq {
    ($lhs:ty, $rhs: ty) => {
        impl<'a, 'bump> PartialEq<$rhs> for $lhs {
            #[inline]
            fn eq(&self, other: &$rhs) -> bool {
                PartialEq::eq(&self[..], &other[..])
            }
        }

        impl<'a, 'b, 'bump> PartialEq<$lhs> for $rhs {
            #[inline]
            fn eq(&self, other: &$lhs) -> bool {
                PartialEq::eq(&self[..], &other[..])
            }
        }
    };
}

impl_eq! { String<'bump>, str }
impl_eq! { String<'bump>, &'a str }
impl_eq! { Cow<'a, str>, String<'bump> }
impl_eq! { core_alloc::string::String, String<'bump> }

impl<'bump> fmt::Display for String<'bump> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&**self, f)
    }
}

impl<'bump> fmt::Debug for String<'bump> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&**self, f)
    }
}

impl<'bump> hash::Hash for String<'bump> {
    #[inline]
    fn hash<H: hash::Hasher>(&self, hasher: &mut H) {
        (**self).hash(hasher)
    }
}

/// Implements the `+` operator for concatenating two strings.
///
/// This consumes the `String<'bump>` on the left-hand side and re-uses its buffer (growing it if
/// necessary). This is done to avoid allocating a new `String<'bump>` and copying the entire contents on
/// every operation, which would lead to `O(n^2)` running time when building an `n`-byte string by
/// repeated concatenation.
///
/// The string on the right-hand side is only borrowed; its contents are copied into the returned
/// `String<'bump>`.
///
/// # Examples
///
/// Concatenating two `String<'bump>`s takes the first by value and borrows the second:
///
/// ```
/// use bumpalo::{Bump, collections::String};
///
/// let bump = Bump::new();
///
/// let a = String::from_str_in("hello", &bump);
/// let b = String::from_str_in(" world", &bump);
/// let c = a + &b;
/// // `a` is moved and can no longer be used here.
/// ```
///
/// If you want to keep using the first `String`, you can clone it and append to the clone instead:
///
/// ```
/// use bumpalo::{Bump, collections::String};
///
/// let bump = Bump::new();
///
/// let a = String::from_str_in("hello", &bump);
/// let b = String::from_str_in(" world", &bump);
/// let c = a.clone() + &b;
/// // `a` is still valid here.
/// ```
///
/// Concatenating `&str` slices can be done by converting the first to a `String`:
///
/// ```
/// use bumpalo::{Bump, collections::String};
///
/// let bump = Bump::new();
///
/// let a = "hello";
/// let b = " world";
/// let c = String::from_str_in(a, &bump) + b;
/// ```
impl<'a, 'bump> Add<&'a str> for String<'bump> {
    type Output = String<'bump>;

    #[inline]
    fn add(mut self, other: &str) -> String<'bump> {
        self.push_str(other);
        self
    }
}

/// Implements the `+=` operator for appending to a `String<'bump>`.
///
/// This has the same behavior as the [`push_str`][String::push_str] method.
impl<'a, 'bump> AddAssign<&'a str> for String<'bump> {
    #[inline]
    fn add_assign(&mut self, other: &str) {
        self.push_str(other);
    }
}

impl<'bump> ops::Index<ops::Range<usize>> for String<'bump> {
    type Output = str;

    #[inline]
    fn index(&self, index: ops::Range<usize>) -> &str {
        &self[..][index]
    }
}
impl<'bump> ops::Index<ops::RangeTo<usize>> for String<'bump> {
    type Output = str;

    #[inline]
    fn index(&self, index: ops::RangeTo<usize>) -> &str {
        &self[..][index]
    }
}
impl<'bump> ops::Index<ops::RangeFrom<usize>> for String<'bump> {
    type Output = str;

    #[inline]
    fn index(&self, index: ops::RangeFrom<usize>) -> &str {
        &self[..][index]
    }
}
impl<'bump> ops::Index<ops::RangeFull> for String<'bump> {
    type Output = str;

    #[inline]
    fn index(&self, _index: ops::RangeFull) -> &str {
        unsafe { str::from_utf8_unchecked(&self.vec) }
    }
}
impl<'bump> ops::Index<ops::RangeInclusive<usize>> for String<'bump> {
    type Output = str;

    #[inline]
    fn index(&self, index: ops::RangeInclusive<usize>) -> &str {
        Index::index(&**self, index)
    }
}
impl<'bump> ops::Index<ops::RangeToInclusive<usize>> for String<'bump> {
    type Output = str;

    #[inline]
    fn index(&self, index: ops::RangeToInclusive<usize>) -> &str {
        Index::index(&**self, index)
    }
}

impl<'bump> ops::IndexMut<ops::Range<usize>> for String<'bump> {
    #[inline]
    fn index_mut(&mut self, index: ops::Range<usize>) -> &mut str {
        &mut self[..][index]
    }
}
impl<'bump> ops::IndexMut<ops::RangeTo<usize>> for String<'bump> {
    #[inline]
    fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut str {
        &mut self[..][index]
    }
}
impl<'bump> ops::IndexMut<ops::RangeFrom<usize>> for String<'bump> {
    #[inline]
    fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut str {
        &mut self[..][index]
    }
}
impl<'bump> ops::IndexMut<ops::RangeFull> for String<'bump> {
    #[inline]
    fn index_mut(&mut self, _index: ops::RangeFull) -> &mut str {
        unsafe { str::from_utf8_unchecked_mut(&mut *self.vec) }
    }
}
impl<'bump> ops::IndexMut<ops::RangeInclusive<usize>> for String<'bump> {
    #[inline]
    fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut str {
        IndexMut::index_mut(&mut **self, index)
    }
}
impl<'bump> ops::IndexMut<ops::RangeToInclusive<usize>> for String<'bump> {
    #[inline]
    fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut str {
        IndexMut::index_mut(&mut **self, index)
    }
}

impl<'bump> ops::Deref for String<'bump> {
    type Target = str;

    #[inline]
    fn deref(&self) -> &str {
        unsafe { str::from_utf8_unchecked(&self.vec) }
    }
}

impl<'bump> ops::DerefMut for String<'bump> {
    #[inline]
    fn deref_mut(&mut self) -> &mut str {
        unsafe { str::from_utf8_unchecked_mut(&mut *self.vec) }
    }
}

impl<'bump> AsRef<str> for String<'bump> {
    #[inline]
    fn as_ref(&self) -> &str {
        self
    }
}

impl<'bump> AsRef<[u8]> for String<'bump> {
    #[inline]
    fn as_ref(&self) -> &[u8] {
        self.as_bytes()
    }
}

impl<'bump> fmt::Write for String<'bump> {
    #[inline]
    fn write_str(&mut self, s: &str) -> fmt::Result {
        self.push_str(s);
        Ok(())
    }

    #[inline]
    fn write_char(&mut self, c: char) -> fmt::Result {
        self.push(c);
        Ok(())
    }
}

impl<'bump> Borrow<str> for String<'bump> {
    #[inline]
    fn borrow(&self) -> &str {
        &self[..]
    }
}

impl<'bump> BorrowMut<str> for String<'bump> {
    #[inline]
    fn borrow_mut(&mut self) -> &mut str {
        &mut self[..]
    }
}

/// A draining iterator for `String`.
///
/// This struct is created by the [`String::drain`] method. See its
/// documentation for more information.
pub struct Drain<'a, 'bump> {
    /// Will be used as &'a mut String in the destructor
    string: *mut String<'bump>,
    /// Start of part to remove
    start: usize,
    /// End of part to remove
    end: usize,
    /// Current remaining range to remove
    iter: Chars<'a>,
}

impl<'a, 'bump> fmt::Debug for Drain<'a, 'bump> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("Drain { .. }")
    }
}

unsafe impl<'a, 'bump> Sync for Drain<'a, 'bump> {}
unsafe impl<'a, 'bump> Send for Drain<'a, 'bump> {}

impl<'a, 'bump> Drop for Drain<'a, 'bump> {
    fn drop(&mut self) {
        unsafe {
            // Use Vec::drain. "Reaffirm" the bounds checks to avoid
            // panic code being inserted again.
            let self_vec = (*self.string).as_mut_vec();
            if self.start <= self.end && self.end <= self_vec.len() {
                self_vec.drain(self.start..self.end);
            }
        }
    }
}

// TODO: implement `AsRef<str/[u8]>` and `as_str`

impl<'a, 'bump> Iterator for Drain<'a, 'bump> {
    type Item = char;

    #[inline]
    fn next(&mut self) -> Option<char> {
        self.iter.next()
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl<'a, 'bump> DoubleEndedIterator for Drain<'a, 'bump> {
    #[inline]
    fn next_back(&mut self) -> Option<char> {
        self.iter.next_back()
    }
}

impl<'a, 'bump> FusedIterator for Drain<'a, 'bump> {}

[ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge