Skip to content

Commit

Permalink
Avoid metadata bloat by using trait FixedSizeArray
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed Mar 17, 2015
1 parent b98255c commit 3c31794
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 54 deletions.
24 changes: 24 additions & 0 deletions src/libcore/array.rs
Expand Up @@ -23,10 +23,34 @@ use marker::{Copy, Sized};
use option::Option;
use slice::{Iter, IterMut, SliceExt};

/// Utility trait implemented only on arrays of fixed size
///
/// This trait can be used to implement other traits on fixed-size arrays
/// without causing much metadata bloat.
#[unstable(feature = "core")]
pub trait FixedSizeArray<T> {
/// Converts the array to immutable slice
fn as_slice(&self) -> &[T];
/// Converts the array to mutable slice
fn as_mut_slice(&mut self) -> &mut [T];
}

// macro for implementing n-ary tuple functions and operations
macro_rules! array_impls {
($($N:expr)+) => {
$(
#[unstable(feature = "core")]
impl<T> FixedSizeArray<T> for [T; $N] {
#[inline]
fn as_slice(&self) -> &[T] {
&self[..]
}
#[inline]
fn as_mut_slice(&mut self) -> &mut [T] {
&mut self[..]
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T:Copy> Clone for [T; $N] {
fn clone(&self) -> [T; $N] {
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/lib.rs
Expand Up @@ -129,6 +129,7 @@ pub mod default;
/* Core types and methods on primitives */

pub mod any;
pub mod array;
pub mod atomic;
pub mod cell;
pub mod char;
Expand All @@ -151,7 +152,6 @@ mod bool {

// note: does not need to be public
mod tuple;
mod array;

#[doc(hidden)]
mod core {
Expand Down
19 changes: 3 additions & 16 deletions src/libstd/ffi/c_str.rs
Expand Up @@ -11,6 +11,7 @@
#![unstable(feature = "std_misc")]

use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
use core::array::FixedSizeArray;
use error::{Error, FromError};
use fmt;
use io;
Expand Down Expand Up @@ -450,22 +451,8 @@ impl IntoBytes for String {
impl IntoBytes for Vec<u8> {
fn into_bytes(self) -> Vec<u8> { self }
}

macro_rules! array_impls {
($($N: expr)+) => {
$(
impl<'a> IntoBytes for &'a [u8; $N] {
fn into_bytes(self) -> Vec<u8> { self.to_vec() }
}
)+
}
}

array_impls! {
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32
impl<'a, T: FixedSizeArray<u8>> IntoBytes for &'a T {
fn into_bytes(self) -> Vec<u8> { self.as_slice().to_vec() }
}

#[cfg(test)]
Expand Down
27 changes: 7 additions & 20 deletions src/libstd/io/cursor.rs
Expand Up @@ -11,6 +11,7 @@
use prelude::v1::*;
use io::prelude::*;

use core::array::FixedSizeArray;
use cmp;
use io::{self, SeekFrom, Error, ErrorKind};
use iter::repeat;
Expand Down Expand Up @@ -72,7 +73,7 @@ macro_rules! seek {
fn seek(&mut self, style: SeekFrom) -> io::Result<u64> {
let pos = match style {
SeekFrom::Start(n) => { self.pos = n; return Ok(n) }
SeekFrom::End(n) => self.inner.len() as i64 + n,
SeekFrom::End(n) => self.inner.as_slice().len() as i64 + n,
SeekFrom::Current(n) => self.pos as i64 + n,
};

Expand All @@ -94,6 +95,7 @@ impl<'a> io::Seek for Cursor<&'a [u8]> { seek!(); }
impl<'a> io::Seek for Cursor<&'a mut [u8]> { seek!(); }
#[stable(feature = "rust1", since = "1.0.0")]
impl io::Seek for Cursor<Vec<u8>> { seek!(); }
impl<'a, T: FixedSizeArray<u8>> io::Seek for Cursor<&'a T> { seek!(); }

macro_rules! read {
() => {
Expand All @@ -111,12 +113,13 @@ impl<'a> Read for Cursor<&'a [u8]> { read!(); }
impl<'a> Read for Cursor<&'a mut [u8]> { read!(); }
#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Cursor<Vec<u8>> { read!(); }
impl<'a, T: FixedSizeArray<u8>> Read for Cursor<&'a T> { read!(); }

macro_rules! buffer {
() => {
fn fill_buf(&mut self) -> io::Result<&[u8]> {
let amt = cmp::min(self.pos, self.inner.len() as u64);
Ok(&self.inner[(amt as usize)..])
let amt = cmp::min(self.pos, self.inner.as_slice().len() as u64);
Ok(&self.inner.as_slice()[(amt as usize)..])
}
fn consume(&mut self, amt: usize) { self.pos += amt as u64; }
}
Expand All @@ -128,23 +131,7 @@ impl<'a> BufRead for Cursor<&'a [u8]> { buffer!(); }
impl<'a> BufRead for Cursor<&'a mut [u8]> { buffer!(); }
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> BufRead for Cursor<Vec<u8>> { buffer!(); }

macro_rules! array_impls {
($($N: expr)+) => {
$(
impl<'a> io::Seek for Cursor<&'a [u8; $N]> { seek!(); }
impl<'a> Read for Cursor<&'a [u8; $N]> { read!(); }
impl<'a> BufRead for Cursor<&'a [u8; $N]> { buffer!(); }
)+
}
}

array_impls! {
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32
}
impl<'a, T: FixedSizeArray<u8>> BufRead for Cursor<&'a T> { buffer!(); }

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Write for Cursor<&'a mut [u8]> {
Expand Down
22 changes: 5 additions & 17 deletions src/libstd/old_path/mod.rs
Expand Up @@ -64,6 +64,7 @@
#![allow(deprecated)] // seriously this is all deprecated
#![allow(unused_imports)]

use core::array::FixedSizeArray;
use core::marker::Sized;
use ffi::CString;
use clone::Clone;
Expand Down Expand Up @@ -895,26 +896,13 @@ impl BytesContainer for [u8] {
}
}

macro_rules! array_impls {
($($N: expr)+) => {
$(
impl BytesContainer for [u8; $N] {
#[inline]
fn container_as_bytes(&self) -> &[u8] {
&self[..]
}
}
)+
impl<T: FixedSizeArray<u8>> BytesContainer for T {
#[inline]
fn container_as_bytes(&self) -> &[u8] {
self.as_slice()
}
}

array_impls! {
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32
}

impl BytesContainer for Vec<u8> {
#[inline]
fn container_as_bytes(&self) -> &[u8] {
Expand Down

0 comments on commit 3c31794

Please sign in to comment.