<commit_before>use std::io::Write;

// TODO: should not use wire_format here
use wire_format;

pub struct CodeWriter<'a> {
    writer: &'a mut (Write + 'a),
    indent: String,
}

impl<'a> CodeWriter<'a> {
    pub fn new(writer: &'a mut Write) -> CodeWriter<'a> {
        CodeWriter {
            writer: writer,
            indent: "".to_string(),
        }
    }

    pub fn write_line<S : AsRef<str>>(&mut self, line: S) {
        (if line.as_ref().is_empty() {
            self.writer.write_all("\n".as_bytes())
        } else {
            let s: String = [self.indent.as_ref(), line.as_ref(), "\n"].concat();
            self.writer.write_all(s.as_bytes())
        }).unwrap();
    }

    pub fn write_generated(&mut self) {
        self.write_line("// This file is generated. Do not edit");

        // https://secure.phabricator.com/T784
        self.write_line("// @generated");

        self.write_line("");
        self.comment("https://github.com/Manishearth/rust-clippy/issues/702");
        self.write_line("#![allow(unknown_lints)]");
        self.write_line("#![allow(clippy)]");
        self.write_line("");
        self.write_line("#![cfg_attr(rustfmt, rustfmt_skip)]");
        self.write_line("");
        self.write_line("#![allow(box_pointers)]");
        self.write_line("#![allow(dead_code)]");
        self.write_line("#![allow(non_camel_case_types)]");
        self.write_line("#![allow(non_snake_case)]");
        self.write_line("#![allow(non_upper_case_globals)]");
        self.write_line("#![allow(trivial_casts)]");
        self.write_line("#![allow(unsafe_code)]");
        self.write_line("#![allow(unused_imports)]");
        self.write_line("#![allow(unused_results)]");
    }

    pub fn todo(&mut self, message: &str) {
        self.write_line(format!("panic!(\"TODO: {}\");", message));
    }

    pub fn indented<F>(&mut self, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        cb(&mut CodeWriter {
            writer: self.writer,
            indent: format!("{}    ", self.indent),
        });
    }

    #[allow(dead_code)]
    pub fn commented<F>(&mut self, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        cb(&mut CodeWriter {
            writer: self.writer,
            indent: format!("// {}", self.indent),
        });
    }

    pub fn lazy_static<S1 : AsRef<str>, S2 : AsRef<str>>(&mut self, name: S1, ty: S2) {
        self.stmt_block(format!("static mut {}: ::protobuf::lazy::Lazy<{}> = ::protobuf::lazy::Lazy", name.as_ref(), ty.as_ref()), |w| {
            w.field_entry("lock", "::protobuf::lazy::ONCE_INIT");
            w.field_entry("ptr", format!("0 as *const {}", ty.as_ref()));
        });
    }

    pub fn lazy_static_decl_get<S1 : AsRef<str>, S2 : AsRef<str>, F>(&mut self, name: S1, ty: S2, init: F)
        where F : Fn(&mut CodeWriter)
    {
        self.lazy_static(name.as_ref(), ty);
        self.unsafe_expr(|w| {
            w.write_line(format!("{}.get(|| {{", name.as_ref()));
            w.indented(|w| init(w));
            w.write_line(format!("}})"));
        });
    }

    pub fn block<S1 : AsRef<str>, S2 : AsRef<str>, F>(&mut self, first_line: S1, last_line: S2, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.write_line(first_line.as_ref());
        self.indented(cb);
        self.write_line(last_line.as_ref());
    }

    pub fn expr_block<S : AsRef<str>, F>(&mut self, prefix: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.block(format!("{} {{", prefix.as_ref()), "}", cb);
    }

    pub fn stmt_block<S : AsRef<str>, F>(&mut self, prefix: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.block(format!("{} {{", prefix.as_ref()), "};", cb);
    }

    pub fn unsafe_expr<F>(&mut self, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block("unsafe", cb);
    }

    pub fn impl_self_block<S : AsRef<str>, F>(&mut self, name: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block(format!("impl {}", name.as_ref()), cb);
    }

    pub fn impl_for_block<S1 : AsRef<str>, S2 : AsRef<str>, F>(&mut self, tr: S1, ty: S2, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block(format!("impl {} for {}", tr.as_ref(), ty.as_ref()), cb);
    }

    pub fn unsafe_impl(&mut self, what: &str, for_what: &str) {
        self.write_line(format!("unsafe impl {} for {} {{}}", what, for_what));
    }

    pub fn pub_struct<S : AsRef<str>, F>(&mut self, name: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block(format!("pub struct {}", name.as_ref()), cb);
    }

    pub fn pub_enum<F>(&mut self, name: &str, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block(format!("pub enum {}", name), cb);
    }

    pub fn pub_trait<F>(&mut self, name: &str, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block(format!("pub trait {}", name), cb);
    }

    pub fn field_entry<S1 : AsRef<str>, S2 : AsRef<str>>(&mut self, name: S1, value: S2) {
        self.write_line(format!("{}: {},", name.as_ref(), value.as_ref()));
    }

    pub fn field_decl<S : AsRef<str>>(&mut self, name: S, field_type: &str) {
        self.field_entry(name, field_type);
    }

    pub fn derive(&mut self, derive: &[&str]) {
        let v: Vec<String> = derive.iter().map(|&s| s.to_string()).collect();
        self.write_line(format!("#[derive({})]", v.join(",")));
    }

    pub fn allow(&mut self, what: &[&str]) {
        let v: Vec<String> = what.iter().map(|&s| s.to_string()).collect();
        self.write_line(format!("#[allow({})]", v.join(",")));
    }

    pub fn comment(&mut self, comment: &str) {
        if comment.is_empty() {
            self.write_line("//");
        } else {
            self.write_line(format!("// {}", comment));
        }
    }

    pub fn fn_def(&mut self, sig: &str) {
        self.write_line(format!("fn {};", sig));
    }

    pub fn pub_fn<S : AsRef<str>, F>(&mut self, sig: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block(format!("pub fn {}", sig.as_ref()), cb);
    }

    pub fn def_fn<S : AsRef<str>, F>(&mut self, sig: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block(format!("fn {}", sig.as_ref()), cb);
    }

    pub fn while_block<S : AsRef<str>, F>(&mut self, cond: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block(format!("while {}", cond.as_ref()), cb);
    }

    // if ... { ... }
    pub fn if_stmt<S : AsRef<str>, F>(&mut self, cond: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.stmt_block(format!("if {}", cond.as_ref()), cb);
    }

    // if ... {} else { ... }
    pub fn if_else_stmt<S : AsRef<str>, F>(&mut self, cond: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.write_line(format!("if {} {{", cond.as_ref()));
        self.write_line("} else {");
        self.indented(cb);
        self.write_line("}");
    }

    // if let ... = ... { ... }
    pub fn if_let_stmt<F>(&mut self, decl: &str, expr: &str, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.if_stmt(format!("let {} = {}", decl, expr), cb);
    }

    // if let ... = ... { } else { ... }
    pub fn if_let_else_stmt<F>(&mut self, decl: &str, expr: &str, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.if_else_stmt(format!("let {} = {}", decl, expr), cb);
    }

    pub fn for_stmt<S1 : AsRef<str>, S2 : AsRef<str>, F>(&mut self, over: S1, varn: S2, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.stmt_block(format!("for {} in {}", varn.as_ref(), over.as_ref()), cb)
    }

    pub fn match_block<S : AsRef<str>, F>(&mut self, value: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.stmt_block(format!("match {}", value.as_ref()), cb);
    }

    pub fn match_expr<S : AsRef<str>, F>(&mut self, value: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block(format!("match {}", value.as_ref()), cb);
    }

    pub fn case_block<S : AsRef<str>, F>(&mut self, cond: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.block(format!("{} => {{", cond.as_ref()), "},", cb);
    }

    pub fn case_expr<S1 : AsRef<str>, S2 : AsRef<str>>(&mut self, cond: S1, body: S2) {
        self.write_line(format!("{} => {},", cond.as_ref(), body.as_ref()));
    }

    pub fn error_unexpected_wire_type(&mut self, wire_type: &str) {
        self.write_line(format!(
                "return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type({}));",
                wire_type));
    }

    pub fn assert_wire_type(&mut self, wire_type: wire_format::WireType) {
        self.if_stmt(format!("wire_type != ::protobuf::wire_format::{:?}", wire_type), |w| {
            w.error_unexpected_wire_type("wire_type");
        });
    }
}
<commit_msg>another function for grpc<commit_after>use std::io::Write;

// TODO: should not use wire_format here
use wire_format;

pub struct CodeWriter<'a> {
    writer: &'a mut (Write + 'a),
    indent: String,
}

