Skip to content

Instantly share code, notes, and snippets.

@mstewartgallus
Last active December 16, 2015 09:38
Show Gist options
  • Save mstewartgallus/5414180 to your computer and use it in GitHub Desktop.
Save mstewartgallus/5414180 to your computer and use it in GitHub Desktop.
Arrays as nonprimitive
// A typical example of idiomatic Rust code ;)
use core::cast;
use core::sys;
#[packed]
pub struct Cons <H, T> { head : H, tail : T }
#[packed]
pub struct Nil;
macro_rules! list (
(
$head : expr,
$( $tail : expr ),*
) => (
Cons { head : $head, tail : (list! ($($tail),+)) }
);
($end : expr) => ( Cons { head : $end, tail : Nil } );
() => ( Nil )
)
pub trait List <T> {
fn len (&self) -> uint;
fn to_array <'r> (&'r self) -> &'r [T];
}
impl <H, T : List <H>> List <H> for Cons <H, T> {
fn len (&self) -> uint { 1 + self.tail.len () }
fn to_array <'r> (&'r self) -> &'r [H] {
unsafe { cast::transmute (ArrayPointer {
length : self.len () * sys::size_of::<H> (),
contents : self
}) }
}
}
impl <T> List <T> for Nil {
fn len (&self) -> uint { 0 }
fn to_array <'r> (&'r self) -> &'r [T] {
unsafe { cast::transmute (ArrayPointer {
length : 0,
contents : self
}) }
}
}
#[packed]
priv struct ArrayPointer <'self, L> { contents : &'self L, length : uint }
static list : &'static List <u8> =
&'static list! (32u8, 43u8, 4u8, 203u8, 20u8) as &'static List <u8>;
fn main () {
let array = list.to_array ();
io::println (fmt! ("The length is %?", list.len ()));
io::println (fmt! ("The contents are %?", array))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment