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

/*!
 * Library to interface with chunks of memory allocated in C.
 *
 * It is often desirable to safely interface with memory allocated from C,
 * encapsulating the unsafety into allocation and destruction time.  Indeed,
 * allocating memory externally is currently the only way to give Rust shared
 * mut state with C programs that keep their own references; vectors are
 * unsuitable because they could be reallocated or moved at any time, and
 * importing C memory into a vector takes a one-time snapshot of the memory.
 *
 * This module simplifies the usage of such external blocks of memory.  Memory
 * is encapsulated into an opaque object after creation; the lifecycle of the
 * memory can be optionally managed by Rust, if an appropriate destructor
 * closure is provided.  Safety is ensured by bounds-checking accesses, which
 * are marshalled through get and set functions.
 *
 * There are three unsafe functions: the two introduction forms, and the
 * pointer elimination form.  The introduction forms are unsafe for the
 * obvious reason (they act on a pointer that cannot be checked inside the
 * method), but the elimination form is somewhat more subtle in its unsafety.
 * By using a pointer taken from a c_vec::t without keeping a reference to the
 * c_vec::t itself around, the CVec could be garbage collected, and the
 * memory within could be destroyed.  There are legitimate uses for the
 * pointer elimination form -- for instance, to pass memory back into C -- but
 * great care must be taken to ensure that a reference to the c_vec::t is
 * still held if needed.
 */

/**
 * The type representing a foreign chunk of memory
 *
 */
pub struct CVec<T> {
    priv base: *mut T,
    priv len: uint,
    priv rsrc: @DtorRes
}

struct DtorRes {
  dtor: Option<@fn()>,
}

#[unsafe_destructor]
impl Drop for DtorRes {
    fn finalize(&self) {
        match self.dtor {
            option::None => (),
            option::Some(f) => f()
        }
    }
}

fn DtorRes(dtor: Option<@fn()>) -> DtorRes {
    DtorRes {
        dtor: dtor
    }
}

/*
 Section: Introduction forms
 */

/**
 * Create a `CVec` from a foreign buffer with a given length.
 *
 * # Arguments
 *
 * * base - A foreign pointer to a buffer
 * * len - The number of elements in the buffer
 */
pub fn CVec<T>(base: *mut T, len: uint) -> CVec<T> {
    return CVec{
        base: base,
        len: len,
        rsrc: @DtorRes(option::None)
    };
}

/**
 * Create a `CVec` from a foreign buffer, with a given length,
 * and a function to run upon destruction.
 *
 * # Arguments
 *
 * * base - A foreign pointer to a buffer
 * * len - The number of elements in the buffer
 * * dtor - A function to run when the value is destructed, useful
 *          for freeing the buffer, etc.
 */
pub fn c_vec_with_dtor<T>(base: *mut T, len: uint, dtor: @fn())
  -> CVec<T> {
    return CVec{
        base: base,
        len: len,
        rsrc: @DtorRes(option::Some(dtor))
    };
}

/*
 Section: Operations
 */

/**
 * Retrieves an element at a given index
 *
 * Fails if `ofs` is greater or equal to the length of the vector
 */
pub fn get<T:Copy>(t: CVec<T>, ofs: uint) -> T {
    assert!(ofs < len(t));
    return unsafe { *ptr::mut_offset(t.base, ofs) };
}

/**
 * Sets the value of an element at a given index
 *
 * Fails if `ofs` is greater or equal to the length of the vector
 */
pub fn set<T:Copy>(t: CVec<T>, ofs: uint, v: T) {
    assert!(ofs < len(t));
    unsafe { *ptr::mut_offset(t.base, ofs) = v };
}

/*
 Section: Elimination forms
 */

/// Returns the length of the vector
pub fn len<T>(t: CVec<T>) -> uint { t.len }

/// Returns a pointer to the first element of the vector
pub fn ptr<T>(t: CVec<T>) -> *mut T { t.base }

#[cfg(test)]
mod tests {

    use c_vec::*;

    use core::libc::*;
    use core::libc;

    fn malloc(n: size_t) -> CVec<u8> {
        unsafe {
            let mem = libc::malloc(n);

            assert!(mem as int != 0);

            return c_vec_with_dtor(mem as *mut u8, n as uint,
                                   || unsafe { free(mem) });
        }
    }

