1
Fork 0

liballoc: implement From for Box, Rc, Arc

Sometimes when writing generic code you want to abstract over
owning/pointer type so that calling code isn't restricted by one
concrete owning/pointer type. This commit makes possible such code:
```
fn i_will_work_with_arc<T: Into<Arc<MyTy>>>(t: T) {
    let the_arc = t.into();
    // Do something
}

i_will_work_with_arc(MyTy::new());

i_will_work_with_arc(Box::new(MyTy::new()));

let arc_that_i_already_have = Arc::new(MyTy::new());
i_will_work_with_arc(arc_that_i_already_have);
```

Please note that this patch doesn't work with DSTs.
This commit is contained in:
Alexander Bulaev 2015-11-04 15:03:33 +03:00
parent a216e84727
commit fcc79f2d60
3 changed files with 69 additions and 0 deletions

View file

@ -84,6 +84,7 @@ use core::ptr::{self, Shared};
use core::marker::Unsize;
use core::hash::{Hash, Hasher};
use core::{usize, isize};
use core::convert::From;
use heap::deallocate;
const MAX_REFCOUNT: usize = (isize::MAX) as usize;
@ -894,8 +895,23 @@ impl<T: ?Sized + Hash> Hash for Arc<T> {
}
}
#[stable(feature = "rust1", since = "1.6.0")]
impl<T> From<T> for Arc<T> {
fn from(t: T) -> Self {
Arc::new(t)
}
}
#[stable(feature = "rust1", since = "1.6.0")]
impl<T> From<Box<T>> for Arc<T> {
fn from(t: Box<T>) -> Self {
Arc::new(*t)
}
}
#[cfg(test)]
mod tests {
use std::boxed::Box;
use std::clone::Clone;
use std::sync::mpsc::channel;
use std::mem::drop;
@ -908,6 +924,7 @@ mod tests {
use std::vec::Vec;
use super::{Arc, Weak};
use std::sync::Mutex;
use std::convert::From;
struct Canary(*mut atomic::AtomicUsize);
@ -1137,6 +1154,20 @@ mod tests {
drop(x);
assert!(y.upgrade().is_none());
}
#[test]
fn test_from_owned() {
let foo = 123;
let foo_arc = Arc::from(foo);
assert!(123 == *foo_arc);
}
#[test]
fn test_from_box() {
let foo_box = Box::new(123);
let foo_arc = Arc::from(foo_box);
assert!(123 == *foo_arc);
}
}
impl<T: ?Sized> borrow::Borrow<T> for Arc<T> {