<commit_before>use crate::simd::intrinsics;
use crate::{LaneCount, Simd, SimdElement, SupportedLaneCount};

/// Rearrange vector elements.
///
/// A new vector is constructed by specifying the the lanes of the source vector or vectors to use.
///
/// When swizzling one vector, the indices of the result vector are indicated by a `const` array
/// of `usize`, like [`Swizzle`].
/// When swizzling two vectors, the indices are indicated by a `const` array of [`Which`], like
/// [`Swizzle2`].
///
/// # Examples
/// ## One source vector
/// ```
/// # #![feature(portable_simd)]
/// # use core_simd::{Simd, simd_swizzle};
/// let v = Simd::<f32, 4>::from_array([0., 1., 2., 3.]);
///
/// // Keeping the same size
/// let r = simd_swizzle!(v, [3, 0, 1, 2]);
/// assert_eq!(r.to_array(), [3., 0., 1., 2.]);
///
/// // Changing the number of lanes
/// let r = simd_swizzle!(v, [3, 1]);
/// assert_eq!(r.to_array(), [3., 1.]);
/// ```
///
/// ## Two source vectors
/// ```
/// # #![feature(portable_simd)]
/// # use core_simd::{Simd, simd_swizzle, Which};
/// use Which::*;
/// let a = Simd::<f32, 4>::from_array([0., 1., 2., 3.]);
/// let b = Simd::<f32, 4>::from_array([4., 5., 6., 7.]);
///
/// // Keeping the same size
/// let r = simd_swizzle!(a, b, [First(0), First(1), Second(2), Second(3)]);
/// assert_eq!(r.to_array(), [0., 1., 6., 7.]);
///
/// // Changing the number of lanes
/// let r = simd_swizzle!(a, b, [First(0), Second(0)]);
/// assert_eq!(r.to_array(), [0., 4.]);
/// ```
#[macro_export]
macro_rules! simd_swizzle {
    {
        $vector:expr, $index:expr $(,)?
    } => {
        {
            use $crate::simd::Swizzle;
            struct SwizzleImpl;
            impl<const LANES: usize> Swizzle<LANES, {$index.len()}> for SwizzleImpl {
                const INDEX: [usize; {$index.len()}] = $index;
            }
            SwizzleImpl::swizzle($vector)
        }
    };
    {
        $first:expr, $second:expr, $index:expr $(,)?
    } => {
        {
            use $crate::simd::{Which, Swizzle2};
            struct SwizzleImpl;
            impl<const LANES: usize> Swizzle2<LANES, {$index.len()}> for SwizzleImpl {
                const INDEX: [Which; {$index.len()}] = $index;
            }
            SwizzleImpl::swizzle2($first, $second)
        }
    }
}

/// An index into one of two vectors.
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Which {
    /// Indexes the first vector.
    First(usize),
    /// Indexes the second vector.
    Second(usize),
}

/// Create a vector from the elements of another vector.
pub trait Swizzle<const INPUT_LANES: usize, const OUTPUT_LANES: usize> {
    /// Map from the lanes of the input vector to the output vector.
    const INDEX: [usize; OUTPUT_LANES];

    /// Create a new vector from the lanes of `vector`.
    ///
    /// Lane `i` of the output is `vector[Self::INDEX[i]]`.
    fn swizzle<T>(vector: Simd<T, INPUT_LANES>) -> Simd<T, OUTPUT_LANES>
    where
        T: SimdElement,
        LaneCount<INPUT_LANES>: SupportedLaneCount,
        LaneCount<OUTPUT_LANES>: SupportedLaneCount,
    {
        unsafe { intrinsics::simd_shuffle(vector, vector, Self::INDEX_IMPL) }
    }
}

/// Create a vector from the elements of two other vectors.
pub trait Swizzle2<const INPUT_LANES: usize, const OUTPUT_LANES: usize> {
    /// Map from the lanes of the input vectors to the output vector
    const INDEX: [Which; OUTPUT_LANES];

    /// Create a new vector from the lanes of `first` and `second`.
    ///
    /// Lane `i` is `first[j]` when `Self::INDEX[i]` is `First(j)`, or `second[j]` when it is
    /// `Second(j)`.
    fn swizzle2<T>(
        first: Simd<T, INPUT_LANES>,
        second: Simd<T, INPUT_LANES>,
    ) -> Simd<T, OUTPUT_LANES>
    where
        T: SimdElement,
        LaneCount<INPUT_LANES>: SupportedLaneCount,
        LaneCount<OUTPUT_LANES>: SupportedLaneCount,
    {
        unsafe { intrinsics::simd_shuffle(first, second, Self::INDEX_IMPL) }
    }
}

/// The `simd_shuffle` intrinsic expects `u32`, so do error checking and conversion here.
trait SwizzleImpl<const INPUT_LANES: usize, const OUTPUT_LANES: usize> {
    const INDEX_IMPL: [u32; OUTPUT_LANES];
}

impl<T, const INPUT_LANES: usize, const OUTPUT_LANES: usize> SwizzleImpl<INPUT_LANES, OUTPUT_LANES>
    for T
where
    T: Swizzle<INPUT_LANES, OUTPUT_LANES> + ?Sized,
{
    const INDEX_IMPL: [u32; OUTPUT_LANES] = {
        let mut output = [0; OUTPUT_LANES];
        let mut i = 0;
        while i < OUTPUT_LANES {
            let index = Self::INDEX[i];
            assert!(index as u32 as usize == index);
            assert!(index < INPUT_LANES, "source lane exceeds input lane count",);
            output[i] = index as u32;
            i += 1;
        }
        output
    };
}

/// The `simd_shuffle` intrinsic expects `u32`, so do error checking and conversion here.
trait Swizzle2Impl<const INPUT_LANES: usize, const OUTPUT_LANES: usize> {
    const INDEX_IMPL: [u32; OUTPUT_LANES];
}

impl<T, const INPUT_LANES: usize, const OUTPUT_LANES: usize> Swizzle2Impl<INPUT_LANES, OUTPUT_LANES>
    for T
where
    T: Swizzle2<INPUT_LANES, OUTPUT_LANES> + ?Sized,
{
    const INDEX_IMPL: [u32; OUTPUT_LANES] = {
        let mut output = [0; OUTPUT_LANES];
        let mut i = 0;
        while i < OUTPUT_LANES {
            let (offset, index) = match Self::INDEX[i] {
                Which::First(index) => (false, index),
                Which::Second(index) => (true, index),
            };
            assert!(index < INPUT_LANES, "source lane exceeds input lane count",);

            // lanes are indexed by the first vector, then second vector
            let index = if offset { index + INPUT_LANES } else { index };
            assert!(index as u32 as usize == index);
            output[i] = index as u32;
            i += 1;
        }
        output
    };
}

impl<T, const LANES: usize> Simd<T, LANES>
where
    T: SimdElement,
    LaneCount<LANES>: SupportedLaneCount,
{
    /// Reverse the order of the lanes in the vector.
    #[inline]
    pub fn reverse(self) -> Self {
        const fn reverse_index<const LANES: usize>() -> [usize; LANES] {
            let mut index = [0; LANES];
            let mut i = 0;
            while i < LANES {
                index[i] = LANES - i - 1;
                i += 1;
            }
            index
        }

        struct Reverse;

        impl<const LANES: usize> Swizzle<LANES, LANES> for Reverse {
            const INDEX: [usize; LANES] = reverse_index::<LANES>();
        }

        Reverse::swizzle(self)
    }

    /// Rotates the vector such that the first `OFFSET` elements of the slice move to the end
    /// while the last `LANES - OFFSET` elements move to the front. After calling `rotate_left`, the
    /// element previously in lane `OFFSET` will become the first element in the slice.
    #[inline]
    pub fn rotate_left<const OFFSET: usize>(self) -> Self {
        const fn rotate_index<const OFFSET: usize, const LANES: usize>() -> [usize; LANES] {
            let offset = OFFSET % LANES;
            let mut index = [0; LANES];
            let mut i = 0;
            while i < LANES {
                index[i] = (i + offset) % LANES;
                i += 1;
            }
            index
        }

        struct Rotate<const OFFSET: usize>;

        impl<const OFFSET: usize, const LANES: usize> Swizzle<LANES, LANES> for Rotate<OFFSET> {
            const INDEX: [usize; LANES] = rotate_index::<OFFSET, LANES>();
        }

        Rotate::<OFFSET>::swizzle(self)
    }

    /// Rotates the vector such that the first `LANES - OFFSET` elements of the vector move to
    /// the end while the last `OFFSET` elements move to the front. After calling `rotate_right`, the
    /// element previously at index `LANES - OFFSET` will become the first element in the slice.
    #[inline]
    pub fn rotate_right<const OFFSET: usize>(self) -> Self {
        const fn rotate_index<const OFFSET: usize, const LANES: usize>() -> [usize; LANES] {
            let offset = LANES - OFFSET % LANES;
            let mut index = [0; LANES];
            let mut i = 0;
            while i < LANES {
                index[i] = (i + offset) % LANES;
                i += 1;
            }
            index
        }

        struct Rotate<const OFFSET: usize>;

        impl<const OFFSET: usize, const LANES: usize> Swizzle<LANES, LANES> for Rotate<OFFSET> {
            const INDEX: [usize; LANES] = rotate_index::<OFFSET, LANES>();
        }

        Rotate::<OFFSET>::swizzle(self)
    }

    /// Interleave two vectors.
    ///
    /// Produces two vectors with lanes taken alternately from `self` and `other`.
    ///
    /// The first result contains the first `LANES / 2` lanes from `self` and `other`,
    /// alternating, starting with the first lane of `self`.
    ///
    /// The second result contains the last `LANES / 2` lanes from `self` and `other`,
    /// alternating, starting with the lane `LANES / 2` from the start of `self`.
    ///
    /// This particular permutation is efficient on many architectures.
    ///
    /// ```
    /// #![feature(portable_simd)]
    /// # use core_simd::Simd;
    /// let a = Simd::from_array([0, 1, 2, 3]);
    /// let b = Simd::from_array([4, 5, 6, 7]);
    /// let (x, y) = a.interleave(b);
    /// assert_eq!(x.to_array(), [0, 4, 1, 5]);
    /// assert_eq!(y.to_array(), [2, 6, 3, 7]);
    /// ```
    #[inline]
    pub fn interleave(self, other: Self) -> (Self, Self) {
        const fn lo<const LANES: usize>() -> [Which; LANES] {
            let mut idx = [Which::First(0); LANES];
            let mut i = 0;
            while i < LANES {
                let offset = i / 2;
                idx[i] = if i % 2 == 0 {
                    Which::First(offset)
                } else {
                    Which::Second(offset)
                };
                i += 1;
            }
            idx
        }
        const fn hi<const LANES: usize>() -> [Which; LANES] {
            let mut idx = [Which::First(0); LANES];
            let mut i = 0;
            while i < LANES {
                let offset = (LANES + i) / 2;
                idx[i] = if i % 2 == 0 {
                    Which::First(offset)
                } else {
                    Which::Second(offset)
                };
                i += 1;
            }
            idx
        }

        struct Lo;
        struct Hi;

        impl<const LANES: usize> Swizzle2<LANES, LANES> for Lo {
            const INDEX: [Which; LANES] = lo::<LANES>();
        }

        impl<const LANES: usize> Swizzle2<LANES, LANES> for Hi {
            const INDEX: [Which; LANES] = hi::<LANES>();
        }

        (Lo::swizzle2(self, other), Hi::swizzle2(self, other))
    }

    /// Deinterleave two vectors.
    ///
    /// The first result takes every other lane of `self` and then `other`, starting with
    /// the first lane.
    ///
    /// The second result takes every other lane of `self` and then `other`, starting with
    /// the second lane.
    ///
    /// This particular permutation is efficient on many architectures.
    ///
    /// ```
    /// #![feature(portable_simd)]
    /// # use core_simd::Simd;
    /// let a = Simd::from_array([0, 4, 1, 5]);
    /// let b = Simd::from_array([2, 6, 3, 7]);
    /// let (x, y) = a.deinterleave(b);
    /// assert_eq!(x.to_array(), [0, 1, 2, 3]);
    /// assert_eq!(y.to_array(), [4, 5, 6, 7]);
    /// ```
    #[inline]
    pub fn deinterleave(self, other: Self) -> (Self, Self) {
        const fn even<const LANES: usize>() -> [Which; LANES] {
            let mut idx = [Which::First(0); LANES];
            let mut i = 0;
            while i < LANES / 2 {
                idx[i] = Which::First(2 * i);
                idx[i + LANES / 2] = Which::Second(2 * i);
                i += 1;
            }
            idx
        }
        const fn odd<const LANES: usize>() -> [Which; LANES] {
            let mut idx = [Which::First(0); LANES];
            let mut i = 0;
            while i < LANES / 2 {
                idx[i] = Which::First(2 * i + 1);
                idx[i + LANES / 2] = Which::Second(2 * i + 1);
                i += 1;
            }
            idx
        }

        struct Even;
        struct Odd;

        impl<const LANES: usize> Swizzle2<LANES, LANES> for Even {
            const INDEX: [Which; LANES] = even::<LANES>();
        }

        impl<const LANES: usize> Swizzle2<LANES, LANES> for Odd {
            const INDEX: [Which; LANES] = odd::<LANES>();
        }

        (Even::swizzle2(self, other), Odd::swizzle2(self, other))
    }
}
<commit_msg>Update crates/core_simd/src/swizzle.rs<commit_after>use crate::simd::intrinsics;
use crate::{LaneCount, Simd, SimdElement, SupportedLaneCount};

