<commit_before>// Copyright 2018 Google LLC
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

//! [![Latest Version](https://img.shields.io/crates/v/tarpc.svg)](https://crates.io/crates/tarpc)
//! [![Join the chat at https://gitter.im/tarpc/Lobby](https://badges.gitter.im/tarpc/Lobby.svg)](https://gitter.im/tarpc/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
//!
//! *Disclaimer*: This is not an official Google product.
//!
//! tarpc is an RPC framework for rust with a focus on ease of use. Defining a
//! service can be done in just a few lines of code, and most of the boilerplate of
//! writing a server is taken care of for you.
//!
//! [Documentation](https://docs.rs/crate/tarpc/)
//!
//! ## What is an RPC framework?
//! "RPC" stands for "Remote Procedure Call," a function call where the work of
//! producing the return value is being done somewhere else. When an rpc function is
//! invoked, behind the scenes the function contacts some other process somewhere
//! and asks them to evaluate the function instead. The original function then
//! returns the value produced by the other process.
//!
//! RPC frameworks are a fundamental building block of most microservices-oriented
//! architectures. Two well-known ones are [gRPC](http://www.grpc.io) and
//! [Cap'n Proto](https://capnproto.org/).
//!
//! tarpc differentiates itself from other RPC frameworks by defining the schema in code,
//! rather than in a separate language such as .proto. This means there's no separate compilation
//! process, and no context switching between different languages.
//!
//! Some other features of tarpc:
//! - Pluggable transport: any type impling `Stream<Item = Request> + Sink<Response>` can be
//!   used as a transport to connect the client and server.
//! - `Send + 'static` optional: if the transport doesn't require it, neither does tarpc!
//! - Cascading cancellation: dropping a request will send a cancellation message to the server.
//!   The server will cease any unfinished work on the request, subsequently cancelling any of its
//!   own requests, repeating for the entire chain of transitive dependencies.
//! - Configurable deadlines and deadline propagation: request deadlines default to 10s if
//!   unspecified. The server will automatically cease work when the deadline has passed. Any
//!   requests sent by the server that use the request context will propagate the request deadline.
//!   For example, if a server is handling a request with a 10s deadline, does 2s of work, then
//!   sends a request to another server, that server will see an 8s deadline.
//! - Serde serialization: enabling the `serde1` Cargo feature will make service requests and
//!   responses `Serialize + Deserialize`. It's entirely optional, though: in-memory transports can
//!   be used, as well, so the price of serialization doesn't have to be paid when it's not needed.
//!
//! ## Usage
//! Add to your `Cargo.toml` dependencies:
//!
//! ```toml
//! tarpc = "0.20.0"
//! ```
//!
//! The `tarpc::service` attribute expands to a collection of items that form an rpc service.
//! These generated types make it easy and ergonomic to write servers with less boilerplate.
//! Simply implement the generated service trait, and you're off to the races!
//!
//! ## Example
//!
//! For this example, in addition to tarpc, also add two other dependencies to
//! your `Cargo.toml`:
//!
//! ```toml
//! futures = "0.3"
//! tokio = "0.2"
//! ```
//!
//! In the following example, we use an in-process channel for communication between
//! client and server. In real code, you will likely communicate over the network.
//! For a more real-world example, see [example-service](example-service).
//!
//! First, let's set up the dependencies and service definition.
//!
//! ```rust
//! # extern crate futures;
//!
//! use futures::{
//!     future::{self, Ready},
//!     prelude::*,
//! };
//! use tarpc::{
//!     client, context,
//!     server::{self, Handler},
//! };
//! use std::io;
//!
//! // This is the service definition. It looks a lot like a trait definition.
//! // It defines one RPC, hello, which takes one arg, name, and returns a String.
//! #[tarpc::service]
//! trait World {
//!     /// Returns a greeting for name.
//!     async fn hello(name: String) -> String;
//! }
//! ```
//!
//! This service definition generates a trait called `World`. Next we need to
//! implement it for our Server struct.
//!
//! ```rust
//! # extern crate futures;
//! # use futures::{
//! #     future::{self, Ready},
//! #     prelude::*,
//! # };
//! # use tarpc::{
//! #     client, context,
//! #     server::{self, Handler},
//! # };
//! # use std::io;
//! # // This is the service definition. It looks a lot like a trait definition.
//! # // It defines one RPC, hello, which takes one arg, name, and returns a String.
//! # #[tarpc::service]
//! # trait World {
//! #     /// Returns a greeting for name.
//! #     async fn hello(name: String) -> String;
//! # }
//! // This is the type that implements the generated World trait. It is the business logic
//! // and is used to start the server.
//! #[derive(Clone)]
//! struct HelloServer;
//!
//! impl World for HelloServer {
//!     // Each defined rpc generates two items in the trait, a fn that serves the RPC, and
//!     // an associated type representing the future output by the fn.
//!
//!     type HelloFut = Ready<String>;
//!
//!     fn hello(self, _: context::Context, name: String) -> Self::HelloFut {
//!         future::ready(format!("Hello, {}!", name))
//!     }
//! }
//! ```
//!
//! Lastly let's write our `main` that will start the server. While this example uses an
//! [in-process channel](rpc::transport::channel), tarpc also ships a generic [`serde_transport`]
//! behind the `serde-transport` feature, with additional [TCP](serde_transport::tcp) functionality
//! available behind the `tcp` feature.
//!
//! ```rust
//! # extern crate futures;
//! # use futures::{
//! #     future::{self, Ready},
//! #     prelude::*,
//! # };
//! # use tarpc::{
//! #     client, context,
//! #     server::{self, Handler},
//! # };
//! # use std::io;
//! # // This is the service definition. It looks a lot like a trait definition.
//! # // It defines one RPC, hello, which takes one arg, name, and returns a String.
//! # #[tarpc::service]
//! # trait World {
//! #     /// Returns a greeting for name.
//! #     async fn hello(name: String) -> String;
//! # }
//! # // This is the type that implements the generated World trait. It is the business logic
//! # // and is used to start the server.
//! # #[derive(Clone)]
//! # struct HelloServer;
//! # impl World for HelloServer {
//! #     // Each defined rpc generates two items in the trait, a fn that serves the RPC, and
//! #     // an associated type representing the future output by the fn.
//! #     type HelloFut = Ready<String>;
//! #     fn hello(self, _: context::Context, name: String) -> Self::HelloFut {
//! #         future::ready(format!("Hello, {}!", name))
//! #     }
//! # }
//! #[tokio::main]
//! async fn main() -> io::Result<()> {
//!     let (client_transport, server_transport) = tarpc::transport::channel::unbounded();
//!
//!     let server = server::new(server::Config::default())
//!         // incoming() takes a stream of transports such as would be returned by
//!         // TcpListener::incoming (but a stream instead of an iterator).
//!         .incoming(stream::once(future::ready(server_transport)))
//!         .respond_with(HelloServer.serve());
//!
//!     tokio::spawn(server);
//!
//!     // WorldClient is generated by the macro. It has a constructor `new` that takes a config and
//!     // any Transport as input
//!     let mut client = WorldClient::new(client::Config::default(), client_transport).spawn()?;
//!
//!     // The client has an RPC method for each RPC defined in the annotated trait. It takes the same
//!     // args as defined, with the addition of a Context, which is always the first arg. The Context
//!     // specifies a deadline and trace information which can be helpful in debugging requests.
//!     let hello = client.hello(context::current(), "Stim".to_string()).await?;
//!
//!     println!("{}", hello);
//!
//!     Ok(())
//! }
//! ```
//!
//! ## Service Documentation
//!
//! Use `cargo doc` as you normally would to see the documentation created for all
//! items expanded by a `service!` invocation.
#![deny(missing_docs)]
#![allow(clippy::type_complexity)]

pub mod rpc;
pub use rpc::*;

#[cfg(feature = "serde-transport")]
pub mod serde_transport;

pub mod trace;

/// The main macro that creates RPC services.
///
/// Rpc methods are specified, mirroring trait syntax:
///
/// ```
/// # fn main() {}
/// #[tarpc::service]
/// trait Service {
/// /// Say hello
/// async fn hello(name: String) -> String;
/// }
/// ```
///
/// Attributes can be attached to each rpc. These attributes
/// will then be attached to the generated service traits'
/// corresponding `fn`s, as well as to the client stubs' RPCs.
///
/// The following items are expanded in the enclosing module:
///
/// * `trait Service` -- defines the RPC service.
///   * `fn serve` -- turns a service impl into a request handler.
/// * `Client` -- a client stub with a fn for each RPC.
///   * `fn new_stub` -- creates a new Client stub.
pub use tarpc_plugins::service;
<commit_msg>Fix clippy lint.<commit_after>// Copyright 2018 Google LLC
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