    #[test]
    fn test_basic() {
        let cv = malloc(16u as size_t);

        set(cv, 3u, 8u8);
        set(cv, 4u, 9u8);
        assert!(get(cv, 3u) == 8u8);
        assert!(get(cv, 4u) == 9u8);
        assert!(len(cv) == 16u);
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    fn test_overrun_get() {
        let cv = malloc(16u as size_t);

        get(cv, 17u);
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    fn test_overrun_set() {
        let cv = malloc(16u as size_t);

        set(cv, 17u, 0u8);
    }

    #[test]
    fn test_and_I_mean_it() {
        let cv = malloc(16u as size_t);
        let p = ptr(cv);

        set(cv, 0u, 32u8);
        set(cv, 1u, 33u8);
        assert!(unsafe { *p } == 32u8);
        set(cv, 2u, 34u8); /* safety */
    }

}
<commit_msg>Mark c_vec functions as unsafe again<commit_after>// Copyright 2012 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.

/*!
 * Library to interface with chunks of memory allocated in C.
 *
 * It is often desirable to safely interface with memory allocated from C,
 * encapsulating the unsafety into allocation and destruction time.  Indeed,
 * allocating memory externally is currently the only way to give Rust shared
 * mut state with C programs that keep their own references; vectors are
 * unsuitable because they could be reallocated or moved at any time, and
 * importing C memory into a vector takes a one-time snapshot of the memory.
 *
 * This module simplifies the usage of such external blocks of memory.  Memory
 * is encapsulated into an opaque object after creation; the lifecycle of the
 * memory can be optionally managed by Rust, if an appropriate destructor
 * closure is provided.  Safety is ensured by bounds-checking accesses, which
 * are marshalled through get and set functions.
 *
 * There are three unsafe functions: the two introduction forms, and the
 * pointer elimination form.  The introduction forms are unsafe for the
 * obvious reason (they act on a pointer that cannot be checked inside the
 * method), but the elimination form is somewhat more subtle in its unsafety.
 * By using a pointer taken from a c_vec::t without keeping a reference to the
 * c_vec::t itself around, the CVec could be garbage collected, and the
 * memory within could be destroyed.  There are legitimate uses for the
 * pointer elimination form -- for instance, to pass memory back into C -- but
 * great care must be taken to ensure that a reference to the c_vec::t is
 * still held if needed.
 */

/**
 * The type representing a foreign chunk of memory
 *
 */
pub struct CVec<T> {
    priv base: *mut T,
    priv len: uint,
    priv rsrc: @DtorRes
}

struct DtorRes {
  dtor: Option<@fn()>,
}

#[unsafe_destructor]
impl Drop for DtorRes {
    fn finalize(&self) {
        match self.dtor {
            option::None => (),
            option::Some(f) => f()
        }
    }
}

fn DtorRes(dtor: Option<@fn()>) -> DtorRes {
    DtorRes {
        dtor: dtor
    }
}

/*
 Section: Introduction forms
 */

/**
 * Create a `CVec` from a foreign buffer with a given length.
 *
 * # Arguments
 *
 * * base - A foreign pointer to a buffer
 * * len - The number of elements in the buffer
 */
pub unsafe fn CVec<T>(base: *mut T, len: uint) -> CVec<T> {
    return CVec{
        base: base,
        len: len,
        rsrc: @DtorRes(option::None)
    };
}

/**
 * Create a `CVec` from a foreign buffer, with a given length,
 * and a function to run upon destruction.
 *
 * # Arguments
 *
 * * base - A foreign pointer to a buffer
 * * len - The number of elements in the buffer
 * * dtor - A function to run when the value is destructed, useful
 *          for freeing the buffer, etc.
 */
pub unsafe fn c_vec_with_dtor<T>(base: *mut T, len: uint, dtor: @fn())
  -> CVec<T> {
    return CVec{
        base: base,
        len: len,
        rsrc: @DtorRes(option::Some(dtor))
    };
}

/*
 Section: Operations
 */

/**
 * Retrieves an element at a given index
 *
 * Fails if `ofs` is greater or equal to the length of the vector
 */
pub fn get<T:Copy>(t: CVec<T>, ofs: uint) -> T {
    assert!(ofs < len(t));
    return unsafe { *ptr::mut_offset(t.base, ofs) };
}

/**
 * Sets the value of an element at a given index
 *
 * Fails if `ofs` is greater or equal to the length of the vector
 */
pub fn set<T:Copy>(t: CVec<T>, ofs: uint, v: T) {
    assert!(ofs < len(t));
    unsafe { *ptr::mut_offset(t.base, ofs) = v };
}

/*
 Section: Elimination forms
 */

/// Returns the length of the vector
pub fn len<T>(t: CVec<T>) -> uint { t.len }

/// Returns a pointer to the first element of the vector
pub unsafe fn ptr<T>(t: CVec<T>) -> *mut T { t.base }

#[cfg(test)]
mod tests {

    use c_vec::*;

    use core::libc::*;
    use core::libc;

    fn malloc(n: size_t) -> CVec<u8> {
        unsafe {
            let mem = libc::malloc(n);

            assert!(mem as int != 0);

            return c_vec_with_dtor(mem as *mut u8, n as uint,
                                   || unsafe { free(mem) });
        }
    }

    #[test]
    fn test_basic() {
        let cv = malloc(16u as size_t);

        set(cv, 3u, 8u8);
        set(cv, 4u, 9u8);
        assert!(get(cv, 3u) == 8u8);
        assert!(get(cv, 4u) == 9u8);
        assert!(len(cv) == 16u);
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    fn test_overrun_get() {
        let cv = malloc(16u as size_t);

        get(cv, 17u);
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(windows))]
    fn test_overrun_set() {
        let cv = malloc(16u as size_t);

        set(cv, 17u, 0u8);
    }

    #[test]
    fn test_and_I_mean_it() {
        let cv = malloc(16u as size_t);
        let p = unsafe { ptr(cv) };

        set(cv, 0u, 32u8);
        set(cv, 1u, 33u8);
        assert!(unsafe { *p } == 32u8);
        set(cv, 2u, 34u8); /* safety */
    }

}
<|endoftext|>


<commit_before>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*! The `Clone` trait for types that cannot be 'implicitly copied'

In Rust, some simple types are "implicitly copyable" and when you
assign them or pass them as arguments, the receiver will get a copy,
leaving the original value in place. These types do not require
allocation to copy and do not have finalizers (i.e. they do not
contain owned boxes or implement `Drop`), so the compiler considers
them cheap and safe to copy. For other types copies must be made
explicitly, by convention implementing the `Clone` trait and calling
the `clone` method.

*/

/// A common trait for cloning an object.
pub trait Clone {
    /// Returns a copy of the value. The contents of owned pointers
    /// are copied to maintain uniqueness, while the contents of
    /// managed pointers are not copied.
    fn clone(&self) -> Self;

    /// Perform copy-assignment from `source`.
    ///
    /// `a.clone_from(&b)` is equivalent to `a = b.clone()` in functionality,
    /// but can be overridden to reuse the resources of `a` to avoid unnecessary
    /// allocations.
    #[inline(always)]
    fn clone_from(&mut self, source: &Self) {
        *self = source.clone()
    }
}

impl<T: Clone> Clone for ~T {
    /// Return a copy of the owned box.
    #[inline]
    fn clone(&self) -> ~T { ~(**self).clone() }

    /// Perform copy-assignment from `source` by reusing the existing allocation.
    fn clone_from(&mut self, source: &~T) {
        **self = (**source).clone()
    }
}

impl<T> Clone for @T {
    /// Return a shallow copy of the managed box.
    #[inline]
    fn clone(&self) -> @T { *self }
}

impl<'a, T> Clone for &'a T {
    /// Return a shallow copy of the reference.
    #[inline]
    fn clone(&self) -> &'a T { *self }
}

impl<'a, T> Clone for &'a [T] {
    /// Return a shallow copy of the slice.
    #[inline]
    fn clone(&self) -> &'a [T] { *self }
}

impl<'a> Clone for &'a str {
    /// Return a shallow copy of the slice.
    #[inline]
    fn clone(&self) -> &'a str { *self }
}

macro_rules! clone_impl(
    ($t:ty) => {
        impl Clone for $t {
            /// Return a deep copy of the value.
            #[inline]
            fn clone(&self) -> $t { *self }
        }
    }
)

clone_impl!(int)
clone_impl!(i8)
clone_impl!(i16)
clone_impl!(i32)
clone_impl!(i64)

clone_impl!(uint)
clone_impl!(u8)
clone_impl!(u16)
clone_impl!(u32)
clone_impl!(u64)

clone_impl!(f32)
clone_impl!(f64)

clone_impl!(())
clone_impl!(bool)
clone_impl!(char)

macro_rules! extern_fn_clone(
    ($($A:ident),*) => (
        impl<$($A,)* ReturnType> Clone for extern "Rust" fn($($A),*) -> ReturnType {
            /// Return a copy of a function pointer
            #[inline]
            fn clone(&self) -> extern "Rust" fn($($A),*) -> ReturnType { *self }
        }
    )
)

extern_fn_clone!()
extern_fn_clone!(A)
extern_fn_clone!(A, B)
extern_fn_clone!(A, B, C)
extern_fn_clone!(A, B, C, D)
extern_fn_clone!(A, B, C, D, E)
extern_fn_clone!(A, B, C, D, E, F)
extern_fn_clone!(A, B, C, D, E, F, G)
extern_fn_clone!(A, B, C, D, E, F, G, H)

#[test]
fn test_owned_clone() {
    let a = ~5i;
    let b: ~int = a.clone();
    assert_eq!(a, b);
}

#[test]
fn test_managed_clone() {
    let a = @5i;
    let b: @int = a.clone();
    assert_eq!(a, b);
}

#[test]
fn test_borrowed_clone() {
    let x = 5i;
    let y: &int = &x;
    let z: &int = (&y).clone();
    assert_eq!(*z, 5);
}

#[test]
fn test_clone_from() {
    let a = ~5;
    let mut b = ~10;
    b.clone_from(&a);
    assert_eq!(*b, 5);
}

#[test]
fn test_extern_fn_clone() {
    trait Empty {}
    impl Empty for int {}

    fn test_fn_a() -> f64 { 1.0 }
    fn test_fn_b<T: Empty>(x: T) -> T { x }
    fn test_fn_c(_: int, _: f64, _: ~[int], _: int, _: int, _: int) {}

    let _ = test_fn_a.clone();
    let _ = test_fn_b::<int>.clone();
    let _ = test_fn_c.clone();
}
<commit_msg>Made the `clone_from` implementation for `~T` reuse the `T` itself if possible by also calling `clone_from` on it.<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*! The `Clone` trait for types that cannot be 'implicitly copied'

In Rust, some simple types are "implicitly copyable" and when you
assign them or pass them as arguments, the receiver will get a copy,
leaving the original value in place. These types do not require
allocation to copy and do not have finalizers (i.e. they do not
contain owned boxes or implement `Drop`), so the compiler considers
them cheap and safe to copy. For other types copies must be made
explicitly, by convention implementing the `Clone` trait and calling
the `clone` method.

*/

/// A common trait for cloning an object.
pub trait Clone {
    /// Returns a copy of the value. The contents of owned pointers
    /// are copied to maintain uniqueness, while the contents of
    /// managed pointers are not copied.
    fn clone(&self) -> Self;

    /// Perform copy-assignment from `source`.
    ///
    /// `a.clone_from(&b)` is equivalent to `a = b.clone()` in functionality,
    /// but can be overridden to reuse the resources of `a` to avoid unnecessary
    /// allocations.
    #[inline(always)]
    fn clone_from(&mut self, source: &Self) {
        *self = source.clone()
    }
}

impl<T: Clone> Clone for ~T {
    /// Return a copy of the owned box.
    #[inline]
    fn clone(&self) -> ~T { ~(**self).clone() }

    /// Perform copy-assignment from `source` by reusing the existing allocation.
    #[inline]
    fn clone_from(&mut self, source: &~T) {
        (**self).clone_from(&(**source));
    }
}

impl<T> Clone for @T {
    /// Return a shallow copy of the managed box.
    #[inline]
    fn clone(&self) -> @T { *self }
}

impl<'a, T> Clone for &'a T {
    /// Return a shallow copy of the reference.
    #[inline]
    fn clone(&self) -> &'a T { *self }
}

impl<'a, T> Clone for &'a [T] {
    /// Return a shallow copy of the slice.
    #[inline]
    fn clone(&self) -> &'a [T] { *self }
}

impl<'a> Clone for &'a str {
    /// Return a shallow copy of the slice.
    #[inline]
    fn clone(&self) -> &'a str { *self }
}

macro_rules! clone_impl(
    ($t:ty) => {
        impl Clone for $t {
            /// Return a deep copy of the value.
            #[inline]
            fn clone(&self) -> $t { *self }
        }
    }
)

clone_impl!(int)
clone_impl!(i8)
clone_impl!(i16)
clone_impl!(i32)
clone_impl!(i64)

clone_impl!(uint)
clone_impl!(u8)
clone_impl!(u16)
clone_impl!(u32)
clone_impl!(u64)

clone_impl!(f32)
clone_impl!(f64)

clone_impl!(())
clone_impl!(bool)
clone_impl!(char)

macro_rules! extern_fn_clone(
    ($($A:ident),*) => (
        impl<$($A,)* ReturnType> Clone for extern "Rust" fn($($A),*) -> ReturnType {
            /// Return a copy of a function pointer
            #[inline]
            fn clone(&self) -> extern "Rust" fn($($A),*) -> ReturnType { *self }
        }
    )
)

extern_fn_clone!()
extern_fn_clone!(A)
extern_fn_clone!(A, B)
extern_fn_clone!(A, B, C)
extern_fn_clone!(A, B, C, D)
extern_fn_clone!(A, B, C, D, E)
extern_fn_clone!(A, B, C, D, E, F)
extern_fn_clone!(A, B, C, D, E, F, G)
extern_fn_clone!(A, B, C, D, E, F, G, H)

#[test]
fn test_owned_clone() {
    let a = ~5i;
    let b: ~int = a.clone();
    assert_eq!(a, b);
}

#[test]
fn test_managed_clone() {
    let a = @5i;
    let b: @int = a.clone();
    assert_eq!(a, b);
}

#[test]
fn test_borrowed_clone() {
    let x = 5i;
    let y: &int = &x;
    let z: &int = (&y).clone();
    assert_eq!(*z, 5);
}

#[test]
fn test_clone_from() {
    let a = ~5;
    let mut b = ~10;
    b.clone_from(&a);
    assert_eq!(*b, 5);
}

#[test]
fn test_extern_fn_clone() {
    trait Empty {}
    impl Empty for int {}

    fn test_fn_a() -> f64 { 1.0 }
    fn test_fn_b<T: Empty>(x: T) -> T { x }
    fn test_fn_c(_: int, _: f64, _: ~[int], _: int, _: int, _: int) {}

    let _ = test_fn_a.clone();
    let _ = test_fn_b::<int>.clone();
    let _ = test_fn_c.clone();
}
<|endoftext|>


<commit_before>use primal_bit::BitVec;

pub const BYTE_SIZE: usize = 8;
pub const BYTE_MODULO: usize = 30;

pub fn small_for(x: usize) -> Option<BitVec> {
    let bits = bits_for(x);
    if bits < wheel30::SMALL_BITS {
        let u64s = (bits + 64 - 1) / 64;
        Some(BitVec::from_u64s(wheel30::SMALL[..u64s].to_owned(), bits))
    } else {
        None
    }
}

pub fn bits_for(x: usize) -> usize {
    (x * BYTE_SIZE + BYTE_MODULO - 1) / BYTE_MODULO
}

pub fn bit_index(n: usize) -> (bool, usize) {
    const POS: &'static [(bool, u8); BYTE_MODULO] = &[
        // 0
        (false, 0), (true, 0), (false, 1), (false, 1), (false, 1), (false, 1),
        // 6
        (false, 1), (true, 1), (false, 2), (false, 2), (false, 2), (true, 2),
        // 12
        (false, 3), (true, 3), (false, 4), (false, 4), (false, 4), (true, 4),
        // 18
        (false, 5), (true, 5), (false, 6), (false, 6), (false, 6), (true, 6),
        // 24
        (false, 7), (false, 7), (false, 7), (false, 7), (false, 7), (true, 7),
        ];
    let init = &POS[n % BYTE_MODULO];
    (init.0, (n / BYTE_MODULO) * BYTE_SIZE + init.1 as usize)
}
pub fn from_bit_index(bit: usize) -> usize {
    const TRUE_AT_BIT: &'static [usize; 8] = &[
        1, 7, 11, 13, 17, 19, 23, 29
            ];
    (bit / BYTE_SIZE) * BYTE_MODULO + TRUE_AT_BIT[bit % BYTE_SIZE]
}

pub const TRUE_AT_BIT_64: &'static [usize; 64] = &[
    1 + 30*0, 7 + 30*0, 11 + 30*0, 13 + 30*0, 17 + 30*0, 19 + 30*0, 23 + 30*0, 29 + 30*0,
    1 + 30*1, 7 + 30*1, 11 + 30*1, 13 + 30*1, 17 + 30*1, 19 + 30*1, 23 + 30*1, 29 + 30*1,
    1 + 30*2, 7 + 30*2, 11 + 30*2, 13 + 30*2, 17 + 30*2, 19 + 30*2, 23 + 30*2, 29 + 30*2,
    1 + 30*3, 7 + 30*3, 11 + 30*3, 13 + 30*3, 17 + 30*3, 19 + 30*3, 23 + 30*3, 29 + 30*3,

    1 + 30*4, 7 + 30*4, 11 + 30*4, 13 + 30*4, 17 + 30*4, 19 + 30*4, 23 + 30*4, 29 + 30*4,
    1 + 30*5, 7 + 30*5, 11 + 30*5, 13 + 30*5, 17 + 30*5, 19 + 30*5, 23 + 30*5, 29 + 30*5,
    1 + 30*6, 7 + 30*6, 11 + 30*6, 13 + 30*6, 17 + 30*6, 19 + 30*6, 23 + 30*6, 29 + 30*6,
    1 + 30*7, 7 + 30*7, 11 + 30*7, 13 + 30*7, 17 + 30*7, 19 + 30*7, 23 + 30*7, 29 + 30*7,
    ];

pub use self::wheel30::Wheel30;
pub use self::wheel210::Wheel210;

pub trait Wheel {
    fn modulo(&self) -> usize;
    fn size(&self) -> usize;
    fn wheel(&self) -> &'static [WheelElem];
    fn init(&self) -> &'static [WheelInit];
    unsafe fn hardcoded_sieve(&self,
                              bytes: &mut [u8], si_: &mut usize, wi_: &mut usize, prime: usize);
}

