<commit_before>//! Defines the `IntoIter` owned iterator for arrays.

use crate::{
    fmt,
    iter::{ExactSizeIterator, FusedIterator, TrustedLen},
    mem::{self, MaybeUninit},
    ops::Range,
    ptr,
};
use super::LengthAtMost32;

/// A by-value [array] iterator.
///
/// [array]: ../../std/primitive.array.html
#[unstable(feature = "array_value_iter", issue = "65798")]
pub struct IntoIter<T, const N: usize>
where
    [T; N]: LengthAtMost32,
{
    /// This is the array we are iterating over.
    ///
    /// Elements with index `i` where `alive.start <= i < alive.end` have not
    /// been yielded yet and are valid array entries. Elements with indices `i
    /// < alive.start` or `i >= alive.end` have been yielded already and must
    /// not be accessed anymore! Those dead elements might even be in a
    /// completely uninitialized state!
    ///
    /// So the invariants are:
    /// - `data[alive]` is alive (i.e. contains valid elements)
    /// - `data[..alive.start]` and `data[alive.end..]` are dead (i.e. the
    ///   elements were already read and must not be touched anymore!)
    data: [MaybeUninit<T>; N],

    /// The elements in `data` that have not been yielded yet.
    ///
    /// Invariants:
    /// - `alive.start <= alive.end`
    /// - `alive.end <= N`
    alive: Range<usize>,
}

