<commit_before>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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 point::Point2D;
use size::Size2D;
use std::cmp::{Eq, Ord};

#[deriving(Eq, Clone)]
pub struct Rect<T> {
    origin: Point2D<T>,
    size: Size2D<T>,
}

pub fn Rect<T:Clone + Ord + Add<T,T> + Sub<T,T>>(origin: Point2D<T>,
                                                 size: Size2D<T>)
        -> Rect<T> {
    return Rect {
        origin: origin,
        size: size
    }
}

impl<T: Clone + Ord + Add<T,T> + Sub<T,T>> Rect<T> {
    pub fn intersects(&self, other: &Rect<T>) -> bool {
        self.origin.x < other.origin.x + other.size.width &&
       other.origin.x <  self.origin.x + self.size.width &&
        self.origin.y < other.origin.y + other.size.height &&
       other.origin.y <  self.origin.y + self.size.height
    }

    pub fn intersection(&self, other: &Rect<T>) -> Option<Rect<T>> {
        if !self.intersects(other) {
            return None;
        }

        Some(Rect(Point2D(max(self.origin.x.clone(), other.origin.x.clone()),
                          max(self.origin.y.clone(), other.origin.y.clone())),
                  Size2D(min(self.origin.x + self.size.width,
                             other.origin.x + other.size.width),
                         min(self.origin.y + self.size.height,
                             other.origin.y + other.size.height))))
    }

    pub fn union(&self, other: &Rect<T>) -> Rect<T> {
        let upper_left = Point2D(min(self.origin.x.clone(), other.origin.x.clone()),
                                 min(self.origin.y.clone(), other.origin.y.clone()));

        let lower_right = Point2D(max(self.origin.x + self.size.width,
                                      other.origin.x + other.size.width),
                                  max(self.origin.y + self.size.height,
                                      other.origin.y + other.size.height));

        Rect {
            origin: upper_left.clone(),
            size: Size2D(lower_right.x - upper_left.x, lower_right.y - upper_left.y)
        }
    }

    pub fn translate(&self, other: &Point2D<T>) -> Rect<T> {
        Rect {
            origin: Point2D(self.origin.x + other.x, self.origin.y + other.y),
            size: self.size.clone()
        }
    }
}

pub fn min<T:Clone + Ord>(x: T, y: T) -> T {
    if x <= y { x } else { y }
}

pub fn max<T:Clone + Ord>(x: T, y: T) -> T {
    if x >= y { x } else { y }
}

#[test]
fn test_min_max() {
    assert!(min(0, 1) == 0);
    assert!(min(-1.0, 0.0) == -1.0);

    assert!(max(0, 1) == 1);
    assert!(max(-1.0, 0.0) == 0.0);
}

#[test]
fn test_translate() {
    let p = Rect(Point2D(0, 0), Size2D(50, 40));
    let pp = p.translate(&Point2D(10,15));

    assert!(pp.size.width == 50);
    assert!(pp.size.height == 40);
    assert!(pp.origin.x == 10);
    assert!(pp.origin.y == 15);

    let r = Rect(Point2D(-10, -5), Size2D(50, 40));
    let rr = r.translate(&Point2D(0,-10));

    assert!(rr.size.width == 50);
    assert!(rr.size.height == 40);
    assert!(rr.origin.x == -10);
    assert!(rr.origin.y == -15);
}

#[test]
fn test_union() {
    let p = Rect(Point2D(0,0), Size2D(50, 40));
    let q = Rect(Point2D(20,20), Size2D(5, 5));
    let r = Rect(Point2D(-15, -30), Size2D(200, 15));
    let s = Rect(Point2D(20, -15), Size2D(250, 200));

    let pq = p.union(&q);
    assert!(pq.origin == Point2D(0, 0));
    assert!(pq.size == Size2D(50, 40));

    let pr = p.union(&r);
    assert!(pr.origin == Point2D(-15, -30));
    assert!(pr.size == Size2D(200, 70));

    let ps = p.union(&s);
    assert!(ps.origin == Point2D(0, -15));
    assert!(ps.size == Size2D(270, 200));

}
<commit_msg>Fix rect intersection, add test<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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 point::Point2D;
use size::Size2D;
use std::cmp::{Eq, Ord};

#[deriving(Eq, Clone)]
pub struct Rect<T> {
    origin: Point2D<T>,
    size: Size2D<T>,
}

pub fn Rect<T:Clone + Ord + Add<T,T> + Sub<T,T>>(origin: Point2D<T>,
                                                 size: Size2D<T>)
        -> Rect<T> {
    return Rect {
        origin: origin,
        size: size
    }
}

impl<T: Clone + Ord + Add<T,T> + Sub<T,T>> Rect<T> {
    pub fn intersects(&self, other: &Rect<T>) -> bool {
        self.origin.x < other.origin.x + other.size.width &&
       other.origin.x <  self.origin.x + self.size.width &&
        self.origin.y < other.origin.y + other.size.height &&
       other.origin.y <  self.origin.y + self.size.height
    }

    pub fn intersection(&self, other: &Rect<T>) -> Option<Rect<T>> {
        if !self.intersects(other) {
            return None;
        }

        let upper_left = Point2D(max(self.origin.x.clone(), other.origin.x.clone()),
                                 max(self.origin.y.clone(), other.origin.y.clone()));

        let lower_right = Point2D(min(self.origin.x + self.size.width,
                                      other.origin.x + other.size.width),
                                  min(self.origin.y + self.size.height,
                                      other.origin.y + other.size.height));

        Some(Rect(upper_left.clone(), Size2D(lower_right.x - upper_left.x,
                                             lower_right.y - upper_left.y)))
    }

    pub fn union(&self, other: &Rect<T>) -> Rect<T> {
        let upper_left = Point2D(min(self.origin.x.clone(), other.origin.x.clone()),
                                 min(self.origin.y.clone(), other.origin.y.clone()));

        let lower_right = Point2D(max(self.origin.x + self.size.width,
                                      other.origin.x + other.size.width),
                                  max(self.origin.y + self.size.height,
                                      other.origin.y + other.size.height));

        Rect {
            origin: upper_left.clone(),
            size: Size2D(lower_right.x - upper_left.x, lower_right.y - upper_left.y)
        }
    }

    pub fn translate(&self, other: &Point2D<T>) -> Rect<T> {
        Rect {
            origin: Point2D(self.origin.x + other.x, self.origin.y + other.y),
            size: self.size.clone()
        }
    }
}

pub fn min<T:Clone + Ord>(x: T, y: T) -> T {
    if x <= y { x } else { y }
}

pub fn max<T:Clone + Ord>(x: T, y: T) -> T {
    if x >= y { x } else { y }
}

#[test]
fn test_min_max() {
    assert!(min(0, 1) == 0);
    assert!(min(-1.0, 0.0) == -1.0);

    assert!(max(0, 1) == 1);
    assert!(max(-1.0, 0.0) == 0.0);
}

#[test]
fn test_translate() {
    let p = Rect(Point2D(0, 0), Size2D(50, 40));
    let pp = p.translate(&Point2D(10,15));

    assert!(pp.size.width == 50);
    assert!(pp.size.height == 40);
    assert!(pp.origin.x == 10);
    assert!(pp.origin.y == 15);

    let r = Rect(Point2D(-10, -5), Size2D(50, 40));
    let rr = r.translate(&Point2D(0,-10));

    assert!(rr.size.width == 50);
    assert!(rr.size.height == 40);
    assert!(rr.origin.x == -10);
    assert!(rr.origin.y == -15);
}

#[test]
fn test_union() {
    let p = Rect(Point2D(0,0), Size2D(50, 40));
    let q = Rect(Point2D(20,20), Size2D(5, 5));
    let r = Rect(Point2D(-15, -30), Size2D(200, 15));
    let s = Rect(Point2D(20, -15), Size2D(250, 200));

    let pq = p.union(&q);
    assert!(pq.origin == Point2D(0, 0));
    assert!(pq.size == Size2D(50, 40));

    let pr = p.union(&r);
    assert!(pr.origin == Point2D(-15, -30));
    assert!(pr.size == Size2D(200, 70));

    let ps = p.union(&s);
    assert!(ps.origin == Point2D(0, -15));
    assert!(ps.size == Size2D(270, 200));

}

#[test]
fn test_intersection() {
    let p = Rect(Point2D(0, 0), Size2D(10, 20));
    let q = Rect(Point2D(5, 15), Size2D(10, 10));
    let r = Rect(Point2D(-5, -5), Size2D(8, 8));

    let pq = p.intersection(&q);
    assert!(pq.is_some());
    let pq = pq.get();
    assert!(pq.origin == Point2D(5, 15));
    assert!(pq.size == Size2D(5, 5));

    let pr = p.intersection(&r);
    assert!(pr.is_some());
    let pr = pr.get();
    assert!(pr.origin == Point2D(0, 0));
    assert!(pr.size == Size2D(3, 3));

    let qr = q.intersection(&r);
    assert!(qr.is_none());
}
<|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.

use std::fmt;
use std::io;

#[deriving(Clone)]
pub struct Layout {
    logo: ~str,
    favicon: ~str,
    crate: ~str,
}

pub struct Page<'self> {
    title: &'self str,
    ty: &'self str,
    root_path: &'self str,
}

pub fn render<T: fmt::Default, S: fmt::Default>(
    dst: &mut io::Writer, layout: &Layout, page: &Page, sidebar: &S, t: &T)
{
    write!(dst,
"<!DOCTYPE html>

    <meta charset=\"utf-8\" />
    <title>{title}</title>

    <link href='http://fonts.googleapis.com/css?family=Oswald:700|Inconsolata:400'
          rel='stylesheet' type='text/css'>
    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}{crate}/main.css\">

    {favicon, select, none{} other{<link rel=\"shortcut icon\" href=\"#\" />}}

        {logo, select, none{} other{

        }}

        {sidebar}

        <form class=\"search-form js-only\">
            <input class=\"search-input\" name=\"search\"
                   autocomplete=\"off\" />
            <button class=\"do-search\">Search</button>
        </form>

{content}

Keyboard shortcuts

?

Show this help dialog

S

Focus the search field

↑

Move up in search results

↓

Move down in search results

&\\#9166;

Go to active search result

Search tricks

                Prefix searches with a type followed by a colon (e.g.
                fn:) to restrict the search to a given type.

                Accepted types are: fn, mod,
                struct (or str), enum,
                trait, typedef (or
                tdef).

",
    content   = *t,
    root_path = page.root_path,
    ty        = page.ty,
    logo      = nonestr(layout.logo),
    title     = page.title,
    favicon   = nonestr(layout.favicon),
    sidebar   = *sidebar,
    crate     = layout.crate,
    );
}

fn boolstr(b: bool) -> &'static str {
    if b { "true" } else { "false" }
}

fn nonestr<'a>(s: &'a str) -> &'a str {
    if s == "" { "none" } else { s }
}
<commit_msg>Add placeholder text to the search bar in the documentation.<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.