impl<'a> CodeWriter<'a> {
    pub fn new(writer: &'a mut Write) -> CodeWriter<'a> {
        CodeWriter {
            writer: writer,
            indent: "".to_string(),
        }
    }

    pub fn write_line<S : AsRef<str>>(&mut self, line: S) {
        (if line.as_ref().is_empty() {
            self.writer.write_all("\n".as_bytes())
        } else {
            let s: String = [self.indent.as_ref(), line.as_ref(), "\n"].concat();
            self.writer.write_all(s.as_bytes())
        }).unwrap();
    }

    pub fn write_generated(&mut self) {
        self.write_line("// This file is generated. Do not edit");

        // https://secure.phabricator.com/T784
        self.write_line("// @generated");

        self.write_line("");
        self.comment("https://github.com/Manishearth/rust-clippy/issues/702");
        self.write_line("#![allow(unknown_lints)]");
        self.write_line("#![allow(clippy)]");
        self.write_line("");
        self.write_line("#![cfg_attr(rustfmt, rustfmt_skip)]");
        self.write_line("");
        self.write_line("#![allow(box_pointers)]");
        self.write_line("#![allow(dead_code)]");
        self.write_line("#![allow(non_camel_case_types)]");
        self.write_line("#![allow(non_snake_case)]");
        self.write_line("#![allow(non_upper_case_globals)]");
        self.write_line("#![allow(trivial_casts)]");
        self.write_line("#![allow(unsafe_code)]");
        self.write_line("#![allow(unused_imports)]");
        self.write_line("#![allow(unused_results)]");
    }

    pub fn todo(&mut self, message: &str) {
        self.write_line(format!("panic!(\"TODO: {}\");", message));
    }

    pub fn indented<F>(&mut self, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        cb(&mut CodeWriter {
            writer: self.writer,
            indent: format!("{}    ", self.indent),
        });
    }

    #[allow(dead_code)]
    pub fn commented<F>(&mut self, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        cb(&mut CodeWriter {
            writer: self.writer,
            indent: format!("// {}", self.indent),
        });
    }

    pub fn lazy_static<S1 : AsRef<str>, S2 : AsRef<str>>(&mut self, name: S1, ty: S2) {
        self.stmt_block(format!("static mut {}: ::protobuf::lazy::Lazy<{}> = ::protobuf::lazy::Lazy", name.as_ref(), ty.as_ref()), |w| {
            w.field_entry("lock", "::protobuf::lazy::ONCE_INIT");
            w.field_entry("ptr", format!("0 as *const {}", ty.as_ref()));
        });
    }

    pub fn lazy_static_decl_get<S1 : AsRef<str>, S2 : AsRef<str>, F>(&mut self, name: S1, ty: S2, init: F)
        where F : Fn(&mut CodeWriter)
    {
        self.lazy_static(name.as_ref(), ty);
        self.unsafe_expr(|w| {
            w.write_line(format!("{}.get(|| {{", name.as_ref()));
            w.indented(|w| init(w));
            w.write_line(format!("}})"));
        });
    }

    pub fn block<S1 : AsRef<str>, S2 : AsRef<str>, F>(&mut self, first_line: S1, last_line: S2, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.write_line(first_line.as_ref());
        self.indented(cb);
        self.write_line(last_line.as_ref());
    }

    pub fn expr_block<S : AsRef<str>, F>(&mut self, prefix: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.block(format!("{} {{", prefix.as_ref()), "}", cb);
    }

    pub fn stmt_block<S : AsRef<str>, F>(&mut self, prefix: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.block(format!("{} {{", prefix.as_ref()), "};", cb);
    }

    pub fn unsafe_expr<F>(&mut self, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block("unsafe", cb);
    }

    pub fn impl_self_block<S : AsRef<str>, F>(&mut self, name: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block(format!("impl {}", name.as_ref()), cb);
    }

    pub fn impl_for_block<S1 : AsRef<str>, S2 : AsRef<str>, F>(&mut self, tr: S1, ty: S2, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block(format!("impl {} for {}", tr.as_ref(), ty.as_ref()), cb);
    }

    pub fn unsafe_impl(&mut self, what: &str, for_what: &str) {
        self.write_line(format!("unsafe impl {} for {} {{}}", what, for_what));
    }

    pub fn pub_struct<S : AsRef<str>, F>(&mut self, name: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block(format!("pub struct {}", name.as_ref()), cb);
    }

    pub fn def_struct<S : AsRef<str>, F>(&mut self, name: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block(format!("struct {}", name.as_ref()), cb);
    }

    pub fn pub_enum<F>(&mut self, name: &str, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block(format!("pub enum {}", name), cb);
    }

    pub fn pub_trait<F>(&mut self, name: &str, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block(format!("pub trait {}", name), cb);
    }

    pub fn field_entry<S1 : AsRef<str>, S2 : AsRef<str>>(&mut self, name: S1, value: S2) {
        self.write_line(format!("{}: {},", name.as_ref(), value.as_ref()));
    }

    pub fn field_decl<S : AsRef<str>>(&mut self, name: S, field_type: &str) {
        self.field_entry(name, field_type);
    }

    pub fn derive(&mut self, derive: &[&str]) {
        let v: Vec<String> = derive.iter().map(|&s| s.to_string()).collect();
        self.write_line(format!("#[derive({})]", v.join(",")));
    }

    pub fn allow(&mut self, what: &[&str]) {
        let v: Vec<String> = what.iter().map(|&s| s.to_string()).collect();
        self.write_line(format!("#[allow({})]", v.join(",")));
    }

    pub fn comment(&mut self, comment: &str) {
        if comment.is_empty() {
            self.write_line("//");
        } else {
            self.write_line(format!("// {}", comment));
        }
    }

    pub fn fn_def(&mut self, sig: &str) {
        self.write_line(format!("fn {};", sig));
    }

    pub fn pub_fn<S : AsRef<str>, F>(&mut self, sig: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block(format!("pub fn {}", sig.as_ref()), cb);
    }

    pub fn def_fn<S : AsRef<str>, F>(&mut self, sig: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block(format!("fn {}", sig.as_ref()), cb);
    }

    pub fn while_block<S : AsRef<str>, F>(&mut self, cond: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block(format!("while {}", cond.as_ref()), cb);
    }

    // if ... { ... }
    pub fn if_stmt<S : AsRef<str>, F>(&mut self, cond: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.stmt_block(format!("if {}", cond.as_ref()), cb);
    }

    // if ... {} else { ... }
    pub fn if_else_stmt<S : AsRef<str>, F>(&mut self, cond: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.write_line(format!("if {} {{", cond.as_ref()));
        self.write_line("} else {");
        self.indented(cb);
        self.write_line("}");
    }

    // if let ... = ... { ... }
    pub fn if_let_stmt<F>(&mut self, decl: &str, expr: &str, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.if_stmt(format!("let {} = {}", decl, expr), cb);
    }

    // if let ... = ... { } else { ... }
    pub fn if_let_else_stmt<F>(&mut self, decl: &str, expr: &str, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.if_else_stmt(format!("let {} = {}", decl, expr), cb);
    }

    pub fn for_stmt<S1 : AsRef<str>, S2 : AsRef<str>, F>(&mut self, over: S1, varn: S2, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.stmt_block(format!("for {} in {}", varn.as_ref(), over.as_ref()), cb)
    }

    pub fn match_block<S : AsRef<str>, F>(&mut self, value: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.stmt_block(format!("match {}", value.as_ref()), cb);
    }

    pub fn match_expr<S : AsRef<str>, F>(&mut self, value: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.expr_block(format!("match {}", value.as_ref()), cb);
    }

    pub fn case_block<S : AsRef<str>, F>(&mut self, cond: S, cb: F)
        where F : Fn(&mut CodeWriter)
    {
        self.block(format!("{} => {{", cond.as_ref()), "},", cb);
    }

    pub fn case_expr<S1 : AsRef<str>, S2 : AsRef<str>>(&mut self, cond: S1, body: S2) {
        self.write_line(format!("{} => {},", cond.as_ref(), body.as_ref()));
    }

    pub fn error_unexpected_wire_type(&mut self, wire_type: &str) {
        self.write_line(format!(
                "return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type({}));",
                wire_type));
    }

    pub fn assert_wire_type(&mut self, wire_type: wire_format::WireType) {
        self.if_stmt(format!("wire_type != ::protobuf::wire_format::{:?}", wire_type), |w| {
            w.error_unexpected_wire_type("wire_type");
        });
    }
}
<|endoftext|>


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

//! The `Default` trait for types which may have meaningful default values.

#![stable(feature = "rust1", since = "1.0.0")]

/// A trait for giving a type a useful default value.
///
/// Sometimes, you want to fall back to some kind of default value, and
/// don't particularly care what it is. This comes up often with `struct`s
/// that define a set of options:
///
/// ```
/// # #[allow(dead_code)]
/// struct SomeOptions {
///     foo: i32,
///     bar: f32,
/// }
/// ```
///
/// How can we define some default values? You can use `Default`:
///
/// ```
/// # #[allow(dead_code)]
/// #[derive(Default)]
/// struct SomeOptions {
///     foo: i32,
///     bar: f32,
/// }
///
/// fn main() {
///     let options: SomeOptions = Default::default();
/// }
/// ```
///
/// Now, you get all of the default values. Rust implements `Default` for various primitives types.
///
/// If you want to override a particular option, but still retain the other defaults:
///
/// ```
/// # #[allow(dead_code)]
/// # #[derive(Default)]
/// # struct SomeOptions {
/// #     foo: i32,
/// #     bar: f32,
/// # }
/// fn main() {
///     let options = SomeOptions { foo: 42, ..Default::default() };
/// }
/// ```
///
/// ## Derivable
///
/// This trait can be used with `#[derive]` if all of the type's fields implement
/// `Default`. When `derive`d, it will use the default value for each field's type.
///
/// ## How can I implement `Default`?
///
/// Provide an implementation for the `default()` method that returns the value of
/// your type that should be the default:
///
/// ```
/// # #![allow(dead_code)]
/// enum Kind {
///     A,
///     B,
///     C,
/// }
///
/// impl Default for Kind {
///     fn default() -> Kind { Kind::A }
/// }
/// ```
///
/// # Examples
///
/// ```
/// # #[allow(dead_code)]
/// #[derive(Default)]
/// struct SomeOptions {
///     foo: i32,
///     bar: f32,
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Default: Sized {
    /// Returns the "default value" for a type.
    ///
    /// Default values are often some kind of initial value, identity value, or anything else that
    /// may make sense as a default.
    ///
    /// # Examples
    ///
    /// Using built-in default values:
    ///
    /// ```
    /// let i: i8 = Default::default();
    /// let (x, y): (Option<String>, f64) = Default::default();
    /// let (a, b, (c, d)): (i32, u32, (bool, bool)) = Default::default();
    /// ```
    ///
    /// Making your own:
    ///
    /// ```
    /// # #[allow(dead_code)]
    /// enum Kind {
    ///     A,
    ///     B,
    ///     C,
    /// }
    ///
    /// impl Default for Kind {
    ///     fn default() -> Kind { Kind::A }
    /// }
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn default() -> Self;
}

macro_rules! default_impl {
    ($t:ty, $v:expr) => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl Default for $t {
            #[inline]
            fn default() -> $t { $v }
        }
    }
}

default_impl! { (), () }
default_impl! { bool, false }
default_impl! { char, '\x00' }

default_impl! { usize, 0 }
default_impl! { u8, 0 }
default_impl! { u16, 0 }
default_impl! { u32, 0 }
default_impl! { u64, 0 }
default_impl! { u128, 0 }

default_impl! { isize, 0 }
default_impl! { i8, 0 }
default_impl! { i16, 0 }
default_impl! { i32, 0 }
default_impl! { i64, 0 }
default_impl! { i128, 0 }

default_impl! { f32, 0.0f32 }
default_impl! { f64, 0.0f64 }
<commit_msg>Document default values for primitive types<commit_after>// Copyright 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.

//! The `Default` trait for types which may have meaningful default values.

#![stable(feature = "rust1", since = "1.0.0")]