#[derive(Debug)]
pub struct State<W> {
    wheel: W,
    prime: u32,
    wheel_index: u16,
    sieve_index: u16,
}
impl<W: Wheel> State<W> {
    #[inline]
    pub fn sieve(&mut self, bytes: &mut [u8]) {
        let bytes = bytes;
        let top = bytes.len();

        let mut si = self.sieve_index as usize;
        let mut wi = self.wheel_index as usize;
        let p = self.prime as usize;
        while si < top {
            raw_set_bit(self.wheel.wheel(),
                        bytes, &mut si, &mut wi, p)
        }
        self.sieve_index = si.wrapping_sub(top) as u16;
        self.wheel_index = wi as u16;
    }
    #[inline]
    pub fn sieve_pair(&mut self, self2: &mut State<W>, bytes: &mut [u8]) {
        let bytes = bytes;
        let top = bytes.len();
        let wheel = self.wheel.wheel();

        let mut si1 = self.sieve_index as usize;
        let mut wi1 = self.wheel_index as usize;
        let p1 = self.prime as usize;
        let mut si2 = self2.sieve_index as usize;
        let mut wi2 = self2.wheel_index as usize;
        let p2 = self2.prime as usize;

        while si1 < top && si2 < top {
            raw_set_bit(wheel,
                        bytes, &mut si1, &mut wi1, p1);
            raw_set_bit(wheel,
                        bytes, &mut si2, &mut wi2, p2);
        }
        while si1 < top {
            raw_set_bit(wheel,
                        bytes, &mut si1, &mut wi1, p1);
        }
        while si2 < top {
            raw_set_bit(wheel,
                        bytes, &mut si2, &mut wi2, p2);
        }

        // if this wraps, we've hit the limit, and so won't be
        // continuing, so whatever, it can be junk.
        self.sieve_index = si1.wrapping_sub(top) as u16;
        self.wheel_index = wi1 as u16;
        self2.sieve_index = si2.wrapping_sub(top) as u16;
        self2.wheel_index = wi2 as u16;
    }
    pub fn sieve_triple(&mut self, self2: &mut State<W>, self3: &mut State<W>,
                        bytes: &mut [u8]) {
        let bytes = bytes;
        let top = bytes.len();
        let wheel = self.wheel.wheel();

        let mut si1 = self.sieve_index as usize;
        let mut wi1 = self.wheel_index as usize;
        let p1 = self.prime as usize;
        let mut si2 = self2.sieve_index as usize;
        let mut wi2 = self2.wheel_index as usize;
        let p2 = self2.prime as usize;
        let mut si3 = self3.sieve_index as usize;
        let mut wi3 = self3.wheel_index as usize;
        let p3 = self3.prime as usize;

        while si1 < top && si2 < top && si3 < top {
            raw_set_bit(wheel,
                        bytes, &mut si1, &mut wi1, p1);
            raw_set_bit(wheel,
                        bytes, &mut si2, &mut wi2, p2);
            raw_set_bit(wheel,
                        bytes, &mut si3, &mut wi3, p3);
        }
        while si1 < top {
            raw_set_bit(wheel,
                        bytes, &mut si1, &mut wi1, p1);
        }
        while si2 < top {
            raw_set_bit(wheel,
                        bytes, &mut si2, &mut wi2, p2);
        }
        while si3 < top {
            raw_set_bit(wheel,
                        bytes, &mut si3, &mut wi3, p3);
        }
        // if this wraps, we've hit the limit, and so won't be
        // continuing, so whatever, it can be junk.
        self.sieve_index = si1.wrapping_sub(top) as u16;
        self.wheel_index = wi1 as u16;
        self2.sieve_index = si2.wrapping_sub(top) as u16;
        self2.wheel_index = wi2 as u16;
        self3.sieve_index = si3.wrapping_sub(top) as u16;
        self3.wheel_index = wi3 as u16;
    }

    pub fn sieve_hardcoded(&mut self, bytes: &mut [u8]) {
        let mut si = self.sieve_index as usize;
        let mut wi = self.wheel_index as usize;
        unsafe {
            self.wheel.hardcoded_sieve(bytes,
                                       &mut si, &mut wi, self.prime as usize)
        }
        self.sieve_index = si as u16;
        self.wheel_index = wi as u16;
    }
}

#[derive(Debug)]
pub struct WheelInit {
    next_mult_factor: u8,
    wheel_index: u8,
}
#[derive(Debug)]
pub struct WheelElem {
    unset_bit: u8,
    next_mult_factor: u8,
    correction: u8,
    next: i8,
}

#[inline(always)]
fn raw_set_bit(wheel: &'static [WheelElem],
               x: &mut [u8], si: &mut usize, wi: &mut usize, prime: usize) {
    unsafe {
        let WheelElem { unset_bit, next_mult_factor, correction, next } =
            *wheel.get_unchecked(*wi);
        *x.get_unchecked_mut(*si) &= unset_bit;

        *si += prime * next_mult_factor as usize;
        *si += correction as usize;
        *wi = wi.wrapping_add(next as usize);
    }
}

const WHEEL_OFFSETS: &'static [usize; BYTE_MODULO] = &[
    0, 0, 0, 0, 0, 0,
    0, 1, 0, 0, 0, 2,
    0, 3, 0, 0, 0, 4,
    0, 5, 0, 0, 0, 6,
    0, 0, 0, 0, 0, 7,
    ];

#[inline(never)]
pub fn compute_wheel_elem<W: Wheel>(w: W, p: usize, low: usize) -> State<W> {
    let mut mult = p * p;

    let init = &w.init()[p % w.modulo()];
    let next_mult_factor = init.next_mult_factor;
    mult += p * next_mult_factor as usize;

    let mut wheel_index = WHEEL_OFFSETS[p % BYTE_MODULO] * w.size();
    let mut sieve_index = mult * BYTE_SIZE / BYTE_MODULO / 8;

    let prime = p / BYTE_MODULO;
    // run the wheel until its above `low`... this is ugly and should be done analytically.
    while sieve_index * BYTE_MODULO < low {
        let WheelElem { next_mult_factor, correction, next, .. } = w.wheel()[wheel_index];
        sieve_index += prime * next_mult_factor as usize;
        sieve_index += correction as usize;
        wheel_index = wheel_index.wrapping_add(next as usize);
    }

    sieve_index -= low / BYTE_MODULO;
    let ret = State {
        wheel: w,
        prime: prime as u32,
        sieve_index: sieve_index as u16,
        wheel_index: wheel_index as u16,
    };
    ret

}

mod wheel30;
mod wheel210;
<commit_msg>sieve: use new types for storing wheel/sieve indices.<commit_after>use primal_bit::BitVec;

pub const BYTE_SIZE: usize = 8;
pub const BYTE_MODULO: usize = 30;

pub fn small_for(x: usize) -> Option<BitVec> {
    let bits = bits_for(x);
    if bits < wheel30::SMALL_BITS {
        let u64s = (bits + 64 - 1) / 64;
        Some(BitVec::from_u64s(wheel30::SMALL[..u64s].to_owned(), bits))
    } else {
        None
    }
}

pub fn bits_for(x: usize) -> usize {
    (x * BYTE_SIZE + BYTE_MODULO - 1) / BYTE_MODULO
}

pub fn bit_index(n: usize) -> (bool, usize) {
    const POS: &'static [(bool, u8); BYTE_MODULO] = &[
        // 0
        (false, 0), (true, 0), (false, 1), (false, 1), (false, 1), (false, 1),
        // 6
        (false, 1), (true, 1), (false, 2), (false, 2), (false, 2), (true, 2),
        // 12
        (false, 3), (true, 3), (false, 4), (false, 4), (false, 4), (true, 4),
        // 18
        (false, 5), (true, 5), (false, 6), (false, 6), (false, 6), (true, 6),
        // 24
        (false, 7), (false, 7), (false, 7), (false, 7), (false, 7), (true, 7),
        ];
    let init = &POS[n % BYTE_MODULO];
    (init.0, (n / BYTE_MODULO) * BYTE_SIZE + init.1 as usize)
}
pub fn from_bit_index(bit: usize) -> usize {
    const TRUE_AT_BIT: &'static [usize; 8] = &[
        1, 7, 11, 13, 17, 19, 23, 29
            ];
    (bit / BYTE_SIZE) * BYTE_MODULO + TRUE_AT_BIT[bit % BYTE_SIZE]
}

pub const TRUE_AT_BIT_64: &'static [usize; 64] = &[
    1 + 30*0, 7 + 30*0, 11 + 30*0, 13 + 30*0, 17 + 30*0, 19 + 30*0, 23 + 30*0, 29 + 30*0,
    1 + 30*1, 7 + 30*1, 11 + 30*1, 13 + 30*1, 17 + 30*1, 19 + 30*1, 23 + 30*1, 29 + 30*1,
    1 + 30*2, 7 + 30*2, 11 + 30*2, 13 + 30*2, 17 + 30*2, 19 + 30*2, 23 + 30*2, 29 + 30*2,
    1 + 30*3, 7 + 30*3, 11 + 30*3, 13 + 30*3, 17 + 30*3, 19 + 30*3, 23 + 30*3, 29 + 30*3,

    1 + 30*4, 7 + 30*4, 11 + 30*4, 13 + 30*4, 17 + 30*4, 19 + 30*4, 23 + 30*4, 29 + 30*4,
    1 + 30*5, 7 + 30*5, 11 + 30*5, 13 + 30*5, 17 + 30*5, 19 + 30*5, 23 + 30*5, 29 + 30*5,
    1 + 30*6, 7 + 30*6, 11 + 30*6, 13 + 30*6, 17 + 30*6, 19 + 30*6, 23 + 30*6, 29 + 30*6,
    1 + 30*7, 7 + 30*7, 11 + 30*7, 13 + 30*7, 17 + 30*7, 19 + 30*7, 23 + 30*7, 29 + 30*7,
    ];

pub use self::wheel30::Wheel30;
pub use self::wheel210::Wheel210;

pub trait Wheel {
    fn modulo(&self) -> usize;
    fn size(&self) -> usize;
    fn wheel(&self) -> &'static [WheelElem];
    fn init(&self) -> &'static [WheelInit];
    unsafe fn hardcoded_sieve(&self,
                              bytes: &mut [u8], si_: &mut usize, wi_: &mut usize, prime: usize);
}

type SI = u32;
type WI = u16;
#[derive(Debug)]
pub struct State<W> {
    wheel: W,
    prime: u32,
    wheel_index: WI,
    sieve_index: SI,
}
impl<W: Wheel> State<W> {
    #[inline]
    pub fn sieve(&mut self, bytes: &mut [u8]) {
        let bytes = bytes;
        let top = bytes.len();

        let mut si = self.sieve_index as usize;
        let mut wi = self.wheel_index as usize;
        let p = self.prime as usize;
        while si < top {
            raw_set_bit(self.wheel.wheel(),
                        bytes, &mut si, &mut wi, p)
        }
        self.sieve_index = si.wrapping_sub(top) as SI;
        self.wheel_index = wi as WI;
    }
    #[inline]
    pub fn sieve_pair(&mut self, self2: &mut State<W>, bytes: &mut [u8]) {
        let bytes = bytes;
        let top = bytes.len();
        let wheel = self.wheel.wheel();

        let mut si1 = self.sieve_index as usize;
        let mut wi1 = self.wheel_index as usize;
        let p1 = self.prime as usize;
        let mut si2 = self2.sieve_index as usize;
        let mut wi2 = self2.wheel_index as usize;
        let p2 = self2.prime as usize;

        while si1 < top && si2 < top {
            raw_set_bit(wheel,
                        bytes, &mut si1, &mut wi1, p1);
            raw_set_bit(wheel,
                        bytes, &mut si2, &mut wi2, p2);
        }
        while si1 < top {
            raw_set_bit(wheel,
                        bytes, &mut si1, &mut wi1, p1);
        }
        while si2 < top {
            raw_set_bit(wheel,
                        bytes, &mut si2, &mut wi2, p2);
        }

        // if this wraps, we've hit the limit, and so won't be
        // continuing, so whatever, it can be junk.
        self.sieve_index = si1.wrapping_sub(top) as SI;
        self.wheel_index = wi1 as WI;
        self2.sieve_index = si2.wrapping_sub(top) as SI;
        self2.wheel_index = wi2 as WI;
    }
    pub fn sieve_triple(&mut self, self2: &mut State<W>, self3: &mut State<W>,
                        bytes: &mut [u8]) {
        let bytes = bytes;
        let top = bytes.len();
        let wheel = self.wheel.wheel();

        let mut si1 = self.sieve_index as usize;
        let mut wi1 = self.wheel_index as usize;
        let p1 = self.prime as usize;
        let mut si2 = self2.sieve_index as usize;
        let mut wi2 = self2.wheel_index as usize;
        let p2 = self2.prime as usize;
        let mut si3 = self3.sieve_index as usize;
        let mut wi3 = self3.wheel_index as usize;
        let p3 = self3.prime as usize;

        while si1 < top && si2 < top && si3 < top {
            raw_set_bit(wheel,
                        bytes, &mut si1, &mut wi1, p1);
            raw_set_bit(wheel,
                        bytes, &mut si2, &mut wi2, p2);
            raw_set_bit(wheel,
                        bytes, &mut si3, &mut wi3, p3);
        }
        while si1 < top {
            raw_set_bit(wheel,
                        bytes, &mut si1, &mut wi1, p1);
        }
        while si2 < top {
            raw_set_bit(wheel,
                        bytes, &mut si2, &mut wi2, p2);
        }
        while si3 < top {
            raw_set_bit(wheel,
                        bytes, &mut si3, &mut wi3, p3);
        }
        // if this wraps, we've hit the limit, and so won't be
        // continuing, so whatever, it can be junk.
        self.sieve_index = si1.wrapping_sub(top) as SI;
        self.wheel_index = wi1 as WI;
        self2.sieve_index = si2.wrapping_sub(top) as SI;
        self2.wheel_index = wi2 as WI;
        self3.sieve_index = si3.wrapping_sub(top) as SI;
        self3.wheel_index = wi3 as WI;
    }

