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