/// A trait for giving a type a useful default value.
///
/// Sometimes, you want to fall back to some kind of default value, and
/// don't particularly care what it is. This comes up often with `struct`s
/// that define a set of options:
///
/// ```
/// # #[allow(dead_code)]
/// struct SomeOptions {
///     foo: i32,
///     bar: f32,
/// }
/// ```
///
/// How can we define some default values? You can use `Default`:
///
/// ```
/// # #[allow(dead_code)]
/// #[derive(Default)]
/// struct SomeOptions {
///     foo: i32,
///     bar: f32,
/// }
///
/// fn main() {
///     let options: SomeOptions = Default::default();
/// }
/// ```
///
/// Now, you get all of the default values. Rust implements `Default` for various primitives types.
///
/// If you want to override a particular option, but still retain the other defaults:
///
/// ```
/// # #[allow(dead_code)]
/// # #[derive(Default)]
/// # struct SomeOptions {
/// #     foo: i32,
/// #     bar: f32,
/// # }
/// fn main() {
///     let options = SomeOptions { foo: 42, ..Default::default() };
/// }
/// ```
///
/// ## Derivable
///
/// This trait can be used with `#[derive]` if all of the type's fields implement
/// `Default`. When `derive`d, it will use the default value for each field's type.
///
/// ## How can I implement `Default`?
///
/// Provide an implementation for the `default()` method that returns the value of
/// your type that should be the default:
///
/// ```
/// # #![allow(dead_code)]
/// enum Kind {
///     A,
///     B,
///     C,
/// }
///
/// impl Default for Kind {
///     fn default() -> Kind { Kind::A }
/// }
/// ```
///
/// # Examples
///
/// ```
/// # #[allow(dead_code)]
/// #[derive(Default)]
/// struct SomeOptions {
///     foo: i32,
///     bar: f32,
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Default: Sized {
    /// Returns the "default value" for a type.
    ///
    /// Default values are often some kind of initial value, identity value, or anything else that
    /// may make sense as a default.
    ///
    /// # Examples
    ///
    /// Using built-in default values:
    ///
    /// ```
    /// let i: i8 = Default::default();
    /// let (x, y): (Option<String>, f64) = Default::default();
    /// let (a, b, (c, d)): (i32, u32, (bool, bool)) = Default::default();
    /// ```
    ///
    /// Making your own:
    ///
    /// ```
    /// # #[allow(dead_code)]
    /// enum Kind {
    ///     A,
    ///     B,
    ///     C,
    /// }
    ///
    /// impl Default for Kind {
    ///     fn default() -> Kind { Kind::A }
    /// }
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn default() -> Self;
}

macro_rules! default_impl {
    ($t:ty, $v:expr, $doc:expr) => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl Default for $t {
            #[inline]
            #[doc = $doc]
            fn default() -> $t { $v }
        }
    }
}

default_impl! { (), (), "Defaults to `()`" }
default_impl! { bool, false, "Defaults to `false`" }
default_impl! { char, '\x00', "Defaults to `\\x00`" }

default_impl! { usize, 0, "Defaults to `0`" }
default_impl! { u8, 0, "Defaults to `0`" }
default_impl! { u16, 0, "Defaults to `0`" }
default_impl! { u32, 0, "Defaults to `0`" }
default_impl! { u64, 0, "Defaults to `0`" }
default_impl! { u128, 0, "Defaults to `0`" }

default_impl! { isize, 0, "Defaults to `0`" }
default_impl! { i8, 0, "Defaults to `0`" }
default_impl! { i16, 0, "Defaults to `0`" }
default_impl! { i32, 0, "Defaults to `0`" }
default_impl! { i64, 0, "Defaults to `0`" }
default_impl! { i128, 0, "Defaults to `0`" }

default_impl! { f32, 0.0f32, "Defaults to `0.0`" }
default_impl! { f64, 0.0f64, "Defaults to `0.0`" }
<|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.
pub use self::MaybeTyped::*;

use rustc_lint;
use rustc_driver::{driver, target_features, abort_on_err};
use rustc::dep_graph::DepGraph;
use rustc::session::{self, config};
use rustc::hir::def_id::DefId;
use rustc::middle::privacy::AccessLevels;
use rustc::ty::{self, TyCtxt};
use rustc::hir::map as hir_map;
use rustc::lint;
use rustc_trans::back::link;
use rustc_resolve as resolve;
use rustc_metadata::cstore::CStore;
use rustc_metadata::creader::read_local_crates;

use syntax::{ast, codemap, errors};
use syntax::errors::emitter::ColorConfig;
use syntax::feature_gate::UnstableFeatures;
use syntax::parse::token;

use std::cell::{RefCell, Cell};
use std::collections::{HashMap, HashSet};
use std::rc::Rc;

use visit_ast::RustdocVisitor;
use clean;
use clean::Clean;
use html::render::RenderInfo;

pub use rustc::session::config::Input;
pub use rustc::session::search_paths::SearchPaths;

/// Are we generating documentation (`Typed`) or tests (`NotTyped`)?
pub enum MaybeTyped<'a, 'tcx: 'a> {
    Typed(TyCtxt<'a, 'tcx, 'tcx>),
    NotTyped(&'a session::Session)
}

pub type Externs = HashMap<String, Vec<String>>;
pub type ExternalPaths = HashMap<DefId, (Vec<String>, clean::TypeKind)>;

pub struct DocContext<'a, 'tcx: 'a> {
    pub map: &'a hir_map::Map<'tcx>,
    pub maybe_typed: MaybeTyped<'a, 'tcx>,
    pub input: Input,
    pub populated_crate_impls: RefCell<HashSet<ast::CrateNum>>,
    pub deref_trait_did: Cell<Option<DefId>>,
    // Note that external items for which `doc(hidden)` applies to are shown as
    // non-reachable while local items aren't. This is because we're reusing
    // the access levels from crateanalysis.
    /// Later on moved into `clean::Crate`
    pub access_levels: RefCell<AccessLevels<DefId>>,
    /// Later on moved into `html::render::CACHE_KEY`
    pub renderinfo: RefCell<RenderInfo>,
    /// Later on moved through `clean::Crate` into `html::render::CACHE_KEY`
    pub external_traits: RefCell<HashMap<DefId, clean::Trait>>,
}

impl<'b, 'tcx> DocContext<'b, 'tcx> {
    pub fn sess<'a>(&'a self) -> &'a session::Session {
        match self.maybe_typed {
            Typed(tcx) => &tcx.sess,
            NotTyped(ref sess) => sess
        }
    }

    pub fn tcx_opt<'a>(&'a self) -> Option<TyCtxt<'a, 'tcx, 'tcx>> {
        match self.maybe_typed {
            Typed(tcx) => Some(tcx),
            NotTyped(_) => None
        }
    }

    pub fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
        let tcx_opt = self.tcx_opt();
        tcx_opt.expect("tcx not present")
    }
}

pub trait DocAccessLevels {
    fn is_doc_reachable(&self, DefId) -> bool;
}

impl DocAccessLevels for AccessLevels<DefId> {
    fn is_doc_reachable(&self, did: DefId) -> bool {
        self.is_public(did)
    }
}

pub fn run_core(search_paths: SearchPaths,
                cfgs: Vec<String>,
                externs: Externs,
                input: Input,
                triple: Option<String>) -> (clean::Crate, RenderInfo)
{
    // Parse, resolve, and typecheck the given crate.

    let cpath = match input {
        Input::File(ref p) => Some(p.clone()),
        _ => None
    };

    let warning_lint = lint::builtin::WARNINGS.name_lower();

    let sessopts = config::Options {
        maybe_sysroot: None,
        search_paths: search_paths,
        crate_types: vec!(config::CrateTypeRlib),
        lint_opts: vec!((warning_lint, lint::Allow)),
        lint_cap: Some(lint::Allow),
        externs: externs,
        target_triple: triple.unwrap_or(config::host_triple().to_string()),
        cfg: config::parse_cfgspecs(cfgs),
        // Ensure that rustdoc works even if rustc is feature-staged
        unstable_features: UnstableFeatures::Allow,
        ..config::basic_options().clone()
    };

    let codemap = Rc::new(codemap::CodeMap::new());
    let diagnostic_handler = errors::Handler::with_tty_emitter(ColorConfig::Auto,
                                                               None,
                                                               true,
                                                               false,
                                                               codemap.clone());

    let dep_graph = DepGraph::new(false);
    let _ignore = dep_graph.in_ignore();
    let cstore = Rc::new(CStore::new(&dep_graph, token::get_ident_interner()));
    let sess = session::build_session_(sessopts, &dep_graph, cpath, diagnostic_handler,
                                       codemap, cstore.clone());
    rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));

    let mut cfg = config::build_configuration(&sess);
    target_features::add_configuration(&mut cfg, &sess);

    let krate = panictry!(driver::phase_1_parse_input(&sess, cfg, &input));

    let name = link::find_crate_name(Some(&sess), &krate.attrs,
                                     &input);

    let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate, &name, None)
                    .expect("phase_2_configure_and_expand aborted in rustdoc!");

    let krate = driver::assign_node_ids(&sess, krate);

    let mut defs = hir_map::collect_definitions(&krate);
    read_local_crates(&sess, &cstore, &defs, &krate, &name, &dep_graph);

    // Lower ast -> hir and resolve.
    let (analysis, resolutions, mut hir_forest) = {
        driver::lower_and_resolve(&sess, &name, &mut defs, &krate,
                                  &sess.dep_graph, resolve::MakeGlobMap::No)
    };

    let arenas = ty::CtxtArenas::new();
    let hir_map = hir_map::map_crate(&mut hir_forest, defs);

    abort_on_err(driver::phase_3_run_analysis_passes(&sess,
                                                     hir_map,
                                                     analysis,
                                                     resolutions,
                                                     &arenas,
                                                     &name,
                                                     |tcx, _, analysis, result| {
        // Return if the driver hit an err (in `result`)
        if let Err(_) = result {
            return None
        }

        let ty::CrateAnalysis { access_levels, .. } = analysis;

        // Convert from a NodeId set to a DefId set since we don't always have easy access
        // to the map from defid -> nodeid
        let access_levels = AccessLevels {
            map: access_levels.map.into_iter()
                                  .map(|(k, v)| (tcx.map.local_def_id(k), v))
                                  .collect()
        };

        let ctxt = DocContext {
            map: &tcx.map,
            maybe_typed: Typed(tcx),
            input: input,
            populated_crate_impls: RefCell::new(HashSet::new()),
            deref_trait_did: Cell::new(None),
            access_levels: RefCell::new(access_levels),
            external_traits: RefCell::new(HashMap::new()),
            renderinfo: RefCell::new(Default::default()),
        };
        debug!("crate: {:?}", ctxt.map.krate());

        let krate = {
            let mut v = RustdocVisitor::new(&ctxt);
            v.visit(ctxt.map.krate());
            v.clean(&ctxt)
        };

        Some((krate, ctxt.renderinfo.into_inner()))
    }), &sess).unwrap()
}
<commit_msg>Auto merge of #33702 - crimsun:pr33678, r=alexcrichton<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.
pub use self::MaybeTyped::*;

