Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libs: make Cow usable, improve documentation #19157

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/libcollections/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@

use self::Direction::*;
use alloc::boxed::Box;
use core::borrow::{BorrowFrom, BorrowFromMut};
use core::borrow::{BorrowFrom, BorrowFromMut, ToOwned};
use core::cmp;
use core::kinds::Sized;
use core::mem::size_of;
Expand Down Expand Up @@ -658,6 +658,11 @@ impl<T> BorrowFromMut<Vec<T>> for [T] {
fn borrow_from_mut(owned: &mut Vec<T>) -> &mut [T] { owned[mut] }
}

#[unstable = "trait is unstable"]
impl<T: Clone> ToOwned<Vec<T>> for [T] {
fn to_owned(&self) -> Vec<T> { self.to_vec() }
}

/// Unsafe operations
pub mod raw {
pub use core::slice::raw::{buf_as_slice, mut_buf_as_slice};
Expand Down
9 changes: 7 additions & 2 deletions src/libcollections/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
pub use self::MaybeOwned::*;
use self::RecompositionState::*;
use self::DecompositionType::*;
use core::borrow::BorrowFrom;
use core::borrow::{BorrowFrom, ToOwned};
use core::default::Default;
use core::fmt;
use core::cmp;
Expand All @@ -67,7 +67,7 @@ use core::prelude::{range};

use hash;
use ring_buf::RingBuf;
use string::String;
use string::{String, ToString};
use unicode;
use vec::Vec;

Expand Down Expand Up @@ -609,6 +609,11 @@ impl BorrowFrom<String> for str {
fn borrow_from(owned: &String) -> &str { owned[] }
}

#[unstable = "trait is unstable"]
impl ToOwned<String> for str {
fn to_owned(&self) -> String { self.to_string() }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use into_string. to_string goes through the formatting infrastructure, and tends to over-allocate space in the heap. See this playpen example, and also see #16415.

}

/// Unsafe string operations.
pub mod raw {
pub use core::str::raw::{from_utf8, c_str_to_static_slice, slice_bytes};
Expand Down
30 changes: 23 additions & 7 deletions src/libcore/borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@
//! data lazily when mutation or ownership is required. The type is designed to
//! work with general borrowed data via the `BorrowFrom` trait.
//!
//! `Cow` implements both `Deref` and `DerefMut`, which means that you can call
//! methods directly on the data it encloses. The first time a mutable reference
//! is required, the data will be cloned (via `to_owned`) if it is not
//! already owned.
//! `Cow` implements both `Deref`, which means that you can call
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extraneous "both"

//! non-mutating methods directly on the data it encloses. If mutation
//! is desired, `to_mut` will obtain a mutable references to an owned
//! value, cloning if necessary.

#![unstable = "recently added as part of collections reform"]

Expand Down Expand Up @@ -84,15 +84,31 @@ impl<T> ToOwned<T> for T where T: Clone {
}

/// A clone-on-write smart pointer.
pub enum Cow<'a, T, B: 'a> where B: ToOwned<T> {
///
/// # Example
///
/// ```rust
/// use std::borrow::Cow;
///
/// fn abs_all(input: &mut Cow<Vec<int>, [int]>) {
/// for i in range(0, input.len()) {
/// let v = input[i];
/// if v < 0 {
/// // clones into a vector the first time (if not already owned)
/// input.to_mut()[i] = -v;
/// }
/// }
/// }
/// ```
pub enum Cow<'a, T, Sized? B: 'a> where B: ToOwned<T> {
/// Borrowed data.
Borrowed(&'a B),

/// Owned data.
Owned(T)
}

impl<'a, T, B> Cow<'a, T, B> where B: ToOwned<T> {
impl<'a, T, Sized? B> Cow<'a, T, B> where B: ToOwned<T> {
/// Acquire a mutable reference to the owned form of the data.
///
/// Copies the data if it is not already owned.
Expand All @@ -117,7 +133,7 @@ impl<'a, T, B> Cow<'a, T, B> where B: ToOwned<T> {
}
}

impl<'a, T, B> Deref<B> for Cow<'a, T, B> where B: ToOwned<T> {
impl<'a, T, Sized? B> Deref<B> for Cow<'a, T, B> where B: ToOwned<T> {
fn deref(&self) -> &B {
match *self {
Borrowed(borrowed) => borrowed,
Expand Down