use std::fmt;
use std::io;

#[deriving(Clone)]
pub struct Layout {
    logo: ~str,
    favicon: ~str,
    crate: ~str,
}

pub struct Page<'self> {
    title: &'self str,
    ty: &'self str,
    root_path: &'self str,
}

pub fn render<T: fmt::Default, S: fmt::Default>(
    dst: &mut io::Writer, layout: &Layout, page: &Page, sidebar: &S, t: &T)
{
    write!(dst,
"<!DOCTYPE html>

    <meta charset=\"utf-8\" />
    <title>{title}</title>

    <link href='http://fonts.googleapis.com/css?family=Oswald:700|Inconsolata:400'
          rel='stylesheet' type='text/css'>
    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}{crate}/main.css\">

    {favicon, select, none{} other{<link rel=\"shortcut icon\" href=\"#\" />}}

        {logo, select, none{} other{

        }}

        {sidebar}

        <form class=\"search-form js-only\">
            <input class=\"search-input\" name=\"search\"
                   autocomplete=\"off\"
                   placeholder=\"Search documentation...\" />
            <button class=\"do-search\">Search</button>
        </form>

{content}

Keyboard shortcuts

?

Show this help dialog

S

Focus the search field

↑

Move up in search results

↓

Move down in search results

&\\#9166;

Go to active search result

Search tricks

                Prefix searches with a type followed by a colon (e.g.
                fn:) to restrict the search to a given type.

                Accepted types are: fn, mod,
                struct (or str), enum,
                trait, typedef (or
                tdef).

",
    content   = *t,
    root_path = page.root_path,
    ty        = page.ty,
    logo      = nonestr(layout.logo),
    title     = page.title,
    favicon   = nonestr(layout.favicon),
    sidebar   = *sidebar,
    crate     = layout.crate,
    );
}

fn boolstr(b: bool) -> &'static str {
    if b { "true" } else { "false" }
}

fn nonestr<'a>(s: &'a str) -> &'a str {
    if s == "" { "none" } else { s }
}
<|endoftext|>


<commit_before>use std::fmt;

use regex;

use super::frontmatter;
use error::*;

#[derive(Debug, Eq, PartialEq, Default, Clone)]
pub struct DocumentBuilder<T: frontmatter::Front> {
    front: T,
    content: String,
}

impl<T: frontmatter::Front> DocumentBuilder<T> {
    pub fn new(front: T, content: String) -> Self {
        Self { front, content }
    }

    pub fn parts(self) -> (T, String) {
        let Self { front, content } = self;
        (front, content)
    }

    pub fn parse(content: &str) -> Result<Self> {
        let (front, content) = split_document(content)?;
        let front = front
            .map(|s| T::parse(s))
            .map_or(Ok(None), |r| r.map(Some))?
            .unwrap_or_else(T::default);
        let content = content.to_owned();
        Ok(Self { front, content })
    }
}

impl<T: frontmatter::Front> fmt::Display for DocumentBuilder<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let front = self.front.to_string().map_err(|_| fmt::Error)?;
        if front.trim().is_empty() {
            write!(f, "{}", self.content)
        } else {
            write!(f, "{}\n---\n{}", front, self.content)
        }
    }
}

fn split_document(content: &str) -> Result<(Option<&str>, &str)> {
    lazy_static! {
        static ref FRONT_MATTER_DIVIDE: regex::Regex = regex::Regex::new(r"---\s*\r?\n").unwrap();
    }

    if FRONT_MATTER_DIVIDE.is_match(content) {
        let mut splits = FRONT_MATTER_DIVIDE.splitn(content, 2);

        // above the split are the attributes
        let front_split = splits.next().unwrap_or("");

        // everything below the split becomes the new content
        let content_split = splits.next().unwrap_or("");

        if front_split.is_empty() {
            Ok((None, content_split))
        } else {
            Ok((Some(front_split), content_split))
        }
    } else {
        Ok((None, content))
    }
}

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

    #[test]
    fn split_document_empty() {
        let input = "";
        let (cobalt_model, content) = split_document(input).unwrap();
        assert!(cobalt_model.is_none());
        assert_eq!(content, "");
    }

    #[test]
    fn split_document_no_front_matter() {
        let input = "Body";
        let (cobalt_model, content) = split_document(input).unwrap();
        assert!(cobalt_model.is_none());
        assert_eq!(content, "Body");
    }

    #[test]
    fn split_document_empty_front_matter() {
        let input = "---\nBody";
        let (cobalt_model, content) = split_document(input).unwrap();
        assert!(cobalt_model.is_none());
        assert_eq!(content, "Body");
    }

    #[test]
    fn split_document_empty_body() {
        let input = "cobalt_model---\n";
        let (cobalt_model, content) = split_document(input).unwrap();
        assert_eq!(cobalt_model.unwrap(), "cobalt_model");
        assert_eq!(content, "");
    }

    #[test]
    fn document_format_empty_has_no_front() {
        let doc = DocumentBuilder::<frontmatter::FrontmatterBuilder>::default();
        let doc = doc.to_string();
        assert_eq!(doc, "");
    }
}
<commit_msg>feat: Jekyll-style frontmatter divider<commit_after>use std::fmt;

use regex;

use super::frontmatter;
use error::*;

#[derive(Debug, Eq, PartialEq, Default, Clone)]
pub struct DocumentBuilder<T: frontmatter::Front> {
    front: T,
    content: String,
}

impl<T: frontmatter::Front> DocumentBuilder<T> {
    pub fn new(front: T, content: String) -> Self {
        Self { front, content }
    }

    pub fn parts(self) -> (T, String) {
        let Self { front, content } = self;
        (front, content)
    }

    pub fn parse(content: &str) -> Result<Self> {
        let (front, content) = split_document(content)?;
        let front = front
            .map(|s| T::parse(s))
            .map_or(Ok(None), |r| r.map(Some))?
            .unwrap_or_else(T::default);
        let content = content.to_owned();
        Ok(Self { front, content })
    }
}

impl<T: frontmatter::Front> fmt::Display for DocumentBuilder<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let front = self.front.to_string().map_err(|_| fmt::Error)?;
        if front.trim().is_empty() {
            write!(f, "{}", self.content)
        } else {
            write!(f, "---\n{}\n---\n{}", front, self.content)
        }
    }
}

fn split_document(content: &str) -> Result<(Option<&str>, &str)> {
    lazy_static! {
        static ref FRONT_MATTER_DIVIDE: regex::Regex = regex::Regex::new(r"---\s*\r?\n").unwrap();
        static ref FRONT_MATTER: regex::Regex =
            regex::Regex::new(r"\A---\s*\r?\n([\s\S]*\n)?---\s*\r?\n").unwrap();
    }

    if FRONT_MATTER.is_match(content) {
        // skip first empty string
        let mut splits = FRONT_MATTER_DIVIDE.splitn(content, 3).skip(1);

        // split between dividers
        let front_split = splits.next().unwrap_or("");

        // split after second divider
        let content_split = splits.next().unwrap_or("");

        if front_split.is_empty() {
            Ok((None, content_split))
        } else {
            Ok((Some(front_split), content_split))
        }
    } else {
        deprecated_split_front_matter(content)
    }
}

fn deprecated_split_front_matter(content: &str) -> Result<(Option<&str>, &str)> {
    lazy_static! {
        static ref FRONT_MATTER_DIVIDE: regex::Regex =
            regex::Regex::new(r"(\A|\n)---\s*\r?\n").unwrap();
    }
    if FRONT_MATTER_DIVIDE.is_match(content) {
        warn!("Trailing separators are deprecated. We recommend frontmatters be surrounded, above and below, with ---");

        let mut splits = FRONT_MATTER_DIVIDE.splitn(content, 2);

        // above the split are the attributes
        let front_split = splits.next().unwrap_or("");

        // everything below the split becomes the new content
        let content_split = splits.next().unwrap_or("");

        if front_split.is_empty() {
            Ok((None, content_split))
        } else {
            Ok((Some(front_split), content_split))
        }
    } else {
        Ok((None, content))
    }
}

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

    #[test]
    fn split_document_empty() {
        let input = "";
        let (cobalt_model, content) = split_document(input).unwrap();
        assert!(cobalt_model.is_none());
        assert_eq!(content, "");
    }

    #[test]
    fn split_document_no_front_matter() {
        let input = "Body";
        let (cobalt_model, content) = split_document(input).unwrap();
        assert!(cobalt_model.is_none());
        assert_eq!(content, "Body");
    }

    #[test]
    fn split_document_deprecated_empty_front_matter() {
        let input = "---\nBody";
        let (cobalt_model, content) = split_document(input).unwrap();
        assert!(cobalt_model.is_none());
        assert_eq!(content, "Body");
    }

    #[test]
    fn split_document_empty_front_matter() {
        let input = "---\n---\nBody";
        let (cobalt_model, content) = split_document(input).unwrap();
        assert!(cobalt_model.is_none());
        assert_eq!(content, "Body");
    }

    #[test]
    fn split_document_deprecated_empty_body() {
        let input = "cobalt_model\n---\n";
        let (cobalt_model, content) = split_document(input).unwrap();
        assert_eq!(cobalt_model.unwrap(), "cobalt_model");
        assert_eq!(content, "");
    }

    #[test]
    fn split_document_empty_body() {
        let input = "---\ncobalt_model\n---\n";
        let (cobalt_model, content) = split_document(input).unwrap();
        assert_eq!(cobalt_model.unwrap(), "cobalt_model\n");
        assert_eq!(content, "");
    }

    #[test]
    fn split_document_front_matter_and_body() {
        let input = "---\ncobalt_model\n---\nbody";
        let (cobalt_model, content) = split_document(input).unwrap();
        assert_eq!(cobalt_model.unwrap(), "cobalt_model\n");
        assert_eq!(content, "body");
    }

    #[test]
    fn split_document_no_new_line_after_front_matter() {
        let input = "invalid_front_matter---\nbody";
        let (cobalt_model, content) = split_document(input).unwrap();
        assert!(cobalt_model.is_none());
        assert_eq!(content, input);
    }

    #[test]
    fn document_format_empty_has_no_front() {
        let doc = DocumentBuilder::<frontmatter::FrontmatterBuilder>::default();
        let doc = doc.to_string();
        assert_eq!(doc, "");
    }
}
<|endoftext|>


<commit_before>// build.rs

use rustc_version::{version, Version};
#[allow(unused_imports)]
use std::env;
use std::fs;
use std::path::Path;
use std::process::exit;

#[allow(dead_code)]
fn rerun_dir<P: AsRef<Path>>(dir: P) {
  for entry in fs::read_dir(dir).unwrap() {
    let entry = entry.unwrap();
    let path = entry.path();
    println!("cargo:rerun-if-changed={}", path.to_string_lossy());

    if path.is_dir() {
      rerun_dir(path);
    }
  }
}