/// Constructs a new vector by selecting values from the lanes of the source vector or vectors to use.
///
/// When swizzling one vector, the indices of the result vector are indicated by a `const` array
/// of `usize`, like [`Swizzle`].
/// When swizzling two vectors, the indices are indicated by a `const` array of [`Which`], like
/// [`Swizzle2`].
///
/// # Examples
/// ## One source vector
/// ```
/// # #![feature(portable_simd)]
/// # use core_simd::{Simd, simd_swizzle};
/// let v = Simd::<f32, 4>::from_array([0., 1., 2., 3.]);
///
/// // Keeping the same size
/// let r = simd_swizzle!(v, [3, 0, 1, 2]);
/// assert_eq!(r.to_array(), [3., 0., 1., 2.]);
///
/// // Changing the number of lanes
/// let r = simd_swizzle!(v, [3, 1]);
/// assert_eq!(r.to_array(), [3., 1.]);
/// ```
///
/// ## Two source vectors
/// ```
/// # #![feature(portable_simd)]
/// # use core_simd::{Simd, simd_swizzle, Which};
/// use Which::*;
/// let a = Simd::<f32, 4>::from_array([0., 1., 2., 3.]);
/// let b = Simd::<f32, 4>::from_array([4., 5., 6., 7.]);
///
/// // Keeping the same size
/// let r = simd_swizzle!(a, b, [First(0), First(1), Second(2), Second(3)]);
/// assert_eq!(r.to_array(), [0., 1., 6., 7.]);
///
/// // Changing the number of lanes
/// let r = simd_swizzle!(a, b, [First(0), Second(0)]);
/// assert_eq!(r.to_array(), [0., 4.]);
/// ```
#[macro_export]
macro_rules! simd_swizzle {
    {
        $vector:expr, $index:expr $(,)?
    } => {
        {
            use $crate::simd::Swizzle;
            struct SwizzleImpl;
            impl<const LANES: usize> Swizzle<LANES, {$index.len()}> for SwizzleImpl {
                const INDEX: [usize; {$index.len()}] = $index;
            }
            SwizzleImpl::swizzle($vector)
        }
    };
    {
        $first:expr, $second:expr, $index:expr $(,)?
    } => {
        {
            use $crate::simd::{Which, Swizzle2};
            struct SwizzleImpl;
            impl<const LANES: usize> Swizzle2<LANES, {$index.len()}> for SwizzleImpl {
                const INDEX: [Which; {$index.len()}] = $index;
            }
            SwizzleImpl::swizzle2($first, $second)
        }
    }
}

/// An index into one of two vectors.
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Which {
    /// Indexes the first vector.
    First(usize),
    /// Indexes the second vector.
    Second(usize),
}

/// Create a vector from the elements of another vector.
pub trait Swizzle<const INPUT_LANES: usize, const OUTPUT_LANES: usize> {
    /// Map from the lanes of the input vector to the output vector.
    const INDEX: [usize; OUTPUT_LANES];

    /// Create a new vector from the lanes of `vector`.
    ///
    /// Lane `i` of the output is `vector[Self::INDEX[i]]`.
    fn swizzle<T>(vector: Simd<T, INPUT_LANES>) -> Simd<T, OUTPUT_LANES>
    where
        T: SimdElement,
        LaneCount<INPUT_LANES>: SupportedLaneCount,
        LaneCount<OUTPUT_LANES>: SupportedLaneCount,
    {
        unsafe { intrinsics::simd_shuffle(vector, vector, Self::INDEX_IMPL) }
    }
}

/// Create a vector from the elements of two other vectors.
pub trait Swizzle2<const INPUT_LANES: usize, const OUTPUT_LANES: usize> {
    /// Map from the lanes of the input vectors to the output vector
    const INDEX: [Which; OUTPUT_LANES];

    /// Create a new vector from the lanes of `first` and `second`.
    ///
    /// Lane `i` is `first[j]` when `Self::INDEX[i]` is `First(j)`, or `second[j]` when it is
    /// `Second(j)`.
    fn swizzle2<T>(
        first: Simd<T, INPUT_LANES>,
        second: Simd<T, INPUT_LANES>,
    ) -> Simd<T, OUTPUT_LANES>
    where
        T: SimdElement,
        LaneCount<INPUT_LANES>: SupportedLaneCount,
        LaneCount<OUTPUT_LANES>: SupportedLaneCount,
    {
        unsafe { intrinsics::simd_shuffle(first, second, Self::INDEX_IMPL) }
    }
}

/// The `simd_shuffle` intrinsic expects `u32`, so do error checking and conversion here.
trait SwizzleImpl<const INPUT_LANES: usize, const OUTPUT_LANES: usize> {
    const INDEX_IMPL: [u32; OUTPUT_LANES];
}

impl<T, const INPUT_LANES: usize, const OUTPUT_LANES: usize> SwizzleImpl<INPUT_LANES, OUTPUT_LANES>
    for T
where
    T: Swizzle<INPUT_LANES, OUTPUT_LANES> + ?Sized,
{
    const INDEX_IMPL: [u32; OUTPUT_LANES] = {
        let mut output = [0; OUTPUT_LANES];
        let mut i = 0;
        while i < OUTPUT_LANES {
            let index = Self::INDEX[i];
            assert!(index as u32 as usize == index);
            assert!(index < INPUT_LANES, "source lane exceeds input lane count",);
            output[i] = index as u32;
            i += 1;
        }
        output
    };
}

/// The `simd_shuffle` intrinsic expects `u32`, so do error checking and conversion here.
trait Swizzle2Impl<const INPUT_LANES: usize, const OUTPUT_LANES: usize> {
    const INDEX_IMPL: [u32; OUTPUT_LANES];
}

impl<T, const INPUT_LANES: usize, const OUTPUT_LANES: usize> Swizzle2Impl<INPUT_LANES, OUTPUT_LANES>
    for T
where
    T: Swizzle2<INPUT_LANES, OUTPUT_LANES> + ?Sized,
{
    const INDEX_IMPL: [u32; OUTPUT_LANES] = {
        let mut output = [0; OUTPUT_LANES];
        let mut i = 0;
        while i < OUTPUT_LANES {
            let (offset, index) = match Self::INDEX[i] {
                Which::First(index) => (false, index),
                Which::Second(index) => (true, index),
            };
            assert!(index < INPUT_LANES, "source lane exceeds input lane count",);

            // lanes are indexed by the first vector, then second vector
            let index = if offset { index + INPUT_LANES } else { index };
            assert!(index as u32 as usize == index);
            output[i] = index as u32;
            i += 1;
        }
        output
    };
}