//! [![Latest Version](https://img.shields.io/crates/v/tarpc.svg)](https://crates.io/crates/tarpc)
//! [![Join the chat at https://gitter.im/tarpc/Lobby](https://badges.gitter.im/tarpc/Lobby.svg)](https://gitter.im/tarpc/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
//!
//! *Disclaimer*: This is not an official Google product.
//!
//! tarpc is an RPC framework for rust with a focus on ease of use. Defining a
//! service can be done in just a few lines of code, and most of the boilerplate of
//! writing a server is taken care of for you.
//!
//! [Documentation](https://docs.rs/crate/tarpc/)
//!
//! ## What is an RPC framework?
//! "RPC" stands for "Remote Procedure Call," a function call where the work of
//! producing the return value is being done somewhere else. When an rpc function is
//! invoked, behind the scenes the function contacts some other process somewhere
//! and asks them to evaluate the function instead. The original function then
//! returns the value produced by the other process.
//!
//! RPC frameworks are a fundamental building block of most microservices-oriented
//! architectures. Two well-known ones are [gRPC](http://www.grpc.io) and
//! [Cap'n Proto](https://capnproto.org/).
//!
//! tarpc differentiates itself from other RPC frameworks by defining the schema in code,
//! rather than in a separate language such as .proto. This means there's no separate compilation
//! process, and no context switching between different languages.
//!
//! Some other features of tarpc:
//! - Pluggable transport: any type impling `Stream<Item = Request> + Sink<Response>` can be
//!   used as a transport to connect the client and server.
//! - `Send + 'static` optional: if the transport doesn't require it, neither does tarpc!
//! - Cascading cancellation: dropping a request will send a cancellation message to the server.
//!   The server will cease any unfinished work on the request, subsequently cancelling any of its
//!   own requests, repeating for the entire chain of transitive dependencies.
//! - Configurable deadlines and deadline propagation: request deadlines default to 10s if
//!   unspecified. The server will automatically cease work when the deadline has passed. Any
//!   requests sent by the server that use the request context will propagate the request deadline.
//!   For example, if a server is handling a request with a 10s deadline, does 2s of work, then
//!   sends a request to another server, that server will see an 8s deadline.
//! - Serde serialization: enabling the `serde1` Cargo feature will make service requests and
//!   responses `Serialize + Deserialize`. It's entirely optional, though: in-memory transports can
//!   be used, as well, so the price of serialization doesn't have to be paid when it's not needed.
//!
//! ## Usage
//! Add to your `Cargo.toml` dependencies:
//!
//! ```toml
//! tarpc = "0.20.0"
//! ```
//!
//! The `tarpc::service` attribute expands to a collection of items that form an rpc service.
//! These generated types make it easy and ergonomic to write servers with less boilerplate.
//! Simply implement the generated service trait, and you're off to the races!
//!
//! ## Example
//!
//! For this example, in addition to tarpc, also add two other dependencies to
//! your `Cargo.toml`:
//!
//! ```toml
//! futures = "0.3"
//! tokio = "0.2"
//! ```
//!
//! In the following example, we use an in-process channel for communication between
//! client and server. In real code, you will likely communicate over the network.
//! For a more real-world example, see [example-service](example-service).
//!
//! First, let's set up the dependencies and service definition.
//!
//! ```rust
//! # extern crate futures;
//!
//! use futures::{
//!     future::{self, Ready},
//!     prelude::*,
//! };
//! use tarpc::{
//!     client, context,
//!     server::{self, Handler},
//! };
//! use std::io;
//!
//! // This is the service definition. It looks a lot like a trait definition.
//! // It defines one RPC, hello, which takes one arg, name, and returns a String.
//! #[tarpc::service]
//! trait World {
//!     /// Returns a greeting for name.
//!     async fn hello(name: String) -> String;
//! }
//! ```
//!
//! This service definition generates a trait called `World`. Next we need to
//! implement it for our Server struct.
//!
//! ```rust
//! # extern crate futures;
//! # use futures::{
//! #     future::{self, Ready},
//! #     prelude::*,
//! # };
//! # use tarpc::{
//! #     client, context,
//! #     server::{self, Handler},
//! # };
//! # use std::io;
//! # // This is the service definition. It looks a lot like a trait definition.
//! # // It defines one RPC, hello, which takes one arg, name, and returns a String.
//! # #[tarpc::service]
//! # trait World {
//! #     /// Returns a greeting for name.
//! #     async fn hello(name: String) -> String;
//! # }
//! // This is the type that implements the generated World trait. It is the business logic
//! // and is used to start the server.
//! #[derive(Clone)]
//! struct HelloServer;
//!
//! impl World for HelloServer {
//!     // Each defined rpc generates two items in the trait, a fn that serves the RPC, and
//!     // an associated type representing the future output by the fn.
//!
//!     type HelloFut = Ready<String>;
//!
//!     fn hello(self, _: context::Context, name: String) -> Self::HelloFut {
//!         future::ready(format!("Hello, {}!", name))
//!     }
//! }
//! ```
//!
//! Lastly let's write our `main` that will start the server. While this example uses an
//! [in-process channel](rpc::transport::channel), tarpc also ships a generic [`serde_transport`]
//! behind the `serde-transport` feature, with additional [TCP](serde_transport::tcp) functionality
//! available behind the `tcp` feature.
//!
//! ```rust
//! # extern crate futures;
//! # use futures::{
//! #     future::{self, Ready},
//! #     prelude::*,
//! # };
//! # use tarpc::{
//! #     client, context,
//! #     server::{self, Handler},
//! # };
//! # use std::io;
//! # // This is the service definition. It looks a lot like a trait definition.
//! # // It defines one RPC, hello, which takes one arg, name, and returns a String.
//! # #[tarpc::service]
//! # trait World {
//! #     /// Returns a greeting for name.
//! #     async fn hello(name: String) -> String;
//! # }
//! # // This is the type that implements the generated World trait. It is the business logic
//! # // and is used to start the server.
//! # #[derive(Clone)]
//! # struct HelloServer;
//! # impl World for HelloServer {
//! #     // Each defined rpc generates two items in the trait, a fn that serves the RPC, and
//! #     // an associated type representing the future output by the fn.
//! #     type HelloFut = Ready<String>;
//! #     fn hello(self, _: context::Context, name: String) -> Self::HelloFut {
//! #         future::ready(format!("Hello, {}!", name))
//! #     }
//! # }
//! #[tokio::main]
//! async fn main() -> io::Result<()> {
//!     let (client_transport, server_transport) = tarpc::transport::channel::unbounded();
//!
//!     let server = server::new(server::Config::default())
//!         // incoming() takes a stream of transports such as would be returned by
//!         // TcpListener::incoming (but a stream instead of an iterator).
//!         .incoming(stream::once(future::ready(server_transport)))
//!         .respond_with(HelloServer.serve());
//!
//!     tokio::spawn(server);
//!
//!     // WorldClient is generated by the macro. It has a constructor `new` that takes a config and
//!     // any Transport as input
//!     let mut client = WorldClient::new(client::Config::default(), client_transport).spawn()?;
//!
//!     // The client has an RPC method for each RPC defined in the annotated trait. It takes the same
//!     // args as defined, with the addition of a Context, which is always the first arg. The Context
//!     // specifies a deadline and trace information which can be helpful in debugging requests.
//!     let hello = client.hello(context::current(), "Stim".to_string()).await?;
//!
//!     println!("{}", hello);
//!
//!     Ok(())
//! }
//! ```
//!
//! ## Service Documentation
//!
//! Use `cargo doc` as you normally would to see the documentation created for all
//! items expanded by a `service!` invocation.
#![deny(missing_docs)]
#![allow(clippy::type_complexity)]

pub mod rpc;
pub use rpc::*;

#[cfg(feature = "serde-transport")]
pub mod serde_transport;

pub mod trace;

/// The main macro that creates RPC services.
///
/// Rpc methods are specified, mirroring trait syntax:
///
/// ```
/// #[tarpc::service]
/// trait Service {
/// /// Say hello
/// async fn hello(name: String) -> String;
/// }
/// ```
///
/// Attributes can be attached to each rpc. These attributes
/// will then be attached to the generated service traits'
/// corresponding `fn`s, as well as to the client stubs' RPCs.
///
/// The following items are expanded in the enclosing module:
///
/// * `trait Service` -- defines the RPC service.
///   * `fn serve` -- turns a service impl into a request handler.
/// * `Client` -- a client stub with a fn for each RPC.
///   * `fn new_stub` -- creates a new Client stub.
pub use tarpc_plugins::service;
<|endoftext|>


<commit_before>use world::WorldView;
use glium::Surface;
use super::{Camera, GameContext};
use std::rc::Rc;

use glium::texture::texture2d::Texture2d;
use glium::texture::UncompressedFloatFormat;
use glium::texture::MipmapsOption;
use glium::texture::{DepthFormat, DepthTexture2d};
use glium::framebuffer::MultiOutputFrameBuffer;
use glium::VertexBuffer;
use glium::{IndexBuffer, Program};
use glium::index::PrimitiveType;
use glium::backend::Facade;

pub struct Renderer {
    context: Rc<GameContext>,
    quad_tex: Texture2d,
    depth_texture: DepthTexture2d,
    tonemapping_program: Program,
    quad_vertex_buffer: VertexBuffer<Vertex>,
    quad_index_buffer: IndexBuffer<u16>,
}

impl Renderer {
    pub fn new(context: Rc<GameContext>) -> Self {
        let resolution = context.get_facade().get_framebuffer_dimensions();
        let quad_tex_temp = Texture2d::empty_with_format(context.get_facade(),
                                                         UncompressedFloatFormat::F32F32F32F32,
                                                         MipmapsOption::NoMipmap,
                                                         resolution.0,
                                                         resolution.1)
            .unwrap();

        let depth_texture = DepthTexture2d::empty_with_format(context.get_facade(),
                                                              DepthFormat::F32,
                                                              MipmapsOption::NoMipmap,
                                                              resolution.0,
                                                              resolution.1)
            .unwrap();

        let ibuf = IndexBuffer::new(context.get_facade(),
                                    PrimitiveType::TrianglesList,
                                    &[0u16, 1, 2, 0, 2, 3])
            .unwrap();

        let tonemapping_program = Program::from_source(context.get_facade(),
                                          include_str!("tonemapping.vert"),
                                          include_str!("tonemapping.frag"),
                                          None)
                .unwrap();

        Renderer {
            context: context.clone(),
            quad_tex: quad_tex_temp,
            tonemapping_program: tonemapping_program,
            depth_texture: depth_texture,
            quad_vertex_buffer: Renderer::create_vertex_buf(context.get_facade()),
            quad_index_buffer: ibuf,
        }
    }

    /// Is called once every main loop iteration
    pub fn render(&self, world_view: &WorldView, camera: &Camera) -> Result<(), ()> {
        // ===================================================================
        // Rendering into HDR framebuffer
        // ===================================================================
        let output = &[("color", &self.quad_tex)];
        let mut hdr_buffer = MultiOutputFrameBuffer::with_depth_buffer(self.context.get_facade(),
                                                                       output.iter().cloned(),
                                                                       &self.depth_texture)
            .unwrap();
        hdr_buffer.clear_color_and_depth((0.0, 0.0, 1.0, 1.0), 1.0);

        world_view.draw(&mut hdr_buffer, camera);

        // ===================================================================
        // Tonemapping
        // ===================================================================
        let mut target = self.context.get_facade().draw();
        target.clear_color_and_depth((0.0, 0.0, 1.0, 1.0), 1.0);

        let uniforms = uniform! {
            decal_texture: &self.quad_tex,
        };

        target.draw(&self.quad_vertex_buffer,
                  &self.quad_index_buffer,
                  &self.tonemapping_program,
                  &uniforms,
                  &Default::default())
            .unwrap();

        target.finish().unwrap();

        Ok(())
    }

    fn create_vertex_buf<F: Facade>(facade: &F) -> VertexBuffer<Vertex> {

        VertexBuffer::new(facade,
                          &[Vertex {
                                position: [-1.0, -1.0, 0.0, 1.0],
                                texcoord: [0.0, 0.0],
                            },
                            Vertex {
                                position: [1.0, -1.0, 0.0, 1.0],
                                texcoord: [1.0, 0.0],
                            },
                            Vertex {
                                position: [1.0, 1.0, 0.0, 1.0],
                                texcoord: [1.0, 1.0],
                            },
                            Vertex {
                                position: [-1.0, 1.0, 0.0, 1.0],
                                texcoord: [0.0, 1.0],
                            }])
            .unwrap()
    }
}

#[derive(Copy, Clone)]
struct Vertex {
    position: [f32; 4],
    texcoord: [f32; 2],
}

implement_vertex!(Vertex, position, texcoord);
<commit_msg>Formatting<commit_after>use world::WorldView;
use glium::Surface;
use super::{Camera, GameContext};
use std::rc::Rc;

use glium::texture::texture2d::Texture2d;
use glium::texture::UncompressedFloatFormat;
use glium::texture::MipmapsOption;
use glium::texture::{DepthFormat, DepthTexture2d};
use glium::framebuffer::MultiOutputFrameBuffer;
use glium::VertexBuffer;
use glium::{IndexBuffer, Program};
use glium::index::PrimitiveType;
use glium::backend::Facade;

pub struct Renderer {
    context: Rc<GameContext>,
    quad_tex: Texture2d,
    depth_texture: DepthTexture2d,
    tonemapping_program: Program,
    quad_vertex_buffer: VertexBuffer<Vertex>,
    quad_index_buffer: IndexBuffer<u16>,
}