#[cfg(feature = "asm")]
fn build_nasm_files() {
  use std::fs::File;
  use std::io::Write;
  let out_dir = env::var("OUT_DIR").unwrap();
  {
    let dest_path = Path::new(&out_dir).join("config.asm");
    let mut config_file = File::create(dest_path).unwrap();
    config_file.write(b"	%define private_prefix rav1e\n").unwrap();
    config_file.write(b"	%define ARCH_X86_32 0\n").unwrap();
    config_file.write(b" %define ARCH_X86_64 1\n").unwrap();
    config_file.write(b"	%define PIC 1\n").unwrap();
    config_file.write(b" %define STACK_ALIGNMENT 16\n").unwrap();
    if cfg!(target_os = "macos") {
      config_file.write(b" %define PREFIX 1\n").unwrap();
    }
  }
  let mut config_include_arg = String::from("-I");
  config_include_arg.push_str(&out_dir);
  config_include_arg.push('/');
  nasm_rs::compile_library_args(
    "rav1easm",
    &[
      "src/x86/ipred.asm",
      "src/x86/ipred_ssse3.asm",
      "src/x86/itx.asm",
      "src/x86/itx_ssse3.asm",
      "src/x86/mc.asm",
      "src/x86/mc_ssse3.asm",
      "src/x86/me.asm",
      "src/x86/sad_sse2.asm",
      "src/x86/sad_avx.asm",
      "src/x86/satd.asm",
      "src/x86/cdef.asm",
    ],
    &[&config_include_arg, "-Isrc/"],
  );
  println!("cargo:rustc-link-lib=static=rav1easm");
  rerun_dir("src/x86");
  rerun_dir("src/ext/x86");
}

fn rustc_version_check() {
  // This should match the version in .travis.yml
  const REQUIRED_VERSION: &str = "1.36.0";
  if version().unwrap() < Version::parse(REQUIRED_VERSION).unwrap() {
    eprintln!("rav1e requires rustc >= {}.", REQUIRED_VERSION);
    exit(1);
  }
}

#[allow(unused_variables)]
fn main() {
  rustc_version_check();

  let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
  let os = env::var("CARGO_CFG_TARGET_OS").unwrap();
  // let env = env::var("CARGO_CFG_TARGET_ENV").unwrap();

  #[cfg(feature = "asm")]
  {
    if arch == "x86_64" {
      println!("cargo:rustc-cfg={}", "nasm_x86_64");
      build_nasm_files()
    }
  }

  if os == "windows" && cfg!(feature = "decode_test") {
    panic!("Unsupported feature on this platform!");
  }

  vergen::generate_cargo_keys(vergen::ConstantsFlags::all())
    .expect("Unable to generate the cargo keys!");
}
<commit_msg>Build mc.S imported from dav1d 0.1 release<commit_after>// build.rs

use rustc_version::{version, Version};
#[allow(unused_imports)]
use std::env;
use std::fs;
use std::path::Path;
use std::process::exit;

#[allow(dead_code)]
fn rerun_dir<P: AsRef<Path>>(dir: P) {
  for entry in fs::read_dir(dir).unwrap() {
    let entry = entry.unwrap();
    let path = entry.path();
    println!("cargo:rerun-if-changed={}", path.to_string_lossy());

    if path.is_dir() {
      rerun_dir(path);
    }
  }
}

#[cfg(feature = "asm")]
fn build_nasm_files() {
  use std::fs::File;
  use std::io::Write;
  let out_dir = env::var("OUT_DIR").unwrap();
  {
    let dest_path = Path::new(&out_dir).join("config.asm");
    let mut config_file = File::create(dest_path).unwrap();
    config_file.write(b"	%define private_prefix rav1e\n").unwrap();
    config_file.write(b"	%define ARCH_X86_32 0\n").unwrap();
    config_file.write(b" %define ARCH_X86_64 1\n").unwrap();
    config_file.write(b"	%define PIC 1\n").unwrap();
    config_file.write(b" %define STACK_ALIGNMENT 16\n").unwrap();
    if cfg!(target_os = "macos") {
      config_file.write(b" %define PREFIX 1\n").unwrap();
    }
  }
  let mut config_include_arg = String::from("-I");
  config_include_arg.push_str(&out_dir);
  config_include_arg.push('/');
  nasm_rs::compile_library_args(
    "rav1easm",
    &[
      "src/x86/ipred.asm",
      "src/x86/ipred_ssse3.asm",
      "src/x86/itx.asm",
      "src/x86/itx_ssse3.asm",
      "src/x86/mc.asm",
      "src/x86/mc_ssse3.asm",
      "src/x86/me.asm",
      "src/x86/sad_sse2.asm",
      "src/x86/sad_avx.asm",
      "src/x86/satd.asm",
      "src/x86/cdef.asm",
    ],
    &[&config_include_arg, "-Isrc/"],
  );
  println!("cargo:rustc-link-lib=static=rav1easm");
  rerun_dir("src/x86");
  rerun_dir("src/ext/x86");
}

#[cfg(feature = "asm")]
fn build_asm_files() {
  use std::fs::File;
  use std::io::Write;
  let out_dir = env::var("OUT_DIR").unwrap();
  {
    let dest_path = Path::new(&out_dir).join("config.h");
    let mut config_file = File::create(dest_path).unwrap();
    config_file.write(b" #define PRIVATE_PREFIX rav1e_\n").unwrap();
    config_file.write(b" #define ARCH_AARCH64 1\n").unwrap();
    config_file.write(b" #define ARCH_ARM 0\n").unwrap();
    config_file.write(b" #define CONFIG_LOG 1 \n").unwrap();
    config_file.write(b" #define HAVE_ASM 1\n").unwrap();
  }
  cc::Build::new()
    .files(&["src/arm/64/mc.S"])
    .include(".")
    .include(&out_dir)
    .compile("rav1e-aarch64");
  rerun_dir("src/arm");
}

fn rustc_version_check() {
  // This should match the version in .travis.yml
  const REQUIRED_VERSION: &str = "1.36.0";
  if version().unwrap() < Version::parse(REQUIRED_VERSION).unwrap() {
    eprintln!("rav1e requires rustc >= {}.", REQUIRED_VERSION);
    exit(1);
  }
}

#[allow(unused_variables)]
fn main() {
  rustc_version_check();

  let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
  let os = env::var("CARGO_CFG_TARGET_OS").unwrap();
  // let env = env::var("CARGO_CFG_TARGET_ENV").unwrap();

  #[cfg(feature = "asm")]
  {
    if arch == "x86_64" {
      println!("cargo:rustc-cfg={}", "nasm_x86_64");
      build_nasm_files()
    }
    if arch == "aarch64" {
      println!("cargo:rustc-cfg={}", "asm_neon");
      build_asm_files()
    }
  }

  if os == "windows" && cfg!(feature = "decode_test") {
    panic!("Unsupported feature on this platform!");
  }

  vergen::generate_cargo_keys(vergen::ConstantsFlags::all())
    .expect("Unable to generate the cargo keys!");
}
<|endoftext|>


<commit_before>// 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::HashMap;
use std::fmt;

use english_cardinal_classifier;
use {Args, Context, Message, MessagePart, PluralCategory, Value};

/// Format a value taking pluralization rules into account.
#[derive(Debug)]
pub struct PluralFormat {
    /// The name of the variable whose value should be formatted.
    variable_name: String,
    classifier: fn(i64) -> PluralCategory,
    literals: HashMap<i64, Message>,
    offset: i64,
    zero: Option<Message>,
    one: Option<Message>,
    two: Option<Message>,
    few: Option<Message>,
    many: Option<Message>,
    other: Message,
}

impl PluralFormat {
    /// Construct a `PluralFormat`.
    pub fn new(variable_name: &str, other: Message) -> Self {
        PluralFormat {
            variable_name: variable_name.to_string(),
            classifier: english_cardinal_classifier,
            literals: HashMap::new(),
            offset: 0,
            zero: None,
            one: None,
            two: None,
            few: None,
            many: None,
            other: other,
        }
    }

    /// Set the `message` to be used for a literal value.
    pub fn literal(&mut self, literal: i64, message: Message) {
        self.literals.insert(literal, message);
    }

    /// Apply an `offset`.
    pub fn offset(&mut self, offset: i64) {
        self.offset = offset;
    }

    /// Set the `message` for `PluralCategory::Zero`.
    pub fn zero(&mut self, message: Message) {
        self.zero = Some(message);
    }

    /// Set the `message` for `PluralCategory::One`.
    pub fn one(&mut self, message: Message) {
        self.one = Some(message);
    }

    /// Set the `message` for `PluralCategory::Two`.
    pub fn two(&mut self, message: Message) {
        self.two = Some(message);
    }

    /// Set the `message` for `PluralCategory::Few`.
    pub fn few(&mut self, message: Message) {
        self.few = Some(message);
    }

    /// Set the `message` for `PluralCategory::Many`.
    pub fn many(&mut self, message: Message) {
        self.many = Some(message);
    }

    /// Given a value adjusted by the `offset`, determine which `Message` to use.
    fn lookup_message(&self, offset_value: i64) -> &Message {
        if let Some(literal) = self.literals.get(&offset_value) {
            literal
        } else {
            let category = (self.classifier)(offset_value);
            match category {
                PluralCategory::Zero => self.zero.as_ref().unwrap_or(&self.other),
                PluralCategory::One => self.one.as_ref().unwrap_or(&self.other),
                PluralCategory::Two => self.two.as_ref().unwrap_or(&self.other),
                PluralCategory::Few => self.few.as_ref().unwrap_or(&self.other),
                PluralCategory::Many => self.many.as_ref().unwrap_or(&self.other),
                PluralCategory::Other => &self.other,
            }
        }
    }
}

impl MessagePart for PluralFormat {
    fn apply_format<'f>(&'f self,
                        context: &Context,
                        stream: &mut fmt::Write,
                        args: &'f Args<'f>)
                        -> fmt::Result {
        if let Some(arg) = args.get(&self.variable_name) {
            let value = match *arg.value() {
                Value::Number(n) => n,
                _ => panic!("Wrong variable type."),
            };
            let offset_value = value - self.offset;
            let message = self.lookup_message(offset_value);
            try!(message.write_message(context, stream, args));
        }
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use icu::parse;
    use super::PluralFormat;
    use {arg, Context, MessagePart};

    #[test]
    fn it_works() {
        let context = Context::new(None);
        let mut fmt = PluralFormat::new("count", parse("Other").unwrap());
        fmt.one(parse("One").unwrap());

        let mut output = String::new();
        fmt.apply_format(&context, &mut output, &arg("count", 0)).unwrap();
        assert_eq!("Other", output);

        let mut output = String::new();
        fmt.apply_format(&context, &mut output, &arg("count", 1)).unwrap();
        assert_eq!("One", output);

        let mut output = String::new();
        fmt.apply_format(&context, &mut output, &arg("count", 3)).unwrap();
        assert_eq!("Other", output);
    }
}
<commit_msg>Replace context with updated one with correct placeholder value.<commit_after>// 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::HashMap;
use std::fmt;

