Auto merge of #42648 - murarth:merge-alloc-collections, r=alexcrichton

Merge crate `collections` into `alloc`

This is a necessary step in order to merge #42565
This commit is contained in:
bors
2017-06-15 12:37:54 +00:00
97 changed files with 2348 additions and 2517 deletions
+1 -10
View File
@@ -36,6 +36,7 @@ name = "alloc"
version = "0.0.0"
dependencies = [
"core 0.0.0",
"std_unicode 0.0.0",
]
[[package]]
@@ -250,15 +251,6 @@ dependencies = [
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "collections"
version = "0.0.0"
dependencies = [
"alloc 0.0.0",
"core 0.0.0",
"std_unicode 0.0.0",
]
[[package]]
name = "compiler_builtins"
version = "0.0.0"
@@ -1594,7 +1586,6 @@ dependencies = [
"alloc_jemalloc 0.0.0",
"alloc_system 0.0.0",
"build_helper 0.1.0",
"collections 0.0.0",
"compiler_builtins 0.0.0",
"core 0.0.0",
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
+1 -2
View File
@@ -376,8 +376,8 @@ pub fn debugger_scripts(build: &Build,
install(&build.src.join("src/etc/rust-windbg.cmd"), &sysroot.join("bin"),
0o755);
cp_debugger_script("natvis/liballoc.natvis");
cp_debugger_script("natvis/libcore.natvis");
cp_debugger_script("natvis/libcollections.natvis");
} else {
cp_debugger_script("debugger_pretty_printers_common.py");
@@ -550,7 +550,6 @@ pub fn rust_src(build: &Build) {
"src/liballoc_jemalloc",
"src/liballoc_system",
"src/libbacktrace",
"src/libcollections",
"src/libcompiler_builtins",
"src/libcore",
"src/liblibc",
+1 -1
View File
@@ -246,7 +246,7 @@ pub fn std(build: &Build, stage: u32, target: &str) {
// for which docs must be built.
if !build.config.compiler_docs {
cargo.arg("--no-deps");
for krate in &["alloc", "collections", "core", "std", "std_unicode"] {
for krate in &["alloc", "core", "std", "std_unicode"] {
cargo.arg("-p").arg(krate);
// Create all crate output directories first to make sure rustdoc uses
// relative links.
-1
View File
@@ -110,7 +110,6 @@
- [coerce_unsized](library-features/coerce-unsized.md)
- [collection_placement](library-features/collection-placement.md)
- [collections_range](library-features/collections-range.md)
- [collections](library-features/collections.md)
- [command_envs](library-features/command-envs.md)
- [compiler_builtins_lib](library-features/compiler-builtins-lib.md)
- [compiler_fences](library-features/compiler-fences.md)
@@ -1,5 +0,0 @@
# `collections`
This feature is internal to the Rust compiler and is not intended for general use.
------------------------
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="collections::vec::Vec&lt;*&gt;">
<Type Name="alloc::vec::Vec&lt;*&gt;">
<DisplayString>{{ size={len} }}</DisplayString>
<Expand>
<Item Name="[size]" ExcludeView="simple">len</Item>
@@ -11,7 +11,7 @@
</ArrayItems>
</Expand>
</Type>
<Type Name="collections::vec_deque::VecDeque&lt;*&gt;">
<Type Name="alloc::vec_deque::VecDeque&lt;*&gt;">
<DisplayString>{{ size={tail &lt;= head ? head - tail : buf.cap - tail + head} }}</DisplayString>
<Expand>
<Item Name="[size]" ExcludeView="simple">tail &lt;= head ? head - tail : buf.cap - tail + head</Item>
@@ -30,18 +30,18 @@
</CustomListItems>
</Expand>
</Type>
<Type Name="collections::linked_list::LinkedList&lt;*&gt;">
<Type Name="alloc::linked_list::LinkedList&lt;*&gt;">
<DisplayString>{{ size={len} }}</DisplayString>
<Expand>
<LinkedListItems>
<Size>len</Size>
<HeadPointer>*(collections::linked_list::Node&lt;$T1&gt; **)&amp;head</HeadPointer>
<NextPointer>*(collections::linked_list::Node&lt;$T1&gt; **)&amp;next</NextPointer>
<HeadPointer>*(alloc::linked_list::Node&lt;$T1&gt; **)&amp;head</HeadPointer>
<NextPointer>*(alloc::linked_list::Node&lt;$T1&gt; **)&amp;next</NextPointer>
<ValueNode>element</ValueNode>
</LinkedListItems>
</Expand>
</Type>
<Type Name="collections::string::String">
<Type Name="alloc::string::String">
<DisplayString>{*(char**)this,[vec.len]}</DisplayString>
<StringView>*(char**)this,[vec.len]</StringView>
<Expand>
@@ -53,4 +53,4 @@
</ArrayItems>
</Expand>
</Type>
</AutoVisualizer>
</AutoVisualizer>
+1 -1
View File
@@ -15,4 +15,4 @@ for /f "delims=" %%i in ('rustc --print=sysroot') do set rustc_sysroot=%%i
set rust_etc=%rustc_sysroot%\lib\rustlib\etc
windbg -c ".nvload %rust_etc%\libcore.natvis;.nvload %rust_etc%\libcollections.natvis;" %*
windbg -c ".nvload %rust_etc%\liballoc.natvis; .nvload %rust_etc%\libcore.natvis;" %*
+9
View File
@@ -9,3 +9,12 @@ path = "lib.rs"
[dependencies]
core = { path = "../libcore" }
std_unicode = { path = "../libstd_unicode" }
[[test]]
name = "collectionstests"
path = "../liballoc/tests/lib.rs"
[[bench]]
name = "collectionsbenches"
path = "../liballoc/benches/lib.rs"
+3 -2
View File
@@ -1222,11 +1222,12 @@ mod tests {
use std::sync::atomic;
use std::sync::atomic::Ordering::{Acquire, SeqCst};
use std::thread;
use std::vec::Vec;
use super::{Arc, Weak};
use std::sync::Mutex;
use std::convert::From;
use super::{Arc, Weak};
use vec::Vec;
struct Canary(*mut atomic::AtomicUsize);
impl Drop for Canary {
+2
View File
@@ -95,6 +95,7 @@
#[unstable(feature = "box_heap",
reason = "may be renamed; uncertain about custom allocator design",
issue = "27779")]
#[allow(missing_debug_implementations)]
#[derive(Copy, Clone)]
pub struct ExchangeHeapSingleton {
_force_singleton: (),
@@ -129,6 +130,7 @@ pub struct ExchangeHeapSingleton {
#[unstable(feature = "placement_in",
reason = "placement box design is still being worked out.",
issue = "27779")]
#[allow(missing_debug_implementations)]
pub struct IntermediateBox<T: ?Sized> {
ptr: *mut u8,
size: usize,
@@ -41,7 +41,6 @@
// - A node of length `n` has `n` keys, `n` values, and (in an internal node) `n + 1` edges.
// This implies that even an empty internal node has at least one edge.
use alloc::heap;
use core::marker::PhantomData;
use core::mem;
use core::nonzero::NonZero;
@@ -49,6 +48,7 @@
use core::slice;
use boxed::Box;
use heap;
const B: usize = 6;
pub const MIN_LEN: usize = B - 1;
+150 -10
View File
@@ -1,4 +1,4 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// Copyright 2014-2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@@ -8,18 +8,16 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! # The Rust core allocation library
//! # The Rust core allocation and collections library
//!
//! This is the lowest level library through which allocation in Rust can be
//! performed.
//! This library provides smart pointers and collections for managing
//! heap-allocated values.
//!
//! This library, like libcore, is not intended for general usage, but rather as
//! a building block of other libraries. The types and interfaces in this
//! library are reexported through the [standard library](../std/index.html),
//! and should not be used through this library.
//!
//! Currently, there are four major definitions in this library.
//!
//! ## Boxed values
//!
//! The [`Box`](boxed/index.html) type is a smart pointer type. There can
@@ -51,6 +49,12 @@
//! paired with synchronization primitives such as mutexes to allow mutation of
//! shared resources.
//!
//! ## Collections
//!
//! Implementations of the most common general purpose data structures are
//! defined in this library. They are reexported through the
//! [standard collections library](../std/collections/index.html).
//!
//! ## Heap interfaces
//!
//! The [`heap`](heap/index.html) module defines the low-level interface to the
@@ -71,8 +75,20 @@
#![no_std]
#![needs_allocator]
#![deny(warnings)]
#![deny(missing_debug_implementations)]
#![cfg_attr(test, allow(deprecated))] // rand
#![cfg_attr(test, feature(placement_in))]
#![cfg_attr(not(test), feature(char_escape_debug))]
#![cfg_attr(not(test), feature(core_float))]
#![cfg_attr(not(test), feature(exact_size_is_empty))]
#![cfg_attr(not(test), feature(slice_rotate))]
#![cfg_attr(not(test), feature(sort_unstable))]
#![cfg_attr(not(test), feature(str_checked_slicing))]
#![cfg_attr(test, feature(rand, test))]
#![feature(allocator)]
#![feature(allow_internal_unstable)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(cfg_target_has_atomic)]
#![feature(coerce_unsized)]
@@ -80,16 +96,33 @@
#![feature(core_intrinsics)]
#![feature(custom_attribute)]
#![feature(dropck_eyepatch)]
#![cfg_attr(not(test), feature(exact_size_is_empty))]
#![feature(exact_size_is_empty)]
#![feature(fmt_internals)]
#![feature(fundamental)]
#![feature(fused)]
#![feature(generic_param_attrs)]
#![feature(i128_type)]
#![feature(inclusive_range)]
#![feature(lang_items)]
#![feature(manually_drop)]
#![feature(needs_allocator)]
#![feature(nonzero)]
#![feature(offset_to)]
#![feature(optin_builtin_traits)]
#![feature(pattern)]
#![feature(placement_in_syntax)]
#![feature(placement_new_protocol)]
#![feature(shared)]
#![feature(slice_get_slice)]
#![feature(slice_patterns)]
#![feature(slice_rsplit)]
#![feature(specialization)]
#![feature(staged_api)]
#![feature(str_internals)]
#![feature(str_mut_extras)]
#![feature(trusted_len)]
#![feature(unboxed_closures)]
#![feature(unicode)]
#![feature(unique)]
#![feature(unsize)]
@@ -101,6 +134,10 @@
#[cfg(test)]
#[macro_use]
extern crate std;
#[cfg(test)]
extern crate test;
extern crate std_unicode;
// Module with internal macros used by other modules (needs to be included before other modules).
#[macro_use]
@@ -120,7 +157,7 @@
pub mod boxed;
#[cfg(test)]
mod boxed {
pub use std::boxed::{Box, HEAP};
pub use std::boxed::{Box, IntermediateBox, HEAP};
}
#[cfg(test)]
mod boxed_test;
@@ -128,8 +165,111 @@ mod boxed {
pub mod arc;
pub mod rc;
pub mod raw_vec;
#[unstable(feature = "str_box_extras", issue = "41119")]
pub mod str;
pub mod oom;
// collections modules
pub mod binary_heap;
mod btree;
pub mod borrow;
pub mod fmt;
pub mod linked_list;
pub mod range;
pub mod slice;
pub mod str;
pub mod string;
pub mod vec;
pub mod vec_deque;
#[stable(feature = "rust1", since = "1.0.0")]
pub mod btree_map {
//! A map based on a B-Tree.
#[stable(feature = "rust1", since = "1.0.0")]
pub use btree::map::*;
}
#[stable(feature = "rust1", since = "1.0.0")]
pub mod btree_set {
//! A set based on a B-Tree.
#[stable(feature = "rust1", since = "1.0.0")]
pub use btree::set::*;
}
#[cfg(not(test))]
mod std {
pub use core::ops; // RangeFull
}
/// An endpoint of a range of keys.
///
/// # Examples
///
/// `Bound`s are range endpoints:
///
/// ```
/// #![feature(collections_range)]
///
/// use std::collections::range::RangeArgument;
/// use std::collections::Bound::*;
///
/// assert_eq!((..100).start(), Unbounded);
/// assert_eq!((1..12).start(), Included(&1));
/// assert_eq!((1..12).end(), Excluded(&12));
/// ```
///
/// Using a tuple of `Bound`s as an argument to [`BTreeMap::range`].
/// Note that in most cases, it's better to use range syntax (`1..5`) instead.
///
/// ```
/// use std::collections::BTreeMap;
/// use std::collections::Bound::{Excluded, Included, Unbounded};
///
/// let mut map = BTreeMap::new();
/// map.insert(3, "a");
/// map.insert(5, "b");
/// map.insert(8, "c");
///
/// for (key, value) in map.range((Excluded(3), Included(8))) {
/// println!("{}: {}", key, value);
/// }
///
/// assert_eq!(Some((&3, &"a")), map.range((Unbounded, Included(5))).next());
/// ```
///
/// [`BTreeMap::range`]: btree_map/struct.BTreeMap.html#method.range
#[stable(feature = "collections_bound", since = "1.17.0")]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub enum Bound<T> {
/// An inclusive bound.
#[stable(feature = "collections_bound", since = "1.17.0")]
Included(T),
/// An exclusive bound.
#[stable(feature = "collections_bound", since = "1.17.0")]
Excluded(T),
/// An infinite endpoint. Indicates that there is no bound in this direction.
#[stable(feature = "collections_bound", since = "1.17.0")]
Unbounded,
}
/// An intermediate trait for specialization of `Extend`.
#[doc(hidden)]
trait SpecExtend<I: IntoIterator> {
/// Extends `self` with the contents of the given iterator.
fn spec_extend(&mut self, iter: I);
}
pub use oom::oom;
#[doc(no_inline)]
pub use binary_heap::BinaryHeap;
#[doc(no_inline)]
pub use btree_map::BTreeMap;
#[doc(no_inline)]
pub use btree_set::BTreeSet;
#[doc(no_inline)]
pub use linked_list::LinkedList;
#[doc(no_inline)]
pub use vec_deque::VecDeque;
#[doc(no_inline)]
pub use string::String;
#[doc(no_inline)]
pub use vec::Vec;
@@ -22,7 +22,6 @@
#![stable(feature = "rust1", since = "1.0.0")]
use alloc::boxed::{Box, IntermediateBox};
use core::cmp::Ordering;
use core::fmt;
use core::hash::{Hasher, Hash};
@@ -32,6 +31,7 @@
use core::ops::{BoxPlace, InPlace, Place, Placer};
use core::ptr::{self, Shared};
use boxed::{Box, IntermediateBox};
use super::SpecExtend;
/// A doubly-linked list with owned nodes.
+83
View File
@@ -8,6 +8,89 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
/// Creates a `Vec` containing the arguments.
///
/// `vec!` allows `Vec`s to be defined with the same syntax as array expressions.
/// There are two forms of this macro:
///
/// - Create a `Vec` containing a given list of elements:
///
/// ```
/// let v = vec![1, 2, 3];
/// assert_eq!(v[0], 1);
/// assert_eq!(v[1], 2);
/// assert_eq!(v[2], 3);
/// ```
///
/// - Create a `Vec` from a given element and size:
///
/// ```
/// let v = vec![1; 3];
/// assert_eq!(v, [1, 1, 1]);
/// ```
///
/// Note that unlike array expressions this syntax supports all elements
/// which implement `Clone` and the number of elements doesn't have to be
/// a constant.
///
/// This will use `clone()` to duplicate an expression, so one should be careful
/// using this with types having a nonstandard `Clone` implementation. For
/// example, `vec![Rc::new(1); 5]` will create a vector of five references
/// to the same boxed integer value, not five references pointing to independently
/// boxed integers.
#[cfg(not(test))]
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable]
macro_rules! vec {
($elem:expr; $n:expr) => (
$crate::vec::from_elem($elem, $n)
);
($($x:expr),*) => (
<[_]>::into_vec(box [$($x),*])
);
($($x:expr,)*) => (vec![$($x),*])
}
// HACK(japaric): with cfg(test) the inherent `[T]::into_vec` method, which is
// required for this macro definition, is not available. Instead use the
// `slice::into_vec` function which is only available with cfg(test)
// NB see the slice::hack module in slice.rs for more information
#[cfg(test)]
macro_rules! vec {
($elem:expr; $n:expr) => (
$crate::vec::from_elem($elem, $n)
);
($($x:expr),*) => (
$crate::slice::into_vec(box [$($x),*])
);
($($x:expr,)*) => (vec![$($x),*])
}
/// Use the syntax described in `std::fmt` to create a value of type `String`.
/// See [`std::fmt`][fmt] for more information.
///
/// [fmt]: ../std/fmt/index.html
///
/// # Panics
///
/// `format!` panics if a formatting trait implementation returns an error.
/// This indicates an incorrect implementation
/// since `fmt::Write for String` never returns an error itself.
///
/// # Examples
///
/// ```
/// format!("test");
/// format!("hello {}", "world!");
/// format!("x = {}, y = {y}", 10, y = 30);
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! format {
($($arg:tt)*) => ($crate::fmt::format(format_args!($($arg)*)))
}
// Private macro to get the offset of a struct field in bytes from the address of the struct.
macro_rules! offset_of {
($container:path, $field:ident) => {{
@@ -27,14 +27,14 @@ pub trait RangeArgument<T: ?Sized> {
/// # Examples
///
/// ```
/// #![feature(collections)]
/// #![feature(alloc)]
/// #![feature(collections_range)]
///
/// extern crate collections;
/// extern crate alloc;
///
/// # fn main() {
/// use collections::range::RangeArgument;
/// use collections::Bound::*;
/// use alloc::range::RangeArgument;
/// use alloc::Bound::*;
///
/// assert_eq!((..10).start(), Unbounded);
/// assert_eq!((3..10).start(), Included(&3));
@@ -49,14 +49,14 @@ pub trait RangeArgument<T: ?Sized> {
/// # Examples
///
/// ```
/// #![feature(collections)]
/// #![feature(alloc)]
/// #![feature(collections_range)]
///
/// extern crate collections;
/// extern crate alloc;
///
/// # fn main() {
/// use collections::range::RangeArgument;
/// use collections::Bound::*;
/// use alloc::range::RangeArgument;
/// use alloc::Bound::*;
///
/// assert_eq!((3..).end(), Unbounded);
/// assert_eq!((3..10).end(), Excluded(&10));
+1
View File
@@ -44,6 +44,7 @@
/// `shrink_to_fit`, and `from_box` will actually set RawVec's private capacity
/// field. This allows zero-sized types to not be special-cased by consumers of
/// this type.
#[allow(missing_debug_implementations)]
pub struct RawVec<T> {
ptr: Unique<T>,
cap: usize,
@@ -97,7 +97,6 @@
// It's cleaner to just turn off the unused_imports warning than to fix them.
#![cfg_attr(test, allow(unused_imports, dead_code))]
use alloc::boxed::Box;
use core::cmp::Ordering::{self, Less};
use core::mem::size_of;
use core::mem;
@@ -105,6 +104,7 @@
use core::slice as core_slice;
use borrow::{Borrow, BorrowMut, ToOwned};
use boxed::Box;
use vec::Vec;
#[stable(feature = "rust1", since = "1.0.0")]
@@ -141,7 +141,7 @@
// `core::slice::SliceExt` - we need to supply these functions for the
// `test_permutations` test
mod hack {
use alloc::boxed::Box;
use boxed::Box;
use core::mem;
#[cfg(test)]
+1983 -2
View File
@@ -8,11 +8,1992 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Methods for dealing with boxed strings.
use core::mem;
//! Unicode string slices.
//!
//! The `&str` type is one of the two main string types, the other being `String`.
//! Unlike its `String` counterpart, its contents are borrowed.
//!
//! # Basic Usage
//!
//! A basic string declaration of `&str` type:
//!
//! ```
//! let hello_world = "Hello, World!";
//! ```
//!
//! Here we have declared a string literal, also known as a string slice.
//! String literals have a static lifetime, which means the string `hello_world`
//! is guaranteed to be valid for the duration of the entire program.
//! We can explicitly specify `hello_world`'s lifetime as well:
//!
//! ```
//! let hello_world: &'static str = "Hello, world!";
//! ```
//!
//! *[See also the `str` primitive type](../../std/primitive.str.html).*
#![stable(feature = "rust1", since = "1.0.0")]
// Many of the usings in this module are only used in the test configuration.
// It's cleaner to just turn off the unused_imports warning than to fix them.
#![allow(unused_imports)]
use core::fmt;
use core::str as core_str;
use core::str::pattern::Pattern;
use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
use core::mem;
use core::iter::FusedIterator;
use std_unicode::str::{UnicodeStr, Utf16Encoder};
use vec_deque::VecDeque;
use borrow::{Borrow, ToOwned};
use string::String;
use std_unicode;
use vec::Vec;
use slice::{SliceConcatExt, SliceIndex};
use boxed::Box;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{FromStr, Utf8Error};
#[allow(deprecated)]
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{Lines, LinesAny};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{Split, RSplit};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{SplitN, RSplitN};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{SplitTerminator, RSplitTerminator};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{Matches, RMatches};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{MatchIndices, RMatchIndices};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{from_utf8, from_utf8_mut, Chars, CharIndices, Bytes};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{from_utf8_unchecked, from_utf8_unchecked_mut, ParseBoolError};
#[stable(feature = "rust1", since = "1.0.0")]
pub use std_unicode::str::SplitWhitespace;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::pattern;
#[unstable(feature = "slice_concat_ext",
reason = "trait should not have to exist",
issue = "27747")]
impl<S: Borrow<str>> SliceConcatExt<str> for [S] {
type Output = String;
fn concat(&self) -> String {
if self.is_empty() {
return String::new();
}
// `len` calculation may overflow but push_str will check boundaries
let len = self.iter().map(|s| s.borrow().len()).sum();
let mut result = String::with_capacity(len);
for s in self {
result.push_str(s.borrow())
}
result
}
fn join(&self, sep: &str) -> String {
if self.is_empty() {
return String::new();
}
// concat is faster
if sep.is_empty() {
return self.concat();
}
// this is wrong without the guarantee that `self` is non-empty
// `len` calculation may overflow but push_str but will check boundaries
let len = sep.len() * (self.len() - 1) +
self.iter().map(|s| s.borrow().len()).sum::<usize>();
let mut result = String::with_capacity(len);
let mut first = true;
for s in self {
if first {
first = false;
} else {
result.push_str(sep);
}
result.push_str(s.borrow());
}
result
}
fn connect(&self, sep: &str) -> String {
self.join(sep)
}
}
/// An iterator of [`u16`] over the string encoded as UTF-16.
///
/// [`u16`]: ../../std/primitive.u16.html
///
/// This struct is created by the [`encode_utf16`] method on [`str`].
/// See its documentation for more.
///
/// [`encode_utf16`]: ../../std/primitive.str.html#method.encode_utf16
/// [`str`]: ../../std/primitive.str.html
#[derive(Clone)]
#[stable(feature = "encode_utf16", since = "1.8.0")]
pub struct EncodeUtf16<'a> {
encoder: Utf16Encoder<Chars<'a>>,
}
#[stable(feature = "collection_debug", since = "1.17.0")]
impl<'a> fmt::Debug for EncodeUtf16<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("EncodeUtf16 { .. }")
}
}
#[stable(feature = "encode_utf16", since = "1.8.0")]
impl<'a> Iterator for EncodeUtf16<'a> {
type Item = u16;
#[inline]
fn next(&mut self) -> Option<u16> {
self.encoder.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.encoder.size_hint()
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a> FusedIterator for EncodeUtf16<'a> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl Borrow<str> for String {
#[inline]
fn borrow(&self) -> &str {
&self[..]
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl ToOwned for str {
type Owned = String;
fn to_owned(&self) -> String {
unsafe { String::from_utf8_unchecked(self.as_bytes().to_owned()) }
}
fn clone_into(&self, target: &mut String) {
let mut b = mem::replace(target, String::new()).into_bytes();
self.as_bytes().clone_into(&mut b);
*target = unsafe { String::from_utf8_unchecked(b) }
}
}
/// Methods for string slices.
#[lang = "str"]
#[cfg(not(test))]
impl str {
/// Returns the length of `self`.
///
/// This length is in bytes, not [`char`]s or graphemes. In other words,
/// it may not be what a human considers the length of the string.
///
/// [`char`]: primitive.char.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let len = "foo".len();
/// assert_eq!(3, len);
///
/// let len = "ƒoo".len(); // fancy f!
/// assert_eq!(4, len);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn len(&self) -> usize {
core_str::StrExt::len(self)
}
/// Returns `true` if `self` has a length of zero bytes.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = "";
/// assert!(s.is_empty());
///
/// let s = "not empty";
/// assert!(!s.is_empty());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn is_empty(&self) -> bool {
core_str::StrExt::is_empty(self)
}
/// Checks that `index`-th byte lies at the start and/or end of a
/// UTF-8 code point sequence.
///
/// The start and end of the string (when `index == self.len()`) are
/// considered to be
/// boundaries.
///
/// Returns `false` if `index` is greater than `self.len()`.
///
/// # Examples
///
/// ```
/// let s = "Löwe 老虎 Léopard";
/// assert!(s.is_char_boundary(0));
/// // start of `老`
/// assert!(s.is_char_boundary(6));
/// assert!(s.is_char_boundary(s.len()));
///
/// // second byte of `ö`
/// assert!(!s.is_char_boundary(2));
///
/// // third byte of `老`
/// assert!(!s.is_char_boundary(8));
/// ```
#[stable(feature = "is_char_boundary", since = "1.9.0")]
#[inline]
pub fn is_char_boundary(&self, index: usize) -> bool {
core_str::StrExt::is_char_boundary(self, index)
}
/// Converts a string slice to a byte slice.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let bytes = "bors".as_bytes();
/// assert_eq!(b"bors", bytes);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline(always)]
pub fn as_bytes(&self) -> &[u8] {
core_str::StrExt::as_bytes(self)
}
/// Converts a mutable string slice to a mutable byte slice.
#[unstable(feature = "str_mut_extras", issue = "41119")]
#[inline(always)]
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
core_str::StrExt::as_bytes_mut(self)
}
/// Converts a string slice to a raw pointer.
///
/// As string slices are a slice of bytes, the raw pointer points to a
/// [`u8`]. This pointer will be pointing to the first byte of the string
/// slice.
///
/// [`u8`]: primitive.u8.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = "Hello";
/// let ptr = s.as_ptr();
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn as_ptr(&self) -> *const u8 {
core_str::StrExt::as_ptr(self)
}
/// Returns a subslice of `str`.
///
/// This is the non-panicking alternative to indexing the `str`. Returns
/// [`None`] whenever equivalent indexing operation would panic.
///
/// [`None`]: option/enum.Option.html#variant.None
///
/// # Examples
///
/// ```
/// # #![feature(str_checked_slicing)]
/// let v = "🗻∈🌏";
/// assert_eq!(Some("🗻"), v.get(0..4));
/// assert!(v.get(1..).is_none());
/// assert!(v.get(..8).is_none());
/// assert!(v.get(..42).is_none());
/// ```
#[unstable(feature = "str_checked_slicing", issue = "39932")]
#[inline]
pub fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
core_str::StrExt::get(self, i)
}
/// Returns a mutable subslice of `str`.
///
/// This is the non-panicking alternative to indexing the `str`. Returns
/// [`None`] whenever equivalent indexing operation would panic.
///
/// [`None`]: option/enum.Option.html#variant.None
///
/// # Examples
///
/// ```
/// # #![feature(str_checked_slicing)]
/// let mut v = String::from("🗻∈🌏");
/// assert_eq!(Some("🗻"), v.get_mut(0..4).map(|v| &*v));
/// assert!(v.get_mut(1..).is_none());
/// assert!(v.get_mut(..8).is_none());
/// assert!(v.get_mut(..42).is_none());
/// ```
#[unstable(feature = "str_checked_slicing", issue = "39932")]
#[inline]
pub fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
core_str::StrExt::get_mut(self, i)
}
/// Returns a unchecked subslice of `str`.
///
/// This is the unchecked alternative to indexing the `str`.
///
/// # Safety
///
/// Callers of this function are responsible that these preconditions are
/// satisfied:
///
/// * The starting index must come before the ending index;
/// * Indexes must be within bounds of the original slice;
/// * Indexes must lie on UTF-8 sequence boundaries.
///
/// Failing that, the returned string slice may reference invalid memory or
/// violate the invariants communicated by the `str` type.
///
/// # Examples
///
/// ```
/// # #![feature(str_checked_slicing)]
/// let v = "🗻∈🌏";
/// unsafe {
/// assert_eq!("🗻", v.get_unchecked(0..4));
/// assert_eq!("∈", v.get_unchecked(4..7));
/// assert_eq!("🌏", v.get_unchecked(7..11));
/// }
/// ```
#[unstable(feature = "str_checked_slicing", issue = "39932")]
#[inline]
pub unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output {
core_str::StrExt::get_unchecked(self, i)
}
/// Returns a mutable, unchecked subslice of `str`.
///
/// This is the unchecked alternative to indexing the `str`.
///
/// # Safety
///
/// Callers of this function are responsible that these preconditions are
/// satisfied:
///
/// * The starting index must come before the ending index;
/// * Indexes must be within bounds of the original slice;
/// * Indexes must lie on UTF-8 sequence boundaries.
///
/// Failing that, the returned string slice may reference invalid memory or
/// violate the invariants communicated by the `str` type.
///
/// # Examples
///
/// ```
/// # #![feature(str_checked_slicing)]
/// let mut v = String::from("🗻∈🌏");
/// unsafe {
/// assert_eq!("🗻", v.get_unchecked_mut(0..4));
/// assert_eq!("∈", v.get_unchecked_mut(4..7));
/// assert_eq!("🌏", v.get_unchecked_mut(7..11));
/// }
/// ```
#[unstable(feature = "str_checked_slicing", issue = "39932")]
#[inline]
pub unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output {
core_str::StrExt::get_unchecked_mut(self, i)
}
/// Creates a string slice from another string slice, bypassing safety
/// checks.
///
/// This is generally not recommended, use with caution! For a safe
/// alternative see [`str`] and [`Index`].
///
/// [`str`]: primitive.str.html
/// [`Index`]: ops/trait.Index.html
///
/// This new slice goes from `begin` to `end`, including `begin` but
/// excluding `end`.
///
/// To get a mutable string slice instead, see the
/// [`slice_mut_unchecked`] method.
///
/// [`slice_mut_unchecked`]: #method.slice_mut_unchecked
///
/// # Safety
///
/// Callers of this function are responsible that three preconditions are
/// satisfied:
///
/// * `begin` must come before `end`.
/// * `begin` and `end` must be byte positions within the string slice.
/// * `begin` and `end` must lie on UTF-8 sequence boundaries.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = "Löwe 老虎 Léopard";
///
/// unsafe {
/// assert_eq!("Löwe 老虎 Léopard", s.slice_unchecked(0, 21));
/// }
///
/// let s = "Hello, world!";
///
/// unsafe {
/// assert_eq!("world", s.slice_unchecked(7, 12));
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
core_str::StrExt::slice_unchecked(self, begin, end)
}
/// Creates a string slice from another string slice, bypassing safety
/// checks.
/// This is generally not recommended, use with caution! For a safe
/// alternative see [`str`] and [`IndexMut`].
///
/// [`str`]: primitive.str.html
/// [`IndexMut`]: ops/trait.IndexMut.html
///
/// This new slice goes from `begin` to `end`, including `begin` but
/// excluding `end`.
///
/// To get an immutable string slice instead, see the
/// [`slice_unchecked`] method.
///
/// [`slice_unchecked`]: #method.slice_unchecked
///
/// # Safety
///
/// Callers of this function are responsible that three preconditions are
/// satisfied:
///
/// * `begin` must come before `end`.
/// * `begin` and `end` must be byte positions within the string slice.
/// * `begin` and `end` must lie on UTF-8 sequence boundaries.
#[stable(feature = "str_slice_mut", since = "1.5.0")]
#[inline]
pub unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str {
core_str::StrExt::slice_mut_unchecked(self, begin, end)
}
/// Divide one string slice into two at an index.
///
/// The argument, `mid`, should be a byte offset from the start of the
/// string. It must also be on the boundary of a UTF-8 code point.
///
/// The two slices returned go from the start of the string slice to `mid`,
/// and from `mid` to the end of the string slice.
///
/// To get mutable string slices instead, see the [`split_at_mut`]
/// method.
///
/// [`split_at_mut`]: #method.split_at_mut
///
/// # Panics
///
/// Panics if `mid` is not on a UTF-8 code point boundary, or if it is
/// beyond the last code point of the string slice.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = "Per Martin-Löf";
///
/// let (first, last) = s.split_at(3);
///
/// assert_eq!("Per", first);
/// assert_eq!(" Martin-Löf", last);
/// ```
#[inline]
#[stable(feature = "str_split_at", since = "1.4.0")]
pub fn split_at(&self, mid: usize) -> (&str, &str) {
core_str::StrExt::split_at(self, mid)
}
/// Divide one mutable string slice into two at an index.
///
/// The argument, `mid`, should be a byte offset from the start of the
/// string. It must also be on the boundary of a UTF-8 code point.
///
/// The two slices returned go from the start of the string slice to `mid`,
/// and from `mid` to the end of the string slice.
///
/// To get immutable string slices instead, see the [`split_at`] method.
///
/// [`split_at`]: #method.split_at
///
/// # Panics
///
/// Panics if `mid` is not on a UTF-8 code point boundary, or if it is
/// beyond the last code point of the string slice.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let mut s = "Per Martin-Löf".to_string();
///
/// let (first, last) = s.split_at_mut(3);
///
/// assert_eq!("Per", first);
/// assert_eq!(" Martin-Löf", last);
/// ```
#[inline]
#[stable(feature = "str_split_at", since = "1.4.0")]
pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
core_str::StrExt::split_at_mut(self, mid)
}
/// Returns an iterator over the [`char`]s of a string slice.
///
/// As a string slice consists of valid UTF-8, we can iterate through a
/// string slice by [`char`]. This method returns such an iterator.
///
/// It's important to remember that [`char`] represents a Unicode Scalar
/// Value, and may not match your idea of what a 'character' is. Iteration
/// over grapheme clusters may be what you actually want.
///
/// [`char`]: primitive.char.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let word = "goodbye";
///
/// let count = word.chars().count();
/// assert_eq!(7, count);
///
/// let mut chars = word.chars();
///
/// assert_eq!(Some('g'), chars.next());
/// assert_eq!(Some('o'), chars.next());
/// assert_eq!(Some('o'), chars.next());
/// assert_eq!(Some('d'), chars.next());
/// assert_eq!(Some('b'), chars.next());
/// assert_eq!(Some('y'), chars.next());
/// assert_eq!(Some('e'), chars.next());
///
/// assert_eq!(None, chars.next());
/// ```
///
/// Remember, [`char`]s may not match your human intuition about characters:
///
/// ```
/// let y = "y̆";
///
/// let mut chars = y.chars();
///
/// assert_eq!(Some('y'), chars.next()); // not 'y̆'
/// assert_eq!(Some('\u{0306}'), chars.next());
///
/// assert_eq!(None, chars.next());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn chars(&self) -> Chars {
core_str::StrExt::chars(self)
}
/// Returns an iterator over the [`char`]s of a string slice, and their
/// positions.
///
/// As a string slice consists of valid UTF-8, we can iterate through a
/// string slice by [`char`]. This method returns an iterator of both
/// these [`char`]s, as well as their byte positions.
///
/// The iterator yields tuples. The position is first, the [`char`] is
/// second.
///
/// [`char`]: primitive.char.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let word = "goodbye";
///
/// let count = word.char_indices().count();
/// assert_eq!(7, count);
///
/// let mut char_indices = word.char_indices();
///
/// assert_eq!(Some((0, 'g')), char_indices.next());
/// assert_eq!(Some((1, 'o')), char_indices.next());
/// assert_eq!(Some((2, 'o')), char_indices.next());
/// assert_eq!(Some((3, 'd')), char_indices.next());
/// assert_eq!(Some((4, 'b')), char_indices.next());
/// assert_eq!(Some((5, 'y')), char_indices.next());
/// assert_eq!(Some((6, 'e')), char_indices.next());
///
/// assert_eq!(None, char_indices.next());
/// ```
///
/// Remember, [`char`]s may not match your human intuition about characters:
///
/// ```
/// let y = "y̆";
///
/// let mut char_indices = y.char_indices();
///
/// assert_eq!(Some((0, 'y')), char_indices.next()); // not (0, 'y̆')
/// assert_eq!(Some((1, '\u{0306}')), char_indices.next());
///
/// assert_eq!(None, char_indices.next());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn char_indices(&self) -> CharIndices {
core_str::StrExt::char_indices(self)
}
/// An iterator over the bytes of a string slice.
///
/// As a string slice consists of a sequence of bytes, we can iterate
/// through a string slice by byte. This method returns such an iterator.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let mut bytes = "bors".bytes();
///
/// assert_eq!(Some(b'b'), bytes.next());
/// assert_eq!(Some(b'o'), bytes.next());
/// assert_eq!(Some(b'r'), bytes.next());
/// assert_eq!(Some(b's'), bytes.next());
///
/// assert_eq!(None, bytes.next());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn bytes(&self) -> Bytes {
core_str::StrExt::bytes(self)
}
/// Split a string slice by whitespace.
///
/// The iterator returned will return string slices that are sub-slices of
/// the original string slice, separated by any amount of whitespace.
///
/// 'Whitespace' is defined according to the terms of the Unicode Derived
/// Core Property `White_Space`.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let mut iter = "A few words".split_whitespace();
///
/// assert_eq!(Some("A"), iter.next());
/// assert_eq!(Some("few"), iter.next());
/// assert_eq!(Some("words"), iter.next());
///
/// assert_eq!(None, iter.next());
/// ```
///
/// All kinds of whitespace are considered:
///
/// ```
/// let mut iter = " Mary had\ta\u{2009}little \n\t lamb".split_whitespace();
/// assert_eq!(Some("Mary"), iter.next());
/// assert_eq!(Some("had"), iter.next());
/// assert_eq!(Some("a"), iter.next());
/// assert_eq!(Some("little"), iter.next());
/// assert_eq!(Some("lamb"), iter.next());
///
/// assert_eq!(None, iter.next());
/// ```
#[stable(feature = "split_whitespace", since = "1.1.0")]
#[inline]
pub fn split_whitespace(&self) -> SplitWhitespace {
UnicodeStr::split_whitespace(self)
}
/// An iterator over the lines of a string, as string slices.
///
/// Lines are ended with either a newline (`\n`) or a carriage return with
/// a line feed (`\r\n`).
///
/// The final line ending is optional.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let text = "foo\r\nbar\n\nbaz\n";
/// let mut lines = text.lines();
///
/// assert_eq!(Some("foo"), lines.next());
/// assert_eq!(Some("bar"), lines.next());
/// assert_eq!(Some(""), lines.next());
/// assert_eq!(Some("baz"), lines.next());
///
/// assert_eq!(None, lines.next());
/// ```
///
/// The final line ending isn't required:
///
/// ```
/// let text = "foo\nbar\n\r\nbaz";
/// let mut lines = text.lines();
///
/// assert_eq!(Some("foo"), lines.next());
/// assert_eq!(Some("bar"), lines.next());
/// assert_eq!(Some(""), lines.next());
/// assert_eq!(Some("baz"), lines.next());
///
/// assert_eq!(None, lines.next());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn lines(&self) -> Lines {
core_str::StrExt::lines(self)
}
/// An iterator over the lines of a string.
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_deprecated(since = "1.4.0", reason = "use lines() instead now")]
#[inline]
#[allow(deprecated)]
pub fn lines_any(&self) -> LinesAny {
core_str::StrExt::lines_any(self)
}
/// Returns an iterator of `u16` over the string encoded as UTF-16.
#[stable(feature = "encode_utf16", since = "1.8.0")]
pub fn encode_utf16(&self) -> EncodeUtf16 {
EncodeUtf16 { encoder: Utf16Encoder::new(self[..].chars()) }
}
/// Returns `true` if the given pattern matches a sub-slice of
/// this string slice.
///
/// Returns `false` if it does not.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let bananas = "bananas";
///
/// assert!(bananas.contains("nana"));
/// assert!(!bananas.contains("apples"));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
core_str::StrExt::contains(self, pat)
}
/// Returns `true` if the given pattern matches a prefix of this
/// string slice.
///
/// Returns `false` if it does not.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let bananas = "bananas";
///
/// assert!(bananas.starts_with("bana"));
/// assert!(!bananas.starts_with("nana"));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
core_str::StrExt::starts_with(self, pat)
}
/// Returns `true` if the given pattern matches a suffix of this
/// string slice.
///
/// Returns `false` if it does not.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let bananas = "bananas";
///
/// assert!(bananas.ends_with("anas"));
/// assert!(!bananas.ends_with("nana"));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
where P::Searcher: ReverseSearcher<'a>
{
core_str::StrExt::ends_with(self, pat)
}
/// Returns the byte index of the first character of this string slice that
/// matches the pattern.
///
/// Returns [`None`] if the pattern doesn't match.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines if
/// a character matches.
///
/// [`char`]: primitive.char.html
/// [`None`]: option/enum.Option.html#variant.None
///
/// # Examples
///
/// Simple patterns:
///
/// ```
/// let s = "Löwe 老虎 Léopard";
///
/// assert_eq!(s.find('L'), Some(0));
/// assert_eq!(s.find('é'), Some(14));
/// assert_eq!(s.find("Léopard"), Some(13));
/// ```
///
/// More complex patterns with closures:
///
/// ```
/// let s = "Löwe 老虎 Léopard";
///
/// assert_eq!(s.find(char::is_whitespace), Some(5));
/// assert_eq!(s.find(char::is_lowercase), Some(1));
/// ```
///
/// Not finding the pattern:
///
/// ```
/// let s = "Löwe 老虎 Léopard";
/// let x: &[_] = &['1', '2'];
///
/// assert_eq!(s.find(x), None);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
core_str::StrExt::find(self, pat)
}
/// Returns the byte index of the last character of this string slice that
/// matches the pattern.
///
/// Returns [`None`] if the pattern doesn't match.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines if
/// a character matches.
///
/// [`char`]: primitive.char.html
/// [`None`]: option/enum.Option.html#variant.None
///
/// # Examples
///
/// Simple patterns:
///
/// ```
/// let s = "Löwe 老虎 Léopard";
///
/// assert_eq!(s.rfind('L'), Some(13));
/// assert_eq!(s.rfind('é'), Some(14));
/// ```
///
/// More complex patterns with closures:
///
/// ```
/// let s = "Löwe 老虎 Léopard";
///
/// assert_eq!(s.rfind(char::is_whitespace), Some(12));
/// assert_eq!(s.rfind(char::is_lowercase), Some(20));
/// ```
///
/// Not finding the pattern:
///
/// ```
/// let s = "Löwe 老虎 Léopard";
/// let x: &[_] = &['1', '2'];
///
/// assert_eq!(s.rfind(x), None);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
where P::Searcher: ReverseSearcher<'a>
{
core_str::StrExt::rfind(self, pat)
}
/// An iterator over substrings of this string slice, separated by
/// characters matched by a pattern.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines the
/// split.
///
/// # Iterator behavior
///
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
/// allows a reverse search and forward/reverse search yields the same
/// elements. This is true for, eg, [`char`] but not for `&str`.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
///
/// If the pattern allows a reverse search but its results might differ
/// from a forward search, the [`rsplit`] method can be used.
///
/// [`char`]: primitive.char.html
/// [`rsplit`]: #method.rsplit
///
/// # Examples
///
/// Simple patterns:
///
/// ```
/// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
/// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
///
/// let v: Vec<&str> = "".split('X').collect();
/// assert_eq!(v, [""]);
///
/// let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect();
/// assert_eq!(v, ["lion", "", "tiger", "leopard"]);
///
/// let v: Vec<&str> = "lion::tiger::leopard".split("::").collect();
/// assert_eq!(v, ["lion", "tiger", "leopard"]);
///
/// let v: Vec<&str> = "abc1def2ghi".split(char::is_numeric).collect();
/// assert_eq!(v, ["abc", "def", "ghi"]);
///
/// let v: Vec<&str> = "lionXtigerXleopard".split(char::is_uppercase).collect();
/// assert_eq!(v, ["lion", "tiger", "leopard"]);
/// ```
///
/// A more complex pattern, using a closure:
///
/// ```
/// let v: Vec<&str> = "abc1defXghi".split(|c| c == '1' || c == 'X').collect();
/// assert_eq!(v, ["abc", "def", "ghi"]);
/// ```
///
/// If a string contains multiple contiguous separators, you will end up
/// with empty strings in the output:
///
/// ```
/// let x = "||||a||b|c".to_string();
/// let d: Vec<_> = x.split('|').collect();
///
/// assert_eq!(d, &["", "", "", "", "a", "", "b", "c"]);
/// ```
///
/// Contiguous separators are separated by the empty string.
///
/// ```
/// let x = "(///)".to_string();
/// let d: Vec<_> = x.split('/').collect();
///
/// assert_eq!(d, &["(", "", "", ")"]);
/// ```
///
/// Separators at the start or end of a string are neighbored
/// by empty strings.
///
/// ```
/// let d: Vec<_> = "010".split("0").collect();
/// assert_eq!(d, &["", "1", ""]);
/// ```
///
/// When the empty string is used as a separator, it separates
/// every character in the string, along with the beginning
/// and end of the string.
///
/// ```
/// let f: Vec<_> = "rust".split("").collect();
/// assert_eq!(f, &["", "r", "u", "s", "t", ""]);
/// ```
///
/// Contiguous separators can lead to possibly surprising behavior
/// when whitespace is used as the separator. This code is correct:
///
/// ```
/// let x = " a b c".to_string();
/// let d: Vec<_> = x.split(' ').collect();
///
/// assert_eq!(d, &["", "", "", "", "a", "", "b", "c"]);
/// ```
///
/// It does _not_ give you:
///
/// ```,ignore
/// assert_eq!(d, &["a", "b", "c"]);
/// ```
///
/// Use [`split_whitespace`] for this behavior.
///
/// [`split_whitespace`]: #method.split_whitespace
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
core_str::StrExt::split(self, pat)
}
/// An iterator over substrings of the given string slice, separated by
/// characters matched by a pattern and yielded in reverse order.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines the
/// split.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator requires that the pattern supports a reverse
/// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse
/// search yields the same elements.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
///
/// For iterating from the front, the [`split`] method can be used.
///
/// [`split`]: #method.split
///
/// # Examples
///
/// Simple patterns:
///
/// ```
/// let v: Vec<&str> = "Mary had a little lamb".rsplit(' ').collect();
/// assert_eq!(v, ["lamb", "little", "a", "had", "Mary"]);
///
/// let v: Vec<&str> = "".rsplit('X').collect();
/// assert_eq!(v, [""]);
///
/// let v: Vec<&str> = "lionXXtigerXleopard".rsplit('X').collect();
/// assert_eq!(v, ["leopard", "tiger", "", "lion"]);
///
/// let v: Vec<&str> = "lion::tiger::leopard".rsplit("::").collect();
/// assert_eq!(v, ["leopard", "tiger", "lion"]);
/// ```
///
/// A more complex pattern, using a closure:
///
/// ```
/// let v: Vec<&str> = "abc1defXghi".rsplit(|c| c == '1' || c == 'X').collect();
/// assert_eq!(v, ["ghi", "def", "abc"]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
core_str::StrExt::rsplit(self, pat)
}
/// An iterator over substrings of the given string slice, separated by
/// characters matched by a pattern.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines the
/// split.
///
/// Equivalent to [`split`], except that the trailing substring
/// is skipped if empty.
///
/// [`split`]: #method.split
///
/// This method can be used for string data that is _terminated_,
/// rather than _separated_ by a pattern.
///
/// # Iterator behavior
///
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
/// allows a reverse search and forward/reverse search yields the same
/// elements. This is true for, eg, [`char`] but not for `&str`.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
/// [`char`]: primitive.char.html
///
/// If the pattern allows a reverse search but its results might differ
/// from a forward search, the [`rsplit_terminator`] method can be used.
///
/// [`rsplit_terminator`]: #method.rsplit_terminator
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let v: Vec<&str> = "A.B.".split_terminator('.').collect();
/// assert_eq!(v, ["A", "B"]);
///
/// let v: Vec<&str> = "A..B..".split_terminator(".").collect();
/// assert_eq!(v, ["A", "", "B", ""]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> {
core_str::StrExt::split_terminator(self, pat)
}
/// An iterator over substrings of `self`, separated by characters
/// matched by a pattern and yielded in reverse order.
///
/// The pattern can be a simple `&str`, [`char`], or a closure that
/// determines the split.
/// Additional libraries might provide more complex patterns like
/// regular expressions.
///
/// [`char`]: primitive.char.html
///
/// Equivalent to [`split`], except that the trailing substring is
/// skipped if empty.
///
/// [`split`]: #method.split
///
/// This method can be used for string data that is _terminated_,
/// rather than _separated_ by a pattern.
///
/// # Iterator behavior
///
/// The returned iterator requires that the pattern supports a
/// reverse search, and it will be double ended if a forward/reverse
/// search yields the same elements.
///
/// For iterating from the front, the [`split_terminator`] method can be
/// used.
///
/// [`split_terminator`]: #method.split_terminator
///
/// # Examples
///
/// ```
/// let v: Vec<&str> = "A.B.".rsplit_terminator('.').collect();
/// assert_eq!(v, ["B", "A"]);
///
/// let v: Vec<&str> = "A..B..".rsplit_terminator(".").collect();
/// assert_eq!(v, ["", "B", "", "A"]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
core_str::StrExt::rsplit_terminator(self, pat)
}
/// An iterator over substrings of the given string slice, separated by a
/// pattern, restricted to returning at most `n` items.
///
/// If `n` substrings are returned, the last substring (the `n`th substring)
/// will contain the remainder of the string.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines the
/// split.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator will not be double ended, because it is
/// not efficient to support.
///
/// If the pattern allows a reverse search, the [`rsplitn`] method can be
/// used.
///
/// [`rsplitn`]: #method.rsplitn
///
/// # Examples
///
/// Simple patterns:
///
/// ```
/// let v: Vec<&str> = "Mary had a little lambda".splitn(3, ' ').collect();
/// assert_eq!(v, ["Mary", "had", "a little lambda"]);
///
/// let v: Vec<&str> = "lionXXtigerXleopard".splitn(3, "X").collect();
/// assert_eq!(v, ["lion", "", "tigerXleopard"]);
///
/// let v: Vec<&str> = "abcXdef".splitn(1, 'X').collect();
/// assert_eq!(v, ["abcXdef"]);
///
/// let v: Vec<&str> = "".splitn(1, 'X').collect();
/// assert_eq!(v, [""]);
/// ```
///
/// A more complex pattern, using a closure:
///
/// ```
/// let v: Vec<&str> = "abc1defXghi".splitn(2, |c| c == '1' || c == 'X').collect();
/// assert_eq!(v, ["abc", "defXghi"]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn splitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> SplitN<'a, P> {
core_str::StrExt::splitn(self, n, pat)
}
/// An iterator over substrings of this string slice, separated by a
/// pattern, starting from the end of the string, restricted to returning
/// at most `n` items.
///
/// If `n` substrings are returned, the last substring (the `n`th substring)
/// will contain the remainder of the string.
///
/// The pattern can be a `&str`, [`char`], or a closure that
/// determines the split.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator will not be double ended, because it is not
/// efficient to support.
///
/// For splitting from the front, the [`splitn`] method can be used.
///
/// [`splitn`]: #method.splitn
///
/// # Examples
///
/// Simple patterns:
///
/// ```
/// let v: Vec<&str> = "Mary had a little lamb".rsplitn(3, ' ').collect();
/// assert_eq!(v, ["lamb", "little", "Mary had a"]);
///
/// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(3, 'X').collect();
/// assert_eq!(v, ["leopard", "tiger", "lionX"]);
///
/// let v: Vec<&str> = "lion::tiger::leopard".rsplitn(2, "::").collect();
/// assert_eq!(v, ["leopard", "lion::tiger"]);
/// ```
///
/// A more complex pattern, using a closure:
///
/// ```
/// let v: Vec<&str> = "abc1defXghi".rsplitn(2, |c| c == '1' || c == 'X').collect();
/// assert_eq!(v, ["ghi", "abc1def"]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> RSplitN<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
core_str::StrExt::rsplitn(self, n, pat)
}
/// An iterator over the disjoint matches of a pattern within the given string
/// slice.
///
/// The pattern can be a `&str`, [`char`], or a closure that
/// determines if a character matches.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
/// allows a reverse search and forward/reverse search yields the same
/// elements. This is true for, eg, [`char`] but not for `&str`.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
/// [`char`]: primitive.char.html
///
/// If the pattern allows a reverse search but its results might differ
/// from a forward search, the [`rmatches`] method can be used.
///
/// [`rmatches`]: #method.rmatches
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let v: Vec<&str> = "abcXXXabcYYYabc".matches("abc").collect();
/// assert_eq!(v, ["abc", "abc", "abc"]);
///
/// let v: Vec<&str> = "1abc2abc3".matches(char::is_numeric).collect();
/// assert_eq!(v, ["1", "2", "3"]);
/// ```
#[stable(feature = "str_matches", since = "1.2.0")]
#[inline]
pub fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> {
core_str::StrExt::matches(self, pat)
}
/// An iterator over the disjoint matches of a pattern within this string slice,
/// yielded in reverse order.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines if
/// a character matches.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator requires that the pattern supports a reverse
/// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse
/// search yields the same elements.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
///
/// For iterating from the front, the [`matches`] method can be used.
///
/// [`matches`]: #method.matches
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let v: Vec<&str> = "abcXXXabcYYYabc".rmatches("abc").collect();
/// assert_eq!(v, ["abc", "abc", "abc"]);
///
/// let v: Vec<&str> = "1abc2abc3".rmatches(char::is_numeric).collect();
/// assert_eq!(v, ["3", "2", "1"]);
/// ```
#[stable(feature = "str_matches", since = "1.2.0")]
#[inline]
pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
core_str::StrExt::rmatches(self, pat)
}
/// An iterator over the disjoint matches of a pattern within this string
/// slice as well as the index that the match starts at.
///
/// For matches of `pat` within `self` that overlap, only the indices
/// corresponding to the first match are returned.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines
/// if a character matches.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
/// allows a reverse search and forward/reverse search yields the same
/// elements. This is true for, eg, [`char`] but not for `&str`.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
///
/// If the pattern allows a reverse search but its results might differ
/// from a forward search, the [`rmatch_indices`] method can be used.
///
/// [`rmatch_indices`]: #method.rmatch_indices
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let v: Vec<_> = "abcXXXabcYYYabc".match_indices("abc").collect();
/// assert_eq!(v, [(0, "abc"), (6, "abc"), (12, "abc")]);
///
/// let v: Vec<_> = "1abcabc2".match_indices("abc").collect();
/// assert_eq!(v, [(1, "abc"), (4, "abc")]);
///
/// let v: Vec<_> = "ababa".match_indices("aba").collect();
/// assert_eq!(v, [(0, "aba")]); // only the first `aba`
/// ```
#[stable(feature = "str_match_indices", since = "1.5.0")]
#[inline]
pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> {
core_str::StrExt::match_indices(self, pat)
}
/// An iterator over the disjoint matches of a pattern within `self`,
/// yielded in reverse order along with the index of the match.
///
/// For matches of `pat` within `self` that overlap, only the indices
/// corresponding to the last match are returned.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines if a
/// character matches.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator requires that the pattern supports a reverse
/// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse
/// search yields the same elements.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
///
/// For iterating from the front, the [`match_indices`] method can be used.
///
/// [`match_indices`]: #method.match_indices
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let v: Vec<_> = "abcXXXabcYYYabc".rmatch_indices("abc").collect();
/// assert_eq!(v, [(12, "abc"), (6, "abc"), (0, "abc")]);
///
/// let v: Vec<_> = "1abcabc2".rmatch_indices("abc").collect();
/// assert_eq!(v, [(4, "abc"), (1, "abc")]);
///
/// let v: Vec<_> = "ababa".rmatch_indices("aba").collect();
/// assert_eq!(v, [(2, "aba")]); // only the last `aba`
/// ```
#[stable(feature = "str_match_indices", since = "1.5.0")]
#[inline]
pub fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
core_str::StrExt::rmatch_indices(self, pat)
}
/// Returns a string slice with leading and trailing whitespace removed.
///
/// 'Whitespace' is defined according to the terms of the Unicode Derived
/// Core Property `White_Space`.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = " Hello\tworld\t";
///
/// assert_eq!("Hello\tworld", s.trim());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn trim(&self) -> &str {
UnicodeStr::trim(self)
}
/// Returns a string slice with leading whitespace removed.
///
/// 'Whitespace' is defined according to the terms of the Unicode Derived
/// Core Property `White_Space`.
///
/// # Text directionality
///
/// A string is a sequence of bytes. 'Left' in this context means the first
/// position of that byte string; for a language like Arabic or Hebrew
/// which are 'right to left' rather than 'left to right', this will be
/// the _right_ side, not the left.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = " Hello\tworld\t";
///
/// assert_eq!("Hello\tworld\t", s.trim_left());
/// ```
///
/// Directionality:
///
/// ```
/// let s = " English";
/// assert!(Some('E') == s.trim_left().chars().next());
///
/// let s = " עברית";
/// assert!(Some('ע') == s.trim_left().chars().next());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn trim_left(&self) -> &str {
UnicodeStr::trim_left(self)
}
/// Returns a string slice with trailing whitespace removed.
///
/// 'Whitespace' is defined according to the terms of the Unicode Derived
/// Core Property `White_Space`.
///
/// # Text directionality
///
/// A string is a sequence of bytes. 'Right' in this context means the last
/// position of that byte string; for a language like Arabic or Hebrew
/// which are 'right to left' rather than 'left to right', this will be
/// the _left_ side, not the right.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = " Hello\tworld\t";
///
/// assert_eq!(" Hello\tworld", s.trim_right());
/// ```
///
/// Directionality:
///
/// ```
/// let s = "English ";
/// assert!(Some('h') == s.trim_right().chars().rev().next());
///
/// let s = "עברית ";
/// assert!(Some('ת') == s.trim_right().chars().rev().next());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn trim_right(&self) -> &str {
UnicodeStr::trim_right(self)
}
/// Returns a string slice with all prefixes and suffixes that match a
/// pattern repeatedly removed.
///
/// The pattern can be a [`char`] or a closure that determines if a
/// character matches.
///
/// [`char`]: primitive.char.html
///
/// # Examples
///
/// Simple patterns:
///
/// ```
/// assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
/// assert_eq!("123foo1bar123".trim_matches(char::is_numeric), "foo1bar");
///
/// let x: &[_] = &['1', '2'];
/// assert_eq!("12foo1bar12".trim_matches(x), "foo1bar");
/// ```
///
/// A more complex pattern, using a closure:
///
/// ```
/// assert_eq!("1foo1barXX".trim_matches(|c| c == '1' || c == 'X'), "foo1bar");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
where P::Searcher: DoubleEndedSearcher<'a>
{
core_str::StrExt::trim_matches(self, pat)
}
/// Returns a string slice with all prefixes that match a pattern
/// repeatedly removed.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines if
/// a character matches.
///
/// [`char`]: primitive.char.html
///
/// # Text directionality
///
/// A string is a sequence of bytes. 'Left' in this context means the first
/// position of that byte string; for a language like Arabic or Hebrew
/// which are 'right to left' rather than 'left to right', this will be
/// the _right_ side, not the left.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
/// assert_eq!("123foo1bar123".trim_left_matches(char::is_numeric), "foo1bar123");
///
/// let x: &[_] = &['1', '2'];
/// assert_eq!("12foo1bar12".trim_left_matches(x), "foo1bar12");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
core_str::StrExt::trim_left_matches(self, pat)
}
/// Returns a string slice with all suffixes that match a pattern
/// repeatedly removed.
///
/// The pattern can be a `&str`, [`char`], or a closure that
/// determines if a character matches.
///
/// [`char`]: primitive.char.html
///
/// # Text directionality
///
/// A string is a sequence of bytes. 'Right' in this context means the last
/// position of that byte string; for a language like Arabic or Hebrew
/// which are 'right to left' rather than 'left to right', this will be
/// the _left_ side, not the right.
///
/// # Examples
///
/// Simple patterns:
///
/// ```
/// assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
/// assert_eq!("123foo1bar123".trim_right_matches(char::is_numeric), "123foo1bar");
///
/// let x: &[_] = &['1', '2'];
/// assert_eq!("12foo1bar12".trim_right_matches(x), "12foo1bar");
/// ```
///
/// A more complex pattern, using a closure:
///
/// ```
/// assert_eq!("1fooX".trim_left_matches(|c| c == '1' || c == 'X'), "fooX");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
where P::Searcher: ReverseSearcher<'a>
{
core_str::StrExt::trim_right_matches(self, pat)
}
/// Parses this string slice into another type.
///
/// Because `parse` is so general, it can cause problems with type
/// inference. As such, `parse` is one of the few times you'll see
/// the syntax affectionately known as the 'turbofish': `::<>`. This
/// helps the inference algorithm understand specifically which type
/// you're trying to parse into.
///
/// `parse` can parse any type that implements the [`FromStr`] trait.
///
/// [`FromStr`]: str/trait.FromStr.html
///
/// # Errors
///
/// Will return [`Err`] if it's not possible to parse this string slice into
/// the desired type.
///
/// [`Err`]: str/trait.FromStr.html#associatedtype.Err
///
/// # Example
///
/// Basic usage
///
/// ```
/// let four: u32 = "4".parse().unwrap();
///
/// assert_eq!(4, four);
/// ```
///
/// Using the 'turbofish' instead of annotating `four`:
///
/// ```
/// let four = "4".parse::<u32>();
///
/// assert_eq!(Ok(4), four);
/// ```
///
/// Failing to parse:
///
/// ```
/// let nope = "j".parse::<u32>();
///
/// assert!(nope.is_err());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
core_str::StrExt::parse(self)
}
/// Converts a `Box<str>` into a `Box<[u8]>` without copying or allocating.
#[unstable(feature = "str_box_extras", issue = "41119")]
pub fn into_boxed_bytes(self: Box<str>) -> Box<[u8]> {
self.into()
}
/// Replaces all matches of a pattern with another string.
///
/// `replace` creates a new [`String`], and copies the data from this string slice into it.
/// While doing so, it attempts to find matches of a pattern. If it finds any, it
/// replaces them with the replacement string slice.
///
/// [`String`]: string/struct.String.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = "this is old";
///
/// assert_eq!("this is new", s.replace("old", "new"));
/// ```
///
/// When the pattern doesn't match:
///
/// ```
/// let s = "this is old";
/// assert_eq!(s, s.replace("cookie monster", "little lamb"));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn replace<'a, P: Pattern<'a>>(&'a self, from: P, to: &str) -> String {
let mut result = String::new();
let mut last_end = 0;
for (start, part) in self.match_indices(from) {
result.push_str(unsafe { self.slice_unchecked(last_end, start) });
result.push_str(to);
last_end = start + part.len();
}
result.push_str(unsafe { self.slice_unchecked(last_end, self.len()) });
result
}
/// Replaces first N matches of a pattern with another string.
///
/// `replacen` creates a new [`String`], and copies the data from this string slice into it.
/// While doing so, it attempts to find matches of a pattern. If it finds any, it
/// replaces them with the replacement string slice at most `count` times.
///
/// [`String`]: string/struct.String.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = "foo foo 123 foo";
/// assert_eq!("new new 123 foo", s.replacen("foo", "new", 2));
/// assert_eq!("faa fao 123 foo", s.replacen('o', "a", 3));
/// assert_eq!("foo foo new23 foo", s.replacen(char::is_numeric, "new", 1));
/// ```
///
/// When the pattern doesn't match:
///
/// ```
/// let s = "this is old";
/// assert_eq!(s, s.replacen("cookie monster", "little lamb", 10));
/// ```
#[stable(feature = "str_replacen", since = "1.16.0")]
pub fn replacen<'a, P: Pattern<'a>>(&'a self, pat: P, to: &str, count: usize) -> String {
// Hope to reduce the times of re-allocation
let mut result = String::with_capacity(32);
let mut last_end = 0;
for (start, part) in self.match_indices(pat).take(count) {
result.push_str(unsafe { self.slice_unchecked(last_end, start) });
result.push_str(to);
last_end = start + part.len();
}
result.push_str(unsafe { self.slice_unchecked(last_end, self.len()) });
result
}
/// Returns the lowercase equivalent of this string slice, as a new [`String`].
///
/// 'Lowercase' is defined according to the terms of the Unicode Derived Core Property
/// `Lowercase`.
///
/// Since some characters can expand into multiple characters when changing
/// the case, this function returns a [`String`] instead of modifying the
/// parameter in-place.
///
/// [`String`]: string/struct.String.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = "HELLO";
///
/// assert_eq!("hello", s.to_lowercase());
/// ```
///
/// A tricky example, with sigma:
///
/// ```
/// let sigma = "Σ";
///
/// assert_eq!("σ", sigma.to_lowercase());
///
/// // but at the end of a word, it's ς, not σ:
/// let odysseus = "ὈΔΥΣΣΕΎΣ";
///
/// assert_eq!("ὀδυσσεύς", odysseus.to_lowercase());
/// ```
///
/// Languages without case are not changed:
///
/// ```
/// let new_year = "农历新年";
///
/// assert_eq!(new_year, new_year.to_lowercase());
/// ```
#[stable(feature = "unicode_case_mapping", since = "1.2.0")]
pub fn to_lowercase(&self) -> String {
let mut s = String::with_capacity(self.len());
for (i, c) in self[..].char_indices() {
if c == 'Σ' {
// Σ maps to σ, except at the end of a word where it maps to ς.
// This is the only conditional (contextual) but language-independent mapping
// in `SpecialCasing.txt`,
// so hard-code it rather than have a generic "condition" mechanism.
// See https://github.com/rust-lang/rust/issues/26035
map_uppercase_sigma(self, i, &mut s)
} else {
s.extend(c.to_lowercase());
}
}
return s;
fn map_uppercase_sigma(from: &str, i: usize, to: &mut String) {
// See http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992
// for the definition of `Final_Sigma`.
debug_assert!('Σ'.len_utf8() == 2);
let is_word_final = case_ignoreable_then_cased(from[..i].chars().rev()) &&
!case_ignoreable_then_cased(from[i + 2..].chars());
to.push_str(if is_word_final { "ς" } else { "σ" });
}
fn case_ignoreable_then_cased<I: Iterator<Item = char>>(iter: I) -> bool {
use std_unicode::derived_property::{Cased, Case_Ignorable};
match iter.skip_while(|&c| Case_Ignorable(c)).next() {
Some(c) => Cased(c),
None => false,
}
}
}
/// Returns the uppercase equivalent of this string slice, as a new [`String`].
///
/// 'Uppercase' is defined according to the terms of the Unicode Derived Core Property
/// `Uppercase`.
///
/// Since some characters can expand into multiple characters when changing
/// the case, this function returns a [`String`] instead of modifying the
/// parameter in-place.
///
/// [`String`]: string/struct.String.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = "hello";
///
/// assert_eq!("HELLO", s.to_uppercase());
/// ```
///
/// Scripts without case are not changed:
///
/// ```
/// let new_year = "农历新年";
///
/// assert_eq!(new_year, new_year.to_uppercase());
/// ```
#[stable(feature = "unicode_case_mapping", since = "1.2.0")]
pub fn to_uppercase(&self) -> String {
let mut s = String::with_capacity(self.len());
s.extend(self.chars().flat_map(|c| c.to_uppercase()));
return s;
}
/// Escapes each char in `s` with [`char::escape_debug`].
///
/// [`char::escape_debug`]: primitive.char.html#method.escape_debug
#[unstable(feature = "str_escape",
reason = "return type may change to be an iterator",
issue = "27791")]
pub fn escape_debug(&self) -> String {
self.chars().flat_map(|c| c.escape_debug()).collect()
}
/// Escapes each char in `s` with [`char::escape_default`].
///
/// [`char::escape_default`]: primitive.char.html#method.escape_default
#[unstable(feature = "str_escape",
reason = "return type may change to be an iterator",
issue = "27791")]
pub fn escape_default(&self) -> String {
self.chars().flat_map(|c| c.escape_default()).collect()
}
/// Escapes each char in `s` with [`char::escape_unicode`].
///
/// [`char::escape_unicode`]: primitive.char.html#method.escape_unicode
#[unstable(feature = "str_escape",
reason = "return type may change to be an iterator",
issue = "27791")]
pub fn escape_unicode(&self) -> String {
self.chars().flat_map(|c| c.escape_unicode()).collect()
}
/// Converts a [`Box<str>`] into a [`String`] without copying or allocating.
///
/// [`String`]: string/struct.String.html
/// [`Box<str>`]: boxed/struct.Box.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let string = String::from("birthday gift");
/// let boxed_str = string.clone().into_boxed_str();
///
/// assert_eq!(boxed_str.into_string(), string);
/// ```
#[stable(feature = "box_str", since = "1.4.0")]
pub fn into_string(self: Box<str>) -> String {
unsafe {
let slice = mem::transmute::<Box<str>, Box<[u8]>>(self);
String::from_utf8_unchecked(slice.into_vec())
}
}
/// Create a [`String`] by repeating a string `n` times.
///
/// [`String`]: string/struct.String.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// assert_eq!("abc".repeat(4), String::from("abcabcabcabc"));
/// ```
#[stable(feature = "repeat_str", since = "1.16.0")]
pub fn repeat(&self, n: usize) -> String {
let mut s = String::with_capacity(self.len() * n);
s.extend((0..n).map(|_| self));
s
}
}
/// Converts a boxed slice of bytes to a boxed string slice without checking
/// that the string contains valid UTF-8.
#[unstable(feature = "str_box_extras", issue = "41119")]
@@ -56,8 +56,6 @@
#![stable(feature = "rust1", since = "1.0.0")]
use alloc::str as alloc_str;
use core::fmt;
use core::hash;
use core::iter::{FromIterator, FusedIterator};
@@ -70,7 +68,7 @@
use borrow::{Cow, ToOwned};
use range::RangeArgument;
use Bound::{Excluded, Included, Unbounded};
use str::{self, FromStr, Utf8Error, Chars};
use str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars};
use vec::Vec;
use boxed::Box;
@@ -1464,7 +1462,7 @@ pub fn splice<'a, 'b, R>(&'a mut self, range: R, replace_with: &'b str) -> Splic
#[stable(feature = "box_str", since = "1.4.0")]
pub fn into_boxed_str(self) -> Box<str> {
let slice = self.vec.into_boxed_slice();
unsafe { alloc_str::from_boxed_utf8_unchecked(slice) }
unsafe { from_boxed_utf8_unchecked(slice) }
}
}
@@ -10,11 +10,11 @@
#![deny(warnings)]
#![feature(alloc)]
#![feature(attr_literals)]
#![feature(box_syntax)]
#![feature(inclusive_range_syntax)]
#![feature(collection_placement)]
#![feature(collections)]
#![feature(const_fn)]
#![feature(exact_size_is_empty)]
#![feature(iterator_step_by)]
@@ -31,7 +31,7 @@
#![feature(unicode)]
#![feature(utf8_error_error_len)]
extern crate collections;
extern crate alloc;
extern crate test;
extern crate std_unicode;
extern crate core;
@@ -66,10 +66,6 @@
#![stable(feature = "rust1", since = "1.0.0")]
use alloc::boxed::Box;
use alloc::raw_vec::RawVec;
use borrow::ToOwned;
use borrow::Cow;
use core::cmp::Ordering;
use core::fmt;
use core::hash::{self, Hash};
@@ -84,6 +80,10 @@
use core::ptr::Shared;
use core::slice;
use borrow::ToOwned;
use borrow::Cow;
use boxed::Box;
use raw_vec::RawVec;
use super::range::RangeArgument;
use Bound::{Excluded, Included, Unbounded};
@@ -29,7 +29,7 @@
use core::hash::{Hash, Hasher};
use core::cmp;
use alloc::raw_vec::RawVec;
use raw_vec::RawVec;
use super::range::RangeArgument;
use Bound::{Excluded, Included, Unbounded};
-21
View File
@@ -1,21 +0,0 @@
[package]
authors = ["The Rust Project Developers"]
name = "collections"
version = "0.0.0"
[lib]
name = "collections"
path = "lib.rs"
[dependencies]
alloc = { path = "../liballoc" }
core = { path = "../libcore" }
std_unicode = { path = "../libstd_unicode" }
[[test]]
name = "collectionstests"
path = "../libcollections/tests/lib.rs"
[[bench]]
name = "collectionsbenches"
path = "../libcollections/benches/lib.rs"
-192
View File
@@ -1,192 +0,0 @@
// Copyright 2013-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.
//! Collection types.
//!
//! See [`std::collections`](../std/collections/index.html) for a detailed
//! discussion of collections in Rust.
#![crate_name = "collections"]
#![crate_type = "rlib"]
#![unstable(feature = "collections",
reason = "library is unlikely to be stabilized with the current \
layout and name, use std::collections instead",
issue = "27783")]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/",
html_playground_url = "https://play.rust-lang.org/",
issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]
#![cfg_attr(test, allow(deprecated))] // rand
#![deny(warnings)]
#![deny(missing_debug_implementations)]
#![feature(alloc)]
#![feature(allow_internal_unstable)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![cfg_attr(not(test), feature(char_escape_debug))]
#![cfg_attr(not(test), feature(core_float))]
#![feature(core_intrinsics)]
#![feature(dropck_eyepatch)]
#![feature(exact_size_is_empty)]
#![feature(fmt_internals)]
#![feature(fused)]
#![feature(generic_param_attrs)]
#![feature(heap_api)]
#![feature(i128_type)]
#![feature(inclusive_range)]
#![feature(lang_items)]
#![feature(manually_drop)]
#![feature(nonzero)]
#![feature(pattern)]
#![feature(placement_in)]
#![feature(placement_in_syntax)]
#![feature(placement_new_protocol)]
#![feature(shared)]
#![feature(slice_get_slice)]
#![feature(slice_patterns)]
#![cfg_attr(not(test), feature(slice_rotate))]
#![feature(slice_rsplit)]
#![cfg_attr(not(test), feature(sort_unstable))]
#![feature(specialization)]
#![feature(staged_api)]
#![feature(str_internals)]
#![feature(str_box_extras)]
#![feature(str_mut_extras)]
#![feature(trusted_len)]
#![feature(unicode)]
#![feature(unique)]
#![cfg_attr(not(test), feature(str_checked_slicing))]
#![cfg_attr(test, feature(rand, test))]
#![feature(offset_to)]
#![no_std]
extern crate std_unicode;
extern crate alloc;
#[cfg(test)]
#[macro_use]
extern crate std;
#[cfg(test)]
extern crate test;
#[doc(no_inline)]
pub use binary_heap::BinaryHeap;
#[doc(no_inline)]
pub use btree_map::BTreeMap;
#[doc(no_inline)]
pub use btree_set::BTreeSet;
#[doc(no_inline)]
pub use linked_list::LinkedList;
#[doc(no_inline)]
pub use vec_deque::VecDeque;
#[doc(no_inline)]
pub use string::String;
#[doc(no_inline)]
pub use vec::Vec;
// Needed for the vec! macro
pub use alloc::boxed;
#[macro_use]
mod macros;
pub mod binary_heap;
mod btree;
pub mod borrow;
pub mod fmt;
pub mod linked_list;
pub mod range;
pub mod slice;
pub mod str;
pub mod string;
pub mod vec;
pub mod vec_deque;
#[stable(feature = "rust1", since = "1.0.0")]
pub mod btree_map {
//! A map based on a B-Tree.
#[stable(feature = "rust1", since = "1.0.0")]
pub use btree::map::*;
}
#[stable(feature = "rust1", since = "1.0.0")]
pub mod btree_set {
//! A set based on a B-Tree.
#[stable(feature = "rust1", since = "1.0.0")]
pub use btree::set::*;
}
#[cfg(not(test))]
mod std {
pub use core::ops; // RangeFull
}
/// An endpoint of a range of keys.
///
/// # Examples
///
/// `Bound`s are range endpoints:
///
/// ```
/// #![feature(collections_range)]
///
/// use std::collections::range::RangeArgument;
/// use std::collections::Bound::*;
///
/// assert_eq!((..100).start(), Unbounded);
/// assert_eq!((1..12).start(), Included(&1));
/// assert_eq!((1..12).end(), Excluded(&12));
/// ```
///
/// Using a tuple of `Bound`s as an argument to [`BTreeMap::range`].
/// Note that in most cases, it's better to use range syntax (`1..5`) instead.
///
/// ```
/// use std::collections::BTreeMap;
/// use std::collections::Bound::{Excluded, Included, Unbounded};
///
/// let mut map = BTreeMap::new();
/// map.insert(3, "a");
/// map.insert(5, "b");
/// map.insert(8, "c");
///
/// for (key, value) in map.range((Excluded(3), Included(8))) {
/// println!("{}: {}", key, value);
/// }
///
/// assert_eq!(Some((&3, &"a")), map.range((Unbounded, Included(5))).next());
/// ```
///
/// [`BTreeMap::range`]: btree_map/struct.BTreeMap.html#method.range
#[stable(feature = "collections_bound", since = "1.17.0")]
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub enum Bound<T> {
/// An inclusive bound.
#[stable(feature = "collections_bound", since = "1.17.0")]
Included(T),
/// An exclusive bound.
#[stable(feature = "collections_bound", since = "1.17.0")]
Excluded(T),
/// An infinite endpoint. Indicates that there is no bound in this direction.
#[stable(feature = "collections_bound", since = "1.17.0")]
Unbounded,
}
/// An intermediate trait for specialization of `Extend`.
#[doc(hidden)]
trait SpecExtend<I: IntoIterator> {
/// Extends `self` with the contents of the given iterator.
fn spec_extend(&mut self, iter: I);
}
-92
View File
@@ -1,92 +0,0 @@
// Copyright 2014-2015 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.
/// Creates a `Vec` containing the arguments.
///
/// `vec!` allows `Vec`s to be defined with the same syntax as array expressions.
/// There are two forms of this macro:
///
/// - Create a `Vec` containing a given list of elements:
///
/// ```
/// let v = vec![1, 2, 3];
/// assert_eq!(v[0], 1);
/// assert_eq!(v[1], 2);
/// assert_eq!(v[2], 3);
/// ```
///
/// - Create a `Vec` from a given element and size:
///
/// ```
/// let v = vec![1; 3];
/// assert_eq!(v, [1, 1, 1]);
/// ```
///
/// Note that unlike array expressions this syntax supports all elements
/// which implement `Clone` and the number of elements doesn't have to be
/// a constant.
///
/// This will use `clone()` to duplicate an expression, so one should be careful
/// using this with types having a nonstandard `Clone` implementation. For
/// example, `vec![Rc::new(1); 5]` will create a vector of five references
/// to the same boxed integer value, not five references pointing to independently
/// boxed integers.
#[cfg(not(test))]
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable]
macro_rules! vec {
($elem:expr; $n:expr) => (
$crate::vec::from_elem($elem, $n)
);
($($x:expr),*) => (
<[_]>::into_vec(box [$($x),*])
);
($($x:expr,)*) => (vec![$($x),*])
}
// HACK(japaric): with cfg(test) the inherent `[T]::into_vec` method, which is
// required for this macro definition, is not available. Instead use the
// `slice::into_vec` function which is only available with cfg(test)
// NB see the slice::hack module in slice.rs for more information
#[cfg(test)]
macro_rules! vec {
($elem:expr; $n:expr) => (
$crate::vec::from_elem($elem, $n)
);
($($x:expr),*) => (
$crate::slice::into_vec(box [$($x),*])
);
($($x:expr,)*) => (vec![$($x),*])
}
/// Use the syntax described in `std::fmt` to create a value of type `String`.
/// See [`std::fmt`][fmt] for more information.
///
/// [fmt]: ../std/fmt/index.html
///
/// # Panics
///
/// `format!` panics if a formatting trait implementation returns an error.
/// This indicates an incorrect implementation
/// since `fmt::Write for String` never returns an error itself.
///
/// # Examples
///
/// ```
/// format!("test");
/// format!("hello {}", "world!");
/// format!("x = {}, y = {y}", 10, y = 30);
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! format {
($($arg:tt)*) => ($crate::fmt::format(format_args!($($arg)*)))
}
-1997
View File
@@ -1,1997 +0,0 @@
// Copyright 2012-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.
//! Unicode string slices.
//!
//! The `&str` type is one of the two main string types, the other being `String`.
//! Unlike its `String` counterpart, its contents are borrowed.
//!
//! # Basic Usage
//!
//! A basic string declaration of `&str` type:
//!
//! ```
//! let hello_world = "Hello, World!";
//! ```
//!
//! Here we have declared a string literal, also known as a string slice.
//! String literals have a static lifetime, which means the string `hello_world`
//! is guaranteed to be valid for the duration of the entire program.
//! We can explicitly specify `hello_world`'s lifetime as well:
//!
//! ```
//! let hello_world: &'static str = "Hello, world!";
//! ```
//!
//! *[See also the `str` primitive type](../../std/primitive.str.html).*
#![stable(feature = "rust1", since = "1.0.0")]
// Many of the usings in this module are only used in the test configuration.
// It's cleaner to just turn off the unused_imports warning than to fix them.
#![allow(unused_imports)]
use core::fmt;
use core::str as core_str;
use core::str::pattern::Pattern;
use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
use core::mem;
use core::iter::FusedIterator;
use std_unicode::str::{UnicodeStr, Utf16Encoder};
use vec_deque::VecDeque;
use borrow::{Borrow, ToOwned};
use string::String;
use std_unicode;
use vec::Vec;
use slice::{SliceConcatExt, SliceIndex};
use boxed::Box;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{FromStr, Utf8Error};
#[allow(deprecated)]
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{Lines, LinesAny};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{Split, RSplit};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{SplitN, RSplitN};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{SplitTerminator, RSplitTerminator};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{Matches, RMatches};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{MatchIndices, RMatchIndices};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{from_utf8, from_utf8_mut, Chars, CharIndices, Bytes};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::{from_utf8_unchecked, from_utf8_unchecked_mut, ParseBoolError};
#[unstable(feature = "str_box_extras", issue = "41119")]
pub use alloc::str::from_boxed_utf8_unchecked;
#[stable(feature = "rust1", since = "1.0.0")]
pub use std_unicode::str::SplitWhitespace;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::pattern;
#[unstable(feature = "slice_concat_ext",
reason = "trait should not have to exist",
issue = "27747")]
impl<S: Borrow<str>> SliceConcatExt<str> for [S] {
type Output = String;
fn concat(&self) -> String {
if self.is_empty() {
return String::new();
}
// `len` calculation may overflow but push_str will check boundaries
let len = self.iter().map(|s| s.borrow().len()).sum();
let mut result = String::with_capacity(len);
for s in self {
result.push_str(s.borrow())
}
result
}
fn join(&self, sep: &str) -> String {
if self.is_empty() {
return String::new();
}
// concat is faster
if sep.is_empty() {
return self.concat();
}
// this is wrong without the guarantee that `self` is non-empty
// `len` calculation may overflow but push_str but will check boundaries
let len = sep.len() * (self.len() - 1) +
self.iter().map(|s| s.borrow().len()).sum::<usize>();
let mut result = String::with_capacity(len);
let mut first = true;
for s in self {
if first {
first = false;
} else {
result.push_str(sep);
}
result.push_str(s.borrow());
}
result
}
fn connect(&self, sep: &str) -> String {
self.join(sep)
}
}
/// An iterator of [`u16`] over the string encoded as UTF-16.
///
/// [`u16`]: ../../std/primitive.u16.html
///
/// This struct is created by the [`encode_utf16`] method on [`str`].
/// See its documentation for more.
///
/// [`encode_utf16`]: ../../std/primitive.str.html#method.encode_utf16
/// [`str`]: ../../std/primitive.str.html
#[derive(Clone)]
#[stable(feature = "encode_utf16", since = "1.8.0")]
pub struct EncodeUtf16<'a> {
encoder: Utf16Encoder<Chars<'a>>,
}
#[stable(feature = "collection_debug", since = "1.17.0")]
impl<'a> fmt::Debug for EncodeUtf16<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("EncodeUtf16 { .. }")
}
}
#[stable(feature = "encode_utf16", since = "1.8.0")]
impl<'a> Iterator for EncodeUtf16<'a> {
type Item = u16;
#[inline]
fn next(&mut self) -> Option<u16> {
self.encoder.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.encoder.size_hint()
}
}
#[unstable(feature = "fused", issue = "35602")]
impl<'a> FusedIterator for EncodeUtf16<'a> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl Borrow<str> for String {
#[inline]
fn borrow(&self) -> &str {
&self[..]
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl ToOwned for str {
type Owned = String;
fn to_owned(&self) -> String {
unsafe { String::from_utf8_unchecked(self.as_bytes().to_owned()) }
}
fn clone_into(&self, target: &mut String) {
let mut b = mem::replace(target, String::new()).into_bytes();
self.as_bytes().clone_into(&mut b);
*target = unsafe { String::from_utf8_unchecked(b) }
}
}
/// Methods for string slices.
#[lang = "str"]
#[cfg(not(test))]
impl str {
/// Returns the length of `self`.
///
/// This length is in bytes, not [`char`]s or graphemes. In other words,
/// it may not be what a human considers the length of the string.
///
/// [`char`]: primitive.char.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let len = "foo".len();
/// assert_eq!(3, len);
///
/// let len = "ƒoo".len(); // fancy f!
/// assert_eq!(4, len);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn len(&self) -> usize {
core_str::StrExt::len(self)
}
/// Returns `true` if `self` has a length of zero bytes.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = "";
/// assert!(s.is_empty());
///
/// let s = "not empty";
/// assert!(!s.is_empty());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn is_empty(&self) -> bool {
core_str::StrExt::is_empty(self)
}
/// Checks that `index`-th byte lies at the start and/or end of a
/// UTF-8 code point sequence.
///
/// The start and end of the string (when `index == self.len()`) are
/// considered to be
/// boundaries.
///
/// Returns `false` if `index` is greater than `self.len()`.
///
/// # Examples
///
/// ```
/// let s = "Löwe 老虎 Léopard";
/// assert!(s.is_char_boundary(0));
/// // start of `老`
/// assert!(s.is_char_boundary(6));
/// assert!(s.is_char_boundary(s.len()));
///
/// // second byte of `ö`
/// assert!(!s.is_char_boundary(2));
///
/// // third byte of `老`
/// assert!(!s.is_char_boundary(8));
/// ```
#[stable(feature = "is_char_boundary", since = "1.9.0")]
#[inline]
pub fn is_char_boundary(&self, index: usize) -> bool {
core_str::StrExt::is_char_boundary(self, index)
}
/// Converts a string slice to a byte slice.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let bytes = "bors".as_bytes();
/// assert_eq!(b"bors", bytes);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline(always)]
pub fn as_bytes(&self) -> &[u8] {
core_str::StrExt::as_bytes(self)
}
/// Converts a mutable string slice to a mutable byte slice.
#[unstable(feature = "str_mut_extras", issue = "41119")]
#[inline(always)]
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
core_str::StrExt::as_bytes_mut(self)
}
/// Converts a string slice to a raw pointer.
///
/// As string slices are a slice of bytes, the raw pointer points to a
/// [`u8`]. This pointer will be pointing to the first byte of the string
/// slice.
///
/// [`u8`]: primitive.u8.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = "Hello";
/// let ptr = s.as_ptr();
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn as_ptr(&self) -> *const u8 {
core_str::StrExt::as_ptr(self)
}
/// Returns a subslice of `str`.
///
/// This is the non-panicking alternative to indexing the `str`. Returns
/// [`None`] whenever equivalent indexing operation would panic.
///
/// [`None`]: option/enum.Option.html#variant.None
///
/// # Examples
///
/// ```
/// # #![feature(str_checked_slicing)]
/// let v = "🗻∈🌏";
/// assert_eq!(Some("🗻"), v.get(0..4));
/// assert!(v.get(1..).is_none());
/// assert!(v.get(..8).is_none());
/// assert!(v.get(..42).is_none());
/// ```
#[unstable(feature = "str_checked_slicing", issue = "39932")]
#[inline]
pub fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
core_str::StrExt::get(self, i)
}
/// Returns a mutable subslice of `str`.
///
/// This is the non-panicking alternative to indexing the `str`. Returns
/// [`None`] whenever equivalent indexing operation would panic.
///
/// [`None`]: option/enum.Option.html#variant.None
///
/// # Examples
///
/// ```
/// # #![feature(str_checked_slicing)]
/// let mut v = String::from("🗻∈🌏");
/// assert_eq!(Some("🗻"), v.get_mut(0..4).map(|v| &*v));
/// assert!(v.get_mut(1..).is_none());
/// assert!(v.get_mut(..8).is_none());
/// assert!(v.get_mut(..42).is_none());
/// ```
#[unstable(feature = "str_checked_slicing", issue = "39932")]
#[inline]
pub fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
core_str::StrExt::get_mut(self, i)
}
/// Returns a unchecked subslice of `str`.
///
/// This is the unchecked alternative to indexing the `str`.
///
/// # Safety
///
/// Callers of this function are responsible that these preconditions are
/// satisfied:
///
/// * The starting index must come before the ending index;
/// * Indexes must be within bounds of the original slice;
/// * Indexes must lie on UTF-8 sequence boundaries.
///
/// Failing that, the returned string slice may reference invalid memory or
/// violate the invariants communicated by the `str` type.
///
/// # Examples
///
/// ```
/// # #![feature(str_checked_slicing)]
/// let v = "🗻∈🌏";
/// unsafe {
/// assert_eq!("🗻", v.get_unchecked(0..4));
/// assert_eq!("∈", v.get_unchecked(4..7));
/// assert_eq!("🌏", v.get_unchecked(7..11));
/// }
/// ```
#[unstable(feature = "str_checked_slicing", issue = "39932")]
#[inline]
pub unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output {
core_str::StrExt::get_unchecked(self, i)
}
/// Returns a mutable, unchecked subslice of `str`.
///
/// This is the unchecked alternative to indexing the `str`.
///
/// # Safety
///
/// Callers of this function are responsible that these preconditions are
/// satisfied:
///
/// * The starting index must come before the ending index;
/// * Indexes must be within bounds of the original slice;
/// * Indexes must lie on UTF-8 sequence boundaries.
///
/// Failing that, the returned string slice may reference invalid memory or
/// violate the invariants communicated by the `str` type.
///
/// # Examples
///
/// ```
/// # #![feature(str_checked_slicing)]
/// let mut v = String::from("🗻∈🌏");
/// unsafe {
/// assert_eq!("🗻", v.get_unchecked_mut(0..4));
/// assert_eq!("∈", v.get_unchecked_mut(4..7));
/// assert_eq!("🌏", v.get_unchecked_mut(7..11));
/// }
/// ```
#[unstable(feature = "str_checked_slicing", issue = "39932")]
#[inline]
pub unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output {
core_str::StrExt::get_unchecked_mut(self, i)
}
/// Creates a string slice from another string slice, bypassing safety
/// checks.
///
/// This is generally not recommended, use with caution! For a safe
/// alternative see [`str`] and [`Index`].
///
/// [`str`]: primitive.str.html
/// [`Index`]: ops/trait.Index.html
///
/// This new slice goes from `begin` to `end`, including `begin` but
/// excluding `end`.
///
/// To get a mutable string slice instead, see the
/// [`slice_mut_unchecked`] method.
///
/// [`slice_mut_unchecked`]: #method.slice_mut_unchecked
///
/// # Safety
///
/// Callers of this function are responsible that three preconditions are
/// satisfied:
///
/// * `begin` must come before `end`.
/// * `begin` and `end` must be byte positions within the string slice.
/// * `begin` and `end` must lie on UTF-8 sequence boundaries.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = "Löwe 老虎 Léopard";
///
/// unsafe {
/// assert_eq!("Löwe 老虎 Léopard", s.slice_unchecked(0, 21));
/// }
///
/// let s = "Hello, world!";
///
/// unsafe {
/// assert_eq!("world", s.slice_unchecked(7, 12));
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
core_str::StrExt::slice_unchecked(self, begin, end)
}
/// Creates a string slice from another string slice, bypassing safety
/// checks.
/// This is generally not recommended, use with caution! For a safe
/// alternative see [`str`] and [`IndexMut`].
///
/// [`str`]: primitive.str.html
/// [`IndexMut`]: ops/trait.IndexMut.html
///
/// This new slice goes from `begin` to `end`, including `begin` but
/// excluding `end`.
///
/// To get an immutable string slice instead, see the
/// [`slice_unchecked`] method.
///
/// [`slice_unchecked`]: #method.slice_unchecked
///
/// # Safety
///
/// Callers of this function are responsible that three preconditions are
/// satisfied:
///
/// * `begin` must come before `end`.
/// * `begin` and `end` must be byte positions within the string slice.
/// * `begin` and `end` must lie on UTF-8 sequence boundaries.
#[stable(feature = "str_slice_mut", since = "1.5.0")]
#[inline]
pub unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str {
core_str::StrExt::slice_mut_unchecked(self, begin, end)
}
/// Divide one string slice into two at an index.
///
/// The argument, `mid`, should be a byte offset from the start of the
/// string. It must also be on the boundary of a UTF-8 code point.
///
/// The two slices returned go from the start of the string slice to `mid`,
/// and from `mid` to the end of the string slice.
///
/// To get mutable string slices instead, see the [`split_at_mut`]
/// method.
///
/// [`split_at_mut`]: #method.split_at_mut
///
/// # Panics
///
/// Panics if `mid` is not on a UTF-8 code point boundary, or if it is
/// beyond the last code point of the string slice.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = "Per Martin-Löf";
///
/// let (first, last) = s.split_at(3);
///
/// assert_eq!("Per", first);
/// assert_eq!(" Martin-Löf", last);
/// ```
#[inline]
#[stable(feature = "str_split_at", since = "1.4.0")]
pub fn split_at(&self, mid: usize) -> (&str, &str) {
core_str::StrExt::split_at(self, mid)
}
/// Divide one mutable string slice into two at an index.
///
/// The argument, `mid`, should be a byte offset from the start of the
/// string. It must also be on the boundary of a UTF-8 code point.
///
/// The two slices returned go from the start of the string slice to `mid`,
/// and from `mid` to the end of the string slice.
///
/// To get immutable string slices instead, see the [`split_at`] method.
///
/// [`split_at`]: #method.split_at
///
/// # Panics
///
/// Panics if `mid` is not on a UTF-8 code point boundary, or if it is
/// beyond the last code point of the string slice.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let mut s = "Per Martin-Löf".to_string();
///
/// let (first, last) = s.split_at_mut(3);
///
/// assert_eq!("Per", first);
/// assert_eq!(" Martin-Löf", last);
/// ```
#[inline]
#[stable(feature = "str_split_at", since = "1.4.0")]
pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
core_str::StrExt::split_at_mut(self, mid)
}
/// Returns an iterator over the [`char`]s of a string slice.
///
/// As a string slice consists of valid UTF-8, we can iterate through a
/// string slice by [`char`]. This method returns such an iterator.
///
/// It's important to remember that [`char`] represents a Unicode Scalar
/// Value, and may not match your idea of what a 'character' is. Iteration
/// over grapheme clusters may be what you actually want.
///
/// [`char`]: primitive.char.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let word = "goodbye";
///
/// let count = word.chars().count();
/// assert_eq!(7, count);
///
/// let mut chars = word.chars();
///
/// assert_eq!(Some('g'), chars.next());
/// assert_eq!(Some('o'), chars.next());
/// assert_eq!(Some('o'), chars.next());
/// assert_eq!(Some('d'), chars.next());
/// assert_eq!(Some('b'), chars.next());
/// assert_eq!(Some('y'), chars.next());
/// assert_eq!(Some('e'), chars.next());
///
/// assert_eq!(None, chars.next());
/// ```
///
/// Remember, [`char`]s may not match your human intuition about characters:
///
/// ```
/// let y = "y̆";
///
/// let mut chars = y.chars();
///
/// assert_eq!(Some('y'), chars.next()); // not 'y̆'
/// assert_eq!(Some('\u{0306}'), chars.next());
///
/// assert_eq!(None, chars.next());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn chars(&self) -> Chars {
core_str::StrExt::chars(self)
}
/// Returns an iterator over the [`char`]s of a string slice, and their
/// positions.
///
/// As a string slice consists of valid UTF-8, we can iterate through a
/// string slice by [`char`]. This method returns an iterator of both
/// these [`char`]s, as well as their byte positions.
///
/// The iterator yields tuples. The position is first, the [`char`] is
/// second.
///
/// [`char`]: primitive.char.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let word = "goodbye";
///
/// let count = word.char_indices().count();
/// assert_eq!(7, count);
///
/// let mut char_indices = word.char_indices();
///
/// assert_eq!(Some((0, 'g')), char_indices.next());
/// assert_eq!(Some((1, 'o')), char_indices.next());
/// assert_eq!(Some((2, 'o')), char_indices.next());
/// assert_eq!(Some((3, 'd')), char_indices.next());
/// assert_eq!(Some((4, 'b')), char_indices.next());
/// assert_eq!(Some((5, 'y')), char_indices.next());
/// assert_eq!(Some((6, 'e')), char_indices.next());
///
/// assert_eq!(None, char_indices.next());
/// ```
///
/// Remember, [`char`]s may not match your human intuition about characters:
///
/// ```
/// let y = "y̆";
///
/// let mut char_indices = y.char_indices();
///
/// assert_eq!(Some((0, 'y')), char_indices.next()); // not (0, 'y̆')
/// assert_eq!(Some((1, '\u{0306}')), char_indices.next());
///
/// assert_eq!(None, char_indices.next());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn char_indices(&self) -> CharIndices {
core_str::StrExt::char_indices(self)
}
/// An iterator over the bytes of a string slice.
///
/// As a string slice consists of a sequence of bytes, we can iterate
/// through a string slice by byte. This method returns such an iterator.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let mut bytes = "bors".bytes();
///
/// assert_eq!(Some(b'b'), bytes.next());
/// assert_eq!(Some(b'o'), bytes.next());
/// assert_eq!(Some(b'r'), bytes.next());
/// assert_eq!(Some(b's'), bytes.next());
///
/// assert_eq!(None, bytes.next());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn bytes(&self) -> Bytes {
core_str::StrExt::bytes(self)
}
/// Split a string slice by whitespace.
///
/// The iterator returned will return string slices that are sub-slices of
/// the original string slice, separated by any amount of whitespace.
///
/// 'Whitespace' is defined according to the terms of the Unicode Derived
/// Core Property `White_Space`.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let mut iter = "A few words".split_whitespace();
///
/// assert_eq!(Some("A"), iter.next());
/// assert_eq!(Some("few"), iter.next());
/// assert_eq!(Some("words"), iter.next());
///
/// assert_eq!(None, iter.next());
/// ```
///
/// All kinds of whitespace are considered:
///
/// ```
/// let mut iter = " Mary had\ta\u{2009}little \n\t lamb".split_whitespace();
/// assert_eq!(Some("Mary"), iter.next());
/// assert_eq!(Some("had"), iter.next());
/// assert_eq!(Some("a"), iter.next());
/// assert_eq!(Some("little"), iter.next());
/// assert_eq!(Some("lamb"), iter.next());
///
/// assert_eq!(None, iter.next());
/// ```
#[stable(feature = "split_whitespace", since = "1.1.0")]
#[inline]
pub fn split_whitespace(&self) -> SplitWhitespace {
UnicodeStr::split_whitespace(self)
}
/// An iterator over the lines of a string, as string slices.
///
/// Lines are ended with either a newline (`\n`) or a carriage return with
/// a line feed (`\r\n`).
///
/// The final line ending is optional.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let text = "foo\r\nbar\n\nbaz\n";
/// let mut lines = text.lines();
///
/// assert_eq!(Some("foo"), lines.next());
/// assert_eq!(Some("bar"), lines.next());
/// assert_eq!(Some(""), lines.next());
/// assert_eq!(Some("baz"), lines.next());
///
/// assert_eq!(None, lines.next());
/// ```
///
/// The final line ending isn't required:
///
/// ```
/// let text = "foo\nbar\n\r\nbaz";
/// let mut lines = text.lines();
///
/// assert_eq!(Some("foo"), lines.next());
/// assert_eq!(Some("bar"), lines.next());
/// assert_eq!(Some(""), lines.next());
/// assert_eq!(Some("baz"), lines.next());
///
/// assert_eq!(None, lines.next());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn lines(&self) -> Lines {
core_str::StrExt::lines(self)
}
/// An iterator over the lines of a string.
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_deprecated(since = "1.4.0", reason = "use lines() instead now")]
#[inline]
#[allow(deprecated)]
pub fn lines_any(&self) -> LinesAny {
core_str::StrExt::lines_any(self)
}
/// Returns an iterator of `u16` over the string encoded as UTF-16.
#[stable(feature = "encode_utf16", since = "1.8.0")]
pub fn encode_utf16(&self) -> EncodeUtf16 {
EncodeUtf16 { encoder: Utf16Encoder::new(self[..].chars()) }
}
/// Returns `true` if the given pattern matches a sub-slice of
/// this string slice.
///
/// Returns `false` if it does not.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let bananas = "bananas";
///
/// assert!(bananas.contains("nana"));
/// assert!(!bananas.contains("apples"));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
core_str::StrExt::contains(self, pat)
}
/// Returns `true` if the given pattern matches a prefix of this
/// string slice.
///
/// Returns `false` if it does not.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let bananas = "bananas";
///
/// assert!(bananas.starts_with("bana"));
/// assert!(!bananas.starts_with("nana"));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
core_str::StrExt::starts_with(self, pat)
}
/// Returns `true` if the given pattern matches a suffix of this
/// string slice.
///
/// Returns `false` if it does not.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let bananas = "bananas";
///
/// assert!(bananas.ends_with("anas"));
/// assert!(!bananas.ends_with("nana"));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
where P::Searcher: ReverseSearcher<'a>
{
core_str::StrExt::ends_with(self, pat)
}
/// Returns the byte index of the first character of this string slice that
/// matches the pattern.
///
/// Returns [`None`] if the pattern doesn't match.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines if
/// a character matches.
///
/// [`char`]: primitive.char.html
/// [`None`]: option/enum.Option.html#variant.None
///
/// # Examples
///
/// Simple patterns:
///
/// ```
/// let s = "Löwe 老虎 Léopard";
///
/// assert_eq!(s.find('L'), Some(0));
/// assert_eq!(s.find('é'), Some(14));
/// assert_eq!(s.find("Léopard"), Some(13));
/// ```
///
/// More complex patterns with closures:
///
/// ```
/// let s = "Löwe 老虎 Léopard";
///
/// assert_eq!(s.find(char::is_whitespace), Some(5));
/// assert_eq!(s.find(char::is_lowercase), Some(1));
/// ```
///
/// Not finding the pattern:
///
/// ```
/// let s = "Löwe 老虎 Léopard";
/// let x: &[_] = &['1', '2'];
///
/// assert_eq!(s.find(x), None);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
core_str::StrExt::find(self, pat)
}
/// Returns the byte index of the last character of this string slice that
/// matches the pattern.
///
/// Returns [`None`] if the pattern doesn't match.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines if
/// a character matches.
///
/// [`char`]: primitive.char.html
/// [`None`]: option/enum.Option.html#variant.None
///
/// # Examples
///
/// Simple patterns:
///
/// ```
/// let s = "Löwe 老虎 Léopard";
///
/// assert_eq!(s.rfind('L'), Some(13));
/// assert_eq!(s.rfind('é'), Some(14));
/// ```
///
/// More complex patterns with closures:
///
/// ```
/// let s = "Löwe 老虎 Léopard";
///
/// assert_eq!(s.rfind(char::is_whitespace), Some(12));
/// assert_eq!(s.rfind(char::is_lowercase), Some(20));
/// ```
///
/// Not finding the pattern:
///
/// ```
/// let s = "Löwe 老虎 Léopard";
/// let x: &[_] = &['1', '2'];
///
/// assert_eq!(s.rfind(x), None);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
where P::Searcher: ReverseSearcher<'a>
{
core_str::StrExt::rfind(self, pat)
}
/// An iterator over substrings of this string slice, separated by
/// characters matched by a pattern.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines the
/// split.
///
/// # Iterator behavior
///
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
/// allows a reverse search and forward/reverse search yields the same
/// elements. This is true for, eg, [`char`] but not for `&str`.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
///
/// If the pattern allows a reverse search but its results might differ
/// from a forward search, the [`rsplit`] method can be used.
///
/// [`char`]: primitive.char.html
/// [`rsplit`]: #method.rsplit
///
/// # Examples
///
/// Simple patterns:
///
/// ```
/// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
/// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
///
/// let v: Vec<&str> = "".split('X').collect();
/// assert_eq!(v, [""]);
///
/// let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect();
/// assert_eq!(v, ["lion", "", "tiger", "leopard"]);
///
/// let v: Vec<&str> = "lion::tiger::leopard".split("::").collect();
/// assert_eq!(v, ["lion", "tiger", "leopard"]);
///
/// let v: Vec<&str> = "abc1def2ghi".split(char::is_numeric).collect();
/// assert_eq!(v, ["abc", "def", "ghi"]);
///
/// let v: Vec<&str> = "lionXtigerXleopard".split(char::is_uppercase).collect();
/// assert_eq!(v, ["lion", "tiger", "leopard"]);
/// ```
///
/// A more complex pattern, using a closure:
///
/// ```
/// let v: Vec<&str> = "abc1defXghi".split(|c| c == '1' || c == 'X').collect();
/// assert_eq!(v, ["abc", "def", "ghi"]);
/// ```
///
/// If a string contains multiple contiguous separators, you will end up
/// with empty strings in the output:
///
/// ```
/// let x = "||||a||b|c".to_string();
/// let d: Vec<_> = x.split('|').collect();
///
/// assert_eq!(d, &["", "", "", "", "a", "", "b", "c"]);
/// ```
///
/// Contiguous separators are separated by the empty string.
///
/// ```
/// let x = "(///)".to_string();
/// let d: Vec<_> = x.split('/').collect();
///
/// assert_eq!(d, &["(", "", "", ")"]);
/// ```
///
/// Separators at the start or end of a string are neighbored
/// by empty strings.
///
/// ```
/// let d: Vec<_> = "010".split("0").collect();
/// assert_eq!(d, &["", "1", ""]);
/// ```
///
/// When the empty string is used as a separator, it separates
/// every character in the string, along with the beginning
/// and end of the string.
///
/// ```
/// let f: Vec<_> = "rust".split("").collect();
/// assert_eq!(f, &["", "r", "u", "s", "t", ""]);
/// ```
///
/// Contiguous separators can lead to possibly surprising behavior
/// when whitespace is used as the separator. This code is correct:
///
/// ```
/// let x = " a b c".to_string();
/// let d: Vec<_> = x.split(' ').collect();
///
/// assert_eq!(d, &["", "", "", "", "a", "", "b", "c"]);
/// ```
///
/// It does _not_ give you:
///
/// ```,ignore
/// assert_eq!(d, &["a", "b", "c"]);
/// ```
///
/// Use [`split_whitespace`] for this behavior.
///
/// [`split_whitespace`]: #method.split_whitespace
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
core_str::StrExt::split(self, pat)
}
/// An iterator over substrings of the given string slice, separated by
/// characters matched by a pattern and yielded in reverse order.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines the
/// split.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator requires that the pattern supports a reverse
/// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse
/// search yields the same elements.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
///
/// For iterating from the front, the [`split`] method can be used.
///
/// [`split`]: #method.split
///
/// # Examples
///
/// Simple patterns:
///
/// ```
/// let v: Vec<&str> = "Mary had a little lamb".rsplit(' ').collect();
/// assert_eq!(v, ["lamb", "little", "a", "had", "Mary"]);
///
/// let v: Vec<&str> = "".rsplit('X').collect();
/// assert_eq!(v, [""]);
///
/// let v: Vec<&str> = "lionXXtigerXleopard".rsplit('X').collect();
/// assert_eq!(v, ["leopard", "tiger", "", "lion"]);
///
/// let v: Vec<&str> = "lion::tiger::leopard".rsplit("::").collect();
/// assert_eq!(v, ["leopard", "tiger", "lion"]);
/// ```
///
/// A more complex pattern, using a closure:
///
/// ```
/// let v: Vec<&str> = "abc1defXghi".rsplit(|c| c == '1' || c == 'X').collect();
/// assert_eq!(v, ["ghi", "def", "abc"]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
core_str::StrExt::rsplit(self, pat)
}
/// An iterator over substrings of the given string slice, separated by
/// characters matched by a pattern.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines the
/// split.
///
/// Equivalent to [`split`], except that the trailing substring
/// is skipped if empty.
///
/// [`split`]: #method.split
///
/// This method can be used for string data that is _terminated_,
/// rather than _separated_ by a pattern.
///
/// # Iterator behavior
///
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
/// allows a reverse search and forward/reverse search yields the same
/// elements. This is true for, eg, [`char`] but not for `&str`.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
/// [`char`]: primitive.char.html
///
/// If the pattern allows a reverse search but its results might differ
/// from a forward search, the [`rsplit_terminator`] method can be used.
///
/// [`rsplit_terminator`]: #method.rsplit_terminator
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let v: Vec<&str> = "A.B.".split_terminator('.').collect();
/// assert_eq!(v, ["A", "B"]);
///
/// let v: Vec<&str> = "A..B..".split_terminator(".").collect();
/// assert_eq!(v, ["A", "", "B", ""]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> {
core_str::StrExt::split_terminator(self, pat)
}
/// An iterator over substrings of `self`, separated by characters
/// matched by a pattern and yielded in reverse order.
///
/// The pattern can be a simple `&str`, [`char`], or a closure that
/// determines the split.
/// Additional libraries might provide more complex patterns like
/// regular expressions.
///
/// [`char`]: primitive.char.html
///
/// Equivalent to [`split`], except that the trailing substring is
/// skipped if empty.
///
/// [`split`]: #method.split
///
/// This method can be used for string data that is _terminated_,
/// rather than _separated_ by a pattern.
///
/// # Iterator behavior
///
/// The returned iterator requires that the pattern supports a
/// reverse search, and it will be double ended if a forward/reverse
/// search yields the same elements.
///
/// For iterating from the front, the [`split_terminator`] method can be
/// used.
///
/// [`split_terminator`]: #method.split_terminator
///
/// # Examples
///
/// ```
/// let v: Vec<&str> = "A.B.".rsplit_terminator('.').collect();
/// assert_eq!(v, ["B", "A"]);
///
/// let v: Vec<&str> = "A..B..".rsplit_terminator(".").collect();
/// assert_eq!(v, ["", "B", "", "A"]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
core_str::StrExt::rsplit_terminator(self, pat)
}
/// An iterator over substrings of the given string slice, separated by a
/// pattern, restricted to returning at most `n` items.
///
/// If `n` substrings are returned, the last substring (the `n`th substring)
/// will contain the remainder of the string.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines the
/// split.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator will not be double ended, because it is
/// not efficient to support.
///
/// If the pattern allows a reverse search, the [`rsplitn`] method can be
/// used.
///
/// [`rsplitn`]: #method.rsplitn
///
/// # Examples
///
/// Simple patterns:
///
/// ```
/// let v: Vec<&str> = "Mary had a little lambda".splitn(3, ' ').collect();
/// assert_eq!(v, ["Mary", "had", "a little lambda"]);
///
/// let v: Vec<&str> = "lionXXtigerXleopard".splitn(3, "X").collect();
/// assert_eq!(v, ["lion", "", "tigerXleopard"]);
///
/// let v: Vec<&str> = "abcXdef".splitn(1, 'X').collect();
/// assert_eq!(v, ["abcXdef"]);
///
/// let v: Vec<&str> = "".splitn(1, 'X').collect();
/// assert_eq!(v, [""]);
/// ```
///
/// A more complex pattern, using a closure:
///
/// ```
/// let v: Vec<&str> = "abc1defXghi".splitn(2, |c| c == '1' || c == 'X').collect();
/// assert_eq!(v, ["abc", "defXghi"]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn splitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> SplitN<'a, P> {
core_str::StrExt::splitn(self, n, pat)
}
/// An iterator over substrings of this string slice, separated by a
/// pattern, starting from the end of the string, restricted to returning
/// at most `n` items.
///
/// If `n` substrings are returned, the last substring (the `n`th substring)
/// will contain the remainder of the string.
///
/// The pattern can be a `&str`, [`char`], or a closure that
/// determines the split.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator will not be double ended, because it is not
/// efficient to support.
///
/// For splitting from the front, the [`splitn`] method can be used.
///
/// [`splitn`]: #method.splitn
///
/// # Examples
///
/// Simple patterns:
///
/// ```
/// let v: Vec<&str> = "Mary had a little lamb".rsplitn(3, ' ').collect();
/// assert_eq!(v, ["lamb", "little", "Mary had a"]);
///
/// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(3, 'X').collect();
/// assert_eq!(v, ["leopard", "tiger", "lionX"]);
///
/// let v: Vec<&str> = "lion::tiger::leopard".rsplitn(2, "::").collect();
/// assert_eq!(v, ["leopard", "lion::tiger"]);
/// ```
///
/// A more complex pattern, using a closure:
///
/// ```
/// let v: Vec<&str> = "abc1defXghi".rsplitn(2, |c| c == '1' || c == 'X').collect();
/// assert_eq!(v, ["ghi", "abc1def"]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> RSplitN<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
core_str::StrExt::rsplitn(self, n, pat)
}
/// An iterator over the disjoint matches of a pattern within the given string
/// slice.
///
/// The pattern can be a `&str`, [`char`], or a closure that
/// determines if a character matches.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
/// allows a reverse search and forward/reverse search yields the same
/// elements. This is true for, eg, [`char`] but not for `&str`.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
/// [`char`]: primitive.char.html
///
/// If the pattern allows a reverse search but its results might differ
/// from a forward search, the [`rmatches`] method can be used.
///
/// [`rmatches`]: #method.rmatches
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let v: Vec<&str> = "abcXXXabcYYYabc".matches("abc").collect();
/// assert_eq!(v, ["abc", "abc", "abc"]);
///
/// let v: Vec<&str> = "1abc2abc3".matches(char::is_numeric).collect();
/// assert_eq!(v, ["1", "2", "3"]);
/// ```
#[stable(feature = "str_matches", since = "1.2.0")]
#[inline]
pub fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> {
core_str::StrExt::matches(self, pat)
}
/// An iterator over the disjoint matches of a pattern within this string slice,
/// yielded in reverse order.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines if
/// a character matches.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator requires that the pattern supports a reverse
/// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse
/// search yields the same elements.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
///
/// For iterating from the front, the [`matches`] method can be used.
///
/// [`matches`]: #method.matches
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let v: Vec<&str> = "abcXXXabcYYYabc".rmatches("abc").collect();
/// assert_eq!(v, ["abc", "abc", "abc"]);
///
/// let v: Vec<&str> = "1abc2abc3".rmatches(char::is_numeric).collect();
/// assert_eq!(v, ["3", "2", "1"]);
/// ```
#[stable(feature = "str_matches", since = "1.2.0")]
#[inline]
pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
core_str::StrExt::rmatches(self, pat)
}
/// An iterator over the disjoint matches of a pattern within this string
/// slice as well as the index that the match starts at.
///
/// For matches of `pat` within `self` that overlap, only the indices
/// corresponding to the first match are returned.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines
/// if a character matches.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
/// allows a reverse search and forward/reverse search yields the same
/// elements. This is true for, eg, [`char`] but not for `&str`.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
///
/// If the pattern allows a reverse search but its results might differ
/// from a forward search, the [`rmatch_indices`] method can be used.
///
/// [`rmatch_indices`]: #method.rmatch_indices
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let v: Vec<_> = "abcXXXabcYYYabc".match_indices("abc").collect();
/// assert_eq!(v, [(0, "abc"), (6, "abc"), (12, "abc")]);
///
/// let v: Vec<_> = "1abcabc2".match_indices("abc").collect();
/// assert_eq!(v, [(1, "abc"), (4, "abc")]);
///
/// let v: Vec<_> = "ababa".match_indices("aba").collect();
/// assert_eq!(v, [(0, "aba")]); // only the first `aba`
/// ```
#[stable(feature = "str_match_indices", since = "1.5.0")]
#[inline]
pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> {
core_str::StrExt::match_indices(self, pat)
}
/// An iterator over the disjoint matches of a pattern within `self`,
/// yielded in reverse order along with the index of the match.
///
/// For matches of `pat` within `self` that overlap, only the indices
/// corresponding to the last match are returned.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines if a
/// character matches.
///
/// [`char`]: primitive.char.html
///
/// # Iterator behavior
///
/// The returned iterator requires that the pattern supports a reverse
/// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse
/// search yields the same elements.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
///
/// For iterating from the front, the [`match_indices`] method can be used.
///
/// [`match_indices`]: #method.match_indices
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let v: Vec<_> = "abcXXXabcYYYabc".rmatch_indices("abc").collect();
/// assert_eq!(v, [(12, "abc"), (6, "abc"), (0, "abc")]);
///
/// let v: Vec<_> = "1abcabc2".rmatch_indices("abc").collect();
/// assert_eq!(v, [(4, "abc"), (1, "abc")]);
///
/// let v: Vec<_> = "ababa".rmatch_indices("aba").collect();
/// assert_eq!(v, [(2, "aba")]); // only the last `aba`
/// ```
#[stable(feature = "str_match_indices", since = "1.5.0")]
#[inline]
pub fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
core_str::StrExt::rmatch_indices(self, pat)
}
/// Returns a string slice with leading and trailing whitespace removed.
///
/// 'Whitespace' is defined according to the terms of the Unicode Derived
/// Core Property `White_Space`.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = " Hello\tworld\t";
///
/// assert_eq!("Hello\tworld", s.trim());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn trim(&self) -> &str {
UnicodeStr::trim(self)
}
/// Returns a string slice with leading whitespace removed.
///
/// 'Whitespace' is defined according to the terms of the Unicode Derived
/// Core Property `White_Space`.
///
/// # Text directionality
///
/// A string is a sequence of bytes. 'Left' in this context means the first
/// position of that byte string; for a language like Arabic or Hebrew
/// which are 'right to left' rather than 'left to right', this will be
/// the _right_ side, not the left.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = " Hello\tworld\t";
///
/// assert_eq!("Hello\tworld\t", s.trim_left());
/// ```
///
/// Directionality:
///
/// ```
/// let s = " English";
/// assert!(Some('E') == s.trim_left().chars().next());
///
/// let s = " עברית";
/// assert!(Some('ע') == s.trim_left().chars().next());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn trim_left(&self) -> &str {
UnicodeStr::trim_left(self)
}
/// Returns a string slice with trailing whitespace removed.
///
/// 'Whitespace' is defined according to the terms of the Unicode Derived
/// Core Property `White_Space`.
///
/// # Text directionality
///
/// A string is a sequence of bytes. 'Right' in this context means the last
/// position of that byte string; for a language like Arabic or Hebrew
/// which are 'right to left' rather than 'left to right', this will be
/// the _left_ side, not the right.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = " Hello\tworld\t";
///
/// assert_eq!(" Hello\tworld", s.trim_right());
/// ```
///
/// Directionality:
///
/// ```
/// let s = "English ";
/// assert!(Some('h') == s.trim_right().chars().rev().next());
///
/// let s = "עברית ";
/// assert!(Some('ת') == s.trim_right().chars().rev().next());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn trim_right(&self) -> &str {
UnicodeStr::trim_right(self)
}
/// Returns a string slice with all prefixes and suffixes that match a
/// pattern repeatedly removed.
///
/// The pattern can be a [`char`] or a closure that determines if a
/// character matches.
///
/// [`char`]: primitive.char.html
///
/// # Examples
///
/// Simple patterns:
///
/// ```
/// assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
/// assert_eq!("123foo1bar123".trim_matches(char::is_numeric), "foo1bar");
///
/// let x: &[_] = &['1', '2'];
/// assert_eq!("12foo1bar12".trim_matches(x), "foo1bar");
/// ```
///
/// A more complex pattern, using a closure:
///
/// ```
/// assert_eq!("1foo1barXX".trim_matches(|c| c == '1' || c == 'X'), "foo1bar");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
where P::Searcher: DoubleEndedSearcher<'a>
{
core_str::StrExt::trim_matches(self, pat)
}
/// Returns a string slice with all prefixes that match a pattern
/// repeatedly removed.
///
/// The pattern can be a `&str`, [`char`], or a closure that determines if
/// a character matches.
///
/// [`char`]: primitive.char.html
///
/// # Text directionality
///
/// A string is a sequence of bytes. 'Left' in this context means the first
/// position of that byte string; for a language like Arabic or Hebrew
/// which are 'right to left' rather than 'left to right', this will be
/// the _right_ side, not the left.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
/// assert_eq!("123foo1bar123".trim_left_matches(char::is_numeric), "foo1bar123");
///
/// let x: &[_] = &['1', '2'];
/// assert_eq!("12foo1bar12".trim_left_matches(x), "foo1bar12");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
core_str::StrExt::trim_left_matches(self, pat)
}
/// Returns a string slice with all suffixes that match a pattern
/// repeatedly removed.
///
/// The pattern can be a `&str`, [`char`], or a closure that
/// determines if a character matches.
///
/// [`char`]: primitive.char.html
///
/// # Text directionality
///
/// A string is a sequence of bytes. 'Right' in this context means the last
/// position of that byte string; for a language like Arabic or Hebrew
/// which are 'right to left' rather than 'left to right', this will be
/// the _left_ side, not the right.
///
/// # Examples
///
/// Simple patterns:
///
/// ```
/// assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
/// assert_eq!("123foo1bar123".trim_right_matches(char::is_numeric), "123foo1bar");
///
/// let x: &[_] = &['1', '2'];
/// assert_eq!("12foo1bar12".trim_right_matches(x), "12foo1bar");
/// ```
///
/// A more complex pattern, using a closure:
///
/// ```
/// assert_eq!("1fooX".trim_left_matches(|c| c == '1' || c == 'X'), "fooX");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
where P::Searcher: ReverseSearcher<'a>
{
core_str::StrExt::trim_right_matches(self, pat)
}
/// Parses this string slice into another type.
///
/// Because `parse` is so general, it can cause problems with type
/// inference. As such, `parse` is one of the few times you'll see
/// the syntax affectionately known as the 'turbofish': `::<>`. This
/// helps the inference algorithm understand specifically which type
/// you're trying to parse into.
///
/// `parse` can parse any type that implements the [`FromStr`] trait.
///
/// [`FromStr`]: str/trait.FromStr.html
///
/// # Errors
///
/// Will return [`Err`] if it's not possible to parse this string slice into
/// the desired type.
///
/// [`Err`]: str/trait.FromStr.html#associatedtype.Err
///
/// # Example
///
/// Basic usage
///
/// ```
/// let four: u32 = "4".parse().unwrap();
///
/// assert_eq!(4, four);
/// ```
///
/// Using the 'turbofish' instead of annotating `four`:
///
/// ```
/// let four = "4".parse::<u32>();
///
/// assert_eq!(Ok(4), four);
/// ```
///
/// Failing to parse:
///
/// ```
/// let nope = "j".parse::<u32>();
///
/// assert!(nope.is_err());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
core_str::StrExt::parse(self)
}
/// Converts a `Box<str>` into a `Box<[u8]>` without copying or allocating.
#[unstable(feature = "str_box_extras", issue = "41119")]
pub fn into_boxed_bytes(self: Box<str>) -> Box<[u8]> {
self.into()
}
/// Replaces all matches of a pattern with another string.
///
/// `replace` creates a new [`String`], and copies the data from this string slice into it.
/// While doing so, it attempts to find matches of a pattern. If it finds any, it
/// replaces them with the replacement string slice.
///
/// [`String`]: string/struct.String.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = "this is old";
///
/// assert_eq!("this is new", s.replace("old", "new"));
/// ```
///
/// When the pattern doesn't match:
///
/// ```
/// let s = "this is old";
/// assert_eq!(s, s.replace("cookie monster", "little lamb"));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn replace<'a, P: Pattern<'a>>(&'a self, from: P, to: &str) -> String {
let mut result = String::new();
let mut last_end = 0;
for (start, part) in self.match_indices(from) {
result.push_str(unsafe { self.slice_unchecked(last_end, start) });
result.push_str(to);
last_end = start + part.len();
}
result.push_str(unsafe { self.slice_unchecked(last_end, self.len()) });
result
}
/// Replaces first N matches of a pattern with another string.
///
/// `replacen` creates a new [`String`], and copies the data from this string slice into it.
/// While doing so, it attempts to find matches of a pattern. If it finds any, it
/// replaces them with the replacement string slice at most `count` times.
///
/// [`String`]: string/struct.String.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = "foo foo 123 foo";
/// assert_eq!("new new 123 foo", s.replacen("foo", "new", 2));
/// assert_eq!("faa fao 123 foo", s.replacen('o', "a", 3));
/// assert_eq!("foo foo new23 foo", s.replacen(char::is_numeric, "new", 1));
/// ```
///
/// When the pattern doesn't match:
///
/// ```
/// let s = "this is old";
/// assert_eq!(s, s.replacen("cookie monster", "little lamb", 10));
/// ```
#[stable(feature = "str_replacen", since = "1.16.0")]
pub fn replacen<'a, P: Pattern<'a>>(&'a self, pat: P, to: &str, count: usize) -> String {
// Hope to reduce the times of re-allocation
let mut result = String::with_capacity(32);
let mut last_end = 0;
for (start, part) in self.match_indices(pat).take(count) {
result.push_str(unsafe { self.slice_unchecked(last_end, start) });
result.push_str(to);
last_end = start + part.len();
}
result.push_str(unsafe { self.slice_unchecked(last_end, self.len()) });
result
}
/// Returns the lowercase equivalent of this string slice, as a new [`String`].
///
/// 'Lowercase' is defined according to the terms of the Unicode Derived Core Property
/// `Lowercase`.
///
/// Since some characters can expand into multiple characters when changing
/// the case, this function returns a [`String`] instead of modifying the
/// parameter in-place.
///
/// [`String`]: string/struct.String.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = "HELLO";
///
/// assert_eq!("hello", s.to_lowercase());
/// ```
///
/// A tricky example, with sigma:
///
/// ```
/// let sigma = "Σ";
///
/// assert_eq!("σ", sigma.to_lowercase());
///
/// // but at the end of a word, it's ς, not σ:
/// let odysseus = "ὈΔΥΣΣΕΎΣ";
///
/// assert_eq!("ὀδυσσεύς", odysseus.to_lowercase());
/// ```
///
/// Languages without case are not changed:
///
/// ```
/// let new_year = "农历新年";
///
/// assert_eq!(new_year, new_year.to_lowercase());
/// ```
#[stable(feature = "unicode_case_mapping", since = "1.2.0")]
pub fn to_lowercase(&self) -> String {
let mut s = String::with_capacity(self.len());
for (i, c) in self[..].char_indices() {
if c == 'Σ' {
// Σ maps to σ, except at the end of a word where it maps to ς.
// This is the only conditional (contextual) but language-independent mapping
// in `SpecialCasing.txt`,
// so hard-code it rather than have a generic "condition" mechanism.
// See https://github.com/rust-lang/rust/issues/26035
map_uppercase_sigma(self, i, &mut s)
} else {
s.extend(c.to_lowercase());
}
}
return s;
fn map_uppercase_sigma(from: &str, i: usize, to: &mut String) {
// See http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992
// for the definition of `Final_Sigma`.
debug_assert!('Σ'.len_utf8() == 2);
let is_word_final = case_ignoreable_then_cased(from[..i].chars().rev()) &&
!case_ignoreable_then_cased(from[i + 2..].chars());
to.push_str(if is_word_final { "ς" } else { "σ" });
}
fn case_ignoreable_then_cased<I: Iterator<Item = char>>(iter: I) -> bool {
use std_unicode::derived_property::{Cased, Case_Ignorable};
match iter.skip_while(|&c| Case_Ignorable(c)).next() {
Some(c) => Cased(c),
None => false,
}
}
}
/// Returns the uppercase equivalent of this string slice, as a new [`String`].
///
/// 'Uppercase' is defined according to the terms of the Unicode Derived Core Property
/// `Uppercase`.
///
/// Since some characters can expand into multiple characters when changing
/// the case, this function returns a [`String`] instead of modifying the
/// parameter in-place.
///
/// [`String`]: string/struct.String.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = "hello";
///
/// assert_eq!("HELLO", s.to_uppercase());
/// ```
///
/// Scripts without case are not changed:
///
/// ```
/// let new_year = "农历新年";
///
/// assert_eq!(new_year, new_year.to_uppercase());
/// ```
#[stable(feature = "unicode_case_mapping", since = "1.2.0")]
pub fn to_uppercase(&self) -> String {
let mut s = String::with_capacity(self.len());
s.extend(self.chars().flat_map(|c| c.to_uppercase()));
return s;
}
/// Escapes each char in `s` with [`char::escape_debug`].
///
/// [`char::escape_debug`]: primitive.char.html#method.escape_debug
#[unstable(feature = "str_escape",
reason = "return type may change to be an iterator",
issue = "27791")]
pub fn escape_debug(&self) -> String {
self.chars().flat_map(|c| c.escape_debug()).collect()
}
/// Escapes each char in `s` with [`char::escape_default`].
///
/// [`char::escape_default`]: primitive.char.html#method.escape_default
#[unstable(feature = "str_escape",
reason = "return type may change to be an iterator",
issue = "27791")]
pub fn escape_default(&self) -> String {
self.chars().flat_map(|c| c.escape_default()).collect()
}
/// Escapes each char in `s` with [`char::escape_unicode`].
///
/// [`char::escape_unicode`]: primitive.char.html#method.escape_unicode
#[unstable(feature = "str_escape",
reason = "return type may change to be an iterator",
issue = "27791")]
pub fn escape_unicode(&self) -> String {
self.chars().flat_map(|c| c.escape_unicode()).collect()
}
/// Converts a [`Box<str>`] into a [`String`] without copying or allocating.
///
/// [`String`]: string/struct.String.html
/// [`Box<str>`]: boxed/struct.Box.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let string = String::from("birthday gift");
/// let boxed_str = string.clone().into_boxed_str();
///
/// assert_eq!(boxed_str.into_string(), string);
/// ```
#[stable(feature = "box_str", since = "1.4.0")]
pub fn into_string(self: Box<str>) -> String {
unsafe {
let slice = mem::transmute::<Box<str>, Box<[u8]>>(self);
String::from_utf8_unchecked(slice.into_vec())
}
}
/// Create a [`String`] by repeating a string `n` times.
///
/// [`String`]: string/struct.String.html
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// assert_eq!("abc".repeat(4), String::from("abcabcabcabc"));
/// ```
#[stable(feature = "repeat_str", since = "1.16.0")]
pub fn repeat(&self, n: usize) -> String {
let mut s = String::with_capacity(self.len() * n);
s.extend((0..n).map(|_| self));
s
}
}
+1 -1
View File
@@ -2015,7 +2015,7 @@ fn index_mut(self, slice: &mut str) -> &mut Self::Output {
issue = "32110")]
pub trait StrExt {
// NB there are no docs here are they're all located on the StrExt trait in
// libcollections, not here.
// liballoc, not here.
#[stable(feature = "core", since = "1.6.0")]
fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool;
+1 -1
View File
@@ -26,7 +26,7 @@ pub fn FnvHashSet<V: Hash + Eq>() -> FnvHashSet<V> {
}
/// A speedy hash algorithm for node ids and def ids. The hashmap in
/// libcollections by default uses SipHash which isn't quite as speedy as we
/// liballoc by default uses SipHash which isn't quite as speedy as we
/// want. In the compiler we're not really worried about DOS attempts, so we
/// just default to a non-cryptographic hash.
///
+1 -1
View File
@@ -26,7 +26,7 @@ pub fn FxHashSet<V: Hash + Eq>() -> FxHashSet<V> {
HashSet::default()
}
/// A speedy hash algorithm for use within rustc. The hashmap in libcollections
/// A speedy hash algorithm for use within rustc. The hashmap in liballoc
/// by default uses SipHash which isn't quite as speedy as we want. In the
/// compiler we're not really worried about DOS attempts, so we use a fast
/// non-cryptographic hash.
+9 -9
View File
@@ -188,16 +188,16 @@ fn main() {}
Erroneous code example:
```compile_fail,E0254
extern crate collections;
extern crate alloc;
mod foo {
pub trait collections {
pub trait alloc {
fn do_something();
}
}
use foo::collections; // error: an extern crate named `collections` has already
// been imported in this module
use foo::alloc; // error: an extern crate named `alloc` has already
// been imported in this module
fn main() {}
```
@@ -206,15 +206,15 @@ fn main() {}
Example:
```ignore
extern crate collections as libcollections; // ok!
extern crate alloc as liballoc; // ok!
mod foo {
pub trait collections {
pub trait alloc {
fn do_something();
}
}
use foo::collections;
use foo::alloc;
fn main() {}
```
@@ -1425,7 +1425,7 @@ mod foo {
```compile_fail,E0469
#[macro_use(drink, be_merry)] // error: imported macro not found
extern crate collections;
extern crate alloc;
fn main() {
// ...
@@ -1467,7 +1467,7 @@ macro_rules! drink {
```compile_fail,E0470
#[macro_reexport(drink, be_merry)]
extern crate collections;
extern crate alloc;
fn main() {
// ...
+2 -2
View File
@@ -2265,8 +2265,8 @@ fn make(&mut self) -> Foo<T> {
following trait `impl` is an error:
```compile_fail,E0210
extern crate collections;
use collections::range::RangeArgument;
extern crate alloc;
use alloc::range::RangeArgument;
impl<T> RangeArgument<T> for T { } // error
+1 -1
View File
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Implementations of serialization for structures found in libcollections
//! Implementations of serialization for structures found in liballoc
use std::hash::{Hash, BuildHasher};
-3
View File
@@ -28,15 +28,12 @@
#![deny(warnings)]
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core_intrinsics)]
#![feature(i128_type)]
#![feature(specialization)]
#![cfg_attr(stage0, feature(staged_api))]
#![cfg_attr(test, feature(test))]
extern crate collections;
pub use self::serialize::{Decoder, Encoder, Decodable, Encodable};
pub use self::serialize::{SpecializationError, SpecializedEncoder, SpecializedDecoder};
-1
View File
@@ -15,7 +15,6 @@ alloc_jemalloc = { path = "../liballoc_jemalloc", optional = true }
alloc_system = { path = "../liballoc_system" }
panic_unwind = { path = "../libpanic_unwind", optional = true }
panic_abort = { path = "../libpanic_abort" }
collections = { path = "../libcollections" }
core = { path = "../libcore" }
libc = { path = "../rustc/libc_shim" }
rand = { path = "../librand" }
+6 -6
View File
@@ -420,15 +420,15 @@
#![stable(feature = "rust1", since = "1.0.0")]
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::Bound;
pub use alloc::Bound;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::{BinaryHeap, BTreeMap, BTreeSet};
pub use alloc::{BinaryHeap, BTreeMap, BTreeSet};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::{LinkedList, VecDeque};
pub use alloc::{LinkedList, VecDeque};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::{binary_heap, btree_map, btree_set};
pub use alloc::{binary_heap, btree_map, btree_set};
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::{linked_list, vec_deque};
pub use alloc::{linked_list, vec_deque};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::hash_map::HashMap;
@@ -436,7 +436,7 @@
pub use self::hash_set::HashSet;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::range;
pub use alloc::range;
mod hash;
+7 -10
View File
@@ -254,7 +254,6 @@
#![feature(cfg_target_vendor)]
#![feature(char_escape_debug)]
#![feature(char_internals)]
#![feature(collections)]
#![feature(collections_range)]
#![feature(compiler_builtins_lib)]
#![feature(const_fn)]
@@ -337,11 +336,9 @@
debug_assert_ne, unreachable, unimplemented, write, writeln, try)]
extern crate core as __core;
#[allow(deprecated)] extern crate rand as core_rand;
#[macro_use]
#[macro_reexport(vec, format)]
extern crate collections as core_collections;
#[allow(deprecated)] extern crate rand as core_rand;
extern crate alloc;
extern crate std_unicode;
extern crate libc;
@@ -430,17 +427,17 @@
#[stable(feature = "rust1", since = "1.0.0")]
pub use alloc::rc;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::borrow;
pub use alloc::borrow;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::fmt;
pub use alloc::fmt;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::slice;
pub use alloc::slice;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::str;
pub use alloc::str;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::string;
pub use alloc::string;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::vec;
pub use alloc::vec;
#[stable(feature = "rust1", since = "1.0.0")]
pub use std_unicode::char;
#[unstable(feature = "i128", issue = "35118")]
+1 -1
View File
@@ -52,7 +52,7 @@ pub mod str {
pub use u_str::Utf16Encoder;
}
// For use in libcollections, not re-exported in libstd.
// For use in liballoc, not re-exported in libstd.
pub mod derived_property {
pub use tables::derived_property::{Case_Ignorable, Cased};
}
+1 -1
View File
@@ -32,7 +32,7 @@ pub struct SplitWhitespace<'a> {
}
/// Methods for Unicode string slices
#[allow(missing_docs)] // docs in libcollections
#[allow(missing_docs)] // docs in liballoc
pub trait UnicodeStr {
fn split_whitespace<'a>(&'a self) -> SplitWhitespace<'a>;
fn is_whitespace(&self) -> bool;
+5 -5
View File
@@ -8,18 +8,18 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(collections)]
#![feature(alloc)]
extern crate collections;
//~^ NOTE previous import of `collections` here
extern crate alloc;
//~^ NOTE previous import of `alloc` here
mod foo {
pub trait collections {
pub trait alloc {
fn do_something();
}
}
use foo::collections;
use foo::alloc;
//~^ ERROR E0254
//~| NOTE already imported
+5 -5
View File
@@ -8,13 +8,13 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(collections, libc)]
#![feature(alloc, libc)]
extern crate collections;
//~^ NOTE previous import of `collections` here
extern crate alloc;
//~^ NOTE previous import of `alloc` here
extern crate libc as collections;
extern crate libc as alloc;
//~^ ERROR E0259
//~| NOTE `collections` already imported
//~| NOTE `alloc` already imported
fn main() {}
+6 -6
View File
@@ -8,14 +8,14 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(collections)]
#![feature(alloc)]
extern crate collections;
//~^ NOTE previous import of `collections` here
extern crate alloc;
//~^ NOTE previous import of `alloc` here
mod collections {
//~^ ERROR `collections` has already been imported in this module [E0260]
//~| NOTE `collections` already imported
mod alloc {
//~^ ERROR `alloc` has already been imported in this module [E0260]
//~| NOTE `alloc` already imported
pub trait MyTrait {
fn do_something();
}
@@ -13,13 +13,13 @@
#![deny(unused_extern_crates)]
#![allow(unused_variables)]
#![allow(deprecated)]
#![feature(alloc)]
#![feature(libc)]
#![feature(collections)]
#![feature(rand)]
extern crate libc; //~ ERROR: unused extern crate
extern crate collections as collecs; // no error, it is used
extern crate alloc as collecs; // no error, it is used
extern crate rand; // no error, the use marks it as used
// even if imported objects aren't used
@@ -8,25 +8,25 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(collections)]
#![feature(alloc)]
mod a {
extern crate collections;
use collections::HashMap;
//~^ ERROR unresolved import `collections::HashMap` [E0432]
//~| Did you mean `self::collections`?
extern crate alloc;
use alloc::HashMap;
//~^ ERROR unresolved import `alloc::HashMap` [E0432]
//~| Did you mean `self::alloc`?
mod b {
use collections::HashMap;
//~^ ERROR unresolved import `collections::HashMap` [E0432]
//~| Did you mean `a::collections`?
use alloc::HashMap;
//~^ ERROR unresolved import `alloc::HashMap` [E0432]
//~| Did you mean `a::alloc`?
mod c {
use collections::HashMap;
//~^ ERROR unresolved import `collections::HashMap` [E0432]
//~| Did you mean `a::collections`?
use alloc::HashMap;
//~^ ERROR unresolved import `alloc::HashMap` [E0432]
//~| Did you mean `a::alloc`?
mod d {
use collections::HashMap;
//~^ ERROR unresolved import `collections::HashMap` [E0432]
//~| Did you mean `a::collections`?
use alloc::HashMap;
//~^ ERROR unresolved import `alloc::HashMap` [E0432]
//~| Did you mean `a::alloc`?
}
}
}
-2
View File
@@ -8,10 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(collections)]
#![feature(rustc_private)]
extern crate collections;
extern crate serialize;
use std::collections::HashMap;
@@ -15,10 +15,9 @@
// - Multiple lifetime parameters
// - Arenas
#![feature(rustc_private, libc, collections)]
#![feature(rustc_private, libc)]
extern crate arena;
extern crate collections;
extern crate libc;
use TypeStructure::{TypeInt, TypeFunction};
@@ -9,8 +9,6 @@
// except according to those terms.
#![feature(collections)]
fn main() {
let args = vec!["foobie", "asdf::asdf"];
let arr: Vec<&str> = args[1].split("::").collect();
+2 -2
View File
@@ -8,12 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(lang_items, start, collections)]
#![feature(lang_items, start, alloc)]
#![no_std]
extern crate std as other;
#[macro_use] extern crate collections;
#[macro_use] extern crate alloc;
#[start]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
@@ -9,10 +9,6 @@
// except according to those terms.
#![feature(collections)]
extern crate collections;
use std::collections::HashMap;
// This is a fancy one: it uses an external iterator established
@@ -9,10 +9,6 @@
// except according to those terms.
#![feature(collections)]
extern crate collections;
use std::collections::HashMap;
pub fn main() {
+3 -3
View File
@@ -10,14 +10,14 @@
// ignore-emscripten missing rust_begin_unwind
#![feature(lang_items, start, collections)]
#![feature(lang_items, start, alloc)]
#![no_std]
extern crate std as other;
#[macro_use] extern crate collections;
#[macro_use] extern crate alloc;
use collections::string::ToString;
use alloc::string::ToString;
#[start]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
-4
View File
@@ -8,10 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(collections)]
extern crate collections;
use std::collections::HashSet;
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
-4
View File
@@ -8,10 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(collections)]
extern crate collections;
use std::collections::HashMap;
pub fn main() {
@@ -9,8 +9,6 @@
// except according to those terms.
#![feature(collections)]
fn main() {
let mut escaped = String::from("");
for c in '\u{10401}'.escape_unicode() {
-3
View File
@@ -10,9 +10,6 @@
// pretty-expanded FIXME #23616
#![feature(collections)]
extern crate collections;
use std::collections::VecDeque;
pub fn main() {
-4
View File
@@ -11,10 +11,6 @@
// Minimized version of issue-2804.rs. Both check that callee IDs don't
// clobber the previous node ID in a macro expr
#![feature(collections)]
extern crate collections;
use std::collections::HashMap;
fn add_interfaces(managed_ip: String, device: HashMap<String, isize>) {
+1 -4
View File
@@ -10,10 +10,7 @@
// pretty-expanded FIXME #23616
#![allow(unknown_features)]
#![feature(box_syntax, collections)]
extern crate collections;
#![feature(box_syntax)]
use std::collections::HashMap;
-4
View File
@@ -8,10 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(collections)]
extern crate collections;
use std::collections::HashMap;
fn check_strs(actual: &str, expected: &str) -> bool {
+1 -4
View File
@@ -9,10 +9,7 @@
// except according to those terms.
#![allow(unknown_features)]
#![feature(box_syntax, collections)]
extern crate collections;
#![feature(box_syntax)]
use std::collections::HashMap;
-4
View File
@@ -13,10 +13,6 @@
// pretty-expanded FIXME #23616
#![feature(collections)]
extern crate collections;
use std::collections::HashMap;
struct A(isize, isize);
-2
View File
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(collections)]
use std::string::String;
fn test_stack_assign() {
-2
View File
@@ -9,8 +9,6 @@
// except according to those terms.
#![feature(collections)]
pub fn main() {
let s = "\u{2603}";
assert_eq!(s, "");
-2
View File
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(collections)]
pub fn main() {
let thing = "{{ f }}";
let f = thing.find("{{");
+1 -1
View File
@@ -9,7 +9,7 @@
// except according to those terms.
#![allow(unknown_features)]
#![feature(box_syntax, collections, core)]
#![feature(box_syntax, core)]
use std::cell::RefCell;
use std::rc::Rc;
-2
View File
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(collections)]
use std::cell::RefCell;
use std::rc::Rc;
use std::string::String;
@@ -9,21 +9,16 @@
// except according to those terms.
#![allow(warnings)]
#![feature(collections)]
#![feature(drain, collections_bound, btree_range, vecmap)]
extern crate collections;
use collections::BinaryHeap;
use collections::{BTreeMap, BTreeSet};
use collections::LinkedList;
use collections::String;
use collections::Vec;
use collections::VecDeque;
use std::collections::BinaryHeap;
use std::collections::{BTreeMap, BTreeSet};
use std::collections::LinkedList;
use std::collections::VecDeque;
use std::collections::HashMap;
use std::collections::HashSet;
use collections::Bound::Included;
use std::collections::Bound::Included;
use std::mem;
fn is_sync<T>(_: T) where T: Sync {}
+1 -1
View File
@@ -9,7 +9,7 @@
// except according to those terms.
//
#![feature(collections, core, str_char)]
#![feature(core, str_char)]
use std::str;
+3 -3
View File
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(lang_items, start, libc, collections)]
#![feature(lang_items, start, libc, alloc)]
#![no_std]
extern crate std as other;
@@ -16,9 +16,9 @@
extern crate libc;
#[macro_use]
extern crate collections;
extern crate alloc;
use collections::vec::Vec;
use alloc::vec::Vec;
// Issue #16806
-2
View File
@@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(collections)]
use std::string::String;
#[derive(PartialEq)]
+5 -5
View File
@@ -118,15 +118,15 @@ fn check(cache: &mut Cache,
return None;
}
// FIXME(#32553)
if file.ends_with("collections/string/struct.String.html") {
if file.ends_with("string/struct.String.html") {
return None;
}
// FIXME(#32130)
if file.ends_with("btree_set/struct.BTreeSet.html") ||
file.ends_with("collections/struct.BTreeSet.html") ||
file.ends_with("collections/btree_map/struct.BTreeMap.html") ||
file.ends_with("collections/hash_map/struct.HashMap.html") ||
file.ends_with("collections/hash_set/struct.HashSet.html") {
file.ends_with("struct.BTreeSet.html") ||
file.ends_with("btree_map/struct.BTreeMap.html") ||
file.ends_with("hash_map/struct.HashMap.html") ||
file.ends_with("hash_set/struct.HashSet.html") {
return None;
}