impl<T, const N: usize> IntoIter<T, {N}>
where
    [T; N]: LengthAtMost32,
{
    /// Creates a new iterator over the given `array`.
    ///
    /// *Note*: this method might never get stabilized and/or removed in the
    /// future as there will likely be another, preferred way of obtaining this
    /// iterator (either via `IntoIterator` for arrays or via another way).
    #[unstable(feature = "array_value_iter", issue = "65798")]
    pub fn new(array: [T; N]) -> Self {
        // The transmute here is actually safe. The docs of `MaybeUninit`
        // promise:
        //
        // > `MaybeUninit<T>` is guaranteed to have the same size and alignment
        // > as `T`.
        //
        // The docs even show a transmute from an array of `MaybeUninit<T>` to
        // an array of `T`.
        //
        // With that, this initialization satisfies the invariants.

        // FIXME(LukasKalbertodt): actually use `mem::transmute` here, once it
        // works with const generics:
        //     `mem::transmute::<[T; {N}], [MaybeUninit<T>; {N}]>(array)`
        //
        // Until then, we do it manually here. We first create a bitwise copy
        // but cast the pointer so that it is treated as a different type. Then
        // we forget `array` so that it is not dropped.
        let data = unsafe {
            let data = ptr::read(&array as *const [T; N] as *const [MaybeUninit<T>; N]);
            mem::forget(array);
            data
        };

        Self {
            data,
            alive: 0..N,
        }
    }

    /// Returns an immutable slice of all elements that have not been yielded
    /// yet.
    fn as_slice(&self) -> &[T] {
        // This transmute is safe. As mentioned in `new`, `MaybeUninit` retains
        // the size and alignment of `T`. Furthermore, we know that all
        // elements within `alive` are properly initialized.
        let slice = &self.data[self.alive.clone()];
        unsafe {
            mem::transmute::<&[MaybeUninit<T>], &[T]>(slice)
        }
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> Iterator for IntoIter<T, {N}>
where
    [T; N]: LengthAtMost32,
{
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        if self.alive.start == self.alive.end {
            return None;
        }

        // Bump start index.
        //
        // From the check above we know that `alive.start != alive.end`.
        // Combine this with the invariant `alive.start <= alive.end`, we know
        // that `alive.start < alive.end`. Increasing `alive.start` by 1
        // maintains the invariant regarding `alive`. However, due to this
        // change, for a short time, the alive zone is not `data[alive]`
        // anymore, but `data[idx..alive.end]`.
        let idx = self.alive.start;
        self.alive.start += 1;

        // Read the element from the array. This is safe: `idx` is an index
        // into the "alive" region of the array. Reading this element means
        // that `data[idx]` is regarded as dead now (i.e. do not touch). As
        // `idx` was the start of the alive-zone, the alive zone is now
        // `data[alive]` again, restoring all invariants.
        let out = unsafe { self.data.get_unchecked(idx).read() };

        Some(out)
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.len();
        (len, Some(len))
    }

    fn count(self) -> usize {
        self.len()
    }

    fn last(mut self) -> Option<Self::Item> {
        self.next_back()
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, {N}>
where
    [T; N]: LengthAtMost32,
{
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.alive.start == self.alive.end {
            return None;
        }

        // Decrease end index.
        //
        // From the check above we know that `alive.start != alive.end`.
        // Combine this with the invariant `alive.start <= alive.end`, we know
        // that `alive.start < alive.end`. As `alive.start` cannot be negative,
        // `alive.end` is at least 1, meaning that we can safely decrement it
        // by one. This also maintains the invariant `alive.start <=
        // alive.end`. However, due to this change, for a short time, the alive
        // zone is not `data[alive]` anymore, but `data[alive.start..alive.end
        // + 1]`.
        self.alive.end -= 1;

        // Read the element from the array. This is safe: `alive.end` is an
        // index into the "alive" region of the array. Compare the previous
        // comment that states that the alive region is
        // `data[alive.start..alive.end + 1]`. Reading this element means that
        // `data[alive.end]` is regarded as dead now (i.e. do not touch). As
        // `alive.end` was the end of the alive-zone, the alive zone is now
        // `data[alive]` again, restoring all invariants.
        let out = unsafe { self.data.get_unchecked(self.alive.end).read() };

        Some(out)
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> Drop for IntoIter<T, {N}>
where
    [T; N]: LengthAtMost32,
{
    fn drop(&mut self) {
        // We simply drop each element via `for_each`. This should not incur
        // any significant runtime overhead and avoids adding another `unsafe`
        // block.
        self.by_ref().for_each(drop);
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> ExactSizeIterator for IntoIter<T, {N}>
where
    [T; N]: LengthAtMost32,
{
    fn len(&self) -> usize {
        // Will never underflow due to the invariant `alive.start <=
        // alive.end`.
        self.alive.end - self.alive.start
    }
    fn is_empty(&self) -> bool {
        self.alive.is_empty()
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> FusedIterator for IntoIter<T, {N}>
where
    [T; N]: LengthAtMost32,
{}

// The iterator indeed reports the correct length. The number of "alive"
// elements (that will still be yielded) is the length of the range `alive`.
// This range is decremented in length in either `next` or `next_back`. It is
// always decremented by 1 in those methods, but only if `Some(_)` is returned.
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
unsafe impl<T, const N: usize> TrustedLen for IntoIter<T, {N}>
where
    [T; N]: LengthAtMost32,
{}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T: Clone, const N: usize> Clone for IntoIter<T, {N}>
where
    [T; N]: LengthAtMost32,
{
    fn clone(&self) -> Self {
        unsafe {
            // This creates a new uninitialized array. Note that the `assume_init`
            // refers to the array, not the individual elements. And it is Ok if
            // the array is in an uninitialized state as all elements may be
            // uninitialized (all bit patterns are valid). Compare the
            // `MaybeUninit` docs for more information.
            let mut new_data: [MaybeUninit<T>; N] = MaybeUninit::uninit().assume_init();

            // Clone all alive elements.
            for idx in self.alive.clone() {
                // The element at `idx` in the old array is alive, so we can
                // safely call `get_ref()`. We then clone it, and write the
                // clone into the new array.
                let clone = self.data.get_unchecked(idx).get_ref().clone();
                new_data.get_unchecked_mut(idx).write(clone);
            }

            Self {
                data: new_data,
                alive: self.alive.clone(),
            }
        }
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T: fmt::Debug, const N: usize> fmt::Debug for IntoIter<T, {N}>
where
    [T; N]: LengthAtMost32,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // Only print the elements that were not yielded yet: we cannot
        // access the yielded elements anymore.
        f.debug_tuple("IntoIter")
            .field(&self.as_slice())
            .finish()
    }
}
<commit_msg>The unsafety in `iter.rs` is already documented wonderfully<commit_after>//! Defines the `IntoIter` owned iterator for arrays.

use crate::{
    fmt,
    iter::{ExactSizeIterator, FusedIterator, TrustedLen},
    mem::{self, MaybeUninit},
    ops::Range,
    ptr,
};
use super::LengthAtMost32;

/// A by-value [array] iterator.
///
/// [array]: ../../std/primitive.array.html
#[unstable(feature = "array_value_iter", issue = "65798")]
pub struct IntoIter<T, const N: usize>
where
    [T; N]: LengthAtMost32,
{
    /// This is the array we are iterating over.
    ///
    /// Elements with index `i` where `alive.start <= i < alive.end` have not
    /// been yielded yet and are valid array entries. Elements with indices `i
    /// < alive.start` or `i >= alive.end` have been yielded already and must
    /// not be accessed anymore! Those dead elements might even be in a
    /// completely uninitialized state!
    ///
    /// So the invariants are:
    /// - `data[alive]` is alive (i.e. contains valid elements)
    /// - `data[..alive.start]` and `data[alive.end..]` are dead (i.e. the
    ///   elements were already read and must not be touched anymore!)
    data: [MaybeUninit<T>; N],

    /// The elements in `data` that have not been yielded yet.
    ///
    /// Invariants:
    /// - `alive.start <= alive.end`
    /// - `alive.end <= N`
    alive: Range<usize>,
}

impl<T, const N: usize> IntoIter<T, {N}>
where
    [T; N]: LengthAtMost32,
{
    /// Creates a new iterator over the given `array`.
    ///
    /// *Note*: this method might never get stabilized and/or removed in the
    /// future as there will likely be another, preferred way of obtaining this
    /// iterator (either via `IntoIterator` for arrays or via another way).
    #[unstable(feature = "array_value_iter", issue = "65798")]
    pub fn new(array: [T; N]) -> Self {
        // SAFETY: The transmute here is actually safe. The docs of `MaybeUninit`
        // promise:
        //
        // > `MaybeUninit<T>` is guaranteed to have the same size and alignment
        // > as `T`.
        //
        // The docs even show a transmute from an array of `MaybeUninit<T>` to
        // an array of `T`.
        //
        // With that, this initialization satisfies the invariants.

        // FIXME(LukasKalbertodt): actually use `mem::transmute` here, once it
        // works with const generics:
        //     `mem::transmute::<[T; {N}], [MaybeUninit<T>; {N}]>(array)`
        //
        // Until then, we do it manually here. We first create a bitwise copy
        // but cast the pointer so that it is treated as a different type. Then
        // we forget `array` so that it is not dropped.
        let data = unsafe {
            let data = ptr::read(&array as *const [T; N] as *const [MaybeUninit<T>; N]);
            mem::forget(array);
            data
        };

        Self {
            data,
            alive: 0..N,
        }
    }

    /// Returns an immutable slice of all elements that have not been yielded
    /// yet.
    fn as_slice(&self) -> &[T] {
        let slice = &self.data[self.alive.clone()];
        // SAFETY: This transmute is safe. As mentioned in `new`, `MaybeUninit` retains
        // the size and alignment of `T`. Furthermore, we know that all
        // elements within `alive` are properly initialized.
        unsafe {
            mem::transmute::<&[MaybeUninit<T>], &[T]>(slice)
        }
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> Iterator for IntoIter<T, {N}>
where
    [T; N]: LengthAtMost32,
{
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        if self.alive.start == self.alive.end {
            return None;
        }

        // Bump start index.
        //
        // From the check above we know that `alive.start != alive.end`.
        // Combine this with the invariant `alive.start <= alive.end`, we know
        // that `alive.start < alive.end`. Increasing `alive.start` by 1
        // maintains the invariant regarding `alive`. However, due to this
        // change, for a short time, the alive zone is not `data[alive]`
        // anymore, but `data[idx..alive.end]`.
        let idx = self.alive.start;
        self.alive.start += 1;

        // Read the element from the array.
        // SAFETY: This is safe: `idx` is an index
        // into the "alive" region of the array. Reading this element means
        // that `data[idx]` is regarded as dead now (i.e. do not touch). As
        // `idx` was the start of the alive-zone, the alive zone is now
        // `data[alive]` again, restoring all invariants.
        let out = unsafe { self.data.get_unchecked(idx).read() };

        Some(out)
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.len();
        (len, Some(len))
    }

    fn count(self) -> usize {
        self.len()
    }

    fn last(mut self) -> Option<Self::Item> {
        self.next_back()
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, {N}>
where
    [T; N]: LengthAtMost32,
{
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.alive.start == self.alive.end {
            return None;
        }

        // Decrease end index.
        //
        // From the check above we know that `alive.start != alive.end`.
        // Combine this with the invariant `alive.start <= alive.end`, we know
        // that `alive.start < alive.end`. As `alive.start` cannot be negative,
        // `alive.end` is at least 1, meaning that we can safely decrement it
        // by one. This also maintains the invariant `alive.start <=
        // alive.end`. However, due to this change, for a short time, the alive
        // zone is not `data[alive]` anymore, but `data[alive.start..alive.end
        // + 1]`.
        self.alive.end -= 1;

        // Read the element from the array.
        // SAFETY: This is safe: `alive.end` is an
        // index into the "alive" region of the array. Compare the previous
        // comment that states that the alive region is
        // `data[alive.start..alive.end + 1]`. Reading this element means that
        // `data[alive.end]` is regarded as dead now (i.e. do not touch). As
        // `alive.end` was the end of the alive-zone, the alive zone is now
        // `data[alive]` again, restoring all invariants.
        let out = unsafe { self.data.get_unchecked(self.alive.end).read() };

        Some(out)
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> Drop for IntoIter<T, {N}>
where
    [T; N]: LengthAtMost32,
{
    fn drop(&mut self) {
        // We simply drop each element via `for_each`. This should not incur
        // any significant runtime overhead and avoids adding another `unsafe`
        // block.
        self.by_ref().for_each(drop);
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> ExactSizeIterator for IntoIter<T, {N}>
where
    [T; N]: LengthAtMost32,
{
    fn len(&self) -> usize {
        // Will never underflow due to the invariant `alive.start <=
        // alive.end`.
        self.alive.end - self.alive.start
    }
    fn is_empty(&self) -> bool {
        self.alive.is_empty()
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> FusedIterator for IntoIter<T, {N}>
where
    [T; N]: LengthAtMost32,
{}

// The iterator indeed reports the correct length. The number of "alive"
// elements (that will still be yielded) is the length of the range `alive`.
// This range is decremented in length in either `next` or `next_back`. It is
// always decremented by 1 in those methods, but only if `Some(_)` is returned.
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
unsafe impl<T, const N: usize> TrustedLen for IntoIter<T, {N}>
where
    [T; N]: LengthAtMost32,
{}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T: Clone, const N: usize> Clone for IntoIter<T, {N}>
where
    [T; N]: LengthAtMost32,
{
    fn clone(&self) -> Self {
        // SAFETY: each point of unsafety is documented inside the unsafe block
        unsafe {
            // This creates a new uninitialized array. Note that the `assume_init`
            // refers to the array, not the individual elements. And it is Ok if
            // the array is in an uninitialized state as all elements may be
            // uninitialized (all bit patterns are valid). Compare the
            // `MaybeUninit` docs for more information.
            let mut new_data: [MaybeUninit<T>; N] = MaybeUninit::uninit().assume_init();

            // Clone all alive elements.
            for idx in self.alive.clone() {
                // The element at `idx` in the old array is alive, so we can
                // safely call `get_ref()`. We then clone it, and write the
                // clone into the new array.
                let clone = self.data.get_unchecked(idx).get_ref().clone();
                new_data.get_unchecked_mut(idx).write(clone);
            }

            Self {
                data: new_data,
                alive: self.alive.clone(),
            }
        }
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T: fmt::Debug, const N: usize> fmt::Debug for IntoIter<T, {N}>
where
    [T; N]: LengthAtMost32,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // Only print the elements that were not yielded yet: we cannot
        // access the yielded elements anymore.
        f.debug_tuple("IntoIter")
            .field(&self.as_slice())
            .finish()
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 The noise-rs developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::num::Float;

use {gradient, math, Seed};

/// 2-dimensional perlin noise
pub fn perlin2<T: Float>(seed: &Seed, point: &math::Point2<T>) -> T {
    #[inline(always)]
    fn gradient<T: Float>(seed: math::Point2<usize>, frac: math::Vector2<T>) -> T {
        math::dot2(frac, gradient::get2((seed[0] ^ seed[1]) as usize))
    }

    let one: T = math::cast(1);

    let xfloor = point[0].floor();
    let yfloor = point[1].floor();

    let x0_whole: isize = math::cast(xfloor);
    let y0_whole: isize = math::cast(yfloor);

    let x1_whole = x0_whole + 1;
    let y1_whole = y0_whole + 1;

    let x0_frac = point[0] - xfloor;
    let y0_frac = point[1] - yfloor;

    let x1_frac = x0_frac - one;
    let y1_frac = y0_frac - one;

    let x_curve = math::scurve5(x0_frac);
    let y_curve = math::scurve5(y0_frac);

    let x0_cache = seed.get1(x0_whole);
    let y0_cache = seed.get1(y0_whole);
    let x1_cache = seed.get1(x1_whole);
    let y1_cache = seed.get1(y1_whole);

    let f00 = gradient([x0_cache, y0_cache], [x0_frac, y0_frac]);
    let f10 = gradient([x1_cache, y0_cache], [x1_frac, y0_frac]);
    let f01 = gradient([x0_cache, y1_cache], [x0_frac, y1_frac]);
    let f11 = gradient([x1_cache, y1_cache], [x1_frac, y1_frac]);

    math::bilerp(x_curve, y_curve, f00, f10, f01, f11)
}

/// 3-dimensional perlin noise
pub fn perlin3<T: Float>(seed: &Seed, point: &math::Point3<T>) -> T {
    #[inline(always)]
    fn gradient<T: Float>(seed: math::Point3<usize>, frac: math::Vector3<T>) -> T {
        math::dot3(frac, gradient::get3(seed[0] ^ seed[1] ^ seed[2]))
    }

    let one: T = math::cast(1);

    let xfloor = point[0].floor();
    let yfloor = point[1].floor();
    let zfloor = point[2].floor();

    let x0_whole: isize = math::cast(xfloor);
    let y0_whole: isize = math::cast(yfloor);
    let z0_whole: isize = math::cast(zfloor);

    let x1_whole = x0_whole + 1;
    let y1_whole = y0_whole + 1;
    let z1_whole = z0_whole + 1;

    let x0_frac = point[0] - xfloor;
    let y0_frac = point[1] - yfloor;
    let z0_frac = point[2] - zfloor;

    let x1_frac = x0_frac - one;
    let y1_frac = y0_frac - one;
    let z1_frac = z0_frac - one;

    let x_curve = math::scurve5(x0_frac);
    let y_curve = math::scurve5(y0_frac);
    let z_curve = math::scurve5(z0_frac);

    let x0_cache = seed.get1(x0_whole);
    let y0_cache = seed.get1(y0_whole);
    let z0_cache = seed.get1(z0_whole);
    let x1_cache = seed.get1(x1_whole);
    let y1_cache = seed.get1(y1_whole);
    let z1_cache = seed.get1(z1_whole);

    let f000 = gradient([x0_cache, y0_cache, z0_cache], [x0_frac, y0_frac, z0_frac]);
    let f100 = gradient([x1_cache, y0_cache, z0_cache], [x1_frac, y0_frac, z0_frac]);
    let f010 = gradient([x0_cache, y1_cache, z0_cache], [x0_frac, y1_frac, z0_frac]);
    let f110 = gradient([x1_cache, y1_cache, z0_cache], [x1_frac, y1_frac, z0_frac]);
    let f001 = gradient([x0_cache, y0_cache, z1_cache], [x0_frac, y0_frac, z1_frac]);
    let f101 = gradient([x1_cache, y0_cache, z1_cache], [x1_frac, y0_frac, z1_frac]);
    let f011 = gradient([x0_cache, y1_cache, z1_cache], [x0_frac, y1_frac, z1_frac]);
    let f111 = gradient([x1_cache, y1_cache, z1_cache], [x1_frac, y1_frac, z1_frac]);

    math::trilerp(x_curve, y_curve, z_curve, f000, f100, f010, f110, f001, f101, f011, f111)
}

/// 4-dimensional perlin noise
pub fn perlin4<T: Float>(seed: &Seed, point: &math::Point4<T>) -> T {
    #[inline(always)]
    fn gradient<T: Float>(seed: math::Point4<usize>, frac: math::Vector4<T>) -> T {
        math::dot4(frac, gradient::get4(seed[0] ^ seed[1] ^ seed[2] ^ seed[3]))
    }

    let one: T = math::cast(1);

    let xfloor = point[0].floor();
    let yfloor = point[1].floor();
    let zfloor = point[2].floor();
    let wfloor = point[3].floor();

    let x0_whole: isize = math::cast(xfloor);
    let y0_whole: isize = math::cast(yfloor);
    let z0_whole: isize = math::cast(zfloor);
    let w0_whole: isize = math::cast(wfloor);

    let x1_whole = x0_whole + 1;
    let y1_whole = y0_whole + 1;
    let z1_whole = z0_whole + 1;
    let w1_whole = w0_whole + 1;

    let x0_frac = point[0] - xfloor;
    let y0_frac = point[1] - yfloor;
    let z0_frac = point[2] - zfloor;
    let w0_frac = point[2] - wfloor;

    let x1_frac = x0_frac - one;
    let y1_frac = y0_frac - one;
    let z1_frac = z0_frac - one;
    let w1_frac = w0_frac - one;

    let x_curve = math::scurve5(x0_frac);
    let y_curve = math::scurve5(y0_frac);
    let z_curve = math::scurve5(z0_frac);
    let w_curve = math::scurve5(w0_frac);

    let x0_cache = seed.get1(x0_whole);
    let y0_cache = seed.get1(y0_whole);
    let z0_cache = seed.get1(z0_whole);
    let w0_cache = seed.get1(w0_whole);
    let x1_cache = seed.get1(x1_whole);
    let y1_cache = seed.get1(y1_whole);
    let z1_cache = seed.get1(z1_whole);
    let w1_cache = seed.get1(w1_whole);

    let f0000 = gradient([x0_cache, y0_cache, z0_cache, w0_cache], [x0_frac, y0_frac, z0_frac, w0_frac]);
    let f1000 = gradient([x1_cache, y0_cache, z0_cache, w0_cache], [x1_frac, y0_frac, z0_frac, w0_frac]);
    let f0001 = gradient([x0_cache, y1_cache, z0_cache, w0_cache], [x0_frac, y1_frac, z0_frac, w0_frac]);
    let f1001 = gradient([x1_cache, y1_cache, z0_cache, w0_cache], [x1_frac, y1_frac, z0_frac, w0_frac]);
    let f0010 = gradient([x0_cache, y0_cache, z1_cache, w0_cache], [x0_frac, y0_frac, z1_frac, w0_frac]);
    let f1010 = gradient([x1_cache, y0_cache, z1_cache, w0_cache], [x1_frac, y0_frac, z1_frac, w0_frac]);
    let f0011 = gradient([x0_cache, y1_cache, z1_cache, w0_cache], [x0_frac, y1_frac, z1_frac, w0_frac]);
    let f1011 = gradient([x1_cache, y1_cache, z1_cache, w0_cache], [x1_frac, y1_frac, z1_frac, w0_frac]);
    let f0100 = gradient([x0_cache, y0_cache, z0_cache, w1_cache], [x0_frac, y0_frac, z0_frac, w1_frac]);
    let f1100 = gradient([x1_cache, y0_cache, z0_cache, w1_cache], [x1_frac, y0_frac, z0_frac, w1_frac]);
    let f0101 = gradient([x0_cache, y1_cache, z0_cache, w1_cache], [x0_frac, y1_frac, z0_frac, w1_frac]);
    let f1101 = gradient([x1_cache, y1_cache, z0_cache, w1_cache], [x1_frac, y1_frac, z0_frac, w1_frac]);
    let f0110 = gradient([x0_cache, y0_cache, z1_cache, w1_cache], [x0_frac, y0_frac, z1_frac, w1_frac]);
    let f1110 = gradient([x1_cache, y0_cache, z1_cache, w1_cache], [x1_frac, y0_frac, z1_frac, w1_frac]);
    let f0111 = gradient([x0_cache, y1_cache, z1_cache, w1_cache], [x0_frac, y1_frac, z1_frac, w1_frac]);
    let f1111 = gradient([x1_cache, y1_cache, z1_cache, w1_cache], [x1_frac, y1_frac, z1_frac, w1_frac]);

    math::quadlerp(x_curve, y_curve, z_curve, w_curve, f0000, f1000, f0001, f1001, f0010, f1010, f0011, f1011, f0100, f1100, f0101, f1101, f0110, f1110, f0111, f1111)
}
<commit_msg>Revert "Cache permutation lookups for perlin"<commit_after>// Copyright 2015 The noise-rs developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::num::Float;

use {gradient, math, Seed};

/// 2-dimensional perlin noise
pub fn perlin2<T: Float>(seed: &Seed, point: &math::Point2<T>) -> T {
    #[inline(always)]
    fn gradient<T: Float>(seed: &Seed, whole: math::Point2<isize>, frac: math::Vector2<T>) -> T {
        math::dot2(frac, gradient::get2(seed.get2(whole)))
    }

    let one: T = math::cast(1);

    let xfloor = point[0].floor();
    let yfloor = point[1].floor();

    let x0_whole: isize = math::cast(xfloor);
    let y0_whole: isize = math::cast(yfloor);

    let x1_whole = x0_whole + 1;
    let y1_whole = y0_whole + 1;

    let x0_frac = point[0] - xfloor;
    let y0_frac = point[1] - yfloor;

    let x1_frac = x0_frac - one;
    let y1_frac = y0_frac - one;

    let x_curve = math::scurve5(x0_frac);
    let y_curve = math::scurve5(y0_frac);

    let f00 = gradient(seed, [x0_whole, y0_whole], [x0_frac, y0_frac]);
    let f10 = gradient(seed, [x1_whole, y0_whole], [x1_frac, y0_frac]);
    let f01 = gradient(seed, [x0_whole, y1_whole], [x0_frac, y1_frac]);
    let f11 = gradient(seed, [x1_whole, y1_whole], [x1_frac, y1_frac]);

    math::bilerp(x_curve, y_curve, f00, f10, f01, f11)
}

/// 3-dimensional perlin noise
pub fn perlin3<T: Float>(seed: &Seed, point: &math::Point3<T>) -> T {
    #[inline(always)]
    fn gradient<T: Float>(seed: &Seed, whole: math::Point3<isize>, frac: math::Vector3<T>) -> T {
        math::dot3(frac, gradient::get3(seed.get3(whole)))
    }

    let one: T = math::cast(1);

    let xfloor = point[0].floor();
    let yfloor = point[1].floor();
    let zfloor = point[2].floor();

    let x0_whole: isize = math::cast(xfloor);
    let y0_whole: isize = math::cast(yfloor);
    let z0_whole: isize = math::cast(zfloor);

    let x1_whole = x0_whole + 1;
    let y1_whole = y0_whole + 1;
    let z1_whole = z0_whole + 1;

    let x0_frac = point[0] - xfloor;
    let y0_frac = point[1] - yfloor;
    let z0_frac = point[2] - zfloor;

    let x1_frac = x0_frac - one;
    let y1_frac = y0_frac - one;
    let z1_frac = z0_frac - one;

    let x_curve = math::scurve5(x0_frac);
    let y_curve = math::scurve5(y0_frac);
    let z_curve = math::scurve5(z0_frac);

    let f000 = gradient(seed, [x0_whole, y0_whole, z0_whole], [x0_frac, y0_frac, z0_frac]);
    let f100 = gradient(seed, [x1_whole, y0_whole, z0_whole], [x1_frac, y0_frac, z0_frac]);
    let f010 = gradient(seed, [x0_whole, y1_whole, z0_whole], [x0_frac, y1_frac, z0_frac]);
    let f110 = gradient(seed, [x1_whole, y1_whole, z0_whole], [x1_frac, y1_frac, z0_frac]);
    let f001 = gradient(seed, [x0_whole, y0_whole, z1_whole], [x0_frac, y0_frac, z1_frac]);
    let f101 = gradient(seed, [x1_whole, y0_whole, z1_whole], [x1_frac, y0_frac, z1_frac]);
    let f011 = gradient(seed, [x0_whole, y1_whole, z1_whole], [x0_frac, y1_frac, z1_frac]);
    let f111 = gradient(seed, [x1_whole, y1_whole, z1_whole], [x1_frac, y1_frac, z1_frac]);

    math::trilerp(x_curve, y_curve, z_curve, f000, f100, f010, f110, f001, f101, f011, f111)
}

/// 4-dimensional perlin noise
pub fn perlin4<T: Float>(seed: &Seed, point: &math::Point4<T>) -> T {
    #[inline(always)]
    fn gradient<T: Float>(seed: &Seed, whole: math::Point4<isize>, frac: math::Vector4<T>) -> T {
        math::dot4(frac, gradient::get4(seed.get4(whole)))
    }

    let one: T = math::cast(1);

    let xfloor = point[0].floor();
    let yfloor = point[1].floor();
    let zfloor = point[2].floor();
    let wfloor = point[3].floor();

    let x0_whole: isize = math::cast(xfloor);
    let y0_whole: isize = math::cast(yfloor);
    let z0_whole: isize = math::cast(zfloor);
    let w0_whole: isize = math::cast(wfloor);

    let x1_whole = x0_whole + 1;
    let y1_whole = y0_whole + 1;
    let z1_whole = z0_whole + 1;
    let w1_whole = w0_whole + 1;

    let x0_frac = point[0] - xfloor;
    let y0_frac = point[1] - yfloor;
    let z0_frac = point[2] - zfloor;
    let w0_frac = point[2] - wfloor;

    let x1_frac = x0_frac - one;
    let y1_frac = y0_frac - one;
    let z1_frac = z0_frac - one;
    let w1_frac = w0_frac - one;

    let x_curve = math::scurve5(x0_frac);
    let y_curve = math::scurve5(y0_frac);
    let z_curve = math::scurve5(z0_frac);
    let w_curve = math::scurve5(w0_frac);

    let f0000 = gradient(seed, [x0_whole, y0_whole, z0_whole, w0_whole], [x0_frac, y0_frac, z0_frac, w0_frac]);
    let f1000 = gradient(seed, [x1_whole, y0_whole, z0_whole, w0_whole], [x1_frac, y0_frac, z0_frac, w0_frac]);
    let f0001 = gradient(seed, [x0_whole, y1_whole, z0_whole, w0_whole], [x0_frac, y1_frac, z0_frac, w0_frac]);
    let f1001 = gradient(seed, [x1_whole, y1_whole, z0_whole, w0_whole], [x1_frac, y1_frac, z0_frac, w0_frac]);
    let f0010 = gradient(seed, [x0_whole, y0_whole, z1_whole, w0_whole], [x0_frac, y0_frac, z1_frac, w0_frac]);
    let f1010 = gradient(seed, [x1_whole, y0_whole, z1_whole, w0_whole], [x1_frac, y0_frac, z1_frac, w0_frac]);
    let f0011 = gradient(seed, [x0_whole, y1_whole, z1_whole, w0_whole], [x0_frac, y1_frac, z1_frac, w0_frac]);
    let f1011 = gradient(seed, [x1_whole, y1_whole, z1_whole, w0_whole], [x1_frac, y1_frac, z1_frac, w0_frac]);
    let f0100 = gradient(seed, [x0_whole, y0_whole, z0_whole, w1_whole], [x0_frac, y0_frac, z0_frac, w1_frac]);
    let f1100 = gradient(seed, [x1_whole, y0_whole, z0_whole, w1_whole], [x1_frac, y0_frac, z0_frac, w1_frac]);
    let f0101 = gradient(seed, [x0_whole, y1_whole, z0_whole, w1_whole], [x0_frac, y1_frac, z0_frac, w1_frac]);
    let f1101 = gradient(seed, [x1_whole, y1_whole, z0_whole, w1_whole], [x1_frac, y1_frac, z0_frac, w1_frac]);
    let f0110 = gradient(seed, [x0_whole, y0_whole, z1_whole, w1_whole], [x0_frac, y0_frac, z1_frac, w1_frac]);
    let f1110 = gradient(seed, [x1_whole, y0_whole, z1_whole, w1_whole], [x1_frac, y0_frac, z1_frac, w1_frac]);
    let f0111 = gradient(seed, [x0_whole, y1_whole, z1_whole, w1_whole], [x0_frac, y1_frac, z1_frac, w1_frac]);
    let f1111 = gradient(seed, [x1_whole, y1_whole, z1_whole, w1_whole], [x1_frac, y1_frac, z1_frac, w1_frac]);

    math::quadlerp(x_curve, y_curve, z_curve, w_curve, f0000, f1000, f0001, f1001, f0010, f1010, f0011, f1011, f0100, f1100, f0101, f1101, f0110, f1110, f0111, f1111)
}
<|endoftext|>


<commit_before>use crate::grammar::model::Fragment;
use nom::branch::alt;
use nom::bytes::complete::{tag, take_until};
use nom::character::complete::{char, multispace0, not_line_ending};
use nom::combinator::value;
use nom::multi::{count, many0};
use nom::sequence::{delimited, preceded, terminated};
use nom::IResult;

/// Parses a Wright single line comment.
/// Wright single line comments start with `//` and will parse until a newline
/// character is reached. The returned value is the content of the comment.
pub fn line_comment(input: Fragment) -> IResult<Fragment, Fragment> {
    preceded(count(char('/'), 2), not_line_ending)(input)
}

/// Parses a Wright multiline comment
pub fn multiline_comment(input: Fragment) -> IResult<Fragment, Fragment> {
    delimited(tag("/*"), take_until("*/"), tag("*/"))(input)
}

/// Parses a sequence of adjacent whitespace and comments,
/// and discards the result.
pub fn token_delimiter(input: Fragment) -> IResult<Fragment, ()> {
    preceded(
        multispace0,
        value(
            (),
            many0(terminated(
                alt((line_comment, multiline_comment)),
                multispace0,
            )),
        ),
    )(input)
}
<commit_msg>docs<commit_after>use crate::grammar::model::Fragment;
use nom::branch::alt;
use nom::bytes::complete::{tag, take_until};
use nom::character::complete::{char, multispace0, not_line_ending};
use nom::combinator::value;
use nom::multi::{count, many0};
use nom::sequence::{delimited, preceded, terminated};
use nom::IResult;

/// Parses a Wright single line comment.
/// Wright single line comments start with `//` and will parse until a newline
/// character is reached. The returned value is the content of the comment.
pub fn line_comment(input: Fragment) -> IResult<Fragment, Fragment> {
    preceded(count(char('/'), 2), not_line_ending)(input)
}

/// Parses a Wright multiline comment. Wright multiline comments are delimited
/// by `/*` and `*/`. They are not recursive. Wright has no concept of nested
/// comments, or any of the content within a comment for that matter.
pub fn multiline_comment(input: Fragment) -> IResult<Fragment, Fragment> {
    delimited(tag("/*"), take_until("*/"), tag("*/"))(input)
}

/// Parses a sequence of adjacent whitespace and comments,
/// and discards the result.
pub fn token_delimiter(input: Fragment) -> IResult<Fragment, ()> {
    preceded(
        multispace0,
        value(
            (),
            many0(terminated(
                alt((line_comment, multiline_comment)),
                multispace0,
            )),
        ),
    )(input)
}
<|endoftext|>


<commit_before>// Copyright 2015 Michael 'ExpHP' Lamparski
//
// Licensed under the terms of the MIT License, available at:
//  http://opensource.org/licenses/MIT
// and also included in the file COPYING at the root of this distribution.
// This file may not be copied, modified, or distributed except according
// to those terms.

extern crate num;

use std::num::{ToPrimitive,FromPrimitive}; // and regret it
use std::iter::range_step;
use std::ops::Shr;
use std::fmt::Debug;

use num::{Zero,One,Integer};
use num::BigUint;

use util::literal;

pub trait PrimeTester<T>
 where T: Eq + Clone + Zero + One,
{
	fn is_prime(self: &Self, x: &T) -> bool;

	fn is_composite(self: &Self, x: &T) -> bool
	{
		if x == &Zero::zero() || x == &One::one() {
			false
		} else {
			!self.is_prime(x)
		}
	}
}

#[derive(Clone,Show)]
pub struct PrimeSieve
{
	sieve: Vec<bool>,
}

impl PrimeSieve
{
	/// Computes and constructs a Sieve of Eratosthenes capable of testing numbers
	///  below `limit` for primality.
	pub fn new(limit: usize) -> Self
	{
		PrimeSieve {
			sieve: compute_sieve_of_eratosthenes(limit),
		}
	}
}

impl<T> PrimeTester<T>
for PrimeSieve
 where T: Eq + Clone + ToPrimitive + FromPrimitive + Integer,
{
	//! All of the work involved in identifying prime numbers with a PrimeSieve
	//!  is done during the sieve's construction, so a PrimeSieve can test primality
	//!  and compositeness in nominal time.
	//!
	//! # Example
	//!
	//! ```
	//! use factor::{PrimeTester,PrimeSieve};
	//!
	//! let tester: Box<PrimeTester<i32>> = Box::new(PrimeSieve::new(42));
	//!
	//! assert!(!tester.is_prime(&0)  && !tester.is_composite(&0));
	//! assert!(!tester.is_prime(&1)  && !tester.is_composite(&1));
	//! assert!(tester.is_prime(&13)  && !tester.is_composite(&13));
	//! assert!(!tester.is_prime(&27) && tester.is_composite(&27));
	//! ```

	/// Tests a number for primality by indexing the underlying vector.
	///
	/// # Panics
	///
	/// Panics if ToPrimitive.to_uint() fails (for whatever reason), or if the index
	///  lies outside the array.
	// TODO: test panics
	#[inline]
	fn is_prime(self: &Self, x: &T) -> bool
	{
		self.sieve[x.to_uint().unwrap()]
	}
}

fn compute_sieve_of_eratosthenes(limit: usize) -> Vec<bool>
{
	let mut sieve: Vec<bool> = Vec::new();

	sieve.resize(limit, true); // not sure if idiomatic way to initialize?
	sieve[0] = false;
	sieve[1] = false;

	for p in (2..limit) {
		if sieve[p] {
			for multiple in range_step(p*p, limit, p) {
//			for multiple in (p*p..limit).step(p) {  // future form of above?
				sieve[multiple] = false;
			};
		};
	};
	sieve
}

pub struct MillerRabinTester<T>;

// TODO: implement non-deterministic miller-rabin
// TODO: implement different choices of witnesses for deterministic miller-rabin (and
//         have them validate their input against the max number for which they work)
impl<T> MillerRabinTester<T>
 where T: Eq + Clone + ToPrimitive + FromPrimitive + Integer,
{
	/// Produces some set of numbers in the half-open interval `[0,x)` to use
	///  as potential witnesses for the Miller Rabin Test.
	// TODO: a term like "witness" prolly isn't fit for public API without definition
	pub fn collect_witnesses(self: &Self, x: T) -> Vec<T> {
		// There's a couple of options here.
		// Several witnesses can be chosen at random for a strong heuristic test,
		//  or one can use a small set of witnesses that has been demonstrated
		//  to correctly identify all numbers up to some limit.

		// This set of witnesses is known to work for all n < 3,474,749,660,383
		vec![literal(2), literal(3), literal(5), literal(7), literal(11), literal(13)]
			.into_iter().filter(|v| v < &x).collect()
	}
}

impl<T> PrimeTester<T>
for MillerRabinTester<T>
 where T: Eq + Clone + ToPrimitive + FromPrimitive + Integer + Shr<usize, Output=T> + Debug,
{
	fn is_prime(self: &Self, x: &T) -> bool
	{
		if *x < literal(2) { return false; }
		if *x <= literal(3) { return *x >= literal(2); }

		let neg_one: T = x.clone() - literal(1);

		let (k,d) = decompose_pow2_odd(neg_one.clone());

		'witness: for witness in self.collect_witnesses(x.clone()).into_iter() {
			// TODO: This must be revised when witness production method can be selected

			let mut cur = mod_pow(witness.clone(), d.clone(), x.clone());

			// test witness ^ d
			if cur == One::one() || cur == neg_one {
				continue 'witness;  // not a witness
			}

			// test witness ^ 2d, witness ^ 4d, ..., witness ^ (2^(k-1) d)
			let mut counter: T = k.clone();
			while counter > literal(0) {  // turn this into a for loop, I dare you  (please?)
				counter = counter - literal(1);

				cur = cur.clone() * cur;
				cur = cur % x.clone();

				if cur == One::one() {
					return false;   // Composite
				}
				if cur == neg_one {
					continue 'witness;  // not a witness
				}
			}

			// We have a witness! (reached if no continues are encountered)
			return false;   // Composite
		}

		// We have no witnesses to the compositeness of x
		return true;   // Probable prime
	}
}

// Decomposes a number `x` into the form `2.pow(k) * d` where `d` is odd,
//  returning `(k,d)`.
fn decompose_pow2_odd<T>(x: T) -> (T, T)
 where T: Eq + Clone + ToPrimitive + FromPrimitive + Integer + Shr<usize, Output=T>,
{
	let mut remaining = x;
	let mut pow2: T = Zero::zero();
	while remaining.is_even() {
		pow2 = pow2 + literal(1);
		remaining = remaining >> literal(1);
	}
	return (pow2, remaining);
}

fn mod_pow<T,P>(x: T, power: P, modulus: T) -> T
 where T: Eq + Clone + ToPrimitive + FromPrimitive + Integer,
       P: Eq + Clone + ToPrimitive + FromPrimitive + Integer + Shr<usize, Output=P>,
{
	let mut prod:T = One::one();
	let mut remaining = power;
	let mut cur = x;
	while remaining > Zero::zero() {
		if remaining.clone() % literal(2) == literal(1) {
			prod = prod * cur.clone();
			prod = prod % modulus.clone();
		}
		remaining = remaining >> 1;
		cur = cur.clone() * cur;
		cur = cur % modulus.clone();
	}
	prod
}

#[test]
fn test_mod_pow()
{
	assert_eq!(mod_pow(234u64, 0, 1259), 1);
	assert_eq!(mod_pow(234u64, 1, 1259), 234);
	assert_eq!(mod_pow(234u64, 2412, 1259), 1091);
}

#[test]
fn test_miller_vs_sieve()
{
	// Test against prime sieve
	let limit = 20000us;
	let expected = PrimeSieve::new(limit).sieve;

	for k in (0us..limit) {
		if MillerRabinTester.is_prime(&k) != expected[k] {
			panic!("MillerRabinTester returned '{:?}' for {:?}", !expected[k], k);
		}
	}
}

#[test]
fn test_miller_mersenne()
{
	// Miller-Rabin should ALWAYS identify a prime as such, no matter how large.
	// (don't go too large, though, or the test will take a while :P)
	for p in vec![19us, 31, 89, 107].into_iter() { // known p-values for some mersenne primes
		let one: BigUint = literal(1);
		let two: BigUint = literal(2);
		let mersenne: BigUint = num::pow(two,p) - one;
		assert!(MillerRabinTester.is_prime(&mersenne));
	}
}
<commit_msg>Some minor benchmarking<commit_after>// Copyright 2015 Michael 'ExpHP' Lamparski
//
// Licensed under the terms of the MIT License, available at:
//  http://opensource.org/licenses/MIT
// and also included in the file COPYING at the root of this distribution.
// This file may not be copied, modified, or distributed except according
// to those terms.

extern crate num;
extern crate test;

use std::num::{ToPrimitive,FromPrimitive}; // and regret it
use std::iter::range_step;
use std::ops::Shr;
use std::fmt::Debug;

use num::{Zero,One,Integer};
use num::BigUint;
use test::Bencher;

use util::literal;

pub trait PrimeTester<T>
 where T: Eq + Clone + Zero + One,
{
	fn is_prime(self: &Self, x: &T) -> bool;

	fn is_composite(self: &Self, x: &T) -> bool
	{
		if x == &Zero::zero() || x == &One::one() {
			false
		} else {
			!self.is_prime(x)
		}
	}
}

#[derive(Clone,Show)]
pub struct PrimeSieve
{
	sieve: Vec<bool>,
}

impl PrimeSieve
{
	/// Computes and constructs a Sieve of Eratosthenes capable of testing numbers
	///  below `limit` for primality.
	pub fn new(limit: usize) -> Self
	{
		PrimeSieve {
			sieve: compute_sieve_of_eratosthenes(limit),
		}
	}
}

impl<T> PrimeTester<T>
for PrimeSieve
 where T: Eq + Clone + ToPrimitive + FromPrimitive + Integer,
{
	//! All of the work involved in identifying prime numbers with a PrimeSieve
	//!  is done during the sieve's construction, so a PrimeSieve can test primality
	//!  and compositeness in nominal time.
	//!
	//! # Example
	//!
	//! ```
	//! use factor::{PrimeTester,PrimeSieve};
	//!
	//! let tester: Box<PrimeTester<i32>> = Box::new(PrimeSieve::new(42));
	//!
	//! assert!(!tester.is_prime(&0)  && !tester.is_composite(&0));
	//! assert!(!tester.is_prime(&1)  && !tester.is_composite(&1));
	//! assert!(tester.is_prime(&13)  && !tester.is_composite(&13));
	//! assert!(!tester.is_prime(&27) && tester.is_composite(&27));
	//! ```

	/// Tests a number for primality by indexing the underlying vector.
	///
	/// # Panics
	///
	/// Panics if ToPrimitive.to_uint() fails (for whatever reason), or if the index
	///  lies outside the array.
	// TODO: test panics
	#[inline]
	fn is_prime(self: &Self, x: &T) -> bool
	{
		self.sieve[x.to_uint().unwrap()]
	}
}

fn compute_sieve_of_eratosthenes(limit: usize) -> Vec<bool>
{
	let mut sieve: Vec<bool> = Vec::new();

	sieve.resize(limit, true); // not sure if idiomatic way to initialize?
	sieve[0] = false;
	sieve[1] = false;

	for p in (2..limit) {
		if sieve[p] {
			for multiple in range_step(p*p, limit, p) {
//			for multiple in (p*p..limit).step(p) {  // future form of above?
				sieve[multiple] = false;
			};
		};
	};
	sieve
}

pub struct MillerRabinTester<T>;

// TODO: implement non-deterministic miller-rabin
// TODO: implement different choices of witnesses for deterministic miller-rabin (and
//         have them validate their input against the max number for which they work)
impl<T> MillerRabinTester<T>
 where T: Eq + Clone + ToPrimitive + FromPrimitive + Integer,
{
	/// Produces some set of numbers in the half-open interval `[0,x)` to use
	///  as potential witnesses for the Miller Rabin Test.
	// TODO: a term like "witness" prolly isn't fit for public API without definition
	pub fn collect_witnesses(self: &Self, x: T) -> Vec<T> {
		// There's a couple of options here.
		// Several witnesses can be chosen at random for a strong heuristic test,
		//  or one can use a small set of witnesses that has been demonstrated
		//  to correctly identify all numbers up to some limit.

		// This set of witnesses is known to work for all n < 3,474,749,660,383

		let v = vec![literal(2), literal(3), literal(5), literal(7), literal(11), literal(13)];

		if x > literal(13) {
			v
		} else {
			v.into_iter().filter(|v| v < &x).collect()
		}
	}
}

impl<T> PrimeTester<T>
for MillerRabinTester<T>
 where T: Eq + Clone + ToPrimitive + FromPrimitive + Integer + Shr<usize, Output=T> + Debug,
{
	fn is_prime(self: &Self, x: &T) -> bool
	{
		if *x < literal(2) { return false; }
		if *x <= literal(3) { return *x >= literal(2); }

		let neg_one: T = x.clone() - literal(1);

		let (k,d) = decompose_pow2_odd(neg_one.clone());

		'witness: for witness in self.collect_witnesses(x.clone()).into_iter() {
			// TODO: This must be revised when witness production method can be selected

			let mut cur = mod_pow(witness.clone(), d.clone(), x.clone());

			// test witness ^ d
			if cur == One::one() || cur == neg_one {
				continue 'witness;  // not a witness
			}

			// test witness ^ 2d, witness ^ 4d, ..., witness ^ (2^(k-1) d)
			let mut counter: T = k.clone();
			while counter > literal(0) {  // turn this into a for loop, I dare you  (please?)
				counter = counter - literal(1);

				cur = cur.clone() * cur;
				cur = cur % x.clone();

				if cur == One::one() {
					return false;   // Composite
				}
				if cur == neg_one {
					continue 'witness;  // not a witness
				}
			}

			// We have a witness! (reached if no continues are encountered)
			return false;   // Composite
		}

		// We have no witnesses to the compositeness of x
		return true;   // Probable prime
	}
}

// Decomposes a number `x` into the form `2.pow(k) * d` where `d` is odd,
//  returning `(k,d)`.
fn decompose_pow2_odd<T>(x: T) -> (T, T)
 where T: Eq + Clone + ToPrimitive + FromPrimitive + Integer + Shr<usize, Output=T>,
{
	let mut remaining = x;
	let mut pow2: T = Zero::zero();
	while remaining.is_even() {
		pow2 = pow2 + literal(1);
		remaining = remaining >> literal(1);
	}
	return (pow2, remaining);
}

fn mod_pow<T,P>(x: T, power: P, modulus: T) -> T
 where T: Eq + Clone + ToPrimitive + FromPrimitive + Integer,
       P: Eq + Clone + ToPrimitive + FromPrimitive + Integer + Shr<usize, Output=P>,
{
	let mut prod:T = One::one();
	let mut remaining = power;
	let mut cur = x;
	while remaining > Zero::zero() {
		if remaining.is_odd() {
			prod = prod * cur.clone();
			prod = prod % modulus.clone();
		}
		remaining = remaining >> 1;
		cur = cur.clone() * cur;
		cur = cur % modulus.clone();
	}
	prod
}

#[test]
fn test_mod_pow()
{
	assert_eq!(mod_pow(234u64, 0, 1259), 1);
	assert_eq!(mod_pow(234u64, 1, 1259), 234);
	assert_eq!(mod_pow(234u64, 2412, 1259), 1091);
}

#[test]
fn test_miller_vs_sieve()
{
	// Test against prime sieve
	let limit = 20000us;
	let expected = PrimeSieve::new(limit).sieve;

	for k in (0us..limit) {
		if MillerRabinTester.is_prime(&k) != expected[k] {
			panic!("MillerRabinTester returned '{:?}' for {:?}", !expected[k], k);
		}
	}
}

#[test]
fn test_miller_mersenne()
{
	// Miller-Rabin should ALWAYS identify a prime as such, no matter how large.
	// (don't go too large, though, or the test will take a while :P)
	for p in vec![19us, 31, 89, 107].into_iter() { // known p-values for some mersenne primes
		let one: BigUint = literal(1);
		let two: BigUint = literal(2);
		let mersenne: BigUint = num::pow(two,p) - one;
		assert!(MillerRabinTester.is_prime(&mersenne));
	}
}

#[bench]
fn bench_mersenne(b: &mut Bencher)
{
	let one: BigUint = literal(1);
	let two: BigUint = literal(2);
	let mersenne: BigUint = num::pow(two,107) - one;

	b.iter(|| {
		MillerRabinTester.is_prime(&mersenne)
	})
}

<|endoftext|>


<commit_before>// Copyright (c) 2013-2016 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use capnp::{any_pointer};
use capnp::Error;
use capnp::capability::Promise;
use capnp::private::capability::{ClientHook, ParamsHook, PipelineHook, PipelineOp,
                                 ResultsHook, ResultsDoneHook};

use futures::Future;

use std::cell::RefCell;
use std::rc::{Rc, Weak};

use {broken, local, Attach, ForkedPromise};
use sender_queue::SenderQueue;

pub struct PipelineInner {
    // Once the promise resolves, this will become non-null and point to the underlying object.
    redirect: Option<Box<PipelineHook>>,

    // Represents the operation which will set `redirect` when possible.
    self_resolution_op: ForkedPromise<Promise<(), Error>>,

    clients_to_resolve: SenderQueue<(Weak<RefCell<ClientInner>>, Vec<PipelineOp>), ()>,
}

impl PipelineInner {
    fn resolve(this: &Rc<RefCell<PipelineInner>>, result: Result<Box<PipelineHook>, Error>) {
        let pipeline = match result {
            Ok(pipeline_hook) => pipeline_hook,
            Err(e) => Box::new(broken::Pipeline::new(e)),
        };

        this.borrow_mut().redirect = Some(pipeline.add_ref());

        for ((weak_client, ops), waiter) in this.borrow_mut().clients_to_resolve.drain() {
            if let Some(client) = weak_client.upgrade() {
                let clienthook = pipeline.get_pipelined_cap_move(ops);
                ClientInner::resolve(&client, Ok(clienthook));
            }
            waiter.complete(());
        }
    }
}

pub struct Pipeline {
    inner: Rc<RefCell<PipelineInner>>,
}

impl Pipeline {
    pub fn new(promise_param: Promise<Box<PipelineHook>, Error>) -> Pipeline {
        let inner = Rc::new(RefCell::new(PipelineInner {
            redirect: None,
            self_resolution_op: ForkedPromise::new(Promise::ok(())),
            clients_to_resolve: SenderQueue::new(),
        }));

        let this = Rc::downgrade(&inner);
        let self_res = ForkedPromise::new(Promise::from_future(promise_param.then(move |result| {
            let this = match this.upgrade() {
                Some(v) => v,
                None => return Err(Error::failed("dangling self reference in queued::Pipeline".into())),
            };
            PipelineInner::resolve(&this, result);
            Ok(())
        })));
        inner.borrow_mut().self_resolution_op = self_res;
        Pipeline { inner: inner }
    }
}

impl Clone for Pipeline {
    fn clone(&self) -> Pipeline {
        Pipeline { inner: self.inner.clone() }
    }
}

impl PipelineHook for Pipeline {
    fn add_ref(&self) -> Box<PipelineHook> {
        Box::new(self.clone())
    }
    fn get_pipelined_cap(&self, ops: &[PipelineOp]) -> Box<ClientHook> {
        self.get_pipelined_cap_move(ops.into())
    }

    fn get_pipelined_cap_move(&self, ops: Vec<PipelineOp>) -> Box<ClientHook> {
        match &self.inner.borrow().redirect {
            &Some(ref p) => {
                return p.get_pipelined_cap_move(ops)
            }
            &None => (),
        }

        let queued_client = Client::new(Some(self.inner.clone()));
        let weak_queued = Rc::downgrade(&queued_client.inner);
        self.inner.borrow_mut().clients_to_resolve.push_detach((weak_queued, ops));

        Box::new(queued_client)
    }
}

pub struct ClientInner {
    // Once the promise resolves, this will become non-null and point to the underlying object.
    redirect: Option<Box<ClientHook>>,

    pipeline_inner: Option<Rc<RefCell<PipelineInner>>>,

    resolved: bool,

    // When this promise resolves, each queued call will be forwarded to the real client.  This needs
    // to occur *before* any 'whenMoreResolved()' promises resolve, because we want to make sure
    // previously-queued calls are delivered before any new calls made in response to the resolution.
    call_forwarding_queue: SenderQueue<(u64, u16, Box<ParamsHook>, Box<ResultsHook>,
                                        Promise<Box<ResultsDoneHook>, Error>),
                                       (Promise<(), Error>, Box<PipelineHook>)>,

    // whenMoreResolved() returns forks of this promise.  These must resolve *after* queued calls
    // have been initiated (so that any calls made in the whenMoreResolved() handler are correctly
    // delivered after calls made earlier), but *before* any queued calls return (because it might
    // confuse the application if a queued call returns before the capability on which it was made
    // resolves).  Luckily, we know that queued calls will involve, at the very least, an
    // eventLoop.evalLater.
    client_resolution_queue: SenderQueue<(), Box<ClientHook>>,
}

impl ClientInner {
    pub fn resolve(state: &Rc<RefCell<ClientInner>>, result: Result<Box<ClientHook>, Error>) {
        assert!(!state.borrow().resolved);
        let client = match result {
            Ok(clienthook) => clienthook,
            Err(e) => broken::new_cap(e),
        };
        state.borrow_mut().redirect = Some(client.add_ref());
        for (args, waiter) in state.borrow_mut().call_forwarding_queue.drain() {
            let (interface_id, method_id, params, results, results_done) = args;
            let result_pair = client.call(interface_id, method_id, params, results, results_done);
            waiter.complete(result_pair);
        }

        for ((), waiter) in state.borrow_mut().client_resolution_queue.drain() {
            waiter.complete(client.add_ref());
        }
        state.borrow_mut().pipeline_inner.take();
        state.borrow_mut().resolved = true;
    }
}

pub struct Client {
    pub inner: Rc<RefCell<ClientInner>>,
}

impl Client {
    pub fn new(pipeline_inner: Option<Rc<RefCell<PipelineInner>>>) -> Client
    {
        let inner = Rc::new(RefCell::new(ClientInner {
            pipeline_inner: pipeline_inner,
            redirect: None,
            resolved: false,
            call_forwarding_queue: SenderQueue::new(),
            client_resolution_queue: SenderQueue::new(),
        }));
        Client {
            inner: inner
        }
    }
}

impl ClientHook for Client {
    fn add_ref(&self) -> Box<ClientHook> {
        Box::new(Client {inner: self.inner.clone()})
    }
    fn new_call(&self, interface_id: u64, method_id: u16,
                size_hint: Option<::capnp::MessageSize>)
                -> ::capnp::capability::Request<any_pointer::Owned, any_pointer::Owned>
    {
        ::capnp::capability::Request::new(
            Box::new(local::Request::new(interface_id, method_id, size_hint, self.add_ref())))
    }

    fn call(&self, interface_id: u64, method_id: u16, params: Box<ParamsHook>, results: Box<ResultsHook>,
            results_done: Promise<Box<ResultsDoneHook>, Error>)
        -> (Promise<(), Error>, Box<PipelineHook>)
    {
        if let Some(ref client) = self.inner.borrow().redirect {
           return client.call(interface_id, method_id, params, results, results_done)
        }

        let inner_clone = self.inner.clone();

        let mut promise_for_pair = Promise::from_future(self.inner.borrow_mut().call_forwarding_queue.push(
            (interface_id, method_id, params, results, results_done)).attach(inner_clone));

        if let Some(ref pipeline_inner) = self.inner.borrow().pipeline_inner {
            promise_for_pair = Promise::from_future(
                pipeline_inner.borrow().self_resolution_op.clone().join(promise_for_pair).map(|v| v.1));
        }

        let (promise_promise, pipeline_promise) = ::split::split(promise_for_pair);
        let pipeline = Pipeline::new(Promise::from_future(pipeline_promise));
        (Promise::from_future(promise_promise.flatten()), Box::new(pipeline))
    }

    fn get_ptr(&self) -> usize {
        (&*self.inner.borrow()) as * const _ as usize
    }

    fn get_brand(&self) -> usize {
        0
    }

    fn get_resolved(&self) -> Option<Box<ClientHook>> {
        match self.inner.borrow().redirect {
            Some(ref inner) => Some(inner.clone()),
            None => None,
        }
    }

    fn when_more_resolved(&self) -> Option<Promise<Box<ClientHook>, Error>> {
        if let Some(ref client) = self.inner.borrow().redirect {
            return Some(Promise::ok(client.add_ref()));
        }

        Some(self.inner.borrow_mut().client_resolution_queue.push(()))
    }
}
<commit_msg>drive future in when_more_resolved()<commit_after>// Copyright (c) 2013-2016 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

use capnp::{any_pointer};
use capnp::Error;
use capnp::capability::Promise;
use capnp::private::capability::{ClientHook, ParamsHook, PipelineHook, PipelineOp,
                                 ResultsHook, ResultsDoneHook};

use futures::Future;

use std::cell::RefCell;
use std::rc::{Rc, Weak};

use {broken, local, Attach, ForkedPromise};
use sender_queue::SenderQueue;

pub struct PipelineInner {
    // Once the promise resolves, this will become non-null and point to the underlying object.
    redirect: Option<Box<PipelineHook>>,

    // Represents the operation which will set `redirect` when possible.
    self_resolution_op: ForkedPromise<Promise<(), Error>>,

    clients_to_resolve: SenderQueue<(Weak<RefCell<ClientInner>>, Vec<PipelineOp>), ()>,
}

impl PipelineInner {
    fn resolve(this: &Rc<RefCell<PipelineInner>>, result: Result<Box<PipelineHook>, Error>) {
        let pipeline = match result {
            Ok(pipeline_hook) => pipeline_hook,
            Err(e) => Box::new(broken::Pipeline::new(e)),
        };

        this.borrow_mut().redirect = Some(pipeline.add_ref());

        for ((weak_client, ops), waiter) in this.borrow_mut().clients_to_resolve.drain() {
            if let Some(client) = weak_client.upgrade() {
                let clienthook = pipeline.get_pipelined_cap_move(ops);
                ClientInner::resolve(&client, Ok(clienthook));
            }
            waiter.complete(());
        }
    }
}

pub struct Pipeline {
    inner: Rc<RefCell<PipelineInner>>,
}

impl Pipeline {
    pub fn new(promise_param: Promise<Box<PipelineHook>, Error>) -> Pipeline {
        let inner = Rc::new(RefCell::new(PipelineInner {
            redirect: None,
            self_resolution_op: ForkedPromise::new(Promise::ok(())),
            clients_to_resolve: SenderQueue::new(),
        }));

        let this = Rc::downgrade(&inner);
        let self_res = ForkedPromise::new(Promise::from_future(promise_param.then(move |result| {
            let this = match this.upgrade() {
                Some(v) => v,
                None => return Err(Error::failed("dangling self reference in queued::Pipeline".into())),
            };
            PipelineInner::resolve(&this, result);
            Ok(())
        })));
        inner.borrow_mut().self_resolution_op = self_res;
        Pipeline { inner: inner }
    }
}

impl Clone for Pipeline {
    fn clone(&self) -> Pipeline {
        Pipeline { inner: self.inner.clone() }
    }
}

impl PipelineHook for Pipeline {
    fn add_ref(&self) -> Box<PipelineHook> {
        Box::new(self.clone())
    }
    fn get_pipelined_cap(&self, ops: &[PipelineOp]) -> Box<ClientHook> {
        self.get_pipelined_cap_move(ops.into())
    }

    fn get_pipelined_cap_move(&self, ops: Vec<PipelineOp>) -> Box<ClientHook> {
        match &self.inner.borrow().redirect {
            &Some(ref p) => {
                return p.get_pipelined_cap_move(ops)
            }
            &None => (),
        }

        let queued_client = Client::new(Some(self.inner.clone()));
        let weak_queued = Rc::downgrade(&queued_client.inner);
        self.inner.borrow_mut().clients_to_resolve.push_detach((weak_queued, ops));

        Box::new(queued_client)
    }
}

pub struct ClientInner {
    // Once the promise resolves, this will become non-null and point to the underlying object.
    redirect: Option<Box<ClientHook>>,

    pipeline_inner: Option<Rc<RefCell<PipelineInner>>>,

    resolved: bool,

    // When this promise resolves, each queued call will be forwarded to the real client.  This needs
    // to occur *before* any 'whenMoreResolved()' promises resolve, because we want to make sure
    // previously-queued calls are delivered before any new calls made in response to the resolution.
    call_forwarding_queue: SenderQueue<(u64, u16, Box<ParamsHook>, Box<ResultsHook>,
                                        Promise<Box<ResultsDoneHook>, Error>),
                                       (Promise<(), Error>, Box<PipelineHook>)>,

    // whenMoreResolved() returns forks of this promise.  These must resolve *after* queued calls
    // have been initiated (so that any calls made in the whenMoreResolved() handler are correctly
    // delivered after calls made earlier), but *before* any queued calls return (because it might
    // confuse the application if a queued call returns before the capability on which it was made
    // resolves).  Luckily, we know that queued calls will involve, at the very least, an
    // eventLoop.evalLater.
    client_resolution_queue: SenderQueue<(), Box<ClientHook>>,
}

impl ClientInner {
    pub fn resolve(state: &Rc<RefCell<ClientInner>>, result: Result<Box<ClientHook>, Error>) {
        assert!(!state.borrow().resolved);
        let client = match result {
            Ok(clienthook) => clienthook,
            Err(e) => broken::new_cap(e),
        };
        state.borrow_mut().redirect = Some(client.add_ref());
        for (args, waiter) in state.borrow_mut().call_forwarding_queue.drain() {
            let (interface_id, method_id, params, results, results_done) = args;
            let result_pair = client.call(interface_id, method_id, params, results, results_done);
            waiter.complete(result_pair);
        }

        for ((), waiter) in state.borrow_mut().client_resolution_queue.drain() {
            waiter.complete(client.add_ref());
        }
        state.borrow_mut().pipeline_inner.take();
        state.borrow_mut().resolved = true;
    }
}

pub struct Client {
    pub inner: Rc<RefCell<ClientInner>>,
}

impl Client {
    pub fn new(pipeline_inner: Option<Rc<RefCell<PipelineInner>>>) -> Client
    {
        let inner = Rc::new(RefCell::new(ClientInner {
            pipeline_inner: pipeline_inner,
            redirect: None,
            resolved: false,
            call_forwarding_queue: SenderQueue::new(),
            client_resolution_queue: SenderQueue::new(),
        }));
        Client {
            inner: inner
        }
    }
}

impl ClientHook for Client {
    fn add_ref(&self) -> Box<ClientHook> {
        Box::new(Client {inner: self.inner.clone()})
    }
    fn new_call(&self, interface_id: u64, method_id: u16,
                size_hint: Option<::capnp::MessageSize>)
                -> ::capnp::capability::Request<any_pointer::Owned, any_pointer::Owned>
    {
        ::capnp::capability::Request::new(
            Box::new(local::Request::new(interface_id, method_id, size_hint, self.add_ref())))
    }

    fn call(&self, interface_id: u64, method_id: u16, params: Box<ParamsHook>, results: Box<ResultsHook>,
            results_done: Promise<Box<ResultsDoneHook>, Error>)
        -> (Promise<(), Error>, Box<PipelineHook>)
    {
        if let Some(ref client) = self.inner.borrow().redirect {
           return client.call(interface_id, method_id, params, results, results_done)
        }

        let inner_clone = self.inner.clone();

        let mut promise_for_pair = Promise::from_future(self.inner.borrow_mut().call_forwarding_queue.push(
            (interface_id, method_id, params, results, results_done)).attach(inner_clone));

        if let Some(ref pipeline_inner) = self.inner.borrow().pipeline_inner {
            promise_for_pair = Promise::from_future(
                pipeline_inner.borrow().self_resolution_op.clone().join(promise_for_pair).map(|v| v.1));
        }

        let (promise_promise, pipeline_promise) = ::split::split(promise_for_pair);
        let pipeline = Pipeline::new(Promise::from_future(pipeline_promise));
        (Promise::from_future(promise_promise.flatten()), Box::new(pipeline))
    }

    fn get_ptr(&self) -> usize {
        (&*self.inner.borrow()) as * const _ as usize
    }

    fn get_brand(&self) -> usize {
        0
    }

    fn get_resolved(&self) -> Option<Box<ClientHook>> {
        match self.inner.borrow().redirect {
            Some(ref inner) => Some(inner.clone()),
            None => None,
        }
    }

    fn when_more_resolved(&self) -> Option<Promise<Box<ClientHook>, Error>> {
        if let Some(ref client) = self.inner.borrow().redirect {
            return Some(Promise::ok(client.add_ref()));
        }

        let maybe_resolution_op =
            match self.inner.borrow().pipeline_inner {
                Some(ref x) => Some(x.borrow().self_resolution_op.clone()),
                None => None,
            };

        match maybe_resolution_op {
            Some(res_op) => {
                Some(Promise::from_future(
                    res_op.join(self.inner.borrow_mut().client_resolution_queue.push(())).map(|v| v.1)))
            }
            None => {
                Some(self.inner.borrow_mut().client_resolution_queue.push(()))
            }
        }
    }
}
<|endoftext|>


<commit_before>#[cfg(any(feature = "std", feature = "collections"))]
use core::{fmt, str};

use core::marker::PhantomData;

#[cfg(feature = "collections")]
use collections::borrow::ToOwned;

#[cfg(feature = "std")]
use std::borrow::Cow;
#[cfg(all(feature = "collections", not(feature = "std")))]
use collections::borrow::Cow;

#[cfg(all(feature = "collections", not(feature = "std")))]
use collections::{String, Vec};

use de::{Deserialize, Deserializer, Error, Visitor};

#[cfg(any(feature = "std", feature = "collections"))]
use de::Unexpected;

#[cfg(any(feature = "std", feature = "collections"))]
pub use de::content::{Content, ContentRefDeserializer, ContentDeserializer, TaggedContentVisitor,
                      TagOrContentField, TagOrContentFieldVisitor, InternallyTaggedUnitVisitor,
                      UntaggedUnitVisitor};

/// If the missing field is of type `Option<T>` then treat is as `None`,
/// otherwise it is an error.
pub fn missing_field<'de, V, E>(field: &'static str) -> Result<V, E>
    where V: Deserialize<'de>,
          E: Error
{
    struct MissingFieldDeserializer<E>(&'static str, PhantomData<E>);

    impl<'de, E> Deserializer<'de> for MissingFieldDeserializer<E>
        where E: Error
    {
        type Error = E;

        fn deserialize<V>(self, _visitor: V) -> Result<V::Value, E>
            where V: Visitor<'de>
        {
            Err(Error::missing_field(self.0))
        }

        fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, E>
            where V: Visitor<'de>
        {
            visitor.visit_none()
        }

        forward_to_deserialize! {
            bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq
            seq_fixed_size bytes byte_buf map unit_struct newtype_struct
            tuple_struct struct struct_field tuple enum ignored_any
        }
    }

    let deserializer = MissingFieldDeserializer(field, PhantomData);
    Deserialize::deserialize(deserializer)
}

#[cfg(any(feature = "std", feature = "collections"))]
pub fn borrow_cow_str<'de, D>(deserializer: D) -> Result<Cow<'de, str>, D::Error>
    where D: Deserializer<'de>
{
    struct CowStrVisitor;

    impl<'a> Visitor<'a> for CowStrVisitor {
        type Value = Cow<'a, str>;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("a string")
        }

        fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
            where E: Error
        {
            Ok(Cow::Owned(v.to_owned()))
        }

        fn visit_borrowed_str<E>(self, v: &'a str) -> Result<Self::Value, E>
            where E: Error
        {
            Ok(Cow::Borrowed(v))
        }

        fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
            where E: Error
        {
            Ok(Cow::Owned(v))
        }

        fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
            where E: Error
        {
            match str::from_utf8(v) {
                Ok(s) => Ok(Cow::Owned(s.to_owned())),
                Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)),
            }
        }

        fn visit_borrowed_bytes<E>(self, v: &'a [u8]) -> Result<Self::Value, E>
            where E: Error
        {
            match str::from_utf8(v) {
                Ok(s) => Ok(Cow::Borrowed(s)),
                Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)),
            }
        }

        fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
            where E: Error
        {
            match String::from_utf8(v) {
                Ok(s) => Ok(Cow::Owned(s)),
                Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self)),
            }
        }
    }

    deserializer.deserialize_str(CowStrVisitor)
}

#[cfg(any(feature = "std", feature = "collections"))]
pub fn borrow_cow_bytes<'de, D>(deserializer: D) -> Result<Cow<'de, [u8]>, D::Error>
    where D: Deserializer<'de>
{
    struct CowBytesVisitor;

    impl<'a> Visitor<'a> for CowBytesVisitor {
        type Value = Cow<'a, [u8]>;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("a byte array")
        }

        fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
            where E: Error
        {
            Ok(Cow::Owned(v.as_bytes().to_vec()))
        }

        fn visit_borrowed_str<E>(self, v: &'a str) -> Result<Self::Value, E>
            where E: Error
        {
            Ok(Cow::Borrowed(v.as_bytes()))
        }

        fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
            where E: Error
        {
            Ok(Cow::Owned(v.into_bytes()))
        }

        fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
            where E: Error
        {
            Ok(Cow::Owned(v.to_vec()))
        }

        fn visit_borrowed_bytes<E>(self, v: &'a [u8]) -> Result<Self::Value, E>
            where E: Error
        {
            Ok(Cow::Borrowed(v))
        }

        fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
            where E: Error
        {
            Ok(Cow::Owned(v))
        }
    }

    deserializer.deserialize_str(CowBytesVisitor)
}
<commit_msg>Relax lifetime requirement of the borrow_cow functions<commit_after>#[cfg(any(feature = "std", feature = "collections"))]
use core::{fmt, str};

use core::marker::PhantomData;

#[cfg(feature = "collections")]
use collections::borrow::ToOwned;

#[cfg(feature = "std")]
use std::borrow::Cow;
#[cfg(all(feature = "collections", not(feature = "std")))]
use collections::borrow::Cow;

#[cfg(all(feature = "collections", not(feature = "std")))]
use collections::{String, Vec};

use de::{Deserialize, Deserializer, Error, Visitor};

#[cfg(any(feature = "std", feature = "collections"))]
use de::Unexpected;

#[cfg(any(feature = "std", feature = "collections"))]
pub use de::content::{Content, ContentRefDeserializer, ContentDeserializer, TaggedContentVisitor,
                      TagOrContentField, TagOrContentFieldVisitor, InternallyTaggedUnitVisitor,
                      UntaggedUnitVisitor};

/// If the missing field is of type `Option<T>` then treat is as `None`,
/// otherwise it is an error.
pub fn missing_field<'de, V, E>(field: &'static str) -> Result<V, E>
    where V: Deserialize<'de>,
          E: Error
{
    struct MissingFieldDeserializer<E>(&'static str, PhantomData<E>);

    impl<'de, E> Deserializer<'de> for MissingFieldDeserializer<E>
        where E: Error
    {
        type Error = E;

        fn deserialize<V>(self, _visitor: V) -> Result<V::Value, E>
            where V: Visitor<'de>
        {
            Err(Error::missing_field(self.0))
        }

        fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, E>
            where V: Visitor<'de>
        {
            visitor.visit_none()
        }

        forward_to_deserialize! {
            bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq
            seq_fixed_size bytes byte_buf map unit_struct newtype_struct
            tuple_struct struct struct_field tuple enum ignored_any
        }
    }

    let deserializer = MissingFieldDeserializer(field, PhantomData);
    Deserialize::deserialize(deserializer)
}

#[cfg(any(feature = "std", feature = "collections"))]
pub fn borrow_cow_str<'de: 'a, 'a, D>(deserializer: D) -> Result<Cow<'a, str>, D::Error>
    where D: Deserializer<'de>
{
    struct CowStrVisitor;

    impl<'a> Visitor<'a> for CowStrVisitor {
        type Value = Cow<'a, str>;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("a string")
        }

        fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
            where E: Error
        {
            Ok(Cow::Owned(v.to_owned()))
        }

        fn visit_borrowed_str<E>(self, v: &'a str) -> Result<Self::Value, E>
            where E: Error
        {
            Ok(Cow::Borrowed(v))
        }

        fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
            where E: Error
        {
            Ok(Cow::Owned(v))
        }

        fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
            where E: Error
        {
            match str::from_utf8(v) {
                Ok(s) => Ok(Cow::Owned(s.to_owned())),
                Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)),
            }
        }

        fn visit_borrowed_bytes<E>(self, v: &'a [u8]) -> Result<Self::Value, E>
            where E: Error
        {
            match str::from_utf8(v) {
                Ok(s) => Ok(Cow::Borrowed(s)),
                Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)),
            }
        }

        fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
            where E: Error
        {
            match String::from_utf8(v) {
                Ok(s) => Ok(Cow::Owned(s)),
                Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self)),
            }
        }
    }

    deserializer.deserialize_str(CowStrVisitor)
}

#[cfg(any(feature = "std", feature = "collections"))]
pub fn borrow_cow_bytes<'de: 'a, 'a, D>(deserializer: D) -> Result<Cow<'a, [u8]>, D::Error>
    where D: Deserializer<'de>
{
    struct CowBytesVisitor;

    impl<'a> Visitor<'a> for CowBytesVisitor {
        type Value = Cow<'a, [u8]>;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("a byte array")
        }

        fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
            where E: Error
        {
            Ok(Cow::Owned(v.as_bytes().to_vec()))
        }

        fn visit_borrowed_str<E>(self, v: &'a str) -> Result<Self::Value, E>
            where E: Error
        {
            Ok(Cow::Borrowed(v.as_bytes()))
        }

        fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
            where E: Error
        {
            Ok(Cow::Owned(v.into_bytes()))
        }

        fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
            where E: Error
        {
            Ok(Cow::Owned(v.to_vec()))
        }

        fn visit_borrowed_bytes<E>(self, v: &'a [u8]) -> Result<Self::Value, E>
            where E: Error
        {
            Ok(Cow::Borrowed(v))
        }

        fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
            where E: Error
        {
            Ok(Cow::Owned(v))
        }
    }

    deserializer.deserialize_str(CowBytesVisitor)
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#![feature(proc_macro)]

extern crate gtk;
#[macro_use]
extern crate relm;
extern crate relm_attributes;
#[macro_use]
extern crate relm_derive;

use gtk::{
    ButtonExt,
    Inhibit,
    OrientableExt,
    WidgetExt,
};
use gtk::Orientation::Vertical;
use relm::Widget;
use relm_attributes::widget;

use self::Msg::*;

// Define the structure of the model.
#[derive(Clone)]
pub struct Model {
    counter: i32,
}

// The messages that can be sent to the update function.
#[derive(Msg)]
pub enum Msg {
    Decrement,
    Increment,
    Quit,
}

#[widget]
impl Widget for Win {
    type Msg = Msg;

    // The initial model.
    fn model() -> Model {
        Model {
            counter: 0,
        }
    }

    // Update the model according to the message received.
    fn update(&mut self, event: Msg, model: &mut Model) {
        match event {
            Decrement => model.counter -= 1,
            Increment => model.counter += 1,
            Quit => gtk::main_quit(),
        }
    }

    view! {
        gtk::Window {
            gtk::Box {
                // Set the orientation property of the Box.
                orientation: Vertical,
                // Create a Button inside the Box.
                gtk::Button {
                    // Send the message Increment when the button is clicked.
                    clicked => Increment,
                    // TODO: check if using two events of the same name work.
                    label: "+",
                },
                gtk::Label {
                    // Bind the text property of the label to the counter attribute of the model.
                    text: &model.counter.to_string(),
                },
                gtk::Button {
                    clicked => Decrement,
                    label: "-",
                },
            },
            delete_event(_, _) => (Quit, Inhibit(false)),
        }
    }
}

fn main() {
    relm::run::<Win>().unwrap();
}
<commit_msg>Remove useless type in buttons attribute example<commit_after>/*
 * Copyright (c) 2017 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#![feature(proc_macro)]

extern crate gtk;
#[macro_use]
extern crate relm;
extern crate relm_attributes;
#[macro_use]
extern crate relm_derive;

use gtk::{
    ButtonExt,
    Inhibit,
    OrientableExt,
    WidgetExt,
};
use gtk::Orientation::Vertical;
use relm::Widget;
use relm_attributes::widget;

use self::Msg::*;

// Define the structure of the model.
#[derive(Clone)]
pub struct Model {
    counter: i32,
}

// The messages that can be sent to the update function.
#[derive(Msg)]
pub enum Msg {
    Decrement,
    Increment,
    Quit,
}

#[widget]
impl Widget for Win {
    // The initial model.
    fn model() -> Model {
        Model {
            counter: 0,
        }
    }

    // Update the model according to the message received.
    fn update(&mut self, event: Msg, model: &mut Model) {
        match event {
            Decrement => model.counter -= 1,
            Increment => model.counter += 1,
            Quit => gtk::main_quit(),
        }
    }

    view! {
        gtk::Window {
            gtk::Box {
                // Set the orientation property of the Box.
                orientation: Vertical,
                // Create a Button inside the Box.
                gtk::Button {
                    // Send the message Increment when the button is clicked.
                    clicked => Increment,
                    // TODO: check if using two events of the same name work.
                    label: "+",
                },
                gtk::Label {
                    // Bind the text property of the label to the counter attribute of the model.
                    text: &model.counter.to_string(),
                },
                gtk::Button {
                    clicked => Decrement,
                    label: "-",
                },
            },
            delete_event(_, _) => (Quit, Inhibit(false)),
        }
    }
}

fn main() {
    relm::run::<Win>().unwrap();
}
<|endoftext|>