2015-02-12 07:16:32 +00:00
|
|
|
//! A module for working with borrowed data.
|
|
|
|
|
|
|
|
#![stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
2015-11-16 16:54:28 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-08-19 14:03:59 +00:00
|
|
|
pub use core::borrow::{Borrow, BorrowMut};
|
2019-02-03 07:27:44 +00:00
|
|
|
use core::cmp::Ordering;
|
|
|
|
use core::hash::{Hash, Hasher};
|
alloc: Add unstable Cfg feature `no-global_oom_handling`
For certain sorts of systems, programming, it's deemed essential that
all allocation failures be explicitly handled where they occur. For
example, see Linus Torvald's opinion in [1]. Merely not calling global
panic handlers, or always `try_reserving` first (for vectors), is not
deemed good enough, because the mere presence of the global OOM handlers
is burdens static analysis.
One option for these projects to use rust would just be to skip `alloc`,
rolling their own allocation abstractions. But this would, in my
opinion be a real shame. `alloc` has a few `try_*` methods already, and
we could easily have more. Features like custom allocator support also
demonstrate and existing to support diverse use-cases with the same
abstractions.
A natural way to add such a feature flag would a Cargo feature, but
there are currently uncertainties around how std library crate's Cargo
features may or not be stable, so to avoid any risk of stabilizing by
mistake we are going with a more low-level "raw cfg" token, which
cannot be interacted with via Cargo alone.
Note also that since there is no notion of "default cfg tokens" outside
of Cargo features, we have to invert the condition from
`global_oom_handling` to to `not(no_global_oom_handling)`. This breaks
the monotonicity that would be important for a Cargo feature (i.e.
turning on more features should never break compatibility), but it
doesn't matter for raw cfg tokens which are not intended to be
"constraint solved" by Cargo or anything else.
To support this use-case we create a new feature, "global-oom-handling",
on by default, and put the global OOM handler infra and everything else
it that depends on it behind it. By default, nothing is changed, but
users concerned about global handling can make sure it is disabled, and
be confident that all OOM handling is local and explicit.
For this first iteration, non-flat collections are outright disabled.
`Vec` and `String` don't yet have `try_*` allocation methods, but are
kept anyways since they can be oom-safely created "from parts", and we
hope to add those `try_` methods in the future.
[1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-17 00:18:04 +00:00
|
|
|
#[cfg(not(no_global_oom_handling))]
|
|
|
|
use core::ops::{Add, AddAssign};
|
2024-03-29 13:33:20 +00:00
|
|
|
use core::ops::{Deref, DerefPure};
|
2015-02-12 07:16:32 +00:00
|
|
|
|
2015-08-19 14:03:59 +00:00
|
|
|
use Cow::*;
|
2015-02-12 07:16:32 +00:00
|
|
|
|
2019-02-03 07:27:44 +00:00
|
|
|
use crate::fmt;
|
alloc: Add unstable Cfg feature `no-global_oom_handling`
For certain sorts of systems, programming, it's deemed essential that
all allocation failures be explicitly handled where they occur. For
example, see Linus Torvald's opinion in [1]. Merely not calling global
panic handlers, or always `try_reserving` first (for vectors), is not
deemed good enough, because the mere presence of the global OOM handlers
is burdens static analysis.
One option for these projects to use rust would just be to skip `alloc`,
rolling their own allocation abstractions. But this would, in my
opinion be a real shame. `alloc` has a few `try_*` methods already, and
we could easily have more. Features like custom allocator support also
demonstrate and existing to support diverse use-cases with the same
abstractions.
A natural way to add such a feature flag would a Cargo feature, but
there are currently uncertainties around how std library crate's Cargo
features may or not be stable, so to avoid any risk of stabilizing by
mistake we are going with a more low-level "raw cfg" token, which
cannot be interacted with via Cargo alone.
Note also that since there is no notion of "default cfg tokens" outside
of Cargo features, we have to invert the condition from
`global_oom_handling` to to `not(no_global_oom_handling)`. This breaks
the monotonicity that would be important for a Cargo feature (i.e.
turning on more features should never break compatibility), but it
doesn't matter for raw cfg tokens which are not intended to be
"constraint solved" by Cargo or anything else.
To support this use-case we create a new feature, "global-oom-handling",
on by default, and put the global OOM handler infra and everything else
it that depends on it behind it. By default, nothing is changed, but
users concerned about global handling can make sure it is disabled, and
be confident that all OOM handling is local and explicit.
For this first iteration, non-flat collections are outright disabled.
`Vec` and `String` don't yet have `try_*` allocation methods, but are
kept anyways since they can be oom-safely created "from parts", and we
hope to add those `try_` methods in the future.
[1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-17 00:18:04 +00:00
|
|
|
#[cfg(not(no_global_oom_handling))]
|
2019-02-03 07:27:44 +00:00
|
|
|
use crate::string::String;
|
2019-02-02 10:05:20 +00:00
|
|
|
|
2015-02-12 07:16:32 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-11-23 22:23:48 +00:00
|
|
|
impl<'a, B: ?Sized> Borrow<B> for Cow<'a, B>
|
|
|
|
where
|
|
|
|
B: ToOwned,
|
|
|
|
{
|
2015-02-12 07:16:32 +00:00
|
|
|
fn borrow(&self) -> &B {
|
|
|
|
&**self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-09 16:51:19 +00:00
|
|
|
/// A generalization of `Clone` to borrowed data.
|
2015-02-12 07:16:32 +00:00
|
|
|
///
|
|
|
|
/// Some types make it possible to go from borrowed to owned, usually by
|
|
|
|
/// implementing the `Clone` trait. But `Clone` works only for going from `&T`
|
|
|
|
/// to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data
|
|
|
|
/// from any borrow of a given type.
|
2021-02-15 22:58:03 +00:00
|
|
|
#[cfg_attr(not(test), rustc_diagnostic_item = "ToOwned")]
|
2021-02-16 02:32:21 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-12 07:16:32 +00:00
|
|
|
pub trait ToOwned {
|
2019-04-15 14:34:08 +00:00
|
|
|
/// The resulting type after obtaining ownership.
|
2015-02-12 07:16:32 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
type Owned: Borrow<Self>;
|
|
|
|
|
2015-04-09 16:51:19 +00:00
|
|
|
/// Creates owned data from borrowed data, usually by cloning.
|
2016-04-05 12:11:08 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// Basic usage:
|
|
|
|
///
|
|
|
|
/// ```
|
2017-02-15 04:07:51 +00:00
|
|
|
/// let s: &str = "a";
|
|
|
|
/// let ss: String = s.to_owned();
|
2016-04-05 12:11:08 +00:00
|
|
|
///
|
2017-02-15 04:07:51 +00:00
|
|
|
/// let v: &[i32] = &[1, 2];
|
|
|
|
/// let vv: Vec<i32> = v.to_owned();
|
2016-04-05 12:11:08 +00:00
|
|
|
/// ```
|
2015-02-12 07:16:32 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2018-03-31 06:06:05 +00:00
|
|
|
#[must_use = "cloning is often expensive and is not expected to have side effects"]
|
2023-09-27 03:56:38 +00:00
|
|
|
#[cfg_attr(not(test), rustc_diagnostic_item = "to_owned_method")]
|
2015-02-12 07:16:32 +00:00
|
|
|
fn to_owned(&self) -> Self::Owned;
|
2017-04-02 02:33:45 +00:00
|
|
|
|
|
|
|
/// Uses borrowed data to replace owned data, usually by cloning.
|
|
|
|
///
|
2022-07-08 20:41:41 +00:00
|
|
|
/// This is borrow-generalized version of [`Clone::clone_from`].
|
2017-04-02 02:33:45 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// Basic usage:
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// let mut s: String = String::new();
|
|
|
|
/// "hello".clone_into(&mut s);
|
|
|
|
///
|
|
|
|
/// let mut v: Vec<i32> = Vec::new();
|
|
|
|
/// [1, 2][..].clone_into(&mut v);
|
|
|
|
/// ```
|
2022-05-27 16:07:45 +00:00
|
|
|
#[stable(feature = "toowned_clone_into", since = "1.63.0")]
|
2017-04-02 02:33:45 +00:00
|
|
|
fn clone_into(&self, target: &mut Self::Owned) {
|
|
|
|
*target = self.to_owned();
|
|
|
|
}
|
2015-02-12 07:16:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-12-20 04:24:00 +00:00
|
|
|
impl<T> ToOwned for T
|
|
|
|
where
|
|
|
|
T: Clone,
|
|
|
|
{
|
2015-02-12 07:16:32 +00:00
|
|
|
type Owned = T;
|
2015-11-23 22:23:48 +00:00
|
|
|
fn to_owned(&self) -> T {
|
|
|
|
self.clone()
|
|
|
|
}
|
2017-04-02 02:33:45 +00:00
|
|
|
|
|
|
|
fn clone_into(&self, target: &mut T) {
|
|
|
|
target.clone_from(self);
|
|
|
|
}
|
2015-02-12 07:16:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// A clone-on-write smart pointer.
|
|
|
|
///
|
|
|
|
/// The type `Cow` is a smart pointer providing clone-on-write functionality: it
|
|
|
|
/// can enclose and provide immutable access to borrowed data, and clone the
|
|
|
|
/// data lazily when mutation or ownership is required. The type is designed to
|
|
|
|
/// work with general borrowed data via the `Borrow` trait.
|
|
|
|
///
|
2015-04-09 16:51:19 +00:00
|
|
|
/// `Cow` implements `Deref`, which means that you can call
|
2015-02-12 07:16:32 +00:00
|
|
|
/// non-mutating methods directly on the data it encloses. If mutation
|
2015-04-09 16:51:19 +00:00
|
|
|
/// is desired, `to_mut` will obtain a mutable reference to an owned
|
2015-02-12 07:16:32 +00:00
|
|
|
/// value, cloning if necessary.
|
|
|
|
///
|
2020-12-28 15:59:36 +00:00
|
|
|
/// If you need reference-counting pointers, note that
|
|
|
|
/// [`Rc::make_mut`][crate::rc::Rc::make_mut] and
|
|
|
|
/// [`Arc::make_mut`][crate::sync::Arc::make_mut] can provide clone-on-write
|
|
|
|
/// functionality as well.
|
|
|
|
///
|
2015-03-12 01:11:40 +00:00
|
|
|
/// # Examples
|
2015-02-12 07:16:32 +00:00
|
|
|
///
|
2015-03-13 02:42:38 +00:00
|
|
|
/// ```
|
2015-02-12 07:16:32 +00:00
|
|
|
/// use std::borrow::Cow;
|
|
|
|
///
|
2023-05-06 21:12:29 +00:00
|
|
|
/// fn abs_all(input: &mut Cow<'_, [i32]>) {
|
2015-02-12 07:16:32 +00:00
|
|
|
/// for i in 0..input.len() {
|
|
|
|
/// let v = input[i];
|
|
|
|
/// if v < 0 {
|
2016-10-15 04:55:46 +00:00
|
|
|
/// // Clones into a vector if not already owned.
|
2015-02-12 07:16:32 +00:00
|
|
|
/// input.to_mut()[i] = -v;
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
/// }
|
2016-10-15 04:55:46 +00:00
|
|
|
///
|
|
|
|
/// // No clone occurs because `input` doesn't need to be mutated.
|
|
|
|
/// let slice = [0, 1, 2];
|
|
|
|
/// let mut input = Cow::from(&slice[..]);
|
|
|
|
/// abs_all(&mut input);
|
|
|
|
///
|
|
|
|
/// // Clone occurs because `input` needs to be mutated.
|
|
|
|
/// let slice = [-1, 0, 1];
|
|
|
|
/// let mut input = Cow::from(&slice[..]);
|
|
|
|
/// abs_all(&mut input);
|
|
|
|
///
|
|
|
|
/// // No clone occurs because `input` is already owned.
|
|
|
|
/// let mut input = Cow::from(vec![-1, 0, 1]);
|
|
|
|
/// abs_all(&mut input);
|
2015-02-12 07:16:32 +00:00
|
|
|
/// ```
|
2018-08-06 14:33:32 +00:00
|
|
|
///
|
2018-08-15 11:00:59 +00:00
|
|
|
/// Another example showing how to keep `Cow` in a struct:
|
2018-08-15 19:06:35 +00:00
|
|
|
///
|
2018-08-06 14:33:32 +00:00
|
|
|
/// ```
|
2019-03-17 16:40:25 +00:00
|
|
|
/// use std::borrow::Cow;
|
2018-08-06 14:33:32 +00:00
|
|
|
///
|
2023-05-06 21:12:29 +00:00
|
|
|
/// struct Items<'a, X> where [X]: ToOwned<Owned = Vec<X>> {
|
2018-08-06 14:33:32 +00:00
|
|
|
/// values: Cow<'a, [X]>,
|
|
|
|
/// }
|
|
|
|
///
|
2019-02-09 22:16:58 +00:00
|
|
|
/// impl<'a, X: Clone + 'a> Items<'a, X> where [X]: ToOwned<Owned = Vec<X>> {
|
2018-08-06 14:33:32 +00:00
|
|
|
/// fn new(v: Cow<'a, [X]>) -> Self {
|
|
|
|
/// Items { values: v }
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// // Creates a container from borrowed values of a slice
|
|
|
|
/// let readonly = [1, 2];
|
|
|
|
/// let borrowed = Items::new((&readonly[..]).into());
|
|
|
|
/// match borrowed {
|
2022-02-12 19:16:17 +00:00
|
|
|
/// Items { values: Cow::Borrowed(b) } => println!("borrowed {b:?}"),
|
2018-08-06 14:33:32 +00:00
|
|
|
/// _ => panic!("expect borrowed value"),
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// let mut clone_on_write = borrowed;
|
|
|
|
/// // Mutates the data from slice into owned vec and pushes a new value on top
|
|
|
|
/// clone_on_write.values.to_mut().push(3);
|
|
|
|
/// println!("clone_on_write = {:?}", clone_on_write.values);
|
|
|
|
///
|
2021-12-18 10:21:58 +00:00
|
|
|
/// // The data was mutated. Let's check it out.
|
2018-08-06 14:33:32 +00:00
|
|
|
/// match clone_on_write {
|
|
|
|
/// Items { values: Cow::Owned(_) } => println!("clone_on_write contains owned data"),
|
|
|
|
/// _ => panic!("expect owned data"),
|
|
|
|
/// }
|
|
|
|
/// ```
|
2015-02-12 07:16:32 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2021-07-15 21:51:34 +00:00
|
|
|
#[cfg_attr(not(test), rustc_diagnostic_item = "Cow")]
|
2015-11-23 22:23:48 +00:00
|
|
|
pub enum Cow<'a, B: ?Sized + 'a>
|
|
|
|
where
|
|
|
|
B: ToOwned,
|
|
|
|
{
|
2015-02-12 07:16:32 +00:00
|
|
|
/// Borrowed data.
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-12-20 04:24:00 +00:00
|
|
|
Borrowed(#[stable(feature = "rust1", since = "1.0.0")] &'a B),
|
2015-02-12 07:16:32 +00:00
|
|
|
|
|
|
|
/// Owned data.
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-12-20 04:24:00 +00:00
|
|
|
Owned(#[stable(feature = "rust1", since = "1.0.0")] <B as ToOwned>::Owned),
|
2015-02-12 07:16:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2019-02-18 03:42:36 +00:00
|
|
|
impl<B: ?Sized + ToOwned> Clone for Cow<'_, B> {
|
|
|
|
fn clone(&self) -> Self {
|
2015-02-12 07:16:32 +00:00
|
|
|
match *self {
|
|
|
|
Borrowed(b) => Borrowed(b),
|
|
|
|
Owned(ref o) => {
|
|
|
|
let b: &B = o.borrow();
|
|
|
|
Owned(b.to_owned())
|
2015-11-23 22:23:48 +00:00
|
|
|
}
|
2015-02-12 07:16:32 +00:00
|
|
|
}
|
|
|
|
}
|
2017-04-02 02:33:45 +00:00
|
|
|
|
2019-02-18 03:42:36 +00:00
|
|
|
fn clone_from(&mut self, source: &Self) {
|
2019-12-11 20:01:33 +00:00
|
|
|
match (self, source) {
|
|
|
|
(&mut Owned(ref mut dest), &Owned(ref o)) => o.borrow().clone_into(dest),
|
|
|
|
(t, s) => *t = s.clone(),
|
2017-04-02 02:33:45 +00:00
|
|
|
}
|
|
|
|
}
|
2015-02-12 07:16:32 +00:00
|
|
|
}
|
|
|
|
|
2019-02-02 11:23:15 +00:00
|
|
|
impl<B: ?Sized + ToOwned> Cow<'_, B> {
|
2019-10-05 22:23:37 +00:00
|
|
|
/// Returns true if the data is borrowed, i.e. if `to_mut` would require additional work.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// #![feature(cow_is_borrowed)]
|
|
|
|
/// use std::borrow::Cow;
|
|
|
|
///
|
|
|
|
/// let cow = Cow::Borrowed("moo");
|
|
|
|
/// assert!(cow.is_borrowed());
|
|
|
|
///
|
|
|
|
/// let bull: Cow<'_, str> = Cow::Owned("...moo?".to_string());
|
|
|
|
/// assert!(!bull.is_borrowed());
|
|
|
|
/// ```
|
|
|
|
#[unstable(feature = "cow_is_borrowed", issue = "65143")]
|
2020-08-31 01:43:47 +00:00
|
|
|
pub const fn is_borrowed(&self) -> bool {
|
2019-10-05 22:23:37 +00:00
|
|
|
match *self {
|
|
|
|
Borrowed(_) => true,
|
|
|
|
Owned(_) => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns true if the data is owned, i.e. if `to_mut` would be a no-op.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// #![feature(cow_is_borrowed)]
|
|
|
|
/// use std::borrow::Cow;
|
|
|
|
///
|
|
|
|
/// let cow: Cow<'_, str> = Cow::Owned("moo".to_string());
|
|
|
|
/// assert!(cow.is_owned());
|
|
|
|
///
|
|
|
|
/// let bull = Cow::Borrowed("...moo?");
|
|
|
|
/// assert!(!bull.is_owned());
|
|
|
|
/// ```
|
|
|
|
#[unstable(feature = "cow_is_borrowed", issue = "65143")]
|
2020-08-31 01:43:47 +00:00
|
|
|
pub const fn is_owned(&self) -> bool {
|
2019-10-05 22:23:37 +00:00
|
|
|
!self.is_borrowed()
|
|
|
|
}
|
|
|
|
|
2015-04-09 16:51:19 +00:00
|
|
|
/// Acquires a mutable reference to the owned form of the data.
|
2015-02-12 07:16:32 +00:00
|
|
|
///
|
2015-07-19 03:54:55 +00:00
|
|
|
/// Clones the data if it is not already owned.
|
2015-03-24 20:48:57 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::borrow::Cow;
|
|
|
|
///
|
2017-06-03 18:54:17 +00:00
|
|
|
/// let mut cow = Cow::Borrowed("foo");
|
|
|
|
/// cow.to_mut().make_ascii_uppercase();
|
2015-03-24 20:48:57 +00:00
|
|
|
///
|
2017-06-03 18:54:17 +00:00
|
|
|
/// assert_eq!(
|
|
|
|
/// cow,
|
2023-05-06 21:12:29 +00:00
|
|
|
/// Cow::Owned(String::from("FOO")) as Cow<'_, str>
|
2017-06-03 18:54:17 +00:00
|
|
|
/// );
|
2015-03-24 20:48:57 +00:00
|
|
|
/// ```
|
2015-02-12 07:16:32 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
pub fn to_mut(&mut self) -> &mut <B as ToOwned>::Owned {
|
|
|
|
match *self {
|
|
|
|
Borrowed(borrowed) => {
|
|
|
|
*self = Owned(borrowed.to_owned());
|
2016-11-04 18:47:32 +00:00
|
|
|
match *self {
|
|
|
|
Borrowed(..) => unreachable!(),
|
|
|
|
Owned(ref mut owned) => owned,
|
|
|
|
}
|
2015-02-12 07:16:32 +00:00
|
|
|
}
|
2015-11-23 22:23:48 +00:00
|
|
|
Owned(ref mut owned) => owned,
|
2015-02-12 07:16:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-09 16:51:19 +00:00
|
|
|
/// Extracts the owned data.
|
2015-02-12 07:16:32 +00:00
|
|
|
///
|
2015-07-19 03:54:55 +00:00
|
|
|
/// Clones the data if it is not already owned.
|
2015-03-24 20:48:57 +00:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
2022-03-23 13:01:00 +00:00
|
|
|
/// Calling `into_owned` on a `Cow::Borrowed` returns a clone of the borrowed data:
|
2017-06-03 18:40:23 +00:00
|
|
|
///
|
2015-03-24 20:48:57 +00:00
|
|
|
/// ```
|
|
|
|
/// use std::borrow::Cow;
|
|
|
|
///
|
2017-06-03 18:40:23 +00:00
|
|
|
/// let s = "Hello world!";
|
|
|
|
/// let cow = Cow::Borrowed(s);
|
|
|
|
///
|
|
|
|
/// assert_eq!(
|
|
|
|
/// cow.into_owned(),
|
2017-11-15 00:23:24 +00:00
|
|
|
/// String::from(s)
|
2017-06-03 18:40:23 +00:00
|
|
|
/// );
|
|
|
|
/// ```
|
|
|
|
///
|
2022-03-23 13:01:00 +00:00
|
|
|
/// Calling `into_owned` on a `Cow::Owned` returns the owned data. The data is moved out of the
|
|
|
|
/// `Cow` without being cloned.
|
2017-06-03 18:40:23 +00:00
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::borrow::Cow;
|
2015-03-24 20:48:57 +00:00
|
|
|
///
|
2017-06-03 18:40:23 +00:00
|
|
|
/// let s = "Hello world!";
|
2023-05-06 21:12:29 +00:00
|
|
|
/// let cow: Cow<'_, str> = Cow::Owned(String::from(s));
|
2015-03-24 20:48:57 +00:00
|
|
|
///
|
2017-06-03 18:40:23 +00:00
|
|
|
/// assert_eq!(
|
|
|
|
/// cow.into_owned(),
|
2017-11-15 00:23:24 +00:00
|
|
|
/// String::from(s)
|
2017-06-03 18:40:23 +00:00
|
|
|
/// );
|
2015-03-24 20:48:57 +00:00
|
|
|
/// ```
|
2015-02-12 07:16:32 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
pub fn into_owned(self) -> <B as ToOwned>::Owned {
|
|
|
|
match self {
|
|
|
|
Borrowed(borrowed) => borrowed.to_owned(),
|
2015-11-23 22:23:48 +00:00
|
|
|
Owned(owned) => owned,
|
2015-02-12 07:16:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2023-03-28 10:25:30 +00:00
|
|
|
impl<B: ?Sized + ToOwned> Deref for Cow<'_, B>
|
2021-09-12 15:26:30 +00:00
|
|
|
where
|
2023-03-28 10:25:30 +00:00
|
|
|
B::Owned: Borrow<B>,
|
2021-09-12 15:26:30 +00:00
|
|
|
{
|
2015-02-12 07:16:32 +00:00
|
|
|
type Target = B;
|
|
|
|
|
|
|
|
fn deref(&self) -> &B {
|
|
|
|
match *self {
|
|
|
|
Borrowed(borrowed) => borrowed,
|
2015-11-23 22:23:48 +00:00
|
|
|
Owned(ref owned) => owned.borrow(),
|
2015-02-12 07:16:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-29 13:33:20 +00:00
|
|
|
#[unstable(feature = "deref_pure_trait", issue = "87121")]
|
|
|
|
unsafe impl<B: ?Sized + ToOwned> DerefPure for Cow<'_, B> where B::Owned: Borrow<B> {}
|
|
|
|
|
2015-02-12 07:16:32 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2019-02-02 11:23:15 +00:00
|
|
|
impl<B: ?Sized> Eq for Cow<'_, B> where B: Eq + ToOwned {}
|
2015-02-12 07:16:32 +00:00
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2019-02-18 03:42:36 +00:00
|
|
|
impl<B: ?Sized> Ord for Cow<'_, B>
|
2016-12-20 04:24:00 +00:00
|
|
|
where
|
|
|
|
B: Ord + ToOwned,
|
|
|
|
{
|
2015-02-12 07:16:32 +00:00
|
|
|
#[inline]
|
2019-02-18 03:42:36 +00:00
|
|
|
fn cmp(&self, other: &Self) -> Ordering {
|
2015-02-12 07:16:32 +00:00
|
|
|
Ord::cmp(&**self, &**other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-11-23 22:23:48 +00:00
|
|
|
impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq<Cow<'b, C>> for Cow<'a, B>
|
|
|
|
where
|
|
|
|
B: PartialEq<C> + ToOwned,
|
|
|
|
C: ToOwned,
|
2015-02-12 07:16:32 +00:00
|
|
|
{
|
|
|
|
#[inline]
|
|
|
|
fn eq(&self, other: &Cow<'b, C>) -> bool {
|
|
|
|
PartialEq::eq(&**self, &**other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2016-12-20 04:24:00 +00:00
|
|
|
impl<'a, B: ?Sized> PartialOrd for Cow<'a, B>
|
|
|
|
where
|
|
|
|
B: PartialOrd + ToOwned,
|
|
|
|
{
|
2015-02-12 07:16:32 +00:00
|
|
|
#[inline]
|
|
|
|
fn partial_cmp(&self, other: &Cow<'a, B>) -> Option<Ordering> {
|
|
|
|
PartialOrd::partial_cmp(&**self, &**other)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2019-02-02 11:23:15 +00:00
|
|
|
impl<B: ?Sized> fmt::Debug for Cow<'_, B>
|
2019-07-31 19:00:35 +00:00
|
|
|
where
|
|
|
|
B: fmt::Debug + ToOwned<Owned: fmt::Debug>,
|
2015-02-12 07:16:32 +00:00
|
|
|
{
|
2019-02-02 11:48:12 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2015-02-12 07:16:32 +00:00
|
|
|
match *self {
|
|
|
|
Borrowed(ref b) => fmt::Debug::fmt(b, f),
|
|
|
|
Owned(ref o) => fmt::Debug::fmt(o, f),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2019-02-02 11:23:15 +00:00
|
|
|
impl<B: ?Sized> fmt::Display for Cow<'_, B>
|
2019-07-31 19:00:35 +00:00
|
|
|
where
|
|
|
|
B: fmt::Display + ToOwned<Owned: fmt::Display>,
|
2015-02-12 07:16:32 +00:00
|
|
|
{
|
2019-02-02 11:48:12 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2015-02-12 07:16:32 +00:00
|
|
|
match *self {
|
|
|
|
Borrowed(ref b) => fmt::Display::fmt(b, f),
|
|
|
|
Owned(ref o) => fmt::Display::fmt(o, f),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-16 13:44:56 +00:00
|
|
|
#[stable(feature = "default", since = "1.11.0")]
|
2019-02-18 03:42:36 +00:00
|
|
|
impl<B: ?Sized> Default for Cow<'_, B>
|
2019-07-31 19:00:35 +00:00
|
|
|
where
|
|
|
|
B: ToOwned<Owned: Default>,
|
2016-06-16 13:44:56 +00:00
|
|
|
{
|
2016-09-11 17:28:01 +00:00
|
|
|
/// Creates an owned Cow<'a, B> with the default value for the contained owned value.
|
2019-02-18 03:42:36 +00:00
|
|
|
fn default() -> Self {
|
2016-06-16 13:44:56 +00:00
|
|
|
Owned(<B as ToOwned>::Owned::default())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-12 07:16:32 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2019-02-18 03:42:36 +00:00
|
|
|
impl<B: ?Sized> Hash for Cow<'_, B>
|
2016-12-20 04:24:00 +00:00
|
|
|
where
|
|
|
|
B: Hash + ToOwned,
|
|
|
|
{
|
2015-02-18 23:34:32 +00:00
|
|
|
#[inline]
|
|
|
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
|
|
Hash::hash(&**self, state)
|
|
|
|
}
|
|
|
|
}
|
2015-02-12 07:16:32 +00:00
|
|
|
|
2015-03-18 16:14:54 +00:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2019-02-02 11:23:15 +00:00
|
|
|
impl<T: ?Sized + ToOwned> AsRef<T> for Cow<'_, T> {
|
2015-03-18 16:14:54 +00:00
|
|
|
fn as_ref(&self) -> &T {
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
2016-09-12 21:35:20 +00:00
|
|
|
|
alloc: Add unstable Cfg feature `no-global_oom_handling`
For certain sorts of systems, programming, it's deemed essential that
all allocation failures be explicitly handled where they occur. For
example, see Linus Torvald's opinion in [1]. Merely not calling global
panic handlers, or always `try_reserving` first (for vectors), is not
deemed good enough, because the mere presence of the global OOM handlers
is burdens static analysis.
One option for these projects to use rust would just be to skip `alloc`,
rolling their own allocation abstractions. But this would, in my
opinion be a real shame. `alloc` has a few `try_*` methods already, and
we could easily have more. Features like custom allocator support also
demonstrate and existing to support diverse use-cases with the same
abstractions.
A natural way to add such a feature flag would a Cargo feature, but
there are currently uncertainties around how std library crate's Cargo
features may or not be stable, so to avoid any risk of stabilizing by
mistake we are going with a more low-level "raw cfg" token, which
cannot be interacted with via Cargo alone.
Note also that since there is no notion of "default cfg tokens" outside
of Cargo features, we have to invert the condition from
`global_oom_handling` to to `not(no_global_oom_handling)`. This breaks
the monotonicity that would be important for a Cargo feature (i.e.
turning on more features should never break compatibility), but it
doesn't matter for raw cfg tokens which are not intended to be
"constraint solved" by Cargo or anything else.
To support this use-case we create a new feature, "global-oom-handling",
on by default, and put the global OOM handler infra and everything else
it that depends on it behind it. By default, nothing is changed, but
users concerned about global handling can make sure it is disabled, and
be confident that all OOM handling is local and explicit.
For this first iteration, non-flat collections are outright disabled.
`Vec` and `String` don't yet have `try_*` allocation methods, but are
kept anyways since they can be oom-safely created "from parts", and we
hope to add those `try_` methods in the future.
[1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-17 00:18:04 +00:00
|
|
|
#[cfg(not(no_global_oom_handling))]
|
2016-11-04 01:07:00 +00:00
|
|
|
#[stable(feature = "cow_add", since = "1.14.0")]
|
2016-09-12 21:35:20 +00:00
|
|
|
impl<'a> Add<&'a str> for Cow<'a, str> {
|
|
|
|
type Output = Cow<'a, str>;
|
|
|
|
|
2016-11-04 01:07:00 +00:00
|
|
|
#[inline]
|
|
|
|
fn add(mut self, rhs: &'a str) -> Self::Output {
|
|
|
|
self += rhs;
|
|
|
|
self
|
2016-09-12 21:35:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
alloc: Add unstable Cfg feature `no-global_oom_handling`
For certain sorts of systems, programming, it's deemed essential that
all allocation failures be explicitly handled where they occur. For
example, see Linus Torvald's opinion in [1]. Merely not calling global
panic handlers, or always `try_reserving` first (for vectors), is not
deemed good enough, because the mere presence of the global OOM handlers
is burdens static analysis.
One option for these projects to use rust would just be to skip `alloc`,
rolling their own allocation abstractions. But this would, in my
opinion be a real shame. `alloc` has a few `try_*` methods already, and
we could easily have more. Features like custom allocator support also
demonstrate and existing to support diverse use-cases with the same
abstractions.
A natural way to add such a feature flag would a Cargo feature, but
there are currently uncertainties around how std library crate's Cargo
features may or not be stable, so to avoid any risk of stabilizing by
mistake we are going with a more low-level "raw cfg" token, which
cannot be interacted with via Cargo alone.
Note also that since there is no notion of "default cfg tokens" outside
of Cargo features, we have to invert the condition from
`global_oom_handling` to to `not(no_global_oom_handling)`. This breaks
the monotonicity that would be important for a Cargo feature (i.e.
turning on more features should never break compatibility), but it
doesn't matter for raw cfg tokens which are not intended to be
"constraint solved" by Cargo or anything else.
To support this use-case we create a new feature, "global-oom-handling",
on by default, and put the global OOM handler infra and everything else
it that depends on it behind it. By default, nothing is changed, but
users concerned about global handling can make sure it is disabled, and
be confident that all OOM handling is local and explicit.
For this first iteration, non-flat collections are outright disabled.
`Vec` and `String` don't yet have `try_*` allocation methods, but are
kept anyways since they can be oom-safely created "from parts", and we
hope to add those `try_` methods in the future.
[1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-17 00:18:04 +00:00
|
|
|
#[cfg(not(no_global_oom_handling))]
|
2016-11-04 01:07:00 +00:00
|
|
|
#[stable(feature = "cow_add", since = "1.14.0")]
|
2016-09-12 21:35:20 +00:00
|
|
|
impl<'a> Add<Cow<'a, str>> for Cow<'a, str> {
|
|
|
|
type Output = Cow<'a, str>;
|
|
|
|
|
2016-11-04 01:07:00 +00:00
|
|
|
#[inline]
|
|
|
|
fn add(mut self, rhs: Cow<'a, str>) -> Self::Output {
|
|
|
|
self += rhs;
|
|
|
|
self
|
2016-09-12 21:35:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
alloc: Add unstable Cfg feature `no-global_oom_handling`
For certain sorts of systems, programming, it's deemed essential that
all allocation failures be explicitly handled where they occur. For
example, see Linus Torvald's opinion in [1]. Merely not calling global
panic handlers, or always `try_reserving` first (for vectors), is not
deemed good enough, because the mere presence of the global OOM handlers
is burdens static analysis.
One option for these projects to use rust would just be to skip `alloc`,
rolling their own allocation abstractions. But this would, in my
opinion be a real shame. `alloc` has a few `try_*` methods already, and
we could easily have more. Features like custom allocator support also
demonstrate and existing to support diverse use-cases with the same
abstractions.
A natural way to add such a feature flag would a Cargo feature, but
there are currently uncertainties around how std library crate's Cargo
features may or not be stable, so to avoid any risk of stabilizing by
mistake we are going with a more low-level "raw cfg" token, which
cannot be interacted with via Cargo alone.
Note also that since there is no notion of "default cfg tokens" outside
of Cargo features, we have to invert the condition from
`global_oom_handling` to to `not(no_global_oom_handling)`. This breaks
the monotonicity that would be important for a Cargo feature (i.e.
turning on more features should never break compatibility), but it
doesn't matter for raw cfg tokens which are not intended to be
"constraint solved" by Cargo or anything else.
To support this use-case we create a new feature, "global-oom-handling",
on by default, and put the global OOM handler infra and everything else
it that depends on it behind it. By default, nothing is changed, but
users concerned about global handling can make sure it is disabled, and
be confident that all OOM handling is local and explicit.
For this first iteration, non-flat collections are outright disabled.
`Vec` and `String` don't yet have `try_*` allocation methods, but are
kept anyways since they can be oom-safely created "from parts", and we
hope to add those `try_` methods in the future.
[1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-17 00:18:04 +00:00
|
|
|
#[cfg(not(no_global_oom_handling))]
|
2016-11-04 01:07:00 +00:00
|
|
|
#[stable(feature = "cow_add", since = "1.14.0")]
|
2016-09-12 21:35:20 +00:00
|
|
|
impl<'a> AddAssign<&'a str> for Cow<'a, str> {
|
|
|
|
fn add_assign(&mut self, rhs: &'a str) {
|
2016-11-04 01:07:00 +00:00
|
|
|
if self.is_empty() {
|
|
|
|
*self = Cow::Borrowed(rhs)
|
2019-12-11 20:01:33 +00:00
|
|
|
} else if !rhs.is_empty() {
|
2016-11-04 01:07:00 +00:00
|
|
|
if let Cow::Borrowed(lhs) = *self {
|
|
|
|
let mut s = String::with_capacity(lhs.len() + rhs.len());
|
|
|
|
s.push_str(lhs);
|
|
|
|
*self = Cow::Owned(s);
|
|
|
|
}
|
|
|
|
self.to_mut().push_str(rhs);
|
|
|
|
}
|
2016-09-12 21:35:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
alloc: Add unstable Cfg feature `no-global_oom_handling`
For certain sorts of systems, programming, it's deemed essential that
all allocation failures be explicitly handled where they occur. For
example, see Linus Torvald's opinion in [1]. Merely not calling global
panic handlers, or always `try_reserving` first (for vectors), is not
deemed good enough, because the mere presence of the global OOM handlers
is burdens static analysis.
One option for these projects to use rust would just be to skip `alloc`,
rolling their own allocation abstractions. But this would, in my
opinion be a real shame. `alloc` has a few `try_*` methods already, and
we could easily have more. Features like custom allocator support also
demonstrate and existing to support diverse use-cases with the same
abstractions.
A natural way to add such a feature flag would a Cargo feature, but
there are currently uncertainties around how std library crate's Cargo
features may or not be stable, so to avoid any risk of stabilizing by
mistake we are going with a more low-level "raw cfg" token, which
cannot be interacted with via Cargo alone.
Note also that since there is no notion of "default cfg tokens" outside
of Cargo features, we have to invert the condition from
`global_oom_handling` to to `not(no_global_oom_handling)`. This breaks
the monotonicity that would be important for a Cargo feature (i.e.
turning on more features should never break compatibility), but it
doesn't matter for raw cfg tokens which are not intended to be
"constraint solved" by Cargo or anything else.
To support this use-case we create a new feature, "global-oom-handling",
on by default, and put the global OOM handler infra and everything else
it that depends on it behind it. By default, nothing is changed, but
users concerned about global handling can make sure it is disabled, and
be confident that all OOM handling is local and explicit.
For this first iteration, non-flat collections are outright disabled.
`Vec` and `String` don't yet have `try_*` allocation methods, but are
kept anyways since they can be oom-safely created "from parts", and we
hope to add those `try_` methods in the future.
[1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-17 00:18:04 +00:00
|
|
|
#[cfg(not(no_global_oom_handling))]
|
2016-11-04 01:07:00 +00:00
|
|
|
#[stable(feature = "cow_add", since = "1.14.0")]
|
2016-09-12 21:35:20 +00:00
|
|
|
impl<'a> AddAssign<Cow<'a, str>> for Cow<'a, str> {
|
|
|
|
fn add_assign(&mut self, rhs: Cow<'a, str>) {
|
2016-11-04 01:07:00 +00:00
|
|
|
if self.is_empty() {
|
|
|
|
*self = rhs
|
2019-12-11 20:01:33 +00:00
|
|
|
} else if !rhs.is_empty() {
|
2016-11-04 01:07:00 +00:00
|
|
|
if let Cow::Borrowed(lhs) = *self {
|
|
|
|
let mut s = String::with_capacity(lhs.len() + rhs.len());
|
|
|
|
s.push_str(lhs);
|
|
|
|
*self = Cow::Owned(s);
|
|
|
|
}
|
|
|
|
self.to_mut().push_str(&rhs);
|
|
|
|
}
|
2016-09-12 21:35:20 +00:00
|
|
|
}
|
|
|
|
}
|