Skip to content

Commit 9b70775

Browse files
committed
Stabilize std::borrow
This commit stabilizes `std::borrow`, making the following modifications to catch up the API with language changes: * It renames `BorrowFrom` to `Borrow`, as was originally intended (but blocked for technical reasons), and reorders the parameters accordingly. * It moves the type parameter of `ToOwned` to an associated type. This is somewhat less flexible, in that each borrowed type must have a unique owned type, but leads to a significant simplification for `Cow`. Flexibility can be regained by using newtyped slices, which is advisable for other reasons anyway. * It removes the owned type parameter from `Cow`, making the type much less verbose. * Deprecates the `is_owned` and `is_borrowed` predicates in favor of direct matching. The above API changes are relatively minor; the basic functionality remains the same, and essentially the whole module is now marked `#[stable]`. [breaking-change]
1 parent 9bb3b37 commit 9b70775

File tree

30 files changed

+765
-424
lines changed

30 files changed

+765
-424
lines changed

src/liballoc/arc.rs

-7
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ use core::prelude::*;
7373

7474
use core::atomic;
7575
use core::atomic::Ordering::{Relaxed, Release, Acquire, SeqCst};
76-
use core::borrow::BorrowFrom;
7776
use core::fmt;
7877
use core::cmp::{Ordering};
7978
use core::default::Default;
@@ -244,12 +243,6 @@ impl<T> Clone for Arc<T> {
244243
}
245244
}
246245

247-
impl<T> BorrowFrom<Arc<T>> for T {
248-
fn borrow_from(owned: &Arc<T>) -> &T {
249-
&**owned
250-
}
251-
}
252-
253246
#[stable(feature = "rust1", since = "1.0.0")]
254247
impl<T> Deref for Arc<T> {
255248
type Target = T;

src/liballoc/rc.rs

-7
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@
144144
145145
#![stable(feature = "rust1", since = "1.0.0")]
146146

147-
use core::borrow::BorrowFrom;
148147
use core::cell::Cell;
149148
use core::clone::Clone;
150149
use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
@@ -349,12 +348,6 @@ impl<T: Clone> Rc<T> {
349348
}
350349
}
351350

