|
| 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 | +//! # The `BorrowFrom` traits |
| 14 | +//! |
| 15 | +//! In general, there may be several ways to "borrow" a piece of data. The |
| 16 | +//! typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T` |
| 17 | +//! (a mutable borrow). But types like `Vec<T>` provide additional kinds of |
| 18 | +//! borrows: the borrowed slices `&[T]` and `&mut [T]`. |
| 19 | +//! |
| 20 | +//! When writing generic code, it is often desirable to abstract over all ways |
| 21 | +//! of borrowing data from a given type. That is the role of the `BorrowFrom` |
| 22 | +//! trait: if `T: BorrowFrom<U>`, then `&T` can be borrowed from `&U`. A given |
| 23 | +//! type can be borrowed as multiple different types. In particular, `Vec<T>: |
| 24 | +//! BorrowFrom<Vec<T>>` and `[T]: BorrowFrom<Vec<T>>`. |
| 25 | +//! |
| 26 | +//! # The `ToOwned` trait |
| 27 | +//! |
| 28 | +//! Some types make it possible to go from borrowed to owned, usually by |
| 29 | +//! implementing the `Clone` trait. But `Clone` works only for going from `&T` |
| 30 | +//! to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data |
| 31 | +//! from any borrow of a given type. |
| 32 | +//! |
| 33 | +//! # The `Cow` (clone-on-write) type |
| 34 | +//! |
| 35 | +//! The type `Cow` is a smart pointer providing clone-on-write functionality: it |
| 36 | +//! can enclose and provide immutable access to borrowed data, and clone the |
| 37 | +//! data lazily when mutation or ownership is required. The type is designed to |
| 38 | +//! work with general borrowed data via the `BorrowFrom` trait. |
| 39 | +//! |
| 40 | +//! `Cow` implements both `Deref` and `DerefMut`, which means that you can call |
| 41 | +//! methods directly on the data it encloses. The first time a mutable reference |
| 42 | +//! is required, the data will be cloned (via `to_owned`) if it is not |
| 43 | +//! already owned. |
| 44 | +
|
| 45 | +#![unstable = "recently added as part of collections reform"] |
| 46 | + |
| 47 | +use clone::Clone; |
| 48 | +use kinds::Sized; |
| 49 | +use ops::Deref; |
| 50 | + |
| 51 | +/// A trait for borrowing data. |
| 52 | +pub trait BorrowFrom<Sized? Owned> for Sized? { |
| 53 | + /// Immutably borrow from an owned value. |
| 54 | + fn borrow_from(owned: &Owned) -> &Self; |
| 55 | +} |
| 56 | + |
| 57 | +/// A trait for mutably borrowing data. |
| 58 | +pub trait BorrowFromMut<Sized? Owned> for Sized? : BorrowFrom<Owned> { |
| 59 | + /// Mutably borrow from an owned value. |
| 60 | + fn borrow_from_mut(owned: &mut Owned) -> &mut Self; |
| 61 | +} |
| 62 | + |
| 63 | +impl<Sized? T> BorrowFrom<T> for T { |
| 64 | + fn borrow_from(owned: &T) -> &T { owned } |
| 65 | +} |
| 66 | + |
| 67 | +impl<Sized? T> BorrowFromMut<T> for T { |
| 68 | + fn borrow_from_mut(owned: &mut T) -> &mut T { owned } |
| 69 | +} |
| 70 | + |
| 71 | +impl BorrowFrom<&'static str> for str { |
| 72 | + fn borrow_from<'a>(owned: &'a &'static str) -> &'a str { &**owned } |
| 73 | +} |
| 74 | + |
| 75 | +/// A generalization of Clone to borrowed data. |
| 76 | +pub trait ToOwned<Owned> for Sized?: BorrowFrom<Owned> { |
| 77 | + /// Create owned data from borrowed data, usually by copying. |
| 78 | + fn to_owned(&self) -> Owned; |
| 79 | +} |
| 80 | + |
| 81 | +impl<T> ToOwned<T> for T where T: Clone { |
| 82 | + fn to_owned(&self) -> T { self.clone() } |
| 83 | +} |
| 84 | + |
| 85 | +/// A clone-on-write smart pointer. |
| 86 | +pub enum Cow<'a, T, B: 'a> where B: ToOwned<T> { |
| 87 | + /// Borrowed data. |
| 88 | + Borrowed(&'a B), |
| 89 | + |
| 90 | + /// Owned data. |
| 91 | + Owned(T) |
| 92 | +} |
| 93 | + |
| 94 | +impl<'a, T, B> Cow<'a, T, B> where B: ToOwned<T> { |
| 95 | + /// Acquire a mutable reference to the owned form of the data. |
| 96 | + /// |
| 97 | + /// Copies the data if it is not already owned. |
| 98 | + pub fn to_mut(&mut self) -> &mut T { |
| 99 | + match *self { |
| 100 | + Borrowed(borrowed) => { |
| 101 | + *self = Owned(borrowed.to_owned()); |
| 102 | + self.to_mut() |
| 103 | + } |
| 104 | + Owned(ref mut owned) => owned |
| 105 | + } |
| 106 | + } |
| 107 | + |
| 108 | + /// Extract the owned data. |
| 109 | + /// |
| 110 | + /// Copies the data if it is not already owned. |
| 111 | + pub fn into_owned(self) -> T { |
| 112 | + match self { |
| 113 | + Borrowed(borrowed) => borrowed.to_owned(), |
| 114 | + Owned(owned) => owned |
| 115 | + } |
| 116 | + } |
| 117 | +} |
| 118 | + |
| 119 | +impl<'a, T, B> Deref<B> for Cow<'a, T, B> where B: ToOwned<T> { |
| 120 | + fn deref(&self) -> &B { |
| 121 | + match *self { |
| 122 | + Borrowed(borrowed) => borrowed, |
| 123 | + Owned(ref owned) => BorrowFrom::borrow_from(owned) |
| 124 | + } |
| 125 | + } |
| 126 | +} |
0 commit comments