impl<T, const LANES: usize> Simd<T, LANES>
where
    T: SimdElement,
    LaneCount<LANES>: SupportedLaneCount,
{
    /// Reverse the order of the lanes in the vector.
    #[inline]
    pub fn reverse(self) -> Self {
        const fn reverse_index<const LANES: usize>() -> [usize; LANES] {
            let mut index = [0; LANES];
            let mut i = 0;
            while i < LANES {
                index[i] = LANES - i - 1;
                i += 1;
            }
            index
        }

        struct Reverse;

        impl<const LANES: usize> Swizzle<LANES, LANES> for Reverse {
            const INDEX: [usize; LANES] = reverse_index::<LANES>();
        }

        Reverse::swizzle(self)
    }

    /// Rotates the vector such that the first `OFFSET` elements of the slice move to the end
    /// while the last `LANES - OFFSET` elements move to the front. After calling `rotate_left`, the
    /// element previously in lane `OFFSET` will become the first element in the slice.
    #[inline]
    pub fn rotate_left<const OFFSET: usize>(self) -> Self {
        const fn rotate_index<const OFFSET: usize, const LANES: usize>() -> [usize; LANES] {
            let offset = OFFSET % LANES;
            let mut index = [0; LANES];
            let mut i = 0;
            while i < LANES {
                index[i] = (i + offset) % LANES;
                i += 1;
            }
            index
        }

        struct Rotate<const OFFSET: usize>;

        impl<const OFFSET: usize, const LANES: usize> Swizzle<LANES, LANES> for Rotate<OFFSET> {
            const INDEX: [usize; LANES] = rotate_index::<OFFSET, LANES>();
        }

        Rotate::<OFFSET>::swizzle(self)
    }

    /// Rotates the vector such that the first `LANES - OFFSET` elements of the vector move to
    /// the end while the last `OFFSET` elements move to the front. After calling `rotate_right`, the
    /// element previously at index `LANES - OFFSET` will become the first element in the slice.
    #[inline]
    pub fn rotate_right<const OFFSET: usize>(self) -> Self {
        const fn rotate_index<const OFFSET: usize, const LANES: usize>() -> [usize; LANES] {
            let offset = LANES - OFFSET % LANES;
            let mut index = [0; LANES];
            let mut i = 0;
            while i < LANES {
                index[i] = (i + offset) % LANES;
                i += 1;
            }
            index
        }

        struct Rotate<const OFFSET: usize>;

        impl<const OFFSET: usize, const LANES: usize> Swizzle<LANES, LANES> for Rotate<OFFSET> {
            const INDEX: [usize; LANES] = rotate_index::<OFFSET, LANES>();
        }

        Rotate::<OFFSET>::swizzle(self)
    }

    /// Interleave two vectors.
    ///
    /// Produces two vectors with lanes taken alternately from `self` and `other`.
    ///
    /// The first result contains the first `LANES / 2` lanes from `self` and `other`,
    /// alternating, starting with the first lane of `self`.
    ///
    /// The second result contains the last `LANES / 2` lanes from `self` and `other`,
    /// alternating, starting with the lane `LANES / 2` from the start of `self`.
    ///
    /// This particular permutation is efficient on many architectures.
    ///
    /// ```
    /// #![feature(portable_simd)]
    /// # use core_simd::Simd;
    /// let a = Simd::from_array([0, 1, 2, 3]);
    /// let b = Simd::from_array([4, 5, 6, 7]);
    /// let (x, y) = a.interleave(b);
    /// assert_eq!(x.to_array(), [0, 4, 1, 5]);
    /// assert_eq!(y.to_array(), [2, 6, 3, 7]);
    /// ```
    #[inline]
    pub fn interleave(self, other: Self) -> (Self, Self) {
        const fn lo<const LANES: usize>() -> [Which; LANES] {
            let mut idx = [Which::First(0); LANES];
            let mut i = 0;
            while i < LANES {
                let offset = i / 2;
                idx[i] = if i % 2 == 0 {
                    Which::First(offset)
                } else {
                    Which::Second(offset)
                };
                i += 1;
            }
            idx
        }
        const fn hi<const LANES: usize>() -> [Which; LANES] {
            let mut idx = [Which::First(0); LANES];
            let mut i = 0;
            while i < LANES {
                let offset = (LANES + i) / 2;
                idx[i] = if i % 2 == 0 {
                    Which::First(offset)
                } else {
                    Which::Second(offset)
                };
                i += 1;
            }
            idx
        }

        struct Lo;
        struct Hi;

        impl<const LANES: usize> Swizzle2<LANES, LANES> for Lo {
            const INDEX: [Which; LANES] = lo::<LANES>();
        }

        impl<const LANES: usize> Swizzle2<LANES, LANES> for Hi {
            const INDEX: [Which; LANES] = hi::<LANES>();
        }

        (Lo::swizzle2(self, other), Hi::swizzle2(self, other))
    }

    /// Deinterleave two vectors.
    ///
    /// The first result takes every other lane of `self` and then `other`, starting with
    /// the first lane.
    ///
    /// The second result takes every other lane of `self` and then `other`, starting with
    /// the second lane.
    ///
    /// This particular permutation is efficient on many architectures.
    ///
    /// ```
    /// #![feature(portable_simd)]
    /// # use core_simd::Simd;
    /// let a = Simd::from_array([0, 4, 1, 5]);
    /// let b = Simd::from_array([2, 6, 3, 7]);
    /// let (x, y) = a.deinterleave(b);
    /// assert_eq!(x.to_array(), [0, 1, 2, 3]);
    /// assert_eq!(y.to_array(), [4, 5, 6, 7]);
    /// ```
    #[inline]
    pub fn deinterleave(self, other: Self) -> (Self, Self) {
        const fn even<const LANES: usize>() -> [Which; LANES] {
            let mut idx = [Which::First(0); LANES];
            let mut i = 0;
            while i < LANES / 2 {
                idx[i] = Which::First(2 * i);
                idx[i + LANES / 2] = Which::Second(2 * i);
                i += 1;
            }
            idx
        }
        const fn odd<const LANES: usize>() -> [Which; LANES] {
            let mut idx = [Which::First(0); LANES];
            let mut i = 0;
            while i < LANES / 2 {
                idx[i] = Which::First(2 * i + 1);
                idx[i + LANES / 2] = Which::Second(2 * i + 1);
                i += 1;
            }
            idx
        }

        struct Even;
        struct Odd;

        impl<const LANES: usize> Swizzle2<LANES, LANES> for Even {
            const INDEX: [Which; LANES] = even::<LANES>();
        }

        impl<const LANES: usize> Swizzle2<LANES, LANES> for Odd {
            const INDEX: [Which; LANES] = odd::<LANES>();
        }

        (Even::swizzle2(self, other), Odd::swizzle2(self, other))
    }
}
<|endoftext|>


<commit_before>use std::sync::Arc;

use ra_syntax::{
    ast::{self, NameOwner},
    SmolStr,
};
use relative_path::RelativePathBuf;
use rustc_hash::{FxHashMap, FxHashSet};
use ra_db::{SourceRoot, SourceRootId, FileResolverImp, Cancelable, FileId,};

use crate::{
    HirDatabase,
};

use super::{
    LinkData, LinkId, ModuleData, ModuleId, ModuleSource,
    ModuleTree, Problem,
};

#[derive(Clone, Hash, PartialEq, Eq, Debug)]
pub enum Submodule {
    Declaration(SmolStr),
    Definition(SmolStr, ModuleSource),
}

impl Submodule {
    fn name(&self) -> &SmolStr {
        match self {
            Submodule::Declaration(name) => name,
            Submodule::Definition(name, _) => name,
        }
    }
}

pub(crate) fn modules<'a>(
    root: impl ast::ModuleItemOwner<'a>,
) -> impl Iterator<Item = (SmolStr, ast::Module<'a>)> {
    root.items()
        .filter_map(|item| match item {
            ast::ModuleItem::Module(m) => Some(m),
            _ => None,
        })
        .filter_map(|module| {
            let name = module.name()?.text();
            Some((name, module))
        })
}

pub(crate) fn module_tree(
    db: &impl HirDatabase,
    source_root: SourceRootId,
) -> Cancelable<Arc<ModuleTree>> {
    db.check_canceled()?;
    let res = create_module_tree(db, source_root)?;
    Ok(Arc::new(res))
}

fn create_module_tree<'a>(
    db: &impl HirDatabase,
    source_root: SourceRootId,
) -> Cancelable<ModuleTree> {
    let mut tree = ModuleTree::default();

    let mut roots = FxHashMap::default();
    let mut visited = FxHashSet::default();

    let source_root = db.source_root(source_root);
    for &file_id in source_root.files.iter() {
        let source = ModuleSource::new_file(db, file_id);
        if visited.contains(&source) {
            continue; // TODO: use explicit crate_roots here
        }
        assert!(!roots.contains_key(&file_id));
        let module_id = build_subtree(
            db,
            &source_root,
            &mut tree,
            &mut visited,
            &mut roots,
            None,
            source,
        )?;
        roots.insert(file_id, module_id);
    }
    Ok(tree)
}

fn build_subtree(
    db: &impl HirDatabase,
    source_root: &SourceRoot,
    tree: &mut ModuleTree,
    visited: &mut FxHashSet<ModuleSource>,
    roots: &mut FxHashMap<FileId, ModuleId>,
    parent: Option<LinkId>,
    source: ModuleSource,
) -> Cancelable<ModuleId> {
    visited.insert(source);
    let id = tree.push_mod(ModuleData {
        source,
        parent,
        children: Vec::new(),
    });
    for sub in db.submodules(source)?.iter() {
        let link = tree.push_link(LinkData {
            name: sub.name().clone(),
            owner: id,
            points_to: Vec::new(),
            problem: None,
        });

        let (points_to, problem) = match sub {
            Submodule::Declaration(name) => {
                let (points_to, problem) =
                    resolve_submodule(source, &name, &source_root.file_resolver);
                let points_to = points_to
                    .into_iter()
                    .map(|file_id| match roots.remove(&file_id) {
                        Some(module_id) => {
                            tree.mods[module_id].parent = Some(link);
                            Ok(module_id)
                        }
                        None => build_subtree(
                            db,
                            source_root,
                            tree,
                            visited,
                            roots,
                            Some(link),
                            ModuleSource::new_file(db, file_id),
                        ),
                    })
                    .collect::<Cancelable<Vec<_>>>()?;
                (points_to, problem)
            }
            Submodule::Definition(_name, submodule_source) => {
                let points_to = build_subtree(
                    db,
                    source_root,
                    tree,
                    visited,
                    roots,
                    Some(link),
                    *submodule_source,
                )?;
                (vec![points_to], None)
            }
        };

        tree.links[link].points_to = points_to;
        tree.links[link].problem = problem;
    }
    Ok(id)
}

fn resolve_submodule(
    source: ModuleSource,
    name: &SmolStr,
    file_resolver: &FileResolverImp,
) -> (Vec<FileId>, Option<Problem>) {
    // TODO: handle submodules of inline modules properly
    let file_id = source.file_id();
    let mod_name = file_resolver.file_stem(file_id);
    let is_dir_owner = mod_name == "mod" || mod_name == "lib" || mod_name == "main";

    let file_mod = RelativePathBuf::from(format!("../{}.rs", name));
    let dir_mod = RelativePathBuf::from(format!("../{}/mod.rs", name));
    let points_to: Vec<FileId>;
    let problem: Option<Problem>;
    if is_dir_owner {
        points_to = [&file_mod, &dir_mod]
            .iter()
            .filter_map(|path| file_resolver.resolve(file_id, path))
            .collect();
        problem = if points_to.is_empty() {
            Some(Problem::UnresolvedModule {
                candidate: file_mod,
            })
        } else {
            None
        }
    } else {
        points_to = Vec::new();
        problem = Some(Problem::NotDirOwner {
            move_to: RelativePathBuf::from(format!("../{}/mod.rs", mod_name)),
            candidate: file_mod,
        });
    }
    (points_to, problem)
}
<commit_msg>resolve 2018 style modules<commit_after>use std::sync::Arc;

use ra_syntax::{
    ast::{self, NameOwner},
    SmolStr,
};
use relative_path::RelativePathBuf;
use rustc_hash::{FxHashMap, FxHashSet};
use ra_db::{SourceRoot, SourceRootId, FileResolverImp, Cancelable, FileId,};

use crate::{
    HirDatabase,
};

use super::{
    LinkData, LinkId, ModuleData, ModuleId, ModuleSource,
    ModuleTree, Problem,
};

#[derive(Clone, Hash, PartialEq, Eq, Debug)]
pub enum Submodule {
    Declaration(SmolStr),
    Definition(SmolStr, ModuleSource),
}

impl Submodule {
    fn name(&self) -> &SmolStr {
        match self {
            Submodule::Declaration(name) => name,
            Submodule::Definition(name, _) => name,
        }
    }
}

pub(crate) fn modules<'a>(
    root: impl ast::ModuleItemOwner<'a>,
) -> impl Iterator<Item = (SmolStr, ast::Module<'a>)> {
    root.items()
        .filter_map(|item| match item {
            ast::ModuleItem::Module(m) => Some(m),
            _ => None,
        })
        .filter_map(|module| {
            let name = module.name()?.text();
            Some((name, module))
        })
}

pub(crate) fn module_tree(
    db: &impl HirDatabase,
    source_root: SourceRootId,
) -> Cancelable<Arc<ModuleTree>> {
    db.check_canceled()?;
    let res = create_module_tree(db, source_root)?;
    Ok(Arc::new(res))
}

fn create_module_tree<'a>(
    db: &impl HirDatabase,
    source_root: SourceRootId,
) -> Cancelable<ModuleTree> {
    let mut tree = ModuleTree::default();

    let mut roots = FxHashMap::default();
    let mut visited = FxHashSet::default();

    let source_root = db.source_root(source_root);
    for &file_id in source_root.files.iter() {
        let source = ModuleSource::new_file(db, file_id);
        if visited.contains(&source) {
            continue; // TODO: use explicit crate_roots here
        }
        assert!(!roots.contains_key(&file_id));
        let module_id = build_subtree(
            db,
            &source_root,
            &mut tree,
            &mut visited,
            &mut roots,
            None,
            source,
        )?;
        roots.insert(file_id, module_id);
    }
    Ok(tree)
}

