<commit_before>//! See docs in build/expr/mod.rs

use crate::build::expr::category::Category;
use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};
use crate::build::{BlockAnd, BlockAndExtension, Builder};
use crate::hair::*;
use rustc::mir::interpret::InterpError::BoundsCheck;
use rustc::mir::*;
use rustc::ty::{CanonicalUserTypeAnnotation, Variance};

use rustc_data_structures::indexed_vec::Idx;

impl<'a, 'tcx> Builder<'a, 'tcx> {
    /// Compile `expr`, yielding a place that we can move from etc.
    pub fn as_place<M>(&mut self, block: BasicBlock, expr: M) -> BlockAnd<Place<'tcx>>
    where
        M: Mirror<'tcx, Output = Expr<'tcx>>,
    {
        let expr = self.hir.mirror(expr);
        self.expr_as_place(block, expr, Mutability::Mut)
    }

    /// Compile `expr`, yielding a place that we can move from etc.
    /// Mutability note: The caller of this method promises only to read from the resulting
    /// place. The place itself may or may not be mutable:
    /// * If this expr is a place expr like a.b, then we will return that place.
    /// * Otherwise, a temporary is created: in that event, it will be an immutable temporary.
    pub fn as_read_only_place<M>(&mut self, block: BasicBlock, expr: M) -> BlockAnd<Place<'tcx>>
    where
        M: Mirror<'tcx, Output = Expr<'tcx>>,
    {
        let expr = self.hir.mirror(expr);
        self.expr_as_place(block, expr, Mutability::Not)
    }

    fn expr_as_place(
        &mut self,
        mut block: BasicBlock,
        expr: Expr<'tcx>,
        mutability: Mutability,
    ) -> BlockAnd<Place<'tcx>> {
        debug!(
            "expr_as_place(block={:?}, expr={:?}, mutability={:?})",
            block, expr, mutability
        );

        let this = self;
        let expr_span = expr.span;
        let source_info = this.source_info(expr_span);
        match expr.kind {
            ExprKind::Scope {
                region_scope,
                lint_level,
                value,
            } => this.in_scope((region_scope, source_info), lint_level, |this| {
                if mutability == Mutability::Not {
                    this.as_read_only_place(block, value)
                } else {
                    this.as_place(block, value)
                }
            }),
            ExprKind::Field { lhs, name } => {
                let place = unpack!(block = this.as_place(block, lhs));
                let place = place.field(name, expr.ty);
                block.and(place)
            }
            ExprKind::Deref { arg } => {
                let place = unpack!(block = this.as_place(block, arg));
                let place = place.deref();
                block.and(place)
            }
            ExprKind::Index { lhs, index } => {
                let (usize_ty, bool_ty) = (this.hir.usize_ty(), this.hir.bool_ty());

                let slice = unpack!(block = this.as_place(block, lhs));
                // region_scope=None so place indexes live forever. They are scalars so they
                // do not need storage annotations, and they are often copied between
                // places.
                // Making this a *fresh* temporary also means we do not have to worry about
                // the index changing later: Nothing will ever change this temporary.
                // The "retagging" transformation (for Stacked Borrows) relies on this.
                let idx = unpack!(block = this.as_temp(block, None, index, Mutability::Mut));

                // bounds check:
                let (len, lt) = (
                    this.temp(usize_ty.clone(), expr_span),
                    this.temp(bool_ty, expr_span),
                );
                this.cfg.push_assign(
                    block,
                    source_info, // len = len(slice)
                    &len,
                    Rvalue::Len(slice.clone()),
                );
                this.cfg.push_assign(
                    block,
                    source_info, // lt = idx < len
                    &lt,
                    Rvalue::BinaryOp(
                        BinOp::Lt,
                        Operand::Copy(Place::from(idx)),
                        Operand::Copy(len.clone()),
                    ),
                );

                let msg = BoundsCheck {
                    len: Operand::Move(len),
                    index: Operand::Copy(Place::from(idx)),
                };
                let success = this.assert(block, Operand::Move(lt), true, msg, expr_span);
                success.and(slice.index(idx))
            }
            ExprKind::SelfRef => block.and(Place::from(Local::new(1))),
            ExprKind::VarRef { id } => {
                let place = if this.is_bound_var_in_guard(id) {
                    let index = this.var_local_id(id, RefWithinGuard);
                    Place::from(index).deref()
                } else {
                    let index = this.var_local_id(id, OutsideGuard);
                    Place::from(index)
                };
                block.and(place)
            }
            ExprKind::StaticRef { id } => block.and(Place::Base(PlaceBase::Static(Box::new(Static {
                ty: expr.ty,
                kind: StaticKind::Static(id),
            })))),

            ExprKind::PlaceTypeAscription { source, user_ty } => {
                let place = unpack!(block = this.as_place(block, source));
                if let Some(user_ty) = user_ty {
                    let annotation_index = this.canonical_user_type_annotations.push(
                        CanonicalUserTypeAnnotation {
                            span: source_info.span,
                            user_ty,
                            inferred_ty: expr.ty,
                        }
                    );
                    this.cfg.push(
                        block,
                        Statement {
                            source_info,
                            kind: StatementKind::AscribeUserType(
                                place.clone(),
                                Variance::Invariant,
                                box UserTypeProjection { base: annotation_index, projs: vec![], },
                            ),
                        },
                    );
                }
                block.and(place)
            }
            ExprKind::ValueTypeAscription { source, user_ty } => {
                let source = this.hir.mirror(source);
                let temp = unpack!(
                    block = this.as_temp(block, source.temp_lifetime, source, mutability)
                );
                if let Some(user_ty) = user_ty {
                    let annotation_index = this.canonical_user_type_annotations.push(
                        CanonicalUserTypeAnnotation {
                            span: source_info.span,
                            user_ty,
                            inferred_ty: expr.ty,
                        }
                    );
                    this.cfg.push(
                        block,
                        Statement {
                            source_info,
                            kind: StatementKind::AscribeUserType(
                                Place::from(temp.clone()),
                                Variance::Invariant,
                                box UserTypeProjection { base: annotation_index, projs: vec![], },
                            ),
                        },
                    );
                }
                block.and(Place::from(temp))
            }

            ExprKind::Array { .. }
            | ExprKind::Tuple { .. }
            | ExprKind::Adt { .. }
            | ExprKind::Closure { .. }
            | ExprKind::Unary { .. }
            | ExprKind::Binary { .. }
            | ExprKind::LogicalOp { .. }
            | ExprKind::Box { .. }
            | ExprKind::Cast { .. }
            | ExprKind::Use { .. }
            | ExprKind::NeverToAny { .. }
            | ExprKind::Pointer { .. }
            | ExprKind::Repeat { .. }
            | ExprKind::Borrow { .. }
            | ExprKind::Match { .. }
            | ExprKind::Loop { .. }
            | ExprKind::Block { .. }
            | ExprKind::Assign { .. }
            | ExprKind::AssignOp { .. }
            | ExprKind::Break { .. }
            | ExprKind::Continue { .. }
            | ExprKind::Return { .. }
            | ExprKind::Literal { .. }
            | ExprKind::InlineAsm { .. }
            | ExprKind::Yield { .. }
            | ExprKind::Call { .. } => {
                // these are not places, so we need to make a temporary.
                debug_assert!(match Category::of(&expr.kind) {
                    Some(Category::Place) => false,
                    _ => true,
                });
                let temp =
                    unpack!(block = this.as_temp(block, expr.temp_lifetime, expr, mutability));
                block.and(Place::from(temp))
            }
        }
    }
}
<commit_msg>Give index temporaries a drop scope<commit_after>//! See docs in build/expr/mod.rs

use crate::build::expr::category::Category;
use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};
use crate::build::{BlockAnd, BlockAndExtension, Builder};
use crate::hair::*;
use rustc::mir::interpret::InterpError::BoundsCheck;
use rustc::mir::*;
use rustc::ty::{CanonicalUserTypeAnnotation, Variance};

use rustc_data_structures::indexed_vec::Idx;

impl<'a, 'tcx> Builder<'a, 'tcx> {
    /// Compile `expr`, yielding a place that we can move from etc.
    pub fn as_place<M>(&mut self, block: BasicBlock, expr: M) -> BlockAnd<Place<'tcx>>
    where
        M: Mirror<'tcx, Output = Expr<'tcx>>,
    {
        let expr = self.hir.mirror(expr);
        self.expr_as_place(block, expr, Mutability::Mut)
    }

    /// Compile `expr`, yielding a place that we can move from etc.
    /// Mutability note: The caller of this method promises only to read from the resulting
    /// place. The place itself may or may not be mutable:
    /// * If this expr is a place expr like a.b, then we will return that place.
    /// * Otherwise, a temporary is created: in that event, it will be an immutable temporary.
    pub fn as_read_only_place<M>(&mut self, block: BasicBlock, expr: M) -> BlockAnd<Place<'tcx>>
    where
        M: Mirror<'tcx, Output = Expr<'tcx>>,
    {
        let expr = self.hir.mirror(expr);
        self.expr_as_place(block, expr, Mutability::Not)
    }

    fn expr_as_place(
        &mut self,
        mut block: BasicBlock,
        expr: Expr<'tcx>,
        mutability: Mutability,
    ) -> BlockAnd<Place<'tcx>> {
        debug!(
            "expr_as_place(block={:?}, expr={:?}, mutability={:?})",
            block, expr, mutability
        );