impl Renderer {
    pub fn new(context: Rc<GameContext>) -> Self {
        let resolution = context.get_facade().get_framebuffer_dimensions();
        let quad_tex_temp = Texture2d::empty_with_format(context.get_facade(),
                                                         UncompressedFloatFormat::F32F32F32F32,
                                                         MipmapsOption::NoMipmap,
                                                         resolution.0,
                                                         resolution.1)
            .unwrap();

        let depth_texture = DepthTexture2d::empty_with_format(context.get_facade(),
                                                              DepthFormat::F32,
                                                              MipmapsOption::NoMipmap,
                                                              resolution.0,
                                                              resolution.1)
            .unwrap();

        let ibuf = IndexBuffer::new(context.get_facade(),
                                    PrimitiveType::TrianglesList,
                                    &[0u16, 1, 2, 0, 2, 3])
            .unwrap();

        let tonemapping_program = Program::from_source(context.get_facade(),
                                                       include_str!("tonemapping.vert"),
                                                       include_str!("tonemapping.frag"),
                                                       None)
            .unwrap();

        Renderer {
            context: context.clone(),
            quad_tex: quad_tex_temp,
            tonemapping_program: tonemapping_program,
            depth_texture: depth_texture,
            quad_vertex_buffer: Renderer::create_vertex_buf(context.get_facade()),
            quad_index_buffer: ibuf,
        }
    }

    /// Is called once every main loop iteration
    pub fn render(&self, world_view: &WorldView, camera: &Camera) -> Result<(), ()> {
        // ===================================================================
        // Rendering into HDR framebuffer
        // ===================================================================
        let output = &[("color", &self.quad_tex)];
        let mut hdr_buffer = MultiOutputFrameBuffer::with_depth_buffer(self.context.get_facade(),
                                                                       output.iter().cloned(),
                                                                       &self.depth_texture)
            .unwrap();
        hdr_buffer.clear_color_and_depth((0.0, 0.0, 1.0, 1.0), 1.0);

        world_view.draw(&mut hdr_buffer, camera);

        // ===================================================================
        // Tonemapping
        // ===================================================================
        let mut target = self.context.get_facade().draw();
        target.clear_color_and_depth((0.0, 0.0, 1.0, 1.0), 1.0);

        let uniforms = uniform! {
            decal_texture: &self.quad_tex,
        };

        target.draw(&self.quad_vertex_buffer,
                  &self.quad_index_buffer,
                  &self.tonemapping_program,
                  &uniforms,
                  &Default::default())
            .unwrap();

        target.finish().unwrap();

        Ok(())
    }

    fn create_vertex_buf<F: Facade>(facade: &F) -> VertexBuffer<Vertex> {

        VertexBuffer::new(facade,
                          &[Vertex {
                                position: [-1.0, -1.0, 0.0, 1.0],
                                texcoord: [0.0, 0.0],
                            },
                            Vertex {
                                position: [1.0, -1.0, 0.0, 1.0],
                                texcoord: [1.0, 0.0],
                            },
                            Vertex {
                                position: [1.0, 1.0, 0.0, 1.0],
                                texcoord: [1.0, 1.0],
                            },
                            Vertex {
                                position: [-1.0, 1.0, 0.0, 1.0],
                                texcoord: [0.0, 1.0],
                            }])
            .unwrap()
    }
}

#[derive(Copy, Clone)]
struct Vertex {
    position: [f32; 4],
    texcoord: [f32; 2],
}

implement_vertex!(Vertex, position, texcoord);
<|endoftext|>


<commit_before>use decoders::Image;
use imageops::fcol;
use imageops::OpBuffer;
use std::cmp;

pub fn demosaic_and_scale(img: &Image, minwidth: usize, minheight: usize) -> OpBuffer {
  let scale = if minwidth == 0 || minheight == 0 {
    0
  } else {
    cmp::min(img.width / minwidth, img.height / minheight)
  };

  if scale <= 1 {
    full(img)
  } else {
    scaled(img, cmp::min(scale, 16)) // Never go less than 1/16th demosaic
  }
}

pub fn full(img: &Image) -> OpBuffer {
  let mut out = OpBuffer::new(img.width, img.height, 4);

  // First we set the colors we already have
  out.mutate_lines(&(|line: &mut [f32], row| {
    for (col, (pixin, pixout)) in img.data.chunks(1).zip(line.chunks_mut(4)).enumerate() {
      let color = fcol(img, row, col);
      pixout[color] = pixin[0] as f32;
    }
  }));

  // Now we go around the image setting the unset colors to the average of the
  // surrounding pixels
  out.mutate_lines(&(|line: &mut [f32], row| {
    for col in 0..img.width {
      let mut sums: [f32; 4] = [0.0;4];
      let mut counts: [u32; 4] = [0; 4];
      let color = fcol(img, row, col);

      for y in (cmp::max(0,(row as isize)-1) as usize) .. cmp::min(img.height, row+2) {
        for x in (cmp::max(0,(col as isize)-1) as usize) .. cmp::min(img.width, col+2) {
          let c = fcol(img, y, x);
          if c != color {
            sums[c] += img.data[y*img.width+x] as f32;
            counts[c] += 1;
          }
        }
      }

      for c in 0..4 {
        if c != color && counts[c] > 0 {
          line[col*4+c] = sums[c] / (counts[c] as f32);
        }
      }
    }
  }));

  out
}

pub fn scaled(img: &Image, scale: usize) -> OpBuffer {
  let width = img.width/scale;
  let mut out = OpBuffer::new(width, img.height/scale, 4);

  // Go around the image averaging every block of pixels
  out.mutate_lines(&(|line: &mut [f32], row| {
    for col in 0..width {
      let mut sums: [f32; 4] = [0.0;4];
      let mut counts: [u32; 4] = [0; 4];

      for y in row*scale..(row+1)*scale {
        for x in col*scale..(col+1)*scale {
          let c = fcol(img, y, x);
          sums[c] += img.data[y*img.width+x] as f32;
          counts[c] += 1;
        }
      }

      for c in 0..4 {
        if counts[c] > 0 {
          line[col*4+c] = sums[c] / (counts[c] as f32);
        }
      }
    }
  }));

  out
}
<commit_msg>demosaic: fix buggy threaded fill-in code<commit_after>use decoders::Image;
use imageops::fcol;
use imageops::OpBuffer;
use std::cmp;

pub fn demosaic_and_scale(img: &Image, minwidth: usize, minheight: usize) -> OpBuffer {
  let scale = if minwidth == 0 || minheight == 0 {
    0
  } else {
    cmp::min(img.width / minwidth, img.height / minheight)
  };

  if scale <= 1 {
    full(img)
  } else {
    scaled(img, cmp::min(scale, 16)) // Never go less than 1/16th demosaic
  }
}

pub fn full(img: &Image) -> OpBuffer {
  let mut out = OpBuffer::new(img.width, img.height, 4);

  // First we set the colors we already have
  out.mutate_lines(&(|line: &mut [f32], row| {
    for (col, (pixin, pixout)) in img.data[img.width*row..].chunks(1).zip(line.chunks_mut(4)).enumerate() {
      let color = fcol(img, row, col);
      pixout[color] = pixin[0] as f32;
    }
  }));

  // Now we go around the image setting the unset colors to the average of the
  // surrounding pixels
  out.mutate_lines(&(|line: &mut [f32], row| {
    for col in 0..img.width {
      let mut sums: [f32; 4] = [0.0;4];
      let mut counts: [u32; 4] = [0; 4];
      let color = fcol(img, row, col);

      for y in (cmp::max(0,(row as isize)-1) as usize) .. cmp::min(img.height, row+2) {
        for x in (cmp::max(0,(col as isize)-1) as usize) .. cmp::min(img.width, col+2) {
          let c = fcol(img, y, x);
          if c != color {
            sums[c] += img.data[y*img.width+x] as f32;
            counts[c] += 1;
          }
        }
      }

      for c in 0..4 {
        if c != color && counts[c] > 0 {
          line[col*4+c] = sums[c] / (counts[c] as f32);
        }
      }
    }
  }));

  out
}

pub fn scaled(img: &Image, scale: usize) -> OpBuffer {
  let width = img.width/scale;
  let mut out = OpBuffer::new(width, img.height/scale, 4);

  // Go around the image averaging every block of pixels
  out.mutate_lines(&(|line: &mut [f32], row| {
    for col in 0..width {
      let mut sums: [f32; 4] = [0.0;4];
      let mut counts: [u32; 4] = [0; 4];

      for y in row*scale..(row+1)*scale {
        for x in col*scale..(col+1)*scale {
          let c = fcol(img, y, x);
          sums[c] += img.data[y*img.width+x] as f32;
          counts[c] += 1;
        }
      }

      for c in 0..4 {
        if counts[c] > 0 {
          line[col*4+c] = sums[c] / (counts[c] as f32);
        }
      }
    }
  }));

  out
}
<|endoftext|>


<commit_before>// Copyright 2014-2016 bluss and ndarray developers.
//
// 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.

//! Constructor methods for ndarray
//!

use libnum::{Zero, One, Float};

use imp_prelude::*;
use dimension;
use linspace;
use error::{self, ShapeError, ErrorKind};

/// A contiguous array shape of n dimensions.
///
/// Either c- or f- memory ordered.
pub struct Shape<D> {
    dim: D,
    is_c: bool,
}

/// An array shape of n dimensions with possibly custom strides.
pub struct StrideShape<D> {
    dim: D,
    strides: D,
    custom: bool,
}

pub trait ShapeBuilder {
    type Dim: Dimension;

    fn f(self) -> Shape<Self::Dim>;
    fn strides(self, st: Self::Dim) -> StrideShape<Self::Dim>;
}

impl<D> From<D> for Shape<D>
    where D: Dimension
{
    fn from(d: D) -> Self {
        Shape {
            dim: d,
            is_c: true,
        }
    }
}

impl<D> From<D> for StrideShape<D>
    where D: Dimension
{
    fn from(d: D) -> Self {
        StrideShape {
            strides: d.default_strides(),
            dim: d,
            custom: false,
        }
    }
}

impl<D> From<Shape<D>> for StrideShape<D>
    where D: Dimension
{
    fn from(shape: Shape<D>) -> Self {
        let d = shape.dim;
        let st = if shape.is_c { d.default_strides() } else { d.fortran_strides() };
        StrideShape {
            strides: st,
            dim: d,
            custom: false,
        }
    }
}

impl<D> ShapeBuilder for D
    where D: Dimension
{
    type Dim = D;
    fn f(self) -> Shape<D> {
        Shape::from(self).f()
    }
    fn strides(self, st: D) -> StrideShape<D> {
        Shape::from(self).strides(st)
    }
}

impl<D> ShapeBuilder for Shape<D>
    where D: Dimension
{
    type Dim = D;
    fn f(mut self) -> Self {
        self.is_c = false;
        self
    }
    fn strides(self, st: D) -> StrideShape<D> {
        StrideShape {
            dim: self.dim,
            strides: st,
            custom: true,
        }
    }
}