fn build_subtree(
    db: &impl HirDatabase,
    source_root: &SourceRoot,
    tree: &mut ModuleTree,
    visited: &mut FxHashSet<ModuleSource>,
    roots: &mut FxHashMap<FileId, ModuleId>,
    parent: Option<LinkId>,
    source: ModuleSource,
) -> Cancelable<ModuleId> {
    visited.insert(source);
    let id = tree.push_mod(ModuleData {
        source,
        parent,
        children: Vec::new(),
    });
    for sub in db.submodules(source)?.iter() {
        let link = tree.push_link(LinkData {
            name: sub.name().clone(),
            owner: id,
            points_to: Vec::new(),
            problem: None,
        });

        let (points_to, problem) = match sub {
            Submodule::Declaration(name) => {
                let (points_to, problem) =
                    resolve_submodule(source, &name, &source_root.file_resolver);
                let points_to = points_to
                    .into_iter()
                    .map(|file_id| match roots.remove(&file_id) {
                        Some(module_id) => {
                            tree.mods[module_id].parent = Some(link);
                            Ok(module_id)
                        }
                        None => build_subtree(
                            db,
                            source_root,
                            tree,
                            visited,
                            roots,
                            Some(link),
                            ModuleSource::new_file(db, file_id),
                        ),
                    })
                    .collect::<Cancelable<Vec<_>>>()?;
                (points_to, problem)
            }
            Submodule::Definition(_name, submodule_source) => {
                let points_to = build_subtree(
                    db,
                    source_root,
                    tree,
                    visited,
                    roots,
                    Some(link),
                    *submodule_source,
                )?;
                (vec![points_to], None)
            }
        };

        tree.links[link].points_to = points_to;
        tree.links[link].problem = problem;
    }
    Ok(id)
}

fn resolve_submodule(
    source: ModuleSource,
    name: &SmolStr,
    file_resolver: &FileResolverImp,
) -> (Vec<FileId>, Option<Problem>) {
    // TODO: handle submodules of inline modules properly
    let file_id = source.file_id();
    let mod_name = file_resolver.file_stem(file_id);
    let is_dir_owner = mod_name == "mod" || mod_name == "lib" || mod_name == "main";

    let file_mod = RelativePathBuf::from(format!("../{}.rs", name));
    let dir_mod = RelativePathBuf::from(format!("../{}/mod.rs", name));
    let file_dir_mod = RelativePathBuf::from(format!("../{}/{}.rs", mod_name, name));
    let tmp1;
    let tmp2;
    let candidates = if is_dir_owner {
        tmp1 = [&file_mod, &dir_mod];
        tmp1.iter()
    } else {
        tmp2 = [&file_dir_mod];
        tmp2.iter()
    };

    let points_to = candidates
        .filter_map(|path| file_resolver.resolve(file_id, path))
        .collect::<Vec<_>>();
    let problem = if points_to.is_empty() {
        Some(Problem::UnresolvedModule {
            candidate: if is_dir_owner { file_mod } else { file_dir_mod },
        })
    } else {
        None
    };
    (points_to, problem)
}
<|endoftext|>


<commit_before>/// This module parses a raw `tt::TokenStream` into macro-by-example token
/// stream. This is a *mostly* identify function, expect for handling of
/// `$var:tt_kind` and `$(repeat),*` constructs.
use crate::ParseError;
use crate::tt_cursor::TtCursor;

pub(crate) fn parse(tt: &tt::Subtree) -> Result<crate::MacroRules, ParseError> {
    let mut parser = TtCursor::new(tt);
    let mut rules = Vec::new();
    while !parser.is_eof() {
        rules.push(parse_rule(&mut parser)?);
        if let Err(e) = parser.expect_char(';') {
            if !parser.is_eof() {
                return Err(e);
            }
            break;
        }
    }
    Ok(crate::MacroRules { rules })
}

fn parse_rule(p: &mut TtCursor) -> Result<crate::Rule, ParseError> {
    let lhs = parse_subtree(p.eat_subtree()?, false)?;
    p.expect_char('=')?;
    p.expect_char('>')?;
    let mut rhs = parse_subtree(p.eat_subtree()?, true)?;
    rhs.delimiter = crate::Delimiter::None;
    Ok(crate::Rule { lhs, rhs })
}

fn parse_subtree(tt: &tt::Subtree, transcriber: bool) -> Result<crate::Subtree, ParseError> {
    let mut token_trees = Vec::new();
    let mut p = TtCursor::new(tt);
    while let Some(tt) = p.eat() {
        let child: crate::TokenTree = match tt {
            tt::TokenTree::Leaf(leaf) => match leaf {
                tt::Leaf::Punct(tt::Punct { char: '$', spacing }) => {
                    if p.at_ident().is_some() {
                        crate::Leaf::from(parse_var(&mut p, transcriber)?).into()
                    } else if let Some(tt::TokenTree::Subtree(_)) = p.current() {
                        parse_repeat(&mut p, transcriber)?.into()
                    } else {
                        // Treat it as normal punct
                        crate::Leaf::from(tt::Punct { char: '$', spacing: *spacing }).into()
                    }
                }
                tt::Leaf::Punct(punct) => crate::Leaf::from(*punct).into(),
                tt::Leaf::Ident(tt::Ident { text, id: _ }) => {
                    crate::Leaf::from(crate::Ident { text: text.clone() }).into()
                }
                tt::Leaf::Literal(tt::Literal { text }) => {
                    crate::Leaf::from(crate::Literal { text: text.clone() }).into()
                }
            },
            tt::TokenTree::Subtree(subtree) => parse_subtree(&subtree, transcriber)?.into(),
        };
        token_trees.push(child);
    }
    Ok(crate::Subtree { token_trees, delimiter: tt.delimiter })
}

fn parse_var(p: &mut TtCursor, transcriber: bool) -> Result<crate::Var, ParseError> {
    let ident = p.eat_ident().unwrap();
    let text = ident.text.clone();
    let kind = if !transcriber && p.at_char(':') {
        p.bump();
        if let Some(ident) = p.eat_ident() {
            Some(ident.text.clone())
        } else {
            p.rev_bump();
            None
        }
    } else {
        None
    };

    Ok(crate::Var { text, kind })
}

fn mk_repeat(
    rep: char,
    subtree: crate::Subtree,
    separator: Option<crate::Separator>,
) -> Result<crate::Repeat, ParseError> {
    let kind = match rep {
        '*' => crate::RepeatKind::ZeroOrMore,
        '+' => crate::RepeatKind::OneOrMore,
        '?' => crate::RepeatKind::ZeroOrOne,
        _ => return Err(ParseError::Expected(String::from("repeat"))),
    };
    Ok(crate::Repeat { subtree, kind, separator })
}

fn parse_repeat(p: &mut TtCursor, transcriber: bool) -> Result<crate::Repeat, ParseError> {
    let subtree = p.eat_subtree()?;
    let mut subtree = parse_subtree(subtree, transcriber)?;
    subtree.delimiter = crate::Delimiter::None;

    if let Some(rep) = p.at_punct() {
        match rep.char {
            '*' | '+' | '?' => {
                p.bump();
                return mk_repeat(rep.char, subtree, None);
            }
            _ => {}
        }
    }

    let sep = p.eat_seperator().ok_or(ParseError::Expected(String::from("separator")))?;
    let rep = p.eat_punct().ok_or(ParseError::Expected(String::from("repeat")))?;

    mk_repeat(rep.char, subtree, Some(sep))
}

#[cfg(test)]
mod tests {
    use ra_syntax::{ast, AstNode};

    use super::*;
    use crate::ast_to_token_tree;

    #[test]
    fn test_invalid_parse() {
        expect_err("invalid", "subtree");

        is_valid("($i:ident) => ()");
        expect_err("$i:ident => ()", "subtree");
        expect_err("($i:ident) ()", "`=`");
        expect_err("($($i:ident)_) => ()", "repeat");
    }

    fn expect_err(macro_body: &str, expected: &str) {
        assert_eq!(
            create_rules(&format_macro(macro_body)),
            Err(ParseError::Expected(String::from(expected)))
        );
    }

    fn is_valid(macro_body: &str) {
        assert!(create_rules(&format_macro(macro_body)).is_ok());
    }

    fn format_macro(macro_body: &str) -> String {
        format!(
            "
        macro_rules! foo {{
            {}
        }}
",
            macro_body
        )
    }

    fn create_rules(macro_definition: &str) -> Result<crate::MacroRules, ParseError> {
        let source_file = ast::SourceFile::parse(macro_definition);
        let macro_definition =
            source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();

        let (definition_tt, _) = ast_to_token_tree(macro_definition.token_tree().unwrap()).unwrap();
        parse(&definition_tt)
    }

}
<commit_msg>Add test<commit_after>/// This module parses a raw `tt::TokenStream` into macro-by-example token
/// stream. This is a *mostly* identify function, expect for handling of
/// `$var:tt_kind` and `$(repeat),*` constructs.
use crate::ParseError;
use crate::tt_cursor::TtCursor;

pub(crate) fn parse(tt: &tt::Subtree) -> Result<crate::MacroRules, ParseError> {
    let mut parser = TtCursor::new(tt);
    let mut rules = Vec::new();
    while !parser.is_eof() {
        rules.push(parse_rule(&mut parser)?);
        if let Err(e) = parser.expect_char(';') {
            if !parser.is_eof() {
                return Err(e);
            }
            break;
        }
    }
    Ok(crate::MacroRules { rules })
}

fn parse_rule(p: &mut TtCursor) -> Result<crate::Rule, ParseError> {
    let lhs = parse_subtree(p.eat_subtree()?, false)?;
    p.expect_char('=')?;
    p.expect_char('>')?;
    let mut rhs = parse_subtree(p.eat_subtree()?, true)?;
    rhs.delimiter = crate::Delimiter::None;
    Ok(crate::Rule { lhs, rhs })
}

fn parse_subtree(tt: &tt::Subtree, transcriber: bool) -> Result<crate::Subtree, ParseError> {
    let mut token_trees = Vec::new();
    let mut p = TtCursor::new(tt);
    while let Some(tt) = p.eat() {
        let child: crate::TokenTree = match tt {
            tt::TokenTree::Leaf(leaf) => match leaf {
                tt::Leaf::Punct(tt::Punct { char: '$', spacing }) => {
                    if p.at_ident().is_some() {
                        crate::Leaf::from(parse_var(&mut p, transcriber)?).into()
                    } else if let Some(tt::TokenTree::Subtree(_)) = p.current() {
                        parse_repeat(&mut p, transcriber)?.into()
                    } else {
                        // Treat it as normal punct
                        crate::Leaf::from(tt::Punct { char: '$', spacing: *spacing }).into()
                    }
                }
                tt::Leaf::Punct(punct) => crate::Leaf::from(*punct).into(),
                tt::Leaf::Ident(tt::Ident { text, id: _ }) => {
                    crate::Leaf::from(crate::Ident { text: text.clone() }).into()
                }
                tt::Leaf::Literal(tt::Literal { text }) => {
                    crate::Leaf::from(crate::Literal { text: text.clone() }).into()
                }
            },
            tt::TokenTree::Subtree(subtree) => parse_subtree(&subtree, transcriber)?.into(),
        };
        token_trees.push(child);
    }
    Ok(crate::Subtree { token_trees, delimiter: tt.delimiter })
}

