Skip to content

Instantly share code, notes, and snippets.

@randomPoison
Created September 27, 2016 12:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save randomPoison/c16e824c318cd580b9d3420784d5f05b to your computer and use it in GitHub Desktop.
Save randomPoison/c16e824c318cd580b9d3420784d5f05b to your computer and use it in GitHub Desktop.
A potential implementation for an aliasing sibling to Rc.
use std::rc::Rc;
#[macro_use]
mod alias {
use std::ops::Deref;
use std::rc::Rc;
#[derive(Debug, Clone)]
pub struct RcAlias<T, U> {
rc: Rc<T>,
data: *const U,
}
impl<T, U> RcAlias<T, U> {
pub unsafe fn new(rc: Rc<T>, data: &U) -> RcAlias<T, U> {
RcAlias {
rc: rc,
data: data,
}
}
}
impl<T, U> Deref for RcAlias<T, U> {
type Target = U;
fn deref(&self) -> &U {
unsafe { &*self.data }
}
}
// macro_rules! build_path {
// ($root: expr, $part: ident ()) => { $root.$part() };
// ($root: expr, $part: ident) => { &$root.$part }
// ($root $( . $part: tt )*) => {
// $root. build_path!()
// };
// }
macro_rules! alias {
($rc: ident $( . $path: ident )*) => {
unsafe {
let data = &$rc $( . $path )*;
$crate::alias::RcAlias::new($rc.clone(), data)
}
};
}
}
pub mod foo {
#[derive(Debug)]
pub struct Foo {
pub inner: u32,
bar: Bar,
}
impl Foo {
pub fn new(inner: u32, bar: Bar) -> Foo {
Foo {
inner: inner,
bar: bar,
}
}
pub fn get_bar(&self) -> &Bar {
&self.bar
}
}
#[derive(Debug)]
pub struct Bar {
pub inner: f32,
}
}
fn main() {
let (inner,) = {
let rc = Rc::new(foo::Foo::new(7, foo::Bar { inner: 9.876 }));
let ref_inner = alias!(rc.inner);
// // `alias!` doesn't support getters yet :(
// let ref_bar = alias!(rc.get_bar());
(ref_inner,)
};
// // We can also alias `RcAlias`.
// let bar_inner = alias!(bar.inner);
println!("the original rc has been dropped, inner: {:?}", &*inner);
// // This junk doesn't compile because the macro (rightly) doesn't allow
// // us to alias a nonexistent submember.
// let rc = Rc::new(Foo {
// inner: 7,
// bar: Bar { inner: 9.876 },
// });
//
// let bad_alias = alias!(rc.not.a.real.member);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment