]> git.lizzy.rs Git - rust.git/blob - library/alloc/src/borrow.rs
Rollup merge of #77074 - lcnr:array-from-ref, r=SimonSapin
[rust.git] / library / alloc / src / borrow.rs
1 //! A module for working with borrowed data.
2
3 #![stable(feature = "rust1", since = "1.0.0")]
4
5 use core::cmp::Ordering;
6 use core::hash::{Hash, Hasher};
7 use core::ops::{Add, AddAssign, Deref};
8
9 #[stable(feature = "rust1", since = "1.0.0")]
10 pub use core::borrow::{Borrow, BorrowMut};
11
12 use crate::fmt;
13 use crate::string::String;
14
15 use Cow::*;
16
17 #[stable(feature = "rust1", since = "1.0.0")]
18 impl<'a, B: ?Sized> Borrow<B> for Cow<'a, B>
19 where
20     B: ToOwned,
21     <B as ToOwned>::Owned: 'a,
22 {
23     fn borrow(&self) -> &B {
24         &**self
25     }
26 }
27
28 /// A generalization of `Clone` to borrowed data.
29 ///
30 /// Some types make it possible to go from borrowed to owned, usually by
31 /// implementing the `Clone` trait. But `Clone` works only for going from `&T`
32 /// to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data
33 /// from any borrow of a given type.
34 #[stable(feature = "rust1", since = "1.0.0")]
35 pub trait ToOwned {
36     /// The resulting type after obtaining ownership.
37     #[stable(feature = "rust1", since = "1.0.0")]
38     type Owned: Borrow<Self>;
39
40     /// Creates owned data from borrowed data, usually by cloning.
41     ///
42     /// # Examples
43     ///
44     /// Basic usage:
45     ///
46     /// ```
47     /// let s: &str = "a";
48     /// let ss: String = s.to_owned();
49     ///
50     /// let v: &[i32] = &[1, 2];
51     /// let vv: Vec<i32> = v.to_owned();
52     /// ```
53     #[stable(feature = "rust1", since = "1.0.0")]
54     #[must_use = "cloning is often expensive and is not expected to have side effects"]
55     fn to_owned(&self) -> Self::Owned;
56
57     /// Uses borrowed data to replace owned data, usually by cloning.
58     ///
59     /// This is borrow-generalized version of `Clone::clone_from`.
60     ///
61     /// # Examples
62     ///
63     /// Basic usage:
64     ///
65     /// ```
66     /// # #![feature(toowned_clone_into)]
67     /// let mut s: String = String::new();
68     /// "hello".clone_into(&mut s);
69     ///
70     /// let mut v: Vec<i32> = Vec::new();
71     /// [1, 2][..].clone_into(&mut v);
72     /// ```
73     #[unstable(feature = "toowned_clone_into", reason = "recently added", issue = "41263")]
74     fn clone_into(&self, target: &mut Self::Owned) {
75         *target = self.to_owned();
76     }
77 }
78
79 #[stable(feature = "rust1", since = "1.0.0")]
80 impl<T> ToOwned for T
81 where
82     T: Clone,
83 {
84     type Owned = T;
85     fn to_owned(&self) -> T {
86         self.clone()
87     }
88
89     fn clone_into(&self, target: &mut T) {
90         target.clone_from(self);
91     }
92 }
93
94 /// A clone-on-write smart pointer.
95 ///
96 /// The type `Cow` is a smart pointer providing clone-on-write functionality: it
97 /// can enclose and provide immutable access to borrowed data, and clone the
98 /// data lazily when mutation or ownership is required. The type is designed to
99 /// work with general borrowed data via the `Borrow` trait.
100 ///
101 /// `Cow` implements `Deref`, which means that you can call
102 /// non-mutating methods directly on the data it encloses. If mutation
103 /// is desired, `to_mut` will obtain a mutable reference to an owned
104 /// value, cloning if necessary.
105 ///
106 /// # Examples
107 ///
108 /// ```
109 /// use std::borrow::Cow;
110 ///
111 /// fn abs_all(input: &mut Cow<[i32]>) {
112 ///     for i in 0..input.len() {
113 ///         let v = input[i];
114 ///         if v < 0 {
115 ///             // Clones into a vector if not already owned.
116 ///             input.to_mut()[i] = -v;
117 ///         }
118 ///     }
119 /// }
120 ///
121 /// // No clone occurs because `input` doesn't need to be mutated.
122 /// let slice = [0, 1, 2];
123 /// let mut input = Cow::from(&slice[..]);
124 /// abs_all(&mut input);
125 ///
126 /// // Clone occurs because `input` needs to be mutated.
127 /// let slice = [-1, 0, 1];
128 /// let mut input = Cow::from(&slice[..]);
129 /// abs_all(&mut input);
130 ///
131 /// // No clone occurs because `input` is already owned.
132 /// let mut input = Cow::from(vec![-1, 0, 1]);
133 /// abs_all(&mut input);
134 /// ```
135 ///
136 /// Another example showing how to keep `Cow` in a struct:
137 ///
138 /// ```
139 /// use std::borrow::Cow;
140 ///
141 /// struct Items<'a, X: 'a> where [X]: ToOwned<Owned = Vec<X>> {
142 ///     values: Cow<'a, [X]>,
143 /// }
144 ///
145 /// impl<'a, X: Clone + 'a> Items<'a, X> where [X]: ToOwned<Owned = Vec<X>> {
146 ///     fn new(v: Cow<'a, [X]>) -> Self {
147 ///         Items { values: v }
148 ///     }
149 /// }
150 ///
151 /// // Creates a container from borrowed values of a slice
152 /// let readonly = [1, 2];
153 /// let borrowed = Items::new((&readonly[..]).into());
154 /// match borrowed {
155 ///     Items { values: Cow::Borrowed(b) } => println!("borrowed {:?}", b),
156 ///     _ => panic!("expect borrowed value"),
157 /// }
158 ///
159 /// let mut clone_on_write = borrowed;
160 /// // Mutates the data from slice into owned vec and pushes a new value on top
161 /// clone_on_write.values.to_mut().push(3);
162 /// println!("clone_on_write = {:?}", clone_on_write.values);
163 ///
164 /// // The data was mutated. Let check it out.
165 /// match clone_on_write {
166 ///     Items { values: Cow::Owned(_) } => println!("clone_on_write contains owned data"),
167 ///     _ => panic!("expect owned data"),
168 /// }
169 /// ```
170 #[stable(feature = "rust1", since = "1.0.0")]
171 pub enum Cow<'a, B: ?Sized + 'a>
172 where
173     B: ToOwned,
174 {
175     /// Borrowed data.
176     #[stable(feature = "rust1", since = "1.0.0")]
177     Borrowed(#[stable(feature = "rust1", since = "1.0.0")] &'a B),
178
179     /// Owned data.
180     #[stable(feature = "rust1", since = "1.0.0")]
181     Owned(#[stable(feature = "rust1", since = "1.0.0")] <B as ToOwned>::Owned),
182 }
183
184 #[stable(feature = "rust1", since = "1.0.0")]
185 impl<B: ?Sized + ToOwned> Clone for Cow<'_, B> {
186     fn clone(&self) -> Self {
187         match *self {
188             Borrowed(b) => Borrowed(b),
189             Owned(ref o) => {
190                 let b: &B = o.borrow();
191                 Owned(b.to_owned())
192             }
193         }
194     }
195
196     fn clone_from(&mut self, source: &Self) {
197         match (self, source) {
198             (&mut Owned(ref mut dest), &Owned(ref o)) => o.borrow().clone_into(dest),
199             (t, s) => *t = s.clone(),
200         }
201     }
202 }
203
204 impl<B: ?Sized + ToOwned> Cow<'_, B> {
205     /// Returns true if the data is borrowed, i.e. if `to_mut` would require additional work.
206     ///
207     /// # Examples
208     ///
209     /// ```
210     /// #![feature(cow_is_borrowed)]
211     /// use std::borrow::Cow;
212     ///
213     /// let cow = Cow::Borrowed("moo");
214     /// assert!(cow.is_borrowed());
215     ///
216     /// let bull: Cow<'_, str> = Cow::Owned("...moo?".to_string());
217     /// assert!(!bull.is_borrowed());
218     /// ```
219     #[unstable(feature = "cow_is_borrowed", issue = "65143")]
220     #[rustc_const_unstable(feature = "const_cow_is_borrowed", issue = "65143")]
221     pub const fn is_borrowed(&self) -> bool {
222         match *self {
223             Borrowed(_) => true,
224             Owned(_) => false,
225         }
226     }
227
228     /// Returns true if the data is owned, i.e. if `to_mut` would be a no-op.
229     ///
230     /// # Examples
231     ///
232     /// ```
233     /// #![feature(cow_is_borrowed)]
234     /// use std::borrow::Cow;
235     ///
236     /// let cow: Cow<'_, str> = Cow::Owned("moo".to_string());
237     /// assert!(cow.is_owned());
238     ///
239     /// let bull = Cow::Borrowed("...moo?");
240     /// assert!(!bull.is_owned());
241     /// ```
242     #[unstable(feature = "cow_is_borrowed", issue = "65143")]
243     #[rustc_const_unstable(feature = "const_cow_is_borrowed", issue = "65143")]
244     pub const fn is_owned(&self) -> bool {
245         !self.is_borrowed()
246     }
247
248     /// Acquires a mutable reference to the owned form of the data.
249     ///
250     /// Clones the data if it is not already owned.
251     ///
252     /// # Examples
253     ///
254     /// ```
255     /// use std::borrow::Cow;
256     ///
257     /// let mut cow = Cow::Borrowed("foo");
258     /// cow.to_mut().make_ascii_uppercase();
259     ///
260     /// assert_eq!(
261     ///   cow,
262     ///   Cow::Owned(String::from("FOO")) as Cow<str>
263     /// );
264     /// ```
265     #[stable(feature = "rust1", since = "1.0.0")]
266     pub fn to_mut(&mut self) -> &mut <B as ToOwned>::Owned {
267         match *self {
268             Borrowed(borrowed) => {
269                 *self = Owned(borrowed.to_owned());
270                 match *self {
271                     Borrowed(..) => unreachable!(),
272                     Owned(ref mut owned) => owned,
273                 }
274             }
275             Owned(ref mut owned) => owned,
276         }
277     }
278
279     /// Extracts the owned data.
280     ///
281     /// Clones the data if it is not already owned.
282     ///
283     /// # Examples
284     ///
285     /// Calling `into_owned` on a `Cow::Borrowed` clones the underlying data
286     /// and becomes a `Cow::Owned`:
287     ///
288     /// ```
289     /// use std::borrow::Cow;
290     ///
291     /// let s = "Hello world!";
292     /// let cow = Cow::Borrowed(s);
293     ///
294     /// assert_eq!(
295     ///   cow.into_owned(),
296     ///   String::from(s)
297     /// );
298     /// ```
299     ///
300     /// Calling `into_owned` on a `Cow::Owned` is a no-op:
301     ///
302     /// ```
303     /// use std::borrow::Cow;
304     ///
305     /// let s = "Hello world!";
306     /// let cow: Cow<str> = Cow::Owned(String::from(s));
307     ///
308     /// assert_eq!(
309     ///   cow.into_owned(),
310     ///   String::from(s)
311     /// );
312     /// ```
313     #[stable(feature = "rust1", since = "1.0.0")]
314     pub fn into_owned(self) -> <B as ToOwned>::Owned {
315         match self {
316             Borrowed(borrowed) => borrowed.to_owned(),
317             Owned(owned) => owned,
318         }
319     }
320 }
321
322 #[stable(feature = "rust1", since = "1.0.0")]
323 impl<B: ?Sized + ToOwned> Deref for Cow<'_, B> {
324     type Target = B;
325
326     fn deref(&self) -> &B {
327         match *self {
328             Borrowed(borrowed) => borrowed,
329             Owned(ref owned) => owned.borrow(),
330         }
331     }
332 }
333
334 #[stable(feature = "rust1", since = "1.0.0")]
335 impl<B: ?Sized> Eq for Cow<'_, B> where B: Eq + ToOwned {}
336
337 #[stable(feature = "rust1", since = "1.0.0")]
338 impl<B: ?Sized> Ord for Cow<'_, B>
339 where
340     B: Ord + ToOwned,
341 {
342     #[inline]
343     fn cmp(&self, other: &Self) -> Ordering {
344         Ord::cmp(&**self, &**other)
345     }
346 }
347
348 #[stable(feature = "rust1", since = "1.0.0")]
349 impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq<Cow<'b, C>> for Cow<'a, B>
350 where
351     B: PartialEq<C> + ToOwned,
352     C: ToOwned,
353 {
354     #[inline]
355     fn eq(&self, other: &Cow<'b, C>) -> bool {
356         PartialEq::eq(&**self, &**other)
357     }
358 }
359
360 #[stable(feature = "rust1", since = "1.0.0")]
361 impl<'a, B: ?Sized> PartialOrd for Cow<'a, B>
362 where
363     B: PartialOrd + ToOwned,
364 {
365     #[inline]
366     fn partial_cmp(&self, other: &Cow<'a, B>) -> Option<Ordering> {
367         PartialOrd::partial_cmp(&**self, &**other)
368     }
369 }
370
371 #[stable(feature = "rust1", since = "1.0.0")]
372 impl<B: ?Sized> fmt::Debug for Cow<'_, B>
373 where
374     B: fmt::Debug + ToOwned<Owned: fmt::Debug>,
375 {
376     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
377         match *self {
378             Borrowed(ref b) => fmt::Debug::fmt(b, f),
379             Owned(ref o) => fmt::Debug::fmt(o, f),
380         }
381     }
382 }
383
384 #[stable(feature = "rust1", since = "1.0.0")]
385 impl<B: ?Sized> fmt::Display for Cow<'_, B>
386 where
387     B: fmt::Display + ToOwned<Owned: fmt::Display>,
388 {
389     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
390         match *self {
391             Borrowed(ref b) => fmt::Display::fmt(b, f),
392             Owned(ref o) => fmt::Display::fmt(o, f),
393         }
394     }
395 }
396
397 #[stable(feature = "default", since = "1.11.0")]
398 impl<B: ?Sized> Default for Cow<'_, B>
399 where
400     B: ToOwned<Owned: Default>,
401 {
402     /// Creates an owned Cow<'a, B> with the default value for the contained owned value.
403     fn default() -> Self {
404         Owned(<B as ToOwned>::Owned::default())
405     }
406 }
407
408 #[stable(feature = "rust1", since = "1.0.0")]
409 impl<B: ?Sized> Hash for Cow<'_, B>
410 where
411     B: Hash + ToOwned,
412 {
413     #[inline]
414     fn hash<H: Hasher>(&self, state: &mut H) {
415         Hash::hash(&**self, state)
416     }
417 }
418
419 #[stable(feature = "rust1", since = "1.0.0")]
420 impl<T: ?Sized + ToOwned> AsRef<T> for Cow<'_, T> {
421     fn as_ref(&self) -> &T {
422         self
423     }
424 }
425
426 #[stable(feature = "cow_add", since = "1.14.0")]
427 impl<'a> Add<&'a str> for Cow<'a, str> {
428     type Output = Cow<'a, str>;
429
430     #[inline]
431     fn add(mut self, rhs: &'a str) -> Self::Output {
432         self += rhs;
433         self
434     }
435 }
436
437 #[stable(feature = "cow_add", since = "1.14.0")]
438 impl<'a> Add<Cow<'a, str>> for Cow<'a, str> {
439     type Output = Cow<'a, str>;
440
441     #[inline]
442     fn add(mut self, rhs: Cow<'a, str>) -> Self::Output {
443         self += rhs;
444         self
445     }
446 }
447
448 #[stable(feature = "cow_add", since = "1.14.0")]
449 impl<'a> AddAssign<&'a str> for Cow<'a, str> {
450     fn add_assign(&mut self, rhs: &'a str) {
451         if self.is_empty() {
452             *self = Cow::Borrowed(rhs)
453         } else if !rhs.is_empty() {
454             if let Cow::Borrowed(lhs) = *self {
455                 let mut s = String::with_capacity(lhs.len() + rhs.len());
456                 s.push_str(lhs);
457                 *self = Cow::Owned(s);
458             }
459             self.to_mut().push_str(rhs);
460         }
461     }
462 }
463
464 #[stable(feature = "cow_add", since = "1.14.0")]
465 impl<'a> AddAssign<Cow<'a, str>> for Cow<'a, str> {
466     fn add_assign(&mut self, rhs: Cow<'a, str>) {
467         if self.is_empty() {
468             *self = rhs
469         } else if !rhs.is_empty() {
470             if let Cow::Borrowed(lhs) = *self {
471                 let mut s = String::with_capacity(lhs.len() + rhs.len());
472                 s.push_str(lhs);
473                 *self = Cow::Owned(s);
474             }
475             self.to_mut().push_str(&rhs);
476         }
477     }
478 }