        let this = self;
        let expr_span = expr.span;
        let source_info = this.source_info(expr_span);
        match expr.kind {
            ExprKind::Scope {
                region_scope,
                lint_level,
                value,
            } => this.in_scope((region_scope, source_info), lint_level, |this| {
                if mutability == Mutability::Not {
                    this.as_read_only_place(block, value)
                } else {
                    this.as_place(block, value)
                }
            }),
            ExprKind::Field { lhs, name } => {
                let place = unpack!(block = this.as_place(block, lhs));
                let place = place.field(name, expr.ty);
                block.and(place)
            }
            ExprKind::Deref { arg } => {
                let place = unpack!(block = this.as_place(block, arg));
                let place = place.deref();
                block.and(place)
            }
            ExprKind::Index { lhs, index } => {
                let (usize_ty, bool_ty) = (this.hir.usize_ty(), this.hir.bool_ty());

                let slice = unpack!(block = this.as_place(block, lhs));
                // Making this a *fresh* temporary also means we do not have to worry about
                // the index changing later: Nothing will ever change this temporary.
                // The "retagging" transformation (for Stacked Borrows) relies on this.
                let idx = unpack!(block = this.as_temp(
                    block,
                    expr.temp_lifetime,
                    index,
                    Mutability::Not,
                ));

                // bounds check:
                let (len, lt) = (
                    this.temp(usize_ty.clone(), expr_span),
                    this.temp(bool_ty, expr_span),
                );
                this.cfg.push_assign(
                    block,
                    source_info, // len = len(slice)
                    &len,
                    Rvalue::Len(slice.clone()),
                );
                this.cfg.push_assign(
                    block,
                    source_info, // lt = idx < len
                    &lt,
                    Rvalue::BinaryOp(
                        BinOp::Lt,
                        Operand::Copy(Place::from(idx)),
                        Operand::Copy(len.clone()),
                    ),
                );

                let msg = BoundsCheck {
                    len: Operand::Move(len),
                    index: Operand::Copy(Place::from(idx)),
                };
                let success = this.assert(block, Operand::Move(lt), true, msg, expr_span);
                success.and(slice.index(idx))
            }
            ExprKind::SelfRef => block.and(Place::from(Local::new(1))),
            ExprKind::VarRef { id } => {
                let place = if this.is_bound_var_in_guard(id) {
                    let index = this.var_local_id(id, RefWithinGuard);
                    Place::from(index).deref()
                } else {
                    let index = this.var_local_id(id, OutsideGuard);
                    Place::from(index)
                };
                block.and(place)
            }
            ExprKind::StaticRef { id } => block.and(Place::Base(PlaceBase::Static(Box::new(Static {
                ty: expr.ty,
                kind: StaticKind::Static(id),
            })))),

            ExprKind::PlaceTypeAscription { source, user_ty } => {
                let place = unpack!(block = this.as_place(block, source));
                if let Some(user_ty) = user_ty {
                    let annotation_index = this.canonical_user_type_annotations.push(
                        CanonicalUserTypeAnnotation {
                            span: source_info.span,
                            user_ty,
                            inferred_ty: expr.ty,
                        }
                    );
                    this.cfg.push(
                        block,
                        Statement {
                            source_info,
                            kind: StatementKind::AscribeUserType(
                                place.clone(),
                                Variance::Invariant,
                                box UserTypeProjection { base: annotation_index, projs: vec![], },
                            ),
                        },
                    );
                }
                block.and(place)
            }
            ExprKind::ValueTypeAscription { source, user_ty } => {
                let source = this.hir.mirror(source);
                let temp = unpack!(
                    block = this.as_temp(block, source.temp_lifetime, source, mutability)
                );
                if let Some(user_ty) = user_ty {
                    let annotation_index = this.canonical_user_type_annotations.push(
                        CanonicalUserTypeAnnotation {
                            span: source_info.span,
                            user_ty,
                            inferred_ty: expr.ty,
                        }
                    );
                    this.cfg.push(
                        block,
                        Statement {
                            source_info,
                            kind: StatementKind::AscribeUserType(
                                Place::from(temp.clone()),
                                Variance::Invariant,
                                box UserTypeProjection { base: annotation_index, projs: vec![], },
                            ),
                        },
                    );
                }
                block.and(Place::from(temp))
            }

            ExprKind::Array { .. }
            | ExprKind::Tuple { .. }
            | ExprKind::Adt { .. }
            | ExprKind::Closure { .. }
            | ExprKind::Unary { .. }
            | ExprKind::Binary { .. }
            | ExprKind::LogicalOp { .. }
            | ExprKind::Box { .. }
            | ExprKind::Cast { .. }
            | ExprKind::Use { .. }
            | ExprKind::NeverToAny { .. }
            | ExprKind::Pointer { .. }
            | ExprKind::Repeat { .. }
            | ExprKind::Borrow { .. }
            | ExprKind::Match { .. }
            | ExprKind::Loop { .. }
            | ExprKind::Block { .. }
            | ExprKind::Assign { .. }
            | ExprKind::AssignOp { .. }
            | ExprKind::Break { .. }
            | ExprKind::Continue { .. }
            | ExprKind::Return { .. }
            | ExprKind::Literal { .. }
            | ExprKind::InlineAsm { .. }
            | ExprKind::Yield { .. }
            | ExprKind::Call { .. } => {
                // these are not places, so we need to make a temporary.
                debug_assert!(match Category::of(&expr.kind) {
                    Some(Category::Place) => false,
                    _ => true,
                });
                let temp =
                    unpack!(block = this.as_temp(block, expr.temp_lifetime, expr, mutability));
                block.and(Place::from(temp))
            }
        }
    }
}
<|endoftext|>


<commit_before>use crate::expression::subselect::Subselect;
use crate::expression::{AsExpression, Expression, ValidGrouping};
use crate::pg::Pg;
use crate::query_builder::*;
use crate::result::QueryResult;
use crate::sql_types::Array;

/// Creates a PostgreSQL `ANY` expression.
///
/// As with most bare functions, this is not exported by default. You can import
/// it specifically from `diesel::pg::expression::dsl::any`, or glob import
/// `diesel::dsl::*`.
///
/// # Example
///
/// ```rust
/// # include!("../../doctest_setup.rs");
/// # use diesel::dsl::*;
/// #
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// #     connection.execute("INSERT INTO users (name) VALUES ('Jim')").unwrap();
/// let sean = (1, "Sean".to_string());
/// let jim = (3, "Jim".to_string());
/// let data = users.filter(name.eq(any(vec!["Sean", "Jim"])));
/// assert_eq!(Ok(vec![sean, jim]), data.load(&connection));
/// # }
/// ```
pub fn any<ST, T>(vals: T) -> Any<T::Expression>
where
    T: AsArrayExpression<ST>,
{
    Any::new(vals.as_expression())
}

/// Creates a PostgreSQL `ALL` expression.
///
/// As with most bare functions, this is not exported by default. You can import
/// it specifically as `diesel::pg::expression::dsl::all`, or glob import
/// `diesel::dsl::*`.
///
/// # Example
///
/// ```rust
/// # include!("../../doctest_setup.rs");
/// # use diesel::dsl::*;
/// #
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// #     connection.execute("INSERT INTO users (name) VALUES ('Jim')").unwrap();
/// let tess = (2, "Tess".to_string());
/// let data = users.filter(name.ne(all(vec!["Sean", "Jim"])));
/// assert_eq!(Ok(vec![tess]), data.load(&connection));
/// # }
/// ```
pub fn all<ST, T>(vals: T) -> All<T::Expression>
where
    T: AsArrayExpression<ST>,
{
    All::new(vals.as_expression())
}

#[doc(hidden)]
#[derive(Debug, Copy, Clone, QueryId, ValidGrouping)]
pub struct Any<Expr> {
    expr: Expr,
}

impl<Expr> Any<Expr> {
    fn new(expr: Expr) -> Self {
        Any { expr: expr }
    }
}

impl<Expr, ST> Expression for Any<Expr>
where
    Expr: Expression<SqlType = Array<ST>>,
{
    type SqlType = ST;
}

impl<Expr> QueryFragment<Pg> for Any<Expr>
where
    Expr: QueryFragment<Pg>,
{
    fn walk_ast(&self, mut out: AstPass<Pg>) -> QueryResult<()> {
        out.push_sql("ANY(");
        self.expr.walk_ast(out.reborrow())?;
        out.push_sql(")");
        Ok(())
    }
}

impl_selectable_expression!(Any<Expr>);

#[doc(hidden)]
#[derive(Debug, Copy, Clone, QueryId, ValidGrouping)]
pub struct All<Expr> {
    expr: Expr,
}

impl<Expr> All<Expr> {
    fn new(expr: Expr) -> Self {
        All { expr: expr }
    }
}

impl<Expr, ST> Expression for All<Expr>
where
    Expr: Expression<SqlType = Array<ST>>,
{
    type SqlType = ST;
}

impl<Expr> QueryFragment<Pg> for All<Expr>
where
    Expr: QueryFragment<Pg>,
{
    fn walk_ast(&self, mut out: AstPass<Pg>) -> QueryResult<()> {
        out.push_sql("ALL(");
        self.expr.walk_ast(out.reborrow())?;
        out.push_sql(")");
        Ok(())
    }
}

impl_selectable_expression!(All<Expr>);

pub trait AsArrayExpression<ST> {
    type Expression: Expression<SqlType = Array<ST>>;

    fn as_expression(self) -> Self::Expression;
}

impl<ST, T> AsArrayExpression<ST> for T
where
    T: AsExpression<Array<ST>>,
{
    type Expression = <T as AsExpression<Array<ST>>>::Expression;

    fn as_expression(self) -> Self::Expression {
        AsExpression::as_expression(self)
    }
}

impl<ST, S, F, W, O, L, Of, G, FU> AsArrayExpression<ST>
    for SelectStatement<S, F, W, O, L, Of, G, FU>
where
    Self: SelectQuery<SqlType = ST>,
{
    type Expression = Subselect<Self, Array<ST>>;

    fn as_expression(self) -> Self::Expression {
        Subselect::new(self)
    }
}

impl<'a, ST, QS, DB> AsArrayExpression<ST> for BoxedSelectStatement<'a, ST, QS, DB>
where
    Self: SelectQuery<SqlType = ST>,
{
    type Expression = Subselect<Self, Array<ST>>;

    fn as_expression(self) -> Self::Expression {
        Subselect::new(self)
    }
}
<commit_msg>apply glob import documentation suggestions<commit_after>use crate::expression::subselect::Subselect;
use crate::expression::{AsExpression, Expression, ValidGrouping};
use crate::pg::Pg;
use crate::query_builder::*;
use crate::result::QueryResult;
use crate::sql_types::Array;

/// Creates a PostgreSQL `ANY` expression.
///
/// As with most bare functions, this is not exported by default. You can import
/// it specifically from `diesel::pg::expression::dsl::any`, or glob import
/// `diesel::dsl::any`.
///
/// # Example
///
/// ```rust
/// # include!("../../doctest_setup.rs");
/// # use diesel::dsl::*;
/// #
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// #     connection.execute("INSERT INTO users (name) VALUES ('Jim')").unwrap();
/// let sean = (1, "Sean".to_string());
/// let jim = (3, "Jim".to_string());
/// let data = users.filter(name.eq(any(vec!["Sean", "Jim"])));
/// assert_eq!(Ok(vec![sean, jim]), data.load(&connection));
/// # }
/// ```
pub fn any<ST, T>(vals: T) -> Any<T::Expression>
where
    T: AsArrayExpression<ST>,
{
    Any::new(vals.as_expression())
}

/// Creates a PostgreSQL `ALL` expression.
///
/// As with most bare functions, this is not exported by default. You can import
/// it specifically as `diesel::pg::expression::dsl::all`, or glob import
/// `diesel::dsl::*`.
///
/// # Example
///
/// ```rust
/// # include!("../../doctest_setup.rs");
/// # use diesel::dsl::*;
/// #
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// #     connection.execute("INSERT INTO users (name) VALUES ('Jim')").unwrap();
/// let tess = (2, "Tess".to_string());
/// let data = users.filter(name.ne(all(vec!["Sean", "Jim"])));
/// assert_eq!(Ok(vec![tess]), data.load(&connection));
/// # }
/// ```
pub fn all<ST, T>(vals: T) -> All<T::Expression>
where
    T: AsArrayExpression<ST>,
{
    All::new(vals.as_expression())
}

#[doc(hidden)]
#[derive(Debug, Copy, Clone, QueryId, ValidGrouping)]
pub struct Any<Expr> {
    expr: Expr,
}

impl<Expr> Any<Expr> {
    fn new(expr: Expr) -> Self {
        Any { expr: expr }
    }
}

impl<Expr, ST> Expression for Any<Expr>
where
    Expr: Expression<SqlType = Array<ST>>,
{
    type SqlType = ST;
}

impl<Expr> QueryFragment<Pg> for Any<Expr>
where
    Expr: QueryFragment<Pg>,
{
    fn walk_ast(&self, mut out: AstPass<Pg>) -> QueryResult<()> {
        out.push_sql("ANY(");
        self.expr.walk_ast(out.reborrow())?;
        out.push_sql(")");
        Ok(())
    }
}

impl_selectable_expression!(Any<Expr>);