/// Constructor methods for one-dimensional arrays.
///
/// Note that the constructor methods apply to `OwnedArray` and `RcArray`,
/// the two array types that have owned storage.
impl<S> ArrayBase<S, Ix>
    where S: DataOwned
{
    /// Create a one-dimensional array from a vector (no copying needed).
    ///
    /// ```rust
    /// use ndarray::OwnedArray;
    ///
    /// let array = OwnedArray::from_vec(vec![1., 2., 3., 4.]);
    /// ```
    pub fn from_vec(v: Vec<S::Elem>) -> ArrayBase<S, Ix> {
        unsafe { Self::from_vec_dim_unchecked(v.len() as Ix, v) }
    }

    /// Create a one-dimensional array from an iterable.
    ///
    /// ```rust
    /// use ndarray::{OwnedArray, arr1};
    ///
    /// let array = OwnedArray::from_iter((0..5).map(|x| x * x));
    /// assert!(array == arr1(&[0, 1, 4, 9, 16]))
    /// ```
    pub fn from_iter<I>(iterable: I) -> ArrayBase<S, Ix>
        where I: IntoIterator<Item=S::Elem>
    {
        Self::from_vec(iterable.into_iter().collect())
    }

    /// Create a one-dimensional array from the inclusive interval
    /// `[start, end]` with `n` elements. `F` must be a floating point type.
    ///
    /// ```rust
    /// use ndarray::{OwnedArray, arr1};
    ///
    /// let array = OwnedArray::linspace(0., 1., 5);
    /// assert!(array == arr1(&[0.0, 0.25, 0.5, 0.75, 1.0]))
    /// ```
    pub fn linspace<F>(start: F, end: F, n: usize) -> ArrayBase<S, Ix>
        where S: Data<Elem=F>,
              F: Float,
    {
        Self::from_vec(::iterators::to_vec(linspace::linspace(start, end, n)))
    }

    /// Create a one-dimensional array from the half-open interval
    /// `[start, end)` with elements spaced by `step`. `F` must be a floating point type.
    ///
    /// ```rust
    /// use ndarray::{OwnedArray, arr1};
    ///
    /// let array = OwnedArray::range(0., 5., 1.);
    /// assert!(array == arr1(&[0., 1., 2., 3., 4.]))
    /// ```
    pub fn range<F>(start: F, end: F, step: F) -> ArrayBase<S, Ix>
        where S: Data<Elem=F>,
              F: Float,
    {
        Self::from_vec(::iterators::to_vec(linspace::range(start, end, step)))
    }
}

/// Constructor methods for two-dimensional arrays.
impl<S, A> ArrayBase<S, (Ix, Ix)>
    where S: DataOwned<Elem=A>,
{
    /// Create an identity matrix of size `n` (square 2D array).
    ///
    /// **Panics** if `n * n` would overflow usize.
    pub fn eye(n: Ix) -> ArrayBase<S, (Ix, Ix)>
        where S: DataMut,
              A: Clone + Zero + One,
    {
        let mut eye = Self::zeros((n, n));
        for a_ii in eye.diag_mut() {
            *a_ii = A::one();
        }
        eye
    }
}

macro_rules! size_checked_unwrap {
    ($dim:expr) => {
        match $dim.size_checked() {
            Some(sz) => sz,
            None => panic!("ndarray: Shape too large, number of elements overflows usize"),
        }
    }
}

/// Constructor methods for n-dimensional arrays.
impl<S, A, D> ArrayBase<S, D>
    where S: DataOwned<Elem=A>,
          D: Dimension,
{
    /// Create an array with copies of `elem`, dimension `dim`.
    ///
    /// **Panics** if the number of elements in `dim` would overflow usize.
    ///
    /// ```
    /// use ndarray::OwnedArray;
    /// use ndarray::arr3;
    ///
    /// let a = OwnedArray::from_elem((2, 2, 2), 1.);
    ///
    /// assert!(
    ///     a == arr3(&[[[1., 1.],
    ///                  [1., 1.]],
    ///                 [[1., 1.],
    ///                  [1., 1.]]])
    /// );
    /// assert!(a.strides() == &[4, 2, 1]);
    /// ```
    pub fn from_elem<Sh>(shape: Sh, elem: A) -> ArrayBase<S, D>
        where A: Clone,
              Sh: Into<Shape<D>>,
    {
        // Note: We don't need to check the case of a size between
        // isize::MAX -> usize::MAX; in this case, the vec constructor itself
        // panics.
        let shape = shape.into();
        let size = size_checked_unwrap!(shape.dim);
        let v = vec![elem; size];
        unsafe { Self::from_shape_vec_unchecked(shape, v) }
    }

    /// Create an array with copies of `elem`, dimension `dim` and fortran
    /// memory order.
    ///
    /// **Panics** if the number of elements would overflow usize.
    ///
    /// ```
    /// use ndarray::OwnedArray;
    ///
    /// let a = OwnedArray::from_elem_f((2, 2, 2), 1.);
    /// assert!(a.strides() == &[1, 2, 4]);
    /// ```
    pub fn from_elem_f(dim: D, elem: A) -> ArrayBase<S, D>
        where A: Clone
    {
        Self::from_elem(dim.f(), elem)
    }

    /// Create an array with zeros, dimension `dim`.
    ///
    /// **Panics** if the number of elements in `dim` would overflow usize.
    pub fn zeros<Sh>(shape: Sh) -> ArrayBase<S, D>
        where A: Clone + Zero,
              Sh: Into<Shape<D>>,
    {
        Self::from_elem(shape, A::zero())
    }

    /// Create an array with zeros, dimension `dim` and fortran memory order.
    ///
    /// **Panics** if the number of elements in `dim` would overflow usize.
    pub fn zeros_f(dim: D) -> ArrayBase<S, D>
        where A: Clone + Zero
    {
        Self::from_elem_f(dim, A::zero())
    }

    /// Create an array with default values, dimension `dim`.
    ///
    /// **Panics** if the number of elements in `dim` would overflow usize.
    pub fn default(dim: D) -> ArrayBase<S, D>
        where A: Default
    {
        let v = (0..dim.size()).map(|_| A::default()).collect();
        unsafe { Self::from_vec_dim_unchecked(dim, v) }
    }

    /// Create an array with the given shape from a vector (no copying needed).
    ///
    /// **Errors** if `dim` does not correspond to the number of elements in `v`.
    pub fn from_shape_vec<Sh>(shape: Sh, v: Vec<A>) -> Result<ArrayBase<S, D>, ShapeError>
        where Sh: Into<StrideShape<D>>,
    {
        // eliminate the type parameter Sh as soon as possible
        Self::from_shape_vec_impl(shape.into(), v)
    }

    fn from_shape_vec_impl(shape: StrideShape<D>, v: Vec<A>) -> Result<ArrayBase<S, D>, ShapeError>
    {
        if shape.custom {
            Self::from_vec_dim_stride(shape.dim, shape.strides, v)
        } else {
            let dim = shape.dim;
            let strides = shape.strides;
            if dim.size_checked() != Some(v.len()) {
                return Err(error::incompatible_shapes(&v.len(), &dim));
            }
            unsafe { Ok(Self::from_vec_dim_stride_unchecked(dim, strides, v)) }
        }
    }

    /// Create an array with the given shape from a vector (no copying needed).
    pub unsafe fn from_shape_vec_unchecked<Sh>(shape: Sh, v: Vec<A>) -> ArrayBase<S, D>
        where Sh: Into<StrideShape<D>>,
    {
        let shape = shape.into();
        Self::from_vec_dim_stride_unchecked(shape.dim, shape.strides, v)
    }

    /// Create an array from a vector (no copying needed).
    ///
    /// **Errors** if `dim` does not correspond to the number of elements in `v`.
    pub fn from_vec_dim(dim: D, v: Vec<A>) -> Result<ArrayBase<S, D>, ShapeError> {
        if dim.size_checked() != Some(v.len()) {
            return Err(error::incompatible_shapes(&v.len(), &dim));
        }
        unsafe { Ok(Self::from_vec_dim_unchecked(dim, v)) }
    }

    /// Create an array from a vector (no copying needed) using fortran
    /// memory order to interpret the data.
    ///
    /// **Errors** if `dim` does not correspond to the number of elements in `v`.
    pub fn from_vec_dim_f(dim: D, v: Vec<A>) -> Result<ArrayBase<S, D>, ShapeError> {
        if dim.size_checked() != Some(v.len()) {
            return Err(error::incompatible_shapes(&v.len(), &dim));
        }
        unsafe { Ok(Self::from_vec_dim_unchecked_f(dim, v)) }
    }

    /// Create an array from a vector (no copying needed).
    ///
    /// Unsafe because dimension is unchecked, and must be correct.
    pub unsafe fn from_vec_dim_unchecked(dim: D, mut v: Vec<A>) -> ArrayBase<S, D> {
        debug_assert!(dim.size_checked() == Some(v.len()));
        ArrayBase {
            ptr: v.as_mut_ptr(),
            data: DataOwned::new(v),
            strides: dim.default_strides(),
            dim: dim,
        }
    }

    /// Create an array from a vector (with no copying needed),
    /// using fortran memory order to interpret the data.
    ///
    /// Unsafe because dimension is unchecked, and must be correct.
    pub unsafe fn from_vec_dim_unchecked_f(dim: D, v: Vec<A>) -> ArrayBase<S, D> {
        debug_assert!(dim.size_checked() == Some(v.len()));
        let strides = dim.fortran_strides();
        Self::from_vec_dim_stride_unchecked(dim, strides, v)
    }

    /// Create an array from a vector and interpret it according to the
    /// provided dimensions and strides. No allocation needed.
    ///
    /// Checks whether `dim` and `strides` are compatible with the vector's
    /// length, returning an `Err` if not compatible.
    ///
    /// **Errors** if strides and dimensions can point out of bounds of `v`.<br>
    /// **Errors** if strides allow multiple indices to point to the same element.
    pub fn from_vec_dim_stride(dim: D, strides: D, v: Vec<A>)
        -> Result<ArrayBase<S, D>, ShapeError>
    {
        dimension::can_index_slice(&v, &dim, &strides).map(|_| {
            unsafe {
                Self::from_vec_dim_stride_unchecked(dim, strides, v)
            }
        })
    }

    /// Create an array from a vector and interpret it according to the
    /// provided dimensions and strides. No allocation needed.
    ///
    /// Unsafe because dimension and strides are unchecked.
    pub unsafe fn from_vec_dim_stride_unchecked(dim: D, strides: D, mut v: Vec<A>)
        -> ArrayBase<S, D>
    {
        // debug check for issues that indicates wrong use of this constructor
        debug_assert!(match dimension::can_index_slice(&v, &dim, &strides) {
            Ok(_) => true,
            Err(ref e) => match e.kind() {
                ErrorKind::OutOfBounds => false,
                ErrorKind::RangeLimited => false,
                _ => true,
            }
        });
        ArrayBase {
            ptr: v.as_mut_ptr(),
            data: DataOwned::new(v),
            strides: strides,
            dim: dim
        }
    }

}
<commit_msg>Deprecate constructors in favour of shape-based methods<commit_after>// Copyright 2014-2016 bluss and ndarray developers.
//
// 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.

//! Constructor methods for ndarray
//!

use libnum::{Zero, One, Float};

use imp_prelude::*;
use dimension;
use linspace;
use error::{self, ShapeError, ErrorKind};

/// A contiguous array shape of n dimensions.
///
/// Either c- or f- memory ordered (*c* a.k.a *row major* is the default).
#[derive(Copy, Clone, Debug)]
pub struct Shape<D> {
    dim: D,
    is_c: bool,
}

/// An array shape of n dimensions c-order, f-order or custom strides.
#[derive(Copy, Clone, Debug)]
pub struct StrideShape<D> {
    dim: D,
    strides: D,
    custom: bool,
}

/// A trait for `Shape` and `D where D: Dimension` that allows
/// customizing the memory layout (strides) of an array shape.
pub trait ShapeBuilder {
    type Dim: Dimension;

    fn f(self) -> Shape<Self::Dim>;
    fn strides(self, st: Self::Dim) -> StrideShape<Self::Dim>;
}

impl<D> From<D> for Shape<D>
    where D: Dimension
{
    fn from(d: D) -> Self {
        Shape {
            dim: d,
            is_c: true,
        }
    }
}

impl<D> From<D> for StrideShape<D>
    where D: Dimension
{
    fn from(d: D) -> Self {
        StrideShape {
            strides: d.default_strides(),
            dim: d,
            custom: false,
        }
    }
}