    pub fn sieve_hardcoded(&mut self, bytes: &mut [u8]) {
        let mut si = self.sieve_index as usize;
        let mut wi = self.wheel_index as usize;
        unsafe {
            self.wheel.hardcoded_sieve(bytes,
                                       &mut si, &mut wi, self.prime as usize)
        }
        self.sieve_index = si as SI;
        self.wheel_index = wi as WI;
    }
}

#[derive(Debug)]
pub struct WheelInit {
    next_mult_factor: u8,
    wheel_index: u8,
}
#[derive(Debug)]
pub struct WheelElem {
    unset_bit: u8,
    next_mult_factor: u8,
    correction: u8,
    next: i8,
}

#[inline(always)]
fn raw_set_bit(wheel: &'static [WheelElem],
               x: &mut [u8], si: &mut usize, wi: &mut usize, prime: usize) {
    unsafe {
        let WheelElem { unset_bit, next_mult_factor, correction, next } =
            *wheel.get_unchecked(*wi);
        *x.get_unchecked_mut(*si) &= unset_bit;
        *si += prime * next_mult_factor as usize;
        *si += correction as usize;
        *wi = wi.wrapping_add(next as usize);
    }
}

const WHEEL_OFFSETS: &'static [usize; BYTE_MODULO] = &[
    0, 0, 0, 0, 0, 0,
    0, 1, 0, 0, 0, 2,
    0, 3, 0, 0, 0, 4,
    0, 5, 0, 0, 0, 6,
    0, 0, 0, 0, 0, 7,
    ];

#[inline(never)]
pub fn compute_wheel_elem<W: Wheel>(w: W, p: usize, low: usize) -> State<W> {
    let mut mult = p * p;

    let init = &w.init()[p % w.modulo()];
    let next_mult_factor = init.next_mult_factor;
    mult += p * next_mult_factor as usize;

    let mut wheel_index = WHEEL_OFFSETS[p % BYTE_MODULO] * w.size();
    let mut sieve_index = mult * BYTE_SIZE / BYTE_MODULO / 8;

    let prime = p / BYTE_MODULO;
    // run the wheel until its above `low`... this is ugly and should be done analytically.
    while sieve_index * BYTE_MODULO < low {
        let WheelElem { next_mult_factor, correction, next, .. } = w.wheel()[wheel_index];
        sieve_index += prime * next_mult_factor as usize;
        sieve_index += correction as usize;
        wheel_index = wheel_index.wrapping_add(next as usize);
    }
    sieve_index -= low / BYTE_MODULO;
    let ret = State {
        wheel: w,
        prime: prime as u32,
        sieve_index: sieve_index as SI,
        wheel_index: wheel_index as WI,
    };
    ret

}

mod wheel30;
mod wheel210;
<|endoftext|>


<commit_before>//! A private parser implementation of IPv4, IPv6, and socket addresses.
//!
//! This module is "publicly exported" through the `FromStr` implementations
//! below.

#[cfg(test)]
mod tests;

use crate::error::Error;
use crate::fmt;
use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use crate::str::FromStr;

struct Parser<'a> {
    // parsing as ASCII, so can use byte array
    state: &'a [u8],
}

impl<'a> Parser<'a> {
    fn new(input: &'a str) -> Parser<'a> {
        Parser { state: input.as_bytes() }
    }

    fn is_eof(&self) -> bool {
        self.state.is_empty()
    }

    /// Run a parser, and restore the pre-parse state if it fails
    fn read_atomically<T, F>(&mut self, inner: F) -> Option<T>
    where
        F: FnOnce(&mut Parser<'_>) -> Option<T>,
    {
        let state = self.state;
        let result = inner(self);
        if result.is_none() {
            self.state = state;
        }
        result
    }

    /// Run a parser, but fail if the entire input wasn't consumed.
    /// Doesn't run atomically.
    fn read_till_eof<T, F>(&mut self, inner: F) -> Option<T>
    where
        F: FnOnce(&mut Parser<'_>) -> Option<T>,
    {
        inner(self).filter(|_| self.is_eof())
    }

    /// Same as read_till_eof, but returns a Result<AddrParseError> on failure
    fn parse_with<T, F>(&mut self, inner: F) -> Result<T, AddrParseError>
    where
        F: FnOnce(&mut Parser<'_>) -> Option<T>,
    {
        self.read_till_eof(inner).ok_or(AddrParseError(()))
    }

    /// Read the next character from the input
    fn read_char(&mut self) -> Option<char> {
        self.state.split_first().map(|(&b, tail)| {
            self.state = tail;
            b as char
        })
    }

    /// Read the next character from the input if it matches the target
    fn read_given_char(&mut self, target: char) -> Option<char> {
        self.read_atomically(|p| p.read_char().filter(|&c| c == target))
    }

    /// Helper for reading separators in an indexed loop. Reads the separator
    /// character iff index > 0, then runs the parser. When used in a loop,
    /// the separator character will only be read on index > 0 (see
    /// read_ipv4_addr for an example)
    fn read_separator<T, F>(&mut self, sep: char, index: usize, inner: F) -> Option<T>
    where
        F: FnOnce(&mut Parser<'_>) -> Option<T>,
    {
        self.read_atomically(move |p| {
            if index > 0 {
                let _ = p.read_given_char(sep)?;
            }
            inner(p)
        })
    }

    // Read a single digit in the given radix. For instance, 0-9 in radix 10;
    // 0-9A-F in radix 16.
    fn read_digit(&mut self, radix: u32) -> Option<u32> {
        self.read_atomically(move |p| p.read_char()?.to_digit(radix))
    }

    // Read a number off the front of the input in the given radix, stopping
    // at the first non-digit character or eof. Fails if the number has more
    // digits than max_digits, or the value is >= upto, or if there is no number.
    fn read_number(&mut self, radix: u32, max_digits: u32, upto: u32) -> Option<u32> {
        self.read_atomically(move |p| {
            let mut result = 0;
            let mut digit_count = 0;

            while let Some(digit) = p.read_digit(radix) {
                result = (result * radix) + digit;
                digit_count += 1;
                if digit_count > max_digits || result >= upto {
                    return None;
                }
            }

            if digit_count == 0 { None } else { Some(result) }
        })
    }

    /// Read an IPv4 address
    fn read_ipv4_addr(&mut self) -> Option<Ipv4Addr> {
        self.read_atomically(|p| {
            let mut groups = [0; 4];

            for (i, slot) in groups.iter_mut().enumerate() {
                *slot = p.read_separator('.', i, |p| p.read_number(10, 3, 0x100))? as u8;
            }

            Some(groups.into())
        })
    }

    /// Read an IPV6 Address
    fn read_ipv6_addr(&mut self) -> Option<Ipv6Addr> {
        /// Read a chunk of an ipv6 address into `groups`. Returns the number
        /// of groups read, along with a bool indicating if an embedded
        /// trailing ipv4 address was read. Specifically, read a series of
        /// colon-separated ipv6 groups (0x0000 - 0xFFFF), with an optional
        /// trailing embedded ipv4 address.
        fn read_groups(p: &mut Parser<'_>, groups: &mut [u16]) -> (usize, bool) {
            let limit = groups.len();

            for (i, slot) in groups.iter_mut().enumerate() {
                // Try to read a trailing embedded ipv4 address. There must be
                // at least two groups left.
                if i < limit - 1 {
                    let ipv4 = p.read_separator(':', i, |p| p.read_ipv4_addr());

                    if let Some(v4_addr) = ipv4 {
                        let octets = v4_addr.octets();
                        groups[i + 0] = ((octets[0] as u16) << 8) | (octets[1] as u16);
                        groups[i + 1] = ((octets[2] as u16) << 8) | (octets[3] as u16);
                        return (i + 2, true);
                    }
                }

                let group = p.read_separator(':', i, |p| p.read_number(16, 4, 0x10000));

                match group {
                    Some(g) => *slot = g as u16,
                    None => return (i, false),
                }
            }
            (groups.len(), false)
        }

        self.read_atomically(|p| {
            // Read the front part of the address; either the whole thing, or up
            // to the first ::
            let mut head = [0; 8];
            let (head_size, head_ipv4) = read_groups(p, &mut head);

            if head_size == 8 {
                return Some(head.into());
            }

            // IPv4 part is not allowed before `::`
            if head_ipv4 {
                return None;
            }

            // read `::` if previous code parsed less than 8 groups
            // `::` indicates one or more groups of 16 bits of zeros
            let _ = p.read_given_char(':')?;
            let _ = p.read_given_char(':')?;

            // Read the back part of the address. The :: must contain at least one
            // set of zeroes, so our max length is 7.
            let mut tail = [0; 7];
            let limit = 8 - (head_size + 1);
            let (tail_size, _) = read_groups(p, &mut tail[..limit]);

            // Concat the head and tail of the IP address
            head[(8 - tail_size)..8].copy_from_slice(&tail[..tail_size]);

            Some(head.into())
        })
    }

    /// Read an IP Address, either IPV4 or IPV6.
    fn read_ip_addr(&mut self) -> Option<IpAddr> {
        self.read_ipv4_addr().map(IpAddr::V4).or_else(move || self.read_ipv6_addr().map(IpAddr::V6))
    }

    /// Read a : followed by a port in base 10
    fn read_port(&mut self) -> Option<u16> {
        self.read_atomically(|p| {
            let _ = p.read_given_char(':')?;
            let port = p.read_number(10, 5, 0x10000)?;
            Some(port as u16)
        })
    }

    /// Read an IPV4 address with a port
    fn read_socket_addr_v4(&mut self) -> Option<SocketAddrV4> {
        self.read_atomically(|p| {
            let ip = p.read_ipv4_addr()?;
            let port = p.read_port()?;
            Some(SocketAddrV4::new(ip, port))
        })
    }

    /// Read an IPV6 address with a port
    fn read_socket_addr_v6(&mut self) -> Option<SocketAddrV6> {
        self.read_atomically(|p| {
            let _ = p.read_given_char('[')?;
            let ip = p.read_ipv6_addr()?;
            let _ = p.read_given_char(']')?;

            let port = p.read_port()?;
            Some(SocketAddrV6::new(ip, port, 0, 0))
        })
    }

    /// Read an IP address with a port
    fn read_socket_addr(&mut self) -> Option<SocketAddr> {
        self.read_socket_addr_v4()
            .map(SocketAddr::V4)
            .or_else(|| self.read_socket_addr_v6().map(SocketAddr::V6))
    }
}

#[stable(feature = "ip_addr", since = "1.7.0")]
impl FromStr for IpAddr {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<IpAddr, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_ip_addr())
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl FromStr for Ipv4Addr {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_ipv4_addr())
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl FromStr for Ipv6Addr {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<Ipv6Addr, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_ipv6_addr())
    }
}

#[stable(feature = "socket_addr_from_str", since = "1.5.0")]
impl FromStr for SocketAddrV4 {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<SocketAddrV4, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_socket_addr_v4())
    }
}

#[stable(feature = "socket_addr_from_str", since = "1.5.0")]
impl FromStr for SocketAddrV6 {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<SocketAddrV6, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_socket_addr_v6())
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl FromStr for SocketAddr {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<SocketAddr, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_socket_addr())
    }
}