use english_cardinal_classifier;
use {Args, Context, Message, MessagePart, PluralCategory, Value};

/// Format a value taking pluralization rules into account.
#[derive(Debug)]
pub struct PluralFormat {
    /// The name of the variable whose value should be formatted.
    variable_name: String,
    classifier: fn(i64) -> PluralCategory,
    literals: HashMap<i64, Message>,
    offset: i64,
    zero: Option<Message>,
    one: Option<Message>,
    two: Option<Message>,
    few: Option<Message>,
    many: Option<Message>,
    other: Message,
}

impl PluralFormat {
    /// Construct a `PluralFormat`.
    pub fn new(variable_name: &str, other: Message) -> Self {
        PluralFormat {
            variable_name: variable_name.to_string(),
            classifier: english_cardinal_classifier,
            literals: HashMap::new(),
            offset: 0,
            zero: None,
            one: None,
            two: None,
            few: None,
            many: None,
            other: other,
        }
    }

    /// Set the `message` to be used for a literal value.
    pub fn literal(&mut self, literal: i64, message: Message) {
        self.literals.insert(literal, message);
    }

    /// Apply an `offset`.
    pub fn offset(&mut self, offset: i64) {
        self.offset = offset;
    }

    /// Set the `message` for `PluralCategory::Zero`.
    pub fn zero(&mut self, message: Message) {
        self.zero = Some(message);
    }

    /// Set the `message` for `PluralCategory::One`.
    pub fn one(&mut self, message: Message) {
        self.one = Some(message);
    }

    /// Set the `message` for `PluralCategory::Two`.
    pub fn two(&mut self, message: Message) {
        self.two = Some(message);
    }

    /// Set the `message` for `PluralCategory::Few`.
    pub fn few(&mut self, message: Message) {
        self.few = Some(message);
    }

    /// Set the `message` for `PluralCategory::Many`.
    pub fn many(&mut self, message: Message) {
        self.many = Some(message);
    }

    /// Given a value adjusted by the `offset`, determine which `Message` to use.
    fn lookup_message(&self, offset_value: i64) -> &Message {
        if let Some(literal) = self.literals.get(&offset_value) {
            literal
        } else {
            let category = (self.classifier)(offset_value);
            match category {
                PluralCategory::Zero => self.zero.as_ref().unwrap_or(&self.other),
                PluralCategory::One => self.one.as_ref().unwrap_or(&self.other),
                PluralCategory::Two => self.two.as_ref().unwrap_or(&self.other),
                PluralCategory::Few => self.few.as_ref().unwrap_or(&self.other),
                PluralCategory::Many => self.many.as_ref().unwrap_or(&self.other),
                PluralCategory::Other => &self.other,
            }
        }
    }
}

impl MessagePart for PluralFormat {
    fn apply_format<'f>(&'f self,
                        context: &Context,
                        stream: &mut fmt::Write,
                        args: &'f Args<'f>)
                        -> fmt::Result {
        if let Some(arg) = args.get(&self.variable_name) {
            let value = match *arg.value() {
                Value::Number(n) => n,
                _ => panic!("Wrong variable type."),
            };
            let offset_value = value - self.offset;
            let message = self.lookup_message(offset_value);
            let context = Context { placeholder_value: Some(offset_value), ..*context };
            try!(message.write_message(&context, stream, args));
        }
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use icu::parse;
    use super::PluralFormat;
    use {arg, Context, MessagePart};

    #[test]
    fn it_works() {
        let context = Context::new(None);
        let mut fmt = PluralFormat::new("count", parse("Other").unwrap());
        fmt.one(parse("One").unwrap());

        let mut output = String::new();
        fmt.apply_format(&context, &mut output, &arg("count", 0)).unwrap();
        assert_eq!("Other", output);

        let mut output = String::new();
        fmt.apply_format(&context, &mut output, &arg("count", 1)).unwrap();
        assert_eq!("One", output);

        let mut output = String::new();
        fmt.apply_format(&context, &mut output, &arg("count", 3)).unwrap();
        assert_eq!("Other", output);
    }
}
<|endoftext|>


<commit_before>//! Representation of migrations

use crate::backend::Backend;
use crate::connection::{BoxableConnection, Connection};
use crate::deserialize::{FromSql, FromSqlRow};
use crate::expression::AsExpression;
use crate::result::QueryResult;
use crate::serialize::ToSql;
use crate::sql_types::Text;
use std::borrow::Cow;
use std::error::Error;
use std::fmt::Display;

/// A specialized result type representing the result of
/// a migration operation
pub type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>;

/// A migration version identifier
///
/// This is used by the migration harness to place migrations
/// in order, therefore two different instances of this type
/// must be sortable
#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, FromSqlRow, AsExpression)]
#[diesel(sql_type = Text)]
pub struct MigrationVersion<'a>(Cow<'a, str>);

impl<'a> MigrationVersion<'a> {
    /// Convert the current migration version into
    /// an owned variant with static life time
    pub fn as_owned(&self) -> MigrationVersion<'static> {
        MigrationVersion(Cow::Owned(self.0.as_ref().to_owned()))
    }
}

impl<'a, DB> FromSql<Text, DB> for MigrationVersion<'a>
where
    String: FromSql<Text, DB>,
    DB: Backend,
{
    fn from_sql(bytes: crate::backend::RawValue<'_, DB>) -> crate::deserialize::Result<Self> {
        let s = String::from_sql(bytes)?;
        Ok(Self(Cow::Owned(s)))
    }
}

impl<'a, DB> ToSql<Text, DB> for MigrationVersion<'a>
where
    Cow<'a, str>: ToSql<Text, DB>,
    DB: Backend,
{
    fn to_sql<'b>(
        &'b self,
        out: &mut crate::serialize::Output<'b, '_, DB>,
    ) -> crate::serialize::Result {
        self.0.to_sql(out)
    }
}

impl<'a> From<String> for MigrationVersion<'a> {
    fn from(s: String) -> Self {
        MigrationVersion(Cow::Owned(s))
    }
}

impl<'a> From<&'a str> for MigrationVersion<'a> {
    fn from(s: &'a str) -> Self {
        MigrationVersion(Cow::Borrowed(s))
    }
}

impl<'a> From<&'a String> for MigrationVersion<'a> {
    fn from(s: &'a String) -> Self {
        MigrationVersion(Cow::Borrowed(s))
    }
}

impl<'a> Display for MigrationVersion<'a> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(self.0.as_ref())
    }
}

/// Represents the name of a migration
///
/// Users should threat this as `impl Display` type,
/// for implementors of custom migration types
/// this opens the possibility to roll out their own versioning
/// schema.
pub trait MigrationName: Display {
    /// The version corresponding to the current migration name
    fn version(&self) -> MigrationVersion<'_>;
}

/// Represents a migration that interacts with diesel
pub trait Migration<DB: Backend> {
    /// Apply this migration
    fn run(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()>;

    /// Revert this migration
    fn revert(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()>;

    /// Get a the attached metadata for this migration
    fn metadata(&self) -> &dyn MigrationMetadata;

    /// Get the name of the current migration
    ///
    /// The provided name is used by migration harness
    /// to get the version of a migration and to
    /// as something to that is displayed and allows
    /// user to identify a specific migration
    fn name(&self) -> &dyn MigrationName;
}

/// This trait is designed to customize the behaviour
/// of the default migration harness of diesel
///
/// Any new customization option will be added
/// as new function here. Each new function
/// will have a default implementation
/// returning the old a value corresponding
/// to the old uncustomized behaviour
pub trait MigrationMetadata {
    /// Whether the current migration is executed in a transaction or not
    ///
    /// By default each migration is executed in a own transaction, but
    /// certain operations (like creating an index on an existing column)
    /// requires running the migration without transaction.
    ///
    /// By default this function returns true
    fn run_in_transaction(&self) -> bool {
        true
    }
}

/// A migration source is an entity that can be used
/// to receive a number of migrations from.
pub trait MigrationSource<DB: Backend> {
    /// Get a list of migrations associated with this
    /// migration soucre.
    fn migrations(&self) -> Result<Vec<Box<dyn Migration<DB>>>>;
}

impl<'a, DB: Backend> Migration<DB> for Box<dyn Migration<DB> + 'a> {
    fn run(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()> {
        (&**self).run(conn)
    }

    fn revert(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()> {
        (&**self).revert(conn)
    }

    fn metadata(&self) -> &dyn MigrationMetadata {
        (&**self).metadata()
    }

    fn name(&self) -> &dyn MigrationName {
        (&**self).name()
    }
}

impl<'a, DB: Backend> Migration<DB> for &'a dyn Migration<DB> {
    fn run(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()> {
        (&**self).run(conn)
    }

    fn revert(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()> {
        (&**self).revert(conn)
    }

    fn metadata(&self) -> &dyn MigrationMetadata {
        (&**self).metadata()
    }

    fn name(&self) -> &dyn MigrationName {
        (&**self).name()
    }
}

/// Create table statement for the `__diesel_schema_migrations` used
/// used by the postgresql, sqlite and mysql backend
pub const CREATE_MIGRATIONS_TABLE: &str = include_str!("setup_migration_table.sql");

/// A trait indicating that a connection could be used to manage migrations
///
/// Only custom backend implementations need to think about this trait
pub trait MigrationConnection: Connection {
    /// Setup the following table:
    ///
    /// ```rust
    /// diesel::table! {
    ///      __diesel_schema_migrations(version) {
    ///          version -> Text,
    ///          /// defaults to `CURRENT_TIMESTAMP`
    ///          run_on -> Timestamp,
    ///      }
    /// }
    /// ```
    fn setup(&mut self) -> QueryResult<usize>;
}

#[cfg(feature = "postgres")]
impl MigrationConnection for crate::pg::PgConnection {
    fn setup(&mut self) -> QueryResult<usize> {
        use crate::RunQueryDsl;
        crate::sql_query(CREATE_MIGRATIONS_TABLE).execute(self)
    }
}

#[cfg(feature = "mysql")]
impl MigrationConnection for crate::mysql::MysqlConnection {
    fn setup(&mut self) -> QueryResult<usize> {
        use crate::RunQueryDsl;
        crate::sql_query(CREATE_MIGRATIONS_TABLE).execute(self)
    }
}

#[cfg(feature = "sqlite")]
impl MigrationConnection for crate::sqlite::SqliteConnection {
    fn setup(&mut self) -> QueryResult<usize> {
        use crate::RunQueryDsl;
        crate::sql_query(CREATE_MIGRATIONS_TABLE).execute(self)
    }
}
<commit_msg>Fix `clippy::needless-borrow` warnings<commit_after>//! Representation of migrations

use crate::backend::Backend;
use crate::connection::{BoxableConnection, Connection};
use crate::deserialize::{FromSql, FromSqlRow};
use crate::expression::AsExpression;
use crate::result::QueryResult;
use crate::serialize::ToSql;
use crate::sql_types::Text;
use std::borrow::Cow;
use std::error::Error;
use std::fmt::Display;

/// A specialized result type representing the result of
/// a migration operation
pub type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>;

/// A migration version identifier
///
/// This is used by the migration harness to place migrations
/// in order, therefore two different instances of this type
/// must be sortable
#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, FromSqlRow, AsExpression)]
#[diesel(sql_type = Text)]
pub struct MigrationVersion<'a>(Cow<'a, str>);

impl<'a> MigrationVersion<'a> {
    /// Convert the current migration version into
    /// an owned variant with static life time
    pub fn as_owned(&self) -> MigrationVersion<'static> {
        MigrationVersion(Cow::Owned(self.0.as_ref().to_owned()))
    }
}

impl<'a, DB> FromSql<Text, DB> for MigrationVersion<'a>
where
    String: FromSql<Text, DB>,
    DB: Backend,
{
    fn from_sql(bytes: crate::backend::RawValue<'_, DB>) -> crate::deserialize::Result<Self> {
        let s = String::from_sql(bytes)?;
        Ok(Self(Cow::Owned(s)))
    }
}

impl<'a, DB> ToSql<Text, DB> for MigrationVersion<'a>
where
    Cow<'a, str>: ToSql<Text, DB>,
    DB: Backend,
{
    fn to_sql<'b>(
        &'b self,
        out: &mut crate::serialize::Output<'b, '_, DB>,
    ) -> crate::serialize::Result {
        self.0.to_sql(out)
    }
}

impl<'a> From<String> for MigrationVersion<'a> {
    fn from(s: String) -> Self {
        MigrationVersion(Cow::Owned(s))
    }
}

impl<'a> From<&'a str> for MigrationVersion<'a> {
    fn from(s: &'a str) -> Self {
        MigrationVersion(Cow::Borrowed(s))
    }
}

impl<'a> From<&'a String> for MigrationVersion<'a> {
    fn from(s: &'a String) -> Self {
        MigrationVersion(Cow::Borrowed(s))
    }
}

impl<'a> Display for MigrationVersion<'a> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(self.0.as_ref())
    }
}

