]> git.lizzy.rs Git - rust.git/blob - src/libcollections/borrow.rs
Auto merge of #27630 - sylvestre:master, r=dotdash
[rust.git] / src / libcollections / borrow.rs
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::convert::AsRef;
18 use core::hash::{Hash, Hasher};
19 use core::marker::Sized;
20 use core::ops::Deref;
21 use core::option::Option;
22
23 use fmt;
24 use alloc::{boxed, rc, arc};
25
26 use self::Cow::*;
27
28 /// A trait for borrowing data.
29 ///
30 /// In general, there may be several ways to "borrow" a piece of data.  The
31 /// typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T`
32 /// (a mutable borrow). But types like `Vec<T>` provide additional kinds of
33 /// borrows: the borrowed slices `&[T]` and `&mut [T]`.
34 ///
35 /// When writing generic code, it is often desirable to abstract over all ways
36 /// of borrowing data from a given type. That is the role of the `Borrow`
37 /// trait: if `T: Borrow<U>`, then `&U` can be borrowed from `&T`.  A given
38 /// type can be borrowed as multiple different types. In particular, `Vec<T>:
39 /// Borrow<Vec<T>>` and `Vec<T>: Borrow<[T]>`.
40 ///
41 /// If you are implementing `Borrow` and both `Self` and `Borrowed` implement
42 /// `Hash`, `Eq`, and/or `Ord`, they must produce the same result.
43 ///
44 /// `Borrow` is very similar to, but different than, `AsRef`. See
45 /// [the book][book] for more.
46 ///
47 /// [book]: ../../book/borrow-and-asref.html
48 #[stable(feature = "rust1", since = "1.0.0")]
49 pub trait Borrow<Borrowed: ?Sized> {
50     /// Immutably borrows from an owned value.
51     ///
52     /// # Examples
53     ///
54     /// ```
55     /// use std::borrow::Borrow;
56     ///
57     /// fn check<T: Borrow<str>>(s: T) {
58     ///     assert_eq!("Hello", s.borrow());
59     /// }
60     ///
61     /// let s = "Hello".to_string();
62     ///
63     /// check(s);
64     ///
65     /// let s = "Hello";
66     ///
67     /// check(s);
68     /// ```
69     #[stable(feature = "rust1", since = "1.0.0")]
70     fn borrow(&self) -> &Borrowed;
71 }
72
73 /// A trait for mutably borrowing data.
74 ///
75 /// Similar to `Borrow`, but for mutable borrows.
76 #[stable(feature = "rust1", since = "1.0.0")]
77 pub trait BorrowMut<Borrowed: ?Sized> : Borrow<Borrowed> {
78     /// Mutably borrows from an owned value.
79     ///
80     /// # Examples
81     ///
82     /// ```
83     /// use std::borrow::BorrowMut;
84     ///
85     /// fn check<T: BorrowMut<[i32]>>(mut v: T) {
86     ///     assert_eq!(&mut [1, 2, 3], v.borrow_mut());
87     /// }
88     ///
89     /// let v = vec![1, 2, 3];
90     ///
91     /// check(v);
92     /// ```
93     #[stable(feature = "rust1", since = "1.0.0")]
94     fn borrow_mut(&mut self) -> &mut Borrowed;
95 }
96
97 #[stable(feature = "rust1", since = "1.0.0")]
98 impl<T: ?Sized> Borrow<T> for T {
99     fn borrow(&self) -> &T { self }
100 }
101
102 #[stable(feature = "rust1", since = "1.0.0")]
103 impl<T: ?Sized> BorrowMut<T> for T {
104     fn borrow_mut(&mut self) -> &mut T { self }
105 }
106
107 #[stable(feature = "rust1", since = "1.0.0")]
108 impl<'a, T: ?Sized> Borrow<T> for &'a T {
109     fn borrow(&self) -> &T { &**self }
110 }
111
112 #[stable(feature = "rust1", since = "1.0.0")]
113 impl<'a, T: ?Sized> Borrow<T> for &'a mut T {
114     fn borrow(&self) -> &T { &**self }
115 }
116
117 #[stable(feature = "rust1", since = "1.0.0")]
118 impl<'a, T: ?Sized> BorrowMut<T> for &'a mut T {
119     fn borrow_mut(&mut self) -> &mut T { &mut **self }
120 }
121
122 impl<T: ?Sized> Borrow<T> for boxed::Box<T> {
123     fn borrow(&self) -> &T { &**self }
124 }
125
126 impl<T: ?Sized> BorrowMut<T> for boxed::Box<T> {
127     fn borrow_mut(&mut self) -> &mut T { &mut **self }
128 }
129
130 impl<T: ?Sized> Borrow<T> for rc::Rc<T> {
131     fn borrow(&self) -> &T { &**self }
132 }
133
134 impl<T: ?Sized> Borrow<T> for arc::Arc<T> {
135     fn borrow(&self) -> &T { &**self }
136 }
137
138 #[stable(feature = "rust1", since = "1.0.0")]
139 impl<'a, B: ?Sized> Borrow<B> for Cow<'a, B> where B: ToOwned, <B as ToOwned>::Owned: 'a {
140     fn borrow(&self) -> &B {
141         &**self
142     }
143 }
144
145 /// A generalization of `Clone` to borrowed data.
146 ///
147 /// Some types make it possible to go from borrowed to owned, usually by
148 /// implementing the `Clone` trait. But `Clone` works only for going from `&T`
149 /// to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data
150 /// from any borrow of a given type.
151 #[stable(feature = "rust1", since = "1.0.0")]
152 pub trait ToOwned {
153     #[stable(feature = "rust1", since = "1.0.0")]
154     type Owned: Borrow<Self>;
155
156     /// Creates owned data from borrowed data, usually by cloning.
157     #[stable(feature = "rust1", since = "1.0.0")]
158     fn to_owned(&self) -> Self::Owned;
159 }
160
161 #[stable(feature = "rust1", since = "1.0.0")]
162 impl<T> ToOwned for T where T: Clone {
163     type Owned = T;
164     fn to_owned(&self) -> T { self.clone() }
165 }
166
167 /// A clone-on-write smart pointer.
168 ///
169 /// The type `Cow` is a smart pointer providing clone-on-write functionality: it
170 /// can enclose and provide immutable access to borrowed data, and clone the
171 /// data lazily when mutation or ownership is required. The type is designed to
172 /// work with general borrowed data via the `Borrow` trait.
173 ///
174 /// `Cow` implements `Deref`, which means that you can call
175 /// non-mutating methods directly on the data it encloses. If mutation
176 /// is desired, `to_mut` will obtain a mutable reference to an owned
177 /// value, cloning if necessary.
178 ///
179 /// # Examples
180 ///
181 /// ```
182 /// use std::borrow::Cow;
183 ///
184 /// fn abs_all(input: &mut Cow<[i32]>) {
185 ///     for i in 0..input.len() {
186 ///         let v = input[i];
187 ///         if v < 0 {
188 ///             // clones into a vector the first time (if not already owned)
189 ///             input.to_mut()[i] = -v;
190 ///         }
191 ///     }
192 /// }
193 /// ```
194 #[stable(feature = "rust1", since = "1.0.0")]
195 pub enum Cow<'a, B: ?Sized + 'a> where B: ToOwned {
196     /// Borrowed data.
197     #[stable(feature = "rust1", since = "1.0.0")]
198     Borrowed(&'a B),
199
200     /// Owned data.
201     #[stable(feature = "rust1", since = "1.0.0")]
202     Owned(<B as ToOwned>::Owned)
203 }
204
205 #[stable(feature = "rust1", since = "1.0.0")]
206 impl<'a, B: ?Sized> Clone for Cow<'a, B> where B: ToOwned {
207     fn clone(&self) -> Cow<'a, B> {
208         match *self {
209             Borrowed(b) => Borrowed(b),
210             Owned(ref o) => {
211                 let b: &B = o.borrow();
212                 Owned(b.to_owned())
213             },
214         }
215     }
216 }
217
218 impl<'a, B: ?Sized> Cow<'a, B> where B: ToOwned {
219     /// Acquires a mutable reference to the owned form of the data.
220     ///
221     /// Clones the data if it is not already owned.
222     ///
223     /// # Examples
224     ///
225     /// ```
226     /// use std::borrow::Cow;
227     ///
228     /// let mut cow: Cow<[_]> = Cow::Owned(vec![1, 2, 3]);
229     ///
230     /// let hello = cow.to_mut();
231     ///
232     /// assert_eq!(hello, &[1, 2, 3]);
233     /// ```
234     #[stable(feature = "rust1", since = "1.0.0")]
235     pub fn to_mut(&mut self) -> &mut <B as ToOwned>::Owned {
236         match *self {
237             Borrowed(borrowed) => {
238                 *self = Owned(borrowed.to_owned());
239                 self.to_mut()
240             }
241             Owned(ref mut owned) => owned
242         }
243     }
244
245     /// Extracts the owned data.
246     ///
247     /// Clones the data if it is not already owned.
248     ///
249     /// # Examples
250     ///
251     /// ```
252     /// use std::borrow::Cow;
253     ///
254     /// let cow: Cow<[_]> = Cow::Owned(vec![1, 2, 3]);
255     ///
256     /// let hello = cow.into_owned();
257     ///
258     /// assert_eq!(vec![1, 2, 3], hello);
259     /// ```
260     #[stable(feature = "rust1", since = "1.0.0")]
261     pub fn into_owned(self) -> <B as ToOwned>::Owned {
262         match self {
263             Borrowed(borrowed) => borrowed.to_owned(),
264             Owned(owned) => owned
265         }
266     }
267 }
268
269 #[stable(feature = "rust1", since = "1.0.0")]
270 impl<'a, B: ?Sized> Deref for Cow<'a, B> where B: ToOwned {
271     type Target = B;
272
273     fn deref(&self) -> &B {
274         match *self {
275             Borrowed(borrowed) => borrowed,
276             Owned(ref owned) => owned.borrow()
277         }
278     }
279 }
280
281 #[stable(feature = "rust1", since = "1.0.0")]
282 impl<'a, B: ?Sized> Eq for Cow<'a, B> where B: Eq + ToOwned {}
283
284 #[stable(feature = "rust1", since = "1.0.0")]
285 impl<'a, B: ?Sized> Ord for Cow<'a, B> where B: Ord + ToOwned {
286     #[inline]
287     fn cmp(&self, other: &Cow<'a, B>) -> Ordering {
288         Ord::cmp(&**self, &**other)
289     }
290 }
291
292 #[stable(feature = "rust1", since = "1.0.0")]
293 impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq<Cow<'b, C>> for Cow<'a, B> where
294     B: PartialEq<C> + ToOwned, C: ToOwned,
295 {
296     #[inline]
297     fn eq(&self, other: &Cow<'b, C>) -> bool {
298         PartialEq::eq(&**self, &**other)
299     }
300 }
301
302 #[stable(feature = "rust1", since = "1.0.0")]
303 impl<'a, B: ?Sized> PartialOrd for Cow<'a, B> where B: PartialOrd + ToOwned,
304 {
305     #[inline]
306     fn partial_cmp(&self, other: &Cow<'a, B>) -> Option<Ordering> {
307         PartialOrd::partial_cmp(&**self, &**other)
308     }
309 }
310
311 #[stable(feature = "rust1", since = "1.0.0")]
312 impl<'a, B: ?Sized> fmt::Debug for Cow<'a, B> where
313     B: fmt::Debug + ToOwned,
314     <B as ToOwned>::Owned: fmt::Debug,
315 {
316     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
317         match *self {
318             Borrowed(ref b) => fmt::Debug::fmt(b, f),
319             Owned(ref o) => fmt::Debug::fmt(o, f),
320         }
321     }
322 }
323
324 #[stable(feature = "rust1", since = "1.0.0")]
325 impl<'a, B: ?Sized> fmt::Display for Cow<'a, B> where
326     B: fmt::Display + ToOwned,
327     <B as ToOwned>::Owned: fmt::Display,
328 {
329     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
330         match *self {
331             Borrowed(ref b) => fmt::Display::fmt(b, f),
332             Owned(ref o) => fmt::Display::fmt(o, f),
333         }
334     }
335 }
336
337 #[stable(feature = "rust1", since = "1.0.0")]
338 impl<'a, B: ?Sized> Hash for Cow<'a, B> where B: Hash + ToOwned
339 {
340     #[inline]
341     fn hash<H: Hasher>(&self, state: &mut H) {
342         Hash::hash(&**self, state)
343     }
344 }
345
346 /// Trait for moving into a `Cow`.
347 #[unstable(feature = "into_cow", reason = "may be replaced by `convert::Into`")]
348 pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
349     /// Moves `self` into `Cow`
350     fn into_cow(self) -> Cow<'a, B>;
351 }
352
353 #[stable(feature = "rust1", since = "1.0.0")]
354 impl<'a,  B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
355     fn into_cow(self) -> Cow<'a, B> {
356         self
357     }
358 }
359
360 #[stable(feature = "rust1", since = "1.0.0")]
361 impl<'a, T: ?Sized + ToOwned> AsRef<T> for Cow<'a, T> {
362     fn as_ref(&self) -> &T {
363         self
364     }
365 }