Merge pull request #78 from DenialAdams/master
Add pop, truncate, and remove functions to ArrayString.
This commit is contained in:
@@ -220,6 +220,99 @@ impl<A: Array<Item=u8>> ArrayString<A> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes the last character from the string and returns it.
|
||||||
|
///
|
||||||
|
/// Returns `None` if this `ArrayString` is empty.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use arrayvec::ArrayString;
|
||||||
|
///
|
||||||
|
/// let mut s = ArrayString::<[_; 3]>::from("foo").unwrap();
|
||||||
|
///
|
||||||
|
/// 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 = match self.chars().rev().next() {
|
||||||
|
Some(ch) => ch,
|
||||||
|
None => return None,
|
||||||
|
};
|
||||||
|
let new_len = self.len() - ch.len_utf8();
|
||||||
|
unsafe {
|
||||||
|
self.set_len(new_len);
|
||||||
|
}
|
||||||
|
Some(ch)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Shortens this `ArrayString` to the specified length.
|
||||||
|
///
|
||||||
|
/// If `new_len` is greater than the string's current length, this has no
|
||||||
|
/// effect.
|
||||||
|
///
|
||||||
|
/// ***Panics*** if `new_len` does not lie on a `char` boundary.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use arrayvec::ArrayString;
|
||||||
|
///
|
||||||
|
/// let mut string = ArrayString::<[_; 6]>::from("foobar").unwrap();
|
||||||
|
/// string.truncate(3);
|
||||||
|
/// assert_eq!(&string[..], "foo");
|
||||||
|
/// string.truncate(4);
|
||||||
|
/// assert_eq!(&string[..], "foo");
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn truncate(&mut self, new_len: usize) {
|
||||||
|
if new_len <= self.len() {
|
||||||
|
assert!(self.is_char_boundary(new_len));
|
||||||
|
unsafe {
|
||||||
|
// In libstd truncate is called on the underlying vector,
|
||||||
|
// which in turns drops each element.
|
||||||
|
// As we know we don't have to worry about Drop,
|
||||||
|
// we can just set the length (a la clear.)
|
||||||
|
self.set_len(new_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Removes a `char` from this `ArrayString` at a byte position and returns it.
|
||||||
|
///
|
||||||
|
/// This is an `O(n)` operation, as it requires copying every element in the
|
||||||
|
/// array.
|
||||||
|
///
|
||||||
|
/// ***Panics*** if `idx` is larger than or equal to the `ArrayString`'s length,
|
||||||
|
/// or if it does not lie on a `char` boundary.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use arrayvec::ArrayString;
|
||||||
|
///
|
||||||
|
/// let mut s = ArrayString::<[_; 3]>::from("foo").unwrap();
|
||||||
|
///
|
||||||
|
/// 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.xs.as_ptr().offset(next as isize),
|
||||||
|
self.xs.as_mut_ptr().offset(idx as isize),
|
||||||
|
len - next);
|
||||||
|
self.set_len(len - (next - idx));
|
||||||
|
}
|
||||||
|
ch
|
||||||
|
}
|
||||||
|
|
||||||
/// Make the string empty.
|
/// Make the string empty.
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|||||||
Reference in New Issue
Block a user