impl<D> From<Shape<D>> for StrideShape<D>
    where D: Dimension
{
    fn from(shape: Shape<D>) -> Self {
        let d = shape.dim;
        let st = if shape.is_c { d.default_strides() } else { d.fortran_strides() };
        StrideShape {
            strides: st,
            dim: d,
            custom: false,
        }
    }
}

impl<D> ShapeBuilder for D
    where D: Dimension
{
    type Dim = D;
    fn f(self) -> Shape<D> {
        Shape::from(self).f()
    }
    fn strides(self, st: D) -> StrideShape<D> {
        Shape::from(self).strides(st)
    }
}

impl<D> ShapeBuilder for Shape<D>
    where D: Dimension
{
    type Dim = D;
    fn f(mut self) -> Self {
        self.is_c = false;
        self
    }
    fn strides(self, st: D) -> StrideShape<D> {
        StrideShape {
            dim: self.dim,
            strides: st,
            custom: true,
        }
    }
}

/// Constructor methods for one-dimensional arrays.
///
/// Note that the constructor methods apply to `OwnedArray` and `RcArray`,
/// the two array types that have owned storage.
impl<S> ArrayBase<S, Ix>
    where S: DataOwned
{
    /// Create a one-dimensional array from a vector (no copying needed).
    ///
    /// ```rust
    /// use ndarray::OwnedArray;
    ///
    /// let array = OwnedArray::from_vec(vec![1., 2., 3., 4.]);
    /// ```
    pub fn from_vec(v: Vec<S::Elem>) -> ArrayBase<S, Ix> {
        unsafe { Self::from_vec_dim_unchecked(v.len() as Ix, v) }
    }

    /// Create a one-dimensional array from an iterable.
    ///
    /// ```rust
    /// use ndarray::{OwnedArray, arr1};
    ///
    /// let array = OwnedArray::from_iter((0..5).map(|x| x * x));
    /// assert!(array == arr1(&[0, 1, 4, 9, 16]))
    /// ```
    pub fn from_iter<I>(iterable: I) -> ArrayBase<S, Ix>
        where I: IntoIterator<Item=S::Elem>
    {
        Self::from_vec(iterable.into_iter().collect())
    }

    /// Create a one-dimensional array from the inclusive interval
    /// `[start, end]` with `n` elements. `F` must be a floating point type.
    ///
    /// ```rust
    /// use ndarray::{OwnedArray, arr1};
    ///
    /// let array = OwnedArray::linspace(0., 1., 5);
    /// assert!(array == arr1(&[0.0, 0.25, 0.5, 0.75, 1.0]))
    /// ```
    pub fn linspace<F>(start: F, end: F, n: usize) -> ArrayBase<S, Ix>
        where S: Data<Elem=F>,
              F: Float,
    {
        Self::from_vec(::iterators::to_vec(linspace::linspace(start, end, n)))
    }

    /// Create a one-dimensional array from the half-open interval
    /// `[start, end)` with elements spaced by `step`. `F` must be a floating point type.
    ///
    /// ```rust
    /// use ndarray::{OwnedArray, arr1};
    ///
    /// let array = OwnedArray::range(0., 5., 1.);
    /// assert!(array == arr1(&[0., 1., 2., 3., 4.]))
    /// ```
    pub fn range<F>(start: F, end: F, step: F) -> ArrayBase<S, Ix>
        where S: Data<Elem=F>,
              F: Float,
    {
        Self::from_vec(::iterators::to_vec(linspace::range(start, end, step)))
    }
}

/// Constructor methods for two-dimensional arrays.
impl<S, A> ArrayBase<S, (Ix, Ix)>
    where S: DataOwned<Elem=A>,
{
    /// Create an identity matrix of size `n` (square 2D array).
    ///
    /// **Panics** if `n * n` would overflow usize.
    pub fn eye(n: Ix) -> ArrayBase<S, (Ix, Ix)>
        where S: DataMut,
              A: Clone + Zero + One,
    {
        let mut eye = Self::zeros((n, n));
        for a_ii in eye.diag_mut() {
            *a_ii = A::one();
        }
        eye
    }
}

macro_rules! size_checked_unwrap {
    ($dim:expr) => {
        match $dim.size_checked() {
            Some(sz) => sz,
            None => panic!("ndarray: Shape too large, number of elements overflows usize"),
        }
    }
}

/// Constructor methods for n-dimensional arrays.
impl<S, A, D> ArrayBase<S, D>
    where S: DataOwned<Elem=A>,
          D: Dimension,
{
    /// Create an array with copies of `elem`, shape `shape`.
    ///
    /// **Panics** if the number of elements in `shape` would overflow usize.
    ///
    /// ```
    /// use ndarray::{OwnedArray, arr3, ShapeBuilder};
    ///
    /// let a = OwnedArray::from_elem((2, 2, 2), 1.);
    ///
    /// assert!(
    ///     a == arr3(&[[[1., 1.],
    ///                  [1., 1.]],
    ///                 [[1., 1.],
    ///                  [1., 1.]]])
    /// );
    /// assert!(a.strides() == &[4, 2, 1]);
    ///
    /// let b = OwnedArray::from_elem((2, 2, 2).f(), 1.);
    /// assert!(b.strides() == &[1, 2, 4]);
    /// ```
    pub fn from_elem<Sh>(shape: Sh, elem: A) -> ArrayBase<S, D>
        where A: Clone,
              Sh: Into<Shape<D>>,
    {
        // Note: We don't need to check the case of a size between
        // isize::MAX -> usize::MAX; in this case, the vec constructor itself
        // panics.
        let shape = shape.into();
        let size = size_checked_unwrap!(shape.dim);
        let v = vec![elem; size];
        unsafe { Self::from_shape_vec_unchecked(shape, v) }
    }

    /// Create an array with zeros, shape `shape`.
    ///
    /// **Panics** if the number of elements in `shape` would overflow usize.
    pub fn zeros<Sh>(shape: Sh) -> ArrayBase<S, D>
        where A: Clone + Zero,
              Sh: Into<Shape<D>>,
    {
        Self::from_elem(shape, A::zero())
    }

    /// Create an array with default values, shape `shape`
    ///
    /// **Panics** if the number of elements in `shape` would overflow usize.
    pub fn default<Sh>(shape: Sh) -> ArrayBase<S, D>
        where A: Default,
              Sh: Into<Shape<D>>,
    {
        let shape = shape.into();
        let v = (0..shape.dim.size()).map(|_| A::default()).collect();
        unsafe { Self::from_shape_vec_unchecked(shape, v) }
    }

    /// Create an array with the given shape from a vector. (No cloning of
    /// elements needed.)
    ///
    /// ----
    ///
    /// For a contiguous c- or f-order shape, the following applies:
    ///
    /// **Errors** if `shape` does not correspond to the number of elements in `v`.
    ///
    /// ----
    ///
    /// For custom strides, the following applies:
    ///
    /// **Errors** if strides and dimensions can point out of bounds of `v`.<br>
    /// **Errors** if strides allow multiple indices to point to the same element.
    pub fn from_shape_vec<Sh>(shape: Sh, v: Vec<A>) -> Result<ArrayBase<S, D>, ShapeError>
        where Sh: Into<StrideShape<D>>,
    {
        // eliminate the type parameter Sh as soon as possible
        Self::from_shape_vec_impl(shape.into(), v)
    }

    fn from_shape_vec_impl(shape: StrideShape<D>, v: Vec<A>) -> Result<ArrayBase<S, D>, ShapeError>
    {
        if shape.custom {
            Self::from_vec_dim_stride(shape.dim, shape.strides, v)
        } else {
            let dim = shape.dim;
            let strides = shape.strides;
            if dim.size_checked() != Some(v.len()) {
                return Err(error::incompatible_shapes(&v.len(), &dim));
            }
            unsafe { Ok(Self::from_vec_dim_stride_unchecked(dim, strides, v)) }
        }
    }

    /// Create an array from a vector and interpret it according to the
    /// provided dimensions and strides. (No cloning of elements needed.)
    ///
    /// Unsafe because dimension and strides are unchecked.
    pub unsafe fn from_shape_vec_unchecked<Sh>(shape: Sh, v: Vec<A>) -> ArrayBase<S, D>
        where Sh: Into<StrideShape<D>>,
    {
        let shape = shape.into();
        Self::from_vec_dim_stride_unchecked(shape.dim, shape.strides, v)
    }

    #[cfg_attr(has_deprecated, deprecated(note="Use from_elem instead."))]
    /// ***Deprecated: Use from_elem instead***
    pub fn from_elem_f(dim: D, elem: A) -> ArrayBase<S, D>
        where A: Clone
    {
        Self::from_elem(dim.f(), elem)
    }

    #[cfg_attr(has_deprecated, deprecated(note="Use zeros instead."))]
    /// ***Deprecated: Use zeros instead***
    pub fn zeros_f(dim: D) -> ArrayBase<S, D>
        where A: Clone + Zero
    {
        Self::from_elem_f(dim, A::zero())
    }

    #[cfg_attr(has_deprecated, deprecated(note="Use from_shape_vec instead."))]
    /// ***Deprecated: Use from_shape_vec instead***
    pub fn from_vec_dim(dim: D, v: Vec<A>) -> Result<ArrayBase<S, D>, ShapeError> {
        if dim.size_checked() != Some(v.len()) {
            return Err(error::incompatible_shapes(&v.len(), &dim));
        }
        unsafe { Ok(Self::from_vec_dim_unchecked(dim, v)) }
    }

    #[cfg_attr(has_deprecated, deprecated(note="Use from_shape_vec instead."))]
    /// ***Deprecated: Use from_shape_vec instead***
    pub fn from_vec_dim_f(dim: D, v: Vec<A>) -> Result<ArrayBase<S, D>, ShapeError> {
        if dim.size_checked() != Some(v.len()) {
            return Err(error::incompatible_shapes(&v.len(), &dim));
        }
        unsafe { Ok(Self::from_vec_dim_unchecked_f(dim, v)) }
    }

    #[cfg_attr(has_deprecated, deprecated(note="Use from_shape_vec_unchecked instead."))]
    /// ***Deprecated: Use from_shape_vec_unchecked instead***
    pub unsafe fn from_vec_dim_unchecked(dim: D, mut v: Vec<A>) -> ArrayBase<S, D> {
        debug_assert!(dim.size_checked() == Some(v.len()));
        ArrayBase {
            ptr: v.as_mut_ptr(),
            data: DataOwned::new(v),
            strides: dim.default_strides(),
            dim: dim,
        }
    }

    #[cfg_attr(has_deprecated, deprecated(note="Use from_shape_vec_unchecked instead."))]
    /// ***Deprecated: Use from_shape_vec_unchecked instead***
    pub unsafe fn from_vec_dim_unchecked_f(dim: D, v: Vec<A>) -> ArrayBase<S, D> {
        debug_assert!(dim.size_checked() == Some(v.len()));
        let strides = dim.fortran_strides();
        Self::from_vec_dim_stride_unchecked(dim, strides, v)
    }

    #[cfg_attr(has_deprecated, deprecated(note="Use from_shape_vec instead."))]
    /// ***Deprecated: Use from_shape_vec instead***
    pub fn from_vec_dim_stride(dim: D, strides: D, v: Vec<A>)
        -> Result<ArrayBase<S, D>, ShapeError>
    {
        dimension::can_index_slice(&v, &dim, &strides).map(|_| {
            unsafe {
                Self::from_vec_dim_stride_unchecked(dim, strides, v)
            }
        })
    }

    #[cfg_attr(has_deprecated, deprecated(note="Use from_shape_vec_unchecked instead."))]
    /// ***Deprecated: Use from_shape_vec_unchecked instead***
    ///
    pub unsafe fn from_vec_dim_stride_unchecked(dim: D, strides: D, mut v: Vec<A>)
        -> ArrayBase<S, D>
    {
        // debug check for issues that indicates wrong use of this constructor
        debug_assert!(match dimension::can_index_slice(&v, &dim, &strides) {
            Ok(_) => true,
            Err(ref e) => match e.kind() {
                ErrorKind::OutOfBounds => false,
                ErrorKind::RangeLimited => false,
                _ => true,
            }
        });
        ArrayBase {
            ptr: v.as_mut_ptr(),
            data: DataOwned::new(v),
            strides: strides,
            dim: dim
        }
    }

}
<|endoftext|>