fn parse_var(p: &mut TtCursor, transcriber: bool) -> Result<crate::Var, ParseError> {
    let ident = p.eat_ident().unwrap();
    let text = ident.text.clone();
    let kind = if !transcriber && p.at_char(':') {
        p.bump();
        if let Some(ident) = p.eat_ident() {
            Some(ident.text.clone())
        } else {
            p.rev_bump();
            None
        }
    } else {
        None
    };

    Ok(crate::Var { text, kind })
}

fn mk_repeat(
    rep: char,
    subtree: crate::Subtree,
    separator: Option<crate::Separator>,
) -> Result<crate::Repeat, ParseError> {
    let kind = match rep {
        '*' => crate::RepeatKind::ZeroOrMore,
        '+' => crate::RepeatKind::OneOrMore,
        '?' => crate::RepeatKind::ZeroOrOne,
        _ => return Err(ParseError::Expected(String::from("repeat"))),
    };
    Ok(crate::Repeat { subtree, kind, separator })
}

fn parse_repeat(p: &mut TtCursor, transcriber: bool) -> Result<crate::Repeat, ParseError> {
    let subtree = p.eat_subtree()?;
    let mut subtree = parse_subtree(subtree, transcriber)?;
    subtree.delimiter = crate::Delimiter::None;

    if let Some(rep) = p.at_punct() {
        match rep.char {
            '*' | '+' | '?' => {
                p.bump();
                return mk_repeat(rep.char, subtree, None);
            }
            _ => {}
        }
    }

    let sep = p.eat_seperator().ok_or(ParseError::Expected(String::from("separator")))?;
    let rep = p.eat_punct().ok_or(ParseError::Expected(String::from("repeat")))?;

    mk_repeat(rep.char, subtree, Some(sep))
}

#[cfg(test)]
mod tests {
    use ra_syntax::{ast, AstNode};

    use super::*;
    use crate::ast_to_token_tree;

    #[test]
    fn test_invalid_parse() {
        expect_err("invalid", "subtree");

        is_valid("($i:ident) => ()");
        is_valid("($($i:ident)*) => ($_)");

        expect_err("$i:ident => ()", "subtree");
        expect_err("($i:ident) ()", "`=`");
        expect_err("($($i:ident)_) => ()", "repeat");
    }

    fn expect_err(macro_body: &str, expected: &str) {
        assert_eq!(
            create_rules(&format_macro(macro_body)),
            Err(ParseError::Expected(String::from(expected)))
        );
    }

    fn is_valid(macro_body: &str) {
        assert!(create_rules(&format_macro(macro_body)).is_ok());
    }

    fn format_macro(macro_body: &str) -> String {
        format!(
            "
        macro_rules! foo {{
            {}
        }}
",
            macro_body
        )
    }

    fn create_rules(macro_definition: &str) -> Result<crate::MacroRules, ParseError> {
        let source_file = ast::SourceFile::parse(macro_definition);
        let macro_definition =
            source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();

        let (definition_tt, _) = ast_to_token_tree(macro_definition.token_tree().unwrap()).unwrap();
        parse(&definition_tt)
    }

}
<|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Define_a_primitive_data_type
// Implements a custom type named CustomInt.
// This type only implements a subset of all traits within std::ops.
use std::ops;

#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Copy, Clone)]
struct CustomInt {
    value: u8,
}

#[derive(Debug)]
enum CustomIntError {
    OutOfBoundsAssn,
}

impl CustomInt {
    fn new(v: u8) -> Result<CustomInt, CustomIntError> {
        if v < 1 || v > 10 {
            Err(CustomIntError::OutOfBoundsAssn)
        } else {
            Ok(CustomInt { value: v })
        }
    }
}

// custom trait to specify bounds
trait Bounded {
    fn in_bounds(&self);
}

impl Bounded for CustomInt {
    fn in_bounds(&self) {
        if self.value < 1 || self.value > 10 {
            panic(self.value);
        }
        #[cold]
        #[inline(never)]
        fn panic(v: u8) -> ! {
            panic!("CustomInt is out of bounds! {} was value", v);
        }
    }
}