/// An error which can be returned when parsing an IP address or a socket address.
///
/// This error is used as the error type for the [`FromStr`] implementation for
/// [`IpAddr`], [`Ipv4Addr`], [`Ipv6Addr`], [`SocketAddr`], [`SocketAddrV4`], and
/// [`SocketAddrV6`].
///
/// # Potential causes
///
/// `AddrParseError` may be thrown because the provided string does not parse as the given type,
/// often because it includes information only handled by a different address type.
///
/// ```should_panic
/// use std::net::IpAddr;
/// let _foo: IpAddr = "127.0.0.1:8080".parse().expect("Cannot handle the socket port");
/// ```
///
/// [`IpAddr`] doesn't handle the port. Use [`SocketAddr`] instead.
///
/// ```
/// use std::net::SocketAddr;
///
/// // No problem, the `panic!` message has disappeared.
/// let _foo: SocketAddr = "127.0.0.1:8080".parse().expect("unreachable panic");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AddrParseError(());

#[stable(feature = "addr_parse_error_error", since = "1.4.0")]
impl fmt::Display for AddrParseError {
    #[allow(deprecated, deprecated_in_future)]
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt.write_str(self.description())
    }
}

#[stable(feature = "addr_parse_error_error", since = "1.4.0")]
impl Error for AddrParseError {
    #[allow(deprecated)]
    fn description(&self) -> &str {
        "invalid IP address syntax"
    }
}
<commit_msg>Avoid unchecked casts in net parser<commit_after>//! A private parser implementation of IPv4, IPv6, and socket addresses.
//!
//! This module is "publicly exported" through the `FromStr` implementations
//! below.

#[cfg(test)]
mod tests;

use crate::convert::TryInto as _;
use crate::error::Error;
use crate::fmt;
use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use crate::str::FromStr;

trait ReadNumberHelper: crate::marker::Sized {
    const ZERO: Self;
    fn checked_mul(&self, other: u32) -> Option<Self>;
    fn checked_add(&self, other: u32) -> Option<Self>;
}

macro_rules! impl_helper {
    ($($t:ty)*) => ($(impl ReadNumberHelper for $t {
        const ZERO: Self = 0;
        #[inline]
        fn checked_mul(&self, other: u32) -> Option<Self> {
            Self::checked_mul(*self, other.try_into().ok()?)
        }
        #[inline]
        fn checked_add(&self, other: u32) -> Option<Self> {
            Self::checked_add(*self, other.try_into().ok()?)
        }
    })*)
}

impl_helper! { u8 u16 }

struct Parser<'a> {
    // parsing as ASCII, so can use byte array
    state: &'a [u8],
}

impl<'a> Parser<'a> {
    fn new(input: &'a str) -> Parser<'a> {
        Parser { state: input.as_bytes() }
    }

    fn is_eof(&self) -> bool {
        self.state.is_empty()
    }

    /// Run a parser, and restore the pre-parse state if it fails
    fn read_atomically<T, F>(&mut self, inner: F) -> Option<T>
    where
        F: FnOnce(&mut Parser<'_>) -> Option<T>,
    {
        let state = self.state;
        let result = inner(self);
        if result.is_none() {
            self.state = state;
        }
        result
    }

    /// Run a parser, but fail if the entire input wasn't consumed.
    /// Doesn't run atomically.
    fn read_till_eof<T, F>(&mut self, inner: F) -> Option<T>
    where
        F: FnOnce(&mut Parser<'_>) -> Option<T>,
    {
        inner(self).filter(|_| self.is_eof())
    }

    /// Same as read_till_eof, but returns a Result<AddrParseError> on failure
    fn parse_with<T, F>(&mut self, inner: F) -> Result<T, AddrParseError>
    where
        F: FnOnce(&mut Parser<'_>) -> Option<T>,
    {
        self.read_till_eof(inner).ok_or(AddrParseError(()))
    }

    /// Read the next character from the input
    fn read_char(&mut self) -> Option<char> {
        self.state.split_first().map(|(&b, tail)| {
            self.state = tail;
            char::from(b)
        })
    }

    /// Read the next character from the input if it matches the target
    fn read_given_char(&mut self, target: char) -> Option<char> {
        self.read_atomically(|p| p.read_char().filter(|&c| c == target))
    }

    /// Helper for reading separators in an indexed loop. Reads the separator
    /// character iff index > 0, then runs the parser. When used in a loop,
    /// the separator character will only be read on index > 0 (see
    /// read_ipv4_addr for an example)
    fn read_separator<T, F>(&mut self, sep: char, index: usize, inner: F) -> Option<T>
    where
        F: FnOnce(&mut Parser<'_>) -> Option<T>,
    {
        self.read_atomically(move |p| {
            if index > 0 {
                let _ = p.read_given_char(sep)?;
            }
            inner(p)
        })
    }

    // Read a number off the front of the input in the given radix, stopping
    // at the first non-digit character or eof. Fails if the number has more
    // digits than max_digits or if there is no number.
    fn read_number<T: ReadNumberHelper>(
        &mut self,
        radix: u32,
        max_digits: Option<usize>,
    ) -> Option<T> {
        self.read_atomically(move |p| {
            let mut result = T::ZERO;
            let mut digit_count = 0;

            while let Some(digit) = p.read_atomically(|p| p.read_char()?.to_digit(radix)) {
                result = result.checked_mul(radix)?;
                result = result.checked_add(digit)?;
                digit_count += 1;
                if let Some(max_digits) = max_digits {
                    if digit_count > max_digits {
                        return None;
                    }
                }
            }

            if digit_count == 0 { None } else { Some(result) }
        })
    }

    /// Read an IPv4 address
    fn read_ipv4_addr(&mut self) -> Option<Ipv4Addr> {
        self.read_atomically(|p| {
            let mut groups = [0; 4];

            for (i, slot) in groups.iter_mut().enumerate() {
                *slot = p.read_separator('.', i, |p| p.read_number(10, None))?;
            }

            Some(groups.into())
        })
    }

    /// Read an IPV6 Address
    fn read_ipv6_addr(&mut self) -> Option<Ipv6Addr> {
        /// Read a chunk of an ipv6 address into `groups`. Returns the number
        /// of groups read, along with a bool indicating if an embedded
        /// trailing ipv4 address was read. Specifically, read a series of
        /// colon-separated ipv6 groups (0x0000 - 0xFFFF), with an optional
        /// trailing embedded ipv4 address.
        fn read_groups(p: &mut Parser<'_>, groups: &mut [u16]) -> (usize, bool) {
            let limit = groups.len();

            for (i, slot) in groups.iter_mut().enumerate() {
                // Try to read a trailing embedded ipv4 address. There must be
                // at least two groups left.
                if i < limit - 1 {
                    let ipv4 = p.read_separator(':', i, |p| p.read_ipv4_addr());

                    if let Some(v4_addr) = ipv4 {
                        let [one, two, three, four] = v4_addr.octets();
                        groups[i + 0] = u16::from_be_bytes([one, two]);
                        groups[i + 1] = u16::from_be_bytes([three, four]);
                        return (i + 2, true);
                    }
                }

                let group = p.read_separator(':', i, |p| p.read_number(16, Some(4)));

                match group {
                    Some(g) => *slot = g,
                    None => return (i, false),
                }
            }
            (groups.len(), false)
        }

        self.read_atomically(|p| {
            // Read the front part of the address; either the whole thing, or up
            // to the first ::
            let mut head = [0; 8];
            let (head_size, head_ipv4) = read_groups(p, &mut head);

            if head_size == 8 {
                return Some(head.into());
            }

            // IPv4 part is not allowed before `::`
            if head_ipv4 {
                return None;
            }

            // read `::` if previous code parsed less than 8 groups
            // `::` indicates one or more groups of 16 bits of zeros
            let _ = p.read_given_char(':')?;
            let _ = p.read_given_char(':')?;

            // Read the back part of the address. The :: must contain at least one
            // set of zeroes, so our max length is 7.
            let mut tail = [0; 7];
            let limit = 8 - (head_size + 1);
            let (tail_size, _) = read_groups(p, &mut tail[..limit]);

            // Concat the head and tail of the IP address
            head[(8 - tail_size)..8].copy_from_slice(&tail[..tail_size]);

            Some(head.into())
        })
    }

    /// Read an IP Address, either IPV4 or IPV6.
    fn read_ip_addr(&mut self) -> Option<IpAddr> {
        self.read_ipv4_addr().map(IpAddr::V4).or_else(move || self.read_ipv6_addr().map(IpAddr::V6))
    }

    /// Read a : followed by a port in base 10.
    fn read_port(&mut self) -> Option<u16> {
        self.read_atomically(|p| {
            let _ = p.read_given_char(':')?;
            p.read_number(10, None)
        })
    }

    /// Read an IPV4 address with a port
    fn read_socket_addr_v4(&mut self) -> Option<SocketAddrV4> {
        self.read_atomically(|p| {
            let ip = p.read_ipv4_addr()?;
            let port = p.read_port()?;
            Some(SocketAddrV4::new(ip, port))
        })
    }

    /// Read an IPV6 address with a port
    fn read_socket_addr_v6(&mut self) -> Option<SocketAddrV6> {
        self.read_atomically(|p| {
            let _ = p.read_given_char('[')?;
            let ip = p.read_ipv6_addr()?;
            let _ = p.read_given_char(']')?;

            let port = p.read_port()?;
            Some(SocketAddrV6::new(ip, port, 0, 0))
        })
    }

    /// Read an IP address with a port
    fn read_socket_addr(&mut self) -> Option<SocketAddr> {
        self.read_socket_addr_v4()
            .map(SocketAddr::V4)
            .or_else(|| self.read_socket_addr_v6().map(SocketAddr::V6))
    }
}

#[stable(feature = "ip_addr", since = "1.7.0")]
impl FromStr for IpAddr {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<IpAddr, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_ip_addr())
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl FromStr for Ipv4Addr {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_ipv4_addr())
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl FromStr for Ipv6Addr {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<Ipv6Addr, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_ipv6_addr())
    }
}

#[stable(feature = "socket_addr_from_str", since = "1.5.0")]
impl FromStr for SocketAddrV4 {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<SocketAddrV4, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_socket_addr_v4())
    }
}

#[stable(feature = "socket_addr_from_str", since = "1.5.0")]
impl FromStr for SocketAddrV6 {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<SocketAddrV6, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_socket_addr_v6())
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl FromStr for SocketAddr {
    type Err = AddrParseError;
    fn from_str(s: &str) -> Result<SocketAddr, AddrParseError> {
        Parser::new(s).parse_with(|p| p.read_socket_addr())
    }
}

/// An error which can be returned when parsing an IP address or a socket address.
///
/// This error is used as the error type for the [`FromStr`] implementation for
/// [`IpAddr`], [`Ipv4Addr`], [`Ipv6Addr`], [`SocketAddr`], [`SocketAddrV4`], and
/// [`SocketAddrV6`].
///
/// # Potential causes
///
/// `AddrParseError` may be thrown because the provided string does not parse as the given type,
/// often because it includes information only handled by a different address type.
///
/// ```should_panic
/// use std::net::IpAddr;
/// let _foo: IpAddr = "127.0.0.1:8080".parse().expect("Cannot handle the socket port");
/// ```
///
/// [`IpAddr`] doesn't handle the port. Use [`SocketAddr`] instead.
///
/// ```
/// use std::net::SocketAddr;
///
/// // No problem, the `panic!` message has disappeared.
/// let _foo: SocketAddr = "127.0.0.1:8080".parse().expect("unreachable panic");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AddrParseError(());

#[stable(feature = "addr_parse_error_error", since = "1.4.0")]
impl fmt::Display for AddrParseError {
    #[allow(deprecated, deprecated_in_future)]
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt.write_str(self.description())
    }
}

#[stable(feature = "addr_parse_error_error", since = "1.4.0")]
impl Error for AddrParseError {
    #[allow(deprecated)]
    fn description(&self) -> &str {
        "invalid IP address syntax"
    }
}
<|endoftext|>


