Skip to content

Commit

Permalink
Add FromIterator implementations for Box<str>
Browse files Browse the repository at this point in the history
These are analogous to impl FromIterator<A> for Box<[A]> (rust-lang#55843).

Fixes rust-lang#65163.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
  • Loading branch information
andersk committed Mar 18, 2020
1 parent ae5b641 commit e355419
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
37 changes: 37 additions & 0 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,10 @@ use core::slice;
use core::task::{Context, Poll};

use crate::alloc::{self, AllocRef, Global};
use crate::borrow::Cow;
use crate::raw_vec::RawVec;
use crate::str::from_boxed_utf8_unchecked;
use crate::string::String;
use crate::vec::Vec;

/// A pointer type for heap allocation.
Expand Down Expand Up @@ -1045,6 +1047,41 @@ impl<A> FromIterator<A> for Box<[A]> {
}
}

#[stable(feature = "boxed_str_from_iter", since = "1.44.0")]
impl<'a> FromIterator<&'a char> for Box<str> {
fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
iter.into_iter().collect::<String>().into_boxed_str()
}
}

#[stable(feature = "boxed_str_from_iter", since = "1.44.0")]
impl<'a> FromIterator<&'a str> for Box<str> {
fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
iter.into_iter().collect::<String>().into_boxed_str()
}
}

#[stable(feature = "boxed_str_from_iter", since = "1.44.0")]
impl<'a> FromIterator<Cow<'a, str>> for Box<str> {
fn from_iter<T: IntoIterator<Item = Cow<'a, str>>>(iter: T) -> Self {
iter.into_iter().collect::<String>().into_boxed_str()
}
}

#[stable(feature = "boxed_str_from_iter", since = "1.44.0")]
impl FromIterator<String> for Box<str> {
fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
iter.into_iter().collect::<String>().into_boxed_str()
}
}

#[stable(feature = "boxed_str_from_iter", since = "1.44.0")]
impl FromIterator<char> for Box<str> {
fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
iter.into_iter().collect::<String>().into_boxed_str()
}
}

#[stable(feature = "box_slice_clone", since = "1.3.0")]
impl<T: Clone> Clone for Box<[T]> {
fn clone(&self) -> Self {
Expand Down
18 changes: 18 additions & 0 deletions src/liballoc/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use core::i64;
use core::ops::Deref;
use core::result::Result::{Err, Ok};

use std::borrow::Cow;
use std::boxed::Box;
use std::string::String;

#[test]
fn test_owned_clone() {
Expand Down Expand Up @@ -140,6 +142,22 @@ fn boxed_slice_from_iter() {
assert_eq!(boxed[7], 7);
}

#[test]
fn boxed_str_from_iter() {
let s = "Hello, world!";
let chars: Box<[char]> = s.chars().collect();
let boxed: Box<str> = chars.iter().collect();
assert_eq!(&*boxed, s);
let boxed: Box<str> = [s].iter().cloned().collect();
assert_eq!(&*boxed, s);
let boxed: Box<str> = [Cow::from(s)].iter().cloned().collect();
assert_eq!(&*boxed, s);
let boxed: Box<str> = [String::from(s)].iter().cloned().collect();
assert_eq!(&*boxed, s);
let boxed: Box<str> = s.chars().collect();
assert_eq!(&*boxed, s);
}

#[test]
fn test_array_from_slice() {
let v = vec![1, 2, 3];
Expand Down

0 comments on commit e355419

Please sign in to comment.