#[doc(hidden)]
#[derive(Debug, Copy, Clone, QueryId, ValidGrouping)]
pub struct All<Expr> {
    expr: Expr,
}

impl<Expr> All<Expr> {
    fn new(expr: Expr) -> Self {
        All { expr: expr }
    }
}

impl<Expr, ST> Expression for All<Expr>
where
    Expr: Expression<SqlType = Array<ST>>,
{
    type SqlType = ST;
}

impl<Expr> QueryFragment<Pg> for All<Expr>
where
    Expr: QueryFragment<Pg>,
{
    fn walk_ast(&self, mut out: AstPass<Pg>) -> QueryResult<()> {
        out.push_sql("ALL(");
        self.expr.walk_ast(out.reborrow())?;
        out.push_sql(")");
        Ok(())
    }
}

impl_selectable_expression!(All<Expr>);

pub trait AsArrayExpression<ST> {
    type Expression: Expression<SqlType = Array<ST>>;

    fn as_expression(self) -> Self::Expression;
}

impl<ST, T> AsArrayExpression<ST> for T
where
    T: AsExpression<Array<ST>>,
{
    type Expression = <T as AsExpression<Array<ST>>>::Expression;

    fn as_expression(self) -> Self::Expression {
        AsExpression::as_expression(self)
    }
}

impl<ST, S, F, W, O, L, Of, G, FU> AsArrayExpression<ST>
    for SelectStatement<S, F, W, O, L, Of, G, FU>
where
    Self: SelectQuery<SqlType = ST>,
{
    type Expression = Subselect<Self, Array<ST>>;

    fn as_expression(self) -> Self::Expression {
        Subselect::new(self)
    }
}

impl<'a, ST, QS, DB> AsArrayExpression<ST> for BoxedSelectStatement<'a, ST, QS, DB>
where
    Self: SelectQuery<SqlType = ST>,
{
    type Expression = Subselect<Self, Array<ST>>;

    fn as_expression(self) -> Self::Expression {
        Subselect::new(self)
    }
}
<|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Define_a_primitive_data_type
// Implements a custom type named CustomInt.
// This type only implements a subset of all traits within std::ops.
use std::ops;

#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Copy, Clone)]
struct CustomInt {
    value: u8,
}

enum CustomIntError {
    OutOfBoundsAssn,
}

impl CustomInt {
    fn custom_int(v: u8) -> Result<CustomInt, CustomIntError> {
        if v < 1 || v > 10 {
            Err(CustomIntError::OutOfBoundsAssn)
        } else {
            Ok(CustomInt { value: v })
        }
    }
}
// custom trait to specify bounds
trait Bounded {
    fn in_bounds(&self);
}

impl Bounded for CustomInt {
    fn in_bounds(&self) {
        if self.value < 1 || self.value > 10 {
            panic(self.value);
        }
        #[cold]
        #[inline(never)]
        fn panic(v: u8) -> ! {
            panic!("CustomInt is out of bounds! {} was value", v);
        }
    }
}