<commit_before>extern crate uuid;
use std::rc::{Rc, Weak};
use std::cell::{Ref, RefMut, RefCell};
use std::cmp::{Eq, PartialEq};
use self::uuid::Uuid;
use super::super::math::vector3::Vector3;
use super::super::math::quaternion::Quaternion;
use super::super::math::matrix4::Matrix4;
use super::super::math::matrix3::Matrix3;
use super::super::math::euler::Euler;
use super::layers::Layers;

pub static mut DEFAULT_UP: Vector3 = Vector3 {
	x: 0.0,
	y: 1.0,
	z: 0.0,
};
pub static mut DEFAULT_MATRIX_AUTO_UPDATE: bool = true;

#[derive(Debug, Clone)]
pub struct Object3D {
	_self: Option<Weak<RefCell<Object3D>>>,
	uuid: Uuid,
	name: &'static str,
	children: Vec<Rc<RefCell<Object3D>>>,
	up: Vector3,
	position: Vector3,
	quaternion: Quaternion,
	scale: Vector3,
	matrix_auto_update: bool,
	matrix_world_needs_update: bool,
	model_view_matrix: Matrix4,
	normal_matrix: Matrix3,
	matrix: Matrix4,
	matrix_world: Matrix4,
	layers: Layers,
	visible: bool,
	cast_shadow: bool,
	receive_shadow: bool,
	frustum_culled: bool,
	render_order: u32,
	parent: Option<Rc<RefCell<Object3D>>>,
}

impl PartialEq for Object3D {
	 fn eq(&self, other: &Object3D) -> bool {
		 self.uuid == other.uuid
	 }
}

impl Object3D {
	pub fn new() -> Rc<RefCell<Object3D>> {
		let mut o = Object3D {
			_self: Option::None,
			uuid: Uuid::new_v4(),
			name: "",
			children: vec![],
			up: unsafe {DEFAULT_UP},
			position: Vector3::new(),
			quaternion: Quaternion::new(),
			scale: Vector3 {
				x: 1.0,
				y: 1.0,
				z: 1.0,
			},
			model_view_matrix: Matrix4::new(),
			normal_matrix: Matrix3::new(),
			matrix: Matrix4::new(),
			matrix_world: Matrix4::new(),
			matrix_auto_update: unsafe {DEFAULT_MATRIX_AUTO_UPDATE},
			matrix_world_needs_update: false,
			layers: Layers::new(),
			visible: true,
			cast_shadow: false,
			receive_shadow: false,
			frustum_culled: true,
			render_order: 0,
			parent: Option::None,
		};
		let rc = Rc::new(RefCell::from(o));
		let weak = Rc::downgrade(&rc);
		rc.borrow_mut()._self = Some(weak);
		rc
	}

	pub fn apply_matrix(&mut self, matrix: &Matrix4) {
		let m = self.matrix;
		self.matrix.multiply_matrices(matrix, &m);
		let mut p = self.position;
		let mut q = self.quaternion;
		let mut s = self.scale;
		self.matrix.decompose(&mut p, &mut q, &mut s);
		self.position = p;
		self.quaternion = q;
		self.scale = s;
	}

	pub fn set_rotation_from_axis_angle(&mut self, axis: &Vector3, angle: f32) {
		self.quaternion.set_from_axis_angle(axis, angle);
	}

	pub fn set_rotation_from_euler(&mut self, euler: &Euler) {
		self.quaternion.set_from_euler(euler);
	}

	pub fn set_rotation_from_matrix(&mut self, m: &Matrix4) {
		self.quaternion.set_from_rotation_matrix(m);
	}

	pub fn set_rotation_from_quaternion(&mut self, q: &Quaternion) {
		self.quaternion.copy(q);
	}

	pub fn rotate_on_axis(&mut self, axis: &Vector3, angle: f32) {
		let mut q1 = Quaternion::new();
		q1.set_from_axis_angle(axis, angle);
		self.quaternion.multiply(&q1);
	}

	pub fn rotate_x(&mut self, angle: f32) {
		let v1 = Vector3 {
			x: 1.0,
			y: 0.0,
			z: 0.0,
		};
		self.rotate_on_axis(&v1, angle);
	}

	pub fn rotate_y(&mut self, angle: f32) {
		let v1 = Vector3 {
			x: 0.0,
			y: 1.0,
			z: 0.0,
		};
		self.rotate_on_axis(&v1, angle);
	}

	pub fn rotate_z(&mut self, angle: f32) {
		let v1 = Vector3 {
			x: 0.0,
			y: 0.0,
			z: 1.0,
		};
		self.rotate_on_axis(&v1, angle);
	}

	pub fn translate_on_axis(&mut self, axis: &Vector3, distance: f32) {
		let mut v1 = Vector3::new();
		v1.copy(axis);
		v1.apply_quaternion(&self.quaternion);
		v1.multiply_scalar(distance);
		self.position.add(&v1);
	}

	pub fn translate_x(&mut self, distance: f32) {
		let v1 = Vector3 {
			x: 1.0,
			y: 0.0,
			z: 0.0,
		};
		self.translate_on_axis(&v1, distance);
	}

	pub fn translate_y(&mut self, distance: f32) {
		let v1 = Vector3 {
			x: 0.0,
			y: 1.0,
			z: 0.0,
		};
		self.translate_on_axis(&v1, distance);
	}

	pub fn translate_z(&mut self, distance: f32) {
		let v1 = Vector3 {
			x: 0.0,
			y: 0.0,
			z: 1.0,
		};
		self.translate_on_axis(&v1, distance);
	}

	pub fn local_to_world(&self, vector: &mut Vector3) {
		vector.apply_matrix4(&self.matrix_world);
	}

	pub fn world_to_local(&self, vector: &mut Vector3) {
		let mut m1 = Matrix4::new();
		m1.get_inverse(&self.matrix_world, false);
		vector.apply_matrix4(&m1);
	}

	pub fn look_at(&mut self, vector: &Vector3) {
		let mut m1 = Matrix4::new();
		m1.look_at(vector, &self.position, &self.up);
		self.quaternion.set_from_rotation_matrix(&m1);
	}

	pub fn add(&mut self, object: Rc<RefCell<Object3D>>) {
		let ref mut s = self._self;
		let self_rc = s.as_mut().unwrap().upgrade().unwrap();
		object.borrow_mut().parent = Some(self_rc);
		self.children.push(object);
	}
}<commit_msg>object3d add remove<commit_after>extern crate uuid;
use std::rc::{Rc, Weak};
use std::cell::{Ref, RefMut, RefCell};
use std::cmp::{Eq, PartialEq};
use self::uuid::Uuid;
use super::super::math::vector3::Vector3;
use super::super::math::quaternion::Quaternion;
use super::super::math::matrix4::Matrix4;
use super::super::math::matrix3::Matrix3;
use super::super::math::euler::Euler;
use super::layers::Layers;

pub static mut DEFAULT_UP: Vector3 = Vector3 {
	x: 0.0,
	y: 1.0,
	z: 0.0,
};
pub static mut DEFAULT_MATRIX_AUTO_UPDATE: bool = true;

pub trait HasObject3D {
	fn get_object3d(&self) -> &Object3D;
	fn get_object3d_mut(&mut self) -> &mut Object3D;
}

#[derive(Clone)]
pub struct Object3D {
	uuid: Uuid,
	name: &'static str,
	children: Vec<Rc<RefCell<HasObject3D>>>,
	up: Vector3,
	position: Vector3,
	quaternion: Quaternion,
	scale: Vector3,
	matrix_auto_update: bool,
	matrix_world_needs_update: bool,
	model_view_matrix: Matrix4,
	normal_matrix: Matrix3,
	matrix: Matrix4,
	matrix_world: Matrix4,
	layers: Layers,
	visible: bool,
	cast_shadow: bool,
	receive_shadow: bool,
	frustum_culled: bool,
	render_order: u32,
	parent: Option<Weak<RefCell<HasObject3D>>>,
}

impl HasObject3D for Object3D {
	fn get_object3d(&self) -> &Object3D {
		self
	}

	fn get_object3d_mut(&mut self) -> &mut Object3D {
		self
	}
}

impl PartialEq for Object3D {
	 fn eq(&self, other: &Object3D) -> bool {
		 self.uuid == other.uuid
	 }
}

impl Object3D {
	pub fn new() -> Object3D {
		Object3D {
			uuid: Uuid::new_v4(),
			name: "",
			children: vec![],
			up: unsafe {DEFAULT_UP},
			position: Vector3::new(),
			quaternion: Quaternion::new(),
			scale: Vector3 {
				x: 1.0,
				y: 1.0,
				z: 1.0,
			},
			model_view_matrix: Matrix4::new(),
			normal_matrix: Matrix3::new(),
			matrix: Matrix4::new(),
			matrix_world: Matrix4::new(),
			matrix_auto_update: unsafe {DEFAULT_MATRIX_AUTO_UPDATE},
			matrix_world_needs_update: false,
			layers: Layers::new(),
			visible: true,
			cast_shadow: false,
			receive_shadow: false,
			frustum_culled: true,
			render_order: 0,
			parent: Option::None,
		}
	}

	pub fn apply_matrix(&mut self, matrix: &Matrix4) {
		let m = self.matrix;
		self.matrix.multiply_matrices(matrix, &m);
		let mut p = self.position;
		let mut q = self.quaternion;
		let mut s = self.scale;
		self.matrix.decompose(&mut p, &mut q, &mut s);
		self.position = p;
		self.quaternion = q;
		self.scale = s;
	}

	pub fn set_rotation_from_axis_angle(&mut self, axis: &Vector3, angle: f32) {
		self.quaternion.set_from_axis_angle(axis, angle);
	}

	pub fn set_rotation_from_euler(&mut self, euler: &Euler) {
		self.quaternion.set_from_euler(euler);
	}

	pub fn set_rotation_from_matrix(&mut self, m: &Matrix4) {
		self.quaternion.set_from_rotation_matrix(m);
	}

	pub fn set_rotation_from_quaternion(&mut self, q: &Quaternion) {
		self.quaternion.copy(q);
	}

	pub fn rotate_on_axis(&mut self, axis: &Vector3, angle: f32) {
		let mut q1 = Quaternion::new();
		q1.set_from_axis_angle(axis, angle);
		self.quaternion.multiply(&q1);
	}

	pub fn rotate_x(&mut self, angle: f32) {
		let v1 = Vector3 {
			x: 1.0,
			y: 0.0,
			z: 0.0,
		};
		self.rotate_on_axis(&v1, angle);
	}

	pub fn rotate_y(&mut self, angle: f32) {
		let v1 = Vector3 {
			x: 0.0,
			y: 1.0,
			z: 0.0,
		};
		self.rotate_on_axis(&v1, angle);
	}

	pub fn rotate_z(&mut self, angle: f32) {
		let v1 = Vector3 {
			x: 0.0,
			y: 0.0,
			z: 1.0,
		};
		self.rotate_on_axis(&v1, angle);
	}

	pub fn translate_on_axis(&mut self, axis: &Vector3, distance: f32) {
		let mut v1 = Vector3::new();
		v1.copy(axis);
		v1.apply_quaternion(&self.quaternion);
		v1.multiply_scalar(distance);
		self.position.add(&v1);
	}

	pub fn translate_x(&mut self, distance: f32) {
		let v1 = Vector3 {
			x: 1.0,
			y: 0.0,
			z: 0.0,
		};
		self.translate_on_axis(&v1, distance);
	}

	pub fn translate_y(&mut self, distance: f32) {
		let v1 = Vector3 {
			x: 0.0,
			y: 1.0,
			z: 0.0,
		};
		self.translate_on_axis(&v1, distance);
	}

	pub fn translate_z(&mut self, distance: f32) {
		let v1 = Vector3 {
			x: 0.0,
			y: 0.0,
			z: 1.0,
		};
		self.translate_on_axis(&v1, distance);
	}

	pub fn local_to_world(&self, vector: &mut Vector3) {
		vector.apply_matrix4(&self.matrix_world);
	}

	pub fn world_to_local(&self, vector: &mut Vector3) {
		let mut m1 = Matrix4::new();
		m1.get_inverse(&self.matrix_world, false);
		vector.apply_matrix4(&m1);
	}