impl ops::Add for CustomInt {
    type Output = CustomInt;
    fn add(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value + rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::Sub for CustomInt {
    type Output = CustomInt;
    fn sub(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value - rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::Mul for CustomInt {
    type Output = CustomInt;
    fn mul(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value * rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::Div for CustomInt {
    type Output = CustomInt;
    fn div(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value / rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::BitAnd for CustomInt {
    type Output = CustomInt;
    fn bitand(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value & rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::BitOr for CustomInt {
    type Output = CustomInt;
    fn bitor(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value | rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::BitXor for CustomInt {
    type Output = CustomInt;
    fn bitxor(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value ^ rhs.value) };
        rval.in_bounds();
        rval
    }
}

fn main() {
    let cint_2: CustomInt = CustomInt::new(2).unwrap();
    let cint_3: CustomInt = CustomInt::new(3).unwrap();
    let cint_4: CustomInt = CustomInt::new(4).unwrap();
    assert_eq!(cint_2 + cint_4, CustomInt { value: 6 });
    assert_eq!(cint_4 - cint_2, CustomInt { value: 2 });
    assert_eq!(cint_4 * cint_2, CustomInt { value: 8 });
    assert_eq!(cint_4 / cint_2, CustomInt { value: 2 });
    assert_eq!(cint_3 & cint_2, CustomInt { value: 2 });
    assert_eq!(cint_3 | cint_2, CustomInt { value: 3 });
    assert_eq!(cint_3 ^ cint_2, CustomInt { value: 1 });
}

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

    #[test]
    fn add_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_4: CustomInt = CustomInt::new(4).unwrap();
        assert_eq!(CustomInt::new(6).unwrap(), cint_2 + cint_4);
    }

    #[test]
    fn sub_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_4: CustomInt = CustomInt::new(4).unwrap();
        assert_eq!(CustomInt::new(2).unwrap(), cint_4 - cint_2);
    }

    #[test]
    fn mul_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_4: CustomInt = CustomInt::new(4).unwrap();
        assert_eq!(CustomInt::new(8).unwrap(), cint_4 * cint_2);
    }

    #[test]
    fn div_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_4: CustomInt = CustomInt::new(4).unwrap();
        assert_eq!(CustomInt::new(2).unwrap(), cint_4 / cint_2);
    }

    #[test]
    fn and_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_3: CustomInt = CustomInt::new(3).unwrap();
        assert_eq!(CustomInt::new(2).unwrap(), cint_3 & cint_2);
    }

    #[test]
    fn or_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_3: CustomInt = CustomInt::new(3).unwrap();
        assert_eq!(CustomInt::new(3).unwrap(), cint_3 | cint_2);
    }

    #[test]
    fn xor_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_3: CustomInt = CustomInt::new(3).unwrap();
        assert_eq!(CustomInt::new(1).unwrap(), cint_3 ^ cint_2);
    }

    #[test]
    fn assn_out_of_bounds_test() {
        let cint_error = CustomInt::new(0);
        assert!(cint_error.is_err());
    }

    #[test]
    #[should_panic(expected = "CustomInt is out of bounds! 11 was value")]
    fn above_out_of_bounds_test() {
        let cint_10: CustomInt = CustomInt::new(10).unwrap();
        let cint_1: CustomInt = CustomInt::new(1).unwrap();
        let _ = cint_10 + cint_1; // should panic here
    }

    #[test]
    #[should_panic(expected = "CustomInt is out of bounds! 0 was value")]
    fn below_out_of_bounds_test() {
        let cint_1: CustomInt = CustomInt::new(1).unwrap();
        let _ = cint_1 - cint_1; // should panic here
    }
}
<commit_msg>use different expressions in subtraction test<commit_after>// http://rosettacode.org/wiki/Define_a_primitive_data_type
// Implements a custom type named CustomInt.
// This type only implements a subset of all traits within std::ops.
use std::ops;

#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Copy, Clone)]
struct CustomInt {
    value: i8,
}

#[derive(Debug)]
enum CustomIntError {
    OutOfBoundsAssn,
}

impl CustomInt {
    fn new(v: u8) -> Result<CustomInt, CustomIntError> {
        if v < 1 || v > 10 {
            Err(CustomIntError::OutOfBoundsAssn)
        } else {
            Ok(CustomInt { value: v as i8 })
        }
    }
}

// custom trait to specify bounds
trait Bounded {
    fn in_bounds(&self);
}

impl Bounded for CustomInt {
    fn in_bounds(&self) {
        if self.value < 1 || self.value > 10 {
            panic(self.value);
        }
        #[cold]
        #[inline(never)]
        fn panic(v: i8) -> ! {
            panic!("CustomInt is out of bounds! {} was value", v);
        }
    }
}

impl ops::Add for CustomInt {
    type Output = CustomInt;
    fn add(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value + rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::Sub for CustomInt {
    type Output = CustomInt;
    fn sub(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value - rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::Mul for CustomInt {
    type Output = CustomInt;
    fn mul(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value * rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::Div for CustomInt {
    type Output = CustomInt;
    fn div(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value / rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::BitAnd for CustomInt {
    type Output = CustomInt;
    fn bitand(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value & rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::BitOr for CustomInt {
    type Output = CustomInt;
    fn bitor(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value | rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::BitXor for CustomInt {
    type Output = CustomInt;
    fn bitxor(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value ^ rhs.value) };
        rval.in_bounds();
        rval
    }
}

fn main() {
    let cint_2: CustomInt = CustomInt::new(2).unwrap();
    let cint_3: CustomInt = CustomInt::new(3).unwrap();
    let cint_4: CustomInt = CustomInt::new(4).unwrap();
    assert_eq!(cint_2 + cint_4, CustomInt { value: 6 });
    assert_eq!(cint_4 - cint_2, CustomInt { value: 2 });
    assert_eq!(cint_4 * cint_2, CustomInt { value: 8 });
    assert_eq!(cint_4 / cint_2, CustomInt { value: 2 });
    assert_eq!(cint_3 & cint_2, CustomInt { value: 2 });
    assert_eq!(cint_3 | cint_2, CustomInt { value: 3 });
    assert_eq!(cint_3 ^ cint_2, CustomInt { value: 1 });
}

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

    #[test]
    fn add_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_4: CustomInt = CustomInt::new(4).unwrap();
        assert_eq!(CustomInt::new(6).unwrap(), cint_2 + cint_4);
    }

    #[test]
    fn sub_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_4: CustomInt = CustomInt::new(4).unwrap();
        assert_eq!(CustomInt::new(2).unwrap(), cint_4 - cint_2);
    }

    #[test]
    fn mul_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_4: CustomInt = CustomInt::new(4).unwrap();
        assert_eq!(CustomInt::new(8).unwrap(), cint_4 * cint_2);
    }

    #[test]
    fn div_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_4: CustomInt = CustomInt::new(4).unwrap();
        assert_eq!(CustomInt::new(2).unwrap(), cint_4 / cint_2);
    }

    #[test]
    fn and_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_3: CustomInt = CustomInt::new(3).unwrap();
        assert_eq!(CustomInt::new(2).unwrap(), cint_3 & cint_2);
    }

    #[test]
    fn or_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_3: CustomInt = CustomInt::new(3).unwrap();
        assert_eq!(CustomInt::new(3).unwrap(), cint_3 | cint_2);
    }

    #[test]
    fn xor_test() {
        let cint_2: CustomInt = CustomInt::new(2).unwrap();
        let cint_3: CustomInt = CustomInt::new(3).unwrap();
        assert_eq!(CustomInt::new(1).unwrap(), cint_3 ^ cint_2);
    }

    #[test]
    fn assn_out_of_bounds_test() {
        let cint_error = CustomInt::new(0);
        assert!(cint_error.is_err());
    }

    #[test]
    #[should_panic(expected = "CustomInt is out of bounds! 11 was value")]
    fn above_out_of_bounds_test() {
        let cint_10: CustomInt = CustomInt::new(10).unwrap();
        let cint_1: CustomInt = CustomInt::new(1).unwrap();
        let _ = cint_10 + cint_1; // should panic here
    }

    #[test]
    #[should_panic(expected = "CustomInt is out of bounds! -9 was value")]
    fn below_out_of_bounds_test() {
        let cint_1: CustomInt = CustomInt::new(1).unwrap();
        let cint_10: CustomInt = CustomInt::new(10).unwrap();
        let _ = cint_1 - cint_10; // should panic here
    }
}
<|endoftext|>


<commit_before>use backend::Backend;
use expression::subselect::Subselect;
use expression::{AppearsOnTable, Expression, NonAggregate, SelectableExpression};
use query_builder::*;
use result::QueryResult;
use sql_types::Bool;

/// Creates a SQL `EXISTS` expression.
///
/// The argument must be a complete SQL query. The query may reference columns
/// from the outer table.
///
/// # Example
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     use diesel::select;
/// #     use diesel::dsl::exists;
/// #     let connection = establish_connection();
/// let sean_exists = select(exists(users.filter(name.eq("Sean"))))
///     .get_result(&connection);
/// let jim_exists = select(exists(users.filter(name.eq("Jim"))))
///     .get_result(&connection);
/// assert_eq!(Ok(true), sean_exists);
/// assert_eq!(Ok(false), jim_exists);
/// # }
/// ```
pub fn exists<T>(query: T) -> Exists<T> {
    Exists(Subselect::new(query))
}

#[derive(Debug, Clone, Copy, QueryId)]
pub struct Exists<T>(Subselect<T, ()>);

impl<T> Expression for Exists<T>
where
    Subselect<T, ()>: Expression,
{
    type SqlType = Bool;
}

impl<T> NonAggregate for Exists<T> where Subselect<T, ()>: NonAggregate {}

impl<T, DB> QueryFragment<DB> for Exists<T>
where
    DB: Backend,
    T: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql("EXISTS (");
        self.0.walk_ast(out.reborrow())?;
        out.push_sql(")");
        Ok(())
    }
}

impl<T, QS> SelectableExpression<QS> for Exists<T>
where
    Self: AppearsOnTable<QS>,
    Subselect<T, ()>: SelectableExpression<QS>,
{
}

impl<T, QS> AppearsOnTable<QS> for Exists<T>
where
    Self: Expression,
    Subselect<T, ()>: AppearsOnTable<QS>,
{
}
<commit_msg>Allow to specialize the `QueryFragment` implementation for `exists`<commit_after>use backend::Backend;
use expression::subselect::Subselect;
use expression::{AppearsOnTable, Expression, NonAggregate, SelectableExpression};
use query_builder::*;
use result::QueryResult;
use sql_types::Bool;

/// Creates a SQL `EXISTS` expression.
///
/// The argument must be a complete SQL query. The query may reference columns
/// from the outer table.
///
/// # Example
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     use diesel::select;
/// #     use diesel::dsl::exists;
/// #     let connection = establish_connection();
/// let sean_exists = select(exists(users.filter(name.eq("Sean"))))
///     .get_result(&connection);
/// let jim_exists = select(exists(users.filter(name.eq("Jim"))))
///     .get_result(&connection);
/// assert_eq!(Ok(true), sean_exists);
/// assert_eq!(Ok(false), jim_exists);
/// # }
/// ```
pub fn exists<T>(query: T) -> Exists<T> {
    Exists(Subselect::new(query))
}

#[derive(Debug, Clone, Copy, QueryId)]
pub struct Exists<T>(pub Subselect<T, ()>);

impl<T> Expression for Exists<T>
where
    Subselect<T, ()>: Expression,
{
    type SqlType = Bool;
}

impl<T> NonAggregate for Exists<T> where Subselect<T, ()>: NonAggregate {}

#[cfg(not(feature = "unstable"))]
impl<T, DB> QueryFragment<DB> for Exists<T>
where
    DB: Backend,
    T: QueryFragment<DB>,
{
    fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql("EXISTS (");
        self.0.walk_ast(out.reborrow())?;
        out.push_sql(")");
        Ok(())
    }
}

#[cfg(feature = "unstable")]
impl<T, DB> QueryFragment<DB> for Exists<T>
where
    DB: Backend,
    T: QueryFragment<DB>,
{
    default fn walk_ast(&self, mut out: AstPass<DB>) -> QueryResult<()> {
        out.push_sql("EXISTS (");
        self.0.walk_ast(out.reborrow())?;
        out.push_sql(")");
        Ok(())
    }
}

impl<T, QS> SelectableExpression<QS> for Exists<T>
where
    Self: AppearsOnTable<QS>,
    Subselect<T, ()>: SelectableExpression<QS>,
{
}

impl<T, QS> AppearsOnTable<QS> for Exists<T>
where
    Self: Expression,
    Subselect<T, ()>: AppearsOnTable<QS>,
{
}
<|endoftext|>


<commit_before>//! Relay for TCP server that running on the server side

use std::io::{self, ErrorKind};
use std::rc::Rc;
use std::time::Duration;

use config::ServerConfig;

use relay::{boxed_future, BoxIoFuture};
use relay::Context;
use relay::dns_resolver::resolve;
use relay::socks5::Address;
use relay::tcprelay::crypto_io::{DecryptedRead, EncryptedWrite};

use futures::{self, Future};
use futures::stream::Stream;

use tokio_core::net::{TcpListener, TcpStream};
use tokio_io::AsyncRead;
use tokio_io::io::{ReadHalf, WriteHalf};

use super::{proxy_handshake, try_timeout, tunnel, DecryptedHalf, EncryptedHalfFut, TcpStreamConnect};

/// Context for doing handshake with client
pub struct TcpRelayClientHandshake {
    s: TcpStream,
    svr_cfg: Rc<ServerConfig>,
}

impl TcpRelayClientHandshake {
    /// Doing handshake with client
    pub fn handshake(self) -> BoxIoFuture<TcpRelayClientPending> {
        let TcpRelayClientHandshake { s, svr_cfg } = self;

        let timeout = *svr_cfg.timeout();
        let fut = proxy_handshake(s, svr_cfg).and_then(move |(r_fut, w_fut)| {
            r_fut.and_then(move |r| {
                let fut = Address::read_from(r).map_err(
                    |_| io::Error::new(ErrorKind::Other, "failed to decode Address, may be wrong method or key"),
                );
                Context::with(|ctx| try_timeout(fut, timeout, ctx.handle()))
            })
                 .map(move |(r, addr)| {
                          TcpRelayClientPending {
                              r: r,
                              addr: addr,
                              w: w_fut,
                              timeout: timeout,
                          }
                      })
        });
        boxed_future(fut)
    }
}

/// Context for connecting remote
pub struct TcpRelayClientPending {
    r: DecryptedHalf,
    addr: Address,
    w: EncryptedHalfFut,
    timeout: Option<Duration>,
}

impl TcpRelayClientPending {
    /// Connect to the remote server
    #[inline]
    fn connect_remote(addr: Address, timeout: Option<Duration>) -> BoxIoFuture<TcpStream> {
        debug!("Connecting to remote {}", addr);

        match addr {
            Address::SocketAddress(saddr) => {
                Context::with(move |ctx| {
                    if ctx.forbidden_ip().contains(&saddr.ip()) {
                        let err = io::Error::new(ErrorKind::Other,
                                                 format!("{} is forbidden, failed to connect {}", saddr.ip(), saddr));
                        return boxed_future(futures::done(Err(err)));
                    }

                    let conn = TcpStream::connect(&saddr, ctx.handle());
                    try_timeout(conn, timeout, ctx.handle())
                })
            }
            Address::DomainNameAddress(dname, port) => {
                let fut = Context::with(move |ctx| {
                    let handle = ctx.handle().clone();
                    try_timeout(resolve(dname.as_str(), port, true), timeout, &handle).and_then(move |addrs| {
                        let conn = TcpStreamConnect::new(addrs.into_iter(), &handle);
                        try_timeout(conn, timeout, &handle)
                    })
                });
                boxed_future(fut)
            }
        }
    }

    /// Connect to the remote server
    pub fn connect(self) -> BoxIoFuture<TcpRelayClientConnected> {
        let addr = self.addr.clone();
        let client_pair = (self.r, self.w);
        let timeout = self.timeout;
        let fut = TcpRelayClientPending::connect_remote(self.addr, self.timeout);
        let fut = fut.map(move |stream| {
                              TcpRelayClientConnected {
                                  server: stream.split(),
                                  client: client_pair,
                                  addr: addr,
                                  timeout: timeout,
                              }
                          });
        Box::new(fut)
    }
}

/// Context for extablishing tunnel
pub struct TcpRelayClientConnected {
    server: (ReadHalf<TcpStream>, WriteHalf<TcpStream>),
    client: (DecryptedHalf, EncryptedHalfFut),
    addr: Address,
    timeout: Option<Duration>,
}

impl TcpRelayClientConnected {
    /// Establish tunnel
    #[inline]
    pub fn tunnel(self) -> BoxIoFuture<()> {
        let (svr_r, svr_w) = self.server;
        let (r, w_fut) = self.client;
        let timeout = self.timeout;

        tunnel(self.addr,
               r.copy_timeout_opt(svr_w, self.timeout),
               w_fut.and_then(move |w| w.copy_timeout_opt(svr_r, timeout)))
    }
}

/// Runs the server
pub fn run() -> Box<Future<Item = (), Error = io::Error>> {
    let mut fut: Option<Box<Future<Item = (), Error = io::Error>>> = None;

    Context::with(|ctx| {
        let config = ctx.config();

        for svr_cfg in &config.server {
            let listener = {
                let addr = svr_cfg.addr();
                let addr = addr.listen_addr();

                let listener =
                    TcpListener::bind(&addr, ctx.handle()).unwrap_or_else(|err| panic!("Failed to listen, {}", err));

                info!("ShadowSocks TCP Listening on {}", addr);
                listener
            };

            let svr_cfg = Rc::new(svr_cfg.clone());
            let listening = listener.incoming()
                                    .for_each(move |(socket, addr)| {
                let server_cfg = svr_cfg.clone();

                trace!("Got connection, addr: {}", addr);
                trace!("Picked proxy server: {:?}", server_cfg);

                let client = TcpRelayClientHandshake {
                    s: socket,
                    svr_cfg: server_cfg,
                };

                let fut = client.handshake()
                                .and_then(|c| c.connect())
                                .and_then(|c| c.tunnel())
                                .map_err(move |err| {
                                             error!("Failed to handle client ({}): {}", addr, err);
                                         });

                Context::with(|ctx| ctx.handle().spawn(fut));
                Ok(())
            })
                                    .map_err(|err| {
                                                 error!("Server run failed: {}", err);
                                                 err
                                             });

            fut = Some(match fut.take() {
                           Some(fut) => {
                               Box::new(fut.join(listening).map(|_| ())) as Box<Future<Item = (), Error = io::Error>>
                           }
                           None => Box::new(listening) as Box<Future<Item = (), Error = io::Error>>,
                       })
        }

        fut.expect("Must have at least one server")
    })
}
<commit_msg>[#88] Prints peer addr while failing to handshake<commit_after>//! Relay for TCP server that running on the server side

use std::io::{self, ErrorKind};
use std::rc::Rc;
use std::time::Duration;

use config::ServerConfig;

use relay::{BoxIoFuture, boxed_future};
use relay::Context;
use relay::dns_resolver::resolve;
use relay::socks5::Address;
use relay::tcprelay::crypto_io::{DecryptedRead, EncryptedWrite};

use futures::{self, Future};
use futures::stream::Stream;

use tokio_core::net::{TcpListener, TcpStream};
use tokio_io::AsyncRead;
use tokio_io::io::{ReadHalf, WriteHalf};

use super::{DecryptedHalf, EncryptedHalfFut, TcpStreamConnect, proxy_handshake, try_timeout, tunnel};

/// Context for doing handshake with client
pub struct TcpRelayClientHandshake {
    s: TcpStream,
    svr_cfg: Rc<ServerConfig>,
}

impl TcpRelayClientHandshake {
    /// Doing handshake with client
    pub fn handshake(self) -> BoxIoFuture<TcpRelayClientPending> {
        let TcpRelayClientHandshake { s, svr_cfg } = self;

        let peer_addr = s.peer_addr().expect("Failed to get peer addr for client");
        debug!("Handshaking with peer {}", peer_addr);

        let timeout = *svr_cfg.timeout();
        let fut = proxy_handshake(s, svr_cfg).and_then(move |(r_fut, w_fut)| {
            r_fut.and_then(move |r| {
                let fut = Address::read_from(r).map_err(move |_| {
                    io::Error::new(ErrorKind::Other,
                                   format!("failed to decode Address, may be wrong method or key, peer: {}", peer_addr))
                });
                Context::with(|ctx| try_timeout(fut, timeout, ctx.handle()))
            })
                 .map(move |(r, addr)| {
                          TcpRelayClientPending {
                              r: r,
                              addr: addr,
                              w: w_fut,
                              timeout: timeout,
                          }
                      })
        });
        boxed_future(fut)
    }
}

/// Context for connecting remote
pub struct TcpRelayClientPending {
    r: DecryptedHalf,
    addr: Address,
    w: EncryptedHalfFut,
    timeout: Option<Duration>,
}

impl TcpRelayClientPending {
    /// Connect to the remote server
    #[inline]
    fn connect_remote(addr: Address, timeout: Option<Duration>) -> BoxIoFuture<TcpStream> {
        debug!("Connecting to remote {}", addr);

        match addr {
            Address::SocketAddress(saddr) => {
                Context::with(move |ctx| {
                    if ctx.forbidden_ip().contains(&saddr.ip()) {
                        let err = io::Error::new(ErrorKind::Other,
                                                 format!("{} is forbidden, failed to connect {}", saddr.ip(), saddr));
                        return boxed_future(futures::done(Err(err)));
                    }

                    let conn = TcpStream::connect(&saddr, ctx.handle());
                    try_timeout(conn, timeout, ctx.handle())
                })
            }
            Address::DomainNameAddress(dname, port) => {
                let fut = Context::with(move |ctx| {
                    let handle = ctx.handle().clone();
                    try_timeout(resolve(dname.as_str(), port, true), timeout, &handle).and_then(move |addrs| {
                        let conn = TcpStreamConnect::new(addrs.into_iter(), &handle);
                        try_timeout(conn, timeout, &handle)
                    })
                });
                boxed_future(fut)
            }
        }
    }

    /// Connect to the remote server
    pub fn connect(self) -> BoxIoFuture<TcpRelayClientConnected> {
        let addr = self.addr.clone();
        let client_pair = (self.r, self.w);
        let timeout = self.timeout;
        let fut = TcpRelayClientPending::connect_remote(self.addr, self.timeout);
        let fut = fut.map(move |stream| {
                              TcpRelayClientConnected {
                                  server: stream.split(),
                                  client: client_pair,
                                  addr: addr,
                                  timeout: timeout,
                              }
                          });
        Box::new(fut)
    }
}

/// Context for extablishing tunnel
pub struct TcpRelayClientConnected {
    server: (ReadHalf<TcpStream>, WriteHalf<TcpStream>),
    client: (DecryptedHalf, EncryptedHalfFut),
    addr: Address,
    timeout: Option<Duration>,
}

impl TcpRelayClientConnected {
    /// Establish tunnel
    #[inline]
    pub fn tunnel(self) -> BoxIoFuture<()> {
        let (svr_r, svr_w) = self.server;
        let (r, w_fut) = self.client;
        let timeout = self.timeout;

        tunnel(self.addr,
               r.copy_timeout_opt(svr_w, self.timeout),
               w_fut.and_then(move |w| w.copy_timeout_opt(svr_r, timeout)))
    }
}

/// Runs the server
pub fn run() -> Box<Future<Item = (), Error = io::Error>> {
    let mut fut: Option<Box<Future<Item = (), Error = io::Error>>> = None;

    Context::with(|ctx| {
        let config = ctx.config();

        for svr_cfg in &config.server {
            let listener = {
                let addr = svr_cfg.addr();
                let addr = addr.listen_addr();

                let listener = TcpListener::bind(&addr, ctx.handle())
                    .unwrap_or_else(|err| panic!("Failed to listen, {}", err));

                info!("ShadowSocks TCP Listening on {}", addr);
                listener
            };

            let svr_cfg = Rc::new(svr_cfg.clone());
            let listening = listener.incoming()
                                    .for_each(move |(socket, addr)| {
                let server_cfg = svr_cfg.clone();

                trace!("Got connection, addr: {}", addr);
                trace!("Picked proxy server: {:?}", server_cfg);

                let client = TcpRelayClientHandshake {
                    s: socket,
                    svr_cfg: server_cfg,
                };

                let fut = client.handshake()
                                .and_then(|c| c.connect())
                                .and_then(|c| c.tunnel())
                                .map_err(move |err| {
                                             error!("Failed to handle client ({}): {}", addr, err);
                                         });

                Context::with(|ctx| ctx.handle().spawn(fut));
                Ok(())
            })
                                    .map_err(|err| {
                                                 error!("Server run failed: {}", err);
                                                 err
                                             });

            fut = Some(match fut.take() {
                           Some(fut) => {
                               Box::new(fut.join(listening).map(|_| ())) as Box<Future<Item = (), Error = io::Error>>
                           }
                           None => Box::new(listening) as Box<Future<Item = (), Error = io::Error>>,
                       })
        }

        fut.expect("Must have at least one server")
    })
}
<|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.

// xfail-fast
// compile-flags:--test

// NB: These tests kill child processes. Valgrind sees these children as leaking
// memory, which makes for some *confusing* logs. That's why these are here
// instead of in std.

use std::libc;
use std::run::*;
use std::run;
use std::str;

#[test]
fn test_destroy_once() {
    let mut p = run::Process::new("echo", [], run::ProcessOptions::new());
    p.destroy(); // this shouldn't crash (and nor should the destructor)
}

#[test]
fn test_destroy_twice() {
    let mut p = run::Process::new("echo", [], run::ProcessOptions::new());
    p.destroy(); // this shouldnt crash...
    p.destroy(); // ...and nor should this (and nor should the destructor)
}

fn test_destroy_actually_kills(force: bool) {

    #[cfg(unix)]
    static BLOCK_COMMAND: &'static str = "cat";

    #[cfg(windows)]
    static BLOCK_COMMAND: &'static str = "cmd";

    #[cfg(unix,not(target_os="android"))]
    fn process_exists(pid: libc::pid_t) -> bool {
        let run::ProcessOutput {output, _} = run::process_output("ps", [~"-p", pid.to_str()]);
        str::from_utf8(output).contains(pid.to_str())
    }

    #[cfg(unix,target_os="android")]
    fn process_exists(pid: libc::pid_t) -> bool {
        let run::ProcessOutput {output, _} = run::process_output("/system/bin/ps", [pid.to_str()]);
        str::from_utf8(output).contains(~"root")
    }

    #[cfg(windows)]
    fn process_exists(pid: libc::pid_t) -> bool {

        use std::libc::types::os::arch::extra::DWORD;
        use std::libc::funcs::extra::kernel32::{CloseHandle, GetExitCodeProcess, OpenProcess};
        use std::libc::consts::os::extra::{FALSE, PROCESS_QUERY_INFORMATION, STILL_ACTIVE };

        unsafe {
            let proc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid as DWORD);
            if proc.is_null() {
                return false;
            }
            // proc will be non-null if the process is alive, or if it died recently
            let mut status = 0;
            GetExitCodeProcess(proc, &mut status);
            CloseHandle(proc);
            return status == STILL_ACTIVE;
        }
    }

    // this process will stay alive indefinitely trying to read from stdin
    let mut p = run::Process::new(BLOCK_COMMAND, [], run::ProcessOptions::new());

    assert!(process_exists(p.get_id()));

    if force {
        p.force_destroy();
    } else {
        p.destroy();
    }

    assert!(!process_exists(p.get_id()));
}

#[test]
fn test_unforced_destroy_actually_kills() {
    test_destroy_actually_kills(false);
}

#[test]
fn test_forced_destroy_actually_kills() {
    test_destroy_actually_kills(true);
}
<commit_msg>pacified test/run-pass/core-run-destroy on Win7x64<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.

// xfail-fast
// compile-flags:--test

// NB: These tests kill child processes. Valgrind sees these children as leaking
// memory, which makes for some *confusing* logs. That's why these are here
// instead of in std.

use std::libc;
use std::run::*;
use std::run;
use std::str;

#[test]
fn test_destroy_once() {
    let mut p = run::Process::new("echo", [], run::ProcessOptions::new());
    p.destroy(); // this shouldn't crash (and nor should the destructor)
}

#[test]
fn test_destroy_twice() {
    let mut p = run::Process::new("echo", [], run::ProcessOptions::new());
    p.destroy(); // this shouldnt crash...
    p.destroy(); // ...and nor should this (and nor should the destructor)
}

fn test_destroy_actually_kills(force: bool) {

    #[cfg(unix)]
    static BLOCK_COMMAND: &'static str = "cat";

    #[cfg(windows)]
    static BLOCK_COMMAND: &'static str = "cmd";

    #[cfg(unix,not(target_os="android"))]
    fn process_exists(pid: libc::pid_t) -> bool {
        let run::ProcessOutput {output, _} = run::process_output("ps", [~"-p", pid.to_str()]);
        str::from_utf8(output).contains(pid.to_str())
    }

    #[cfg(unix,target_os="android")]
    fn process_exists(pid: libc::pid_t) -> bool {
        let run::ProcessOutput {output, _} = run::process_output("/system/bin/ps", [pid.to_str()]);
        str::from_utf8(output).contains(~"root")
    }

    #[cfg(windows)]
    fn process_exists(pid: libc::pid_t) -> bool {
        #[fixed_stack_segment];

        use std::libc::types::os::arch::extra::DWORD;
        use std::libc::funcs::extra::kernel32::{CloseHandle, GetExitCodeProcess, OpenProcess};
        use std::libc::consts::os::extra::{FALSE, PROCESS_QUERY_INFORMATION, STILL_ACTIVE };

        unsafe {
            let proc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid as DWORD);
            if proc.is_null() {
                return false;
            }
            // proc will be non-null if the process is alive, or if it died recently
            let mut status = 0;
            GetExitCodeProcess(proc, &mut status);
            CloseHandle(proc);
            return status == STILL_ACTIVE;
        }
    }

    // this process will stay alive indefinitely trying to read from stdin
    let mut p = run::Process::new(BLOCK_COMMAND, [], run::ProcessOptions::new());

    assert!(process_exists(p.get_id()));

    if force {
        p.force_destroy();
    } else {
        p.destroy();
    }

    assert!(!process_exists(p.get_id()));
}

#[test]
fn test_unforced_destroy_actually_kills() {
    test_destroy_actually_kills(false);
}

#[test]
fn test_forced_destroy_actually_kills() {
    test_destroy_actually_kills(true);
}
<|endoftext|>


<commit_before>/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use std::ffi::OsString;
use std::io;
use std::os::windows::ffi::OsStringExt;

use winapi::shared::lmcons;
use winapi::shared::minwindef::DWORD;
use winapi::um::winbase;

pub fn get_username() -> io::Result<OsString> {
    const BUF_LEN: DWORD = lmcons::UNLEN + 1;
    let mut buffer = [0_u16; BUF_LEN as usize];
    let mut len = BUF_LEN;
    // SAFETY: buffer.len() == len
    unsafe {
        if winbase::GetUserNameW(buffer.as_mut_ptr(), &mut len) == 0 {
            return Err(io::Error::last_os_error());
        }
    }
    Ok(OsString::from_wide(&buffer[..len as usize - 1]))
}
<commit_msg>whoami: Restrict scope of unsafe<commit_after>/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use std::ffi::OsString;
use std::io;
use std::os::windows::ffi::OsStringExt;

use winapi::shared::lmcons;
use winapi::shared::minwindef::DWORD;
use winapi::um::winbase;

pub fn get_username() -> io::Result<OsString> {
    const BUF_LEN: DWORD = lmcons::UNLEN + 1;
    let mut buffer = [0_u16; BUF_LEN as usize];
    let mut len = BUF_LEN;
    // SAFETY: buffer.len() == len
    if unsafe { winbase::GetUserNameW(buffer.as_mut_ptr(), &mut len) } == 0 {
        return Err(io::Error::last_os_error());
    }
    Ok(OsString::from_wide(&buffer[..len as usize - 1]))
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::prelude::*;
use std::collections::HashMap;

fn get_input() -> std::io::Result<String> {
    let mut file = File::open("05.txt")?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;

    Ok(contents)
}

fn react(input: &str) -> String {
    let mut result;
    let mut polymer = input.to_string();

    loop {
        let chars: Vec<char> = polymer.chars().collect();
        let mut ignore_index = None;

        result = String::new();

        for (i, c) in chars.iter().enumerate() {
            if ignore_index == Some(i) {
                continue;
            }

            if i + 1 < chars.len() {
                let next_char = chars[i + 1];
                let reactable = next_char.eq_ignore_ascii_case(c) && match c.is_ascii_uppercase() {
                    true => next_char.is_ascii_lowercase(),
                    false => next_char.is_ascii_uppercase()
                };

                if reactable {
                    ignore_index = Some(i + 1);
                    continue;
                }
            }

            result.push(*c);
        }

        if result == polymer {
            return result;
        } else {
            polymer = result;
        }
    }
}

fn main() {
    let input = get_input().unwrap();
    let polymer = input.trim().to_string();
    let reacted = react(&polymer);

    println!("Part 1: {}", reacted.len());

    let improved = "abcdefghijklmnopqrstuvwxyz".chars()
        .map(|c| {
            polymer.chars()
            .filter(|&d| d != c && d != c.to_ascii_uppercase())
            .fold(String::new(), |mut acc, d| {
                acc.push(d);
                acc
            })
        })
        .map(|polymer| react(&polymer))
        .map(|reacted| reacted.len())
        .min()
        .unwrap();

    println!("Part 2: {}", improved);
}
<commit_msg>Make react O(n)<commit_after>use std::fs::File;
use std::io::prelude::*;

fn get_input() -> std::io::Result<String> {
    let mut file = File::open("05.txt")?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;

    Ok(contents)
}

fn react(input: &str) -> String {
    input.chars()
    .fold(String::new(), |mut acc, c| {
        match acc.chars().rev().next() {
            Some(d) if d.eq_ignore_ascii_case(&c) && d != c => { acc.pop(); },
            _ => acc.push(c)
        };

        acc
    })
}

fn main() {
    let input = get_input().unwrap();
    let reacted = react(input.trim());

    println!("Part 1: {}", reacted.len());

    let improved = "abcdefghijklmnopqrstuvwxyz".chars()
        .map(|c| {
            let mut polymer = input.clone();

            polymer.retain(|d| !d.eq_ignore_ascii_case(&c));
            react(&polymer)
        })
        .map(|reacted| reacted.len())
        .min()
        .unwrap();

    println!("Part 2: {}", improved);
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::prelude::*;
use std::collections::HashMap;

#[derive(Debug, Clone, Copy)]
enum Direction {
  Left,
  Right,
  Up,
  Down
}

type Wire = Vec<(Direction, usize)>;
type Grid = HashMap<(i32, i32), HashMap<usize, usize>>;

fn get_input() -> std::io::Result<String> {
  let mut file = File::open("03.txt")?;
  let mut contents = String::new();
  file.read_to_string(&mut contents)?;

  Ok(contents)
}

fn norm((x, y): (i32, i32)) -> i32 {
  x.abs() + y.abs()
}

fn parse_wires(input: &str) -> Vec<Wire> {
  input.lines()
  .map(|line| {
    line.split(',')
    .filter_map(|token| {
      if token.len() < 2 {
        return None;
      }

      let steps = token.get(1..).and_then(|steps| steps.parse::<usize>().ok());
      let direction = match token.chars().nth(0) {
        Some('L') => Some(Direction::Left),
        Some('R') => Some(Direction::Right),
        Some('U') => Some(Direction::Up),
        Some('D') => Some(Direction::Down),
        _ => None
      };

      match (direction, steps) {
        (Some(direction), Some(steps)) => Some((direction, steps)),
        _ => None
      }
    })
    .collect::<Vec<_>>()
  })
  .collect::<Vec<_>>()
}

fn trace_wire(grid: &mut Grid, id: usize, wire: &Wire) {
  let mut position = (0, 0);
  let mut timestamp = 0;

  for &(direction, steps) in wire.iter() {
    let move_vector = match direction {
      Direction::Left => (-1, 0),
      Direction::Right => (1, 0),
      Direction::Up => (0, 1),
      Direction::Down => (0, -1)
    };

    for _ in 0..steps {
      position = (position.0 + move_vector.0, position.1 + move_vector.1);
      timestamp += 1;

      if !grid.contains_key(&position) {
        grid.insert(position, HashMap::new());
      }

      let ids = grid.get_mut(&position).unwrap();

      if !ids.contains_key(&id) {
        ids.insert(id, timestamp);
      }
    }
  }
}

fn iter_collisions<'a>(grid: &'a Grid) -> impl Iterator<Item = (i32, i32)> + 'a {
  grid.iter()
  .filter(|(_, ids)| ids.len() > 1)
  .map(|(&pos, _)| pos)
}

fn iter_collision_times<'a>(grid: &'a Grid) -> impl Iterator<Item = usize> + 'a {
  iter_collisions(grid)
  .map(move |pos| {
    grid.get(&pos)
    .unwrap()
    .values()
    .sum()
  })
}

