#![unstable = "recently added as part of collections reform"]
use clone::Clone;
use cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
use fmt;
use kinds::Sized;
use ops::Deref;
use option::Option;
use self::Cow::*;
pub trait BorrowFrom<Sized? Owned> for Sized? {
fn borrow_from(owned: &Owned) -> &Self;
}
pub trait BorrowFromMut<Sized? Owned> for Sized? : BorrowFrom<Owned> {
fn borrow_from_mut(owned: &mut Owned) -> &mut Self;
}
impl<Sized? T> BorrowFrom<T> for T {
fn borrow_from(owned: &T) -> &T { owned }
}
impl<Sized? T> BorrowFromMut<T> for T {
fn borrow_from_mut(owned: &mut T) -> &mut T { owned }
}
impl<'a, Sized? T> BorrowFrom<&'a T> for T {
fn borrow_from<'b>(owned: &'b &'a T) -> &'b T { &**owned }
}
impl<'a, Sized? T> BorrowFrom<&'a mut T> for T {
fn borrow_from<'b>(owned: &'b &'a mut T) -> &'b T { &**owned }
}
impl<'a, Sized? T> BorrowFromMut<&'a mut T> for T {
fn borrow_from_mut<'b>(owned: &'b mut &'a mut T) -> &'b mut T { &mut **owned }
}
impl<'a, T, Sized? B> BorrowFrom<Cow<'a, T, B>> for B where B: ToOwned<T> {
fn borrow_from<'b>(owned: &'b Cow<'a, T, B>) -> &'b B {
&**owned
}
}
pub trait IntoCow<'a, T, Sized? B> {
fn into_cow(self) -> Cow<'a, T, B>;
}
impl<'a, T, Sized? B> IntoCow<'a, T, B> for Cow<'a, T, B> where B: ToOwned<T> {
fn into_cow(self) -> Cow<'a, T, B> {
self
}
}
pub trait ToOwned<Owned> for Sized?: BorrowFrom<Owned> {
fn to_owned(&self) -> Owned;
}
impl<T> ToOwned<T> for T where T: Clone {
fn to_owned(&self) -> T { self.clone() }
}
pub enum Cow<'a, T, Sized? B: 'a> where B: ToOwned<T> {
Borrowed(&'a B),
Owned(T)
}
#[stable]
impl<'a, T, Sized? B> Clone for Cow<'a, T, B> where B: ToOwned<T> {
fn clone(&self) -> Cow<'a, T, B> {
match *self {
Borrowed(b) => Borrowed(b),
Owned(ref o) => {
let b: &B = BorrowFrom::borrow_from(o);
Owned(b.to_owned())
},
}
}
}
impl<'a, T, Sized? B> Cow<'a, T, B> where B: ToOwned<T> {
pub fn to_mut(&mut self) -> &mut T {
match *self {
Borrowed(borrowed) => {
*self = Owned(borrowed.to_owned());
self.to_mut()
}
Owned(ref mut owned) => owned
}
}
pub fn into_owned(self) -> T {
match self {
Borrowed(borrowed) => borrowed.to_owned(),
Owned(owned) => owned
}
}
pub fn is_borrowed(&self) -> bool {
match *self {
Borrowed(_) => true,
_ => false,
}
}
pub fn is_owned(&self) -> bool {
match *self {
Owned(_) => true,
_ => false,
}
}
}
impl<'a, T, Sized? B> Deref<B> for Cow<'a, T, B> where B: ToOwned<T> {
fn deref(&self) -> &B {
match *self {
Borrowed(borrowed) => borrowed,
Owned(ref owned) => BorrowFrom::borrow_from(owned)
}
}
}
#[stable]
impl<'a, T, Sized? B> Eq for Cow<'a, T, B> where B: Eq + ToOwned<T> {}
#[stable]
impl<'a, T, Sized? B> Ord for Cow<'a, T, B> where B: Ord + ToOwned<T> {
#[inline]
fn cmp(&self, other: &Cow<'a, T, B>) -> Ordering {
Ord::cmp(&**self, &**other)
}
}
#[stable]
impl<'a, 'b, T, U, Sized? B, Sized? C> PartialEq<Cow<'b, U, C>> for Cow<'a, T, B> where
B: PartialEq<C> + ToOwned<T>,
C: ToOwned<U>,
{
#[inline]
fn eq(&self, other: &Cow<'b, U, C>) -> bool {
PartialEq::eq(&**self, &**other)
}
}
#[stable]
impl<'a, T, Sized? B> PartialOrd for Cow<'a, T, B> where B: PartialOrd + ToOwned<T> {
#[inline]
fn partial_cmp(&self, other: &Cow<'a, T, B>) -> Option<Ordering> {
PartialOrd::partial_cmp(&**self, &**other)
}
}
impl<'a, T, Sized? B> fmt::Show for Cow<'a, T, B> where B: fmt::Show + ToOwned<T>, T: fmt::Show {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Borrowed(ref b) => fmt::Show::fmt(b, f),
Owned(ref o) => fmt::Show::fmt(o, f),
}
}
}