	pub fn look_at(&mut self, vector: &Vector3) {
		let mut m1 = Matrix4::new();
		m1.look_at(vector, &self.position, &self.up);
		self.quaternion.set_from_rotation_matrix(&m1);
	}

	pub fn add(parent: &Rc<RefCell<HasObject3D>>, child: &Rc<RefCell<HasObject3D>>) {
		let weak = Rc::downgrade(parent);
		child.borrow_mut().get_object3d_mut().parent = Some(weak);
		parent.borrow_mut().get_object3d_mut().children.push(child.clone());
	}

	pub fn remove(&mut self, object: &Rc<RefCell<HasObject3D>>) -> bool {
		let mut idx: Option<usize> = Option::None;
		for (i, o) in self.children.iter().enumerate() {
			if o.borrow().get_object3d() == object.borrow().get_object3d() {
				idx = Some(i);
				break;
			}
		}
		if let Some(i) = idx {
			self.children.swap_remove(i);
			object.borrow_mut().get_object3d_mut().parent = Option::None;
			return true;
		}
		false
	}

	// pub fn remove_self(&mut self) -> bool {
	// 	if self.parent.is_some() {
	// 		true
	// 	} else {
	// 		false
	// 	}
	// }
}<|endoftext|>


<commit_before>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use num_traits::{Float, FloatConst, Zero, One};
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, Sub, SubAssign};
use core::cmp::{Eq, PartialEq};
use core::hash::{Hash};
use crate::trig::Trig;
use crate::approxeq::ApproxEq;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

/// An angle in radians
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Angle<T> {
    pub radians: T,
}

impl<T> Angle<T> {
    #[inline]
    pub fn radians(radians: T) -> Self {
        Angle { radians }
    }

    #[inline]
    pub fn get(self) -> T {
        self.radians
    }
}

impl<T> Angle<T>
where
    T: Trig,
{
    #[inline]
    pub fn degrees(deg: T) -> Self {
        Angle {
            radians: T::degrees_to_radians(deg),
        }
    }

    #[inline]
    pub fn to_degrees(self) -> T {
        T::radians_to_degrees(self.radians)
    }
}

impl<T> Angle<T>
where
    T: Rem<Output = T> + Sub<Output = T> + Add<Output = T> + Zero + FloatConst + PartialOrd + Copy,
{
    /// Returns this angle in the [0..2*PI[ range.
    pub fn positive(&self) -> Self {
        let two_pi = T::PI() + T::PI();
        let mut a = self.radians % two_pi;
        if a < T::zero() {
            a = a + two_pi;
        }
        Angle::radians(a)
    }

    /// Returns this angle in the ]-PI..PI] range.
    pub fn signed(&self) -> Self {
        Angle::pi() - (Angle::pi() - *self).positive()
    }

}

impl<T> Angle<T>
where
    T: Rem<Output = T> + Mul<Output = T> + Sub<Output = T> + Add<Output = T> + One + FloatConst + Copy,
{
    /// Returns the shortest signed angle between two angles.
    ///
    /// Takes wrapping and signs into account.
    pub fn angle_to(&self, to: Self) -> Self {
        let two = T::one() + T::one();
        let max = T::PI() * two;
        let d = (to.radians - self.radians) % max;

        Angle::radians(two * d % max - d)
    }

    /// Linear interpolation between two angles, using the shortest path.
    pub fn lerp(&self, other: Self, t: T) -> Self {
        *self + self.angle_to(other) * t
    }
}

impl<T> Angle<T>
where
    T: Float,
{
    /// Returns (sin(self), cos(self)).
    pub fn sin_cos(self) -> (T, T) {
        self.radians.sin_cos()
    }
}

impl<T> Angle<T>
where
    T: Zero,
{
    pub fn zero() -> Self {
        Angle::radians(T::zero())
    }
}

impl<T> Angle<T>
where
    T: FloatConst + Add<Output = T>,
{
    pub fn pi() -> Self {
        Angle::radians(T::PI())
    }

    pub fn two_pi() -> Self {
        Angle::radians(T::PI() + T::PI())
    }

    pub fn frac_pi_2() -> Self {
        Angle::radians(T::FRAC_PI_2())
    }

    pub fn frac_pi_3() -> Self {
        Angle::radians(T::FRAC_PI_3())
    }

    pub fn frac_pi_4() -> Self {
        Angle::radians(T::FRAC_PI_4())
    }
}

impl<T: Add<T, Output = T>> Add for Angle<T> {
    type Output = Angle<T>;
    fn add(self, other: Angle<T>) -> Angle<T> {
        Angle::radians(self.radians + other.radians)
    }
}

impl<T: AddAssign<T>> AddAssign for Angle<T> {
    fn add_assign(&mut self, other: Angle<T>) {
        self.radians += other.radians;
    }
}

impl<T: Sub<T, Output = T>> Sub<Angle<T>> for Angle<T> {
    type Output = Angle<T>;
    fn sub(self, other: Angle<T>) -> <Self as Sub>::Output {
        Angle::radians(self.radians - other.radians)
    }
}

impl<T: SubAssign<T>> SubAssign for Angle<T> {
    fn sub_assign(&mut self, other: Angle<T>) {
        self.radians -= other.radians;
    }
}

impl<T: Div<T, Output = T>> Div<Angle<T>> for Angle<T> {
    type Output = T;
    #[inline]
    fn div(self, other: Angle<T>) -> T {
        self.radians / other.radians
    }
}

impl<T: Div<T, Output = T>> Div<T> for Angle<T> {
    type Output = Angle<T>;
    #[inline]
    fn div(self, factor: T) -> Angle<T> {
        Angle::radians(self.radians / factor)
    }
}

impl<T: DivAssign<T>> DivAssign<T> for Angle<T> {
    fn div_assign(&mut self, factor: T) {
        self.radians /= factor;
    }
}

impl<T: Mul<T, Output = T>> Mul<T> for Angle<T> {
    type Output = Angle<T>;
    #[inline]
    fn mul(self, factor: T) -> Angle<T> {
        Angle::radians(self.radians * factor)
    }
}

impl<T: MulAssign<T>> MulAssign<T> for Angle<T> {
    fn mul_assign(&mut self, factor: T) {
        self.radians *= factor;
    }
}

impl<T: Neg<Output = T>> Neg for Angle<T> {
    type Output = Self;
    fn neg(self) -> Self {
        Angle::radians(-self.radians)
    }
}

impl<T: ApproxEq<T>> ApproxEq<T> for Angle<T> {
    #[inline]
    fn approx_epsilon() -> T {
        T::approx_epsilon()
    }

    #[inline]
    fn approx_eq_eps(&self, other: &Angle<T>, approx_epsilon: &T) -> bool {
        self.radians.approx_eq_eps(&other.radians, approx_epsilon)
    }
}

#[test]
fn wrap_angles() {
    use core::f32::consts::{FRAC_PI_2, PI};

    assert!(Angle::radians(0.0).positive().approx_eq(&Angle::zero()));
    assert!(
        Angle::radians(FRAC_PI_2)
            .positive()
            .approx_eq(&Angle::frac_pi_2())
    );
    assert!(
        Angle::radians(-FRAC_PI_2)
            .positive()
            .approx_eq(&Angle::radians(3.0 * FRAC_PI_2))
    );
    assert!(
        Angle::radians(3.0 * FRAC_PI_2)
            .positive()
            .approx_eq(&Angle::radians(3.0 * FRAC_PI_2))
    );
    assert!(
        Angle::radians(5.0 * FRAC_PI_2)
            .positive()
            .approx_eq(&Angle::frac_pi_2())
    );
    assert!(Angle::radians(2.0 * PI).positive().approx_eq(&Angle::zero()));
    assert!(Angle::radians(-2.0 * PI).positive().approx_eq(&Angle::zero()));
    assert!(Angle::radians(PI).positive().approx_eq(&Angle::pi()));
    assert!(Angle::radians(-PI).positive().approx_eq(&Angle::pi()));

    assert!(
        Angle::radians(FRAC_PI_2)
            .signed()
            .approx_eq(&Angle::frac_pi_2())
    );
    assert!(
        Angle::radians(3.0 * FRAC_PI_2)
            .signed()
            .approx_eq(&-Angle::frac_pi_2())
    );
    assert!(
        Angle::radians(5.0 * FRAC_PI_2)
            .signed()
            .approx_eq(&Angle::frac_pi_2())
    );
    assert!(Angle::radians(2.0 * PI).signed().approx_eq(&Angle::zero()));
    assert!(Angle::radians(-2.0 * PI).signed().approx_eq(&Angle::zero()));
    assert!(Angle::radians(-PI).signed().approx_eq(&Angle::pi()));
    assert!(Angle::radians(PI).signed().approx_eq(&Angle::pi()));
}

#[test]
fn lerp() {
    type A = Angle<f32>;

    let a = A::radians(1.0);
    let b = A::radians(2.0);
    assert!(a.lerp(b, 0.25).approx_eq(&Angle::radians(1.25)));
    assert!(a.lerp(b, 0.5).approx_eq(&Angle::radians(1.5)));
    assert!(a.lerp(b, 0.75).approx_eq(&Angle::radians(1.75)));
    assert!(a.lerp(b + A::two_pi(), 0.75).approx_eq(&Angle::radians(1.75)));
    assert!(a.lerp(b - A::two_pi(), 0.75).approx_eq(&Angle::radians(1.75)));
    assert!(a.lerp(b + A::two_pi() * 5.0, 0.75).approx_eq(&Angle::radians(1.75)));
}
<commit_msg>Derive Default for Angle<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use num_traits::{Float, FloatConst, Zero, One};
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, Sub, SubAssign};
use core::cmp::{Eq, PartialEq};
use core::hash::{Hash};
use crate::trig::Trig;
use crate::approxeq::ApproxEq;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

/// An angle in radians
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Angle<T> {
    pub radians: T,
}

impl<T> Angle<T> {
    #[inline]
    pub fn radians(radians: T) -> Self {
        Angle { radians }
    }

    #[inline]
    pub fn get(self) -> T {
        self.radians
    }
}

impl<T> Angle<T>
where
    T: Trig,
{
    #[inline]
    pub fn degrees(deg: T) -> Self {
        Angle {
            radians: T::degrees_to_radians(deg),
        }
    }

    #[inline]
    pub fn to_degrees(self) -> T {
        T::radians_to_degrees(self.radians)
    }
}

impl<T> Angle<T>
where
    T: Rem<Output = T> + Sub<Output = T> + Add<Output = T> + Zero + FloatConst + PartialOrd + Copy,
{
    /// Returns this angle in the [0..2*PI[ range.
    pub fn positive(&self) -> Self {
        let two_pi = T::PI() + T::PI();
        let mut a = self.radians % two_pi;
        if a < T::zero() {
            a = a + two_pi;
        }
        Angle::radians(a)
    }

    /// Returns this angle in the ]-PI..PI] range.
    pub fn signed(&self) -> Self {
        Angle::pi() - (Angle::pi() - *self).positive()
    }

}

impl<T> Angle<T>
where
    T: Rem<Output = T> + Mul<Output = T> + Sub<Output = T> + Add<Output = T> + One + FloatConst + Copy,
{
    /// Returns the shortest signed angle between two angles.
    ///
    /// Takes wrapping and signs into account.
    pub fn angle_to(&self, to: Self) -> Self {
        let two = T::one() + T::one();
        let max = T::PI() * two;
        let d = (to.radians - self.radians) % max;

        Angle::radians(two * d % max - d)
    }

    /// Linear interpolation between two angles, using the shortest path.
    pub fn lerp(&self, other: Self, t: T) -> Self {
        *self + self.angle_to(other) * t
    }
}

impl<T> Angle<T>
where
    T: Float,
{
    /// Returns (sin(self), cos(self)).
    pub fn sin_cos(self) -> (T, T) {
        self.radians.sin_cos()
    }
}

impl<T> Angle<T>
where
    T: Zero,
{
    pub fn zero() -> Self {
        Angle::radians(T::zero())
    }
}