impl ops::Add for CustomInt {
    type Output = CustomInt;
    fn add(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value + rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::Sub for CustomInt {
    type Output = CustomInt;
    fn sub(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value - rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::Mul for CustomInt {
    type Output = CustomInt;
    fn mul(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value * rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::Div for CustomInt {
    type Output = CustomInt;
    fn div(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value / rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::BitAnd for CustomInt {
    type Output = CustomInt;
    fn bitand(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value & rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::BitOr for CustomInt {
    type Output = CustomInt;
    fn bitor(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value | rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::BitXor for CustomInt {
    type Output = CustomInt;
    fn bitxor(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value ^ rhs.value) };
        rval.in_bounds();
        rval
    }
}

fn main() {
    let cint_2: CustomInt = CustomInt::custom_int(2).ok().unwrap();
    let cint_3: CustomInt = CustomInt::custom_int(3).ok().unwrap();
    let cint_4: CustomInt = CustomInt::custom_int(4).ok().unwrap();
    cint_2 + cint_4; // CustomInt { value: 6 }
    cint_4 - cint_2; // CustomInt { value: 2 }
    cint_4 * cint_2; // CustomInt { value: 8 }
    cint_4 / cint_2; // CustomInt { value: 2 }
    cint_3 & cint_2; // CustomInt { value: 2 }
    cint_3 | cint_2; // CustomInt { value: 3 }
    cint_3 ^ cint_2; // CustomInt { value: 1 }
}

#[cfg(test)]
mod tests {
    use super::CustomInt;

    #[test]
    fn add_test() {
        let cint_2: CustomInt = CustomInt::custom_int(2).ok().unwrap();
        let cint_4: CustomInt = CustomInt::custom_int(4).ok().unwrap();
        assert_eq!(CustomInt::custom_int(6).ok().unwrap(), cint_2 + cint_4);
    }

    #[test]
    fn sub_test() {
        let cint_2: CustomInt = CustomInt::custom_int(2).ok().unwrap();
        let cint_4: CustomInt = CustomInt::custom_int(4).ok().unwrap();
        assert_eq!(CustomInt::custom_int(2).ok().unwrap(), cint_4 - cint_2);
    }

    #[test]
    fn mul_test() {
        let cint_2: CustomInt = CustomInt::custom_int(2).ok().unwrap();
        let cint_4: CustomInt = CustomInt::custom_int(4).ok().unwrap();
        assert_eq!(CustomInt::custom_int(8).ok().unwrap(), cint_4 * cint_2);
    }

    #[test]
    fn div_test() {
        let cint_2: CustomInt = CustomInt::custom_int(2).ok().unwrap();
        let cint_4: CustomInt = CustomInt::custom_int(4).ok().unwrap();
        assert_eq!(CustomInt::custom_int(2).ok().unwrap(), cint_4 / cint_2);
    }

    #[test]
    fn and_test() {
        let cint_2: CustomInt = CustomInt::custom_int(2).ok().unwrap();
        let cint_3: CustomInt = CustomInt::custom_int(3).ok().unwrap();
        assert_eq!(CustomInt::custom_int(2).ok().unwrap(), cint_3 & cint_2);
    }

    #[test]
    fn or_test() {
        let cint_2: CustomInt = CustomInt::custom_int(2).ok().unwrap();
        let cint_3: CustomInt = CustomInt::custom_int(3).ok().unwrap();
        assert_eq!(CustomInt::custom_int(3).ok().unwrap(), cint_3 | cint_2);
    }

    #[test]
    fn xor_test() {
        let cint_2: CustomInt = CustomInt::custom_int(2).ok().unwrap();
        let cint_3: CustomInt = CustomInt::custom_int(3).ok().unwrap();
        assert_eq!(CustomInt::custom_int(1).ok().unwrap(), cint_3 ^ cint_2);
    }

    #[test]
    fn assn_out_of_bounds_test() {
        let cint_error = CustomInt::custom_int(0);
        assert!(cint_error.is_err());
    }

    #[test]
    #[should_panic(expected = "CustomInt is out of bounds! 11 was value")]
    fn above_out_of_bounds_test() {
        let cint_10: CustomInt = CustomInt::custom_int(10).ok().unwrap();
        let cint_1: CustomInt = CustomInt::custom_int(1).ok().unwrap();
        cint_10 + cint_1; // should panic here
    }

    #[test]
    #[should_panic(expected = "CustomInt is out of bounds! 0 was value")]
    fn below_out_of_bounds_test() {
        let cint_1: CustomInt = CustomInt::custom_int(1).ok().unwrap();
        cint_1 - cint_1; // should panic here
    }
}
<commit_msg>fix naming convention, write .unwrap() instead<commit_after>// http://rosettacode.org/wiki/Define_a_primitive_data_type
// Implements a custom type named CustomInt.
// This type only implements a subset of all traits within std::ops.
use std::ops;

#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Copy, Clone)]
struct CustomInt {
    value: u8,
}

#[derive(Debug)]
enum CustomIntError {
    OutOfBoundsAssn,
}

impl CustomInt {
    fn new(v: u8) -> Result<CustomInt, CustomIntError> {
        if v < 1 || v > 10 {
            Err(CustomIntError::OutOfBoundsAssn)
        } else {
            Ok(CustomInt { value: v })
        }
    }
}

// custom trait to specify bounds
trait Bounded {
    fn in_bounds(&self);
}

impl Bounded for CustomInt {
    fn in_bounds(&self) {
        if self.value < 1 || self.value > 10 {
            panic(self.value);
        }
        #[cold]
        #[inline(never)]
        fn panic(v: u8) -> ! {
            panic!("CustomInt is out of bounds! {} was value", v);
        }
    }
}

impl ops::Add for CustomInt {
    type Output = CustomInt;
    fn add(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value + rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::Sub for CustomInt {
    type Output = CustomInt;
    fn sub(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value - rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::Mul for CustomInt {
    type Output = CustomInt;
    fn mul(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value * rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::Div for CustomInt {
    type Output = CustomInt;
    fn div(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value / rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::BitAnd for CustomInt {
    type Output = CustomInt;
    fn bitand(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value & rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::BitOr for CustomInt {
    type Output = CustomInt;
    fn bitor(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value | rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::BitXor for CustomInt {
    type Output = CustomInt;
    fn bitxor(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value ^ rhs.value) };
        rval.in_bounds();
        rval
    }
}

fn main() {
    let cint_2: CustomInt = CustomInt::new(2).unwrap();
    let cint_3: CustomInt = CustomInt::new(3).unwrap();
    let cint_4: CustomInt = CustomInt::new(4).unwrap();
    cint_2 + cint_4; // CustomInt { value: 6 }
    cint_4 - cint_2; // CustomInt { value: 2 }
    cint_4 * cint_2; // CustomInt { value: 8 }
    cint_4 / cint_2; // CustomInt { value: 2 }
    cint_3 & cint_2; // CustomInt { value: 2 }
    cint_3 | cint_2; // CustomInt { value: 3 }
    cint_3 ^ cint_2; // CustomInt { value: 1 }
}

#[cfg(test)]
mod tests {
    use super::CustomInt;

    #[test]
    fn add_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_4: CustomInt = CustomInt::new(4).unwrap();
        assert_eq!(CustomInt::new(6).unwrap(), cint_2 + cint_4);
    }

    #[test]
    fn sub_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_4: CustomInt = CustomInt::new(4).unwrap();
        assert_eq!(CustomInt::new(2).unwrap(), cint_4 - cint_2);
    }

    #[test]
    fn mul_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_4: CustomInt = CustomInt::new(4).unwrap();
        assert_eq!(CustomInt::new(8).unwrap(), cint_4 * cint_2);
    }

    #[test]
    fn div_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_4: CustomInt = CustomInt::new(4).unwrap();
        assert_eq!(CustomInt::new(2).unwrap(), cint_4 / cint_2);
    }

    #[test]
    fn and_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_3: CustomInt = CustomInt::new(3).unwrap();
        assert_eq!(CustomInt::new(2).unwrap(), cint_3 & cint_2);
    }

    #[test]
    fn or_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_3: CustomInt = CustomInt::new(3).unwrap();
        assert_eq!(CustomInt::new(3).unwrap(), cint_3 | cint_2);
    }

    #[test]
    fn xor_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_3: CustomInt = CustomInt::new(3).unwrap();
        assert_eq!(CustomInt::new(1).unwrap(), cint_3 ^ cint_2);
    }

    #[test]
    fn assn_out_of_bounds_test() {
        let cint_error = CustomInt::new(0);
        assert!(cint_error.is_err());
    }

    #[test]
    #[should_panic(expected = "CustomInt is out of bounds! 11 was value")]
    fn above_out_of_bounds_test() {
        let cint_10: CustomInt = CustomInt::new(10).unwrap();
        let cint_1: CustomInt = CustomInt::new(1).unwrap();
        cint_10 + cint_1; // should panic here
    }

    #[test]
    #[should_panic(expected = "CustomInt is out of bounds! 0 was value")]
    fn below_out_of_bounds_test() {
        let cint_1: CustomInt = CustomInt::new(1).unwrap();
        cint_1 - cint_1; // should panic here
    }
}
<|endoftext|>


<commit_before>use std::cmp::Ordering;
use std::{mem};

// Bounded package merge algorithm, based on the paper
// "A Fast and Space-Economical Algorithm for Length-Limited Coding
// Jyrki Katajainen, Alistair Moffat, Andrew Turpin".

#[derive(Debug, Clone)]
struct Node {
    weight: usize,
    leaf_counts: Vec<usize>,
}

impl Node {
    fn new(weight: usize, initial_count: usize, capacity: usize) -> Node {
        let mut n = Node {
            weight: weight,
            leaf_counts: Vec::with_capacity(capacity),
        };
        n.leaf_counts.push(initial_count);
        n
    }
}

#[derive(Debug)]
struct Leaf {
    weight: usize,
    index: usize,
}
impl PartialEq for Leaf {
    fn eq(&self, other: &Self) -> bool {
        self.weight == other.weight
    }
}
impl Eq for Leaf { }
impl Ord for Leaf {
    fn cmp(&self, other: &Self) -> Ordering {
        self.weight.cmp(&other.weight)
    }
}
impl PartialOrd for Leaf {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

#[derive(Debug, Clone)]
struct List {
    lookahead1: Node,
    lookahead2: Node,
    next_leaf_index: usize,
}

/// Calculates the bitlengths for the Huffman tree, based on the counts of each
/// symbol.
pub fn length_limited_code_lengths(frequencies: &[usize], max_bits: usize) -> Vec<u32> {
    let num_freqs = frequencies.len();
    let mut result = vec![0; num_freqs];

    // Count used symbols and place them in the leaves.
    let mut leaves: Vec<_> = frequencies.iter()
        .enumerate()
        .filter(|&(_, &freq)| freq != 0)
        .map(|(i, &freq)| Leaf { weight: freq, index: i })
        .collect();

    let num_symbols = leaves.len();

    // Short circuit some special cases

    // TODO:
    // if ((1 << maxbits) < numsymbols) {
    //   free(leaves);
    //   return 1;  /* Error, too few maxbits to represent symbols. */
    // }

    if num_symbols == 0 {
        // There are no non-zero frequencies.
        return result;
    }
    if num_symbols == 1 {
        result[leaves[0].index] = 1;
        return result;
    }
    if num_symbols == 2 {
        result[leaves[0].index] = 1;
        result[leaves[1].index] = 1;
        return result;
    }

    // Sort the leaves from least frequent to most frequent.
    leaves.sort();

    let max_num_leaves = 2 * num_symbols - 2;
    let mut lists = vec![
        List {
            lookahead1: Node::new(leaves[0].weight, 1, max_num_leaves),
            lookahead2: Node::new(leaves[1].weight, 2, max_num_leaves),
            next_leaf_index: 2,
        };
        max_bits
    ];

    // In the last list, 2 * numsymbols - 2 active chains need to be created. Two
    // are already created in the initialization. Each boundary_pm run creates one.
    let num_boundary_pm_runs = max_num_leaves - 2;
    for _ in 0..num_boundary_pm_runs {
        boundary_pm_toplevel(&mut lists[..], &leaves);
    }

    let mut a = lists.pop().unwrap().lookahead2.leaf_counts.into_iter().rev().peekable();

    let mut bitlength_value = 1;
    while let Some(leaf_count) = a.next() {
        let next_count = *a.peek().unwrap_or(&0);
        for leaf in &leaves[next_count..leaf_count] {
            result[leaf.index] = bitlength_value;
        }
        bitlength_value += 1;
    }

    result
}

fn lowest_list(lists: &mut [List], leaves: &[Leaf]) {
    // We're in the lowest list, just add another leaf to the lookaheads
    // There will always be more leaves to be added on level 0 so this is safe.
    let mut current_list = &mut lists[0];
    let next_leaf = &leaves[current_list.next_leaf_index];
    current_list.lookahead2.weight = next_leaf.weight;

    current_list.lookahead2.leaf_counts[0] = current_list.lookahead1.leaf_counts.last().unwrap() + 1;
    current_list.next_leaf_index += 1;
}

fn next_leaf(lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
    let mut current_list = &mut lists[current_list_index];

    // The next leaf goes next; counting itself makes the leaf_count increase by one.
    current_list.lookahead2.weight = leaves[current_list.next_leaf_index].weight;
    current_list.lookahead2.leaf_counts.clear();
    current_list.lookahead2.leaf_counts.extend_from_slice(&current_list.lookahead1.leaf_counts);
    let last_index = current_list.lookahead2.leaf_counts.len() - 1;
    current_list.lookahead2.leaf_counts[last_index] += 1;
    current_list.next_leaf_index += 1;
}

fn next_tree(weight_sum: usize, lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
    {
        let (head, tail) = lists.split_at_mut(current_list_index);
        let prev_list = head.last_mut().unwrap();
        let current_list = tail.first_mut().unwrap();

        let previous_list_leaf_counts = &prev_list.lookahead2.leaf_counts;

        // Make a tree from the lookaheads from the previous list; that goes next.
        // This is not a leaf node, so the leaf count stays the same.
        current_list.lookahead2.weight = weight_sum;
        current_list.lookahead2.leaf_counts.clear();

        current_list.lookahead2.leaf_counts.extend_from_slice(previous_list_leaf_counts);
        current_list.lookahead2.leaf_counts.push(*current_list.lookahead1.leaf_counts.last().unwrap());
    }

    // The previous list needs two new lookahead nodes.
    boundary_pm(lists, leaves, current_list_index - 1);
    boundary_pm(lists, leaves, current_list_index - 1);
}

fn boundary_pm_toplevel(lists: &mut [List], leaves: &[Leaf]) {
    let last_index = lists.len() - 1;
    boundary_pm(lists, leaves, last_index);
}

fn boundary_pm(lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
    let next_leaf_index = lists[current_list_index].next_leaf_index;
    let num_symbols = leaves.len();

    if current_list_index == 0 && next_leaf_index == num_symbols {
        // We've added all the leaves to the lowest list, so we're done here
        return;
    }

    mem::swap(&mut lists[current_list_index].lookahead1, &mut lists[current_list_index].lookahead2);

    if current_list_index == 0 {
        lowest_list(lists, leaves);
    } else {
        // We're at a list other than the lowest list.
        let weight_sum = {
            let previous_list = &lists[current_list_index - 1];
            previous_list.lookahead1.weight + previous_list.lookahead2.weight
        };

        if next_leaf_index < num_symbols && weight_sum > leaves[next_leaf_index].weight {
            next_leaf(lists, leaves, current_list_index);
        } else {
            next_tree(weight_sum, lists, leaves, current_list_index);
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_from_paper_3() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 3);
        let answer = vec![3, 3, 3, 3, 2, 2];
        assert_eq!(output, answer);
    }

    #[test]
    fn test_from_paper_4() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 4);
        let answer = vec![4, 4, 3, 2, 2, 2];
        assert_eq!(output, answer);
    }

    #[test]
    fn max_bits_7() {
        let input = [252, 0, 1, 6, 9, 10, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![1, 0, 6, 4, 3, 3, 3, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn max_bits_15() {
        let input = [0, 0, 0, 0, 0, 0, 18, 0, 6, 0, 12, 2, 14, 9, 27, 15, 23, 15, 17, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 15);
        let answer = vec! [0, 0, 0, 0, 0, 0, 3, 0, 5, 0, 4, 6, 4, 4, 3, 4, 3, 3, 3, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn no_frequencies() {
        let input = [0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn only_one_frequency() {
        let input = [0, 10, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![0, 1, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn only_two_frequencies() {
        let input = [0, 0, 0, 0, 252, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }
}
<commit_msg>Rename leaf index to leaf count to be more like the C code<commit_after>use std::cmp::Ordering;
use std::{mem};

// Bounded package merge algorithm, based on the paper
// "A Fast and Space-Economical Algorithm for Length-Limited Coding
// Jyrki Katajainen, Alistair Moffat, Andrew Turpin".

#[derive(Debug, Clone)]
struct Node {
    weight: usize,
    leaf_counts: Vec<usize>,
}

impl Node {
    fn new(weight: usize, initial_count: usize, capacity: usize) -> Node {
        let mut n = Node {
            weight: weight,
            leaf_counts: Vec::with_capacity(capacity),
        };
        n.leaf_counts.push(initial_count);
        n
    }
}

#[derive(Debug)]
struct Leaf {
    weight: usize,
    count: usize,
}
impl PartialEq for Leaf {
    fn eq(&self, other: &Self) -> bool {
        self.weight == other.weight
    }
}
impl Eq for Leaf { }
impl Ord for Leaf {
    fn cmp(&self, other: &Self) -> Ordering {
        self.weight.cmp(&other.weight)
    }
}
impl PartialOrd for Leaf {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

#[derive(Debug, Clone)]
struct List {
    lookahead1: Node,
    lookahead2: Node,
    next_leaf_index: usize,
}

/// Calculates the bitlengths for the Huffman tree, based on the counts of each
/// symbol.
pub fn length_limited_code_lengths(frequencies: &[usize], max_bits: usize) -> Vec<u32> {
    let num_freqs = frequencies.len();
    let mut result = vec![0; num_freqs];

    // Count used symbols and place them in the leaves.
    let mut leaves: Vec<_> = frequencies.iter()
        .enumerate()
        .filter(|&(_, &freq)| freq != 0)
        .map(|(i, &freq)| Leaf { weight: freq, count: i })
        .collect();

    let num_symbols = leaves.len();

    // Short circuit some special cases

    // TODO:
    // if ((1 << maxbits) < numsymbols) {
    //   free(leaves);
    //   return 1;  /* Error, too few maxbits to represent symbols. */
    // }

    if num_symbols == 0 {
        // There are no non-zero frequencies.
        return result;
    }
    if num_symbols == 1 {
        result[leaves[0].count] = 1;
        return result;
    }
    if num_symbols == 2 {
        result[leaves[0].count] = 1;
        result[leaves[1].count] = 1;
        return result;
    }

    // Sort the leaves from least frequent to most frequent.
    leaves.sort();

    let max_num_leaves = 2 * num_symbols - 2;
    let mut lists = vec![
        List {
            lookahead1: Node::new(leaves[0].weight, 1, max_num_leaves),
            lookahead2: Node::new(leaves[1].weight, 2, max_num_leaves),
            next_leaf_index: 2,
        };
        max_bits
    ];

    // In the last list, 2 * numsymbols - 2 active chains need to be created. Two
    // are already created in the initialization. Each boundary_pm run creates one.
    let num_boundary_pm_runs = max_num_leaves - 2;
    for _ in 0..num_boundary_pm_runs {
        boundary_pm_toplevel(&mut lists[..], &leaves);
    }

    let mut a = lists.pop().unwrap().lookahead2.leaf_counts.into_iter().rev().peekable();

    let mut bitlength_value = 1;
    while let Some(leaf_count) = a.next() {
        let next_count = *a.peek().unwrap_or(&0);
        for leaf in &leaves[next_count..leaf_count] {
            result[leaf.count] = bitlength_value;
        }
        bitlength_value += 1;
    }

    result
}

fn lowest_list(lists: &mut [List], leaves: &[Leaf]) {
    // We're in the lowest list, just add another leaf to the lookaheads
    // There will always be more leaves to be added on level 0 so this is safe.
    let mut current_list = &mut lists[0];
    let next_leaf = &leaves[current_list.next_leaf_index];
    current_list.lookahead2.weight = next_leaf.weight;

    current_list.lookahead2.leaf_counts[0] = current_list.lookahead1.leaf_counts.last().unwrap() + 1;
    current_list.next_leaf_index += 1;
}

fn next_leaf(lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
    let mut current_list = &mut lists[current_list_index];

    // The next leaf goes next; counting itself makes the leaf_count increase by one.
    current_list.lookahead2.weight = leaves[current_list.next_leaf_index].weight;
    current_list.lookahead2.leaf_counts.clear();
    current_list.lookahead2.leaf_counts.extend_from_slice(&current_list.lookahead1.leaf_counts);
    let last_index = current_list.lookahead2.leaf_counts.len() - 1;
    current_list.lookahead2.leaf_counts[last_index] += 1;
    current_list.next_leaf_index += 1;
}

fn next_tree(weight_sum: usize, lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
    {
        let (head, tail) = lists.split_at_mut(current_list_index);
        let prev_list = head.last_mut().unwrap();
        let current_list = tail.first_mut().unwrap();

        let previous_list_leaf_counts = &prev_list.lookahead2.leaf_counts;

        // Make a tree from the lookaheads from the previous list; that goes next.
        // This is not a leaf node, so the leaf count stays the same.
        current_list.lookahead2.weight = weight_sum;
        current_list.lookahead2.leaf_counts.clear();

        current_list.lookahead2.leaf_counts.extend_from_slice(previous_list_leaf_counts);
        current_list.lookahead2.leaf_counts.push(*current_list.lookahead1.leaf_counts.last().unwrap());
    }

    // The previous list needs two new lookahead nodes.
    boundary_pm(lists, leaves, current_list_index - 1);
    boundary_pm(lists, leaves, current_list_index - 1);
}

fn boundary_pm_toplevel(lists: &mut [List], leaves: &[Leaf]) {
    let last_index = lists.len() - 1;
    boundary_pm(lists, leaves, last_index);
}

fn boundary_pm(lists: &mut [List], leaves: &[Leaf], current_list_index: usize) {
    let next_leaf_index = lists[current_list_index].next_leaf_index;
    let num_symbols = leaves.len();

    if current_list_index == 0 && next_leaf_index == num_symbols {
        // We've added all the leaves to the lowest list, so we're done here
        return;
    }

    mem::swap(&mut lists[current_list_index].lookahead1, &mut lists[current_list_index].lookahead2);

    if current_list_index == 0 {
        lowest_list(lists, leaves);
    } else {
        // We're at a list other than the lowest list.
        let weight_sum = {
            let previous_list = &lists[current_list_index - 1];
            previous_list.lookahead1.weight + previous_list.lookahead2.weight
        };

        if next_leaf_index < num_symbols && weight_sum > leaves[next_leaf_index].weight {
            next_leaf(lists, leaves, current_list_index);
        } else {
            next_tree(weight_sum, lists, leaves, current_list_index);
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_from_paper_3() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 3);
        let answer = vec![3, 3, 3, 3, 2, 2];
        assert_eq!(output, answer);
    }

    #[test]
    fn test_from_paper_4() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 4);
        let answer = vec![4, 4, 3, 2, 2, 2];
        assert_eq!(output, answer);
    }

    #[test]
    fn max_bits_7() {
        let input = [252, 0, 1, 6, 9, 10, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![1, 0, 6, 4, 3, 3, 3, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn max_bits_15() {
        let input = [0, 0, 0, 0, 0, 0, 18, 0, 6, 0, 12, 2, 14, 9, 27, 15, 23, 15, 17, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 15);
        let answer = vec! [0, 0, 0, 0, 0, 0, 3, 0, 5, 0, 4, 6, 4, 4, 3, 4, 3, 3, 3, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn no_frequencies() {
        let input = [0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn only_one_frequency() {
        let input = [0, 10, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = vec![0, 1, 0];
        assert_eq!(output, answer);
    }

    #[test]
    fn only_two_frequencies() {
        let input = [0, 0, 0, 0, 252, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let output = length_limited_code_lengths(&input, 7);
        let answer = [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(output, answer);
    }
}
<|endoftext|>


<commit_before>// (c) 2016 Productize SPRL <joost@productize.be>

// extension: .kicad_pcb
// format: new-style

// from parent
use Result;
use symbolic_expressions;
use symbolic_expressions::IntoSexp;
use str_error;
use formatter::KicadFormatter;
use from_sexp;

pub use layout::data::*;

/// convert a Kicad layout to a String
pub fn layout_to_string(layout: &Layout, indent_level: i64) -> Result<String> {
    let formatter = KicadFormatter::new(indent_level);
    symbolic_expressions::ser::to_string_with_formatter(&layout.into_sexp(), formatter)
        .map_err(From::from)
}

/// parse a &str to a Kicad layout
pub fn parse(s: &str) -> Result<Layout> {
    match symbolic_expressions::parser::parse_str(s) {
        Ok(s) => from_sexp(&s),
        Err(x) => str_error(format!("ParseError: {:?}", x)),
    }
}

mod data;
mod de;
mod ser;
<commit_msg>add newline at end of file<commit_after>// (c) 2016 Productize SPRL <joost@productize.be>

// extension: .kicad_pcb
// format: new-style

// from parent
use Result;
use symbolic_expressions;
use symbolic_expressions::IntoSexp;
use str_error;
use formatter::KicadFormatter;
use from_sexp;

pub use layout::data::*;

/// convert a Kicad layout to a String
pub fn layout_to_string(layout: &Layout, indent_level: i64) -> Result<String> {
    let formatter = KicadFormatter::new(indent_level);
    let mut s = symbolic_expressions::ser::to_string_with_formatter(&layout.into_sexp(), formatter)?;
    s.push('\n');
    Ok(s)
}

/// parse a &str to a Kicad layout
pub fn parse(s: &str) -> Result<Layout> {
    match symbolic_expressions::parser::parse_str(s) {
        Ok(s) => from_sexp(&s),
        Err(x) => str_error(format!("ParseError: {:?}", x)),
    }
}

mod data;
mod de;
mod ser;
<|endoftext|>


<commit_before>use std;
import std::vec;
import std::task;
import std::uint;
import std::str;

fn f(n: uint) {
    let i = 0u;
    while i < n { let thunk = g; task::join_id(task::spawn(thunk)); i += 1u; }
}

fn g() { }

fn main(args: [str]) {

    let n =
        if vec::len(args) < 2u {
            10u
        } else { uint::parse_buf(str::bytes(args[1]), 10u) };
    let i = 0u;
    while i < n { task::spawn(bind f(n)); i += 1u; }
}
<commit_msg>Convert task-perf-spawnalot to spawn_joinable. XFAIL<commit_after>// xfail-stage1
// xfail-stage2
// xfail-stage3

use std;
import std::vec;
import std::task;
import std::uint;
import std::str;

fn f(n: uint) {
    let i = 0u;
    while i < n {
        let thunk = g;
        task::join(task::spawn_joinable(thunk)); i += 1u; }
}

fn g() { }

fn main(args: [str]) {

    let n =
        if vec::len(args) < 2u {
            10u
        } else { uint::parse_buf(str::bytes(args[1]), 10u) };
    let i = 0u;
    while i < n { task::spawn(bind f(n)); i += 1u; }
}
<|endoftext|>


<commit_before>// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// ignore-pretty - token trees can't pretty print

macro_rules! compiles_fine {
    (#[$at:meta]) => {
        // test that the different types of attributes work
        #[attribute]
        /// Documentation!
        #[$at]

        // check that the attributes are recognised by requiring this
        // to be removed to avoid a compile error
        #[cfg(always_remove)]
        static MISTYPED: () = "foo";
    }
}

// item
compiles_fine!(#[foo]);

pub fn main() {
    // statement
    compiles_fine!(#[bar]);
}
<commit_msg>Rollup merge of #22944 - Manishearth:patch-1, r=sfackler<commit_after>// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// ignore-pretty - token trees can't pretty print

#![feature(custom_attribute)]

macro_rules! compiles_fine {
    (#[$at:meta]) => {
        // test that the different types of attributes work
        #[attribute]
        /// Documentation!
        #[$at]

        // check that the attributes are recognised by requiring this
        // to be removed to avoid a compile error
        #[cfg(always_remove)]
        static MISTYPED: () = "foo";
    }
}

// item
compiles_fine!(#[foo]);

pub fn main() {
    // statement
    compiles_fine!(#[bar]);
}
<|endoftext|>


<commit_before>//! When we are combining two NFAs, we will grab all the outgoing
//! edges from a set of nodes and wind up with a bunch of potentially
//! overlapping character ranges like:
//!
//!     a-z
//!     c-l
//!     0-9
//!
//! This module contains code to turn those into non-overlapping ranges like:
//!
//!     a-b
//!     c-l
//!     m-z
//!     0-9
//!
//! Specifically, we want to ensure that the same set of characters is
//! covered when we started, and that each of the input ranges is
//! covered precisely by some set of ranges in the output.

use collections::Set;
use lexer::nfa::Test;
use std::cmp;

pub fn remove_overlap(ranges: &Set<Test>) -> Vec<Test> {
    // We will do this in the dumbest possible way to start. :)
    // Maintain a result vector that contains disjoint ranges.  To
    // insert a new range, we walk over this vector and split things
    // up as we go. This algorithm is so naive as to be exponential, I
    // think. Sue me.

    let mut disjoint_ranges = vec![];

    for &range in ranges {
        add_range(range, 0, &mut disjoint_ranges);
    }

    // the algorithm above leaves some empty ranges in for simplicity;
    // prune them out.
    disjoint_ranges.retain(|r| !r.is_empty());

    disjoint_ranges
}

fn add_range(range: Test,
             start_index: usize,
             disjoint_ranges: &mut Vec<Test>)
{
    if range.is_empty() {
        return;
    }

    // Find first overlapping range in `disjoint_ranges`, if any.
    match disjoint_ranges[start_index..].iter().position(|r| r.intersects(range)) {
        Some(index) => {
            let index = index + start_index;
            let overlapping_range = disjoint_ranges[index];

            // If the range we are trying to add already exists, we're all done.
            if overlapping_range == range {
                return;
            }

            // Otherwise, we want to create three ranges (some of which may
            // be empty). e.g. imagine one range is `a-z` and the other
            // is `c-l`, we want `a-b`, `c-l`, and `m-z`.
            let min_min = cmp::min(range.start, overlapping_range.start);
            let mid_min = cmp::max(range.start, overlapping_range.start);
            let mid_max = cmp::min(range.end, overlapping_range.end);
            let max_max = cmp::max(range.end, overlapping_range.end);
            let low_range = Test { start: min_min, end: mid_min };
            let mid_range = Test { start: mid_min, end: mid_max };
            let max_range = Test { start: mid_max, end: max_max };

            assert!(low_range.is_disjoint(mid_range));
            assert!(low_range.is_disjoint(max_range));
            assert!(mid_range.is_disjoint(max_range));

            // Replace the existing range with the low range, and then
            // add the mid and max ranges in. (The low range may be
            // empty, but we'll prune that out later.)
            disjoint_ranges[index] = low_range;
            add_range(mid_range, index + 1, disjoint_ranges);
            add_range(max_range, index + 1, disjoint_ranges);
        }

        None => {
            // no overlap -- easy case.
            disjoint_ranges.push(range);
        }
    }
}

macro_rules! test {
    ($($range:expr,)*) => {
        {
            use collections::set;
            use lexer::nfa::Test;
            use std::char;
            let mut s = set();
            $({ let r = $range; s.insert(Test::exclusive_range(r.start, r.end)); })*
            remove_overlap(&s).into_iter()
                              .map(|r|
                                   char::from_u32(r.start).unwrap() ..
                                   char::from_u32(r.end).unwrap())
                              .collect::<Vec<_>>()
        }
    }
}

#[test]
fn alphabet() {
    let result = test! {
        'a' .. 'z',
        'c' .. 'l',
        '0' .. '9',
    };
    assert_eq!(result, vec!['0'..'9', 'a'..'c', 'c'..'l', 'l'..'z']);
}

#[test]
fn repeat() {
    let result = test! {
        'a' .. 'z',
        'c' .. 'l',
        'l' .. 'z',
        '0' .. '9',
    };
    assert_eq!(result, vec!['0'..'9', 'a'..'c', 'c'..'l', 'l'..'z']);
}

#[test]
fn stagger() {
    let result = test! {
        '0' .. '3',
        '2' .. '4',
        '3' .. '5',
    };
    assert_eq!(result, vec!['0'..'2', '2'..'3', '3'..'4', '4'..'5']);
}
<commit_msg>add missing `#[cfg(test)]`<commit_after>//! When we are combining two NFAs, we will grab all the outgoing
//! edges from a set of nodes and wind up with a bunch of potentially
//! overlapping character ranges like:
//!
//!     a-z
//!     c-l
//!     0-9
//!
//! This module contains code to turn those into non-overlapping ranges like:
//!
//!     a-b
//!     c-l
//!     m-z
//!     0-9
//!
//! Specifically, we want to ensure that the same set of characters is
//! covered when we started, and that each of the input ranges is
//! covered precisely by some set of ranges in the output.

use collections::Set;
use lexer::nfa::Test;
use std::cmp;

pub fn remove_overlap(ranges: &Set<Test>) -> Vec<Test> {
    // We will do this in the dumbest possible way to start. :)
    // Maintain a result vector that contains disjoint ranges.  To
    // insert a new range, we walk over this vector and split things
    // up as we go. This algorithm is so naive as to be exponential, I
    // think. Sue me.

    let mut disjoint_ranges = vec![];

    for &range in ranges {
        add_range(range, 0, &mut disjoint_ranges);
    }

    // the algorithm above leaves some empty ranges in for simplicity;
    // prune them out.
    disjoint_ranges.retain(|r| !r.is_empty());

    disjoint_ranges
}

fn add_range(range: Test,
             start_index: usize,
             disjoint_ranges: &mut Vec<Test>)
{
    if range.is_empty() {
        return;
    }

    // Find first overlapping range in `disjoint_ranges`, if any.
    match disjoint_ranges[start_index..].iter().position(|r| r.intersects(range)) {
        Some(index) => {
            let index = index + start_index;
            let overlapping_range = disjoint_ranges[index];

            // If the range we are trying to add already exists, we're all done.
            if overlapping_range == range {
                return;
            }

            // Otherwise, we want to create three ranges (some of which may
            // be empty). e.g. imagine one range is `a-z` and the other
            // is `c-l`, we want `a-b`, `c-l`, and `m-z`.
            let min_min = cmp::min(range.start, overlapping_range.start);
            let mid_min = cmp::max(range.start, overlapping_range.start);
            let mid_max = cmp::min(range.end, overlapping_range.end);
            let max_max = cmp::max(range.end, overlapping_range.end);
            let low_range = Test { start: min_min, end: mid_min };
            let mid_range = Test { start: mid_min, end: mid_max };
            let max_range = Test { start: mid_max, end: max_max };

            assert!(low_range.is_disjoint(mid_range));
            assert!(low_range.is_disjoint(max_range));
            assert!(mid_range.is_disjoint(max_range));

            // Replace the existing range with the low range, and then
            // add the mid and max ranges in. (The low range may be
            // empty, but we'll prune that out later.)
            disjoint_ranges[index] = low_range;
            add_range(mid_range, index + 1, disjoint_ranges);
            add_range(max_range, index + 1, disjoint_ranges);
        }

        None => {
            // no overlap -- easy case.
            disjoint_ranges.push(range);
        }
    }
}

#[cfg(test)]
macro_rules! test {
    ($($range:expr,)*) => {
        {
            use collections::set;
            use lexer::nfa::Test;
            use std::char;
            let mut s = set();
            $({ let r = $range; s.insert(Test::exclusive_range(r.start, r.end)); })*
            remove_overlap(&s).into_iter()
                              .map(|r|
                                   char::from_u32(r.start).unwrap() ..
                                   char::from_u32(r.end).unwrap())
                              .collect::<Vec<_>>()
        }
    }
}

#[test]
fn alphabet() {
    let result = test! {
        'a' .. 'z',
        'c' .. 'l',
        '0' .. '9',
    };
    assert_eq!(result, vec!['0'..'9', 'a'..'c', 'c'..'l', 'l'..'z']);
}

#[test]
fn repeat() {
    let result = test! {
        'a' .. 'z',
        'c' .. 'l',
        'l' .. 'z',
        '0' .. '9',
    };
    assert_eq!(result, vec!['0'..'9', 'a'..'c', 'c'..'l', 'l'..'z']);
}

#[test]
fn stagger() {
    let result = test! {
        '0' .. '3',
        '2' .. '4',
        '3' .. '5',
    };
    assert_eq!(result, vec!['0'..'2', '2'..'3', '3'..'4', '4'..'5']);
}
<|endoftext|>


<commit_before>/*
This library is a shim around `lazy_static` that disambiguates it with the `lazy_static`
that's shipped with the Rust toolchain. We re-export the entire public API of `lazy_static`
under a different crate name so that can be imported in the compile tests.

This currently appears to use the right local build of `lazy_static`.
*/

#![feature(use_extern_macros)]

extern crate lazy_static;

pub use self::lazy_static::*;
<commit_msg>remove unnecessary feature gate<commit_after>/*
This library is a shim around `lazy_static` that disambiguates it with the `lazy_static`
that's shipped with the Rust toolchain. We re-export the entire public API of `lazy_static`
under a different crate name so that can be imported in the compile tests.

This currently appears to use the right local build of `lazy_static`.
*/

extern crate lazy_static;

pub use self::lazy_static::*;
<|endoftext|>


<commit_before>/// Determines the hyperlink style used in commit and issue links. Defaults to `LinksStyle::Github`
///
/// # Example
///
/// ```no_run
/// # use clog::{LinkStyle, Clog};
/// let mut clog = Clog::new().unwrap();
/// clog.link_style(LinkStyle::Stash);
/// ```
clog_enum!{
    #[derive(Debug)]
    pub enum LinkStyle {
        Github,
        Gitlab,
        Stash
    }
}

impl LinkStyle {
    /// Gets a hyperlink url to an issue in the specified format.
    ///
    /// # Example
    ///
    /// ```no_run
    /// # use clog::{LinkStyle, Clog};
    /// let link = LinkStyle::Github;
    /// let issue = link.issue_link("141", "https://github.com/thoughtram/clog");
    ///
    /// assert_eq!("https://github.com/thoughtram/clog/issues/141", issue);
    /// ```
    pub fn issue_link<S: AsRef<str>>(&self, issue: S, repo: S) -> String {
        match repo.as_ref() {
            "" => format!("{}", issue.as_ref()),
            link => {
                match *self {
                    LinkStyle::Github => format!("{}/issues/{}", link, issue.as_ref()),
                    LinkStyle::Gitlab => format!("{}/issues/{}", link, issue.as_ref()),
                    LinkStyle::Stash => format!("{}", issue.as_ref()),
                }
            }
        }
    }

    /// Gets a hyperlink url to a commit in the specified format.
    ///
    /// # Example
    /// ```no_run
    /// # use clog::{LinkStyle, Clog};
    /// let link = LinkStyle::Github;
    /// let commit = link.commit_link("123abc891234567890abcdefabc4567898724", "https://github.com/thoughtram/clog");
    ///
    /// assert_eq!("https://github.com/thoughtram/clog/commit/123abc891234567890abcdefabc4567898724", commit);
    /// ```
    pub fn commit_link<S: AsRef<str>>(&self, hash: S, repo: S) -> String {
        match repo.as_ref() {
            "" => format!("{}", &hash.as_ref()[0..8]),
            link => {
                match *self {
                    LinkStyle::Github => format!("{}/commit/{}", link, hash.as_ref()),
                    LinkStyle::Gitlab => format!("{}/commit/{}", link, hash.as_ref()),
                    LinkStyle::Stash => format!("{}/commits/{}", link, hash.as_ref()),
                }
            }
        }
    }
}
<commit_msg>feat: add cgit link style<commit_after>/// Determines the hyperlink style used in commit and issue links. Defaults to `LinksStyle::Github`
///
/// # Example
///
/// ```no_run
/// # use clog::{LinkStyle, Clog};
/// let mut clog = Clog::new().unwrap();
/// clog.link_style(LinkStyle::Stash);
/// ```
clog_enum!{
    #[derive(Debug)]
    pub enum LinkStyle {
        Github,
        Gitlab,
        Stash,
        Cgit
    }
}

impl LinkStyle {
    /// Gets a hyperlink url to an issue in the specified format.
    ///
    /// # Example
    ///
    /// ```no_run
    /// # use clog::{LinkStyle, Clog};
    /// let link = LinkStyle::Github;
    /// let issue = link.issue_link("141", "https://github.com/thoughtram/clog");
    ///
    /// assert_eq!("https://github.com/thoughtram/clog/issues/141", issue);
    /// ```
    pub fn issue_link<S: AsRef<str>>(&self, issue: S, repo: S) -> String {
        match repo.as_ref() {
            "" => format!("{}", issue.as_ref()),
            link => {
                match *self {
                    LinkStyle::Github => format!("{}/issues/{}", link, issue.as_ref()),
                    LinkStyle::Gitlab => format!("{}/issues/{}", link, issue.as_ref()),
                    LinkStyle::Stash => format!("{}", issue.as_ref()),
                    // cgit does not support issues
                    LinkStyle::Cgit => format!("{}", issue.as_ref()),
                }
            }
        }
    }

    /// Gets a hyperlink url to a commit in the specified format.
    ///
    /// # Example
    /// ```no_run
    /// # use clog::{LinkStyle, Clog};
    /// let link = LinkStyle::Github;
    /// let commit = link.commit_link("123abc891234567890abcdefabc4567898724", "https://github.com/thoughtram/clog");
    ///
    /// assert_eq!("https://github.com/thoughtram/clog/commit/123abc891234567890abcdefabc4567898724", commit);
    /// ```
    pub fn commit_link<S: AsRef<str>>(&self, hash: S, repo: S) -> String {
        match repo.as_ref() {
            "" => format!("{}", &hash.as_ref()[0..8]),
            link => {
                match *self {
                    LinkStyle::Github => format!("{}/commit/{}", link, hash.as_ref()),
                    LinkStyle::Gitlab => format!("{}/commit/{}", link, hash.as_ref()),
                    LinkStyle::Stash => format!("{}/commits/{}", link, hash.as_ref()),
                    LinkStyle::Cgit => format!("{}/commit/?id={}", link, hash.as_ref()),
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>// aux-build:cci_capture_clause.rs

// This test makes sure we can do cross-crate inlining on functions
// that use capture clauses.

use cci_capture_clause;

import comm::recv;
import comm::methods;

fn main() {
    cci_capture_clause::foo(()).recv()
}
<commit_msg>Adding xfail-fast, since multi-crate tests don't work on Windows.<commit_after>// aux-build:cci_capture_clause.rs
// xfail-fast

// This test makes sure we can do cross-crate inlining on functions
// that use capture clauses.

use cci_capture_clause;

import comm::recv;
import comm::methods;

fn main() {
    cci_capture_clause::foo(()).recv()
}
<|endoftext|>


<commit_before>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(unknown_features)]
#![feature(box_syntax)]
#![feature(intrinsics)]
// needed to check for drop fill word.
#![feature(filling_drop)]

use std::mem::{self, transmute};

mod rusti {
    extern "rust-intrinsic" {
        pub fn init<T>() -> T;
        pub fn move_val_init<T>(dst: &mut T, src: T);
    }
}

pub fn main() {
    unsafe {
        let x: Box<_> = box 1;
        let mut y = rusti::init();
        let mut z: *const usize = transmute(&x);
        rusti::move_val_init(&mut y, x);
        assert_eq!(*y, 1);
        // `x` is nulled out, not directly visible
        assert_eq!(*z, mem::POST_DROP_USIZE);
    }
}
<commit_msg>Update the `intrinsic-move-val.rs` test to reflect its newer signature.<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(unknown_features)]
#![feature(box_syntax)]
#![feature(intrinsics)]
// needed to check for drop fill word.
#![feature(filling_drop)]

use std::mem::{self, transmute};

mod rusti {
    extern "rust-intrinsic" {
        pub fn init<T>() -> T;
        pub fn move_val_init<T>(dst: *mut T, src: T);
    }
}

pub fn main() {
    unsafe {
        let x: Box<_> = box 1;
        let mut y = rusti::init();
        let mut z: *const usize = transmute(&x);
        rusti::move_val_init(&mut y, x);
        assert_eq!(*y, 1);
        // `x` is nulled out, not directly visible
        assert_eq!(*z, mem::POST_DROP_USIZE);
    }
}
<|endoftext|>


<commit_before>// Test that the contents of constants are displayed as part of the
// documentation.

// @has show_const_contents/constant.CONST_S.html 'show this'
// @!has show_const_contents/constant.CONST_S.html '; //'
pub const CONST_S: &'static str = "show this";

// @has show_const_contents/constant.CONST_I32.html '= 42;'
// @!has show_const_contents/constant.CONST_I32.html '; //'
pub const CONST_I32: i32 = 42;

// @has show_const_contents/constant.CONST_I32_HEX.html '= 0x42;'
// @!has show_const_contents/constant.CONST_I32_HEX.html '; //'
pub const CONST_I32_HEX: i32 = 0x42;

// @has show_const_contents/constant.CONST_NEG_I32.html '= -42;'
// @!has show_const_contents/constant.CONST_NEG_I32.html '; //'
pub const CONST_NEG_I32: i32 = -42;

// @has show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '= 42i32;'
// @!has show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '// 42i32'
pub const CONST_EQ_TO_VALUE_I32: i32 = 42i32;

// @has show_const_contents/constant.CONST_CALC_I32.html '= 42 + 1; // 43i32'
pub const CONST_CALC_I32: i32 = 42 + 1;

// @!has show_const_contents/constant.CONST_REF_I32.html '= &42;'
// @!has show_const_contents/constant.CONST_REF_I32.html '; //'
pub const CONST_REF_I32: &'static i32 = &42;

// @has show_const_contents/constant.CONST_I32_MAX.html '= i32::max_value(); // 2_147_483_647i32'
pub const CONST_I32_MAX: i32 = i32::max_value();

// @!has show_const_contents/constant.UNIT.html '= ();'
// @!has show_const_contents/constant.UNIT.html '; //'
pub const UNIT: () = ();

pub struct MyType(i32);

// @!has show_const_contents/constant.MY_TYPE.html '= MyType(42);'
// @!has show_const_contents/constant.MY_TYPE.html '; //'
pub const MY_TYPE: MyType = MyType(42);

pub struct MyTypeWithStr(&'static str);

// @!has show_const_contents/constant.MY_TYPE_WITH_STR.html '= MyTypeWithStr("show this");'
// @!has show_const_contents/constant.MY_TYPE_WITH_STR.html '; //'
pub const MY_TYPE_WITH_STR: MyTypeWithStr = MyTypeWithStr("show this");

// @has show_const_contents/constant.PI.html '= 3.14159265358979323846264338327950288f32;'
// @has show_const_contents/constant.PI.html '; // 3.14159274f32'
pub use std::f32::consts::PI;

// @has show_const_contents/constant.MAX.html '= i32::max_value(); // 2_147_483_647i32'
pub use std::i32::MAX;

macro_rules! int_module {
    ($T:ident) => (
        pub const MIN: $T = $T::min_value();
    )
}

// @has show_const_contents/constant.MIN.html '= i16::min_value(); // -32_768i16'
int_module!(i16);

// @has show_const_contents/constant.ESCAPE.html //pre '= r#"<script>alert("ESCAPE");</script>"#;'
pub const ESCAPE: &str = r#"<script>alert("ESCAPE");</script>"#;
<commit_msg>Fix show-const-contents rustdoc test<commit_after>// Test that the contents of constants are displayed as part of the
// documentation.

// @has show_const_contents/constant.CONST_S.html 'show this'
// @!has show_const_contents/constant.CONST_S.html '; //'
pub const CONST_S: &'static str = "show this";

// @has show_const_contents/constant.CONST_I32.html '= 42;'
// @!has show_const_contents/constant.CONST_I32.html '; //'
pub const CONST_I32: i32 = 42;

// @has show_const_contents/constant.CONST_I32_HEX.html '= 0x42;'
// @!has show_const_contents/constant.CONST_I32_HEX.html '; //'
pub const CONST_I32_HEX: i32 = 0x42;

// @has show_const_contents/constant.CONST_NEG_I32.html '= -42;'
// @!has show_const_contents/constant.CONST_NEG_I32.html '; //'
pub const CONST_NEG_I32: i32 = -42;

// @has show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '= 42i32;'
// @!has show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '// 42i32'
pub const CONST_EQ_TO_VALUE_I32: i32 = 42i32;

// @has show_const_contents/constant.CONST_CALC_I32.html '= 42 + 1; // 43i32'
pub const CONST_CALC_I32: i32 = 42 + 1;

// @!has show_const_contents/constant.CONST_REF_I32.html '= &42;'
// @!has show_const_contents/constant.CONST_REF_I32.html '; //'
pub const CONST_REF_I32: &'static i32 = &42;

// @has show_const_contents/constant.CONST_I32_MAX.html '= i32::max_value(); // 2_147_483_647i32'
pub const CONST_I32_MAX: i32 = i32::max_value();

// @!has show_const_contents/constant.UNIT.html '= ();'
// @!has show_const_contents/constant.UNIT.html '; //'
pub const UNIT: () = ();

pub struct MyType(i32);

// @!has show_const_contents/constant.MY_TYPE.html '= MyType(42);'
// @!has show_const_contents/constant.MY_TYPE.html '; //'
pub const MY_TYPE: MyType = MyType(42);

pub struct MyTypeWithStr(&'static str);

// @!has show_const_contents/constant.MY_TYPE_WITH_STR.html '= MyTypeWithStr("show this");'
// @!has show_const_contents/constant.MY_TYPE_WITH_STR.html '; //'
pub const MY_TYPE_WITH_STR: MyTypeWithStr = MyTypeWithStr("show this");

// @has show_const_contents/constant.PI.html '= 3.14159265358979323846264338327950288f32;'
// @has show_const_contents/constant.PI.html '; // 3.14159274f32'
pub use std::f32::consts::PI;

// @has show_const_contents/constant.MAX.html '= i32::MAX; // 2_147_483_647i32'
pub use std::i32::MAX;

macro_rules! int_module {
    ($T:ident) => (
        pub const MIN: $T = $T::min_value();
    )
}

// @has show_const_contents/constant.MIN.html '= i16::min_value(); // -32_768i16'
int_module!(i16);

// @has show_const_contents/constant.ESCAPE.html //pre '= r#"<script>alert("ESCAPE");</script>"#;'
pub const ESCAPE: &str = r#"<script>alert("ESCAPE");</script>"#;
<|endoftext|>


<commit_before>#![allow(deprecated)]
use utils::data as D;
use std::ops::Index;
use std::path::PathBuf;
use std::{io, fs};
use curl::easy::Easy;
use flate2::{Flush, Decompress};
use std::io::Write;
use utils::data::{Dataset, DatasetIntf};
use std::rc::Rc;
use tensor::Tensor;

type Sample = (Tensor<f32>, Tensor<i64>);

static URLS: [&str; 4] = ["http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz",
                          "http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz",
                          "http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz",
                          "http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz"];

fn download(root: &String) -> io::Result<()> {
    let raw_path = PathBuf::from(root).join("raw");
    let processed_path = PathBuf::from(root).join("processed");
    // XXX how to ignore EEXIST?
    fs::create_dir(raw_path.clone())?;
    fs::create_dir(processed_path)?;

    for url in URLS.iter() {
        println!("downloading {}", url);
        let paths: Vec<_> = url.split("/").collect();
        let fname: Vec<_> = paths[5].split("/").collect();
        let file_path = raw_path.join(fname[0]);
        let mut file = fs::OpenOptions::new()
            .write(true)
            .create(true)
            .open(file_path)?;
        let mut data = Vec::new();
        let mut handle = Easy::new();
        handle.url(url).unwrap();
        {
            let mut transfer = handle.transfer();
            transfer
                .write_function(|new_data| {
                                    data.extend_from_slice(new_data);
                                    Ok(new_data.len())
                                })
                .unwrap();
            transfer.perform().unwrap();
        }
        let mut output = Vec::with_capacity(data.len());
        // do we have a header?
        Decompress::new(false)
            .decompress_vec(data.as_slice(), &mut output, Flush::Finish)?;
        file.write_all(output.as_slice())?;
    }
    println!("Proceeding");
    Ok(())
}

pub struct MNIST {
    pub root: String,
    pub train: bool,
//    pub transform: Option<fn(Vec<u8>)>,
}

#[builder(pattern="owned")]
#[derive(Builder)]
pub struct MNISTArgs {
    root: String,
    #[builder(default="true")]
    train: bool,
    #[builder(default="false")]
    download: bool,
//    #[builder(default="None")]
//    transform: Option<Box<fn(&Vec<u8>)>>,
}

impl MNISTArgsBuilder {
    pub fn done(self) -> Dataset<Sample> {
        let args = self.build().unwrap();
        Dataset::new(Rc::new(MNIST::new(&args)))
    }
}

impl MNIST {
    pub fn build(root: &str) -> MNISTArgsBuilder {
        MNISTArgsBuilder::default().root(root.into())
    }
    pub fn new(args: &MNISTArgs) -> Self {
        if args.download {
            download(&args.root);
        }
        MNIST {
            root: args.root.clone(),
            train: args.train,
//            transform: args.transform,
        }
    }
}

impl Index<usize> for MNIST {
    type Output = Sample;
    fn index(&self, idx: usize) -> &Self::Output {
        unimplemented!()
    }
}

impl D::DatasetIntf<Sample> for MNIST {
    fn len(&self) -> usize {
        if self.train { 60000 } else { 10000 }
    }
    fn iter(&self) -> Box<Iterator<Item = Sample>> {
        unimplemented!();
    }
}
<commit_msg>further progress on MNIST<commit_after>#![allow(deprecated)]
use utils::data as D;
use std::ops::Index;
use std::path::PathBuf;
use std::{io, fs};
use curl::easy::Easy;
use flate2::{Flush, Decompress};
use std::io::Write;
use utils::data::{Dataset, DatasetIntf};
use std::rc::Rc;
use tensor::{Tensor, TensorKind};
use torch;

type Sample = (Tensor<f32>, Tensor<i64>);

static URLS: [&str; 4] = ["http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz",
                          "http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz",
                          "http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz",
                          "http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz"];
static RAW_FOLDER: &str = "raw";
static PROCESSED_FOLDER: &str = "processed";
static TRAINING_FILE: &str = "training.pt";
static TEST_FILE: &str = "test.pt";

fn download(root: &String) -> io::Result<()> {
    let raw_path = PathBuf::from(root).join(RAW_FOLDER);
    let processed_path = PathBuf::from(root).join(PROCESSED_FOLDER);
    // XXX how to ignore EEXIST?
    fs::create_dir(raw_path.clone())?;
    fs::create_dir(processed_path.clone())?;

    for url in URLS.iter() {
        println!("downloading {}", url);
        let paths: Vec<_> = url.split("/").collect();
        let fname: Vec<_> = paths[5].split("/").collect();
        let file_path = raw_path.join(fname[0]);
        let mut file = fs::OpenOptions::new()
            .write(true)
            .create(true)
            .open(file_path)?;
        let mut data = Vec::new();
        let mut handle = Easy::new();
        handle.url(url).unwrap();
        {
            let mut transfer = handle.transfer();
            transfer
                .write_function(|new_data| {
                                    data.extend_from_slice(new_data);
                                    Ok(new_data.len())
                                })
                .unwrap();
            transfer.perform().unwrap();
        }
        let mut output = Vec::with_capacity(data.len());
        // do we have a header?
        Decompress::new(false)
            .decompress_vec(data.as_slice(), &mut output, Flush::Finish)?;
        file.write_all(output.as_slice())?;
    }
    println!("Proceeding");

    let training_set = vec![read_image_file(raw_path.join("train-images-idx3-ubyte")),
                            read_label_file(raw_path.join("train-labels-idx1-ubyte"))];
    let test_set = vec![read_image_file(raw_path.join("t10k-images-idx3-ubyte")),
                        read_label_file(raw_path.join("t10k-labels-idx1-ubyte"))];

    torch::save(processed_path.join(TRAINING_FILE), &training_set)?;
    torch::save(processed_path.join(TEST_FILE), &test_set)?;

    Ok(())
}

fn read_label_file(path: PathBuf) -> TensorKind {
    unimplemented!()
}
fn read_image_file(path: PathBuf) -> TensorKind {
    unimplemented!()
}

pub struct MNIST {
    pub root: String,
    pub train: bool,
    pub data: Tensor<u8>,
    pub labels: Tensor<i64>,
//    pub transform: Option<fn(Vec<u8>)>,
}

#[builder(pattern="owned")]
#[derive(Builder)]
pub struct MNISTArgs {
    root: String,
    #[builder(default="true")]
    train: bool,
    #[builder(default="false")]
    download: bool,
//    #[builder(default="None")]
//    transform: Option<Box<fn(&Vec<u8>)>>,
}

impl MNISTArgsBuilder {
    pub fn done(self) -> Dataset<Sample> {
        let args = self.build().unwrap();
        Dataset::new(Rc::new(MNIST::new(&args)))
    }
}

impl MNIST {
    pub fn build(root: &str) -> MNISTArgsBuilder {
        MNISTArgsBuilder::default().root(root.into())
    }
    pub fn new(args: &MNISTArgs) -> Self {
        if args.download {
            download(&args.root).expect("download failed");
        }
        let processed_path = PathBuf::from(&args.root).join(PROCESSED_FOLDER);
        let mut v = if args.train {
            torch::load(processed_path.join(TRAINING_FILE)).expect("torch load failed")
        } else {
            torch::load(processed_path.join(TEST_FILE)).expect("torch load failed")
        };
        let (data, labels) = (v.remove(0), v.remove(0));

        MNIST {
            root: args.root.clone(),
            train: args.train,
            data: data.into(),
            labels: labels.into(),
//            transform: args.transform,
        }
    }
}

impl Index<usize> for MNIST {
    type Output = Sample;
    fn index(&self, idx: usize) -> &Self::Output {
        unimplemented!()
    }
}

impl D::DatasetIntf<Sample> for MNIST {
    fn len(&self) -> usize {
        if self.train { 60000 } else { 10000 }
    }
    fn iter(&self) -> Box<Iterator<Item = Sample>> {
        unimplemented!();
    }
}
<|endoftext|>


<commit_before>//
//  SOS: the Stupid Operating System
//  by Hawk Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015 Hawk Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! Kernel memory management.
//!
//! This module contains all of the non-arch-specific paging code, and
//! re-exports memory-related definitions.
use alloc::buddy;

use core::{ops, cmp, convert};

pub use arch::memory::{PAddr, HEAP_BASE, HEAP_TOP, PAGE_SHIFT, PAGE_SIZE};

pub mod paging;
#[macro_use] pub mod macros;

/// A virtual address is a machine-sized unsigned integer
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct VAddr(usize);

pub trait Addr: ops::Add<Self> + ops::Sub<Self>
              + ops::Mul<Self> + ops::Div<Self>
              + ops::Shl<Self> + ops::Shr<Self>
              + convert::From<*mut u8> + convert::From<*const u8>
              + Sized {
    type Repr;
}

derive_addr! { VAddr, usize }

impl VAddr {
    #[inline] pub fn from_ptr<T>(ptr: *mut T) -> Self { VAddr(ptr as usize) }
    #[inline] pub const fn from_usize(u: usize) -> Self { VAddr(u) }
    #[inline] pub const fn as_usize(&self) -> usize { self.0 }

    /// Calculate the index in the PML4 table corresponding to this address.
    #[inline] pub fn pml4_index(&self) -> usize {
        (self >> 39) & 0b111111111
    }

    /// Calculate the index in the PDPT table corresponding to this address.
    #[inline] pub fn pdpt_index(&self) -> usize {
        (self >> 30) & 0b111111111
    }

    /// Calculate the index in the PD table corresponding to this address.
    #[inline] pub fn pd_index(&self) -> usize {
        (self >> 21) & 0b111111111
    }

    /// Calculate the index in the PT table corresponding to this address.
    #[inline] pub fn pt_index(&self) -> usize {
        (self >> 12) & 0b111111111
    }
}

#[inline] pub fn heap_base_addr() -> usize {
    unsafe { (&mut HEAP_BASE as *mut _) as usize }
}

#[inline] pub fn heap_top_addr() -> usize {
    unsafe { (&mut HEAP_TOP as *mut _) as usize }
}

/// Initialise the kernel heap.
//  TODO: this is the Worst Thing In The Universe. De-stupid-ify it.
pub unsafe fn init_heap<'a>() -> Result<&'a str, &'a str> {
    let heap_base_ptr
        = &mut HEAP_BASE as *mut _;
    let heap_size
        = (&mut HEAP_TOP as *mut _) as usize - heap_base_ptr as usize;
    buddy::system::init_heap(heap_base_ptr, heap_size);
    Ok("[ OKAY ]")
}
//
//impl<A, P> convert::From<A> for P
//where P: Page<Address = A>  {
//
//}

//macro_rules! make_addr_range {
//    $($name:ident, $addr:ty),+ => {$(
//
//    )+}
//}
<commit_msg>[kernel] remove an unused import<commit_after>//
//  SOS: the Stupid Operating System
//  by Hawk Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015 Hawk Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! Kernel memory management.
//!
//! This module contains all of the non-arch-specific paging code, and
//! re-exports memory-related definitions.
use alloc::buddy;

use core::{ops, convert};

pub use arch::memory::{PAddr, HEAP_BASE, HEAP_TOP, PAGE_SHIFT, PAGE_SIZE};

pub mod paging;
#[macro_use] pub mod macros;

/// A virtual address is a machine-sized unsigned integer
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct VAddr(usize);

pub trait Addr: ops::Add<Self> + ops::Sub<Self>
              + ops::Mul<Self> + ops::Div<Self>
              + ops::Shl<Self> + ops::Shr<Self>
              + convert::From<*mut u8> + convert::From<*const u8>
              + Sized {
    type Repr;
}

derive_addr! { VAddr, usize }

impl VAddr {
    #[inline] pub fn from_ptr<T>(ptr: *mut T) -> Self { VAddr(ptr as usize) }
    #[inline] pub const fn from_usize(u: usize) -> Self { VAddr(u) }
    #[inline] pub const fn as_usize(&self) -> usize { self.0 }

    /// Calculate the index in the PML4 table corresponding to this address.
    #[inline] pub fn pml4_index(&self) -> usize {
        (self >> 39) & 0b111111111
    }

    /// Calculate the index in the PDPT table corresponding to this address.
    #[inline] pub fn pdpt_index(&self) -> usize {
        (self >> 30) & 0b111111111
    }

    /// Calculate the index in the PD table corresponding to this address.
    #[inline] pub fn pd_index(&self) -> usize {
        (self >> 21) & 0b111111111
    }

    /// Calculate the index in the PT table corresponding to this address.
    #[inline] pub fn pt_index(&self) -> usize {
        (self >> 12) & 0b111111111
    }
}

#[inline] pub fn heap_base_addr() -> usize {
    unsafe { (&mut HEAP_BASE as *mut _) as usize }
}

#[inline] pub fn heap_top_addr() -> usize {
    unsafe { (&mut HEAP_TOP as *mut _) as usize }
}

/// Initialise the kernel heap.
//  TODO: this is the Worst Thing In The Universe. De-stupid-ify it.
pub unsafe fn init_heap<'a>() -> Result<&'a str, &'a str> {
    let heap_base_ptr
        = &mut HEAP_BASE as *mut _;
    let heap_size
        = (&mut HEAP_TOP as *mut _) as usize - heap_base_ptr as usize;
    buddy::system::init_heap(heap_base_ptr, heap_size);
    Ok("[ OKAY ]")
}
//
//impl<A, P> convert::From<A> for P
//where P: Page<Address = A>  {
//
//}

//macro_rules! make_addr_range {
//    $($name:ident, $addr:ty),+ => {$(
//
//    )+}
//}
<|endoftext|>