From bab9564280a02ca04aa95e71c1c7163a31bc7867 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Thu, 20 Nov 2014 08:43:37 -0800 Subject: [PATCH] libs: make Cow usable, improve documentation This commit makes `Cow` more usable by allowing it to be applied to unsized types (as was intended) and providing some basic `ToOwned` implementations on slice types. It also corrects the documentation for `Cow` to no longer mention `DerefMut`, and adds an example. --- src/libcollections/slice.rs | 7 ++++++- src/libcollections/str.rs | 9 +++++++-- src/libcore/borrow.rs | 30 +++++++++++++++++++++++------- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 5e341ba8b04..345d8955eec 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -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; @@ -658,6 +658,11 @@ impl BorrowFromMut> for [T] { fn borrow_from_mut(owned: &mut Vec) -> &mut [T] { owned[mut] } } +#[unstable = "trait is unstable"] +impl ToOwned> for [T] { + fn to_owned(&self) -> Vec { self.to_vec() } +} + /// Unsafe operations pub mod raw { pub use core::slice::raw::{buf_as_slice, mut_buf_as_slice}; diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index aaa7da312f2..a4c3c43ddb9 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -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; @@ -67,7 +67,7 @@ use hash; use ring_buf::RingBuf; -use string::String; +use string::{String, ToString}; use unicode; use vec::Vec; @@ -609,6 +609,11 @@ impl BorrowFrom for str { fn borrow_from(owned: &String) -> &str { owned[] } } +#[unstable = "trait is unstable"] +impl ToOwned for str { + fn to_owned(&self) -> String { self.to_string() } +} + /// Unsafe string operations. pub mod raw { pub use core::str::raw::{from_utf8, c_str_to_static_slice, slice_bytes}; diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index f0a14c02382..f381d70a91b 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -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 +//! 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"] @@ -84,7 +84,23 @@ fn to_owned(&self) -> T { self.clone() } } /// A clone-on-write smart pointer. -pub enum Cow<'a, T, B: 'a> where B: ToOwned { +/// +/// # Example +/// +/// ```rust +/// use std::borrow::Cow; +/// +/// fn abs_all(input: &mut Cow, [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 { /// Borrowed data. Borrowed(&'a B), @@ -92,7 +108,7 @@ pub enum Cow<'a, T, B: 'a> where B: ToOwned { Owned(T) } -impl<'a, T, B> Cow<'a, T, B> where B: ToOwned { +impl<'a, T, Sized? B> Cow<'a, T, B> where B: ToOwned { /// Acquire a mutable reference to the owned form of the data. /// /// Copies the data if it is not already owned. @@ -117,7 +133,7 @@ pub fn into_owned(self) -> T { } } -impl<'a, T, B> Deref for Cow<'a, T, B> where B: ToOwned { +impl<'a, T, Sized? B> Deref for Cow<'a, T, B> where B: ToOwned { fn deref(&self) -> &B { match *self { Borrowed(borrowed) => borrowed,