fn main() {
  let input = get_input().unwrap();
  let wires = parse_wires(&input);
  let mut grid = Grid::new();

  for (i, wire) in wires.iter().enumerate() {
    trace_wire(&mut grid, i, wire);
  }

  iter_collisions(&grid)
  .map(|pos| norm(pos))
  .min()
  .map(|min_collision_norm| {
    println!("Part 1: {}", min_collision_norm);
  });

  iter_collision_times(&grid)
  .min()
  .map(|min_collision_time| {
    println!("Part 2: {}", min_collision_time);
  });
}
<commit_msg>Use anonymous lifetime<commit_after>use std::fs::File;
use std::io::prelude::*;
use std::collections::HashMap;

#[derive(Debug, Clone, Copy)]
enum Direction {
  Left,
  Right,
  Up,
  Down
}

type Wire = Vec<(Direction, usize)>;
type Grid = HashMap<(i32, i32), HashMap<usize, usize>>;

fn get_input() -> std::io::Result<String> {
  let mut file = File::open("03.txt")?;
  let mut contents = String::new();
  file.read_to_string(&mut contents)?;

  Ok(contents)
}

fn norm((x, y): (i32, i32)) -> i32 {
  x.abs() + y.abs()
}

fn parse_wires(input: &str) -> Vec<Wire> {
  input.lines()
  .map(|line| {
    line.split(',')
    .filter_map(|token| {
      if token.len() < 2 {
        return None;
      }

      let steps = token.get(1..).and_then(|steps| steps.parse::<usize>().ok());
      let direction = match token.chars().nth(0) {
        Some('L') => Some(Direction::Left),
        Some('R') => Some(Direction::Right),
        Some('U') => Some(Direction::Up),
        Some('D') => Some(Direction::Down),
        _ => None
      };

      match (direction, steps) {
        (Some(direction), Some(steps)) => Some((direction, steps)),
        _ => None
      }
    })
    .collect::<Vec<_>>()
  })
  .collect::<Vec<_>>()
}