/// Represents the name of a migration
///
/// Users should threat this as `impl Display` type,
/// for implementors of custom migration types
/// this opens the possibility to roll out their own versioning
/// schema.
pub trait MigrationName: Display {
    /// The version corresponding to the current migration name
    fn version(&self) -> MigrationVersion<'_>;
}

/// Represents a migration that interacts with diesel
pub trait Migration<DB: Backend> {
    /// Apply this migration
    fn run(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()>;

    /// Revert this migration
    fn revert(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()>;

    /// Get a the attached metadata for this migration
    fn metadata(&self) -> &dyn MigrationMetadata;

    /// Get the name of the current migration
    ///
    /// The provided name is used by migration harness
    /// to get the version of a migration and to
    /// as something to that is displayed and allows
    /// user to identify a specific migration
    fn name(&self) -> &dyn MigrationName;
}

/// This trait is designed to customize the behaviour
/// of the default migration harness of diesel
///
/// Any new customization option will be added
/// as new function here. Each new function
/// will have a default implementation
/// returning the old a value corresponding
/// to the old uncustomized behaviour
pub trait MigrationMetadata {
    /// Whether the current migration is executed in a transaction or not
    ///
    /// By default each migration is executed in a own transaction, but
    /// certain operations (like creating an index on an existing column)
    /// requires running the migration without transaction.
    ///
    /// By default this function returns true
    fn run_in_transaction(&self) -> bool {
        true
    }
}

/// A migration source is an entity that can be used
/// to receive a number of migrations from.
pub trait MigrationSource<DB: Backend> {
    /// Get a list of migrations associated with this
    /// migration soucre.
    fn migrations(&self) -> Result<Vec<Box<dyn Migration<DB>>>>;
}

impl<'a, DB: Backend> Migration<DB> for Box<dyn Migration<DB> + 'a> {
    fn run(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()> {
        (**self).run(conn)
    }

    fn revert(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()> {
        (**self).revert(conn)
    }

    fn metadata(&self) -> &dyn MigrationMetadata {
        (**self).metadata()
    }

    fn name(&self) -> &dyn MigrationName {
        (**self).name()
    }
}

impl<'a, DB: Backend> Migration<DB> for &'a dyn Migration<DB> {
    fn run(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()> {
        (**self).run(conn)
    }

    fn revert(&self, conn: &mut dyn BoxableConnection<DB>) -> Result<()> {
        (**self).revert(conn)
    }

    fn metadata(&self) -> &dyn MigrationMetadata {
        (**self).metadata()
    }

    fn name(&self) -> &dyn MigrationName {
        (**self).name()
    }
}

/// Create table statement for the `__diesel_schema_migrations` used
/// used by the postgresql, sqlite and mysql backend
pub const CREATE_MIGRATIONS_TABLE: &str = include_str!("setup_migration_table.sql");

/// A trait indicating that a connection could be used to manage migrations
///
/// Only custom backend implementations need to think about this trait
pub trait MigrationConnection: Connection {
    /// Setup the following table:
    ///
    /// ```rust
    /// diesel::table! {
    ///      __diesel_schema_migrations(version) {
    ///          version -> Text,
    ///          /// defaults to `CURRENT_TIMESTAMP`
    ///          run_on -> Timestamp,
    ///      }
    /// }
    /// ```
    fn setup(&mut self) -> QueryResult<usize>;
}

#[cfg(feature = "postgres")]
impl MigrationConnection for crate::pg::PgConnection {
    fn setup(&mut self) -> QueryResult<usize> {
        use crate::RunQueryDsl;
        crate::sql_query(CREATE_MIGRATIONS_TABLE).execute(self)
    }
}

#[cfg(feature = "mysql")]
impl MigrationConnection for crate::mysql::MysqlConnection {
    fn setup(&mut self) -> QueryResult<usize> {
        use crate::RunQueryDsl;
        crate::sql_query(CREATE_MIGRATIONS_TABLE).execute(self)
    }
}

#[cfg(feature = "sqlite")]
impl MigrationConnection for crate::sqlite::SqliteConnection {
    fn setup(&mut self) -> QueryResult<usize> {
        use crate::RunQueryDsl;
        crate::sql_query(CREATE_MIGRATIONS_TABLE).execute(self)
    }
}
<|endoftext|>


<commit_before>#[derive(Debug)]
enum Direction {
    Diagonal,
    Up,
    Left,
}

use Direction::*;
use std::cmp::max;

fn get_hsp(w1: &String, w2: &String, match_scr: i32, mism_scr: i32, gap_scr: i32) -> i32 {
    let mut hsp = 0;

    let mut chars2 = w2.chars();
    for c1 in w1.chars() {
        let c2 = chars2.next().unwrap();
        hsp += if c1 == c2 {
            match_scr
        } else if c1 == '_' || c2 == '_' {
            gap_scr
        } else {
            mism_scr
        }
    }

    hsp
}

fn get_score(a: char, b: char) -> i32 {
    if a == b { 1 } else { -1 }
}

fn align_secuence(sec_1: &str, sec_2: &str) -> (String, String) {
    let len_1 = sec_1.len() + 1;
    let len_2 = sec_2.len() + 1;

    /********* Initialize matrix **********/
    let mut matrix: Vec<Vec<i32>> = vec![vec![0; len_1]; len_2];

    let mut init_val = -5;
    for i in 1..len_1 {
        matrix[0][i] = init_val;
        init_val -= 5;
    }

    init_val = -5;
    for i in 1..len_2 {
        matrix[i][0] = init_val;
        init_val -= 5;
    }
    /**************************************/

    let mut diag_val;
    let mut left_val;
    let mut uppr_val;

    let mut i = 1;
    let mut j;
    for c2 in sec_2.chars() {
        j = 1;
        for c1 in sec_1.chars() {
            let score = get_score(c2, c1);
            diag_val = score + matrix[i - 1][j - 1];
            left_val = -2 + matrix[i][j - 1];
            uppr_val = -2 + matrix[i - 1][j];
            matrix[i][j] = max(diag_val, max(left_val, uppr_val));
            j += 1;
        }
        i += 1;
    }

    /************** Alignment **************/
    let mut align1 = String::new();
    let mut align2 = String::new();

    i = sec_2.len();
    j = sec_1.len();

    let mut direct = Diagonal;
    let mut greater;
    loop {
        if i == 0 || j == 0 {
            break;
        }

        diag_val = matrix[i - 1][j - 1];
        left_val = matrix[i][j - 1];
        uppr_val = matrix[i - 1][j];
        greater = max(diag_val, max(left_val, uppr_val));

        match direct {
            Diagonal => {
                align1.push(sec_1.as_bytes()[j - 1] as char);
                align2.push(sec_2.as_bytes()[i - 1] as char);
            }
            Up => {
                align1.push('_');
                align2.push(sec_2.as_bytes()[i - 1] as char);
            }
            Left => {
                align1.push(sec_1.as_bytes()[j - 1] as char);
                align2.push('_');
            }
        }

        if greater == diag_val {
            direct = Diagonal;
            i -= 1;
            j -= 1;
        } else if greater == left_val {
            direct = Left;
            j -= 1;
        } else if greater == uppr_val {
            direct = Up;
            i -= 1;
        }
    }
    /****************************************/

    align1 = align1.chars().rev().collect::<String>();
    align2 = align2.chars().rev().collect::<String>();

    (align2, align1)
}

fn tps_alignment(seqs: Vec<&str>) {
    let len = seqs.len();

    for i in 0..len {
        let mut j = i + 1;
        while j < len {
            let aligns = align_secuence(seqs[i], seqs[j]);
            println!("{}", get_hsp(&aligns.0, &aligns.1, 0, 3, 2));
            j += 1;
        }
    }
}

fn main() {
    let seqs: Vec<&str> = vec!["ACTCAT",
                               "AGTCAT",
                               "ACGTCCT"];
    tps_alignment(seqs);
}
<commit_msg>After class<commit_after>#[derive(Debug)]
enum Direction {
    Diagonal,
    Up,
    Left,
}

use Direction::*;
use std::cmp::max;

fn get_hsp(w1: &String, w2: &String, match_scr: i32, mism_scr: i32, gap_scr: i32) -> i32 {
    let mut hsp = 0;

    let mut chars2 = w2.chars();
    for c1 in w1.chars() {
        let c2 = chars2.next().unwrap();
        hsp += if c1 == c2 {
            match_scr
        } else if c1 == '_' || c2 == '_' {
            gap_scr
        } else {
            mism_scr
        }
    }

    hsp
}

fn get_score(a: char, b: char) -> i32 {
    if a == b { 1 } else { -1 }
}

fn align_secuence(sec_1: &str, sec_2: &str) -> (String, String) {
    let len_1 = sec_1.len() + 1;
    let len_2 = sec_2.len() + 1;

    /********* Initialize matrix **********/
    let mut matrix: Vec<Vec<i32>> = vec![vec![0; len_1]; len_2];

    let mut init_val = -5;
    for i in 1..len_1 {
        matrix[0][i] = init_val;
        init_val -= 5;
    }

    init_val = -5;
    for i in 1..len_2 {
        matrix[i][0] = init_val;
        init_val -= 5;
    }
    /**************************************/

    let mut diag_val;
    let mut left_val;
    let mut uppr_val;

    let mut i = 1;
    let mut j;
    for c2 in sec_2.chars() {
        j = 1;
        for c1 in sec_1.chars() {
            let score = get_score(c2, c1);
            diag_val = score + matrix[i - 1][j - 1];
            left_val = -2 + matrix[i][j - 1];
            uppr_val = -2 + matrix[i - 1][j];
            matrix[i][j] = max(diag_val, max(left_val, uppr_val));
            j += 1;
        }
        i += 1;
    }

    /************** Alignment **************/
    let mut align1 = String::new();
    let mut align2 = String::new();

    i = sec_2.len();
    j = sec_1.len();

    let mut direct = Diagonal;
    let mut greater;
    loop {
        if i == 0 || j == 0 {
            break;
        }

        diag_val = matrix[i - 1][j - 1];
        left_val = matrix[i][j - 1];
        uppr_val = matrix[i - 1][j];
        greater = max(diag_val, max(left_val, uppr_val));

        match direct {
            Diagonal => {
                align1.push(sec_1.as_bytes()[j - 1] as char);
                align2.push(sec_2.as_bytes()[i - 1] as char);
            }
            Up => {
                align1.push('_');
                align2.push(sec_2.as_bytes()[i - 1] as char);
            }
            Left => {
                align1.push(sec_1.as_bytes()[j - 1] as char);
                align2.push('_');
            }
        }

        if greater == diag_val {
            direct = Diagonal;
            i -= 1;
            j -= 1;
        } else if greater == left_val {
            direct = Left;
            j -= 1;
        } else if greater == uppr_val {
            direct = Up;
            i -= 1;
        }
    }
    /****************************************/

    align1 = align1.chars().rev().collect::<String>();
    align2 = align2.chars().rev().collect::<String>();

    (align2, align1)
}

fn tps_alignment(seqs: Vec<&str>) {
    let len = seqs.len();

    let m
    for i in 0..len {
        let mut j = i + 1;
        while j < len {
            let aligns = align_secuence(seqs[i], seqs[j]);
            println!("{}", get_hsp(&aligns.0, &aligns.1, 0, 3, 2));
            j += 1;
        }
    }
}

fn main() {
    let seqs: Vec<&str> = vec!["ACTCAT",
                               "AGTCAT",
                               "ACGTCCT"];
    tps_alignment(seqs);
}
<|endoftext|>


<commit_before>//! `coresimd`

#[macro_use]
mod macros;

mod simd;

/// Platform dependent vendor intrinsics.
///
/// This documentation is for the version of this module in the `coresimd`
/// crate, but you probably want to use the [`stdsimd` crate][stdsimd] which
/// should have more complete documentation.
///
/// [stdsimd]: https://rust-lang-nursery.github.io/stdsimd/x86_64/stdsimd/arch/index.html
///
/// Also note that while this module may appear to contains the intrinsics for
/// only one platform it actually contains intrinsics for multiple platforms
/// compiled in conditionally. For other platforms of stdsimd see:
///
/// * [`x86`]
/// * [`x86_64`]
/// * [`arm`]
/// * [`aarch64`]
/// * [`mips`]
/// * [`mips64`]
/// * [`PowerPC`]
/// * [`PowerPC64`]
///
/// [`x86`]: https://rust-lang-nursery.github.io/stdsimd/x86/stdsimd/arch/index.html
/// [`x86_64`]: https://rust-lang-nursery.github.io/stdsimd/x86_64/stdsimd/arch/index.html
/// [`arm`]: https://rust-lang-nursery.github.io/stdsimd/arm/stdsimd/arch/index.html
/// [`aarch64`]: https://rust-lang-nursery.github.io/stdsimd/aarch64/stdsimd/arch/index.html
/// [`mips`]: https://rust-lang-nursery.github.io/stdsimd/mips/stdsimd/arch/index.html
/// [`mips64`]: https://rust-lang-nursery.github.io/stdsimd/mips64/stdsimd/arch/index.html
/// [`PowerPC`]: https://rust-lang-nursery.github.io/stdsimd/powerpc/stdsimd/arch/index.html
/// [`PowerPC64`]: https://rust-lang-nursery.github.io/stdsimd/powerpc64/stdsimd/arch/index.html
#[stable(feature = "simd_arch", since = "1.27.0")]
pub mod arch {
    /// Platform-specific intrinsics for the `x86` platform.
    ///
    /// See the [module documentation](../index.html) for more details.
    #[cfg(any(target_arch = "x86", dox))]
    #[doc(cfg(target_arch = "x86"))]
    #[stable(feature = "simd_x86", since = "1.27.0")]
    pub mod x86 {
        #[stable(feature = "simd_x86", since = "1.27.0")]
        pub use coresimd::x86::*;
    }

    /// Platform-specific intrinsics for the `x86_64` platform.
    ///
    /// See the [module documentation](../index.html) for more details.
    #[cfg(any(target_arch = "x86_64", dox))]
    #[doc(cfg(target_arch = "x86_64"))]
    #[stable(feature = "simd_x86", since = "1.27.0")]
    pub mod x86_64 {
        #[stable(feature = "simd_x86", since = "1.27.0")]
        pub use coresimd::x86::*;
        #[stable(feature = "simd_x86", since = "1.27.0")]
        pub use coresimd::x86_64::*;
    }

    /// Platform-specific intrinsics for the `arm` platform.
    ///
    /// See the [module documentation](../index.html) for more details.
    #[cfg(any(target_arch = "arm", dox))]
    #[doc(cfg(target_arch = "arm"))]
    #[unstable(feature = "stdsimd", issue = "27731")]
    pub mod arm {
        pub use coresimd::arm::*;
    }

    /// Platform-specific intrinsics for the `aarch64` platform.
    ///
    /// See the [module documentation](../index.html) for more details.
    #[cfg(any(target_arch = "aarch64", dox))]
    #[doc(cfg(target_arch = "aarch64"))]
    #[unstable(feature = "stdsimd", issue = "27731")]
    pub mod aarch64 {
        pub use coresimd::aarch64::*;
        pub use coresimd::arm::*;
    }

    /// Platform-specific intrinsics for the `wasm32` platform.
    ///
    /// See the [module documentation](../index.html) for more details.
    #[cfg(target_arch = "wasm32")]
    #[unstable(feature = "stdsimd", issue = "27731")]
    pub mod wasm32 {
        pub use coresimd::wasm32::*;
    }

    /// Platform-specific intrinsics for the `mips` platform.
    ///
    /// See the [module documentation](../index.html) for more details.
    #[cfg(any(target_arch = "mips", dox))]
    #[doc(cfg(target_arch = "mips"))]
    #[unstable(feature = "stdsimd", issue = "27731")]
    pub mod mips {
        pub use coresimd::mips::*;
    }

    /// Platform-specific intrinsics for the `mips64` platform.
    ///
    /// See the [module documentation](../index.html) for more details.
    #[cfg(any(target_arch = "mips64", dox))]
    #[doc(cfg(target_arch = "mips64"))]
    #[unstable(feature = "stdsimd", issue = "27731")]
    pub mod mips64 {
        pub use coresimd::mips::*;
    }

    /// Platform-specific intrinsics for the `PowerPC` platform.
    ///
    /// See the [module documentation](../index.html) for more details.
    #[cfg(any(target_arch = "powerpc", dox))]
    #[doc(cfg(target_arch = "powerpc"))]
    #[unstable(feature = "stdsimd", issue = "27731")]
    pub mod powerpc {
        pub use coresimd::powerpc::*;
    }

    /// Platform-specific intrinsics for the `PowerPC64` platform.
    ///
    /// See the [module documentation](../index.html) for more details.
    #[cfg(any(target_arch = "powerpc64", dox))]
    #[doc(cfg(target_arch = "powerpc64"))]
    #[unstable(feature = "stdsimd", issue = "27731")]
    pub mod powerpc64 {
        pub use coresimd::powerpc64::*;
    }
}

mod simd_llvm;

#[cfg(any(target_arch = "x86", target_arch = "x86_64", dox))]
#[doc(cfg(any(target_arch = "x86", target_arch = "x86_64")))]
mod x86;
#[cfg(any(target_arch = "x86_64", dox))]
#[doc(cfg(target_arch = "x86_64"))]
mod x86_64;

#[cfg(any(target_arch = "aarch64", dox))]
#[doc(cfg(target_arch = "aarch64"))]
mod aarch64;
#[cfg(any(target_arch = "arm", target_arch = "aarch64", dox))]
#[doc(cfg(any(target_arch = "arm", target_arch = "aarch64")))]
mod arm;
#[cfg(target_arch = "wasm32")]
mod wasm32;

#[cfg(any(target_arch = "mips", target_arch = "mips64", dox))]
#[doc(cfg(any(target_arch = "mips", target_arch = "mips64")))]
mod mips;

#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64", dox))]
#[doc(cfg(any(target_arch = "powerpc", target_arch = "powerpc64")))]
mod powerpc;

#[cfg(any(target_arch = "powerpc64", dox))]
#[doc(cfg(target_arch = "powerpc64"))]
mod powerpc64;

mod nvptx;
<commit_msg>Expose NVPTX intrinsics in core::arch<commit_after>//! `coresimd`

#[macro_use]
mod macros;

mod simd;

/// Platform dependent vendor intrinsics.
///
/// This documentation is for the version of this module in the `coresimd`
/// crate, but you probably want to use the [`stdsimd` crate][stdsimd] which
/// should have more complete documentation.
///
/// [stdsimd]: https://rust-lang-nursery.github.io/stdsimd/x86_64/stdsimd/arch/index.html
///
/// Also note that while this module may appear to contains the intrinsics for
/// only one platform it actually contains intrinsics for multiple platforms
/// compiled in conditionally. For other platforms of stdsimd see:
///
/// * [`x86`]
/// * [`x86_64`]
/// * [`arm`]
/// * [`aarch64`]
/// * [`mips`]
/// * [`mips64`]
/// * [`PowerPC`]
/// * [`PowerPC64`]
/// * [`NVPTX`]
///
/// [`x86`]: https://rust-lang-nursery.github.io/stdsimd/x86/stdsimd/arch/index.html
/// [`x86_64`]: https://rust-lang-nursery.github.io/stdsimd/x86_64/stdsimd/arch/index.html
/// [`arm`]: https://rust-lang-nursery.github.io/stdsimd/arm/stdsimd/arch/index.html
/// [`aarch64`]: https://rust-lang-nursery.github.io/stdsimd/aarch64/stdsimd/arch/index.html
/// [`mips`]: https://rust-lang-nursery.github.io/stdsimd/mips/stdsimd/arch/index.html
/// [`mips64`]: https://rust-lang-nursery.github.io/stdsimd/mips64/stdsimd/arch/index.html
/// [`PowerPC`]: https://rust-lang-nursery.github.io/stdsimd/powerpc/stdsimd/arch/index.html
/// [`PowerPC64`]: https://rust-lang-nursery.github.io/stdsimd/powerpc64/stdsimd/arch/index.html
/// [`NVPTX`]: https://rust-lang-nursery.github.io/stdsimd/nvptx/stdsimd/arch/index.html
#[stable(feature = "simd_arch", since = "1.27.0")]
pub mod arch {
    /// Platform-specific intrinsics for the `x86` platform.
    ///
    /// See the [module documentation](../index.html) for more details.
    #[cfg(any(target_arch = "x86", dox))]
    #[doc(cfg(target_arch = "x86"))]
    #[stable(feature = "simd_x86", since = "1.27.0")]
    pub mod x86 {
        #[stable(feature = "simd_x86", since = "1.27.0")]
        pub use coresimd::x86::*;
    }

    /// Platform-specific intrinsics for the `x86_64` platform.
    ///
    /// See the [module documentation](../index.html) for more details.
    #[cfg(any(target_arch = "x86_64", dox))]
    #[doc(cfg(target_arch = "x86_64"))]
    #[stable(feature = "simd_x86", since = "1.27.0")]
    pub mod x86_64 {
        #[stable(feature = "simd_x86", since = "1.27.0")]
        pub use coresimd::x86::*;
        #[stable(feature = "simd_x86", since = "1.27.0")]
        pub use coresimd::x86_64::*;
    }

    /// Platform-specific intrinsics for the `arm` platform.
    ///
    /// See the [module documentation](../index.html) for more details.
    #[cfg(any(target_arch = "arm", dox))]
    #[doc(cfg(target_arch = "arm"))]
    #[unstable(feature = "stdsimd", issue = "27731")]
    pub mod arm {
        pub use coresimd::arm::*;
    }

    /// Platform-specific intrinsics for the `aarch64` platform.
    ///
    /// See the [module documentation](../index.html) for more details.
    #[cfg(any(target_arch = "aarch64", dox))]
    #[doc(cfg(target_arch = "aarch64"))]
    #[unstable(feature = "stdsimd", issue = "27731")]
    pub mod aarch64 {
        pub use coresimd::aarch64::*;
        pub use coresimd::arm::*;
    }

    /// Platform-specific intrinsics for the `wasm32` platform.
    ///
    /// See the [module documentation](../index.html) for more details.
    #[cfg(target_arch = "wasm32")]
    #[unstable(feature = "stdsimd", issue = "27731")]
    pub mod wasm32 {
        pub use coresimd::wasm32::*;
    }

    /// Platform-specific intrinsics for the `mips` platform.
    ///
    /// See the [module documentation](../index.html) for more details.
    #[cfg(any(target_arch = "mips", dox))]
    #[doc(cfg(target_arch = "mips"))]
    #[unstable(feature = "stdsimd", issue = "27731")]
    pub mod mips {
        pub use coresimd::mips::*;
    }

    /// Platform-specific intrinsics for the `mips64` platform.
    ///
    /// See the [module documentation](../index.html) for more details.
    #[cfg(any(target_arch = "mips64", dox))]
    #[doc(cfg(target_arch = "mips64"))]
    #[unstable(feature = "stdsimd", issue = "27731")]
    pub mod mips64 {
        pub use coresimd::mips::*;
    }

    /// Platform-specific intrinsics for the `PowerPC` platform.
    ///
    /// See the [module documentation](../index.html) for more details.
    #[cfg(any(target_arch = "powerpc", dox))]
    #[doc(cfg(target_arch = "powerpc"))]
    #[unstable(feature = "stdsimd", issue = "27731")]
    pub mod powerpc {
        pub use coresimd::powerpc::*;
    }

    /// Platform-specific intrinsics for the `PowerPC64` platform.
    ///
    /// See the [module documentation](../index.html) for more details.
    #[cfg(any(target_arch = "powerpc64", dox))]
    #[doc(cfg(target_arch = "powerpc64"))]
    #[unstable(feature = "stdsimd", issue = "27731")]
    pub mod powerpc64 {
        pub use coresimd::powerpc64::*;
    }

    /// Platform-specific intrinsics for the `NVPTX` platform.
    ///
    /// See the [module documentation](../index.html) for more details.
    #[cfg(any(target_arch = "nvptx", target_arch = "nvptx64", dox))]
    #[doc(cfg(any(target_arch = "nvptx", target_arch = "nvptx64")))]
    #[unstable(feature = "stdsimd", issue = "27731")]
    pub mod nvptx {
        pub use coresimd::nvptx::*;
    }
}

mod simd_llvm;

#[cfg(any(target_arch = "x86", target_arch = "x86_64", dox))]
#[doc(cfg(any(target_arch = "x86", target_arch = "x86_64")))]
mod x86;
#[cfg(any(target_arch = "x86_64", dox))]
#[doc(cfg(target_arch = "x86_64"))]
mod x86_64;

#[cfg(any(target_arch = "aarch64", dox))]
#[doc(cfg(target_arch = "aarch64"))]
mod aarch64;
#[cfg(any(target_arch = "arm", target_arch = "aarch64", dox))]
#[doc(cfg(any(target_arch = "arm", target_arch = "aarch64")))]
mod arm;
#[cfg(target_arch = "wasm32")]
mod wasm32;

#[cfg(any(target_arch = "mips", target_arch = "mips64", dox))]
#[doc(cfg(any(target_arch = "mips", target_arch = "mips64")))]
mod mips;

#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64", dox))]
#[doc(cfg(any(target_arch = "powerpc", target_arch = "powerpc64")))]
mod powerpc;

#[cfg(any(target_arch = "powerpc64", dox))]
#[doc(cfg(target_arch = "powerpc64"))]
mod powerpc64;

#[cfg(any(target_arch = "nvptx", target_arch = "nvptx64", dox))]
#[doc(cfg(any(target_arch = "nvptx", target_arch = "nvptx64")))]
mod nvptx;
<|endoftext|>


<commit_before>//! Implements `StdTimeManager`.

use std::sync::RwLock;
use std::time::{SystemTime, Duration};
use board::*;
use depth::*;
use value::*;
use search_executor::*;
use hash_table::Variation;
use search_node::SearchNode;
use time_manager::{TimeManager, RemainingTime};
use uci::{SetOption, OptionDescription};

/// Implements the `TimeManager` trait.
pub struct StdTimeManager {
    started_at: SystemTime,
    depth: Depth,
    value: Value,
    extrapolation_points: Vec<(f64, f64)>,
    hard_limit: f64,
    allotted_time: f64,
    must_play: bool,
}

impl<T> TimeManager<T> for StdTimeManager
    where T: SearchExecutor<ReportData = Vec<Variation>>
{
    fn new(position: &T::SearchNode, time: &RemainingTime) -> StdTimeManager {
        // Get our remaining time and increment (in milliseconds).
        let (t, inc) = if position.board().to_move == WHITE {
            (time.white_millis as f64, time.winc_millis as f64)
        } else {
            (time.black_millis as f64, time.binc_millis as f64)
        };

        // Get the number of moves until the next time control, or if
        // not available, guess the number of moves to the end of the
        // game.
        let n = time.movestogo.unwrap_or(40) as f64;
        debug_assert!(n >= 1.0);

        // Calculate the total time we have.
        let time_heap = t + inc * (n - 1.0);

        // Set a hard limit for the time we will spend on this
        // move. Thinking longer that that would be reckless.
        let hard_limit = (t / n.sqrt() + inc).min(t - 1000.0);

        StdTimeManager {
            started_at: SystemTime::now(),
            depth: 0,
            value: VALUE_UNKNOWN,
            extrapolation_points: Vec::with_capacity(32),
            hard_limit: if position.legal_moves().len() > 1 {
                hard_limit
            } else {
                // When there is only one legal move, the engine is
                // allowed to think just a fraction of a second in
                // order to find a good ponder move.
                hard_limit.min(500.0)
            },
            allotted_time: if *PONDERING_IS_ALLOWED.read().unwrap() {
                // Statistically, the move we ponder will be played in
                // 50% of the cases. Therefore, in principal we should
                // add half of opponent's thinking time to our time
                // heap. In reality we do not know how opponent's time
                // will be spend, so we speculatively increase our
                // time heap by 50%.
                1.5 * time_heap / n
            } else {
                time_heap / n
            },
            must_play: false,
        }
    }

    #[allow(unused_variables)]
    fn must_play(&mut self,
                 search_executor: &mut T,
                 report: Option<&SearchReport<Vec<Variation>>>)
                 -> bool {
        if !self.must_play {
            let mut is_finished = false;
            if let Some(r) = report {
                if r.depth > self.depth {
                    self.depth = r.depth;
                    is_finished = self.is_deep_enough(r);
                }
            }
            self.must_play = is_finished || elapsed_millis(&self.started_at) > self.hard_limit;
        }
        self.must_play
    }
}

impl SetOption for StdTimeManager {
    fn options() -> Vec<(String, OptionDescription)> {
        vec![("Ponder".to_string(), OptionDescription::Check { default: false })]
    }

    fn set_option(name: &str, value: &str) {
        if name == "Ponder" {
            match value {
                "true" => *PONDERING_IS_ALLOWED.write().unwrap() = true,
                "false" => *PONDERING_IS_ALLOWED.write().unwrap() = false,
                _ => (),
            }
        }
    }
}

impl StdTimeManager {
    /// A helper method. It decides whether we should stop now or we
    /// should search deeper.
    fn is_deep_enough(&mut self, report: &SearchReport<Vec<Variation>>) -> bool {
        let t = elapsed_millis(&self.started_at);
        if t == 0.0 || report.searched_nodes < 100 {
            // We ignore the first few depths.
            return false;
        }

        // We maintain a list of data points so as to be able to
        // intelligently guess how much time it will take for the
        // next search depth to complete. (We apply an exponential
        // regression over the last `M` points in the list.)
        const M: usize = 5;
        let x = report.depth as f64;
        let y = t.ln();
        self.extrapolation_points.push((x, y));
        let expected_duration = match self.extrapolation_points.len() {
            n if n >= M => {
                let last_m = &self.extrapolation_points[n - M..];
                let factor = (extrapolate_y(last_m, x + 1.0).exp() / t).max(1.0);

                // let x_max = extrapolate_x(last_m, y_max);
                // let slope = (y_max - y) / (x_max - x);

                // Update `BRANCHING_FACTOR`. This is an average
                // branching factor calculated over the last few
                // moves.
                if n == M {
                    let mut bf = BRANCHING_FACTOR.write().unwrap();
                    *bf = (*bf * 2.0 + factor) / 3.0;
                }

                factor * t
            }
            _ => *BRANCHING_FACTOR.read().unwrap() * t,
        };

        // We may need to revise the allotted time if position's
        // evaluation has changed a lot with the newly completed
        // depth.
        //
        // TODO: `25` must be bound to pawn's value.
        if (expected_duration > self.allotted_time) &&
           (self.value != VALUE_UNKNOWN && report.value != VALUE_UNKNOWN) &&
           (self.value as isize - report.value as isize).abs() >= 25 {
            self.allotted_time = expected_duration;
        }
        self.value = report.value;

        // We try to stay as close as possible to the allotted
        // time, without crossing the hard limit.
        1.33 * expected_duration > self.hard_limit ||
        (expected_duration > self.allotted_time &&
         expected_duration - self.allotted_time > self.allotted_time - t)
    }
}

lazy_static! {
    static ref PONDERING_IS_ALLOWED: RwLock<bool> = RwLock::new(false);
    static ref BRANCHING_FACTOR: RwLock<f64> = RwLock::new(2.0);
}

/// A helper function. It calculates the elapsed milliseconds since a
/// given time.
fn elapsed_millis(since: &SystemTime) -> f64 {
    let d = since.elapsed().unwrap_or(Duration::from_millis(0));
    (1000 * d.as_secs()) as f64 + (d.subsec_nanos() / 1_000_000) as f64
}

/// A helper function. It linearly extrapolates the value y(x) using
/// the (x, y) values in `points` as a reference.
fn extrapolate_y(points: &[(f64, f64)], x: f64) -> f64 {
    debug_assert!(points.len() > 1);
    let sum_x = points.iter().fold(0.0, |acc, &p| acc + p.0);
    let sum_y = points.iter().fold(0.0, |acc, &p| acc + p.1);
    let sum_xx = points.iter().fold(0.0, |acc, &p| acc + p.0 * p.0);
    let sum_xy = points.iter().fold(0.0, |acc, &p| acc + p.0 * p.1);
    let n = points.len() as f64;
    let slope = (n * sum_xy - sum_x * sum_y) / (n * sum_xx - sum_x * sum_x);
    let intercept = (sum_y - slope * sum_x) / n;
    slope * x + intercept
}

/// A helper function. It linearly extrapolates the value x(y) using
/// the (x, y) values in `points` as a reference.
fn extrapolate_x(points: &[(f64, f64)], y: f64) -> f64 {
    debug_assert!(points.len() > 1);
    let sum_x = points.iter().fold(0.0, |acc, &p| acc + p.0);
    let sum_y = points.iter().fold(0.0, |acc, &p| acc + p.1);
    let sum_xx = points.iter().fold(0.0, |acc, &p| acc + p.0 * p.0);
    let sum_xy = points.iter().fold(0.0, |acc, &p| acc + p.0 * p.1);
    let n = points.len() as f64;
    let slope = (n * sum_xy - sum_x * sum_y) / (n * sum_xx - sum_x * sum_x);
    let intercept = (sum_y - slope * sum_x) / n;
    (y - intercept) / slope.max(0.01)
}

#[cfg(test)]
mod tests {
    #[test]
    fn linear_regression() {
        use super::{extrapolate_x, extrapolate_y};
        let points = vec![(21.0, 1.0), (22.0, 2.0), (23.0, 3.0), (24.0, 4.0)];
        let x = 25.0;
        let y = extrapolate_y(&points, x);
        assert!(4.99 < y && y < 5.01);
        let y = 5.0;
        let x = extrapolate_x(&points, y);
        assert!(24.99 < x && x < 25.01);
    }
}
<commit_msg>calculate target_depth<commit_after>//! Implements `StdTimeManager`.

use std::sync::RwLock;
use std::time::{SystemTime, Duration};
use std::cmp::min;
use board::*;
use depth::*;
use value::*;
use search_executor::*;
use hash_table::Variation;
use search_node::SearchNode;
use time_manager::{TimeManager, RemainingTime};
use uci::{SetOption, OptionDescription};

/// Implements the `TimeManager` trait.
pub struct StdTimeManager {
    started_at: SystemTime,
    depth: Depth,
    value: Value,
    data_points: Vec<(f64, f64)>,
    hard_limit: f64,
    allotted_time: f64,
    must_play: bool,
}

impl<T> TimeManager<T> for StdTimeManager
    where T: SearchExecutor<ReportData = Vec<Variation>>
{
    fn new(position: &T::SearchNode, time: &RemainingTime) -> StdTimeManager {
        // Get our remaining time and increment (in milliseconds).
        let (t, inc) = if position.board().to_move == WHITE {
            (time.white_millis as f64, time.winc_millis as f64)
        } else {
            (time.black_millis as f64, time.binc_millis as f64)
        };

        // Get the number of moves until the next time control, or if
        // not available, guess the number of moves to the end of the
        // game.
        let n = time.movestogo.unwrap_or(40) as f64;
        debug_assert!(n >= 1.0);

        // Calculate the total time we have.
        let time_heap = t + inc * (n - 1.0);

        // Set a hard limit for the time we will spend on this
        // move. Thinking longer that that would be reckless.
        let hard_limit = (t / n.sqrt() + inc).min(t - 1000.0);

        StdTimeManager {
            started_at: SystemTime::now(),
            depth: 0,
            value: VALUE_UNKNOWN,
            data_points: Vec::with_capacity(32),
            hard_limit: if position.legal_moves().len() > 1 {
                hard_limit
            } else {
                // When there is only one legal move, the engine is
                // allowed to think just a fraction of a second in
                // order to find a good ponder move.
                hard_limit.min(500.0)
            },
            allotted_time: if *PONDERING_IS_ALLOWED.read().unwrap() {
                // Statistically, the move we ponder will be played in
                // 50% of the cases. Therefore, in principal we should
                // add half of opponent's thinking time to our time
                // heap. In reality we do not know how opponent's time
                // will be spend, so we speculatively increase our
                // time heap by 50%.
                1.5 * time_heap / n
            } else {
                time_heap / n
            },
            must_play: false,
        }
    }

    #[allow(unused_variables)]
    fn must_play(&mut self,
                 search_executor: &mut T,
                 report: Option<&SearchReport<Vec<Variation>>>)
                 -> bool {
        if !self.must_play {
            let mut is_finished = false;
            if let Some(r) = report {
                if r.depth > self.depth {
                    self.depth = r.depth;
                    is_finished = self.is_deep_enough(r);
                }
            }
            self.must_play = is_finished || elapsed_millis(&self.started_at) > self.hard_limit;
        }
        self.must_play
    }
}

impl SetOption for StdTimeManager {
    fn options() -> Vec<(String, OptionDescription)> {
        vec![("Ponder".to_string(), OptionDescription::Check { default: false })]
    }

    fn set_option(name: &str, value: &str) {
        if name == "Ponder" {
            match value {
                "true" => *PONDERING_IS_ALLOWED.write().unwrap() = true,
                "false" => *PONDERING_IS_ALLOWED.write().unwrap() = false,
                _ => (),
            }
        }
    }
}

impl StdTimeManager {
    /// A helper method. It decides whether we should stop now or we
    /// should search deeper.
    fn is_deep_enough(&mut self, report: &SearchReport<Vec<Variation>>) -> bool {
        let t = elapsed_millis(&self.started_at);
        if t < 0.001 || report.searched_nodes < 100 {
            // We ignore the first few depths.
            return false;
        }

        // We maintain a list of (x, y) data points so as to be able
        // to intelligently guess how much time it will take for the
        // next search depth to complete, and what target depth we
        // will be able to reach. (To do that we apply a linear
        // regression over the last `M` points in the list.)
        const M: usize = 5;
        let x = report.depth as f64;
        let y = t.ln();
        let x_max;
        let y_max = self.allotted_time.ln(); // TODO: `self.allotted_time != 0.0`?
        self.data_points.push((x, y));
        let t_next = match self.data_points.len() {
            n if n >= M => {
                let last_m = &self.data_points[n - M..];
                let (slope, intercept) = linear_regression(last_m);
                debug_assert!(slope >= 0.001);
                x_max = (y_max - intercept) / slope;
                if n == M {
                    // Update `AVG_SLOPE`.
                    let mut s = AVG_SLOPE.write().unwrap();
                    *s = (*s * 2.0 + slope) / 3.0;
                }
                (slope * (x + 1.0) + intercept).exp()
            }
            _ => {
                // There are not enough data points yet -- use `AVG_SLOPE`.
                let s = AVG_SLOPE.read().unwrap();
                x_max = x + (y_max - y) / *s;
                t * s.exp()
            }
        };
        let mut target_depth = x_max.round()
                                    .min(DEPTH_MAX as f64)
                                    .max(DEPTH_MIN as f64) as Depth;

        if target_depth <= report.depth &&
           (self.value != VALUE_UNKNOWN && report.value != VALUE_UNKNOWN) &&
           (self.value as isize - report.value as isize).abs() >= 25 {
            // Search one ply deeper if position's evaluation has
            // changed a lot with the newly completed depth.
            //
            // TODO: `25` must be bound to pawn's value.
            target_depth = min(report.depth + 1, DEPTH_MAX);
        }
        self.value = report.value;

        report.depth >= target_depth || 1.5 * t_next > self.hard_limit
    }
}

lazy_static! {
    static ref PONDERING_IS_ALLOWED: RwLock<bool> = RwLock::new(false);
    static ref AVG_SLOPE: RwLock<f64> = RwLock::new(0.7);
}

/// A helper function. It calculates the elapsed milliseconds since a
/// given time.
fn elapsed_millis(since: &SystemTime) -> f64 {
    let d = since.elapsed().unwrap_or(Duration::from_millis(0));
    (1000 * d.as_secs()) as f64 + (d.subsec_nanos() / 1_000_000) as f64
}

/// A helper function. It linearly extrapolates the values in `points`.
fn linear_regression(points: &[(f64, f64)]) -> (f64, f64) {
    debug_assert!(points.len() > 1);
    let sum_x = points.iter().fold(0.0, |acc, &p| acc + p.0);
    let sum_y = points.iter().fold(0.0, |acc, &p| acc + p.1);
    let sum_xx = points.iter().fold(0.0, |acc, &p| acc + p.0 * p.0);
    let sum_xy = points.iter().fold(0.0, |acc, &p| acc + p.0 * p.1);
    let n = points.len() as f64;
    let slope = (n * sum_xy - sum_x * sum_y) / (n * sum_xx - sum_x * sum_x);
    let intercept = (sum_y - slope * sum_x) / n;
    (slope.max(0.001), intercept)
}

#[cfg(test)]
mod tests {
    #[test]
    fn linear_regression() {
        use super::linear_regression;
        let points = vec![(21.0, 1.0), (22.0, 2.0), (23.0, 3.0), (24.0, 4.0)];
        let x = 25.0;
        let (slope, intercept) = linear_regression(&points);
        let y = slope * x + intercept;
        assert!(4.99 < y && y < 5.01);
    }
}
<|endoftext|>