use rustc_lint;
use rustc_driver::{driver, target_features, abort_on_err};
use rustc::dep_graph::DepGraph;
use rustc::session::{self, config};
use rustc::hir::def_id::DefId;
use rustc::middle::privacy::AccessLevels;
use rustc::ty::{self, TyCtxt};
use rustc::hir::map as hir_map;
use rustc::lint;
use rustc_trans::back::link;
use rustc_resolve as resolve;
use rustc_metadata::cstore::CStore;
use rustc_metadata::creader::read_local_crates;

use syntax::{ast, codemap, errors};
use syntax::errors::emitter::ColorConfig;
use syntax::feature_gate::UnstableFeatures;
use syntax::parse::token;

use std::cell::{RefCell, Cell};
use std::collections::{HashMap, HashSet};
use std::rc::Rc;

use visit_ast::RustdocVisitor;
use clean;
use clean::Clean;
use html::render::RenderInfo;

pub use rustc::session::config::Input;
pub use rustc::session::search_paths::SearchPaths;

/// Are we generating documentation (`Typed`) or tests (`NotTyped`)?
pub enum MaybeTyped<'a, 'tcx: 'a> {
    Typed(TyCtxt<'a, 'tcx, 'tcx>),
    NotTyped(&'a session::Session)
}

pub type Externs = HashMap<String, Vec<String>>;
pub type ExternalPaths = HashMap<DefId, (Vec<String>, clean::TypeKind)>;

pub struct DocContext<'a, 'tcx: 'a> {
    pub map: &'a hir_map::Map<'tcx>,
    pub maybe_typed: MaybeTyped<'a, 'tcx>,
    pub input: Input,
    pub populated_crate_impls: RefCell<HashSet<ast::CrateNum>>,
    pub deref_trait_did: Cell<Option<DefId>>,
    // Note that external items for which `doc(hidden)` applies to are shown as
    // non-reachable while local items aren't. This is because we're reusing
    // the access levels from crateanalysis.
    /// Later on moved into `clean::Crate`
    pub access_levels: RefCell<AccessLevels<DefId>>,
    /// Later on moved into `html::render::CACHE_KEY`
    pub renderinfo: RefCell<RenderInfo>,
    /// Later on moved through `clean::Crate` into `html::render::CACHE_KEY`
    pub external_traits: RefCell<HashMap<DefId, clean::Trait>>,
}

impl<'b, 'tcx> DocContext<'b, 'tcx> {
    pub fn sess<'a>(&'a self) -> &'a session::Session {
        match self.maybe_typed {
            Typed(tcx) => &tcx.sess,
            NotTyped(ref sess) => sess
        }
    }

    pub fn tcx_opt<'a>(&'a self) -> Option<TyCtxt<'a, 'tcx, 'tcx>> {
        match self.maybe_typed {
            Typed(tcx) => Some(tcx),
            NotTyped(_) => None
        }
    }

    pub fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
        let tcx_opt = self.tcx_opt();
        tcx_opt.expect("tcx not present")
    }
}

pub trait DocAccessLevels {
    fn is_doc_reachable(&self, DefId) -> bool;
}

impl DocAccessLevels for AccessLevels<DefId> {
    fn is_doc_reachable(&self, did: DefId) -> bool {
        self.is_public(did)
    }
}

pub fn run_core(search_paths: SearchPaths,
                cfgs: Vec<String>,
                externs: Externs,
                input: Input,
                triple: Option<String>) -> (clean::Crate, RenderInfo)
{
    // Parse, resolve, and typecheck the given crate.

    let cpath = match input {
        Input::File(ref p) => Some(p.clone()),
        _ => None
    };

    let warning_lint = lint::builtin::WARNINGS.name_lower();

    let sessopts = config::Options {
        maybe_sysroot: None,
        search_paths: search_paths,
        crate_types: vec!(config::CrateTypeRlib),
        lint_opts: vec!((warning_lint, lint::Allow)),
        lint_cap: Some(lint::Allow),
        externs: externs,
        target_triple: triple.unwrap_or(config::host_triple().to_string()),
        cfg: config::parse_cfgspecs(cfgs),
        // Ensure that rustdoc works even if rustc is feature-staged
        unstable_features: UnstableFeatures::Allow,
        ..config::basic_options().clone()
    };

    let codemap = Rc::new(codemap::CodeMap::new());
    let diagnostic_handler = errors::Handler::with_tty_emitter(ColorConfig::Auto,
                                                               None,
                                                               true,
                                                               false,
                                                               codemap.clone());

    let dep_graph = DepGraph::new(false);
    let _ignore = dep_graph.in_ignore();
    let cstore = Rc::new(CStore::new(&dep_graph, token::get_ident_interner()));
    let sess = session::build_session_(sessopts, &dep_graph, cpath, diagnostic_handler,
                                       codemap, cstore.clone());
    rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));

    let mut cfg = config::build_configuration(&sess);
    target_features::add_configuration(&mut cfg, &sess);

    let krate = panictry!(driver::phase_1_parse_input(&sess, cfg, &input));

    let name = link::find_crate_name(Some(&sess), &krate.attrs,
                                     &input);

    let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate, &name, None)
                    .expect("phase_2_configure_and_expand aborted in rustdoc!");

    let krate = driver::assign_node_ids(&sess, krate);

    let mut defs = hir_map::collect_definitions(&krate);
    read_local_crates(&sess, &cstore, &defs, &krate, &name, &dep_graph);

    // Lower ast -> hir and resolve.
    let (analysis, resolutions, mut hir_forest) = {
        driver::lower_and_resolve(&sess, &name, &mut defs, &krate,
                                  &sess.dep_graph, resolve::MakeGlobMap::No)
    };

    let arenas = ty::CtxtArenas::new();
    let hir_map = hir_map::map_crate(&mut hir_forest, defs);

    abort_on_err(driver::phase_3_run_analysis_passes(&sess,
                                                     hir_map,
                                                     analysis,
                                                     resolutions,
                                                     &arenas,
                                                     &name,
                                                     |tcx, _, analysis, result| {
        if let Err(_) = result {
            sess.fatal("Compilation failed, aborting rustdoc");
        }

        let ty::CrateAnalysis { access_levels, .. } = analysis;

        // Convert from a NodeId set to a DefId set since we don't always have easy access
        // to the map from defid -> nodeid
        let access_levels = AccessLevels {
            map: access_levels.map.into_iter()
                                  .map(|(k, v)| (tcx.map.local_def_id(k), v))
                                  .collect()
        };

        let ctxt = DocContext {
            map: &tcx.map,
            maybe_typed: Typed(tcx),
            input: input,
            populated_crate_impls: RefCell::new(HashSet::new()),
            deref_trait_did: Cell::new(None),
            access_levels: RefCell::new(access_levels),
            external_traits: RefCell::new(HashMap::new()),
            renderinfo: RefCell::new(Default::default()),
        };
        debug!("crate: {:?}", ctxt.map.krate());

        let krate = {
            let mut v = RustdocVisitor::new(&ctxt);
            v.visit(ctxt.map.krate());
            v.clean(&ctxt)
        };

        (krate, ctxt.renderinfo.into_inner())
    }), &sess)
}
<|endoftext|>


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

//! The `bitflags!` macro generates a `struct` that holds a set of C-style
//! bitmask flags. It is useful for creating typesafe wrappers for C APIs.
//!
//! The flags should only be defined for integer types, otherwise unexpected
//! type errors may occur at compile time.
//!
//! # Example
//!
//! ~~~rust
//! bitflags!(
//!     flags Flags: u32 {
//!         static FlagA       = 0x00000001,
//!         static FlagB       = 0x00000010,
//!         static FlagC       = 0x00000100,
//!         static FlagABC     = FlagA.bits
//!                            | FlagB.bits
//!                            | FlagC.bits,
//!     }
//! )
//!
//! fn main() {
//!     let e1 = FlagA | FlagC;
//!     let e2 = FlagB | FlagC;
//!     assert!((e1 | e2) == FlagABC);   // union
//!     assert!((e1 & e2) == FlagC);     // intersection
//!     assert!((e1 - e2) == FlagA);     // set difference
//!     assert!(!e2 == FlagA);           // set complement
//! }
//! ~~~
//!
//! The generated `struct`s can also be extended with type and trait implementations:
//!
//! ~~~rust
//! use std::fmt;
//!
//! bitflags!(
//!     flags Flags: u32 {
//!         static FlagA   = 0x00000001,
//!         static FlagB   = 0x00000010,
//!     }
//! )
//!
//! impl Flags {
//!     pub fn clear(&mut self) {
//!         self.bits = 0;  // The `bits` field can be accessed from within the
//!                         // same module where the `bitflags!` macro was invoked.
//!     }
//! }
//!
//! impl fmt::Show for Flags {
//!     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
//!         write!(f, "hi!")
//!     }
//! }
//!
//! fn main() {
//!     let mut flags = FlagA | FlagB;
//!     flags.clear();
//!     assert!(flags.is_empty());
//!     assert_eq!(format!("{}", flags).as_slice(), "hi!");
//! }
//! ~~~
//!
//! # Attributes
//!
//! Attributes can be attached to the generated `struct` by placing them
//! before the `flags` keyword.
//!
//! # Derived traits
//!
//! The `PartialEq` and `Clone` traits are automatically derived for the `struct` using
//! the `deriving` attribute. Additional traits can be derived by providing an
//! explicit `deriving` attribute on `flags`.
//!
//! # Operators
//!
//! The following operator traits are implemented for the generated `struct`:
//!
//! - `BitOr`: union
//! - `BitAnd`: intersection
//! - `Sub`: set difference
//! - `Not`: set complement
//!
//! # Methods
//!
//! The following methods are defined for the generated `struct`:
//!
//! - `empty`: an empty set of flags
//! - `all`: the set of all flags
//! - `bits`: the raw value of the flags currently stored
//! - `is_empty`: `true` if no flags are currently stored
//! - `is_all`: `true` if all flags are currently set
//! - `intersects`: `true` if there are flags common to both `self` and `other`
//! - `contains`: `true` all of the flags in `other` are contained within `self`
//! - `insert`: inserts the specified flags in-place
//! - `remove`: removes the specified flags in-place