<commit_before>// Copyright 2019 The CryptoCorrosion Contributors
// Copyright 2020 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The ChaCha random number generator.

use ppv_lite86::{dispatch, dispatch_light128};

#[cfg(feature = "rustcrypto_api")]
pub use stream_cipher::generic_array;

pub use ppv_lite86::Machine;
use ppv_lite86::{vec128_storage, ArithOps, BitOps32, LaneWords4, MultiLane, StoreBytes, Vec4};

pub(crate) const BLOCK: usize = 64;
pub(crate) const BLOCK64: u64 = BLOCK as u64;
const LOG2_BUFBLOCKS: u64 = 2;
const BUFBLOCKS: u64 = 1 << LOG2_BUFBLOCKS;
pub(crate) const BUFSZ64: u64 = BLOCK64 * BUFBLOCKS;
pub(crate) const BUFSZ: usize = BUFSZ64 as usize;

#[derive(Clone)]
pub struct ChaCha {
    pub(crate) b: vec128_storage,
    pub(crate) c: vec128_storage,
    pub(crate) d: vec128_storage,
}

#[derive(Clone)]
pub struct State<V> {
    pub(crate) a: V,
    pub(crate) b: V,
    pub(crate) c: V,
    pub(crate) d: V,
}

#[inline(always)]
pub(crate) fn round<V: ArithOps + BitOps32>(mut x: State<V>) -> State<V> {
    x.a += x.b;
    x.d = (x.d ^ x.a).rotate_each_word_right16();
    x.c += x.d;
    x.b = (x.b ^ x.c).rotate_each_word_right20();
    x.a += x.b;
    x.d = (x.d ^ x.a).rotate_each_word_right24();
    x.c += x.d;
    x.b = (x.b ^ x.c).rotate_each_word_right25();
    x
}

#[inline(always)]
pub(crate) fn diagonalize<V: LaneWords4>(mut x: State<V>) -> State<V> {
    x.b = x.b.shuffle_lane_words3012();
    x.c = x.c.shuffle_lane_words2301();
    x.d = x.d.shuffle_lane_words1230();
    x
}
#[inline(always)]
pub(crate) fn undiagonalize<V: LaneWords4>(mut x: State<V>) -> State<V> {
    x.b = x.b.shuffle_lane_words1230();
    x.c = x.c.shuffle_lane_words2301();
    x.d = x.d.shuffle_lane_words3012();
    x
}

impl ChaCha {
    #[inline(always)]
    pub fn new(key: &[u8; 32], nonce: &[u8]) -> Self {
        init_chacha(key, nonce)
    }

    #[inline(always)]
    fn pos64<M: Machine>(&self, m: M) -> u64 {
        let d: M::u32x4 = m.unpack(self.d);
        ((d.extract(1) as u64) << 32) | d.extract(0) as u64
    }

    /// Produce 4 blocks of output, advancing the state
    #[inline(always)]
    pub fn refill4(&mut self, drounds: u32, out: &mut [u8; BUFSZ]) {
        refill_wide(self, drounds, out)
    }

    #[inline(always)]
    pub fn set_stream_param(&mut self, param: u32, value: u64) {
        set_stream_param(self, param, value)
    }

    #[inline(always)]
    pub fn get_stream_param(&self, param: u32) -> u64 {
        get_stream_param(self, param)
    }
}

#[inline(always)]
fn refill_wide_impl<Mach: Machine>(
    m: Mach,
    state: &mut ChaCha,
    drounds: u32,
    out: &mut [u8; BUFSZ],
) {
    let k = m.vec([0x6170_7865, 0x3320_646e, 0x7962_2d32, 0x6b20_6574]);
    let mut pos = state.pos64(m);
    let d0: Mach::u32x4 = m.unpack(state.d);
    pos += 1;
    let d1 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
    pos += 1;
    let d2 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
    pos += 1;
    let d3 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);

    let b = m.unpack(state.b);
    let c = m.unpack(state.c);
    let mut x = State {
        a: Mach::u32x4x4::from_lanes([k, k, k, k]),
        b: Mach::u32x4x4::from_lanes([b, b, b, b]),
        c: Mach::u32x4x4::from_lanes([c, c, c, c]),
        d: m.unpack(Mach::u32x4x4::from_lanes([d0, d1, d2, d3]).into()),
    };
    for _ in 0..drounds {
        x = round(x);
        x = undiagonalize(round(diagonalize(x)));
    }
    let mut pos = state.pos64(m);
    let d0: Mach::u32x4 = m.unpack(state.d);
    pos += 1;
    let d1 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
    pos += 1;
    let d2 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
    pos += 1;
    let d3 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
    pos += 1;
    let d4 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);

    let (a, b, c, d) = (
        x.a.to_lanes(),
        x.b.to_lanes(),
        x.c.to_lanes(),
        x.d.to_lanes(),
    );
    let sb = m.unpack(state.b);
    let sc = m.unpack(state.c);
    let sd = [m.unpack(state.d), d1, d2, d3];
    state.d = d4.into();
    let mut words = out.chunks_exact_mut(16);
    for ((((&a, &b), &c), &d), &sd) in a.iter().zip(&b).zip(&c).zip(&d).zip(&sd) {
        (a + k).write_le(words.next().unwrap());
        (b + sb).write_le(words.next().unwrap());
        (c + sc).write_le(words.next().unwrap());
        (d + sd).write_le(words.next().unwrap());
    }
}

dispatch!(m, Mach, {
    fn refill_wide(state: &mut ChaCha, drounds: u32, out: &mut [u8; BUFSZ]) {
        refill_wide_impl(m, state, drounds, out);
    }
});

// Single-block, rounds-only; shared by try_apply_keystream for tails shorter than BUFSZ
// and XChaCha's setup step.
dispatch!(m, Mach, {
    fn refill_narrow_rounds(state: &mut ChaCha, drounds: u32) -> State<vec128_storage> {
        let k: Mach::u32x4 = m.vec([0x6170_7865, 0x3320_646e, 0x7962_2d32, 0x6b20_6574]);
        let mut x = State {
            a: k,
            b: m.unpack(state.b),
            c: m.unpack(state.c),
            d: m.unpack(state.d),
        };
        for _ in 0..drounds {
            x = round(x);
            x = undiagonalize(round(diagonalize(x)));
        }
        State {
            a: x.a.into(),
            b: x.b.into(),
            c: x.c.into(),
            d: x.d.into(),
        }
    }
});

dispatch_light128!(m, Mach, {
    fn set_stream_param(state: &mut ChaCha, param: u32, value: u64) {
        let d: Mach::u32x4 = m.unpack(state.d);
        state.d = d
            .insert((value >> 32) as u32, (param << 1) | 1)
            .insert(value as u32, param << 1)
            .into();
    }
});

dispatch_light128!(m, Mach, {
    fn get_stream_param(state: &ChaCha, param: u32) -> u64 {
        let d: Mach::u32x4 = m.unpack(state.d);
        ((d.extract((param << 1) | 1) as u64) << 32) | d.extract(param << 1) as u64
    }
});

fn read_u32le(xs: &[u8]) -> u32 {
    assert_eq!(xs.len(), 4);
    u32::from(xs[0]) | (u32::from(xs[1]) << 8) | (u32::from(xs[2]) << 16) | (u32::from(xs[3]) << 24)
}

dispatch_light128!(m, Mach, {
    fn init_chacha(key: &[u8; 32], nonce: &[u8]) -> ChaCha {
        let ctr_nonce = [
            0,
            if nonce.len() == 12 {
                read_u32le(&nonce[0..4])
            } else {
                0
            },
            read_u32le(&nonce[nonce.len() - 8..nonce.len() - 4]),
            read_u32le(&nonce[nonce.len() - 4..]),
        ];
        let key0: Mach::u32x4 = m.read_le(&key[..16]);
        let key1: Mach::u32x4 = m.read_le(&key[16..]);
        ChaCha {
            b: key0.into(),
            c: key1.into(),
            d: ctr_nonce.into(),
        }
    }
});

dispatch_light128!(m, Mach, {
    fn init_chacha_x(key: &[u8; 32], nonce: &[u8; 24], rounds: u32) -> ChaCha {
        let key0: Mach::u32x4 = m.read_le(&key[..16]);
        let key1: Mach::u32x4 = m.read_le(&key[16..]);
        let nonce0: Mach::u32x4 = m.read_le(&nonce[..16]);
        let mut state = ChaCha {
            b: key0.into(),
            c: key1.into(),
            d: nonce0.into(),
        };
        let x = refill_narrow_rounds(&mut state, rounds);
        let ctr_nonce1 = [0, 0, read_u32le(&nonce[16..20]), read_u32le(&nonce[20..24])];
        state.b = x.a;
        state.c = x.d;
        state.d = ctr_nonce1.into();
        state
    }
});
<commit_msg>rand_chacha: cargo fmt<commit_after>// Copyright 2019 The CryptoCorrosion Contributors
// Copyright 2020 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The ChaCha random number generator.

use ppv_lite86::{dispatch, dispatch_light128};

#[cfg(feature = "rustcrypto_api")] pub use stream_cipher::generic_array;

pub use ppv_lite86::Machine;
use ppv_lite86::{vec128_storage, ArithOps, BitOps32, LaneWords4, MultiLane, StoreBytes, Vec4};

pub(crate) const BLOCK: usize = 64;
pub(crate) const BLOCK64: u64 = BLOCK as u64;
const LOG2_BUFBLOCKS: u64 = 2;
const BUFBLOCKS: u64 = 1 << LOG2_BUFBLOCKS;
pub(crate) const BUFSZ64: u64 = BLOCK64 * BUFBLOCKS;
pub(crate) const BUFSZ: usize = BUFSZ64 as usize;

#[derive(Clone)]
pub struct ChaCha {
    pub(crate) b: vec128_storage,
    pub(crate) c: vec128_storage,
    pub(crate) d: vec128_storage,
}

#[derive(Clone)]
pub struct State<V> {
    pub(crate) a: V,
    pub(crate) b: V,
    pub(crate) c: V,
    pub(crate) d: V,
}

#[inline(always)]
pub(crate) fn round<V: ArithOps + BitOps32>(mut x: State<V>) -> State<V> {
    x.a += x.b;
    x.d = (x.d ^ x.a).rotate_each_word_right16();
    x.c += x.d;
    x.b = (x.b ^ x.c).rotate_each_word_right20();
    x.a += x.b;
    x.d = (x.d ^ x.a).rotate_each_word_right24();
    x.c += x.d;
    x.b = (x.b ^ x.c).rotate_each_word_right25();
    x
}