352-
impl<T> BorrowFrom<Rc<T>> for T {
353-
fn borrow_from(owned: &Rc<T>) -> &T {
354-
&**owned
355-
}
356-
}
357-
358351
#[stable(feature = "rust1", since = "1.0.0")]
359352
impl<T> Deref for Rc<T> {
360353
type Target = T;

src/libcollections/borrow.rs

+306
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,306 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! A module for working with borrowed data.
12+
13+
#![stable(feature = "rust1", since = "1.0.0")]
14+
15+
use core::clone::Clone;
16+
use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
17+
use core::hash::{Hash, Hasher};
18+
use core::marker::Sized;
19+
use core::ops::Deref;
20+
use core::option::Option;
21+
22+
use fmt;
23+
use alloc::{rc, arc};
24+
25+
use self::Cow::*;
26+
27+
/// A trait for borrowing data.
28+
///
29+
/// In general, there may be several ways to "borrow" a piece of data. The
30+
/// typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T`
31+
/// (a mutable borrow). But types like `Vec<T>` provide additional kinds of
32+
/// borrows: the borrowed slices `&[T]` and `&mut [T]`.
33+
///
34+
/// When writing generic code, it is often desirable to abstract over all ways
35+
/// of borrowing data from a given type. That is the role of the `Borrow`
36+
/// trait: if `T: Borrow<U>`, then `&U` can be borrowed from `&T`. A given
37+
/// type can be borrowed as multiple different types. In particular, `Vec<T>:
38+
/// Borrow<Vec<T>>` and `Vec<T>: Borrow<[T]>`.
39+
#[stable(feature = "rust1", since = "1.0.0")]
40+
pub trait Borrow<Borrowed: ?Sized> {
41+
/// Immutably borrow from an owned value.
42+
#[stable(feature = "rust1", since = "1.0.0")]
43+
fn borrow(&self) -> &Borrowed;
44+
}
45+
46+
/// A trait for mutably borrowing data.
47+
///
48+
/// Similar to `Borrow`, but for mutable borrows.
49+
#[stable(feature = "rust1", since = "1.0.0")]
50+
pub trait BorrowMut<Borrowed: ?Sized> : Borrow<Borrowed> {
51+
/// Mutably borrow from an owned value.
52+
#[stable(feature = "rust1", since = "1.0.0")]
53+
fn borrow_mut(&mut self) -> &mut Borrowed;
54+
}
55+
56+
#[stable(feature = "rust1", since = "1.0.0")]
57+
impl<T: ?Sized> Borrow<T> for T {
58+
fn borrow(&self) -> &T { self }
59+
}
60+
61+
#[stable(feature = "rust1", since = "1.0.0")]
62+
impl<T: ?Sized> BorrowMut<T> for T {
63+
fn borrow_mut(&mut self) -> &mut T { self }
64+
}
65+
66+
#[stable(feature = "rust1", since = "1.0.0")]
67+
impl<'a, T: ?Sized> Borrow<T> for &'a T {
68+
fn borrow(&self) -> &T { &**self }
69+
}
70+
71+
#[stable(feature = "rust1", since = "1.0.0")]
72+
impl<'a, T: ?Sized> Borrow<T> for &'a mut T {
73+
fn borrow(&self) -> &T { &**self }
74+
}
75+
76+
#[stable(feature = "rust1", since = "1.0.0")]
77+
impl<'a, T: ?Sized> BorrowMut<T> for &'a mut T {
78+
fn borrow_mut(&mut self) -> &mut T { &mut **self }
79+
}
80+
81+
impl<T> Borrow<T> for rc::Rc<T> {
82+
fn borrow(&self) -> &T { &**self }
83+
}
84+
85+
impl<T> Borrow<T> for arc::Arc<T> {
86+
fn borrow(&self) -> &T { &**self }
87+
}
88+
89+
#[stable(feature = "rust1", since = "1.0.0")]
90+
impl<'a, B: ?Sized> Borrow<B> for Cow<'a, B> where B: ToOwned, <B as ToOwned>::Owned: 'a {
91+
fn borrow(&self) -> &B {
92+
&**self
93+
}
94+
}
95+
96+
/// A generalization of Clone to borrowed data.
97+
///
98+
/// Some types make it possible to go from borrowed to owned, usually by
99+
/// implementing the `Clone` trait. But `Clone` works only for going from `&T`
100+
/// to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data
101+
/// from any borrow of a given type.
102+
#[stable(feature = "rust1", since = "1.0.0")]
103+
pub trait ToOwned {
104+
#[stable(feature = "rust1", since = "1.0.0")]
105+
type Owned: Borrow<Self>;
106+
107+
/// Create owned data from borrowed data, usually by copying.
108+
#[stable(feature = "rust1", since = "1.0.0")]
109+
fn to_owned(&self) -> Self::Owned;
110+
}
111+
112+
#[stable(feature = "rust1", since = "1.0.0")]
113+
impl<T> ToOwned for T where T: Clone {
114+
type Owned = T;
115+
fn to_owned(&self) -> T { self.clone() }
116+
}
117+
118+
/// A clone-on-write smart pointer.
119+
///
120+
/// The type `Cow` is a smart pointer providing clone-on-write functionality: it
121+
/// can enclose and provide immutable access to borrowed data, and clone the
122+
/// data lazily when mutation or ownership is required. The type is designed to
123+
/// work with general borrowed data via the `Borrow` trait.
124+
///
125+
/// `Cow` implements both `Deref`, which means that you can call
126+
/// non-mutating methods directly on the data it encloses. If mutation
127+
/// is desired, `to_mut` will obtain a mutable references to an owned
128+
/// value, cloning if necessary.
129+
///
130+
/// # Example
131+
///
132+
/// ```rust
133+
/// use std::borrow::Cow;
134+
///
135+
/// fn abs_all(input: &mut Cow<[int]>) {
136+
/// for i in 0..input.len() {
137+
/// let v = input[i];
138+
/// if v < 0 {
139+
/// // clones into a vector the first time (if not already owned)
140+
/// input.to_mut()[i] = -v;
141+
/// }
142+
/// }
143+
/// }
144+
/// ```
145+
#[stable(feature = "rust1", since = "1.0.0")]
146+
pub enum Cow<'a, B: ?Sized + 'a> where B: ToOwned {
147+
/// Borrowed data.
148+
#[stable(feature = "rust1", since = "1.0.0")]
149+
Borrowed(&'a B),
150+
151+
/// Owned data.
152+
#[stable(feature = "rust1", since = "1.0.0")]
153+
Owned(<B as ToOwned>::Owned)
154+
}
155+
156+
#[stable(feature = "rust1", since = "1.0.0")]
157+
impl<'a, B: ?Sized> Clone for Cow<'a, B> where B: ToOwned {
158+
fn clone(&self) -> Cow<'a, B> {
159+
match *self {
160+
Borrowed(b) => Borrowed(b),
161+
Owned(ref o) => {
162+
let b: &B = o.borrow();
163+
Owned(b.to_owned())
164+
},
165+
}
166+
}
167+
}
168+
169+
impl<'a, B: ?Sized> Cow<'a, B> where B: ToOwned {
170+
/// Acquire a mutable reference to the owned form of the data.
171+
///
172+
/// Copies the data if it is not already owned.
173+
#[stable(feature = "rust1", since = "1.0.0")]
174+
pub fn to_mut(&mut self) -> &mut <B as ToOwned>::Owned {
175+
match *self {
176+
Borrowed(borrowed) => {
177+
*self = Owned(borrowed.to_owned());
178+
self.to_mut()
179+
}
180+
Owned(ref mut owned) => owned
181+
}
182+
}
183+
184+
/// Extract the owned data.
185+
///
186+
/// Copies the data if it is not already owned.
187+
#[stable(feature = "rust1", since = "1.0.0")]
188+
pub fn into_owned(self) -> <B as ToOwned>::Owned {
189+
match self {
190+
Borrowed(borrowed) => borrowed.to_owned(),
191+
Owned(owned) => owned
192+
}
193+
}
194+
195+
/// Returns true if this `Cow` wraps a borrowed value
196+
#[deprecated(since = "1.0.0", reason = "match on the enum instead")]
197+
#[unstable(feature = "std_misc")]
198+
pub fn is_borrowed(&self) -> bool {
199+
match *self {
200+
Borrowed(_) => true,
201+
_ => false,
202+
}
203+
}
204+
205+
/// Returns true if this `Cow` wraps an owned value
206+
#[deprecated(since = "1.0.0", reason = "match on the enum instead")]
207+
#[unstable(feature = "std_misc")]
208+
pub fn is_owned(&self) -> bool {
209+
match *self {
210+
Owned(_) => true,
211+
_ => false,
212+
}
213+
}
214+
}
215+
216+
#[stable(feature = "rust1", since = "1.0.0")]
217+
impl<'a, B: ?Sized> Deref for Cow<'a, B> where B: ToOwned {
218+
type Target = B;
219+
220+
fn deref(&self) -> &B {
221+
match *self {
222+
Borrowed(borrowed) => borrowed,
223+
Owned(ref owned) => owned.borrow()
224+
}
225+
}
226+
}
227+
228+
#[stable(feature = "rust1", since = "1.0.0")]
229+
impl<'a, B: ?Sized> Eq for Cow<'a, B> where B: Eq + ToOwned {}
230+
231+
#[stable(feature = "rust1", since = "1.0.0")]
232+
impl<'a, B: ?Sized> Ord for Cow<'a, B> where B: Ord + ToOwned {
233+
#[inline]
234+
fn cmp(&self, other: &Cow<'a, B>) -> Ordering {
235+
Ord::cmp(&**self, &**other)
236+
}
237+
}
238+
239+
#[stable(feature = "rust1", since = "1.0.0")]
240+
impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq<Cow<'b, C>> for Cow<'a, B> where
241+
B: PartialEq<C> + ToOwned, C: ToOwned,
242+
{
243+
#[inline]
244+
fn eq(&self, other: &Cow<'b, C>) -> bool {
245+
PartialEq::eq(&**self, &**other)
246+
}
247+
}
248+
249+
#[stable(feature = "rust1", since = "1.0.0")]
250+
impl<'a, B: ?Sized> PartialOrd for Cow<'a, B> where B: PartialOrd + ToOwned,
251+
{
252+
#[inline]
253+
fn partial_cmp(&self, other: &Cow<'a, B>) -> Option<Ordering> {
254+
PartialOrd::partial_cmp(&**self, &**other)
255+
}
256+
}
257+
258+
#[stable(feature = "rust1", since = "1.0.0")]
259+
impl<'a, B: ?Sized> fmt::Debug for Cow<'a, B> where
260+
B: fmt::Debug + ToOwned,
261+
<B as ToOwned>::Owned: fmt::Debug,
262+
{
263+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
264+
match *self {
265+
Borrowed(ref b) => fmt::Debug::fmt(b, f),
266+
Owned(ref o) => fmt::Debug::fmt(o, f),
267+
}
268+
}
269+
}
270+
271+
#[stable(feature = "rust1", since = "1.0.0")]
272+
impl<'a, B: ?Sized> fmt::Display for Cow<'a, B> where
273+
B: fmt::Display + ToOwned,
274+
<B as ToOwned>::Owned: fmt::Display,
275+
{
276+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
277+
match *self {
278+
Borrowed(ref b) => fmt::Display::fmt(b, f),
279+
Owned(ref o) => fmt::Display::fmt(o, f),
280+
}
281+
}
282+
}
283+
284+
#[stable(feature = "rust1", since = "1.0.0")]
285+
impl<'a, B: ?Sized, S: Hasher> Hash<S> for Cow<'a, B> where B: Hash<S> + ToOwned
286+
{
287+
#[inline]
288+
fn hash(&self, state: &mut S) {
289+
Hash::hash(&**self, state)
290+
}
291+
}
292+
293+
/// Trait for moving into a `Cow`
294+
#[stable(feature = "rust1", since = "1.0.0")]
295+
pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
296+
/// Moves `self` into `Cow`
297+
#[stable(feature = "rust1", since = "1.0.0")]
298+
fn into_cow(self) -> Cow<'a, B>;
299+
}
300+
301+
#[stable(feature = "rust1", since = "1.0.0")]
302+
impl<'a, B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
303+
fn into_cow(self) -> Cow<'a, B> {
304+
self
305+
}
306+
}

0 commit comments

Comments
 (0)