<commit_before>// Copyright 2016 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.

use std::collections::HashSet;

use build::{Build, Compiler};

#[derive(Hash, Eq, PartialEq, Clone, Debug)]
pub struct Step<'a> {
    pub src: Source<'a>,
    pub target: &'a str,
}

macro_rules! targets {
    ($m:ident) => {
        $m! {
            // Step representing building the stageN compiler. This is just the
            // compiler executable itself, not any of the support libraries
            (rustc, Rustc { stage: u32 }),

            // Steps for the two main cargo builds. These are parameterized over
            // the compiler which is producing the artifact.
            (libstd, Libstd { compiler: Compiler<'a> }),
            (libtest, Libtest { compiler: Compiler<'a> }),
            (librustc, Librustc { compiler: Compiler<'a> }),

            // Links the target produced by the compiler provided into the
            // host's directory also provided.
            (libstd_link, LibstdLink {
                compiler: Compiler<'a>,
                host: &'a str
            }),
            (libtest_link, LibtestLink {
                compiler: Compiler<'a>,
                host: &'a str
            }),
            (librustc_link, LibrustcLink {
                compiler: Compiler<'a>,
                host: &'a str
            }),

            // Various tools that we can build as part of the build.
            (tool_linkchecker, ToolLinkchecker { stage: u32 }),
            (tool_rustbook, ToolRustbook { stage: u32 }),
            (tool_error_index, ToolErrorIndex { stage: u32 }),
            (tool_cargotest, ToolCargoTest { stage: u32 }),

            // Steps for long-running native builds. Ideally these wouldn't
            // actually exist and would be part of build scripts, but for now
            // these are here.
            //
            // There aren't really any parameters to this, but empty structs
            // with braces are unstable so we just pick something that works.
            (llvm, Llvm { _dummy: () }),
            (compiler_rt, CompilerRt { _dummy: () }),

            // Steps for various pieces of documentation that we can generate,
            // the 'doc' step is just a pseudo target to depend on a bunch of
            // others.
            (doc, Doc { stage: u32 }),
            (doc_book, DocBook { stage: u32 }),
            (doc_nomicon, DocNomicon { stage: u32 }),
            (doc_style, DocStyle { stage: u32 }),
            (doc_standalone, DocStandalone { stage: u32 }),
            (doc_std, DocStd { stage: u32 }),
            (doc_test, DocTest { stage: u32 }),
            (doc_rustc, DocRustc { stage: u32 }),
            (doc_error_index, DocErrorIndex { stage: u32 }),

            // Steps for running tests. The 'check' target is just a pseudo
            // target to depend on a bunch of others.
            (check, Check { stage: u32, compiler: Compiler<'a> }),
            (check_linkcheck, CheckLinkcheck { stage: u32 }),
            (check_cargotest, CheckCargoTest { stage: u32 }),

            // Distribution targets, creating tarballs
            (dist, Dist { stage: u32 }),
            (dist_docs, DistDocs { stage: u32 }),
            (dist_mingw, DistMingw { _dummy: () }),
            (dist_rustc, DistRustc { stage: u32 }),
            (dist_std, DistStd { compiler: Compiler<'a> }),
        }
    }
}

macro_rules! item { ($a:item) => ($a) }

macro_rules! define_source {
    ($(($short:ident, $name:ident { $($args:tt)* }),)*) => {
        item! {
            #[derive(Hash, Eq, PartialEq, Clone, Debug)]
            pub enum Source<'a> {
                $($name { $($args)* }),*
            }
        }
    }
}

targets!(define_source);

pub fn all(build: &Build) -> Vec<Step> {
    let mut ret = Vec::new();
    let mut all = HashSet::new();
    for target in top_level(build) {
        fill(build, &target, &mut ret, &mut all);
    }
    return ret;

    fn fill<'a>(build: &'a Build,
                target: &Step<'a>,
                ret: &mut Vec<Step<'a>>,
                set: &mut HashSet<Step<'a>>) {
        if set.insert(target.clone()) {
            for dep in target.deps(build) {
                fill(build, &dep, ret, set);
            }
            ret.push(target.clone());
        }
    }
}

fn top_level(build: &Build) -> Vec<Step> {
    let mut targets = Vec::new();
    let stage = build.flags.stage.unwrap_or(2);

    let host = Step {
        src: Source::Llvm { _dummy: () },
        target: build.flags.host.iter().next()
                     .unwrap_or(&build.config.build),
    };
    let target = Step {
        src: Source::Llvm { _dummy: () },
        target: build.flags.target.iter().next().map(|x| &x[..])
                     .unwrap_or(host.target)
    };

    add_steps(build, stage, &host, &target, &mut targets);

    if targets.len() == 0 {
        let t = Step {
            src: Source::Llvm { _dummy: () },
            target: &build.config.build,
        };
        targets.push(t.doc(stage));
        for host in build.config.host.iter() {
            if !build.flags.host.contains(host) {
                continue
            }
            let host = t.target(host);
            if host.target == build.config.build {
                targets.push(host.librustc(host.compiler(stage)));
            } else {
                targets.push(host.librustc_link(t.compiler(stage), host.target));
            }
            for target in build.config.target.iter() {
                if !build.flags.target.contains(target) {
                    continue
                }

                if host.target == build.config.build {
                    targets.push(host.target(target)
                                     .libtest(host.compiler(stage)));
                } else {
                    targets.push(host.target(target)
                                     .libtest_link(t.compiler(stage), host.target));
                }
            }
        }
    }

    return targets

}

fn add_steps<'a>(build: &'a Build,
                 stage: u32,
                 host: &Step<'a>,
                 target: &Step<'a>,
                 targets: &mut Vec<Step<'a>>) {
    struct Context<'a> {
        stage: u32,
        compiler: Compiler<'a>,
        _dummy: (),
        host: &'a str,
    }
    for step in build.flags.step.iter() {

        // The macro below insists on hygienic access to all local variables, so
        // we shove them all in a struct and subvert hygiene by accessing struct
        // fields instead,
        let cx = Context {
            stage: stage,
            compiler: host.target(&build.config.build).compiler(stage),
            _dummy: (),
            host: host.target,
        };
        macro_rules! add_step {
            ($(($short:ident, $name:ident { $($arg:ident: $t:ty),* }),)*) => ({$(
                let name = stringify!($short).replace("_", "-");
                if &step[..] == &name[..] {
                    targets.push(target.$short($(cx.$arg),*));
                    continue
                }
                drop(name);
            )*})
        }

        targets!(add_step);

        panic!("unknown step: {}", step);
    }
}

macro_rules! constructors {
    ($(($short:ident, $name:ident { $($arg:ident: $t:ty),* }),)*) => {$(
        fn $short(&self, $($arg: $t),*) -> Step<'a> {
            Step {
                src: Source::$name { $($arg: $arg),* },
                target: self.target,
            }
        }
    )*}
}

impl<'a> Step<'a> {
    fn compiler(&self, stage: u32) -> Compiler<'a> {
        Compiler::new(stage, self.target)
    }

    fn target(&self, target: &'a str) -> Step<'a> {
        Step { target: target, src: self.src.clone() }
    }

    targets!(constructors);

    pub fn deps(&self, build: &'a Build) -> Vec<Step<'a>> {
        match self.src {
            Source::Rustc { stage: 0 } => {
                Vec::new()
            }
            Source::Rustc { stage } => {
                let compiler = Compiler::new(stage - 1, &build.config.build);
                vec![self.librustc(compiler)]
            }
            Source::Librustc { compiler } => {
                vec![self.libtest(compiler), self.llvm(())]
            }
            Source::Libtest { compiler } => {
                vec![self.libstd(compiler)]
            }
            Source::Libstd { compiler } => {
                vec![self.compiler_rt(()),
                     self.rustc(compiler.stage).target(compiler.host)]
            }
            Source::LibrustcLink { compiler, host } => {
                vec![self.librustc(compiler),
                     self.libtest_link(compiler, host)]
            }
            Source::LibtestLink { compiler, host } => {
                vec![self.libtest(compiler), self.libstd_link(compiler, host)]
            }
            Source::LibstdLink { compiler, host } => {
                vec![self.libstd(compiler),
                     self.target(host).rustc(compiler.stage)]
            }
            Source::CompilerRt { _dummy } => {
                vec![self.llvm(()).target(&build.config.build)]
            }
            Source::Llvm { _dummy } => Vec::new(),

            // Note that all doc targets depend on artifacts from the build
            // architecture, not the target (which is where we're generating
            // docs into).
            Source::DocStd { stage } => {
                let compiler = self.target(&build.config.build).compiler(stage);
                vec![self.libstd(compiler)]
            }
            Source::DocTest { stage } => {
                let compiler = self.target(&build.config.build).compiler(stage);
                vec![self.libtest(compiler)]
            }
            Source::DocBook { stage } |
            Source::DocNomicon { stage } |
            Source::DocStyle { stage } => {
                vec![self.target(&build.config.build).tool_rustbook(stage)]
            }
            Source::DocErrorIndex { stage } => {
                vec![self.target(&build.config.build).tool_error_index(stage)]
            }
            Source::DocStandalone { stage } => {
                vec![self.target(&build.config.build).rustc(stage)]
            }
            Source::DocRustc { stage } => {
                vec![self.doc_test(stage)]
            }
            Source::Doc { stage } => {
                vec![self.doc_book(stage), self.doc_nomicon(stage),
                     self.doc_style(stage), self.doc_standalone(stage),
                     self.doc_std(stage),
                     self.doc_error_index(stage)]
            }
            Source::Check { stage, compiler: _ } => {
                vec![self.check_linkcheck(stage),
                     self.dist(stage)]
            }
            Source::CheckLinkcheck { stage } => {
                vec![self.tool_linkchecker(stage), self.doc(stage)]
            }
            Source::CheckCargoTest { stage } => {
                vec![self.tool_cargotest(stage)]
            }

            Source::ToolLinkchecker { stage } => {
                vec![self.libstd(self.compiler(stage))]
            }
            Source::ToolErrorIndex { stage } |
            Source::ToolRustbook { stage } => {
                vec![self.librustc(self.compiler(stage))]
            }
            Source::ToolCargoTest { stage } => {
                vec![self.librustc(self.compiler(stage))]
            }

            Source::DistDocs { stage } => vec![self.doc(stage)],
            Source::DistMingw { _dummy: _ } => Vec::new(),
            Source::DistRustc { stage } => {
                vec![self.rustc(stage)]
            }
            Source::DistStd { compiler } => {
                vec![self.libtest(compiler)]
            }

            Source::Dist { stage } => {
                let mut base = Vec::new();

                for host in build.config.host.iter() {
                    let host = self.target(host);
                    base.push(host.dist_rustc(stage));
                    if host.target.contains("windows-gnu") {
                        base.push(host.dist_mingw(()));
                    }

                    let compiler = self.compiler(stage);
                    for target in build.config.target.iter() {
                        let target = self.target(target);
                        base.push(target.dist_docs(stage));
                        base.push(target.dist_std(compiler));
                    }
                }
                return base
            }
        }
    }
}
<commit_msg>rustbuild: Skip generating docs if the config disables them.<commit_after>// Copyright 2016 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.

use std::collections::HashSet;

use build::{Build, Compiler};

#[derive(Hash, Eq, PartialEq, Clone, Debug)]
pub struct Step<'a> {
    pub src: Source<'a>,
    pub target: &'a str,
}

macro_rules! targets {
    ($m:ident) => {
        $m! {
            // Step representing building the stageN compiler. This is just the
            // compiler executable itself, not any of the support libraries
            (rustc, Rustc { stage: u32 }),

            // Steps for the two main cargo builds. These are parameterized over
            // the compiler which is producing the artifact.
            (libstd, Libstd { compiler: Compiler<'a> }),
            (libtest, Libtest { compiler: Compiler<'a> }),
            (librustc, Librustc { compiler: Compiler<'a> }),

            // Links the target produced by the compiler provided into the
            // host's directory also provided.
            (libstd_link, LibstdLink {
                compiler: Compiler<'a>,
                host: &'a str
            }),
            (libtest_link, LibtestLink {
                compiler: Compiler<'a>,
                host: &'a str
            }),
            (librustc_link, LibrustcLink {
                compiler: Compiler<'a>,
                host: &'a str
            }),

            // Various tools that we can build as part of the build.
            (tool_linkchecker, ToolLinkchecker { stage: u32 }),
            (tool_rustbook, ToolRustbook { stage: u32 }),
            (tool_error_index, ToolErrorIndex { stage: u32 }),
            (tool_cargotest, ToolCargoTest { stage: u32 }),

            // Steps for long-running native builds. Ideally these wouldn't
            // actually exist and would be part of build scripts, but for now
            // these are here.
            //
            // There aren't really any parameters to this, but empty structs
            // with braces are unstable so we just pick something that works.
            (llvm, Llvm { _dummy: () }),
            (compiler_rt, CompilerRt { _dummy: () }),

            // Steps for various pieces of documentation that we can generate,
            // the 'doc' step is just a pseudo target to depend on a bunch of
            // others.
            (doc, Doc { stage: u32 }),
            (doc_book, DocBook { stage: u32 }),
            (doc_nomicon, DocNomicon { stage: u32 }),
            (doc_style, DocStyle { stage: u32 }),
            (doc_standalone, DocStandalone { stage: u32 }),
            (doc_std, DocStd { stage: u32 }),
            (doc_test, DocTest { stage: u32 }),
            (doc_rustc, DocRustc { stage: u32 }),
            (doc_error_index, DocErrorIndex { stage: u32 }),

            // Steps for running tests. The 'check' target is just a pseudo
            // target to depend on a bunch of others.
            (check, Check { stage: u32, compiler: Compiler<'a> }),
            (check_linkcheck, CheckLinkcheck { stage: u32 }),
            (check_cargotest, CheckCargoTest { stage: u32 }),

            // Distribution targets, creating tarballs
            (dist, Dist { stage: u32 }),
            (dist_docs, DistDocs { stage: u32 }),
            (dist_mingw, DistMingw { _dummy: () }),
            (dist_rustc, DistRustc { stage: u32 }),
            (dist_std, DistStd { compiler: Compiler<'a> }),
        }
    }
}

macro_rules! item { ($a:item) => ($a) }

macro_rules! define_source {
    ($(($short:ident, $name:ident { $($args:tt)* }),)*) => {
        item! {
            #[derive(Hash, Eq, PartialEq, Clone, Debug)]
            pub enum Source<'a> {
                $($name { $($args)* }),*
            }
        }
    }
}

targets!(define_source);

pub fn all(build: &Build) -> Vec<Step> {
    let mut ret = Vec::new();
    let mut all = HashSet::new();
    for target in top_level(build) {
        fill(build, &target, &mut ret, &mut all);
    }
    return ret;

    fn fill<'a>(build: &'a Build,
                target: &Step<'a>,
                ret: &mut Vec<Step<'a>>,
                set: &mut HashSet<Step<'a>>) {
        if set.insert(target.clone()) {
            for dep in target.deps(build) {
                fill(build, &dep, ret, set);
            }
            ret.push(target.clone());
        }
    }
}

fn top_level(build: &Build) -> Vec<Step> {
    let mut targets = Vec::new();
    let stage = build.flags.stage.unwrap_or(2);

    let host = Step {
        src: Source::Llvm { _dummy: () },
        target: build.flags.host.iter().next()
                     .unwrap_or(&build.config.build),
    };
    let target = Step {
        src: Source::Llvm { _dummy: () },
        target: build.flags.target.iter().next().map(|x| &x[..])
                     .unwrap_or(host.target)
    };

    add_steps(build, stage, &host, &target, &mut targets);

    if targets.len() == 0 {
        let t = Step {
            src: Source::Llvm { _dummy: () },
            target: &build.config.build,
        };
        if build.config.docs {
          targets.push(t.doc(stage));
        }
        for host in build.config.host.iter() {
            if !build.flags.host.contains(host) {
                continue
            }
            let host = t.target(host);
            if host.target == build.config.build {
                targets.push(host.librustc(host.compiler(stage)));
            } else {
                targets.push(host.librustc_link(t.compiler(stage), host.target));
            }
            for target in build.config.target.iter() {
                if !build.flags.target.contains(target) {
                    continue
                }

                if host.target == build.config.build {
                    targets.push(host.target(target)
                                     .libtest(host.compiler(stage)));
                } else {
                    targets.push(host.target(target)
                                     .libtest_link(t.compiler(stage), host.target));
                }
            }
        }
    }

    return targets

}

fn add_steps<'a>(build: &'a Build,
                 stage: u32,
                 host: &Step<'a>,
                 target: &Step<'a>,
                 targets: &mut Vec<Step<'a>>) {
    struct Context<'a> {
        stage: u32,
        compiler: Compiler<'a>,
        _dummy: (),
        host: &'a str,
    }
    for step in build.flags.step.iter() {

        // The macro below insists on hygienic access to all local variables, so
        // we shove them all in a struct and subvert hygiene by accessing struct
        // fields instead,
        let cx = Context {
            stage: stage,
            compiler: host.target(&build.config.build).compiler(stage),
            _dummy: (),
            host: host.target,
        };
        macro_rules! add_step {
            ($(($short:ident, $name:ident { $($arg:ident: $t:ty),* }),)*) => ({$(
                let name = stringify!($short).replace("_", "-");
                if &step[..] == &name[..] {
                    targets.push(target.$short($(cx.$arg),*));
                    continue
                }
                drop(name);
            )*})
        }

        targets!(add_step);

        panic!("unknown step: {}", step);
    }
}

macro_rules! constructors {
    ($(($short:ident, $name:ident { $($arg:ident: $t:ty),* }),)*) => {$(
        fn $short(&self, $($arg: $t),*) -> Step<'a> {
            Step {
                src: Source::$name { $($arg: $arg),* },
                target: self.target,
            }
        }
    )*}
}

impl<'a> Step<'a> {
    fn compiler(&self, stage: u32) -> Compiler<'a> {
        Compiler::new(stage, self.target)
    }

    fn target(&self, target: &'a str) -> Step<'a> {
        Step { target: target, src: self.src.clone() }
    }

    targets!(constructors);

    pub fn deps(&self, build: &'a Build) -> Vec<Step<'a>> {
        match self.src {
            Source::Rustc { stage: 0 } => {
                Vec::new()
            }
            Source::Rustc { stage } => {
                let compiler = Compiler::new(stage - 1, &build.config.build);
                vec![self.librustc(compiler)]
            }
            Source::Librustc { compiler } => {
                vec![self.libtest(compiler), self.llvm(())]
            }
            Source::Libtest { compiler } => {
                vec![self.libstd(compiler)]
            }
            Source::Libstd { compiler } => {
                vec![self.compiler_rt(()),
                     self.rustc(compiler.stage).target(compiler.host)]
            }
            Source::LibrustcLink { compiler, host } => {
                vec![self.librustc(compiler),
                     self.libtest_link(compiler, host)]
            }
            Source::LibtestLink { compiler, host } => {
                vec![self.libtest(compiler), self.libstd_link(compiler, host)]
            }
            Source::LibstdLink { compiler, host } => {
                vec![self.libstd(compiler),
                     self.target(host).rustc(compiler.stage)]
            }
            Source::CompilerRt { _dummy } => {
                vec![self.llvm(()).target(&build.config.build)]
            }
            Source::Llvm { _dummy } => Vec::new(),

            // Note that all doc targets depend on artifacts from the build
            // architecture, not the target (which is where we're generating
            // docs into).
            Source::DocStd { stage } => {
                let compiler = self.target(&build.config.build).compiler(stage);
                vec![self.libstd(compiler)]
            }
            Source::DocTest { stage } => {
                let compiler = self.target(&build.config.build).compiler(stage);
                vec![self.libtest(compiler)]
            }
            Source::DocBook { stage } |
            Source::DocNomicon { stage } |
            Source::DocStyle { stage } => {
                vec![self.target(&build.config.build).tool_rustbook(stage)]
            }
            Source::DocErrorIndex { stage } => {
                vec![self.target(&build.config.build).tool_error_index(stage)]
            }
            Source::DocStandalone { stage } => {
                vec![self.target(&build.config.build).rustc(stage)]
            }
            Source::DocRustc { stage } => {
                vec![self.doc_test(stage)]
            }
            Source::Doc { stage } => {
                vec![self.doc_book(stage), self.doc_nomicon(stage),
                     self.doc_style(stage), self.doc_standalone(stage),
                     self.doc_std(stage),
                     self.doc_error_index(stage)]
            }
            Source::Check { stage, compiler: _ } => {
                vec![self.check_linkcheck(stage),
                     self.dist(stage)]
            }
            Source::CheckLinkcheck { stage } => {
                vec![self.tool_linkchecker(stage), self.doc(stage)]
            }
            Source::CheckCargoTest { stage } => {
                vec![self.tool_cargotest(stage)]
            }

            Source::ToolLinkchecker { stage } => {
                vec![self.libstd(self.compiler(stage))]
            }
            Source::ToolErrorIndex { stage } |
            Source::ToolRustbook { stage } => {
                vec![self.librustc(self.compiler(stage))]
            }
            Source::ToolCargoTest { stage } => {
                vec![self.librustc(self.compiler(stage))]
            }

            Source::DistDocs { stage } => vec![self.doc(stage)],
            Source::DistMingw { _dummy: _ } => Vec::new(),
            Source::DistRustc { stage } => {
                vec![self.rustc(stage)]
            }
            Source::DistStd { compiler } => {
                vec![self.libtest(compiler)]
            }

            Source::Dist { stage } => {
                let mut base = Vec::new();

                for host in build.config.host.iter() {
                    let host = self.target(host);
                    base.push(host.dist_rustc(stage));
                    if host.target.contains("windows-gnu") {
                        base.push(host.dist_mingw(()));
                    }

                    let compiler = self.compiler(stage);
                    for target in build.config.target.iter() {
                        let target = self.target(target);
                        if build.config.docs {
                            base.push(target.dist_docs(stage));
                        }
                        base.push(target.dist_std(compiler));
                    }
                }
                return base
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>imag-view: Replace read with typed read<commit_after><|endoftext|>


<commit_before><commit_msg>Adds a trait definition for Intl.PluralRules.<commit_after>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// Contains the API configuration as prescribed by [ECMA 402][ecma].
///
///    [ecma]: https://www.ecma-international.org/publications/standards/Ecma-402.htm
///
/// The meaning of the options is the same as in the similarly named
/// options in the JS version.
///
/// See [Options] for the contents of the options.  See the [PluralRules::try_new]
/// for the use of the options.
pub mod options {
    /// The type of plural rules with respect to cardinality and ordinality.
    #[derive(Eq, PartialEq, Debug, Clone)]
    pub enum Type {
        /// As in "one, two, three, ..."
        Cardinal,
        /// As in: "first, second, third, ..."
        Ordinal,
    }
}

/// The options set by the user at construction time.  See discussion at the top level
/// about the name choice.  Provides as a "bag of options" since we don't expect any
/// implementations to be attached to this struct.
///
/// The default values of all the options are prescribed in by the [TC39 report][tc39lf].
///
///   [tc39lf]: https://tc39.es/proposal-intl-list-format/#sec-Intl.ListFormat
#[derive(Eq, PartialEq, Debug, Clone)]
pub struct Options {
    /// Selects a [options::Type] for the formatted list.  If unset, defaults to
    /// [options::Type::Cardinal].
    pub in_type: options::Type,
    pub minimum_integer_digits: u8,
    pub minimum_fraction_digits: u8,
    pub maximum_fraction_digits: u8,
    pub minimum_significant_digits: u8,
    pub maximum_significant_digits: u8,
}

/// Allows the use of `pluralrules::Rules::try_new(..., Default::default())`.
impl Default for Options {
    /// Gets the default values of [Options] if omitted at setup.  The
    /// default values are prescribed in by the [TC39 report][tc39lf].
    ///
    ///   [tc39lf]: https://tc39.es/proposal-intl-list-format/#sec-Intl.ListFormat
    fn default() -> Self {
        Options {
            in_type: options::Type::Cardinal,
            minimum_integer_digits: 1,
            minimum_fraction_digits: 0,
            maximum_fraction_digits: 3,
            minimum_significant_digits: 1,
            maximum_significant_digits: 21,
        }
    }
}

use std::fmt;

/// Returns the plural class of each of the supplied number.
pub trait PluralRules {
    /// The type of error reported, if any.
    type Error: std::error::Error;

    /// Creates a new [Rules].
    ///
    /// Creation may fail, for example, if the locale-specific data is not loaded, or if
    /// the supplied options are inconsistent.
    fn try_new<L>(l: L, opts: Options) -> Result<Self, Self::Error>
    where
        L: crate::Locale,
        Self: Sized;

    /// Formats the plural class of `number` into the supplied `writer`.
    ///
    /// The function implements [`Intl.PluralRules`][plr] from [ECMA 402][ecma].
    ///
    ///    [plr]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules
    ///    [ecma]: https://www.ecma-international.org/publications/standards/Ecma-402.htm
    fn select<W>(self, number: f64, writer: &mut W) -> fmt::Result
    where
        W: fmt::Write;
}
<|endoftext|>


<commit_before><commit_msg>max_idle config<commit_after><|endoftext|>


<commit_before><commit_msg>expose fields<commit_after><|endoftext|>


<commit_before><commit_msg>add editor.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Initial stretchy symbol implementation<commit_after>/*
 * Copyright 2017 Sreejith Krishnan R
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

use std::f32;

use super::{Drawable, MeasureMode, BoundingBox, AbsoluteLayout, AbsoluteLayoutParams, Glyph, GlyphIndex};
use ::platform::Context;
use ::paint::{Point, Canvas, GlyphConstructionDirection, MathRuler, GlyphAssembly};
use ::props::{Color, Directionality};
use ::elements::Element;

type SymbolReader<T> = fn(&T) -> u32;
type SymmetricReader<T> = fn(&T) -> bool;
type SizeReader<T> = fn(&T) -> f32;
type DirReader<T> = fn(&T) -> &Directionality;
type ColorReader<T> = fn(&T) -> &Color;

pub struct Symbol<'a, T: Element + 'a> {
    props: &'a T,
    symbol_reader: SymbolReader<T>,
    symmetric_reader: SymmetricReader<T>,
    base_size_reader: SizeReader<T>,
    max_size_reader: SizeReader<T>,
    min_size_reader: SizeReader<T>,
    dir_reader: DirReader<T>,
    color_reader: ColorReader<T>,

    bounding_box: BoundingBox,
    layout: AbsoluteLayout<'a>,
}

impl<'a, T: Element + 'a> Drawable for Symbol<'a, T> {
    fn draw(&self, canvas: &Canvas, pen_pos: &Point) {
        self.layout.draw(canvas, pen_pos);
    }

    fn calculate(&mut self, context: &Context, width: f32, width_mode: &MeasureMode, height: f32,
                 height_mode: &MeasureMode) {
        let base_size = (self.base_size_reader)(self.props);
        let symbol = (self.symbol_reader)(self.props);
        let ruler = context.platform().get_math_ruler(self.props, base_size);

        if *height_mode == MeasureMode::UpTo {
            let stretch_dir = GlyphConstructionDirection::Vertical;

            if self.try_stretch_symbol(context,symbol, ruler, height, &stretch_dir) {
                return;
            }
        }

        if *width_mode == MeasureMode::UpTo {
            let stretch_dir = GlyphConstructionDirection::Horizontal;

            if self.try_stretch_symbol(context,symbol, ruler, width, &stretch_dir) {
                return;
            }
        }

        self.set_single_glyph(context,GlyphIndex::Char(symbol));
    }

    fn bounding_box(&self) -> &BoundingBox {
        &self.bounding_box
    }
}

impl<'a, T: Element + 'a> Symbol<'a, T> {
    pub fn new(props: &'a T, symbol_reader: SymbolReader<T>, symmetric_reader: SymmetricReader<T>,
               base_size_reader: SizeReader<T>, max_size_reader: SizeReader<T>,
               min_size_reader: SizeReader<T>, dir_reader: DirReader<T>,
               color_reader: ColorReader<T>) -> Symbol<'a, T> {
        Symbol {
            props,
            symbol_reader,
            symmetric_reader,
            base_size_reader,
            max_size_reader,
            min_size_reader,
            dir_reader,
            color_reader,
            bounding_box: BoundingBox::default(),
            layout: AbsoluteLayout::new(),
        }
    }

    fn set_single_glyph(&mut self, context: &Context, glyph: GlyphIndex) {
        let glyph = Glyph::new(
            self.props,
            glyph,
            self.base_size_reader,
            self.color_reader,
            self.dir_reader
        );

        self.layout.clear();
        self.layout.add_child(Box::new(glyph),
                              AbsoluteLayoutParams::new(Point::new(0., 0.)));

        self.layout.calculate(context, -1., &MeasureMode::Wrap, -1., &MeasureMode::Wrap);

        self.bounding_box = self.layout.bounding_box().clone();
    }

    fn try_stretch_symbol(&mut self, context: &Context, symbol: u32, ruler: &MathRuler,
                          stretched_size: f32, stretch_dir: &GlyphConstructionDirection) -> bool {
        let variants = ruler.glyph_variants(symbol, stretch_dir);

        for variant in variants {
            if variant.advance() >= stretched_size {
                self.set_single_glyph(context, GlyphIndex::Index(variant.glyph_index()));
                return true;
            }
        }

        let assembly = ruler.glyph_assembly(symbol, stretch_dir);
        if assembly.parts().len() >= 2 {
            self.set_glyph_assembly(context, assembly, &stretch_dir, stretched_size, ruler);
            return true;
        }

        return false;
    }

    fn set_glyph_assembly(&mut self, context: &Context, assembly: GlyphAssembly,
                          stretch_dir: &GlyphConstructionDirection,
                          stretched_size: f32, ruler: &MathRuler) {
        let min_connector_overlap = ruler.minimum_connector_overlap(stretch_dir);

        let mut num_extenders = 0;
        let mut total_extender_advance = 0f32;

        let mut num_non_extenders = 0;
        let mut total_non_extender_advance = 0f32;

        let mut max_connector_overlap = 0f32;

        for (index, part) in assembly.parts().iter().enumerate() {
            if part.is_extender() {
                num_extenders += 1;
                total_extender_advance += part.full_advance();
            } else {
                num_non_extenders += 1;
                total_non_extender_advance += part.full_advance();
            }

            if index != 0 {
                max_connector_overlap = max_connector_overlap.min(part.start_connector_length());
            }

            max_connector_overlap = max_connector_overlap.min(part.full_advance());

            if index != assembly.parts().len()-1 {
                max_connector_overlap = max_connector_overlap.min(part.end_connector_length());
            }

            max_connector_overlap = max_connector_overlap
                .min(part.start_connector_length())
                .min(part.end_connector_length())
                .min(part.full_advance());
        }

        let num_extenders = num_extenders as f32;
        let num_non_extenders = num_non_extenders as f32;

        let extender_multiplier = ((stretched_size + (min_connector_overlap * (num_non_extenders + 1.))
            - total_non_extender_advance) /
            (total_extender_advance + (min_connector_overlap * num_extenders))).ceil();

        let required_overlap = (total_non_extender_advance + (extender_multiplier * total_extender_advance)
            - stretched_size) /
            (num_non_extenders + (extender_multiplier * num_extenders) - 1.);

        let overlap = required_overlap.min(max_connector_overlap);

        self.layout.clear();

        let mut pen_pos = 0f32;
        for part in assembly.parts().iter() {
            self.layout.add_child(
                Box::new(Glyph::new(
                    self.props,
                    GlyphIndex::Index(part.glyph_index()),
                    self.base_size_reader,
                    self.color_reader,
                    self.dir_reader)
                ),
                AbsoluteLayoutParams::new(match *stretch_dir {
                    GlyphConstructionDirection::Horizontal => Point::new(pen_pos, 0.),
                    GlyphConstructionDirection::Vertical => Point::new(0., pen_pos)
                })
            );

            pen_pos += part.full_advance()-overlap;
        }

        self.layout.calculate(context, -1., &MeasureMode::Wrap, -1., &MeasureMode::Wrap);

        self.bounding_box = self.layout.bounding_box().clone();
    }
}<|endoftext|>


<commit_before><commit_msg>Add ability to pause drivers<commit_after><|endoftext|>


<commit_before>use super::{Error, Result, raw};
use std;

/// Handle to an ODBC Environment
///
/// Creating an instance of this type is the first thing you do then using ODBC. The environment
/// must outlive all connections created with it
pub struct Environment {
    handle: raw::SQLHENV,
}

/// Struct holding information available on a driver.
///
/// Can be obtained via `Environment::drivers`
#[derive(Clone, Debug)]
pub struct DriverInfo {
    pub description: String,
    pub attributes: Vec<(String, String)>,
}

impl Environment {
    /// Allocates a new ODBC Environment
    ///
    /// Declares the Application's ODBC Version to be 3
    pub fn new() -> Result<Environment> {
        unsafe {
            let mut env = std::ptr::null_mut();
            let mut result =
                match raw::SQLAllocHandle(raw::SQL_HANDLE_ENV, std::ptr::null_mut(), &mut env) {
                    raw::SQL_SUCCESS => Environment { handle: env },
                    raw::SQL_SUCCESS_WITH_INFO => Environment { handle: env },
                    // Driver Manager failed to allocate environment
                    raw::SQL_ERROR => return Err(Error {}),
                    _ => unreachable!(),
                };
            // no leak if we return an error here, env handle is already wrapped and would be
            // dropped
            result.set_attribute(raw::SQL_ATTR_ODBC_VERSION,
                               raw::SQL_OV_ODBC3 as *mut std::os::raw::c_void,
                               0)?;

            Ok(result)
        }
    }

    /// Stores all driver description and attributes in a Vec
    pub fn drivers(&self) -> Result<Vec<DriverInfo>> {
        // Iterate twice, once for reading the maximum required buffer lengths so we can read
        // everything without truncating and a second time for actually storing the values
        let string_buf = std::ptr::null_mut();
        let mut desc_length_out: raw::SQLSMALLINT = 0;
        let mut attr_length_out: raw::SQLSMALLINT = 0;
        let mut max_desc = 0;
        let mut max_attr = 0;
        let mut count = 0;
        let mut result;
        unsafe {
            // Although the rather lengthy function call kind of blows the code, let's do the first
            // one using SQL_FETCH_FIRST, so we list all drivers independent from environment state
            result = raw::SQLDrivers(self.handle,
                                     raw::SQL_FETCH_FIRST,
                                     string_buf,
                                     0,
                                     &mut desc_length_out as *mut raw::SQLSMALLINT,
                                     string_buf,
                                     0,
                                     &mut attr_length_out as *mut raw::SQLSMALLINT);
        }
        loop {
            match result {
                raw::SQL_SUCCESS |
                raw::SQL_SUCCESS_WITH_INFO => {
                    count += 1;
                    max_desc = std::cmp::max(max_desc, desc_length_out);
                    max_attr = std::cmp::max(max_attr, attr_length_out);
                }
                raw::SQL_NO_DATA => break,
                raw::SQL_ERROR => return Err(Error {}),
                _ => unreachable!(),
            }
            unsafe {
                result = raw::SQLDrivers(self.handle,
                                         raw::SQL_FETCH_NEXT,
                                         string_buf,
                                         0,
                                         &mut desc_length_out as *mut raw::SQLSMALLINT,
                                         string_buf,
                                         0,
                                         &mut attr_length_out as *mut raw::SQLSMALLINT);
            }
        }

        let mut driver_list = Vec::with_capacity(count);
        loop {
            let mut description_buffer: Vec<_> = (0..(max_desc + 1)).map(|_| 0u8).collect();
            let mut attribute_buffer: Vec<_> = (0..(max_attr + 1)).map(|_| 0u8).collect();
            unsafe {
                result = raw::SQLDrivers(self.handle,
                                         // Its ok to use fetch next here, since we know
                                         // last state has been SQL_NO_DATA
                                         raw::SQL_FETCH_NEXT,
                                         &mut description_buffer[0] as *mut u8,
                                         max_desc + 1,
                                         &mut desc_length_out as *mut raw::SQLSMALLINT,
                                         &mut attribute_buffer[0] as *mut u8,
                                         max_attr + 1,
                                         &mut attr_length_out as *mut raw::SQLSMALLINT);
            }
            match result {
                raw::SQL_SUCCESS |
                raw::SQL_SUCCESS_WITH_INFO => {
                    description_buffer.resize(desc_length_out as usize, 0);
                    driver_list.push(DriverInfo {
                        description: String::from_utf8(description_buffer)
                            .expect("String returned by Driver Manager should be utf8 encoded"),
                        attributes: Self::parse_attributes(attribute_buffer),
                    })
                }
                raw::SQL_ERROR => return Err(Error {}),
                raw::SQL_NO_DATA => break,
                _ => unreachable!(),
            }
        }
        Ok(driver_list)
    }

    /// Allows access to the raw ODBC handle
    pub unsafe fn raw(&mut self) -> raw::SQLHENV {
        self.handle
    }

    /// Allows setting attributes to Environment
    pub unsafe fn set_attribute(&mut self,
                                attribute: raw::SQLINTEGER,
                                value: raw::SQLPOINTER,
                                length: raw::SQLINTEGER)
                                -> Result<()> {
        match raw::SQLSetEnvAttr(self.handle, attribute, value, length) {
            raw::SQL_SUCCESS => Ok(()),
            raw::SQL_SUCCESS_WITH_INFO => Ok(()),
            _ => Err(Error {}),
        }
    }

    /// Called by drivers to pares list of attributes
    ///
    /// Key value pairs are seperated by `\0`. Key and value are seperated by `=`
    fn parse_attributes(attribute_buffer: Vec<u8>) -> Vec<(String, String)> {
        String::from_utf8(attribute_buffer)
            .expect("String returned by Driver Manager should be utf8 encoded")
            .split('\0')
            .take_while(|kv_str| *kv_str != String::new())
            .map(|kv_str| {
                let mut iter = kv_str.split('=');
                let key = iter.next().unwrap();
                let value = iter.next().unwrap();
                (key.to_string(), value.to_string())
            })
            .collect()
    }
}

impl Drop for Environment {
    fn drop(&mut self) {
        unsafe {
            raw::SQLFreeEnv(self.handle);
        }
    }
}

#[cfg(test)]
mod test {

    use super::*;

    #[test]
    fn parse_attributes() {
        let buffer = "APILevel=2\0ConnectFunctions=YYY\0CPTimeout=60\0DriverODBCVer=03.\
                      50\0FileUsage=0\0SQLLevel=1\0UsageCount=1\0\0"
            .as_bytes()
            .iter()
            .cloned()
            .collect();
        let attributes = Environment::parse_attributes(buffer);
        let expected: Vec<_> = [("APILevel", "2"),
                                ("ConnectFunctions", "YYY"),
                                ("CPTimeout", "60"),
                                ("DriverODBCVer", "03.50"),
                                ("FileUsage", "0"),
                                ("SQLLevel", "1"),
                                ("UsageCount", "1")]
            .iter()
            .map(|&(k, v)| (k.to_string(), v.to_string()))
            .collect();
        assert_eq!(expected, attributes);
    }
}<commit_msg>driver() returns HashMap instead of Vec<commit_after>use super::{Error, Result, raw};
use std::collections::HashMap;
use std;

/// Handle to an ODBC Environment
///
/// Creating an instance of this type is the first thing you do then using ODBC. The environment
/// must outlive all connections created with it
pub struct Environment {
    handle: raw::SQLHENV,
}

/// Struct holding information available on a driver.
///
/// Can be obtained via `Environment::drivers`
#[derive(Clone, Debug)]
pub struct DriverInfo {
    pub description: String,
    pub attributes: HashMap<String, String>,
}

impl Environment {
    /// Allocates a new ODBC Environment
    ///
    /// Declares the Application's ODBC Version to be 3
    pub fn new() -> Result<Environment> {
        unsafe {
            let mut env = std::ptr::null_mut();
            let mut result =
                match raw::SQLAllocHandle(raw::SQL_HANDLE_ENV, std::ptr::null_mut(), &mut env) {
                    raw::SQL_SUCCESS => Environment { handle: env },
                    raw::SQL_SUCCESS_WITH_INFO => Environment { handle: env },
                    // Driver Manager failed to allocate environment
                    raw::SQL_ERROR => return Err(Error {}),
                    _ => unreachable!(),
                };
            // no leak if we return an error here, env handle is already wrapped and would be
            // dropped
            result.set_attribute(raw::SQL_ATTR_ODBC_VERSION,
                               raw::SQL_OV_ODBC3 as *mut std::os::raw::c_void,
                               0)?;

            Ok(result)
        }
    }

    /// Stores all driver description and attributes in a Vec
    pub fn drivers(&self) -> Result<Vec<DriverInfo>> {
        // Iterate twice, once for reading the maximum required buffer lengths so we can read
        // everything without truncating and a second time for actually storing the values
        let string_buf = std::ptr::null_mut();
        let mut desc_length_out: raw::SQLSMALLINT = 0;
        let mut attr_length_out: raw::SQLSMALLINT = 0;
        let mut max_desc = 0;
        let mut max_attr = 0;
        let mut count = 0;
        let mut result;
        unsafe {
            // Although the rather lengthy function call kind of blows the code, let's do the first
            // one using SQL_FETCH_FIRST, so we list all drivers independent from environment state
            result = raw::SQLDrivers(self.handle,
                                     raw::SQL_FETCH_FIRST,
                                     string_buf,
                                     0,
                                     &mut desc_length_out as *mut raw::SQLSMALLINT,
                                     string_buf,
                                     0,
                                     &mut attr_length_out as *mut raw::SQLSMALLINT);
        }
        loop {
            match result {
                raw::SQL_SUCCESS |
                raw::SQL_SUCCESS_WITH_INFO => {
                    count += 1;
                    max_desc = std::cmp::max(max_desc, desc_length_out);
                    max_attr = std::cmp::max(max_attr, attr_length_out);
                }
                raw::SQL_NO_DATA => break,
                raw::SQL_ERROR => return Err(Error {}),
                _ => unreachable!(),
            }
            unsafe {
                result = raw::SQLDrivers(self.handle,
                                         raw::SQL_FETCH_NEXT,
                                         string_buf,
                                         0,
                                         &mut desc_length_out as *mut raw::SQLSMALLINT,
                                         string_buf,
                                         0,
                                         &mut attr_length_out as *mut raw::SQLSMALLINT);
            }
        }

        let mut driver_list = Vec::with_capacity(count);
        loop {
            let mut description_buffer: Vec<_> = (0..(max_desc + 1)).map(|_| 0u8).collect();
            let mut attribute_buffer: Vec<_> = (0..(max_attr + 1)).map(|_| 0u8).collect();
            unsafe {
                result = raw::SQLDrivers(self.handle,
                                         // Its ok to use fetch next here, since we know
                                         // last state has been SQL_NO_DATA
                                         raw::SQL_FETCH_NEXT,
                                         &mut description_buffer[0] as *mut u8,
                                         max_desc + 1,
                                         &mut desc_length_out as *mut raw::SQLSMALLINT,
                                         &mut attribute_buffer[0] as *mut u8,
                                         max_attr + 1,
                                         &mut attr_length_out as *mut raw::SQLSMALLINT);
            }
            match result {
                raw::SQL_SUCCESS |
                raw::SQL_SUCCESS_WITH_INFO => {
                    description_buffer.resize(desc_length_out as usize, 0);
                    driver_list.push(DriverInfo {
                        description: String::from_utf8(description_buffer)
                            .expect("String returned by Driver Manager should be utf8 encoded"),
                        attributes: Self::parse_attributes(attribute_buffer),
                    })
                }
                raw::SQL_ERROR => return Err(Error {}),
                raw::SQL_NO_DATA => break,
                _ => unreachable!(),
            }
        }
        Ok(driver_list)
    }

    /// Allows access to the raw ODBC handle
    pub unsafe fn raw(&mut self) -> raw::SQLHENV {
        self.handle
    }

    /// Allows setting attributes to Environment
    pub unsafe fn set_attribute(&mut self,
                                attribute: raw::SQLINTEGER,
                                value: raw::SQLPOINTER,
                                length: raw::SQLINTEGER)
                                -> Result<()> {
        match raw::SQLSetEnvAttr(self.handle, attribute, value, length) {
            raw::SQL_SUCCESS => Ok(()),
            raw::SQL_SUCCESS_WITH_INFO => Ok(()),
            _ => Err(Error {}),
        }
    }

    /// Called by drivers to pares list of attributes
    ///
    /// Key value pairs are seperated by `\0`. Key and value are seperated by `=`
    fn parse_attributes(attribute_buffer: Vec<u8>) -> HashMap<String, String> {
        String::from_utf8(attribute_buffer)
            .expect("String returned by Driver Manager should be utf8 encoded")
            .split('\0')
            .take_while(|kv_str| *kv_str != String::new())
            .map(|kv_str| {
                let mut iter = kv_str.split('=');
                let key = iter.next().unwrap();
                let value = iter.next().unwrap();
                (key.to_string(), value.to_string())
            })
            .collect()
    }
}

impl Drop for Environment {
    fn drop(&mut self) {
        unsafe {
            raw::SQLFreeEnv(self.handle);
        }
    }
}

#[cfg(test)]
mod test {

    use super::*;

    #[test]
    fn parse_attributes() {
        let buffer = "APILevel=2\0ConnectFunctions=YYY\0CPTimeout=60\0DriverODBCVer=03.\
                      50\0FileUsage=0\0SQLLevel=1\0UsageCount=1\0\0"
            .as_bytes()
            .iter()
            .cloned()
            .collect();
        let attributes = Environment::parse_attributes(buffer);
        assert_eq!(attributes["APILevel"], "2");
        assert_eq!(attributes["ConnectFunctions"], "YYY");
        assert_eq!(attributes["CPTimeout"], "60");
        assert_eq!(attributes["DriverODBCVer"], "03.50");
        assert_eq!(attributes["FileUsage"], "0");
        assert_eq!(attributes["SQLLevel"], "1");
        assert_eq!(attributes["UsageCount"], "1");
    }
}<|endoftext|>


<commit_before><commit_msg>added a bleeding edge feature - const indexing.<commit_after>#![feature(const_indexing)]

// used to have
// const_arr.rs:5:24: 5:30 error: array length constant evaluation error: unsupported constant expr [E0250]
// const_arr.rs:5    const ARR2: [usize; ARR[1]] = [42, 99];
//                                       ^~~~~~
// const_arr.rs:5:24: 5:30 help: run `rustc --explain E0250` to see a detailed explanation

fn main() {
    const ARR: [usize; 5] = [1, 2, 3, 4, 5];
    const ARR2: [usize; ARR[1]] = [42, 99];
}
<|endoftext|>


<commit_before><commit_msg>Upgrade print function<commit_after><|endoftext|>


<commit_before>// Copyright 2012-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.

//! Basic functions for dealing with memory
//!
//! This module contains functions for querying the size and alignment of
//! types, initializing and manipulating memory.

use intrinsics;
use num::Int;
use ptr;

pub use intrinsics::transmute;

/// Returns the size of a type in bytes.
#[inline]
#[stable]
pub fn size_of<T>() -> uint {
    unsafe { intrinsics::size_of::<T>() }
}

/// Returns the size of the type that `_val` points to in bytes.
#[inline]
#[stable]
pub fn size_of_val<T>(_val: &T) -> uint {
    size_of::<T>()
}

/// Deprecated, this function will be removed soon
#[inline]
#[deprecated = "this function will be removed soon"]
pub fn nonzero_size_of<T>() -> uint {
    match size_of::<T>() {
        0 => 1,
        n => n,
    }
}

/// Deprecated, this function will be removed soon
#[inline]
#[deprecated = "this function will be removed soon"]
pub fn nonzero_size_of_val<T>(val: &T) -> uint {
    match size_of_val::<T>(val) {
        0 => 1,
        n => n,
    }
}

/// Returns the ABI-required minimum alignment of a type
///
/// This is the alignment used for struct fields. It may be smaller
/// than the preferred alignment.
#[inline]
#[stable]
pub fn min_align_of<T>() -> uint {
    unsafe { intrinsics::min_align_of::<T>() }
}

/// Returns the ABI-required minimum alignment of the type of the value that
/// `_val` points to
#[inline]
#[stable]
pub fn min_align_of_val<T>(_val: &T) -> uint {
    min_align_of::<T>()
}

/// Returns the alignment in memory for a type.
///
/// This function will return the alignment, in bytes, of a type in memory. If
/// the alignment returned is adhered to, then the type is guaranteed to
/// function properly.
#[inline]
#[stable]
pub fn align_of<T>() -> uint {
    // We use the preferred alignment as the default alignment for a type. This
    // appears to be what clang migrated towards as well:
    //
    // http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20110725/044411.html
    unsafe { intrinsics::pref_align_of::<T>() }
}

/// Returns the alignment of the type of the value that `_val` points to.
///
/// This is similar to `align_of`, but function will properly handle types such
/// as trait objects (in the future), returning the alignment for an arbitrary
/// value at runtime.
#[inline]
#[stable]
pub fn align_of_val<T>(_val: &T) -> uint {
    align_of::<T>()
}

/// Deprecated, this function has been renamed to align_of
#[inline]
#[deprecated = "use mem::align_of instead"]
pub fn pref_align_of<T>() -> uint { align_of::<T>() }

/// Deprecated, this function has been renamed to align_of_val
#[inline]
#[deprecated = "use mem::align_of_val instead"]
pub fn pref_align_of_val<T>(val: &T) -> uint { align_of_val(val) }

/// Create a value initialized to zero.
///
/// This function is similar to allocating space for a a local variable and
/// zeroing it out (an unsafe operation).
///
/// Care must be taken when using this function, if the type `T` has a
/// destructor and the value falls out of scope (due to unwinding or returning)
/// before being initialized, then the destructor will run on zeroed
/// data, likely leading to crashes.
///
/// This is useful for FFI functions sometimes, but should generally be avoided.
#[inline]
#[stable]
pub unsafe fn zeroed<T>() -> T {
    intrinsics::init()
}

/// Deprecated, use zeroed() instead
#[inline]
#[deprecated = "this function has been renamed to zeroed()"]
pub unsafe fn init<T>() -> T { zeroed() }

/// Create an uninitialized value.
///
/// Care must be taken when using this function, if the type `T` has a
/// destructor and the value falls out of scope (due to unwinding or returning)
/// before being initialized, then the destructor will run on uninitialized
/// data, likely leading to crashes.
///
/// This is useful for FFI functions sometimes, but should generally be avoided.
#[inline]
#[stable]
pub unsafe fn uninitialized<T>() -> T {
    intrinsics::uninit()
}

/// Deprecated, use `uninitialized` instead.
#[inline]
#[deprecated = "this function has been renamed to `uninitialized`"]
pub unsafe fn uninit<T>() -> T {
    intrinsics::uninit()
}

/// Unsafely overwrite a memory location with the given value without destroying
/// the old value.
///
/// This operation is unsafe because it does not destroy the previous value
/// contained at the location `dst`. This could leak allocations or resources,
/// so care must be taken to previously deallocate the value at `dst`.
#[inline]
#[deprecated = "use ptr::write"]
pub unsafe fn overwrite<T>(dst: *mut T, src: T) {
    intrinsics::move_val_init(&mut *dst, src)
}

/// Deprecated, use `overwrite` instead
#[inline]
#[deprecated = "use ptr::write"]
pub unsafe fn move_val_init<T>(dst: &mut T, src: T) {
    ptr::write(dst, src)
}

/// Convert an u16 to little endian from the target's endianness.
///
/// On little endian, this is a no-op.  On big endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::to_le` instead"]
pub fn to_le16(x: u16) -> u16 { x.to_le() }

/// Convert an u32 to little endian from the target's endianness.
///
/// On little endian, this is a no-op.  On big endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::to_le` instead"]
pub fn to_le32(x: u32) -> u32 { x.to_le() }

/// Convert an u64 to little endian from the target's endianness.
///
/// On little endian, this is a no-op.  On big endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::to_le` instead"]
pub fn to_le64(x: u64) -> u64 { x.to_le() }

/// Convert an u16 to big endian from the target's endianness.
///
/// On big endian, this is a no-op.  On little endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::to_be` instead"]
pub fn to_be16(x: u16) -> u16 { x.to_be() }

/// Convert an u32 to big endian from the target's endianness.
///
/// On big endian, this is a no-op.  On little endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::to_be` instead"]
pub fn to_be32(x: u32) -> u32 { x.to_be() }

/// Convert an u64 to big endian from the target's endianness.
///
/// On big endian, this is a no-op.  On little endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::to_be` instead"]
pub fn to_be64(x: u64) -> u64 { x.to_be() }

/// Convert an u16 from little endian to the target's endianness.
///
/// On little endian, this is a no-op.  On big endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::from_le` instead"]
pub fn from_le16(x: u16) -> u16 { Int::from_le(x) }

/// Convert an u32 from little endian to the target's endianness.
///
/// On little endian, this is a no-op.  On big endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::from_le` instead"]
pub fn from_le32(x: u32) -> u32 { Int::from_le(x) }

/// Convert an u64 from little endian to the target's endianness.
///
/// On little endian, this is a no-op.  On big endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::from_le` instead"]
pub fn from_le64(x: u64) -> u64 { Int::from_le(x) }

/// Convert an u16 from big endian to the target's endianness.
///
/// On big endian, this is a no-op.  On little endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::from_be` instead"]
pub fn from_be16(x: u16) -> u16 { Int::from_be(x) }

/// Convert an u32 from big endian to the target's endianness.
///
/// On big endian, this is a no-op.  On little endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::from_be` instead"]
pub fn from_be32(x: u32) -> u32 { Int::from_be(x) }

/// Convert an u64 from big endian to the target's endianness.
///
/// On big endian, this is a no-op.  On little endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::from_be` instead"]
pub fn from_be64(x: u64) -> u64 { Int::from_be(x) }

/// Swap the values at two mutable locations of the same type, without
/// deinitialising or copying either one.
#[inline]
#[stable]
pub fn swap<T>(x: &mut T, y: &mut T) {
    unsafe {
        // Give ourselves some scratch space to work with
        let mut t: T = uninitialized();

        // Perform the swap, `&mut` pointers never alias
        ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
        ptr::copy_nonoverlapping_memory(x, &*y, 1);
        ptr::copy_nonoverlapping_memory(y, &t, 1);

        // y and t now point to the same thing, but we need to completely forget `t`
        // because it's no longer relevant.
        forget(t);
    }
}

/// Replace the value at a mutable location with a new one, returning the old
/// value, without deinitialising or copying either one.
///
/// This is primarily used for transferring and swapping ownership of a value
/// in a mutable location. For example, this function allows consumption of
/// one field of a struct by replacing it with another value. The normal approach
/// doesn't always work:
///
/// ```rust,ignore
/// struct Buffer<T> { buf: Vec<T> }
///
/// impl<T> Buffer<T> {
///     fn get_and_reset(&mut self) -> Vec<T> {
///         // error: cannot move out of dereference of `&mut`-pointer
///         let buf = self.buf;
///         self.buf = Vec::new();
///         buf
///     }
/// }
/// ```
///
/// Note that `T` does not necessarily implement `Clone`, so it can't even
/// clone and reset `self.buf`. But `replace` can be used to disassociate
/// the original value of `self.buf` from `self`, allowing it to be returned:
///
/// ```rust
/// # struct Buffer<T> { buf: Vec<T> }
/// impl<T> Buffer<T> {
///     fn get_and_reset(&mut self) -> Vec<T> {
///         use std::mem::replace;
///         replace(&mut self.buf, Vec::new())
///     }
/// }
/// ```
#[inline]
#[stable]
pub fn replace<T>(dest: &mut T, mut src: T) -> T {
    swap(dest, &mut src);
    src
}

/// Disposes of a value.
///
/// This function can be used to destroy any value by allowing `drop` to take
/// ownership of its argument.
///
/// # Example
///
/// ```
/// use std::cell::RefCell;
///
/// let x = RefCell::new(1i);
///
/// let mut mutable_borrow = x.borrow_mut();
/// *mutable_borrow = 1;
/// drop(mutable_borrow); // relinquish the mutable borrow on this slot
///
/// let borrow = x.borrow();
/// println!("{}", *borrow);
/// ```
#[inline]
#[stable]
pub fn drop<T>(_x: T) { }

/// Moves a thing into the void.
///
/// The forget function will take ownership of the provided value but neglect
/// to run any required cleanup or memory management operations on it.
///
/// This function is the unsafe version of the `drop` function because it does
/// not run any destructors.
#[inline]
#[stable]
pub unsafe fn forget<T>(thing: T) { intrinsics::forget(thing) }

/// Interprets `src` as `&U`, and then reads `src` without moving the contained
/// value.
///
/// This function will unsafely assume the pointer `src` is valid for
/// `sizeof(U)` bytes by transmuting `&T` to `&U` and then reading the `&U`. It
/// will also unsafely create a copy of the contained value instead of moving
/// out of `src`.
///
/// It is not a compile-time error if `T` and `U` have different sizes, but it
/// is highly encouraged to only invoke this function where `T` and `U` have the
/// same size. This function triggers undefined behavior if `U` is larger than
/// `T`.
#[inline]
#[stable]
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
    ptr::read(src as *const T as *const U)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
#[unstable = "this function may be removed in the future due to its \
              questionable utility"]
pub unsafe fn copy_lifetime<'a, S, T>(_ptr: &'a S, ptr: &T) -> &'a T {
    transmute(ptr)
}

/// Transforms lifetime of the second mutable pointer to match the first.
#[inline]
#[unstable = "this function may be removed in the future due to its \
              questionable utility"]
pub unsafe fn copy_mut_lifetime<'a, S, T>(_ptr: &'a mut S,
                                          ptr: &mut T) -> &'a mut T {
    transmute(ptr)
}
<commit_msg>libcore: Get rid of useless mem::forget wrapper.<commit_after>// Copyright 2012-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.

//! Basic functions for dealing with memory
//!
//! This module contains functions for querying the size and alignment of
//! types, initializing and manipulating memory.

use intrinsics;
use num::Int;
use ptr;

pub use intrinsics::transmute;

/// Moves a thing into the void.
///
/// The forget function will take ownership of the provided value but neglect
/// to run any required cleanup or memory management operations on it.
///
/// This function is the unsafe version of the `drop` function because it does
/// not run any destructors.
#[stable]
pub use intrinsics::forget;

/// Returns the size of a type in bytes.
#[inline]
#[stable]
pub fn size_of<T>() -> uint {
    unsafe { intrinsics::size_of::<T>() }
}

/// Returns the size of the type that `_val` points to in bytes.
#[inline]
#[stable]
pub fn size_of_val<T>(_val: &T) -> uint {
    size_of::<T>()
}

/// Deprecated, this function will be removed soon
#[inline]
#[deprecated = "this function will be removed soon"]
pub fn nonzero_size_of<T>() -> uint {
    match size_of::<T>() {
        0 => 1,
        n => n,
    }
}

/// Deprecated, this function will be removed soon
#[inline]
#[deprecated = "this function will be removed soon"]
pub fn nonzero_size_of_val<T>(val: &T) -> uint {
    match size_of_val::<T>(val) {
        0 => 1,
        n => n,
    }
}

/// Returns the ABI-required minimum alignment of a type
///
/// This is the alignment used for struct fields. It may be smaller
/// than the preferred alignment.
#[inline]
#[stable]
pub fn min_align_of<T>() -> uint {
    unsafe { intrinsics::min_align_of::<T>() }
}

/// Returns the ABI-required minimum alignment of the type of the value that
/// `_val` points to
#[inline]
#[stable]
pub fn min_align_of_val<T>(_val: &T) -> uint {
    min_align_of::<T>()
}

/// Returns the alignment in memory for a type.
///
/// This function will return the alignment, in bytes, of a type in memory. If
/// the alignment returned is adhered to, then the type is guaranteed to
/// function properly.
#[inline]
#[stable]
pub fn align_of<T>() -> uint {
    // We use the preferred alignment as the default alignment for a type. This
    // appears to be what clang migrated towards as well:
    //
    // http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20110725/044411.html
    unsafe { intrinsics::pref_align_of::<T>() }
}

/// Returns the alignment of the type of the value that `_val` points to.
///
/// This is similar to `align_of`, but function will properly handle types such
/// as trait objects (in the future), returning the alignment for an arbitrary
/// value at runtime.
#[inline]
#[stable]
pub fn align_of_val<T>(_val: &T) -> uint {
    align_of::<T>()
}

/// Deprecated, this function has been renamed to align_of
#[inline]
#[deprecated = "use mem::align_of instead"]
pub fn pref_align_of<T>() -> uint { align_of::<T>() }

/// Deprecated, this function has been renamed to align_of_val
#[inline]
#[deprecated = "use mem::align_of_val instead"]
pub fn pref_align_of_val<T>(val: &T) -> uint { align_of_val(val) }

/// Create a value initialized to zero.
///
/// This function is similar to allocating space for a a local variable and
/// zeroing it out (an unsafe operation).
///
/// Care must be taken when using this function, if the type `T` has a
/// destructor and the value falls out of scope (due to unwinding or returning)
/// before being initialized, then the destructor will run on zeroed
/// data, likely leading to crashes.
///
/// This is useful for FFI functions sometimes, but should generally be avoided.
#[inline]
#[stable]
pub unsafe fn zeroed<T>() -> T {
    intrinsics::init()
}

/// Deprecated, use zeroed() instead
#[inline]
#[deprecated = "this function has been renamed to zeroed()"]
pub unsafe fn init<T>() -> T { zeroed() }

/// Create an uninitialized value.
///
/// Care must be taken when using this function, if the type `T` has a
/// destructor and the value falls out of scope (due to unwinding or returning)
/// before being initialized, then the destructor will run on uninitialized
/// data, likely leading to crashes.
///
/// This is useful for FFI functions sometimes, but should generally be avoided.
#[inline]
#[stable]
pub unsafe fn uninitialized<T>() -> T {
    intrinsics::uninit()
}

/// Deprecated, use `uninitialized` instead.
#[inline]
#[deprecated = "this function has been renamed to `uninitialized`"]
pub unsafe fn uninit<T>() -> T {
    intrinsics::uninit()
}

/// Unsafely overwrite a memory location with the given value without destroying
/// the old value.
///
/// This operation is unsafe because it does not destroy the previous value
/// contained at the location `dst`. This could leak allocations or resources,
/// so care must be taken to previously deallocate the value at `dst`.
#[inline]
#[deprecated = "use ptr::write"]
pub unsafe fn overwrite<T>(dst: *mut T, src: T) {
    intrinsics::move_val_init(&mut *dst, src)
}

/// Deprecated, use `overwrite` instead
#[inline]
#[deprecated = "use ptr::write"]
pub unsafe fn move_val_init<T>(dst: &mut T, src: T) {
    ptr::write(dst, src)
}

/// Convert an u16 to little endian from the target's endianness.
///
/// On little endian, this is a no-op.  On big endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::to_le` instead"]
pub fn to_le16(x: u16) -> u16 { x.to_le() }

/// Convert an u32 to little endian from the target's endianness.
///
/// On little endian, this is a no-op.  On big endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::to_le` instead"]
pub fn to_le32(x: u32) -> u32 { x.to_le() }

/// Convert an u64 to little endian from the target's endianness.
///
/// On little endian, this is a no-op.  On big endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::to_le` instead"]
pub fn to_le64(x: u64) -> u64 { x.to_le() }

/// Convert an u16 to big endian from the target's endianness.
///
/// On big endian, this is a no-op.  On little endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::to_be` instead"]
pub fn to_be16(x: u16) -> u16 { x.to_be() }

/// Convert an u32 to big endian from the target's endianness.
///
/// On big endian, this is a no-op.  On little endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::to_be` instead"]
pub fn to_be32(x: u32) -> u32 { x.to_be() }

/// Convert an u64 to big endian from the target's endianness.
///
/// On big endian, this is a no-op.  On little endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::to_be` instead"]
pub fn to_be64(x: u64) -> u64 { x.to_be() }

/// Convert an u16 from little endian to the target's endianness.
///
/// On little endian, this is a no-op.  On big endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::from_le` instead"]
pub fn from_le16(x: u16) -> u16 { Int::from_le(x) }

/// Convert an u32 from little endian to the target's endianness.
///
/// On little endian, this is a no-op.  On big endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::from_le` instead"]
pub fn from_le32(x: u32) -> u32 { Int::from_le(x) }

/// Convert an u64 from little endian to the target's endianness.
///
/// On little endian, this is a no-op.  On big endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::from_le` instead"]
pub fn from_le64(x: u64) -> u64 { Int::from_le(x) }

/// Convert an u16 from big endian to the target's endianness.
///
/// On big endian, this is a no-op.  On little endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::from_be` instead"]
pub fn from_be16(x: u16) -> u16 { Int::from_be(x) }

/// Convert an u32 from big endian to the target's endianness.
///
/// On big endian, this is a no-op.  On little endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::from_be` instead"]
pub fn from_be32(x: u32) -> u32 { Int::from_be(x) }

/// Convert an u64 from big endian to the target's endianness.
///
/// On big endian, this is a no-op.  On little endian, the bytes are swapped.
#[inline]
#[deprecated = "use `Int::from_be` instead"]
pub fn from_be64(x: u64) -> u64 { Int::from_be(x) }

/// Swap the values at two mutable locations of the same type, without
/// deinitialising or copying either one.
#[inline]
#[stable]
pub fn swap<T>(x: &mut T, y: &mut T) {
    unsafe {
        // Give ourselves some scratch space to work with
        let mut t: T = uninitialized();

        // Perform the swap, `&mut` pointers never alias
        ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
        ptr::copy_nonoverlapping_memory(x, &*y, 1);
        ptr::copy_nonoverlapping_memory(y, &t, 1);

        // y and t now point to the same thing, but we need to completely forget `t`
        // because it's no longer relevant.
        forget(t);
    }
}

/// Replace the value at a mutable location with a new one, returning the old
/// value, without deinitialising or copying either one.
///
/// This is primarily used for transferring and swapping ownership of a value
/// in a mutable location. For example, this function allows consumption of
/// one field of a struct by replacing it with another value. The normal approach
/// doesn't always work:
///
/// ```rust,ignore
/// struct Buffer<T> { buf: Vec<T> }
///
/// impl<T> Buffer<T> {
///     fn get_and_reset(&mut self) -> Vec<T> {
///         // error: cannot move out of dereference of `&mut`-pointer
///         let buf = self.buf;
///         self.buf = Vec::new();
///         buf
///     }
/// }
/// ```
///
/// Note that `T` does not necessarily implement `Clone`, so it can't even
/// clone and reset `self.buf`. But `replace` can be used to disassociate
/// the original value of `self.buf` from `self`, allowing it to be returned:
///
/// ```rust
/// # struct Buffer<T> { buf: Vec<T> }
/// impl<T> Buffer<T> {
///     fn get_and_reset(&mut self) -> Vec<T> {
///         use std::mem::replace;
///         replace(&mut self.buf, Vec::new())
///     }
/// }
/// ```
#[inline]
#[stable]
pub fn replace<T>(dest: &mut T, mut src: T) -> T {
    swap(dest, &mut src);
    src
}

/// Disposes of a value.
///
/// This function can be used to destroy any value by allowing `drop` to take
/// ownership of its argument.
///
/// # Example
///
/// ```
/// use std::cell::RefCell;
///
/// let x = RefCell::new(1i);
///
/// let mut mutable_borrow = x.borrow_mut();
/// *mutable_borrow = 1;
/// drop(mutable_borrow); // relinquish the mutable borrow on this slot
///
/// let borrow = x.borrow();
/// println!("{}", *borrow);
/// ```
#[inline]
#[stable]
pub fn drop<T>(_x: T) { }

/// Interprets `src` as `&U`, and then reads `src` without moving the contained
/// value.
///
/// This function will unsafely assume the pointer `src` is valid for
/// `sizeof(U)` bytes by transmuting `&T` to `&U` and then reading the `&U`. It
/// will also unsafely create a copy of the contained value instead of moving
/// out of `src`.
///
/// It is not a compile-time error if `T` and `U` have different sizes, but it
/// is highly encouraged to only invoke this function where `T` and `U` have the
/// same size. This function triggers undefined behavior if `U` is larger than
/// `T`.
#[inline]
#[stable]
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
    ptr::read(src as *const T as *const U)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
#[unstable = "this function may be removed in the future due to its \
              questionable utility"]
pub unsafe fn copy_lifetime<'a, S, T>(_ptr: &'a S, ptr: &T) -> &'a T {
    transmute(ptr)
}

/// Transforms lifetime of the second mutable pointer to match the first.
#[inline]
#[unstable = "this function may be removed in the future due to its \
              questionable utility"]
pub unsafe fn copy_mut_lifetime<'a, S, T>(_ptr: &'a mut S,
                                          ptr: &mut T) -> &'a mut T {
    transmute(ptr)
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 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.

//! Types dealing with dynamic mutability

use cast;
use clone::Clone;
use cmp::Eq;
use fmt;
use kinds::{marker, Copy};
use ops::{Deref, DerefMut, Drop};
use option::{None, Option, Some};
use ty::Unsafe;

/// A mutable memory location that admits only `Copy` data.
pub struct Cell<T> {
    value: Unsafe<T>,
    noshare: marker::NoShare,
}

impl<T:Copy> Cell<T> {
    /// Creates a new `Cell` containing the given value.
    pub fn new(value: T) -> Cell<T> {
        Cell {
            value: Unsafe::new(value),
            noshare: marker::NoShare,
        }
    }

    /// Returns a copy of the contained value.
    #[inline]
    pub fn get(&self) -> T {
        unsafe{ *self.value.get() }
    }

    /// Sets the contained value.
    #[inline]
    pub fn set(&self, value: T) {
        unsafe {
            *self.value.get() = value;
        }
    }
}

impl<T:Copy> Clone for Cell<T> {
    fn clone(&self) -> Cell<T> {
        Cell::new(self.get())
    }
}

impl<T:Eq + Copy> Eq for Cell<T> {
    fn eq(&self, other: &Cell<T>) -> bool {
        self.get() == other.get()
    }
}

impl<T: Copy + fmt::Show> fmt::Show for Cell<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f.buf, r"Cell \{ value: {} \}", self.get())
    }
}

/// A mutable memory location with dynamically checked borrow rules
pub struct RefCell<T> {
    value: Unsafe<T>,
    borrow: BorrowFlag,
    nocopy: marker::NoCopy,
    noshare: marker::NoShare,
}

// Values [1, MAX-1] represent the number of `Ref` active
// (will not outgrow its range since `uint` is the size of the address space)
type BorrowFlag = uint;
static UNUSED: BorrowFlag = 0;
static WRITING: BorrowFlag = -1;

impl<T> RefCell<T> {
    /// Create a new `RefCell` containing `value`
    pub fn new(value: T) -> RefCell<T> {
        RefCell {
            value: Unsafe::new(value),
            nocopy: marker::NoCopy,
            noshare: marker::NoShare,
            borrow: UNUSED,
        }
    }

    /// Consumes the `RefCell`, returning the wrapped value.
    pub fn unwrap(self) -> T {
        assert!(self.borrow == UNUSED);
        unsafe{self.value.unwrap()}
    }

    unsafe fn as_mut<'a>(&'a self) -> &'a mut RefCell<T> {
        cast::transmute_mut(self)
    }

    /// Attempts to immutably borrow the wrapped value.
    ///
    /// The borrow lasts until the returned `Ref` exits scope. Multiple
    /// immutable borrows can be taken out at the same time.
    ///
    /// Returns `None` if the value is currently mutably borrowed.
    pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
        match self.borrow {
            WRITING => None,
            _ => {
                unsafe { self.as_mut().borrow += 1; }
                Some(Ref { parent: self })
            }
        }
    }

    /// Immutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `Ref` exits scope. Multiple
    /// immutable borrows can be taken out at the same time.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently mutably borrowed.
    pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
        match self.try_borrow() {
            Some(ptr) => ptr,
            None => fail!("RefCell<T> already mutably borrowed")
        }
    }

    /// Mutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `RefMut` exits scope. The value
    /// cannot be borrowed while this borrow is active.
    ///
    /// Returns `None` if the value is currently borrowed.
    pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
        match self.borrow {
            UNUSED => unsafe {
                let mut_self = self.as_mut();
                mut_self.borrow = WRITING;
                Some(RefMut { parent: mut_self })
            },
            _ => None
        }
    }

    /// Mutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `RefMut` exits scope. The value
    /// cannot be borrowed while this borrow is active.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently borrowed.
    pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
        match self.try_borrow_mut() {
            Some(ptr) => ptr,
            None => fail!("RefCell<T> already borrowed")
        }
    }
}

impl<T: Clone> Clone for RefCell<T> {
    fn clone(&self) -> RefCell<T> {
        RefCell::new(self.borrow().clone())
    }
}

impl<T: Eq> Eq for RefCell<T> {
    fn eq(&self, other: &RefCell<T>) -> bool {
        *self.borrow() == *other.borrow()
    }
}

/// Wraps a borrowed reference to a value in a `RefCell` box.
pub struct Ref<'b, T> {
    parent: &'b RefCell<T>
}

#[unsafe_destructor]
impl<'b, T> Drop for Ref<'b, T> {
    fn drop(&mut self) {
        assert!(self.parent.borrow != WRITING && self.parent.borrow != UNUSED);
        unsafe { self.parent.as_mut().borrow -= 1; }
    }
}

impl<'b, T> Deref<T> for Ref<'b, T> {
    #[inline]
    fn deref<'a>(&'a self) -> &'a T {
        unsafe { &*self.parent.value.get() }
    }
}

/// Wraps a mutable borrowed reference to a value in a `RefCell` box.
pub struct RefMut<'b, T> {
    parent: &'b mut RefCell<T>
}

#[unsafe_destructor]
impl<'b, T> Drop for RefMut<'b, T> {
    fn drop(&mut self) {
        assert!(self.parent.borrow == WRITING);
        self.parent.borrow = UNUSED;
    }
}

impl<'b, T> Deref<T> for RefMut<'b, T> {
    #[inline]
    fn deref<'a>(&'a self) -> &'a T {
        unsafe { &*self.parent.value.get() }
    }
}

impl<'b, T> DerefMut<T> for RefMut<'b, T> {
    #[inline]
    fn deref_mut<'a>(&'a mut self) -> &'a mut T {
        unsafe { &mut *self.parent.value.get() }
    }
}

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

    #[test]
    fn smoketest_cell() {
        let x = Cell::new(10);
        assert_eq!(x, Cell::new(10));
        assert_eq!(x.get(), 10);
        x.set(20);
        assert_eq!(x, Cell::new(20));
        assert_eq!(x.get(), 20);

        let y = Cell::new((30, 40));
        assert_eq!(y, Cell::new((30, 40)));
        assert_eq!(y.get(), (30, 40));
    }

    #[test]
    fn cell_has_sensible_show() {
        use str::StrSlice;

        let x = Cell::new("foo bar");
        assert!(format!("{}", x).contains(x.get()));

        x.set("baz qux");
        assert!(format!("{}", x).contains(x.get()));
    }

    #[test]
    fn double_imm_borrow() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        x.borrow();
    }

    #[test]
    fn no_mut_then_imm_borrow() {
        let x = RefCell::new(0);
        let _b1 = x.borrow_mut();
        assert!(x.try_borrow().is_none());
    }

    #[test]
    fn no_imm_then_borrow_mut() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        assert!(x.try_borrow_mut().is_none());
    }

    #[test]
    fn no_double_borrow_mut() {
        let x = RefCell::new(0);
        let _b1 = x.borrow_mut();
        assert!(x.try_borrow_mut().is_none());
    }

    #[test]
    fn imm_release_borrow_mut() {
        let x = RefCell::new(0);
        {
            let _b1 = x.borrow();
        }
        x.borrow_mut();
    }

    #[test]
    fn mut_release_borrow_mut() {
        let x = RefCell::new(0);
        {
            let _b1 = x.borrow_mut();
        }
        x.borrow();
    }

    #[test]
    fn double_borrow_single_release_no_borrow_mut() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        {
            let _b2 = x.borrow();
        }
        assert!(x.try_borrow_mut().is_none());
    }

    #[test]
    #[should_fail]
    fn discard_doesnt_unborrow() {
        let x = RefCell::new(0);
        let _b = x.borrow();
        let _ = _b;
        let _b = x.borrow_mut();
    }
}
<commit_msg>Stop using transmute_mut in RefCell<commit_after>// Copyright 2012-2013 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.

//! Types dealing with dynamic mutability

use clone::Clone;
use cmp::Eq;
use fmt;
use kinds::{marker, Copy};
use ops::{Deref, DerefMut, Drop};
use option::{None, Option, Some};
use ty::Unsafe;

/// A mutable memory location that admits only `Copy` data.
pub struct Cell<T> {
    value: Unsafe<T>,
    noshare: marker::NoShare,
}

impl<T:Copy> Cell<T> {
    /// Creates a new `Cell` containing the given value.
    pub fn new(value: T) -> Cell<T> {
        Cell {
            value: Unsafe::new(value),
            noshare: marker::NoShare,
        }
    }

    /// Returns a copy of the contained value.
    #[inline]
    pub fn get(&self) -> T {
        unsafe{ *self.value.get() }
    }

    /// Sets the contained value.
    #[inline]
    pub fn set(&self, value: T) {
        unsafe {
            *self.value.get() = value;
        }
    }
}

impl<T:Copy> Clone for Cell<T> {
    fn clone(&self) -> Cell<T> {
        Cell::new(self.get())
    }
}

impl<T:Eq + Copy> Eq for Cell<T> {
    fn eq(&self, other: &Cell<T>) -> bool {
        self.get() == other.get()
    }
}

impl<T: Copy + fmt::Show> fmt::Show for Cell<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f.buf, r"Cell \{ value: {} \}", self.get())
    }
}

/// A mutable memory location with dynamically checked borrow rules
pub struct RefCell<T> {
    value: Unsafe<T>,
    borrow: Cell<BorrowFlag>,
    nocopy: marker::NoCopy,
    noshare: marker::NoShare,
}

// Values [1, MAX-1] represent the number of `Ref` active
// (will not outgrow its range since `uint` is the size of the address space)
type BorrowFlag = uint;
static UNUSED: BorrowFlag = 0;
static WRITING: BorrowFlag = -1;

impl<T> RefCell<T> {
    /// Create a new `RefCell` containing `value`
    pub fn new(value: T) -> RefCell<T> {
        RefCell {
            value: Unsafe::new(value),
            borrow: Cell::new(UNUSED),
            nocopy: marker::NoCopy,
            noshare: marker::NoShare,
        }
    }

    /// Consumes the `RefCell`, returning the wrapped value.
    pub fn unwrap(self) -> T {
        assert!(self.borrow.get() == UNUSED);
        unsafe{self.value.unwrap()}
    }

    /// Attempts to immutably borrow the wrapped value.
    ///
    /// The borrow lasts until the returned `Ref` exits scope. Multiple
    /// immutable borrows can be taken out at the same time.
    ///
    /// Returns `None` if the value is currently mutably borrowed.
    pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
        match self.borrow.get() {
            WRITING => None,
            borrow => {
                self.borrow.set(borrow + 1);
                Some(Ref { parent: self })
            }
        }
    }

    /// Immutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `Ref` exits scope. Multiple
    /// immutable borrows can be taken out at the same time.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently mutably borrowed.
    pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
        match self.try_borrow() {
            Some(ptr) => ptr,
            None => fail!("RefCell<T> already mutably borrowed")
        }
    }

    /// Mutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `RefMut` exits scope. The value
    /// cannot be borrowed while this borrow is active.
    ///
    /// Returns `None` if the value is currently borrowed.
    pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
        match self.borrow.get() {
            UNUSED => {
                self.borrow.set(WRITING);
                Some(RefMut { parent: self })
            },
            _ => None
        }
    }

    /// Mutably borrows the wrapped value.
    ///
    /// The borrow lasts until the returned `RefMut` exits scope. The value
    /// cannot be borrowed while this borrow is active.
    ///
    /// # Failure
    ///
    /// Fails if the value is currently borrowed.
    pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
        match self.try_borrow_mut() {
            Some(ptr) => ptr,
            None => fail!("RefCell<T> already borrowed")
        }
    }
}

impl<T: Clone> Clone for RefCell<T> {
    fn clone(&self) -> RefCell<T> {
        RefCell::new(self.borrow().clone())
    }
}

impl<T: Eq> Eq for RefCell<T> {
    fn eq(&self, other: &RefCell<T>) -> bool {
        *self.borrow() == *other.borrow()
    }
}

/// Wraps a borrowed reference to a value in a `RefCell` box.
pub struct Ref<'b, T> {
    parent: &'b RefCell<T>
}

#[unsafe_destructor]
impl<'b, T> Drop for Ref<'b, T> {
    fn drop(&mut self) {
        let borrow = self.parent.borrow.get();
        assert!(borrow != WRITING && borrow != UNUSED);
        self.parent.borrow.set(borrow - 1);
    }
}

impl<'b, T> Deref<T> for Ref<'b, T> {
    #[inline]
    fn deref<'a>(&'a self) -> &'a T {
        unsafe { &*self.parent.value.get() }
    }
}

/// Wraps a mutable borrowed reference to a value in a `RefCell` box.
pub struct RefMut<'b, T> {
    parent: &'b RefCell<T>
}

#[unsafe_destructor]
impl<'b, T> Drop for RefMut<'b, T> {
    fn drop(&mut self) {
        let borrow = self.parent.borrow.get();
        assert!(borrow == WRITING);
        self.parent.borrow.set(UNUSED);
    }
}

impl<'b, T> Deref<T> for RefMut<'b, T> {
    #[inline]
    fn deref<'a>(&'a self) -> &'a T {
        unsafe { &*self.parent.value.get() }
    }
}

impl<'b, T> DerefMut<T> for RefMut<'b, T> {
    #[inline]
    fn deref_mut<'a>(&'a mut self) -> &'a mut T {
        unsafe { &mut *self.parent.value.get() }
    }
}

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

    #[test]
    fn smoketest_cell() {
        let x = Cell::new(10);
        assert_eq!(x, Cell::new(10));
        assert_eq!(x.get(), 10);
        x.set(20);
        assert_eq!(x, Cell::new(20));
        assert_eq!(x.get(), 20);

        let y = Cell::new((30, 40));
        assert_eq!(y, Cell::new((30, 40)));
        assert_eq!(y.get(), (30, 40));
    }

    #[test]
    fn cell_has_sensible_show() {
        use str::StrSlice;

        let x = Cell::new("foo bar");
        assert!(format!("{}", x).contains(x.get()));

        x.set("baz qux");
        assert!(format!("{}", x).contains(x.get()));
    }

    #[test]
    fn double_imm_borrow() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        x.borrow();
    }

    #[test]
    fn no_mut_then_imm_borrow() {
        let x = RefCell::new(0);
        let _b1 = x.borrow_mut();
        assert!(x.try_borrow().is_none());
    }

    #[test]
    fn no_imm_then_borrow_mut() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        assert!(x.try_borrow_mut().is_none());
    }

    #[test]
    fn no_double_borrow_mut() {
        let x = RefCell::new(0);
        let _b1 = x.borrow_mut();
        assert!(x.try_borrow_mut().is_none());
    }

    #[test]
    fn imm_release_borrow_mut() {
        let x = RefCell::new(0);
        {
            let _b1 = x.borrow();
        }
        x.borrow_mut();
    }

    #[test]
    fn mut_release_borrow_mut() {
        let x = RefCell::new(0);
        {
            let _b1 = x.borrow_mut();
        }
        x.borrow();
    }

    #[test]
    fn double_borrow_single_release_no_borrow_mut() {
        let x = RefCell::new(0);
        let _b1 = x.borrow();
        {
            let _b2 = x.borrow();
        }
        assert!(x.try_borrow_mut().is_none());
    }

    #[test]
    #[should_fail]
    fn discard_doesnt_unborrow() {
        let x = RefCell::new(0);
        let _b = x.borrow();
        let _ = _b;
        let _b = x.borrow_mut();
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix: git dir is not worktree dir<commit_after><|endoftext|>


<commit_before><commit_msg>Add rust code for acronym case<commit_after>pub fn abbreviate<S>(name: S) -> String where S: Into<String> {
    let mut next_capital = true;
    let mut prev_lowercase = false;

    name.into()
        .chars()
        .flat_map(|x| match x {
            _ if next_capital => {
                next_capital = false;
                Some(x.to_uppercase().to_string())
            }
            _ if x == '-' => {
                next_capital = true;
                None
            }
            _ if x.is_whitespace() => {
                next_capital = true;
                None
            }
            _ if x.is_uppercase() && !next_capital && prev_lowercase => {
                prev_lowercase = false;
                Some(x.to_uppercase().to_string())
            }
            _ if x.is_lowercase() && !next_capital => {
                prev_lowercase = true;
                None
            }
            _ => None,
        })
        .collect()
}
<|endoftext|>


<commit_before><commit_msg>avoid getting timed out for pleb links<commit_after><|endoftext|>


<commit_before><commit_msg>Add Is::remove_isflag() for removing header flags<commit_after><|endoftext|>


<commit_before><commit_msg>Stop parsing trailing args without need for --<commit_after><|endoftext|>


<commit_before><commit_msg>Remove serializing where result was unused<commit_after><|endoftext|>


<commit_before><commit_msg>Fix: imag-log should report touched entries<commit_after><|endoftext|>


<commit_before><commit_msg>Fix include path for release<commit_after><|endoftext|>