impl<T> Angle<T>
where
    T: FloatConst + Add<Output = T>,
{
    pub fn pi() -> Self {
        Angle::radians(T::PI())
    }

    pub fn two_pi() -> Self {
        Angle::radians(T::PI() + T::PI())
    }

    pub fn frac_pi_2() -> Self {
        Angle::radians(T::FRAC_PI_2())
    }

    pub fn frac_pi_3() -> Self {
        Angle::radians(T::FRAC_PI_3())
    }

    pub fn frac_pi_4() -> Self {
        Angle::radians(T::FRAC_PI_4())
    }
}

impl<T: Add<T, Output = T>> Add for Angle<T> {
    type Output = Angle<T>;
    fn add(self, other: Angle<T>) -> Angle<T> {
        Angle::radians(self.radians + other.radians)
    }
}

impl<T: AddAssign<T>> AddAssign for Angle<T> {
    fn add_assign(&mut self, other: Angle<T>) {
        self.radians += other.radians;
    }
}

impl<T: Sub<T, Output = T>> Sub<Angle<T>> for Angle<T> {
    type Output = Angle<T>;
    fn sub(self, other: Angle<T>) -> <Self as Sub>::Output {
        Angle::radians(self.radians - other.radians)
    }
}

impl<T: SubAssign<T>> SubAssign for Angle<T> {
    fn sub_assign(&mut self, other: Angle<T>) {
        self.radians -= other.radians;
    }
}

impl<T: Div<T, Output = T>> Div<Angle<T>> for Angle<T> {
    type Output = T;
    #[inline]
    fn div(self, other: Angle<T>) -> T {
        self.radians / other.radians
    }
}

impl<T: Div<T, Output = T>> Div<T> for Angle<T> {
    type Output = Angle<T>;
    #[inline]
    fn div(self, factor: T) -> Angle<T> {
        Angle::radians(self.radians / factor)
    }
}

impl<T: DivAssign<T>> DivAssign<T> for Angle<T> {
    fn div_assign(&mut self, factor: T) {
        self.radians /= factor;
    }
}

impl<T: Mul<T, Output = T>> Mul<T> for Angle<T> {
    type Output = Angle<T>;
    #[inline]
    fn mul(self, factor: T) -> Angle<T> {
        Angle::radians(self.radians * factor)
    }
}

impl<T: MulAssign<T>> MulAssign<T> for Angle<T> {
    fn mul_assign(&mut self, factor: T) {
        self.radians *= factor;
    }
}

impl<T: Neg<Output = T>> Neg for Angle<T> {
    type Output = Self;
    fn neg(self) -> Self {
        Angle::radians(-self.radians)
    }
}

impl<T: ApproxEq<T>> ApproxEq<T> for Angle<T> {
    #[inline]
    fn approx_epsilon() -> T {
        T::approx_epsilon()
    }

    #[inline]
    fn approx_eq_eps(&self, other: &Angle<T>, approx_epsilon: &T) -> bool {
        self.radians.approx_eq_eps(&other.radians, approx_epsilon)
    }
}

#[test]
fn wrap_angles() {
    use core::f32::consts::{FRAC_PI_2, PI};

    assert!(Angle::radians(0.0).positive().approx_eq(&Angle::zero()));
    assert!(
        Angle::radians(FRAC_PI_2)
            .positive()
            .approx_eq(&Angle::frac_pi_2())
    );
    assert!(
        Angle::radians(-FRAC_PI_2)
            .positive()
            .approx_eq(&Angle::radians(3.0 * FRAC_PI_2))
    );
    assert!(
        Angle::radians(3.0 * FRAC_PI_2)
            .positive()
            .approx_eq(&Angle::radians(3.0 * FRAC_PI_2))
    );
    assert!(
        Angle::radians(5.0 * FRAC_PI_2)
            .positive()
            .approx_eq(&Angle::frac_pi_2())
    );
    assert!(Angle::radians(2.0 * PI).positive().approx_eq(&Angle::zero()));
    assert!(Angle::radians(-2.0 * PI).positive().approx_eq(&Angle::zero()));
    assert!(Angle::radians(PI).positive().approx_eq(&Angle::pi()));
    assert!(Angle::radians(-PI).positive().approx_eq(&Angle::pi()));

    assert!(
        Angle::radians(FRAC_PI_2)
            .signed()
            .approx_eq(&Angle::frac_pi_2())
    );
    assert!(
        Angle::radians(3.0 * FRAC_PI_2)
            .signed()
            .approx_eq(&-Angle::frac_pi_2())
    );
    assert!(
        Angle::radians(5.0 * FRAC_PI_2)
            .signed()
            .approx_eq(&Angle::frac_pi_2())
    );
    assert!(Angle::radians(2.0 * PI).signed().approx_eq(&Angle::zero()));
    assert!(Angle::radians(-2.0 * PI).signed().approx_eq(&Angle::zero()));
    assert!(Angle::radians(-PI).signed().approx_eq(&Angle::pi()));
    assert!(Angle::radians(PI).signed().approx_eq(&Angle::pi()));
}

#[test]
fn lerp() {
    type A = Angle<f32>;

    let a = A::radians(1.0);
    let b = A::radians(2.0);
    assert!(a.lerp(b, 0.25).approx_eq(&Angle::radians(1.25)));
    assert!(a.lerp(b, 0.5).approx_eq(&Angle::radians(1.5)));
    assert!(a.lerp(b, 0.75).approx_eq(&Angle::radians(1.75)));
    assert!(a.lerp(b + A::two_pi(), 0.75).approx_eq(&Angle::radians(1.75)));
    assert!(a.lerp(b - A::two_pi(), 0.75).approx_eq(&Angle::radians(1.75)));
    assert!(a.lerp(b + A::two_pi() * 5.0, 0.75).approx_eq(&Angle::radians(1.75)));
}
<|endoftext|>


<commit_before>// Copyright 2013 The OMath Developers. For a full listing of the authors,
// refer to the Cargo.toml 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::mem;
use std::ptr;
use std::ops::*;

use num::PartialOrd;

/// An array containing elements of type `Element`
pub trait Array1 where
    // FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
    Self: Index<usize, Output = <Self as Array1>::Element>,
    Self: IndexMut<usize, Output = <Self as Array1>::Element>,
{
    type Element: Copy;

    /// Get the pointer to the first element of the array.
    fn ptr<'a>(&'a self) -> &'a Self::Element {
        &self[0]
    }

    /// Get a mutable pointer to the first element of the array.
    fn mut_ptr<'a>(&'a mut self) -> &'a mut Self::Element {
        &mut self[0]
    }

    /// Swap the elements at indices `i` and `j` in-place.
    #[inline]
    fn swap_elems(&mut self, i: usize, j: usize) {
        // Yeah, ok borrow checker – I know what I'm doing here
        unsafe { ptr::swap(&mut self[i], &mut self[j]) };
    }

    /// Replace an element in the array.
    #[inline]
    fn replace_elem(&mut self, i: usize, src: Self::Element) -> Self::Element {
        mem::replace(&mut self[i], src)
    }

    /// The sum of the elements of the array.
    fn sum(self) -> Self::Element where Self::Element: Add<Output = <Self as Array1>::Element>;

    /// The product of the elements of the array.
    fn product(self) -> Self::Element where Self::Element: Mul<Output = <Self as Array1>::Element>;

    /// The minimum element of the array.
    fn min(self) -> Self::Element where Self::Element: PartialOrd;

    /// The maximum element of the array.
    fn max(self) -> Self::Element where Self::Element: PartialOrd;
}

/// A column-major array
pub trait Array2 where
    // FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
    Self: Index<usize, Output = <Self as Array2>::Column>,
    Self: IndexMut<usize, Output = <Self as Array2>::Column>,
{
    type Element: Copy;
    type Column: Array1<Element = Self::Element>;
    type Row: Array1<Element = Self::Element>;

    /// Get the pointer to the first element of the array.
    fn ptr<'a>(&'a self) -> &'a Self::Element {
        &self[0][0]
    }

    /// Get a mutable pointer to the first element of the array.
    fn mut_ptr<'a>(&'a mut self) -> &'a mut Self::Element {
        &mut self[0][0]
    }

    /// Swap two columns of this array.
    #[inline]
    fn swap_cols(&mut self, a: usize, b: usize) {
        unsafe { ptr::swap(&mut self[a], &mut self[b]) };
    }

    /// Replace a column in the array.
    #[inline]
    fn replace_col(&mut self, c: usize, src: Self::Column) -> Self::Column {
        mem::replace(&mut self[c], src)
    }

    /// Get a row from this array by-value.
    fn row(&self, r: usize) -> Self::Row;

    /// Swap two rows of this array.
    fn swap_rows(&mut self, a: usize, b: usize);

    /// Swap the values at index `a` and `b`
    #[inline]
    fn swap_elems(&mut self, a: (usize, usize), b: (usize, usize)) {
        let (ac, ar) = a;
        let (bc, br) = b;
        unsafe { ptr::swap(&mut self[ac][ar], &mut self[bc][br]) };
    }
}
<commit_msg>Make pointer access function names match those in std<commit_after>// Copyright 2013 The OMath Developers. For a full listing of the authors,
// refer to the Cargo.toml 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::mem;
use std::ptr;
use std::ops::*;

use num::PartialOrd;

/// An array containing elements of type `Element`
pub trait Array1 where
    // FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
    Self: Index<usize, Output = <Self as Array1>::Element>,
    Self: IndexMut<usize, Output = <Self as Array1>::Element>,
{
    type Element: Copy;

    /// Get the pointer to the first element of the array.
    #[inline]
    fn as_ptr(&self) -> *const Self::Element {
        &self[0]
    }

    /// Get a mutable pointer to the first element of the array.
    #[inline]
    fn as_mut_ptr(&mut self) -> *mut Self::Element {
        &mut self[0]
    }

    /// Swap the elements at indices `i` and `j` in-place.
    #[inline]
    fn swap_elems(&mut self, i: usize, j: usize) {
        // Yeah, ok borrow checker – I know what I'm doing here
        unsafe { ptr::swap(&mut self[i], &mut self[j]) };
    }

    /// Replace an element in the array.
    #[inline]
    fn replace_elem(&mut self, i: usize, src: Self::Element) -> Self::Element {
        mem::replace(&mut self[i], src)
    }

    /// The sum of the elements of the array.
    fn sum(self) -> Self::Element where Self::Element: Add<Output = <Self as Array1>::Element>;

    /// The product of the elements of the array.
    fn product(self) -> Self::Element where Self::Element: Mul<Output = <Self as Array1>::Element>;

    /// The minimum element of the array.
    fn min(self) -> Self::Element where Self::Element: PartialOrd;

    /// The maximum element of the array.
    fn max(self) -> Self::Element where Self::Element: PartialOrd;
}

/// A column-major array
pub trait Array2 where
    // FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
    Self: Index<usize, Output = <Self as Array2>::Column>,
    Self: IndexMut<usize, Output = <Self as Array2>::Column>,
{
    type Element: Copy;
    type Column: Array1<Element = Self::Element>;
    type Row: Array1<Element = Self::Element>;

    /// Get the pointer to the first element of the array.
    #[inline]
    fn as_ptr(&self) -> *const Self::Element {
        &self[0][0]
    }

    /// Get a mutable pointer to the first element of the array.
    #[inline]
    fn as_mut_ptr(&mut self) -> *mut Self::Element {
        &mut self[0][0]
    }

    /// Swap two columns of this array.
    #[inline]
    fn swap_cols(&mut self, a: usize, b: usize) {
        unsafe { ptr::swap(&mut self[a], &mut self[b]) };
    }

    /// Replace a column in the array.
    #[inline]
    fn replace_col(&mut self, c: usize, src: Self::Column) -> Self::Column {
        mem::replace(&mut self[c], src)
    }

    /// Get a row from this array by-value.
    fn row(&self, r: usize) -> Self::Row;

    /// Swap two rows of this array.
    fn swap_rows(&mut self, a: usize, b: usize);

    /// Swap the values at index `a` and `b`
    #[inline]
    fn swap_elems(&mut self, a: (usize, usize), b: (usize, usize)) {
        let (ac, ar) = a;
        let (bc, br) = b;
        unsafe { ptr::swap(&mut self[ac][ar], &mut self[bc][br]) };
    }
}
<|endoftext|>