Skip to content

Instantly share code, notes, and snippets.

@johncf

johncf/lib.rs Secret

Created May 29, 2017 19:02
Show Gist options
  • Save johncf/432cb5e7d166173c15bbe1507a46ac32 to your computer and use it in GitHub Desktop.
Save johncf/432cb5e7d166173c15bbe1507a46ac32 to your computer and use it in GitHub Desktop.
use std::rc::Rc;
use std::sync::Arc;
// Definition and impls for RefCounted
pub trait RefCounted: Clone {
type Target;
fn new(obj: Self::Target) -> Self;
fn strong_count(this: &Self) -> usize;
}
impl<T> RefCounted for Rc<T> {
type Target = T;
fn new(obj: T) -> Rc<T> {
Rc::new(obj)
}
fn strong_count(this: &Rc<T>) -> usize {
Rc::strong_count(this)
}
}
impl<T> RefCounted for Arc<T> {
type Target = T;
fn new(obj: T) -> Arc<T> {
Arc::new(obj)
}
fn strong_count(this: &Arc<T>) -> usize {
Arc::strong_count(this)
}
}
// Avoid creating infinite types by using an additional trait to provide some
// indirection
trait RefCountedConstructor<T> {
type RC: RefCounted<Target = T>;
}
enum RcConstructor {}
impl<T> RefCountedConstructor<T> for RcConstructor {
type RC = Rc<T>;
}
enum ArcConstructor {}
impl<T> RefCountedConstructor<T> for ArcConstructor {
type RC = Arc<T>;
}
// Actual definition and impl for Hello
struct Hello<T, RCC>
where RCC: RefCountedConstructor<Hello<T, RCC>>
{
val: T,
next: Option<RCC::RC>,
}
impl<T, RCC> Hello<T, RCC>
where RCC: RefCountedConstructor<Hello<T, RCC>>
{
fn new(val: T) -> Hello<T, RCC> {
Hello {
val: val,
next: None,
}
}
fn set_next(&mut self, val: T) {
self.next = Some(RCC::RC::new(Hello::new(val)));
}
}
// It works!
fn main() {
let mut hello_rc = Hello::<_, RcConstructor>::new(0);
hello_rc.set_next(1);
let mut hello_arc = Hello::<_, ArcConstructor>::new(0);
hello_arc.set_next(1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment