Replace SliceConcatExt trait with inherent methods and SliceConcat helper trait
Before this change `SliceConcatExt` was an unstable extension trait with stable methods. It was in the libstd prelude, so that its methods could be used on the stable channel. This replaces it with inherent methods, which can be used without any addition to the prelude. Since the methods are stable and very generic (with for example a return type that depends on the types of parameters), an helper trait is still needed. But now that trait does not need to be in scope for the methods to be used. Removing this depedency on the libstd prelude allows the methods to be used in `#![no_std]` crate that use liballoc, which does not have its own implicitly-imported prelude.
This commit is contained in:
parent
baab1914ec
commit
e808d921dd
@ -6,6 +6,5 @@
|
||||
|
||||
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::borrow::ToOwned;
|
||||
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::boxed::Box;
|
||||
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::slice::SliceConcatExt;
|
||||
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::string::{String, ToString};
|
||||
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::vec::Vec;
|
||||
|
@ -484,6 +484,56 @@ impl<T> [T] {
|
||||
}
|
||||
buf
|
||||
}
|
||||
|
||||
/// Flattens a slice of `T` into a single value `Self::Output`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!(["hello", "world"].concat(), "helloworld");
|
||||
/// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn concat<Separator: ?Sized>(&self) -> T::Output
|
||||
where T: SliceConcat<Separator>
|
||||
{
|
||||
SliceConcat::concat(self)
|
||||
}
|
||||
|
||||
/// Flattens a slice of `T` into a single value `Self::Output`, placing a
|
||||
/// given separator between each.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!(["hello", "world"].join(" "), "hello world");
|
||||
/// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
|
||||
/// ```
|
||||
#[stable(feature = "rename_connect_to_join", since = "1.3.0")]
|
||||
pub fn join<Separator: ?Sized>(&self, sep: &Separator) -> T::Output
|
||||
where T: SliceConcat<Separator>
|
||||
{
|
||||
SliceConcat::join(self, sep)
|
||||
}
|
||||
|
||||
/// Flattens a slice of `T` into a single value `Self::Output`, placing a
|
||||
/// given separator between each.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![allow(deprecated)]
|
||||
/// assert_eq!(["hello", "world"].connect(" "), "hello world");
|
||||
/// assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_deprecated(since = "1.3.0", reason = "renamed to join")]
|
||||
pub fn connect<Separator: ?Sized>(&self, sep: &Separator) -> T::Output
|
||||
where T: SliceConcat<Separator>
|
||||
{
|
||||
SliceConcat::join(self, sep)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[lang = "slice_u8_alloc"]
|
||||
@ -527,87 +577,46 @@ impl [u8] {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Extension traits for slices over specific kinds of data
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#[unstable(feature = "slice_concat_ext",
|
||||
reason = "trait should not have to exist",
|
||||
issue = "27747")]
|
||||
/// An extension trait for concatenating slices
|
||||
///
|
||||
/// While this trait is unstable, the methods are stable. `SliceConcatExt` is
|
||||
/// included in the [standard library prelude], so you can use [`join()`] and
|
||||
/// [`concat()`] as if they existed on `[T]` itself.
|
||||
///
|
||||
/// [standard library prelude]: ../../std/prelude/index.html
|
||||
/// [`join()`]: #tymethod.join
|
||||
/// [`concat()`]: #tymethod.concat
|
||||
pub trait SliceConcatExt<T: ?Sized> {
|
||||
#[unstable(feature = "slice_concat_ext",
|
||||
reason = "trait should not have to exist",
|
||||
issue = "27747")]
|
||||
|
||||
/// Helper trait for [`[T]::concat`](../../std/primitive.slice.html#method.concat)
|
||||
/// and [`[T]::join`](../../std/primitive.slice.html#method.join)
|
||||
#[unstable(feature = "slice_concat_trait", issue = "27747")]
|
||||
pub trait SliceConcat<Separator: ?Sized>: Sized {
|
||||
#[unstable(feature = "slice_concat_trait", issue = "27747")]
|
||||
/// The resulting type after concatenation
|
||||
type Output;
|
||||
|
||||
/// Flattens a slice of `T` into a single value `Self::Output`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!(["hello", "world"].concat(), "helloworld");
|
||||
/// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn concat(&self) -> Self::Output;
|
||||
/// Implementation of [`[T]::concat`](../../std/primitive.slice.html#method.concat)
|
||||
#[unstable(feature = "slice_concat_trait", issue = "27747")]
|
||||
fn concat(slice: &[Self]) -> Self::Output;
|
||||
|
||||
/// Flattens a slice of `T` into a single value `Self::Output`, placing a
|
||||
/// given separator between each.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!(["hello", "world"].join(" "), "hello world");
|
||||
/// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
|
||||
/// ```
|
||||
#[stable(feature = "rename_connect_to_join", since = "1.3.0")]
|
||||
fn join(&self, sep: &T) -> Self::Output;
|
||||
|
||||
/// Flattens a slice of `T` into a single value `Self::Output`, placing a
|
||||
/// given separator between each.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![allow(deprecated)]
|
||||
/// assert_eq!(["hello", "world"].connect(" "), "hello world");
|
||||
/// assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_deprecated(since = "1.3.0", reason = "renamed to join")]
|
||||
fn connect(&self, sep: &T) -> Self::Output {
|
||||
self.join(sep)
|
||||
}
|
||||
/// Implementation of [`[T]::join`](../../std/primitive.slice.html#method.join)
|
||||
#[unstable(feature = "slice_concat_trait", issue = "27747")]
|
||||
fn join(slice: &[Self], sep: &Separator) -> Self::Output;
|
||||
}
|
||||
|
||||
#[unstable(feature = "slice_concat_ext",
|
||||
reason = "trait should not have to exist",
|
||||
issue = "27747")]
|
||||
impl<T: Clone, V: Borrow<[T]>> SliceConcatExt<T> for [V] {
|
||||
impl<T: Clone, V: Borrow<[T]>> SliceConcat<T> for V {
|
||||
type Output = Vec<T>;
|
||||
|
||||
fn concat(&self) -> Vec<T> {
|
||||
let size = self.iter().map(|slice| slice.borrow().len()).sum();
|
||||
fn concat(slice: &[Self]) -> Vec<T> {
|
||||
let size = slice.iter().map(|slice| slice.borrow().len()).sum();
|
||||
let mut result = Vec::with_capacity(size);
|
||||
for v in self {
|
||||
for v in slice {
|
||||
result.extend_from_slice(v.borrow())
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn join(&self, sep: &T) -> Vec<T> {
|
||||
let mut iter = self.iter();
|
||||
fn join(slice: &[Self], sep: &T) -> Vec<T> {
|
||||
let mut iter = slice.iter();
|
||||
let first = match iter.next() {
|
||||
Some(first) => first,
|
||||
None => return vec![],
|
||||
};
|
||||
let size = self.iter().map(|slice| slice.borrow().len()).sum::<usize>() + self.len() - 1;
|
||||
let size = slice.iter().map(|slice| slice.borrow().len()).sum::<usize>() + slice.len() - 1;
|
||||
let mut result = Vec::with_capacity(size);
|
||||
result.extend_from_slice(first.borrow());
|
||||
|
||||
|
@ -37,7 +37,7 @@ use core::unicode::conversions;
|
||||
|
||||
use crate::borrow::ToOwned;
|
||||
use crate::boxed::Box;
|
||||
use crate::slice::{SliceConcatExt, SliceIndex};
|
||||
use crate::slice::{SliceConcat, SliceIndex};
|
||||
use crate::string::String;
|
||||
use crate::vec::Vec;
|
||||
|
||||
@ -74,16 +74,16 @@ pub use core::str::{EscapeDebug, EscapeDefault, EscapeUnicode};
|
||||
#[unstable(feature = "slice_concat_ext",
|
||||
reason = "trait should not have to exist",
|
||||
issue = "27747")]
|
||||
impl<S: Borrow<str>> SliceConcatExt<str> for [S] {
|
||||
impl<S: Borrow<str>> SliceConcat<str> for S {
|
||||
type Output = String;
|
||||
|
||||
fn concat(&self) -> String {
|
||||
self.join("")
|
||||
fn concat(slice: &[Self]) -> String {
|
||||
Self::join(slice, "")
|
||||
}
|
||||
|
||||
fn join(&self, sep: &str) -> String {
|
||||
fn join(slice: &[Self], sep: &str) -> String {
|
||||
unsafe {
|
||||
String::from_utf8_unchecked( join_generic_copy(self, sep.as_bytes()) )
|
||||
String::from_utf8_unchecked( join_generic_copy(slice, sep.as_bytes()) )
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -126,7 +126,7 @@ macro_rules! copy_slice_and_advance {
|
||||
|
||||
// Optimized join implementation that works for both Vec<T> (T: Copy) and String's inner vec
|
||||
// Currently (2018-05-13) there is a bug with type inference and specialization (see issue #36262)
|
||||
// For this reason SliceConcatExt<T> is not specialized for T: Copy and SliceConcatExt<str> is the
|
||||
// For this reason SliceConcat<T> is not specialized for T: Copy and SliceConcat<str> is the
|
||||
// only user of this function. It is left in place for the time when that is fixed.
|
||||
//
|
||||
// the bounds for String-join are S: Borrow<str> and for Vec-join Borrow<[T]>
|
||||
|
@ -71,9 +71,6 @@
|
||||
//! * [`std::result`]::[`Result`]::{`self`, `Ok`, `Err`}. A type for functions
|
||||
//! that may succeed or fail. Like [`Option`], its variants are exported as
|
||||
//! well.
|
||||
//! * [`std::slice`]::[`SliceConcatExt`], a trait that exists for technical
|
||||
//! reasons, but shouldn't have to exist. It provides a few useful methods on
|
||||
//! slices.
|
||||
//! * [`std::string`]::{[`String`], [`ToString`]}, heap allocated strings.
|
||||
//! * [`std::vec`]::[`Vec`](../vec/struct.Vec.html), a growable, heap-allocated
|
||||
//! vector.
|
||||
|
@ -60,9 +60,6 @@ pub use crate::boxed::Box;
|
||||
pub use crate::borrow::ToOwned;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[doc(no_inline)]
|
||||
pub use crate::slice::SliceConcatExt;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[doc(no_inline)]
|
||||
pub use crate::string::{String, ToString};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[doc(no_inline)]
|
||||
|
Loading…
x
Reference in New Issue
Block a user