fn trace_wire(grid: &mut Grid, id: usize, wire: &Wire) {
  let mut position = (0, 0);
  let mut timestamp = 0;

  for &(direction, steps) in wire.iter() {
    let move_vector = match direction {
      Direction::Left => (-1, 0),
      Direction::Right => (1, 0),
      Direction::Up => (0, 1),
      Direction::Down => (0, -1)
    };

    for _ in 0..steps {
      position = (position.0 + move_vector.0, position.1 + move_vector.1);
      timestamp += 1;

      if !grid.contains_key(&position) {
        grid.insert(position, HashMap::new());
      }

      let ids = grid.get_mut(&position).unwrap();

      if !ids.contains_key(&id) {
        ids.insert(id, timestamp);
      }
    }
  }
}

fn iter_collisions(grid: &Grid) -> impl Iterator<Item = (i32, i32)> + '_ {
  grid.iter()
  .filter(|(_, ids)| ids.len() > 1)
  .map(|(&pos, _)| pos)
}

fn iter_collision_times(grid: &Grid) -> impl Iterator<Item = usize> + '_ {
  iter_collisions(grid)
  .map(move |pos| {
    grid.get(&pos)
    .unwrap()
    .values()
    .sum()
  })
}

fn main() {
  let input = get_input().unwrap();
  let wires = parse_wires(&input);
  let mut grid = Grid::new();

  for (i, wire) in wires.iter().enumerate() {
    trace_wire(&mut grid, i, wire);
  }

  iter_collisions(&grid)
  .map(|pos| norm(pos))
  .min()
  .map(|min_collision_norm| {
    println!("Part 1: {}", min_collision_norm);
  });

  iter_collision_times(&grid)
  .min()
  .map(|min_collision_time| {
    println!("Part 2: {}", min_collision_time);
  });
}
<|endoftext|>