#![experimental]
#![macro_escape]

#[macro_export]
macro_rules! bitflags(
    ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
        $($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+
    }) => (
        #[deriving(PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
        $(#[$attr])*
        pub struct $BitFlags {
            bits: $T,
        }

        $($(#[$Flag_attr])* pub static $Flag: $BitFlags = $BitFlags { bits: $value };)+

        impl $BitFlags {
            /// Returns an empty set of flags.
            pub fn empty() -> $BitFlags {
                $BitFlags { bits: 0 }
            }

            /// Returns the set containing all flags.
            pub fn all() -> $BitFlags {
                $BitFlags { bits: $($value)|+ }
            }

            /// Returns the raw value of the flags currently stored.
            pub fn bits(&self) -> $T {
                self.bits
            }

            /// Convert from underlying bit representation, unless that
            /// representation contains bits that do not correspond to a flag.
            pub fn from_bits(bits: $T) -> ::std::option::Option<$BitFlags> {
                if (bits & !$BitFlags::all().bits()) != 0 {
                    ::std::option::None
                } else {
                    ::std::option::Some($BitFlags { bits: bits })
                }
            }

            /// Convert from underlying bit representation, dropping any bits
            /// that do not correspond to flags.
            pub fn from_bits_truncate(bits: $T) -> $BitFlags {
                $BitFlags { bits: bits } & $BitFlags::all()
            }

            /// Returns `true` if no flags are currently stored.
            pub fn is_empty(&self) -> bool {
                *self == $BitFlags::empty()
            }

            /// Returns `true` if all flags are currently set.
            pub fn is_all(&self) -> bool {
                *self == $BitFlags::all()
            }

            /// Returns `true` if there are flags common to both `self` and `other`.
            pub fn intersects(&self, other: $BitFlags) -> bool {
                !(self & other).is_empty()
            }

            /// Returns `true` all of the flags in `other` are contained within `self`.
            pub fn contains(&self, other: $BitFlags) -> bool {
                (self & other) == other
            }

            /// Inserts the specified flags in-place.
            pub fn insert(&mut self, other: $BitFlags) {
                self.bits |= other.bits;
            }

            /// Removes the specified flags in-place.
            pub fn remove(&mut self, other: $BitFlags) {
                self.bits &= !other.bits;
            }
        }

        impl BitOr<$BitFlags, $BitFlags> for $BitFlags {
            /// Returns the union of the two sets of flags.
            #[inline]
            fn bitor(&self, other: &$BitFlags) -> $BitFlags {
                $BitFlags { bits: self.bits | other.bits }
            }
        }

        impl BitAnd<$BitFlags, $BitFlags> for $BitFlags {
            /// Returns the intersection between the two sets of flags.
            #[inline]
            fn bitand(&self, other: &$BitFlags) -> $BitFlags {
                $BitFlags { bits: self.bits & other.bits }
            }
        }

        impl Sub<$BitFlags, $BitFlags> for $BitFlags {
            /// Returns the set difference of the two sets of flags.
            #[inline]
            fn sub(&self, other: &$BitFlags) -> $BitFlags {
                $BitFlags { bits: self.bits & !other.bits }
            }
        }

        impl Not<$BitFlags> for $BitFlags {
            /// Returns the complement of this set of flags.
            #[inline]
            fn not(&self) -> $BitFlags {
                $BitFlags { bits: !self.bits } & $BitFlags::all()
            }
        }
    );
    ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
        $($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+,
    }) => (
        bitflags!(
            $(#[$attr])*
            flags $BitFlags: u32 {
                $($(#[$Flag_attr])* static $Flag = $value),+
            }
        )
    );
)

#[cfg(test)]
mod tests {
    use hash;
    use option::{Some, None};
    use ops::{BitOr, BitAnd, Sub, Not};

    bitflags!(
        #[doc = "> The first principle is that you must not fool yourself — and"]
        #[doc = "> you are the easiest person to fool."]
        #[doc = "> "]
        #[doc = "> - Richard Feynman"]
        flags Flags: u32 {
            static FlagA       = 0x00000001,
            #[doc = "<pcwalton> macros are way better at generating code than trans is"]
            static FlagB       = 0x00000010,
            static FlagC       = 0x00000100,
            #[doc = "* cmr bed"]
            #[doc = "* strcat table"]
            #[doc = "<strcat> wait what?"]
            static FlagABC     = FlagA.bits
                               | FlagB.bits
                               | FlagC.bits,
        }
    )

    #[test]
    fn test_bits(){
        assert_eq!(Flags::empty().bits(), 0x00000000);
        assert_eq!(FlagA.bits(), 0x00000001);
        assert_eq!(FlagABC.bits(), 0x00000111);
    }

    #[test]
    fn test_from_bits() {
        assert!(Flags::from_bits(0) == Some(Flags::empty()));
        assert!(Flags::from_bits(0x1) == Some(FlagA));
        assert!(Flags::from_bits(0x10) == Some(FlagB));
        assert!(Flags::from_bits(0x11) == Some(FlagA | FlagB));
        assert!(Flags::from_bits(0x1000) == None);
    }

    #[test]
    fn test_from_bits_truncate() {
        assert!(Flags::from_bits_truncate(0) == Flags::empty());
        assert!(Flags::from_bits_truncate(0x1) == FlagA);
        assert!(Flags::from_bits_truncate(0x10) == FlagB);
        assert!(Flags::from_bits_truncate(0x11) == (FlagA | FlagB));
        assert!(Flags::from_bits_truncate(0x1000) == Flags::empty());
        assert!(Flags::from_bits_truncate(0x1001) == FlagA);
    }

    #[test]
    fn test_is_empty(){
        assert!(Flags::empty().is_empty());
        assert!(!FlagA.is_empty());
        assert!(!FlagABC.is_empty());
    }

    #[test]
    fn test_is_all() {
        assert!(Flags::all().is_all());
        assert!(!FlagA.is_all());
        assert!(FlagABC.is_all());
    }

    #[test]
    fn test_two_empties_do_not_intersect() {
        let e1 = Flags::empty();
        let e2 = Flags::empty();
        assert!(!e1.intersects(e2));
    }

    #[test]
    fn test_empty_does_not_intersect_with_full() {
        let e1 = Flags::empty();
        let e2 = FlagABC;
        assert!(!e1.intersects(e2));
    }

    #[test]
    fn test_disjoint_intersects() {
        let e1 = FlagA;
        let e2 = FlagB;
        assert!(!e1.intersects(e2));
    }

    #[test]
    fn test_overlapping_intersects() {
        let e1 = FlagA;
        let e2 = FlagA | FlagB;
        assert!(e1.intersects(e2));
    }

    #[test]
    fn test_contains() {
        let e1 = FlagA;
        let e2 = FlagA | FlagB;
        assert!(!e1.contains(e2));
        assert!(e2.contains(e1));
        assert!(FlagABC.contains(e2));
    }

    #[test]
    fn test_insert(){
        let mut e1 = FlagA;
        let e2 = FlagA | FlagB;
        e1.insert(e2);
        assert!(e1 == e2);
    }

    #[test]
    fn test_remove(){
        let mut e1 = FlagA | FlagB;
        let e2 = FlagA | FlagC;
        e1.remove(e2);
        assert!(e1 == FlagB);
    }

    #[test]
    fn test_operators() {
        let e1 = FlagA | FlagC;
        let e2 = FlagB | FlagC;
        assert!((e1 | e2) == FlagABC);   // union
        assert!((e1 & e2) == FlagC);     // intersection
        assert!((e1 - e2) == FlagA);     // set difference
        assert!(!e2 == FlagA);           // set complement
    }

    #[test]
    fn test_lt() {
        let mut a = Flags::empty();
        let mut b = Flags::empty();

        assert!(!(a < b) && !(b < a));
        b = FlagB;
        assert!(a < b);
        a = FlagC;
        assert!(!(a < b) && b < a);
        b = FlagC | FlagB;
        assert!(a < b);
    }

    #[test]
    fn test_ord() {
        let mut a = Flags::empty();
        let mut b = Flags::empty();

        assert!(a <= b && a >= b);
        a = FlagA;
        assert!(a > b && a >= b);
        assert!(b < a && b <= a);
        b = FlagB;
        assert!(b > a && b >= a);
        assert!(a < b && a <= b);
    }

    #[test]
    fn test_hash() {
      let mut x = Flags::empty();
      let mut y = Flags::empty();
      assert!(hash::hash(&x) == hash::hash(&y));
      x = Flags::all();
      y = FlagABC;
      assert!(hash::hash(&x) == hash::hash(&y));
    }
}
<commit_msg>Attach documentation to the bitflags! macro itself<commit_after>// Copyright 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.

#![experimental]
#![macro_escape]

//! A typesafe bitmask flag generator.

/// The `bitflags!` macro generates a `struct` that holds a set of C-style
/// bitmask flags. It is useful for creating typesafe wrappers for C APIs.
///
/// The flags should only be defined for integer types, otherwise unexpected
/// type errors may occur at compile time.
///
/// # Example
///
/// ~~~rust
/// bitflags!(
///     flags Flags: u32 {
///         static FlagA       = 0x00000001,
///         static FlagB       = 0x00000010,
///         static FlagC       = 0x00000100,
///         static FlagABC     = FlagA.bits
///                            | FlagB.bits
///                            | FlagC.bits,
///     }
/// )
///
/// fn main() {
///     let e1 = FlagA | FlagC;
///     let e2 = FlagB | FlagC;
///     assert!((e1 | e2) == FlagABC);   // union
///     assert!((e1 & e2) == FlagC);     // intersection
///     assert!((e1 - e2) == FlagA);     // set difference
///     assert!(!e2 == FlagA);           // set complement
/// }
/// ~~~
///
/// The generated `struct`s can also be extended with type and trait implementations:
///
/// ~~~rust
/// use std::fmt;
///
/// bitflags!(
///     flags Flags: u32 {
///         static FlagA   = 0x00000001,
///         static FlagB   = 0x00000010,
///     }
/// )
///
/// impl Flags {
///     pub fn clear(&mut self) {
///         self.bits = 0;  // The `bits` field can be accessed from within the
///                         // same module where the `bitflags!` macro was invoked.
///     }
/// }
///
/// impl fmt::Show for Flags {
///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
///         write!(f, "hi!")
///     }
/// }
///
/// fn main() {
///     let mut flags = FlagA | FlagB;
///     flags.clear();
///     assert!(flags.is_empty());
///     assert_eq!(format!("{}", flags).as_slice(), "hi!");
/// }
/// ~~~
///
/// # Attributes
///
/// Attributes can be attached to the generated `struct` by placing them
/// before the `flags` keyword.
///
/// # Derived traits
///
/// The `PartialEq` and `Clone` traits are automatically derived for the `struct` using
/// the `deriving` attribute. Additional traits can be derived by providing an
/// explicit `deriving` attribute on `flags`.
///
/// # Operators
///
/// The following operator traits are implemented for the generated `struct`:
///
/// - `BitOr`: union
/// - `BitAnd`: intersection
/// - `Sub`: set difference
/// - `Not`: set complement
///
/// # Methods
///
/// The following methods are defined for the generated `struct`:
///
/// - `empty`: an empty set of flags
/// - `all`: the set of all flags
/// - `bits`: the raw value of the flags currently stored
/// - `is_empty`: `true` if no flags are currently stored
/// - `is_all`: `true` if all flags are currently set
/// - `intersects`: `true` if there are flags common to both `self` and `other`
/// - `contains`: `true` all of the flags in `other` are contained within `self`
/// - `insert`: inserts the specified flags in-place
/// - `remove`: removes the specified flags in-place
#[macro_export]
macro_rules! bitflags(
    ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
        $($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+
    }) => (
        #[deriving(PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
        $(#[$attr])*
        pub struct $BitFlags {
            bits: $T,
        }

        $($(#[$Flag_attr])* pub static $Flag: $BitFlags = $BitFlags { bits: $value };)+

        impl $BitFlags {
            /// Returns an empty set of flags.
            pub fn empty() -> $BitFlags {
                $BitFlags { bits: 0 }
            }

            /// Returns the set containing all flags.
            pub fn all() -> $BitFlags {
                $BitFlags { bits: $($value)|+ }
            }

            /// Returns the raw value of the flags currently stored.
            pub fn bits(&self) -> $T {
                self.bits
            }

            /// Convert from underlying bit representation, unless that
            /// representation contains bits that do not correspond to a flag.
            pub fn from_bits(bits: $T) -> ::std::option::Option<$BitFlags> {
                if (bits & !$BitFlags::all().bits()) != 0 {
                    ::std::option::None
                } else {
                    ::std::option::Some($BitFlags { bits: bits })
                }
            }

            /// Convert from underlying bit representation, dropping any bits
            /// that do not correspond to flags.
            pub fn from_bits_truncate(bits: $T) -> $BitFlags {
                $BitFlags { bits: bits } & $BitFlags::all()
            }

            /// Returns `true` if no flags are currently stored.
            pub fn is_empty(&self) -> bool {
                *self == $BitFlags::empty()
            }

            /// Returns `true` if all flags are currently set.
            pub fn is_all(&self) -> bool {
                *self == $BitFlags::all()
            }

            /// Returns `true` if there are flags common to both `self` and `other`.
            pub fn intersects(&self, other: $BitFlags) -> bool {
                !(self & other).is_empty()
            }

            /// Returns `true` all of the flags in `other` are contained within `self`.
            pub fn contains(&self, other: $BitFlags) -> bool {
                (self & other) == other
            }

            /// Inserts the specified flags in-place.
            pub fn insert(&mut self, other: $BitFlags) {
                self.bits |= other.bits;
            }

            /// Removes the specified flags in-place.
            pub fn remove(&mut self, other: $BitFlags) {
                self.bits &= !other.bits;
            }
        }

        impl BitOr<$BitFlags, $BitFlags> for $BitFlags {
            /// Returns the union of the two sets of flags.
            #[inline]
            fn bitor(&self, other: &$BitFlags) -> $BitFlags {
                $BitFlags { bits: self.bits | other.bits }
            }
        }

        impl BitAnd<$BitFlags, $BitFlags> for $BitFlags {
            /// Returns the intersection between the two sets of flags.
            #[inline]
            fn bitand(&self, other: &$BitFlags) -> $BitFlags {
                $BitFlags { bits: self.bits & other.bits }
            }
        }

        impl Sub<$BitFlags, $BitFlags> for $BitFlags {
            /// Returns the set difference of the two sets of flags.
            #[inline]
            fn sub(&self, other: &$BitFlags) -> $BitFlags {
                $BitFlags { bits: self.bits & !other.bits }
            }
        }

        impl Not<$BitFlags> for $BitFlags {
            /// Returns the complement of this set of flags.
            #[inline]
            fn not(&self) -> $BitFlags {
                $BitFlags { bits: !self.bits } & $BitFlags::all()
            }
        }
    );
    ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
        $($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+,
    }) => (
        bitflags!(
            $(#[$attr])*
            flags $BitFlags: u32 {
                $($(#[$Flag_attr])* static $Flag = $value),+
            }
        )
    );
)

#[cfg(test)]
mod tests {
    use hash;
    use option::{Some, None};
    use ops::{BitOr, BitAnd, Sub, Not};

    bitflags!(
        #[doc = "> The first principle is that you must not fool yourself — and"]
        #[doc = "> you are the easiest person to fool."]
        #[doc = "> "]
        #[doc = "> - Richard Feynman"]
        flags Flags: u32 {
            static FlagA       = 0x00000001,
            #[doc = "<pcwalton> macros are way better at generating code than trans is"]
            static FlagB       = 0x00000010,
            static FlagC       = 0x00000100,
            #[doc = "* cmr bed"]
            #[doc = "* strcat table"]
            #[doc = "<strcat> wait what?"]
            static FlagABC     = FlagA.bits
                               | FlagB.bits
                               | FlagC.bits,
        }
    )

    #[test]
    fn test_bits(){
        assert_eq!(Flags::empty().bits(), 0x00000000);
        assert_eq!(FlagA.bits(), 0x00000001);
        assert_eq!(FlagABC.bits(), 0x00000111);
    }

    #[test]
    fn test_from_bits() {
        assert!(Flags::from_bits(0) == Some(Flags::empty()));
        assert!(Flags::from_bits(0x1) == Some(FlagA));
        assert!(Flags::from_bits(0x10) == Some(FlagB));
        assert!(Flags::from_bits(0x11) == Some(FlagA | FlagB));
        assert!(Flags::from_bits(0x1000) == None);
    }

    #[test]
    fn test_from_bits_truncate() {
        assert!(Flags::from_bits_truncate(0) == Flags::empty());
        assert!(Flags::from_bits_truncate(0x1) == FlagA);
        assert!(Flags::from_bits_truncate(0x10) == FlagB);
        assert!(Flags::from_bits_truncate(0x11) == (FlagA | FlagB));
        assert!(Flags::from_bits_truncate(0x1000) == Flags::empty());
        assert!(Flags::from_bits_truncate(0x1001) == FlagA);
    }

    #[test]
    fn test_is_empty(){
        assert!(Flags::empty().is_empty());
        assert!(!FlagA.is_empty());
        assert!(!FlagABC.is_empty());
    }

    #[test]
    fn test_is_all() {
        assert!(Flags::all().is_all());
        assert!(!FlagA.is_all());
        assert!(FlagABC.is_all());
    }

    #[test]
    fn test_two_empties_do_not_intersect() {
        let e1 = Flags::empty();
        let e2 = Flags::empty();
        assert!(!e1.intersects(e2));
    }

    #[test]
    fn test_empty_does_not_intersect_with_full() {
        let e1 = Flags::empty();
        let e2 = FlagABC;
        assert!(!e1.intersects(e2));
    }

    #[test]
    fn test_disjoint_intersects() {
        let e1 = FlagA;
        let e2 = FlagB;
        assert!(!e1.intersects(e2));
    }

    #[test]
    fn test_overlapping_intersects() {
        let e1 = FlagA;
        let e2 = FlagA | FlagB;
        assert!(e1.intersects(e2));
    }

    #[test]
    fn test_contains() {
        let e1 = FlagA;
        let e2 = FlagA | FlagB;
        assert!(!e1.contains(e2));
        assert!(e2.contains(e1));
        assert!(FlagABC.contains(e2));
    }

    #[test]
    fn test_insert(){
        let mut e1 = FlagA;
        let e2 = FlagA | FlagB;
        e1.insert(e2);
        assert!(e1 == e2);
    }

    #[test]
    fn test_remove(){
        let mut e1 = FlagA | FlagB;
        let e2 = FlagA | FlagC;
        e1.remove(e2);
        assert!(e1 == FlagB);
    }

    #[test]
    fn test_operators() {
        let e1 = FlagA | FlagC;
        let e2 = FlagB | FlagC;
        assert!((e1 | e2) == FlagABC);   // union
        assert!((e1 & e2) == FlagC);     // intersection
        assert!((e1 - e2) == FlagA);     // set difference
        assert!(!e2 == FlagA);           // set complement
    }

    #[test]
    fn test_lt() {
        let mut a = Flags::empty();
        let mut b = Flags::empty();

        assert!(!(a < b) && !(b < a));
        b = FlagB;
        assert!(a < b);
        a = FlagC;
        assert!(!(a < b) && b < a);
        b = FlagC | FlagB;
        assert!(a < b);
    }

    #[test]
    fn test_ord() {
        let mut a = Flags::empty();
        let mut b = Flags::empty();

        assert!(a <= b && a >= b);
        a = FlagA;
        assert!(a > b && a >= b);
        assert!(b < a && b <= a);
        b = FlagB;
        assert!(b > a && b >= a);
        assert!(a < b && a <= b);
    }

    #[test]
    fn test_hash() {
      let mut x = Flags::empty();
      let mut y = Flags::empty();
      assert!(hash::hash(&x) == hash::hash(&y));
      x = Flags::all();
      y = FlagABC;
      assert!(hash::hash(&x) == hash::hash(&y));
    }
}
<|endoftext|>


<commit_before>#[cfg(feature = "serde-serialize")]
use serde::{Deserialize, Serialize};

use alga::general::ComplexField;

use crate::allocator::Allocator;
use crate::base::{DefaultAllocator, Matrix, MatrixMN, MatrixN, SquareMatrix};
use crate::constraint::{SameNumberOfRows, ShapeConstraint};
use crate::dimension::{Dim, DimSub, Dynamic, U1};
use crate::storage::{Storage, StorageMut};

/// The Cholesky decomposition of a symmetric-definite-positive matrix.
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr(
    feature = "serde-serialize",
    serde(bound(serialize = "DefaultAllocator: Allocator<N, D>,
         MatrixN<N, D>: Serialize"))
)]
#[cfg_attr(
    feature = "serde-serialize",
    serde(bound(deserialize = "DefaultAllocator: Allocator<N, D>,
         MatrixN<N, D>: Deserialize<'de>"))
)]
#[derive(Clone, Debug)]
pub struct Cholesky<N: ComplexField, D: Dim>
where
    DefaultAllocator: Allocator<N, D, D>,
{
    chol: MatrixN<N, D>,
}

impl<N: ComplexField, D: Dim> Copy for Cholesky<N, D>
where
    DefaultAllocator: Allocator<N, D, D>,
    MatrixN<N, D>: Copy,
{
}

impl<N: ComplexField, D: DimSub<Dynamic>> Cholesky<N, D>
where
    DefaultAllocator: Allocator<N, D, D>,
{
    /// Attempts to compute the Cholesky decomposition of `matrix`.
    ///
    /// Returns `None` if the input matrix is not definite-positive. The input matrix is assumed
    /// to be symmetric and only the lower-triangular part is read.
    pub fn new(mut matrix: MatrixN<N, D>) -> Option<Self> {
        assert!(matrix.is_square(), "The input matrix must be square.");

        let n = matrix.nrows();

        for j in 0..n {
            for k in 0..j {
                let factor = unsafe { -*matrix.get_unchecked((j, k)) };

                let (mut col_j, col_k) = matrix.columns_range_pair_mut(j, k);
                let mut col_j = col_j.rows_range_mut(j..);
                let col_k = col_k.rows_range(j..);

                col_j.axpy(factor.conjugate(), &col_k, N::one());
            }

            let diag = unsafe { *matrix.get_unchecked((j, j)) };
            if !diag.is_zero() {
                if let Some(denom) = diag.try_sqrt() {
                    unsafe {
                        *matrix.get_unchecked_mut((j, j)) = denom;
                    }

                    let mut col = matrix.slice_range_mut(j + 1.., j);
                    col /= denom;
                    continue;
                }
            }

            // The diagonal element is either zero or its square root could not
            // be taken (e.g. for negative real numbers).
            return None;
        }

        Some(Cholesky { chol: matrix })
    }

    /// Retrieves the lower-triangular factor of the Cholesky decomposition with its strictly
    /// upper-triangular part filled with zeros.
    pub fn unpack(mut self) -> MatrixN<N, D> {
        self.chol.fill_upper_triangle(N::zero(), 1);
        self.chol
    }

    /// Retrieves the lower-triangular factor of the Cholesky decomposition, without zeroing-out
    /// its strict upper-triangular part.
    ///
    /// The values of the strict upper-triangular part are garbage and should be ignored by further
    /// computations.
    pub fn unpack_dirty(self) -> MatrixN<N, D> {
        self.chol
    }

    /// Retrieves the lower-triangular factor of the Cholesky decomposition with its strictly
    /// uppen-triangular part filled with zeros.
    pub fn l(&self) -> MatrixN<N, D> {
        self.chol.lower_triangle()
    }

    /// Retrieves the lower-triangular factor of the Cholesky decomposition, without zeroing-out
    /// its strict upper-triangular part.
    ///
    /// This is an allocation-less version of `self.l()`. The values of the strict upper-triangular
    /// part are garbage and should be ignored by further computations.
    pub fn l_dirty(&self) -> &MatrixN<N, D> {
        &self.chol
    }

    /// Solves the system `self * x = b` where `self` is the decomposed matrix and `x` the unknown.
    ///
    /// The result is stored on `b`.
    pub fn solve_mut<R2: Dim, C2: Dim, S2>(&self, b: &mut Matrix<N, R2, C2, S2>)
    where
        S2: StorageMut<N, R2, C2>,
        ShapeConstraint: SameNumberOfRows<R2, D>,
    {
        let _ = self.chol.solve_lower_triangular_mut(b);
        let _ = self.chol.ad_solve_lower_triangular_mut(b);
    }

    /// Returns the solution of the system `self * x = b` where `self` is the decomposed matrix and
    /// `x` the unknown.
    pub fn solve<R2: Dim, C2: Dim, S2>(&self, b: &Matrix<N, R2, C2, S2>) -> MatrixMN<N, R2, C2>
    where
        S2: Storage<N, R2, C2>,
        DefaultAllocator: Allocator<N, R2, C2>,
        ShapeConstraint: SameNumberOfRows<R2, D>,
    {
        let mut res = b.clone_owned();
        self.solve_mut(&mut res);
        res
    }

    /// Computes the inverse of the decomposed matrix.
    pub fn inverse(&self) -> MatrixN<N, D> {
        let shape = self.chol.data.shape();
        let mut res = MatrixN::identity_generic(shape.0, shape.1);

        self.solve_mut(&mut res);
        res
    }

    /// Given the Cholesky decomposition of a matrix `M`, a scalar `sigma` and a vector `v`,
    /// performs a rank one update such that we end up with the decomposition of `M + sigma * v*v.adjoint()`.
    pub fn rank_one_update<R2: Dim, S2>(&mut self, x: &Matrix<N, R2, U1, S2>, sigma: N::RealField)
    where
        S2: Storage<N, R2, U1>,
        DefaultAllocator: Allocator<N, R2, U1>,
        ShapeConstraint: SameNumberOfRows<R2, D>,
    {
        // for a description of the operation, see https://en.wikipedia.org/wiki/Cholesky_decomposition#Updating_the_decomposition
        // heavily inspired by Eigen's implementation https://eigen.tuxfamily.org/dox/LLT_8h_source.html
        let n = x.nrows();
        let mut x = x.clone_owned();
        let mut beta = crate::one::<N::RealField>();
        for j in 0..n {
            let diag = N::real(unsafe { *self.chol.get_unchecked((j, j)) });
            let diag2 = diag * diag;
            let xj = unsafe { *x.get_unchecked(j) };
            let sigma_xj2 = sigma * N::modulus_squared(xj);
            let gamma = diag2 * beta + sigma_xj2;
            let new_diag = (diag2 + sigma_xj2 / beta).sqrt();
            unsafe { *self.chol.get_unchecked_mut((j, j)) = N::from_real(new_diag) };
            beta += sigma_xj2 / diag2;
            // Update the terms of L
            if j < n {
                let mut xjplus = x.rows_range_mut(j + 1..);
                let mut col_j = self.chol.slice_range_mut(j + 1.., j);
                // temp_jplus -= (wj / N::from_real(diag)) * col_j;
                xjplus.axpy(-xj / N::from_real(diag), &col_j, N::one());
                if gamma != crate::zero::<N::RealField>() {
                    // col_j = N::from_real(nljj / diag) * col_j  + (N::from_real(nljj * sigma / gamma) * N::conjugate(wj)) * temp_jplus;
                    col_j.axpy(
                        N::from_real(new_diag * sigma / gamma) * N::conjugate(xj),
                        &xjplus,
                        N::from_real(new_diag / diag),
                    );
                }
            }
        }
    }
}

impl<N: ComplexField, D: DimSub<Dynamic>, S: Storage<N, D, D>> SquareMatrix<N, D, S>
where
    DefaultAllocator: Allocator<N, D, D>,
{
    /// Attempts to compute the Cholesky decomposition of this matrix.
    ///
    /// Returns `None` if the input matrix is not definite-positive. The input matrix is assumed
    /// to be symmetric and only the lower-triangular part is read.
    pub fn cholesky(self) -> Option<Cholesky<N, D>> {
        Cholesky::new(self.into_owned())
    }
}
<commit_msg>code cleaned<commit_after>#[cfg(feature = "serde-serialize")]
use serde::{Deserialize, Serialize};

use alga::general::ComplexField;

use crate::allocator::Allocator;
use crate::base::{DefaultAllocator, Matrix, MatrixMN, MatrixN, SquareMatrix};
use crate::constraint::{SameNumberOfRows, ShapeConstraint};
use crate::dimension::{Dim, DimSub, Dynamic, U1};
use crate::storage::{Storage, StorageMut};

/// The Cholesky decomposition of a symmetric-definite-positive matrix.
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr(
    feature = "serde-serialize",
    serde(bound(serialize = "DefaultAllocator: Allocator<N, D>,
         MatrixN<N, D>: Serialize"))
)]
#[cfg_attr(
    feature = "serde-serialize",
    serde(bound(deserialize = "DefaultAllocator: Allocator<N, D>,
         MatrixN<N, D>: Deserialize<'de>"))
)]
#[derive(Clone, Debug)]
pub struct Cholesky<N: ComplexField, D: Dim>
where
    DefaultAllocator: Allocator<N, D, D>,
{
    chol: MatrixN<N, D>,
}

impl<N: ComplexField, D: Dim> Copy for Cholesky<N, D>
where
    DefaultAllocator: Allocator<N, D, D>,
    MatrixN<N, D>: Copy,
{
}

impl<N: ComplexField, D: DimSub<Dynamic>> Cholesky<N, D>
where
    DefaultAllocator: Allocator<N, D, D>,
{
    /// Attempts to compute the Cholesky decomposition of `matrix`.
    ///
    /// Returns `None` if the input matrix is not definite-positive. The input matrix is assumed
    /// to be symmetric and only the lower-triangular part is read.
    pub fn new(mut matrix: MatrixN<N, D>) -> Option<Self> {
        assert!(matrix.is_square(), "The input matrix must be square.");

        let n = matrix.nrows();

        for j in 0..n {
            for k in 0..j {
                let factor = unsafe { -*matrix.get_unchecked((j, k)) };

                let (mut col_j, col_k) = matrix.columns_range_pair_mut(j, k);
                let mut col_j = col_j.rows_range_mut(j..);
                let col_k = col_k.rows_range(j..);

                col_j.axpy(factor.conjugate(), &col_k, N::one());
            }

            let diag = unsafe { *matrix.get_unchecked((j, j)) };
            if !diag.is_zero() {
                if let Some(denom) = diag.try_sqrt() {
                    unsafe {
                        *matrix.get_unchecked_mut((j, j)) = denom;
                    }

                    let mut col = matrix.slice_range_mut(j + 1.., j);
                    col /= denom;
                    continue;
                }
            }

            // The diagonal element is either zero or its square root could not
            // be taken (e.g. for negative real numbers).
            return None;
        }

        Some(Cholesky { chol: matrix })
    }

    /// Retrieves the lower-triangular factor of the Cholesky decomposition with its strictly
    /// upper-triangular part filled with zeros.
    pub fn unpack(mut self) -> MatrixN<N, D> {
        self.chol.fill_upper_triangle(N::zero(), 1);
        self.chol
    }

    /// Retrieves the lower-triangular factor of the Cholesky decomposition, without zeroing-out
    /// its strict upper-triangular part.
    ///
    /// The values of the strict upper-triangular part are garbage and should be ignored by further
    /// computations.
    pub fn unpack_dirty(self) -> MatrixN<N, D> {
        self.chol
    }

    /// Retrieves the lower-triangular factor of the Cholesky decomposition with its strictly
    /// uppen-triangular part filled with zeros.
    pub fn l(&self) -> MatrixN<N, D> {
        self.chol.lower_triangle()
    }

    /// Retrieves the lower-triangular factor of the Cholesky decomposition, without zeroing-out
    /// its strict upper-triangular part.
    ///
    /// This is an allocation-less version of `self.l()`. The values of the strict upper-triangular
    /// part are garbage and should be ignored by further computations.
    pub fn l_dirty(&self) -> &MatrixN<N, D> {
        &self.chol
    }

    /// Solves the system `self * x = b` where `self` is the decomposed matrix and `x` the unknown.
    ///
    /// The result is stored on `b`.
    pub fn solve_mut<R2: Dim, C2: Dim, S2>(&self, b: &mut Matrix<N, R2, C2, S2>)
    where
        S2: StorageMut<N, R2, C2>,
        ShapeConstraint: SameNumberOfRows<R2, D>,
    {
        let _ = self.chol.solve_lower_triangular_mut(b);
        let _ = self.chol.ad_solve_lower_triangular_mut(b);
    }

    /// Returns the solution of the system `self * x = b` where `self` is the decomposed matrix and
    /// `x` the unknown.
    pub fn solve<R2: Dim, C2: Dim, S2>(&self, b: &Matrix<N, R2, C2, S2>) -> MatrixMN<N, R2, C2>
    where
        S2: Storage<N, R2, C2>,
        DefaultAllocator: Allocator<N, R2, C2>,
        ShapeConstraint: SameNumberOfRows<R2, D>,
    {
        let mut res = b.clone_owned();
        self.solve_mut(&mut res);
        res
    }

    /// Computes the inverse of the decomposed matrix.
    pub fn inverse(&self) -> MatrixN<N, D> {
        let shape = self.chol.data.shape();
        let mut res = MatrixN::identity_generic(shape.0, shape.1);

        self.solve_mut(&mut res);
        res
    }

    /// Given the Cholesky decomposition of a matrix `M`, a scalar `sigma` and a vector `v`,
    /// performs a rank one update such that we end up with the decomposition of `M + sigma * v*v.adjoint()`.
    pub fn rank_one_update<R2: Dim, S2>(&mut self, x: &Matrix<N, R2, U1, S2>, sigma: N::RealField)
    where
        S2: Storage<N, R2, U1>,
        DefaultAllocator: Allocator<N, R2, U1>,
        ShapeConstraint: SameNumberOfRows<R2, D>,
    {
        // heavily inspired by Eigen's `llt_rank_update_lower` implementation https://eigen.tuxfamily.org/dox/LLT_8h_source.html
        let n = x.nrows();
        let mut x = x.clone_owned();
        let mut beta = crate::one::<N::RealField>();
        for j in 0..n {
            let diag = N::real(unsafe { *self.chol.get_unchecked((j, j)) });
            let diag2 = diag * diag;
            let xj = unsafe { *x.get_unchecked(j) };
            let sigma_xj2 = sigma * N::modulus_squared(xj);
            let gamma = diag2 * beta + sigma_xj2;
            let new_diag = (diag2 + sigma_xj2 / beta).sqrt();
            unsafe { *self.chol.get_unchecked_mut((j, j)) = N::from_real(new_diag) };
            beta += sigma_xj2 / diag2;
            // Update the terms of L
            if j < n {
                let mut xjplus = x.rows_range_mut(j + 1..);
                let mut col_j = self.chol.slice_range_mut(j + 1.., j);
                // temp_jplus -= (wj / N::from_real(diag)) * col_j;
                xjplus.axpy(-xj / N::from_real(diag), &col_j, N::one());
                if gamma != crate::zero::<N::RealField>() {
                    // col_j = N::from_real(nljj / diag) * col_j  + (N::from_real(nljj * sigma / gamma) * N::conjugate(wj)) * temp_jplus;
                    col_j.axpy(
                        N::from_real(new_diag * sigma / gamma) * N::conjugate(xj),
                        &xjplus,
                        N::from_real(new_diag / diag),
                    );
                }
            }
        }
    }
}

impl<N: ComplexField, D: DimSub<Dynamic>, S: Storage<N, D, D>> SquareMatrix<N, D, S>
where
    DefaultAllocator: Allocator<N, D, D>,
{
    /// Attempts to compute the Cholesky decomposition of this matrix.
    ///
    /// Returns `None` if the input matrix is not definite-positive. The input matrix is assumed
    /// to be symmetric and only the lower-triangular part is read.
    pub fn cholesky(self) -> Option<Cholesky<N, D>> {
        Cholesky::new(self.into_owned())
    }
}
<|endoftext|>


<commit_before>use crate::{
    ChainSpec, Domain, EthSpec, Fork, Hash256, PublicKey, SecretKey, Signature, SignedRoot, Slot,
};
use safe_arith::{ArithError, SafeArith};
use std::cmp;
use std::convert::TryInto;
use tree_hash::TreeHash;

#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(PartialEq, Debug, Clone)]
pub struct SelectionProof(Signature);

impl SelectionProof {
    pub fn new<T: EthSpec>(
        slot: Slot,
        secret_key: &SecretKey,
        fork: &Fork,
        genesis_validators_root: Hash256,
        spec: &ChainSpec,
    ) -> Self {
        let domain = spec.get_domain(
            slot.epoch(T::slots_per_epoch()),
            Domain::SelectionProof,
            fork,
            genesis_validators_root,
        );
        let message = slot.signing_root(domain);

        Self(Signature::new(message.as_bytes(), secret_key))
    }

    /// Returns the "modulo" used for determining if a `SelectionProof` elects an aggregator.
    pub fn modulo(committee_len: usize, spec: &ChainSpec) -> Result<u64, ArithError> {
        Ok(cmp::max(
            1,
            (committee_len as u64).safe_div(spec.target_aggregators_per_committee)?,
        ))
    }

    pub fn is_aggregator(
        &self,
        committee_len: usize,
        spec: &ChainSpec,
    ) -> Result<bool, ArithError> {
        self.is_aggregator_from_modulo(Self::modulo(committee_len, spec)?)
    }

    pub fn is_aggregator_from_modulo(&self, modulo: u64) -> Result<bool, ArithError> {
        let signature_hash = self.0.tree_hash_root();
        let signature_hash_int = u64::from_le_bytes(
            signature_hash[0..8]
                .as_ref()
                .try_into()
                .expect("first 8 bytes of signature should always convert to fixed array"),
        );

        signature_hash_int.safe_rem(modulo).map(|rem| rem == 0)
    }

    pub fn verify<T: EthSpec>(
        &self,
        slot: Slot,
        pubkey: &PublicKey,
        fork: &Fork,
        genesis_validators_root: Hash256,
        spec: &ChainSpec,
    ) -> bool {
        let domain = spec.get_domain(
            slot.epoch(T::slots_per_epoch()),
            Domain::SelectionProof,
            fork,
            genesis_validators_root,
        );
        let message = slot.signing_root(domain);

        self.0.verify(message.as_bytes(), pubkey)
    }
}

impl Into<Signature> for SelectionProof {
    fn into(self) -> Signature {
        self.0
    }
}

impl From<Signature> for SelectionProof {
    fn from(sig: Signature) -> Self {
        Self(sig)
    }
}
<commit_msg>Use hash instead of tree hash for is_aggregator (#1296)<commit_after>use crate::{
    ChainSpec, Domain, EthSpec, Fork, Hash256, PublicKey, SecretKey, Signature, SignedRoot, Slot,
};
use eth2_hashing::hash;
use safe_arith::{ArithError, SafeArith};
use ssz::Encode;
use std::cmp;
use std::convert::TryInto;

#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(PartialEq, Debug, Clone)]
pub struct SelectionProof(Signature);

impl SelectionProof {
    pub fn new<T: EthSpec>(
        slot: Slot,
        secret_key: &SecretKey,
        fork: &Fork,
        genesis_validators_root: Hash256,
        spec: &ChainSpec,
    ) -> Self {
        let domain = spec.get_domain(
            slot.epoch(T::slots_per_epoch()),
            Domain::SelectionProof,
            fork,
            genesis_validators_root,
        );
        let message = slot.signing_root(domain);

        Self(Signature::new(message.as_bytes(), secret_key))
    }

    /// Returns the "modulo" used for determining if a `SelectionProof` elects an aggregator.
    pub fn modulo(committee_len: usize, spec: &ChainSpec) -> Result<u64, ArithError> {
        Ok(cmp::max(
            1,
            (committee_len as u64).safe_div(spec.target_aggregators_per_committee)?,
        ))
    }

    pub fn is_aggregator(
        &self,
        committee_len: usize,
        spec: &ChainSpec,
    ) -> Result<bool, ArithError> {
        self.is_aggregator_from_modulo(Self::modulo(committee_len, spec)?)
    }

    pub fn is_aggregator_from_modulo(&self, modulo: u64) -> Result<bool, ArithError> {
        let signature_hash = hash(&self.0.as_ssz_bytes());
        let signature_hash_int = u64::from_le_bytes(
            signature_hash[0..8]
                .as_ref()
                .try_into()
                .expect("first 8 bytes of signature should always convert to fixed array"),
        );

        signature_hash_int.safe_rem(modulo).map(|rem| rem == 0)
    }

    pub fn verify<T: EthSpec>(
        &self,
        slot: Slot,
        pubkey: &PublicKey,
        fork: &Fork,
        genesis_validators_root: Hash256,
        spec: &ChainSpec,
    ) -> bool {
        let domain = spec.get_domain(
            slot.epoch(T::slots_per_epoch()),
            Domain::SelectionProof,
            fork,
            genesis_validators_root,
        );
        let message = slot.signing_root(domain);

        self.0.verify(message.as_bytes(), pubkey)
    }
}

impl Into<Signature> for SelectionProof {
    fn into(self) -> Signature {
        self.0
    }
}

impl From<Signature> for SelectionProof {
    fn from(sig: Signature) -> Self {
        Self(sig)
    }
}
<|endoftext|>