#[inline(always)]
pub(crate) fn diagonalize<V: LaneWords4>(mut x: State<V>) -> State<V> {
    x.b = x.b.shuffle_lane_words3012();
    x.c = x.c.shuffle_lane_words2301();
    x.d = x.d.shuffle_lane_words1230();
    x
}
#[inline(always)]
pub(crate) fn undiagonalize<V: LaneWords4>(mut x: State<V>) -> State<V> {
    x.b = x.b.shuffle_lane_words1230();
    x.c = x.c.shuffle_lane_words2301();
    x.d = x.d.shuffle_lane_words3012();
    x
}

impl ChaCha {
    #[inline(always)]
    pub fn new(key: &[u8; 32], nonce: &[u8]) -> Self {
        init_chacha(key, nonce)
    }

    #[inline(always)]
    fn pos64<M: Machine>(&self, m: M) -> u64 {
        let d: M::u32x4 = m.unpack(self.d);
        ((d.extract(1) as u64) << 32) | d.extract(0) as u64
    }

    /// Produce 4 blocks of output, advancing the state
    #[inline(always)]
    pub fn refill4(&mut self, drounds: u32, out: &mut [u8; BUFSZ]) {
        refill_wide(self, drounds, out)
    }

    #[inline(always)]
    pub fn set_stream_param(&mut self, param: u32, value: u64) {
        set_stream_param(self, param, value)
    }

    #[inline(always)]
    pub fn get_stream_param(&self, param: u32) -> u64 {
        get_stream_param(self, param)
    }
}

#[inline(always)]
fn refill_wide_impl<Mach: Machine>(
    m: Mach, state: &mut ChaCha, drounds: u32, out: &mut [u8; BUFSZ],
) {
    let k = m.vec([0x6170_7865, 0x3320_646e, 0x7962_2d32, 0x6b20_6574]);
    let mut pos = state.pos64(m);
    let d0: Mach::u32x4 = m.unpack(state.d);
    pos += 1;
    let d1 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
    pos += 1;
    let d2 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
    pos += 1;
    let d3 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);

    let b = m.unpack(state.b);
    let c = m.unpack(state.c);
    let mut x = State {
        a: Mach::u32x4x4::from_lanes([k, k, k, k]),
        b: Mach::u32x4x4::from_lanes([b, b, b, b]),
        c: Mach::u32x4x4::from_lanes([c, c, c, c]),
        d: m.unpack(Mach::u32x4x4::from_lanes([d0, d1, d2, d3]).into()),
    };
    for _ in 0..drounds {
        x = round(x);
        x = undiagonalize(round(diagonalize(x)));
    }
    let mut pos = state.pos64(m);
    let d0: Mach::u32x4 = m.unpack(state.d);
    pos += 1;
    let d1 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
    pos += 1;
    let d2 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
    pos += 1;
    let d3 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
    pos += 1;
    let d4 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);

    let (a, b, c, d) = (
        x.a.to_lanes(),
        x.b.to_lanes(),
        x.c.to_lanes(),
        x.d.to_lanes(),
    );
    let sb = m.unpack(state.b);
    let sc = m.unpack(state.c);
    let sd = [m.unpack(state.d), d1, d2, d3];
    state.d = d4.into();
    let mut words = out.chunks_exact_mut(16);
    for ((((&a, &b), &c), &d), &sd) in a.iter().zip(&b).zip(&c).zip(&d).zip(&sd) {
        (a + k).write_le(words.next().unwrap());
        (b + sb).write_le(words.next().unwrap());
        (c + sc).write_le(words.next().unwrap());
        (d + sd).write_le(words.next().unwrap());
    }
}

dispatch!(m, Mach, {
    fn refill_wide(state: &mut ChaCha, drounds: u32, out: &mut [u8; BUFSZ]) {
        refill_wide_impl(m, state, drounds, out);
    }
});

// Single-block, rounds-only; shared by try_apply_keystream for tails shorter than BUFSZ
// and XChaCha's setup step.
dispatch!(m, Mach, {
    fn refill_narrow_rounds(state: &mut ChaCha, drounds: u32) -> State<vec128_storage> {
        let k: Mach::u32x4 = m.vec([0x6170_7865, 0x3320_646e, 0x7962_2d32, 0x6b20_6574]);
        let mut x = State {
            a: k,
            b: m.unpack(state.b),
            c: m.unpack(state.c),
            d: m.unpack(state.d),
        };
        for _ in 0..drounds {
            x = round(x);
            x = undiagonalize(round(diagonalize(x)));
        }
        State {
            a: x.a.into(),
            b: x.b.into(),
            c: x.c.into(),
            d: x.d.into(),
        }
    }
});

dispatch_light128!(m, Mach, {
    fn set_stream_param(state: &mut ChaCha, param: u32, value: u64) {
        let d: Mach::u32x4 = m.unpack(state.d);
        state.d = d
            .insert((value >> 32) as u32, (param << 1) | 1)
            .insert(value as u32, param << 1)
            .into();
    }
});

dispatch_light128!(m, Mach, {
    fn get_stream_param(state: &ChaCha, param: u32) -> u64 {
        let d: Mach::u32x4 = m.unpack(state.d);
        ((d.extract((param << 1) | 1) as u64) << 32) | d.extract(param << 1) as u64
    }
});

fn read_u32le(xs: &[u8]) -> u32 {
    assert_eq!(xs.len(), 4);
    u32::from(xs[0]) | (u32::from(xs[1]) << 8) | (u32::from(xs[2]) << 16) | (u32::from(xs[3]) << 24)
}

dispatch_light128!(m, Mach, {
    fn init_chacha(key: &[u8; 32], nonce: &[u8]) -> ChaCha {
        let ctr_nonce = [
            0,
            if nonce.len() == 12 {
                read_u32le(&nonce[0..4])
            } else {
                0
            },
            read_u32le(&nonce[nonce.len() - 8..nonce.len() - 4]),
            read_u32le(&nonce[nonce.len() - 4..]),
        ];
        let key0: Mach::u32x4 = m.read_le(&key[..16]);
        let key1: Mach::u32x4 = m.read_le(&key[16..]);
        ChaCha {
            b: key0.into(),
            c: key1.into(),
            d: ctr_nonce.into(),
        }
    }
});

dispatch_light128!(m, Mach, {
    fn init_chacha_x(key: &[u8; 32], nonce: &[u8; 24], rounds: u32) -> ChaCha {
        let key0: Mach::u32x4 = m.read_le(&key[..16]);
        let key1: Mach::u32x4 = m.read_le(&key[16..]);
        let nonce0: Mach::u32x4 = m.read_le(&nonce[..16]);
        let mut state = ChaCha {
            b: key0.into(),
            c: key1.into(),
            d: nonce0.into(),
        };
        let x = refill_narrow_rounds(&mut state, rounds);
        let ctr_nonce1 = [0, 0, read_u32le(&nonce[16..20]), read_u32le(&nonce[20..24])];
        state.b = x.a;
        state.c = x.d;
        state.d = ctr_nonce1.into();
        state
    }
});
<|endoftext|>


<commit_before>use calx::KernelTerrain;
use self::TerrainType::*;

// TODO: Figure out how to not require explicit element count.
macro_rules! terrain_data {
    {
        $($symbol:ident, $name:expr;)*
    } => {
#[derive(Copy, Eq, PartialEq, Clone, Debug)]
        pub enum TerrainType {
            $($symbol,)*
        }

        fn terrain_name(t: TerrainType) -> &'static str {
            match t {
                $($symbol => $name,)*
            }
        }

        pub static _TERRAINS: [TerrainType; count_exprs!($($name),*)] = [
            $($symbol,)*
            ];

    }
}

terrain_data! {
    Void, "void";
    Floor, "floor";
    Water, "water";
    Shallows, "shallows";
    Magma, "magma";
    Downstairs, "stairs down";
    Wall, "wall";
    RockWall, "rock wall";
    Rock, "rock";
    Tree, "tree";
    Grass, "grass";
    // Render variant, do not use directly.
    Grass2, "grass";
    Stalagmite, "stalagmite";
    Door, "door";
    OpenDoor, "open door";
    Window, "window";
    Table, "table";
    Fence, "fence";
    Bars, "bars";
    Fountain, "fountain";
    Altar, "altar";
    Barrel, "barrel";
    Grave, "grave";
    Stone, "stone";
    Menhir, "menhir";
    DeadTree, "dead tree";
}

impl TerrainType {
    pub fn from_name(name: &str) -> Option<TerrainType> {
        for &t in _TERRAINS.iter() {
            if t.name() == name { return Some(t); }
        }
        None
    }

    pub fn blocks_sight(&self) -> bool {
        match *self {
            Wall | RockWall | Rock | Door | Tree | DeadTree => true,
            _ => false
        }
    }

    pub fn blocks_shot(&self) -> bool {
        match *self {
            Wall | RockWall | Rock | Tree | Stalagmite | Door | Menhir | DeadTree => true,
            _ => false
        }
    }

    pub fn blocks_walk(&self) -> bool {
        match *self {
            Floor | Shallows | Grass | Grass2 | Downstairs
                | Door | OpenDoor => false,
            _ => true
        }
    }

    pub fn is_exit(&self) -> bool {
        match *self {
            Downstairs => true,
            _ => false
        }
    }

    pub fn valid_spawn_spot(&self) -> bool { !self.blocks_walk() && !self.is_exit() }

    pub fn is_door(&self) -> bool { *self == Door }

    pub fn is_luminous(&self) -> bool { *self == Magma }

    pub fn name(&self) -> &'static str { terrain_name(*self) }
}

impl KernelTerrain for TerrainType {
    fn is_wall(&self) -> bool {
        match *self {
            Wall | RockWall | Rock | Door | OpenDoor | Window | Bars | Fence => true,
            _ => false
        }
    }

    fn is_block(&self) -> bool {
        match *self {
            Rock => true,
            _ => false
        }
    }
}
<commit_msg>Don't classify Rock blocks as walls<commit_after>use calx::KernelTerrain;
use self::TerrainType::*;

// TODO: Figure out how to not require explicit element count.
macro_rules! terrain_data {
    {
        $($symbol:ident, $name:expr;)*
    } => {
#[derive(Copy, Eq, PartialEq, Clone, Debug)]
        pub enum TerrainType {
            $($symbol,)*
        }

        fn terrain_name(t: TerrainType) -> &'static str {
            match t {
                $($symbol => $name,)*
            }
        }

        pub static _TERRAINS: [TerrainType; count_exprs!($($name),*)] = [
            $($symbol,)*
            ];

    }
}

terrain_data! {
    Void, "void";
    Floor, "floor";
    Water, "water";
    Shallows, "shallows";
    Magma, "magma";
    Downstairs, "stairs down";
    Wall, "wall";
    RockWall, "rock wall";
    Rock, "rock";
    Tree, "tree";
    Grass, "grass";
    // Render variant, do not use directly.
    Grass2, "grass";
    Stalagmite, "stalagmite";
    Door, "door";
    OpenDoor, "open door";
    Window, "window";
    Table, "table";
    Fence, "fence";
    Bars, "bars";
    Fountain, "fountain";
    Altar, "altar";
    Barrel, "barrel";
    Grave, "grave";
    Stone, "stone";
    Menhir, "menhir";
    DeadTree, "dead tree";
}

impl TerrainType {
    pub fn from_name(name: &str) -> Option<TerrainType> {
        for &t in _TERRAINS.iter() {
            if t.name() == name { return Some(t); }
        }
        None
    }

    pub fn blocks_sight(&self) -> bool {
        match *self {
            Wall | RockWall | Rock | Door | Tree | DeadTree => true,
            _ => false
        }
    }

    pub fn blocks_shot(&self) -> bool {
        match *self {
            Wall | RockWall | Rock | Tree | Stalagmite | Door | Menhir | DeadTree => true,
            _ => false
        }
    }

    pub fn blocks_walk(&self) -> bool {
        match *self {
            Floor | Shallows | Grass | Grass2 | Downstairs
                | Door | OpenDoor => false,
            _ => true
        }
    }

    pub fn is_exit(&self) -> bool {
        match *self {
            Downstairs => true,
            _ => false
        }
    }

    pub fn valid_spawn_spot(&self) -> bool { !self.blocks_walk() && !self.is_exit() }

    pub fn is_door(&self) -> bool { *self == Door }

    pub fn is_luminous(&self) -> bool { *self == Magma }

    pub fn name(&self) -> &'static str { terrain_name(*self) }
}

impl KernelTerrain for TerrainType {
    fn is_wall(&self) -> bool {
        match *self {
            Wall | RockWall | Door | OpenDoor | Window | Bars | Fence => true,
            _ => false
        }
    }

    fn is_block(&self) -> bool {
        match *self {
            Rock => true,
            _ => false
        }
    }
}
<|endoftext|>


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

#![feature(static_nobundle)]

#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]

// See librustc_cratesio_shim/Cargo.toml for a comment explaining this.
#[allow(unused_extern_crates)]
extern crate rustc_cratesio_shim;

// NOTE: This crate only exists to allow linking on mingw targets.

/// Initialize targets enabled by the build script via `cfg(llvm_component = "...")`.
/// NB: this function can't be moved to `rustc_codegen_llvm` because of the `cfg`s.
pub fn initialize_available_targets() {
    macro_rules! init_target(
        ($cfg:meta, $($method:ident),*) => { {
            #[cfg($cfg)]
            fn init() {
                extern {
                    $(fn $method();)*
                }
                unsafe {
                    $($method();)*
                }
            }
            #[cfg(not($cfg))]
            fn init() { }
            init();
        } }
    );
    init_target!(llvm_component = "x86",
                 LLVMInitializeX86TargetInfo,
                 LLVMInitializeX86Target,
                 LLVMInitializeX86TargetMC,
                 LLVMInitializeX86AsmPrinter,
                 LLVMInitializeX86AsmParser);
    init_target!(llvm_component = "arm",
                 LLVMInitializeARMTargetInfo,
                 LLVMInitializeARMTarget,
                 LLVMInitializeARMTargetMC,
                 LLVMInitializeARMAsmPrinter,
                 LLVMInitializeARMAsmParser);
    init_target!(llvm_component = "aarch64",
                 LLVMInitializeAArch64TargetInfo,
                 LLVMInitializeAArch64Target,
                 LLVMInitializeAArch64TargetMC,
                 LLVMInitializeAArch64AsmPrinter,
                 LLVMInitializeAArch64AsmParser);
    init_target!(llvm_component = "amdgpu",
                 LLVMInitializeAMDGPUTargetInfo,
                 LLVMInitializeAMDGPUTarget,
                 LLVMInitializeAMDGPUTargetMC,
                 LLVMInitializeAMDGPUAsmPrinter,
                 LLVMInitializeAMDGPUAsmParser);
    init_target!(llvm_component = "mips",
                 LLVMInitializeMipsTargetInfo,
                 LLVMInitializeMipsTarget,
                 LLVMInitializeMipsTargetMC,
                 LLVMInitializeMipsAsmPrinter,
                 LLVMInitializeMipsAsmParser);
    init_target!(llvm_component = "powerpc",
                 LLVMInitializePowerPCTargetInfo,
                 LLVMInitializePowerPCTarget,
                 LLVMInitializePowerPCTargetMC,
                 LLVMInitializePowerPCAsmPrinter,
                 LLVMInitializePowerPCAsmParser);
    init_target!(llvm_component = "systemz",
                 LLVMInitializeSystemZTargetInfo,
                 LLVMInitializeSystemZTarget,
                 LLVMInitializeSystemZTargetMC,
                 LLVMInitializeSystemZAsmPrinter,
                 LLVMInitializeSystemZAsmParser);
    init_target!(llvm_component = "jsbackend",
                 LLVMInitializeJSBackendTargetInfo,
                 LLVMInitializeJSBackendTarget,
                 LLVMInitializeJSBackendTargetMC);
    init_target!(llvm_component = "msp430",
                 LLVMInitializeMSP430TargetInfo,
                 LLVMInitializeMSP430Target,
                 LLVMInitializeMSP430TargetMC,
                 LLVMInitializeMSP430AsmPrinter);
    init_target!(llvm_component = "riscv",
                 LLVMInitializeRISCVTargetInfo,
                 LLVMInitializeRISCVTarget,
                 LLVMInitializeRISCVTargetMC,
                 LLVMInitializeRISCVAsmPrinter,
                 LLVMInitializeRISCVAsmParser);
    init_target!(llvm_component = "sparc",
                 LLVMInitializeSparcTargetInfo,
                 LLVMInitializeSparcTarget,
                 LLVMInitializeSparcTargetMC,
                 LLVMInitializeSparcAsmPrinter,
                 LLVMInitializeSparcAsmParser);
    init_target!(llvm_component = "nvptx",
                 LLVMInitializeNVPTXTargetInfo,
                 LLVMInitializeNVPTXTarget,
                 LLVMInitializeNVPTXTargetMC,
                 LLVMInitializeNVPTXAsmPrinter);
    init_target!(llvm_component = "hexagon",
                 LLVMInitializeHexagonTargetInfo,
                 LLVMInitializeHexagonTarget,
                 LLVMInitializeHexagonTargetMC,
                 LLVMInitializeHexagonAsmPrinter,
                 LLVMInitializeHexagonAsmParser);
    init_target!(llvm_component = "webassembly",
                 LLVMInitializeWebAssemblyTargetInfo,
                 LLVMInitializeWebAssemblyTarget,
                 LLVMInitializeWebAssemblyTargetMC,
                 LLVMInitializeWebAssemblyAsmPrinter);
}
<commit_msg>[nll] librustc_llvm: enable feature(nll) for bootstrap<commit_after>// Copyright 2012-2015 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.

#![cfg_attr(not(stage0), feature(nll))]
#![feature(static_nobundle)]

#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]

// See librustc_cratesio_shim/Cargo.toml for a comment explaining this.
#[allow(unused_extern_crates)]
extern crate rustc_cratesio_shim;

// NOTE: This crate only exists to allow linking on mingw targets.

/// Initialize targets enabled by the build script via `cfg(llvm_component = "...")`.
/// NB: this function can't be moved to `rustc_codegen_llvm` because of the `cfg`s.
pub fn initialize_available_targets() {
    macro_rules! init_target(
        ($cfg:meta, $($method:ident),*) => { {
            #[cfg($cfg)]
            fn init() {
                extern {
                    $(fn $method();)*
                }
                unsafe {
                    $($method();)*
                }
            }
            #[cfg(not($cfg))]
            fn init() { }
            init();
        } }
    );
    init_target!(llvm_component = "x86",
                 LLVMInitializeX86TargetInfo,
                 LLVMInitializeX86Target,
                 LLVMInitializeX86TargetMC,
                 LLVMInitializeX86AsmPrinter,
                 LLVMInitializeX86AsmParser);
    init_target!(llvm_component = "arm",
                 LLVMInitializeARMTargetInfo,
                 LLVMInitializeARMTarget,
                 LLVMInitializeARMTargetMC,
                 LLVMInitializeARMAsmPrinter,
                 LLVMInitializeARMAsmParser);
    init_target!(llvm_component = "aarch64",
                 LLVMInitializeAArch64TargetInfo,
                 LLVMInitializeAArch64Target,
                 LLVMInitializeAArch64TargetMC,
                 LLVMInitializeAArch64AsmPrinter,
                 LLVMInitializeAArch64AsmParser);
    init_target!(llvm_component = "amdgpu",
                 LLVMInitializeAMDGPUTargetInfo,
                 LLVMInitializeAMDGPUTarget,
                 LLVMInitializeAMDGPUTargetMC,
                 LLVMInitializeAMDGPUAsmPrinter,
                 LLVMInitializeAMDGPUAsmParser);
    init_target!(llvm_component = "mips",
                 LLVMInitializeMipsTargetInfo,
                 LLVMInitializeMipsTarget,
                 LLVMInitializeMipsTargetMC,
                 LLVMInitializeMipsAsmPrinter,
                 LLVMInitializeMipsAsmParser);
    init_target!(llvm_component = "powerpc",
                 LLVMInitializePowerPCTargetInfo,
                 LLVMInitializePowerPCTarget,
                 LLVMInitializePowerPCTargetMC,
                 LLVMInitializePowerPCAsmPrinter,
                 LLVMInitializePowerPCAsmParser);
    init_target!(llvm_component = "systemz",
                 LLVMInitializeSystemZTargetInfo,
                 LLVMInitializeSystemZTarget,
                 LLVMInitializeSystemZTargetMC,
                 LLVMInitializeSystemZAsmPrinter,
                 LLVMInitializeSystemZAsmParser);
    init_target!(llvm_component = "jsbackend",
                 LLVMInitializeJSBackendTargetInfo,
                 LLVMInitializeJSBackendTarget,
                 LLVMInitializeJSBackendTargetMC);
    init_target!(llvm_component = "msp430",
                 LLVMInitializeMSP430TargetInfo,
                 LLVMInitializeMSP430Target,
                 LLVMInitializeMSP430TargetMC,
                 LLVMInitializeMSP430AsmPrinter);
    init_target!(llvm_component = "riscv",
                 LLVMInitializeRISCVTargetInfo,
                 LLVMInitializeRISCVTarget,
                 LLVMInitializeRISCVTargetMC,
                 LLVMInitializeRISCVAsmPrinter,
                 LLVMInitializeRISCVAsmParser);
    init_target!(llvm_component = "sparc",
                 LLVMInitializeSparcTargetInfo,
                 LLVMInitializeSparcTarget,
                 LLVMInitializeSparcTargetMC,
                 LLVMInitializeSparcAsmPrinter,
                 LLVMInitializeSparcAsmParser);
    init_target!(llvm_component = "nvptx",
                 LLVMInitializeNVPTXTargetInfo,
                 LLVMInitializeNVPTXTarget,
                 LLVMInitializeNVPTXTargetMC,
                 LLVMInitializeNVPTXAsmPrinter);
    init_target!(llvm_component = "hexagon",
                 LLVMInitializeHexagonTargetInfo,
                 LLVMInitializeHexagonTarget,
                 LLVMInitializeHexagonTargetMC,
                 LLVMInitializeHexagonAsmPrinter,
                 LLVMInitializeHexagonAsmParser);
    init_target!(llvm_component = "webassembly",
                 LLVMInitializeWebAssemblyTargetInfo,
                 LLVMInitializeWebAssemblyTarget,
                 LLVMInitializeWebAssemblyTargetMC,
                 LLVMInitializeWebAssemblyAsmPrinter);
}
<|endoftext|>


<commit_before><commit_msg>Auto merge of #2153 - umanwizard:locale, r=JohnTitor<commit_after><|endoftext|>