<commit_before>
use std::iter::Filter;
use std::ops::RangeFrom;

use common::divisible;

#[allow(dead_code)]
pub fn is_prime(n: u64) -> bool {
    let half = n / 2 + 1;
    let mut range = 2..half; // TODO: find out why this needs to be 'mut'
    n != 1 && !range.any(|r| divisible(n, r))
}

#[allow(dead_code)]
pub fn factorize(n: u64) -> Vec<u64> {
    let mut factors: Vec<u64> = vec![];
    let mut current = n;
    let mut i = 2;
    loop {
        if divisible(current, i) {
            factors.push(i);
            current = current / i;
            if current == 1 {
                return factors;
            }
        } else {
            i = i + 1;
        }
    }
}

#[allow(dead_code)]
#[allow(unused_variables)]
pub fn factorize_fun(n: u64) -> Vec<u64> {
    let primes = (1..).filter(|&n| is_prime(n));
    let five = primes.take(5).collect::<Vec<u64>>();
    //print!("!!!!!!!! primes: {:?}", five);
    //let a = prime_factors(n, primes);
    vec![]
}

#[allow(dead_code)]
#[allow(unused_variables)]
fn prime_factors(n: u64, series: Filter<RangeFrom<u64>, u64>) -> Vec<u64> {
    match (n, series) {
        (1, _)  => vec![],
        (m, ps) => {
            let (q, r) = (m/2, m/2);
            vec![]
        }
    }
}

#[allow(dead_code)]
pub fn largest_prime_factor(n: u64) -> u64 {
    let factors = factorize(n);
    match factors.last() {
        Some(&f) => f,
        _ => 0
    }
}

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    //#[should_panic(expected="assertion failed")]
    fn one_is_not_prime() {
        assert!(!is_prime(1));
    }

    #[test]
    fn there_are_168_primes_under_1000() {
        let primes = (1..1000).filter(|n| is_prime(*n)).count();
        assert_eq!(primes, 168);
    }

    #[test]
    fn example_factors() {
        assert_eq!(factorize(13195), vec![5, 7, 13, 29]);
    }

    #[test]
    fn factors_repeating() { // TODO: this is not what I wanted
        factorize_fun(12);
        assert_eq!(factorize(12), vec![2, 2, 3]);
    }

    #[test]
    fn example() {
        assert_eq!(largest_prime_factor(13195), 29);
    }

    #[test]
    fn solution() {
        assert_eq!(largest_prime_factor(600851475143), 6857);
    }
}
<commit_msg>TODOs for unfinished code<commit_after>
use std::iter::Filter;
use std::ops::RangeFrom;

use common::divisible;

#[allow(dead_code)]
pub fn is_prime(n: u64) -> bool {
    let half = n / 2 + 1;
    let mut range = 2..half; // TODO: find out why this needs to be 'mut'
    n != 1 && !range.any(|r| divisible(n, r))
}

#[allow(dead_code)]
pub fn factorize(n: u64) -> Vec<u64> {
    let mut factors: Vec<u64> = vec![];
    let mut current = n;
    let mut i = 2;
    loop {
        if divisible(current, i) {
            factors.push(i);
            current = current / i;
            if current == 1 {
                return factors;
            }
        } else {
            i = i + 1;
        }
    }
}

#[allow(dead_code)]
pub fn largest_prime_factor(n: u64) -> u64 {
    let factors = factorize(n);
    match factors.last() {
        Some(&f) => f,
        _ => 1
    }
}

// TODO: finish functional way

#[allow(dead_code)]
#[allow(unused_variables)]
pub fn factorize_fun(n: u64) -> Vec<u64> {
    let primes = (1..).filter(|&n| is_prime(n));
    let five = primes.take(5).collect::<Vec<u64>>();
    //print!("!!!!!!!! primes: {:?}", five);
    //let a = prime_factors(n, primes);
    vec![]
}

#[allow(dead_code)]
#[allow(unused_variables)]
fn prime_factors(n: u64, series: Filter<RangeFrom<u64>, u64>) -> Vec<u64> {
    match (n, series) {
        (1, _)  => vec![],
        (m, ps) => {
            let (q, r) = (m/2, m/2);
            vec![]
        }
    }
}

// \TODO

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    //#[should_panic(expected="assertion failed")]
    fn one_is_not_prime() {
        assert!(!is_prime(1));
    }

    #[test]
    fn there_are_168_primes_under_1000() {
        let primes = (1..1000).filter(|n| is_prime(*n)).count();
        assert_eq!(primes, 168);
    }

    #[test]
    fn example_factors() {
        assert_eq!(factorize(13195), vec![5, 7, 13, 29]);
    }

    #[test]
    fn factors_repeating() { // TODO: this is not what I wanted
        factorize_fun(12);
        assert_eq!(factorize(12), vec![2, 2, 3]);
    }

    #[test]
    fn example() {
        assert_eq!(largest_prime_factor(13195), 29);
    }

    #[test]
    fn solution() {
        assert_eq!(largest_prime_factor(600851475143), 6857);
    }
}
<|endoftext|>


<commit_before>use headers::serialization_utils::{push_quoted_string, quoted_string, WriterUtil};
use std::rt::io::{Reader, Writer};

#[deriving(Clone, Eq)]
pub struct EntityTag {
    weak: bool,
    opaque_tag: ~str,
}

pub fn weak_etag<S: Str>(opaque_tag: S) -> EntityTag {
    EntityTag {
        weak: true,
        opaque_tag: opaque_tag.into_owned(),
    }
}

pub fn strong_etag<S: Str>(opaque_tag: S) -> EntityTag {
    EntityTag {
        weak: false,
        opaque_tag: opaque_tag.into_owned(),
    }
}

impl ToStr for EntityTag {
    fn to_str(&self) -> ~str {
        if self.weak {
            push_quoted_string(~"W/", self.opaque_tag)
        } else {
            quoted_string(self.opaque_tag)
        }
    }
}

impl super::HeaderConvertible for EntityTag {
    fn from_stream<R: Reader>(reader: &mut super::HeaderValueByteIterator<R>) -> Option<EntityTag> {
        let weak = match reader.next() {
            Some(b) if b == 'W' as u8 => {
                if reader.next() != Some('/' as u8) || reader.next() != Some('"' as u8) {
                    return None;
                }
                true
            },
            Some(b) if b == '"' as u8 => {
                false
            },
            _ => {
                return None;
            }
        };
        let opaque_tag = match reader.read_quoted_string(true) {
            Some(tag) => tag,
            None => return None,
        };
        reader.some_if_consumed(EntityTag {
            weak: weak,
            opaque_tag: opaque_tag,
        })
    }

    fn to_stream<W: Writer>(&self, writer: &mut W) {
        if self.weak {
            writer.write(bytes!("W/"));
        }
        writer.write_quoted_string(self.opaque_tag);
    }

    fn http_value(&self) -> ~str {
        self.to_str()
    }
}

#[test]
fn test_etag() {
    use headers::test_utils::*;
    assert_conversion_correct("\"\"", strong_etag(""));
    assert_conversion_correct("\"fO0\"", strong_etag("fO0"));
    assert_conversion_correct("\"fO0 bar\"", strong_etag("fO0 bar"));
    assert_conversion_correct("\"fO0 \\\"bar\"", strong_etag("fO0 \"bar"));
    assert_conversion_correct("\"fO0 \\\"bar\\\"\"", strong_etag("fO0 \"bar\""));

    assert_conversion_correct("W/\"\"", weak_etag(""));
    assert_conversion_correct("W/\"fO0\"", weak_etag("fO0"));
    assert_conversion_correct("W/\"fO0 bar\"", weak_etag("fO0 bar"));
    assert_conversion_correct("W/\"fO0 \\\"bar\"", weak_etag("fO0 \"bar"));
    assert_conversion_correct("W/\"fO0 \\\"bar\\\"\"", weak_etag("fO0 \"bar\""));
    assert_interpretation_correct("w/\"fO0\"", weak_etag("fO0"));

    assert_invalid::<EntityTag>("");
    assert_invalid::<EntityTag>("fO0");
    assert_invalid::<EntityTag>("\"\\\"");
    assert_invalid::<EntityTag>("\"\"\"\"");
}
<commit_msg>Make entity-tag W/ case insensitive (fixes a test).<commit_after>use headers::serialization_utils::{push_quoted_string, quoted_string, WriterUtil};
use std::rt::io::{Reader, Writer};

#[deriving(Clone, Eq)]
pub struct EntityTag {
    weak: bool,
    opaque_tag: ~str,
}

pub fn weak_etag<S: Str>(opaque_tag: S) -> EntityTag {
    EntityTag {
        weak: true,
        opaque_tag: opaque_tag.into_owned(),
    }
}

pub fn strong_etag<S: Str>(opaque_tag: S) -> EntityTag {
    EntityTag {
        weak: false,
        opaque_tag: opaque_tag.into_owned(),
    }
}

impl ToStr for EntityTag {
    fn to_str(&self) -> ~str {
        if self.weak {
            push_quoted_string(~"W/", self.opaque_tag)
        } else {
            quoted_string(self.opaque_tag)
        }
    }
}

impl super::HeaderConvertible for EntityTag {
    fn from_stream<R: Reader>(reader: &mut super::HeaderValueByteIterator<R>) -> Option<EntityTag> {
        let weak = match reader.next() {
            Some(b) if b == 'W' as u8 || b == 'w' as u8 => {
                if reader.next() != Some('/' as u8) || reader.next() != Some('"' as u8) {
                    return None;
                }
                true
            },
            Some(b) if b == '"' as u8 => {
                false
            },
            _ => {
                return None;
            }
        };
        let opaque_tag = match reader.read_quoted_string(true) {
            Some(tag) => tag,
            None => return None,
        };
        reader.some_if_consumed(EntityTag {
            weak: weak,
            opaque_tag: opaque_tag,
        })
    }

    fn to_stream<W: Writer>(&self, writer: &mut W) {
        if self.weak {
            writer.write(bytes!("W/"));
        }
        writer.write_quoted_string(self.opaque_tag);
    }

    fn http_value(&self) -> ~str {
        self.to_str()
    }
}

#[test]
fn test_etag() {
    use headers::test_utils::*;
    assert_conversion_correct("\"\"", strong_etag(""));
    assert_conversion_correct("\"fO0\"", strong_etag("fO0"));
    assert_conversion_correct("\"fO0 bar\"", strong_etag("fO0 bar"));
    assert_conversion_correct("\"fO0 \\\"bar\"", strong_etag("fO0 \"bar"));
    assert_conversion_correct("\"fO0 \\\"bar\\\"\"", strong_etag("fO0 \"bar\""));

    assert_conversion_correct("W/\"\"", weak_etag(""));
    assert_conversion_correct("W/\"fO0\"", weak_etag("fO0"));
    assert_conversion_correct("W/\"fO0 bar\"", weak_etag("fO0 bar"));
    assert_conversion_correct("W/\"fO0 \\\"bar\"", weak_etag("fO0 \"bar"));
    assert_conversion_correct("W/\"fO0 \\\"bar\\\"\"", weak_etag("fO0 \"bar\""));
    assert_interpretation_correct("w/\"fO0\"", weak_etag("fO0"));

    assert_invalid::<EntityTag>("");
    assert_invalid::<EntityTag>("fO0");
    assert_invalid::<EntityTag>("\"\\\"");
    assert_invalid::<EntityTag>("\"\"\"\"");
}
<|endoftext|>


<commit_before>use crate::ops::Try;
use crate::usize;

use super::super::{Iterator, DoubleEndedIterator, FusedIterator, TrustedLen};

/// An iterator that strings two iterators together.
///
/// This `struct` is created by the [`chain`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`chain`]: trait.Iterator.html#method.chain
/// [`Iterator`]: trait.Iterator.html
#[derive(Clone, Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Chain<A, B> {
    a: A,
    b: B,
    state: ChainState,
}
impl<A, B> Chain<A, B> {
    pub(in super::super) fn new(a: A, b: B) -> Chain<A, B> {
        Chain { a, b, state: ChainState::Both }
    }
}

// The iterator protocol specifies that iteration ends with the return value
// `None` from `.next()` (or `.next_back()`) and it is unspecified what
// further calls return. The chain adaptor must account for this since it uses
// two subiterators.
//
//  It uses three states:
//
//  - Both: `a` and `b` are remaining
//  - Front: `a` remaining
//  - Back: `b` remaining
//
//  The fourth state (neither iterator is remaining) only occurs after Chain has
//  returned None once, so we don't need to store this state.
#[derive(Clone, Debug)]
enum ChainState {
    // both front and back iterator are remaining
    Both,
    // only front is remaining
    Front,
    // only back is remaining
    Back,
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A, B> Iterator for Chain<A, B> where
    A: Iterator,
    B: Iterator<Item = A::Item>
{
    type Item = A::Item;

    #[inline]
    fn next(&mut self) -> Option<A::Item> {
        match self.state {
            ChainState::Both => match self.a.next() {
                elt @ Some(..) => elt,
                None => {
                    self.state = ChainState::Back;
                    self.b.next()
                }
            },
            ChainState::Front => self.a.next(),
            ChainState::Back => self.b.next(),
        }
    }

    #[inline]
    #[rustc_inherit_overflow_checks]
    fn count(self) -> usize {
        match self.state {
            ChainState::Both => self.a.count() + self.b.count(),
            ChainState::Front => self.a.count(),
            ChainState::Back => self.b.count(),
        }
    }

    fn try_fold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R where
        Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
    {
        let mut accum = init;
        match self.state {
            ChainState::Both | ChainState::Front => {
                accum = self.a.try_fold(accum, &mut f)?;
                if let ChainState::Both = self.state {
                    self.state = ChainState::Back;
                }
            }
            _ => { }
        }
        if let ChainState::Back = self.state {
            accum = self.b.try_fold(accum, &mut f)?;
        }
        Try::from_ok(accum)
    }

    fn fold<Acc, F>(self, init: Acc, mut f: F) -> Acc
        where F: FnMut(Acc, Self::Item) -> Acc,
    {
        let mut accum = init;
        match self.state {
            ChainState::Both | ChainState::Front => {
                accum = self.a.fold(accum, &mut f);
            }
            _ => { }
        }
        match self.state {
            ChainState::Both | ChainState::Back => {
                accum = self.b.fold(accum, &mut f);
            }
            _ => { }
        }
        accum
    }

    #[inline]
    fn nth(&mut self, mut n: usize) -> Option<A::Item> {
        match self.state {
            ChainState::Both | ChainState::Front => {
                for x in self.a.by_ref() {
                    if n == 0 {
                        return Some(x)
                    }
                    n -= 1;
                }
                if let ChainState::Both = self.state {
                    self.state = ChainState::Back;
                }
            }
            ChainState::Back => {}
        }
        if let ChainState::Back = self.state {
            self.b.nth(n)
        } else {
            None
        }
    }

    #[inline]
    fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item> where
        P: FnMut(&Self::Item) -> bool,
    {
        match self.state {
            ChainState::Both => match self.a.find(&mut predicate) {
                None => {
                    self.state = ChainState::Back;
                    self.b.find(predicate)
                }
                v => v
            },
            ChainState::Front => self.a.find(predicate),
            ChainState::Back => self.b.find(predicate),
        }
    }

    #[inline]
    fn last(self) -> Option<A::Item> {
        match self.state {
            ChainState::Both => {
                // Must exhaust a before b.
                let a_last = self.a.last();
                let b_last = self.b.last();
                b_last.or(a_last)
            },
            ChainState::Front => self.a.last(),
            ChainState::Back => self.b.last()
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        match self.state {
            ChainState::Both => {
                let (a_lower, a_upper) = self.a.size_hint();
                let (b_lower, b_upper) = self.b.size_hint();

                let lower = a_lower.saturating_add(b_lower);

                let upper = match (a_upper, b_upper) {
                    (Some(x), Some(y)) => x.checked_add(y),
                    _ => None
                };

                (lower, upper)
            }
            ChainState::Front => self.a.size_hint(),
            ChainState::Back => self.b.size_hint(),
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A, B> DoubleEndedIterator for Chain<A, B> where
    A: DoubleEndedIterator,
    B: DoubleEndedIterator<Item=A::Item>,
{
    #[inline]
    fn next_back(&mut self) -> Option<A::Item> {
        match self.state {
            ChainState::Both => match self.b.next_back() {
                elt @ Some(..) => elt,
                None => {
                    self.state = ChainState::Front;
                    self.a.next_back()
                }
            },
            ChainState::Front => self.a.next_back(),
            ChainState::Back => self.b.next_back(),
        }
    }

    #[inline]
    fn nth_back(&mut self, mut n: usize) -> Option<A::Item> {
        match self.state {
            ChainState::Both | ChainState::Back => {
                for x in self.b.by_ref().rev() {
                    if n == 0 {
                        return Some(x)
                    }
                    n -= 1;
                }
                if let ChainState::Both = self.state {
                    self.state = ChainState::Front;
                }
            }
            ChainState::Front => {}
        }
        if let ChainState::Front = self.state {
            self.a.nth_back(n)
        } else {
            None
        }
    }

    fn try_rfold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R where
        Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
    {
        let mut accum = init;
        match self.state {
            ChainState::Both | ChainState::Back => {
                accum = self.b.try_rfold(accum, &mut f)?;
                if let ChainState::Both = self.state {
                    self.state = ChainState::Front;
                }
            }
            _ => { }
        }
        if let ChainState::Front = self.state {
            accum = self.a.try_rfold(accum, &mut f)?;
        }
        Try::from_ok(accum)
    }

    fn rfold<Acc, F>(self, init: Acc, mut f: F) -> Acc
        where F: FnMut(Acc, Self::Item) -> Acc,
    {
        let mut accum = init;
        match self.state {
            ChainState::Both | ChainState::Back => {
                accum = self.b.rfold(accum, &mut f);
            }
            _ => { }
        }
        match self.state {
            ChainState::Both | ChainState::Front => {
                accum = self.a.rfold(accum, &mut f);
            }
            _ => { }
        }
        accum
    }

}

// Note: *both* must be fused to handle double-ended iterators.
#[stable(feature = "fused", since = "1.26.0")]
impl<A, B> FusedIterator for Chain<A, B>
    where A: FusedIterator,
          B: FusedIterator<Item=A::Item>,
{}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A, B> TrustedLen for Chain<A, B>
    where A: TrustedLen, B: TrustedLen<Item=A::Item>,
{}
<commit_msg>Fixed std::iter::Chain documentation<commit_after>use crate::ops::Try;
use crate::usize;

use super::super::{Iterator, DoubleEndedIterator, FusedIterator, TrustedLen};

/// An iterator that links two iterators together, in a chain.
///
/// This `struct` is created by the [`chain`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`chain`]: trait.Iterator.html#method.chain
/// [`Iterator`]: trait.Iterator.html
#[derive(Clone, Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Chain<A, B> {
    a: A,
    b: B,
    state: ChainState,
}
impl<A, B> Chain<A, B> {
    pub(in super::super) fn new(a: A, b: B) -> Chain<A, B> {
        Chain { a, b, state: ChainState::Both }
    }
}

// The iterator protocol specifies that iteration ends with the return value
// `None` from `.next()` (or `.next_back()`) and it is unspecified what
// further calls return. The chain adaptor must account for this since it uses
// two subiterators.
//
//  It uses three states:
//
//  - Both: `a` and `b` are remaining
//  - Front: `a` remaining
//  - Back: `b` remaining
//
//  The fourth state (neither iterator is remaining) only occurs after Chain has
//  returned None once, so we don't need to store this state.
#[derive(Clone, Debug)]
enum ChainState {
    // both front and back iterator are remaining
    Both,
    // only front is remaining
    Front,
    // only back is remaining
    Back,
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A, B> Iterator for Chain<A, B> where
    A: Iterator,
    B: Iterator<Item = A::Item>
{
    type Item = A::Item;

    #[inline]
    fn next(&mut self) -> Option<A::Item> {
        match self.state {
            ChainState::Both => match self.a.next() {
                elt @ Some(..) => elt,
                None => {
                    self.state = ChainState::Back;
                    self.b.next()
                }
            },
            ChainState::Front => self.a.next(),
            ChainState::Back => self.b.next(),
        }
    }

    #[inline]
    #[rustc_inherit_overflow_checks]
    fn count(self) -> usize {
        match self.state {
            ChainState::Both => self.a.count() + self.b.count(),
            ChainState::Front => self.a.count(),
            ChainState::Back => self.b.count(),
        }
    }

    fn try_fold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R where
        Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
    {
        let mut accum = init;
        match self.state {
            ChainState::Both | ChainState::Front => {
                accum = self.a.try_fold(accum, &mut f)?;
                if let ChainState::Both = self.state {
                    self.state = ChainState::Back;
                }
            }
            _ => { }
        }
        if let ChainState::Back = self.state {
            accum = self.b.try_fold(accum, &mut f)?;
        }
        Try::from_ok(accum)
    }

    fn fold<Acc, F>(self, init: Acc, mut f: F) -> Acc
        where F: FnMut(Acc, Self::Item) -> Acc,
    {
        let mut accum = init;
        match self.state {
            ChainState::Both | ChainState::Front => {
                accum = self.a.fold(accum, &mut f);
            }
            _ => { }
        }
        match self.state {
            ChainState::Both | ChainState::Back => {
                accum = self.b.fold(accum, &mut f);
            }
            _ => { }
        }
        accum
    }

    #[inline]
    fn nth(&mut self, mut n: usize) -> Option<A::Item> {
        match self.state {
            ChainState::Both | ChainState::Front => {
                for x in self.a.by_ref() {
                    if n == 0 {
                        return Some(x)
                    }
                    n -= 1;
                }
                if let ChainState::Both = self.state {
                    self.state = ChainState::Back;
                }
            }
            ChainState::Back => {}
        }
        if let ChainState::Back = self.state {
            self.b.nth(n)
        } else {
            None
        }
    }

    #[inline]
    fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item> where
        P: FnMut(&Self::Item) -> bool,
    {
        match self.state {
            ChainState::Both => match self.a.find(&mut predicate) {
                None => {
                    self.state = ChainState::Back;
                    self.b.find(predicate)
                }
                v => v
            },
            ChainState::Front => self.a.find(predicate),
            ChainState::Back => self.b.find(predicate),
        }
    }

    #[inline]
    fn last(self) -> Option<A::Item> {
        match self.state {
            ChainState::Both => {
                // Must exhaust a before b.
                let a_last = self.a.last();
                let b_last = self.b.last();
                b_last.or(a_last)
            },
            ChainState::Front => self.a.last(),
            ChainState::Back => self.b.last()
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        match self.state {
            ChainState::Both => {
                let (a_lower, a_upper) = self.a.size_hint();
                let (b_lower, b_upper) = self.b.size_hint();

                let lower = a_lower.saturating_add(b_lower);

                let upper = match (a_upper, b_upper) {
                    (Some(x), Some(y)) => x.checked_add(y),
                    _ => None
                };

                (lower, upper)
            }
            ChainState::Front => self.a.size_hint(),
            ChainState::Back => self.b.size_hint(),
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A, B> DoubleEndedIterator for Chain<A, B> where
    A: DoubleEndedIterator,
    B: DoubleEndedIterator<Item=A::Item>,
{
    #[inline]
    fn next_back(&mut self) -> Option<A::Item> {
        match self.state {
            ChainState::Both => match self.b.next_back() {
                elt @ Some(..) => elt,
                None => {
                    self.state = ChainState::Front;
                    self.a.next_back()
                }
            },
            ChainState::Front => self.a.next_back(),
            ChainState::Back => self.b.next_back(),
        }
    }

    #[inline]
    fn nth_back(&mut self, mut n: usize) -> Option<A::Item> {
        match self.state {
            ChainState::Both | ChainState::Back => {
                for x in self.b.by_ref().rev() {
                    if n == 0 {
                        return Some(x)
                    }
                    n -= 1;
                }
                if let ChainState::Both = self.state {
                    self.state = ChainState::Front;
                }
            }
            ChainState::Front => {}
        }
        if let ChainState::Front = self.state {
            self.a.nth_back(n)
        } else {
            None
        }
    }

    fn try_rfold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R where
        Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
    {
        let mut accum = init;
        match self.state {
            ChainState::Both | ChainState::Back => {
                accum = self.b.try_rfold(accum, &mut f)?;
                if let ChainState::Both = self.state {
                    self.state = ChainState::Front;
                }
            }
            _ => { }
        }
        if let ChainState::Front = self.state {
            accum = self.a.try_rfold(accum, &mut f)?;
        }
        Try::from_ok(accum)
    }

    fn rfold<Acc, F>(self, init: Acc, mut f: F) -> Acc
        where F: FnMut(Acc, Self::Item) -> Acc,
    {
        let mut accum = init;
        match self.state {
            ChainState::Both | ChainState::Back => {
                accum = self.b.rfold(accum, &mut f);
            }
            _ => { }
        }
        match self.state {
            ChainState::Both | ChainState::Front => {
                accum = self.a.rfold(accum, &mut f);
            }
            _ => { }
        }
        accum
    }

}

// Note: *both* must be fused to handle double-ended iterators.
#[stable(feature = "fused", since = "1.26.0")]
impl<A, B> FusedIterator for Chain<A, B>
    where A: FusedIterator,
          B: FusedIterator<Item=A::Item>,
{}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A, B> TrustedLen for Chain<A, B>
    where A: TrustedLen, B: TrustedLen<Item=A::Item>,
{}
<|endoftext|>


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

use infer::{GenericKind, InferCtxt};
use infer::outlives::free_region_map::FreeRegionMap;
use traits::query::outlives_bounds::{self, OutlivesBound};
use ty::{self, Ty};

use syntax::ast;
use syntax_pos::Span;

/// The `OutlivesEnvironment` collects information about what outlives
/// what in a given type-checking setting. For example, if we have a
/// where-clause like `where T: 'a` in scope, then the
/// `OutlivesEnvironment` would record that (in its
/// `region_bound_pairs` field). Similarly, it contains methods for
/// processing and adding implied bounds into the outlives
/// environment.
///
/// Other code at present does not typically take a
/// `&OutlivesEnvironment`, but rather takes some of its fields (e.g.,
/// `process_registered_region_obligations` wants the
/// region-bound-pairs). There is no mistaking it: the current setup
/// of tracking region information is quite scattered! The
/// `OutlivesEnvironment`, for example, needs to sometimes be combined
/// with the `middle::RegionRelations`, to yield a full picture of how
/// (lexical) lifetimes interact. However, I'm reluctant to do more
/// refactoring here, since the setup with NLL is quite different.
/// For example, NLL has no need of `RegionRelations`, and is solely
/// interested in the `OutlivesEnvironment`. -nmatsakis
#[derive(Clone)]
pub struct OutlivesEnvironment<'tcx> {
    param_env: ty::ParamEnv<'tcx>,
    free_region_map: FreeRegionMap<'tcx>,
    region_bound_pairs: Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>,
}

impl<'a, 'gcx: 'tcx, 'tcx: 'a> OutlivesEnvironment<'tcx> {
    pub fn new(param_env: ty::ParamEnv<'tcx>) -> Self {
        let mut env = OutlivesEnvironment {
            param_env,
            free_region_map: FreeRegionMap::new(),
            region_bound_pairs: vec![],
        };

        env.add_outlives_bounds(None, outlives_bounds::explicit_outlives_bounds(param_env));

        env
    }

    /// Borrows current value of the `free_region_map`.
    pub fn free_region_map(&self) -> &FreeRegionMap<'tcx> {
        &self.free_region_map
    }

    /// Borrows current value of the `region_bound_pairs`.
    pub fn region_bound_pairs(&self) -> &[(ty::Region<'tcx>, GenericKind<'tcx>)] {
        &self.region_bound_pairs
    }

    /// Returns ownership of the `free_region_map`.
    pub fn into_free_region_map(self) -> FreeRegionMap<'tcx> {
        self.free_region_map
    }

    /// This is a hack to support the old-skool regionck, which
    /// processes region constraints from the main function and the
    /// closure together. In that context, when we enter a closure, we
    /// want to be able to "save" the state of the surrounding a
    /// function. We can then add implied bounds and the like from the
    /// closure arguments into the environment -- these should only
    /// apply in the closure body, so once we exit, we invoke
    /// `pop_snapshot_post_closure` to remove them.
    ///
    /// Example:
    ///
    /// ```
    /// fn foo<T>() {
    ///    callback(for<'a> |x: &'a T| {
    ///         // ^^^^^^^ not legal syntax, but probably should be
    ///         // within this closure body, `T: 'a` holds
    ///    })
    /// }
    /// ```
    ///
    /// This "containment" of closure's effects only works so well. In
    /// particular, we (intentionally) leak relationships between free
    /// regions that are created by the closure's bounds. The case
    /// where this is useful is when you have (e.g.) a closure with a
    /// signature like `for<'a, 'b> fn(x: &'a &'b u32)` -- in this
    /// case, we want to keep the relationship `'b: 'a` in the
    /// free-region-map, so that later if we have to take `LUB('b,
    /// 'a)` we can get the result `'b`.
    ///
    /// I have opted to keep **all modifications** to the
    /// free-region-map, however, and not just those that concern free
    /// variables bound in the closure. The latter seems more correct,
    /// but it is not the existing behavior, and I could not find a
    /// case where the existing behavior went wrong. In any case, it
    /// seems like it'd be readily fixed if we wanted. There are
    /// similar leaks around givens that seem equally suspicious, to
    /// be honest. --nmatsakis
    pub fn push_snapshot_pre_closure(&self) -> usize {
        self.region_bound_pairs.len()
    }

    /// See `push_snapshot_pre_closure`.
    pub fn pop_snapshot_post_closure(&mut self, len: usize) {
        self.region_bound_pairs.truncate(len);
    }

    /// This method adds "implied bounds" into the outlives environment.
    /// Implied bounds are outlives relationships that we can deduce
    /// on the basis that certain types must be well-formed -- these are
    /// either the types that appear in the function signature or else
    /// the input types to an impl. For example, if you have a function
    /// like
    ///
    /// ```
    /// fn foo<'a, 'b, T>(x: &'a &'b [T]) { }
    /// ```
    ///
    /// we can assume in the caller's body that `'b: 'a` and that `T:
    /// 'b` (and hence, transitively, that `T: 'a`). This method would
    /// add those assumptions into the outlives-environment.
    ///
    /// Tests: `src/test/compile-fail/regions-free-region-ordering-*.rs`
    pub fn add_implied_bounds(
        &mut self,
        infcx: &InferCtxt<'a, 'gcx, 'tcx>,
        fn_sig_tys: &[Ty<'tcx>],
        body_id: ast::NodeId,
        span: Span,
    ) {
        debug!("add_implied_bounds()");

        for &ty in fn_sig_tys {
            let ty = infcx.resolve_type_vars_if_possible(&ty);
            debug!("add_implied_bounds: ty = {}", ty);
            let implied_bounds = infcx.implied_outlives_bounds(self.param_env, body_id, ty, span);
            self.add_outlives_bounds(Some(infcx), implied_bounds)
        }
    }

    /// Processes outlives bounds that are known to hold, whether from implied or other sources.
    ///
    /// The `infcx` parameter is optional; if the implied bounds may
    /// contain inference variables, it must be supplied, in which
    /// case we will register "givens" on the inference context. (See
    /// `RegionConstraintData`.)
    fn add_outlives_bounds<I>(
        &mut self,
        infcx: Option<&InferCtxt<'a, 'gcx, 'tcx>>,
        outlives_bounds: I,
    ) where
        I: IntoIterator<Item = OutlivesBound<'tcx>>,
    {
        // Record relationships such as `T:'x` that don't go into the
        // free-region-map but which we use here.
        for outlives_bound in outlives_bounds {
            debug!("add_outlives_bounds: outlives_bound={:?}", outlives_bound);
            match outlives_bound {
                OutlivesBound::RegionSubRegion(r_a @ &ty::ReEarlyBound(_), &ty::ReVar(vid_b)) |
                OutlivesBound::RegionSubRegion(r_a @ &ty::ReFree(_), &ty::ReVar(vid_b)) => {
                    infcx.expect("no infcx provided but region vars found").add_given(r_a, vid_b);
                }
                OutlivesBound::RegionSubParam(r_a, param_b) => {
                    self.region_bound_pairs
                        .push((r_a, GenericKind::Param(param_b)));
                }
                OutlivesBound::RegionSubProjection(r_a, projection_b) => {
                    self.region_bound_pairs
                        .push((r_a, GenericKind::Projection(projection_b)));
                }
                OutlivesBound::RegionSubRegion(r_a, r_b) => {
                    // In principle, we could record (and take
                    // advantage of) every relationship here, but
                    // we are also free not to -- it simply means
                    // strictly less that we can successfully type
                    // check. Right now we only look for things
                    // relationships between free regions. (It may
                    // also be that we should revise our inference
                    // system to be more general and to make use
                    // of *every* relationship that arises here,
                    // but presently we do not.)
                    self.free_region_map.relate_regions(r_a, r_b);
                }
            }
        }
    }
}
<commit_msg>outlives/env: rustfmt<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use infer::outlives::free_region_map::FreeRegionMap;
use infer::{GenericKind, InferCtxt};
use traits::query::outlives_bounds::{self, OutlivesBound};
use ty::{self, Ty};

use syntax::ast;
use syntax_pos::Span;

/// The `OutlivesEnvironment` collects information about what outlives
/// what in a given type-checking setting. For example, if we have a
/// where-clause like `where T: 'a` in scope, then the
/// `OutlivesEnvironment` would record that (in its
/// `region_bound_pairs` field). Similarly, it contains methods for
/// processing and adding implied bounds into the outlives
/// environment.
///
/// Other code at present does not typically take a
/// `&OutlivesEnvironment`, but rather takes some of its fields (e.g.,
/// `process_registered_region_obligations` wants the
/// region-bound-pairs). There is no mistaking it: the current setup
/// of tracking region information is quite scattered! The
/// `OutlivesEnvironment`, for example, needs to sometimes be combined
/// with the `middle::RegionRelations`, to yield a full picture of how
/// (lexical) lifetimes interact. However, I'm reluctant to do more
/// refactoring here, since the setup with NLL is quite different.
/// For example, NLL has no need of `RegionRelations`, and is solely
/// interested in the `OutlivesEnvironment`. -nmatsakis
#[derive(Clone)]
pub struct OutlivesEnvironment<'tcx> {
    param_env: ty::ParamEnv<'tcx>,
    free_region_map: FreeRegionMap<'tcx>,
    region_bound_pairs: Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>,
}

impl<'a, 'gcx: 'tcx, 'tcx: 'a> OutlivesEnvironment<'tcx> {
    pub fn new(param_env: ty::ParamEnv<'tcx>) -> Self {
        let mut env = OutlivesEnvironment {
            param_env,
            free_region_map: FreeRegionMap::new(),
            region_bound_pairs: vec![],
        };

        env.add_outlives_bounds(None, outlives_bounds::explicit_outlives_bounds(param_env));

        env
    }

    /// Borrows current value of the `free_region_map`.
    pub fn free_region_map(&self) -> &FreeRegionMap<'tcx> {
        &self.free_region_map
    }

    /// Borrows current value of the `region_bound_pairs`.
    pub fn region_bound_pairs(&self) -> &[(ty::Region<'tcx>, GenericKind<'tcx>)] {
        &self.region_bound_pairs
    }

    /// Returns ownership of the `free_region_map`.
    pub fn into_free_region_map(self) -> FreeRegionMap<'tcx> {
        self.free_region_map
    }

    /// This is a hack to support the old-skool regionck, which
    /// processes region constraints from the main function and the
    /// closure together. In that context, when we enter a closure, we
    /// want to be able to "save" the state of the surrounding a
    /// function. We can then add implied bounds and the like from the
    /// closure arguments into the environment -- these should only
    /// apply in the closure body, so once we exit, we invoke
    /// `pop_snapshot_post_closure` to remove them.
    ///
    /// Example:
    ///
    /// ```
    /// fn foo<T>() {
    ///    callback(for<'a> |x: &'a T| {
    ///         // ^^^^^^^ not legal syntax, but probably should be
    ///         // within this closure body, `T: 'a` holds
    ///    })
    /// }
    /// ```
    ///
    /// This "containment" of closure's effects only works so well. In
    /// particular, we (intentionally) leak relationships between free
    /// regions that are created by the closure's bounds. The case
    /// where this is useful is when you have (e.g.) a closure with a
    /// signature like `for<'a, 'b> fn(x: &'a &'b u32)` -- in this
    /// case, we want to keep the relationship `'b: 'a` in the
    /// free-region-map, so that later if we have to take `LUB('b,
    /// 'a)` we can get the result `'b`.
    ///
    /// I have opted to keep **all modifications** to the
    /// free-region-map, however, and not just those that concern free
    /// variables bound in the closure. The latter seems more correct,
    /// but it is not the existing behavior, and I could not find a
    /// case where the existing behavior went wrong. In any case, it
    /// seems like it'd be readily fixed if we wanted. There are
    /// similar leaks around givens that seem equally suspicious, to
    /// be honest. --nmatsakis
    pub fn push_snapshot_pre_closure(&self) -> usize {
        self.region_bound_pairs.len()
    }

    /// See `push_snapshot_pre_closure`.
    pub fn pop_snapshot_post_closure(&mut self, len: usize) {
        self.region_bound_pairs.truncate(len);
    }

    /// This method adds "implied bounds" into the outlives environment.
    /// Implied bounds are outlives relationships that we can deduce
    /// on the basis that certain types must be well-formed -- these are
    /// either the types that appear in the function signature or else
    /// the input types to an impl. For example, if you have a function
    /// like
    ///
    /// ```
    /// fn foo<'a, 'b, T>(x: &'a &'b [T]) { }
    /// ```
    ///
    /// we can assume in the caller's body that `'b: 'a` and that `T:
    /// 'b` (and hence, transitively, that `T: 'a`). This method would
    /// add those assumptions into the outlives-environment.
    ///
    /// Tests: `src/test/compile-fail/regions-free-region-ordering-*.rs`
    pub fn add_implied_bounds(
        &mut self,
        infcx: &InferCtxt<'a, 'gcx, 'tcx>,
        fn_sig_tys: &[Ty<'tcx>],
        body_id: ast::NodeId,
        span: Span,
    ) {
        debug!("add_implied_bounds()");

        for &ty in fn_sig_tys {
            let ty = infcx.resolve_type_vars_if_possible(&ty);
            debug!("add_implied_bounds: ty = {}", ty);
            let implied_bounds = infcx.implied_outlives_bounds(self.param_env, body_id, ty, span);
            self.add_outlives_bounds(Some(infcx), implied_bounds)
        }
    }

    /// Processes outlives bounds that are known to hold, whether from implied or other sources.
    ///
    /// The `infcx` parameter is optional; if the implied bounds may
    /// contain inference variables, it must be supplied, in which
    /// case we will register "givens" on the inference context. (See
    /// `RegionConstraintData`.)
    fn add_outlives_bounds<I>(
        &mut self,
        infcx: Option<&InferCtxt<'a, 'gcx, 'tcx>>,
        outlives_bounds: I,
    ) where
        I: IntoIterator<Item = OutlivesBound<'tcx>>,
    {
        // Record relationships such as `T:'x` that don't go into the
        // free-region-map but which we use here.
        for outlives_bound in outlives_bounds {
            debug!("add_outlives_bounds: outlives_bound={:?}", outlives_bound);
            match outlives_bound {
                OutlivesBound::RegionSubRegion(r_a @ &ty::ReEarlyBound(_), &ty::ReVar(vid_b))
                | OutlivesBound::RegionSubRegion(r_a @ &ty::ReFree(_), &ty::ReVar(vid_b)) => {
                    infcx
                        .expect("no infcx provided but region vars found")
                        .add_given(r_a, vid_b);
                }
                OutlivesBound::RegionSubParam(r_a, param_b) => {
                    self.region_bound_pairs
                        .push((r_a, GenericKind::Param(param_b)));
                }
                OutlivesBound::RegionSubProjection(r_a, projection_b) => {
                    self.region_bound_pairs
                        .push((r_a, GenericKind::Projection(projection_b)));
                }
                OutlivesBound::RegionSubRegion(r_a, r_b) => {
                    // In principle, we could record (and take
                    // advantage of) every relationship here, but
                    // we are also free not to -- it simply means
                    // strictly less that we can successfully type
                    // check. Right now we only look for things
                    // relationships between free regions. (It may
                    // also be that we should revise our inference
                    // system to be more general and to make use
                    // of *every* relationship that arises here,
                    // but presently we do not.)
                    self.free_region_map.relate_regions(r_a, r_b);
                }
            }
        }
    }
}
<|endoftext|>


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

//! A single-producer single-consumer concurrent queue
//!
//! This module contains the implementation of an SPSC queue which can be used
//! concurrently between two threads. This data structure is safe to use and
//! enforces the semantics that there is one pusher and one popper.

// http://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue

use alloc::boxed::Box;
use core::ptr;
use core::cell::UnsafeCell;

use sync::atomic::{AtomicPtr, AtomicUsize, Ordering};

use super::cache_aligned::CacheAligned;

// Node within the linked list queue of messages to send
struct Node<T> {
    // FIXME: this could be an uninitialized T if we're careful enough, and
    //      that would reduce memory usage (and be a bit faster).
    //      is it worth it?
    value: Option<T>,           // nullable for re-use of nodes
    cached: bool,               // This node goes into the node cache
    next: AtomicPtr<Node<T>>,   // next node in the queue
}

/// The single-producer single-consumer queue. This structure is not cloneable,
/// but it can be safely shared in an Arc if it is guaranteed that there
/// is only one popper and one pusher touching the queue at any one point in
/// time.
pub struct Queue<T, ProducerAddition=(), ConsumerAddition=()> {
    // consumer fields
    consumer: CacheAligned<Consumer<T, ConsumerAddition>>,

    // producer fields
    producer: CacheAligned<Producer<T, ProducerAddition>>,
}

struct Consumer<T, Addition> {
    tail: UnsafeCell<*mut Node<T>>, // where to pop from
    tail_prev: AtomicPtr<Node<T>>, // where to pop from
    cache_bound: usize, // maximum cache size
    cached_nodes: AtomicUsize, // number of nodes marked as cachable
    addition: Addition,
}

struct Producer<T, Addition> {
    head: UnsafeCell<*mut Node<T>>,      // where to push to
    first: UnsafeCell<*mut Node<T>>,     // where to get new nodes from
    tail_copy: UnsafeCell<*mut Node<T>>, // between first/tail
    addition: Addition,
}

unsafe impl<T: Send, P: Send + Sync, C: Send + Sync> Send for Queue<T, P, C> { }

unsafe impl<T: Send, P: Send + Sync, C: Send + Sync> Sync for Queue<T, P, C> { }

impl<T> Node<T> {
    fn new() -> *mut Node<T> {
        Box::into_raw(box Node {
            value: None,
            cached: false,
            next: AtomicPtr::new(ptr::null_mut::<Node<T>>()),
        })
    }
}

impl<T> Queue<T> {
    #[cfg(all(test, not(target_os = "emscripten")))]
    /// Creates a new queue.
    ///
    /// This is unsafe as the type system doesn't enforce a single
    /// consumer-producer relationship. It also allows the consumer to `pop`
    /// items while there is a `peek` active due to all methods having a
    /// non-mutable receiver.
    ///
    /// # Arguments
    ///
    ///   * `bound` - This queue implementation is implemented with a linked
    ///               list, and this means that a push is always a malloc. In
    ///               order to amortize this cost, an internal cache of nodes is
    ///               maintained to prevent a malloc from always being
    ///               necessary. This bound is the limit on the size of the
    ///               cache (if desired). If the value is 0, then the cache has
    ///               no bound. Otherwise, the cache will never grow larger than
    ///               `bound` (although the queue itself could be much larger.
    pub unsafe fn new(bound: usize) -> Queue<T> {
        Self::with_additions(bound, (), ())
    }
}

impl<T, ProducerAddition, ConsumerAddition> Queue<T, ProducerAddition, ConsumerAddition> {

    /// Creates a new queue. With given additional elements in the producer and
    /// consumer portions of the queue.
    ///
    /// Due to the performance implications of cache-contention,
    /// we wish to keep fields used mainly by the producer on a separate cache
    /// line than those used by the consumer.
    /// Since cache lines are usually 64 bytes, it is unreasonably expensive to
    /// allocate one for small fields, so we allow users to insert additional
    /// fields into the cache lines already allocated by this for the producer
    /// and consumer.
    ///
    /// This is unsafe as the type system doesn't enforce a single
    /// consumer-producer relationship. It also allows the consumer to `pop`
    /// items while there is a `peek` active due to all methods having a
    /// non-mutable receiver.
    ///
    /// # Arguments
    ///
    ///   * `bound` - This queue implementation is implemented with a linked
    ///               list, and this means that a push is always a malloc. In
    ///               order to amortize this cost, an internal cache of nodes is
    ///               maintained to prevent a malloc from always being
    ///               necessary. This bound is the limit on the size of the
    ///               cache (if desired). If the value is 0, then the cache has
    ///               no bound. Otherwise, the cache will never grow larger than
    ///               `bound` (although the queue itself could be much larger.
    pub unsafe fn with_additions(
        bound: usize,
        producer_addition: ProducerAddition,
        consumer_addition: ConsumerAddition,
    ) -> Self {
        let n1 = Node::new();
        let n2 = Node::new();
        (*n1).next.store(n2, Ordering::Relaxed);
        Queue {
            consumer: CacheAligned::new(Consumer {
                tail: UnsafeCell::new(n2),
                tail_prev: AtomicPtr::new(n1),
                cache_bound: bound,
                cached_nodes: AtomicUsize::new(0),
                addition: consumer_addition
            }),
            producer: CacheAligned::new(Producer {
                head: UnsafeCell::new(n2),
                first: UnsafeCell::new(n1),
                tail_copy: UnsafeCell::new(n1),
                addition: producer_addition
            }),
        }
    }

    /// Pushes a new value onto this queue. Note that to use this function
    /// safely, it must be externally guaranteed that there is only one pusher.
    pub fn push(&self, t: T) {
        unsafe {
            // Acquire a node (which either uses a cached one or allocates a new
            // one), and then append this to the 'head' node.
            let n = self.alloc();
            assert!((*n).value.is_none());
            (*n).value = Some(t);
            (*n).next.store(ptr::null_mut(), Ordering::Relaxed);
            (**self.producer.head.get()).next.store(n, Ordering::Release);
            *(&self.producer.head).get() = n;
        }
    }

    unsafe fn alloc(&self) -> *mut Node<T> {
        // First try to see if we can consume the 'first' node for our uses.
        if *self.producer.first.get() != *self.producer.tail_copy.get() {
            let ret = *self.producer.first.get();
            *self.producer.0.first.get() = (*ret).next.load(Ordering::Relaxed);
            return ret;
        }
        // If the above fails, then update our copy of the tail and try
        // again.
        *self.producer.0.tail_copy.get() =
            self.consumer.tail_prev.load(Ordering::Acquire);
        if *self.producer.first.get() != *self.producer.tail_copy.get() {
            let ret = *self.producer.first.get();
            *self.producer.0.first.get() = (*ret).next.load(Ordering::Relaxed);
            return ret;
        }
        // If all of that fails, then we have to allocate a new node
        // (there's nothing in the node cache).
        Node::new()
    }

    /// Attempts to pop a value from this queue. Remember that to use this type
    /// safely you must ensure that there is only one popper at a time.
    pub fn pop(&self) -> Option<T> {
        unsafe {
            // The `tail` node is not actually a used node, but rather a
            // sentinel from where we should start popping from. Hence, look at
            // tail's next field and see if we can use it. If we do a pop, then
            // the current tail node is a candidate for going into the cache.
            let tail = *self.consumer.tail.get();
            let next = (*tail).next.load(Ordering::Acquire);
            if next.is_null() { return None }
            assert!((*next).value.is_some());
            let ret = (*next).value.take();

            *self.consumer.0.tail.get() = next;
            if self.consumer.cache_bound == 0 {
                self.consumer.tail_prev.store(tail, Ordering::Release);
            } else {
                let cached_nodes = self.consumer.cached_nodes.load(Ordering::Relaxed);
                if cached_nodes < self.consumer.cache_bound && !(*tail).cached {
                    self.consumer.cached_nodes.store(cached_nodes, Ordering::Relaxed);
                    (*tail).cached = true;
                }

                if (*tail).cached {
                    self.consumer.tail_prev.store(tail, Ordering::Release);
                } else {
                    (*self.consumer.tail_prev.load(Ordering::Relaxed))
                        .next.store(next, Ordering::Relaxed);
                    // We have successfully erased all references to 'tail', so
                    // now we can safely drop it.
                    let _: Box<Node<T>> = Box::from_raw(tail);
                }
            }
            ret
        }
    }

    /// Attempts to peek at the head of the queue, returning `None` if the queue
    /// has no data currently
    ///
    /// # Warning
    /// The reference returned is invalid if it is not used before the consumer
    /// pops the value off the queue. If the producer then pushes another value
    /// onto the queue, it will overwrite the value pointed to by the reference.
    pub fn peek(&self) -> Option<&mut T> {
        // This is essentially the same as above with all the popping bits
        // stripped out.
        unsafe {
            let tail = *self.consumer.tail.get();
            let next = (*tail).next.load(Ordering::Acquire);
            if next.is_null() { None } else { (*next).value.as_mut() }
        }
    }

    pub fn producer_addition(&self) -> &ProducerAddition {
        &self.producer.addition
    }

    pub fn consumer_addition(&self) -> &ConsumerAddition {
        &self.consumer.addition
    }
}

impl<T, ProducerAddition, ConsumerAddition> Drop for Queue<T, ProducerAddition, ConsumerAddition> {
    fn drop(&mut self) {
        unsafe {
            let mut cur = *self.producer.first.get();
            while !cur.is_null() {
                let next = (*cur).next.load(Ordering::Relaxed);
                let _n: Box<Node<T>> = Box::from_raw(cur);
                cur = next;
            }
        }
    }
}

#[cfg(all(test, not(target_os = "emscripten")))]
mod tests {
    use sync::Arc;
    use super::Queue;
    use thread;
    use sync::mpsc::channel;

    #[test]
    fn smoke() {
        unsafe {
            let queue = Queue::new(0);
            queue.push(1);
            queue.push(2);
            assert_eq!(queue.pop(), Some(1));
            assert_eq!(queue.pop(), Some(2));
            assert_eq!(queue.pop(), None);
            queue.push(3);
            queue.push(4);
            assert_eq!(queue.pop(), Some(3));
            assert_eq!(queue.pop(), Some(4));
            assert_eq!(queue.pop(), None);
        }
    }

    #[test]
    fn peek() {
        unsafe {
            let queue = Queue::new(0);
            queue.push(vec![1]);

            // Ensure the borrowchecker works
            match queue.peek() {
                Some(vec) => {
                    assert_eq!(&*vec, &[1]);
                },
                None => unreachable!()
            }

            match queue.pop() {
                Some(vec) => {
                    assert_eq!(&*vec, &[1]);
                },
                None => unreachable!()
            }
        }
    }

    #[test]
    fn drop_full() {
        unsafe {
            let q: Queue<Box<_>> = Queue::new(0);
            q.push(box 1);
            q.push(box 2);
        }
    }

    #[test]
    fn smoke_bound() {
        unsafe {
            let q = Queue::new(0);
            q.push(1);
            q.push(2);
            assert_eq!(q.pop(), Some(1));
            assert_eq!(q.pop(), Some(2));
            assert_eq!(q.pop(), None);
            q.push(3);
            q.push(4);
            assert_eq!(q.pop(), Some(3));
            assert_eq!(q.pop(), Some(4));
            assert_eq!(q.pop(), None);
        }
    }

    #[test]
    fn stress() {
        unsafe {
            stress_bound(0);
            stress_bound(1);
        }

        unsafe fn stress_bound(bound: usize) {
            let q = Arc::new(Queue::new(bound));

            let (tx, rx) = channel();
            let q2 = q.clone();
            let _t = thread::spawn(move|| {
                for _ in 0..100000 {
                    loop {
                        match q2.pop() {
                            Some(1) => break,
                            Some(_) => panic!(),
                            None => {}
                        }
                    }
                }
                tx.send(()).unwrap();
            });
            for _ in 0..100000 {
                q.push(1);
            }
            rx.recv().unwrap();
        }
    }
}
<commit_msg>Remove Queue::new.<commit_after>// Copyright 2017 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.

//! A single-producer single-consumer concurrent queue
//!
//! This module contains the implementation of an SPSC queue which can be used
//! concurrently between two threads. This data structure is safe to use and
//! enforces the semantics that there is one pusher and one popper.

// http://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue

use alloc::boxed::Box;
use core::ptr;
use core::cell::UnsafeCell;

use sync::atomic::{AtomicPtr, AtomicUsize, Ordering};

use super::cache_aligned::CacheAligned;

// Node within the linked list queue of messages to send
struct Node<T> {
    // FIXME: this could be an uninitialized T if we're careful enough, and
    //      that would reduce memory usage (and be a bit faster).
    //      is it worth it?
    value: Option<T>,           // nullable for re-use of nodes
    cached: bool,               // This node goes into the node cache
    next: AtomicPtr<Node<T>>,   // next node in the queue
}

/// The single-producer single-consumer queue. This structure is not cloneable,
/// but it can be safely shared in an Arc if it is guaranteed that there
/// is only one popper and one pusher touching the queue at any one point in
/// time.
pub struct Queue<T, ProducerAddition=(), ConsumerAddition=()> {
    // consumer fields
    consumer: CacheAligned<Consumer<T, ConsumerAddition>>,

    // producer fields
    producer: CacheAligned<Producer<T, ProducerAddition>>,
}

struct Consumer<T, Addition> {
    tail: UnsafeCell<*mut Node<T>>, // where to pop from
    tail_prev: AtomicPtr<Node<T>>, // where to pop from
    cache_bound: usize, // maximum cache size
    cached_nodes: AtomicUsize, // number of nodes marked as cachable
    addition: Addition,
}

struct Producer<T, Addition> {
    head: UnsafeCell<*mut Node<T>>,      // where to push to
    first: UnsafeCell<*mut Node<T>>,     // where to get new nodes from
    tail_copy: UnsafeCell<*mut Node<T>>, // between first/tail
    addition: Addition,
}

unsafe impl<T: Send, P: Send + Sync, C: Send + Sync> Send for Queue<T, P, C> { }

unsafe impl<T: Send, P: Send + Sync, C: Send + Sync> Sync for Queue<T, P, C> { }

impl<T> Node<T> {
    fn new() -> *mut Node<T> {
        Box::into_raw(box Node {
            value: None,
            cached: false,
            next: AtomicPtr::new(ptr::null_mut::<Node<T>>()),
        })
    }
}

impl<T, ProducerAddition, ConsumerAddition> Queue<T, ProducerAddition, ConsumerAddition> {

    /// Creates a new queue. With given additional elements in the producer and
    /// consumer portions of the queue.
    ///
    /// Due to the performance implications of cache-contention,
    /// we wish to keep fields used mainly by the producer on a separate cache
    /// line than those used by the consumer.
    /// Since cache lines are usually 64 bytes, it is unreasonably expensive to
    /// allocate one for small fields, so we allow users to insert additional
    /// fields into the cache lines already allocated by this for the producer
    /// and consumer.
    ///
    /// This is unsafe as the type system doesn't enforce a single
    /// consumer-producer relationship. It also allows the consumer to `pop`
    /// items while there is a `peek` active due to all methods having a
    /// non-mutable receiver.
    ///
    /// # Arguments
    ///
    ///   * `bound` - This queue implementation is implemented with a linked
    ///               list, and this means that a push is always a malloc. In
    ///               order to amortize this cost, an internal cache of nodes is
    ///               maintained to prevent a malloc from always being
    ///               necessary. This bound is the limit on the size of the
    ///               cache (if desired). If the value is 0, then the cache has
    ///               no bound. Otherwise, the cache will never grow larger than
    ///               `bound` (although the queue itself could be much larger.
    pub unsafe fn with_additions(
        bound: usize,
        producer_addition: ProducerAddition,
        consumer_addition: ConsumerAddition,
    ) -> Self {
        let n1 = Node::new();
        let n2 = Node::new();
        (*n1).next.store(n2, Ordering::Relaxed);
        Queue {
            consumer: CacheAligned::new(Consumer {
                tail: UnsafeCell::new(n2),
                tail_prev: AtomicPtr::new(n1),
                cache_bound: bound,
                cached_nodes: AtomicUsize::new(0),
                addition: consumer_addition
            }),
            producer: CacheAligned::new(Producer {
                head: UnsafeCell::new(n2),
                first: UnsafeCell::new(n1),
                tail_copy: UnsafeCell::new(n1),
                addition: producer_addition
            }),
        }
    }

    /// Pushes a new value onto this queue. Note that to use this function
    /// safely, it must be externally guaranteed that there is only one pusher.
    pub fn push(&self, t: T) {
        unsafe {
            // Acquire a node (which either uses a cached one or allocates a new
            // one), and then append this to the 'head' node.
            let n = self.alloc();
            assert!((*n).value.is_none());
            (*n).value = Some(t);
            (*n).next.store(ptr::null_mut(), Ordering::Relaxed);
            (**self.producer.head.get()).next.store(n, Ordering::Release);
            *(&self.producer.head).get() = n;
        }
    }

    unsafe fn alloc(&self) -> *mut Node<T> {
        // First try to see if we can consume the 'first' node for our uses.
        if *self.producer.first.get() != *self.producer.tail_copy.get() {
            let ret = *self.producer.first.get();
            *self.producer.0.first.get() = (*ret).next.load(Ordering::Relaxed);
            return ret;
        }
        // If the above fails, then update our copy of the tail and try
        // again.
        *self.producer.0.tail_copy.get() =
            self.consumer.tail_prev.load(Ordering::Acquire);
        if *self.producer.first.get() != *self.producer.tail_copy.get() {
            let ret = *self.producer.first.get();
            *self.producer.0.first.get() = (*ret).next.load(Ordering::Relaxed);
            return ret;
        }
        // If all of that fails, then we have to allocate a new node
        // (there's nothing in the node cache).
        Node::new()
    }

    /// Attempts to pop a value from this queue. Remember that to use this type
    /// safely you must ensure that there is only one popper at a time.
    pub fn pop(&self) -> Option<T> {
        unsafe {
            // The `tail` node is not actually a used node, but rather a
            // sentinel from where we should start popping from. Hence, look at
            // tail's next field and see if we can use it. If we do a pop, then
            // the current tail node is a candidate for going into the cache.
            let tail = *self.consumer.tail.get();
            let next = (*tail).next.load(Ordering::Acquire);
            if next.is_null() { return None }
            assert!((*next).value.is_some());
            let ret = (*next).value.take();

            *self.consumer.0.tail.get() = next;
            if self.consumer.cache_bound == 0 {
                self.consumer.tail_prev.store(tail, Ordering::Release);
            } else {
                let cached_nodes = self.consumer.cached_nodes.load(Ordering::Relaxed);
                if cached_nodes < self.consumer.cache_bound && !(*tail).cached {
                    self.consumer.cached_nodes.store(cached_nodes, Ordering::Relaxed);
                    (*tail).cached = true;
                }

                if (*tail).cached {
                    self.consumer.tail_prev.store(tail, Ordering::Release);
                } else {
                    (*self.consumer.tail_prev.load(Ordering::Relaxed))
                        .next.store(next, Ordering::Relaxed);
                    // We have successfully erased all references to 'tail', so
                    // now we can safely drop it.
                    let _: Box<Node<T>> = Box::from_raw(tail);
                }
            }
            ret
        }
    }

    /// Attempts to peek at the head of the queue, returning `None` if the queue
    /// has no data currently
    ///
    /// # Warning
    /// The reference returned is invalid if it is not used before the consumer
    /// pops the value off the queue. If the producer then pushes another value
    /// onto the queue, it will overwrite the value pointed to by the reference.
    pub fn peek(&self) -> Option<&mut T> {
        // This is essentially the same as above with all the popping bits
        // stripped out.
        unsafe {
            let tail = *self.consumer.tail.get();
            let next = (*tail).next.load(Ordering::Acquire);
            if next.is_null() { None } else { (*next).value.as_mut() }
        }
    }

    pub fn producer_addition(&self) -> &ProducerAddition {
        &self.producer.addition
    }

    pub fn consumer_addition(&self) -> &ConsumerAddition {
        &self.consumer.addition
    }
}

impl<T, ProducerAddition, ConsumerAddition> Drop for Queue<T, ProducerAddition, ConsumerAddition> {
    fn drop(&mut self) {
        unsafe {
            let mut cur = *self.producer.first.get();
            while !cur.is_null() {
                let next = (*cur).next.load(Ordering::Relaxed);
                let _n: Box<Node<T>> = Box::from_raw(cur);
                cur = next;
            }
        }
    }
}

#[cfg(all(test, not(target_os = "emscripten")))]
mod tests {
    use sync::Arc;
    use super::Queue;
    use thread;
    use sync::mpsc::channel;

    #[test]
    fn smoke() {
        unsafe {
            let queue = Queue::with_additions(0, (), ());
            queue.push(1);
            queue.push(2);
            assert_eq!(queue.pop(), Some(1));
            assert_eq!(queue.pop(), Some(2));
            assert_eq!(queue.pop(), None);
            queue.push(3);
            queue.push(4);
            assert_eq!(queue.pop(), Some(3));
            assert_eq!(queue.pop(), Some(4));
            assert_eq!(queue.pop(), None);
        }
    }

    #[test]
    fn peek() {
        unsafe {
            let queue = Queue::with_additions(0, (), ());
            queue.push(vec![1]);

            // Ensure the borrowchecker works
            match queue.peek() {
                Some(vec) => {
                    assert_eq!(&*vec, &[1]);
                },
                None => unreachable!()
            }

            match queue.pop() {
                Some(vec) => {
                    assert_eq!(&*vec, &[1]);
                },
                None => unreachable!()
            }
        }
    }

    #[test]
    fn drop_full() {
        unsafe {
            let q: Queue<Box<_>> = Queue::with_additions(0, (), ());
            q.push(box 1);
            q.push(box 2);
        }
    }

    #[test]
    fn smoke_bound() {
        unsafe {
            let q = Queue::with_additions(0, (), ());
            q.push(1);
            q.push(2);
            assert_eq!(q.pop(), Some(1));
            assert_eq!(q.pop(), Some(2));
            assert_eq!(q.pop(), None);
            q.push(3);
            q.push(4);
            assert_eq!(q.pop(), Some(3));
            assert_eq!(q.pop(), Some(4));
            assert_eq!(q.pop(), None);
        }
    }

    #[test]
    fn stress() {
        unsafe {
            stress_bound(0);
            stress_bound(1);
        }

        unsafe fn stress_bound(bound: usize) {
            let q = Arc::new(Queue::with_additions(bound, (), ()));

            let (tx, rx) = channel();
            let q2 = q.clone();
            let _t = thread::spawn(move|| {
                for _ in 0..100000 {
                    loop {
                        match q2.pop() {
                            Some(1) => break,
                            Some(_) => panic!(),
                            None => {}
                        }
                    }
                }
                tx.send(()).unwrap();
            });
            for _ in 0..100000 {
                q.push(1);
            }
            rx.recv().unwrap();
        }
    }
}
<|endoftext|>


<commit_before>use syntax::{ast, AstNode, SmolStr};

use crate::{AssistContext, AssistId, AssistKind, Assists, GroupLabel};

// Assist: convert_integer_literal
//
// Converts the base of integer literals to other bases.
//
// ```
// const _: i32 = 10<|>;
// ```
// ->
// ```
// const _: i32 = 0b1010;
// ```
pub(crate) fn convert_integer_literal(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let literal = ctx.find_node_at_offset::<ast::Literal>()?;
    let range = literal.syntax().text_range();
    let group_id = GroupLabel("Convert integer base".into());

    let suffix = match literal.kind() {
        ast::LiteralKind::IntNumber { suffix } => suffix,
        _ => return None,
    };
    let suffix_len = suffix.as_ref().map(|s| s.len()).unwrap_or(0);
    let raw_literal_text = literal.syntax().to_string();

    // Gets the literal's text without the type suffix and without underscores.
    let literal_text = raw_literal_text
        .chars()
        .take(raw_literal_text.len() - suffix_len)
        .filter(|c| *c != '_')
        .collect::<SmolStr>();
    let literal_base = IntegerLiteralBase::identify(&literal_text)?;

    for base in IntegerLiteralBase::bases() {
        if *base == literal_base {
            continue;
        }

        let mut converted = literal_base.convert(&literal_text, base);

        let label = if let Some(suffix) = &suffix {
            format!("Convert {} ({}) to {}", &literal_text, suffix, &converted)
        } else {
            format!("Convert {} to {}", &literal_text, &converted)
        };

        // Appends the type suffix back into the new literal if it exists.
        if let Some(suffix) = &suffix {
            converted.push_str(&suffix);
        }

        acc.add_group(
            &group_id,
            AssistId("convert_integer_literal", AssistKind::RefactorInline),
            label,
            range,
            |builder| builder.replace(range, converted),
        );
    }

    Some(())
}

#[derive(Debug, PartialEq, Eq)]
enum IntegerLiteralBase {
    Binary,
    Octal,
    Decimal,
    Hexadecimal,
}

impl IntegerLiteralBase {
    fn identify(literal_text: &str) -> Option<Self> {
        // We cannot express a literal in anything other than decimal in under 3 characters, so we return here if possible.
        if literal_text.len() < 3 && literal_text.chars().all(|c| c.is_digit(10)) {
            return Some(Self::Decimal);
        }

        let base = match &literal_text[..2] {
            "0b" => Self::Binary,
            "0o" => Self::Octal,
            "0x" => Self::Hexadecimal,
            _ => Self::Decimal,
        };

        // Checks that all characters after the base prefix are all valid digits for that base.
        if literal_text[base.prefix_len()..]
            .chars()
            .all(|c| c.is_digit(base.base()))
        {
            Some(base)
        } else {
            None
        }
    }

    fn convert(&self, literal_text: &str, to: &IntegerLiteralBase) -> String {
        let digits = &literal_text[self.prefix_len()..];
        let value = u128::from_str_radix(digits, self.base()).unwrap();

        match to {
            Self::Binary => format!("0b{:b}", value),
            Self::Octal => format!("0o{:o}", value),
            Self::Decimal => value.to_string(),
            Self::Hexadecimal => format!("0x{:X}", value),
        }
    }

    const fn base(&self) -> u32 {
        match self {
            Self::Binary => 2,
            Self::Octal => 8,
            Self::Decimal => 10,
            Self::Hexadecimal => 16,
        }
    }

    const fn prefix_len(&self) -> usize {
        match self {
            Self::Decimal => 0,
            _ => 2,
        }
    }

    const fn bases() -> &'static [IntegerLiteralBase] {
        &[
            IntegerLiteralBase::Binary,
            IntegerLiteralBase::Octal,
            IntegerLiteralBase::Decimal,
            IntegerLiteralBase::Hexadecimal,
        ]
    }
}
<commit_msg>Add tests for convert integer literal assist<commit_after>use syntax::{ast, AstNode, SmolStr};

use crate::{AssistContext, AssistId, AssistKind, Assists, GroupLabel};

// Assist: convert_integer_literal
//
// Converts the base of integer literals to other bases.
//
// ```
// const _: i32 = 10<|>;
// ```
// ->
// ```
// const _: i32 = 0b1010;
// ```
pub(crate) fn convert_integer_literal(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let literal = ctx.find_node_at_offset::<ast::Literal>()?;
    let range = literal.syntax().text_range();
    let group_id = GroupLabel("Convert integer base".into());

    let suffix = match literal.kind() {
        ast::LiteralKind::IntNumber { suffix } => suffix,
        _ => return None,
    };
    let suffix_len = suffix.as_ref().map(|s| s.len()).unwrap_or(0);
    let raw_literal_text = literal.syntax().to_string();

    // Gets the literal's text without the type suffix and without underscores.
    let literal_text = raw_literal_text
        .chars()
        .take(raw_literal_text.len() - suffix_len)
        .filter(|c| *c != '_')
        .collect::<SmolStr>();
    let literal_base = IntegerLiteralBase::identify(&literal_text)?;

    for base in IntegerLiteralBase::bases() {
        if *base == literal_base {
            continue;
        }

        let mut converted = literal_base.convert(&literal_text, base);

        let label = if let Some(suffix) = &suffix {
            format!("Convert {} ({}) to {}", &literal_text, suffix, &converted)
        } else {
            format!("Convert {} to {}", &literal_text, &converted)
        };

        // Appends the type suffix back into the new literal if it exists.
        if let Some(suffix) = &suffix {
            converted.push_str(&suffix);
        }

        acc.add_group(
            &group_id,
            AssistId("convert_integer_literal", AssistKind::RefactorInline),
            label,
            range,
            |builder| builder.replace(range, converted),
        );
    }

    Some(())
}

#[derive(Debug, PartialEq, Eq)]
enum IntegerLiteralBase {
    Binary,
    Octal,
    Decimal,
    Hexadecimal,
}

impl IntegerLiteralBase {
    fn identify(literal_text: &str) -> Option<Self> {
        // We cannot express a literal in anything other than decimal in under 3 characters, so we return here if possible.
        if literal_text.len() < 3 && literal_text.chars().all(|c| c.is_digit(10)) {
            return Some(Self::Decimal);
        }

        let base = match &literal_text[..2] {
            "0b" => Self::Binary,
            "0o" => Self::Octal,
            "0x" => Self::Hexadecimal,
            _ => Self::Decimal,
        };

        // Checks that all characters after the base prefix are all valid digits for that base.
        if literal_text[base.prefix_len()..].chars().all(|c| c.is_digit(base.base())) {
            Some(base)
        } else {
            None
        }
    }

    fn convert(&self, literal_text: &str, to: &IntegerLiteralBase) -> String {
        let digits = &literal_text[self.prefix_len()..];
        let value = u128::from_str_radix(digits, self.base()).unwrap();

        match to {
            Self::Binary => format!("0b{:b}", value),
            Self::Octal => format!("0o{:o}", value),
            Self::Decimal => value.to_string(),
            Self::Hexadecimal => format!("0x{:X}", value),
        }
    }

    const fn base(&self) -> u32 {
        match self {
            Self::Binary => 2,
            Self::Octal => 8,
            Self::Decimal => 10,
            Self::Hexadecimal => 16,
        }
    }

    const fn prefix_len(&self) -> usize {
        match self {
            Self::Decimal => 0,
            _ => 2,
        }
    }

    const fn bases() -> &'static [IntegerLiteralBase] {
        &[
            IntegerLiteralBase::Binary,
            IntegerLiteralBase::Octal,
            IntegerLiteralBase::Decimal,
            IntegerLiteralBase::Hexadecimal,
        ]
    }
}

#[cfg(test)]
mod tests {

    use super::*;
    use crate::tests::{check_assist_by_label, check_assist_target};

    #[test]
    fn binary_target() {
        check_assist_target(convert_integer_literal, "const _: i32 = 0b1010<|>;", "0b1010");
    }

    #[test]
    fn octal_target() {
        check_assist_target(convert_integer_literal, "const _: i32 = 0o12<|>;", "0o12");
    }

    #[test]
    fn decimal_target() {
        check_assist_target(convert_integer_literal, "const _: i32 = 10<|>;", "10");
    }

    #[test]
    fn hexadecimal_target() {
        check_assist_target(convert_integer_literal, "const _: i32 = 0xA<|>;", "0xA");
    }

    #[test]
    fn binary_target_with_underscores() {
        check_assist_target(convert_integer_literal, "const _: i32 = 0b10_10<|>;", "0b10_10");
    }

    #[test]
    fn octal_target_with_underscores() {
        check_assist_target(convert_integer_literal, "const _: i32 = 0o1_2<|>;", "0o1_2");
    }

    #[test]
    fn decimal_target_with_underscores() {
        check_assist_target(convert_integer_literal, "const _: i32 = 1_0<|>;", "1_0");
    }

    #[test]
    fn hexadecimal_target_with_underscores() {
        check_assist_target(convert_integer_literal, "const _: i32 = 0x_A<|>;", "0x_A");
    }

    #[test]
    fn convert_decimal_integer() {
        let before = "const _: i32 = 1000<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0b1111101000;",
            "Convert 1000 to 0b1111101000",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0o1750;",
            "Convert 1000 to 0o1750",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0x3E8;",
            "Convert 1000 to 0x3E8",
        );
    }

    // Decimal numbers under 3 digits have a special case where they return early because we can't fit a
    // other base's prefix, so we have a separate test for that.
    #[test]
    fn convert_small_decimal_integer() {
        let before = "const _: i32 = 10<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0b1010;",
            "Convert 10 to 0b1010",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0o12;",
            "Convert 10 to 0o12",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0xA;",
            "Convert 10 to 0xA",
        );
    }

    #[test]
    fn convert_hexadecimal_integer() {
        let before = "const _: i32 = 0xFF<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0b11111111;",
            "Convert 0xFF to 0b11111111",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0o377;",
            "Convert 0xFF to 0o377",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 255;",
            "Convert 0xFF to 255",
        );
    }

    #[test]
    fn convert_binary_integer() {
        let before = "const _: i32 = 0b11111111<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0o377;",
            "Convert 0b11111111 to 0o377",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 255;",
            "Convert 0b11111111 to 255",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0xFF;",
            "Convert 0b11111111 to 0xFF",
        );
    }

    #[test]
    fn convert_octal_integer() {
        let before = "const _: i32 = 0o377<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0b11111111;",
            "Convert 0o377 to 0b11111111",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 255;",
            "Convert 0o377 to 255",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0xFF;",
            "Convert 0o377 to 0xFF",
        );
    }

    #[test]
    fn convert_decimal_integer_with_underscores() {
        let before = "const _: i32 = 1_00_0<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0b1111101000;",
            "Convert 1000 to 0b1111101000",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0o1750;",
            "Convert 1000 to 0o1750",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0x3E8;",
            "Convert 1000 to 0x3E8",
        );
    }

    #[test]
    fn convert_small_decimal_integer_with_underscores() {
        let before = "const _: i32 = 1_0<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0b1010;",
            "Convert 10 to 0b1010",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0o12;",
            "Convert 10 to 0o12",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0xA;",
            "Convert 10 to 0xA",
        );
    }

    #[test]
    fn convert_hexadecimal_integer_with_underscores() {
        let before = "const _: i32 = 0x_F_F<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0b11111111;",
            "Convert 0xFF to 0b11111111",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0o377;",
            "Convert 0xFF to 0o377",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 255;",
            "Convert 0xFF to 255",
        );
    }

    #[test]
    fn convert_binary_integer_with_underscores() {
        let before = "const _: i32 = 0b1111_1111<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0o377;",
            "Convert 0b11111111 to 0o377",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 255;",
            "Convert 0b11111111 to 255",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0xFF;",
            "Convert 0b11111111 to 0xFF",
        );
    }

    #[test]
    fn convert_octal_integer_with_underscores() {
        let before = "const _: i32 = 0o3_77<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0b11111111;",
            "Convert 0o377 to 0b11111111",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 255;",
            "Convert 0o377 to 255",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0xFF;",
            "Convert 0o377 to 0xFF",
        );
    }

    #[test]
    fn convert_decimal_integer_with_suffix() {
        let before = "const _: i32 = 1000i32<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0b1111101000i32;",
            "Convert 1000 (i32) to 0b1111101000",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0o1750i32;",
            "Convert 1000 (i32) to 0o1750",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0x3E8i32;",
            "Convert 1000 (i32) to 0x3E8",
        );
    }

    #[test]
    fn convert_small_decimal_integer_with_suffix() {
        let before = "const _: i32 = 10i32<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0b1010i32;",
            "Convert 10 (i32) to 0b1010",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0o12i32;",
            "Convert 10 (i32) to 0o12",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0xAi32;",
            "Convert 10 (i32) to 0xA",
        );
    }

    #[test]
    fn convert_hexadecimal_integer_with_suffix() {
        let before = "const _: i32 = 0xFFi32<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0b11111111i32;",
            "Convert 0xFF (i32) to 0b11111111",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0o377i32;",
            "Convert 0xFF (i32) to 0o377",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 255i32;",
            "Convert 0xFF (i32) to 255",
        );
    }

    #[test]
    fn convert_binary_integer_with_suffix() {
        let before = "const _: i32 = 0b11111111i32<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0o377i32;",
            "Convert 0b11111111 (i32) to 0o377",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 255i32;",
            "Convert 0b11111111 (i32) to 255",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0xFFi32;",
            "Convert 0b11111111 (i32) to 0xFF",
        );
    }

    #[test]
    fn convert_octal_integer_with_suffix() {
        let before = "const _: i32 = 0o377i32<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0b11111111i32;",
            "Convert 0o377 (i32) to 0b11111111",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 255i32;",
            "Convert 0o377 (i32) to 255",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0xFFi32;",
            "Convert 0o377 (i32) to 0xFF",
        );
    }

    #[test]
    fn convert_decimal_integer_with_underscores_and_suffix() {
        let before = "const _: i32 = 1_00_0i32<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0b1111101000i32;",
            "Convert 1000 (i32) to 0b1111101000",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0o1750i32;",
            "Convert 1000 (i32) to 0o1750",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0x3E8i32;",
            "Convert 1000 (i32) to 0x3E8",
        );
    }

    #[test]
    fn convert_small_decimal_integer_with_underscores_and_suffix() {
        let before = "const _: i32 = 1_0i32<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0b1010i32;",
            "Convert 10 (i32) to 0b1010",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0o12i32;",
            "Convert 10 (i32) to 0o12",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0xAi32;",
            "Convert 10 (i32) to 0xA",
        );
    }

    #[test]
    fn convert_hexadecimal_integer_with_underscores_and_suffix() {
        let before = "const _: i32 = 0x_F_Fi32<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0b11111111i32;",
            "Convert 0xFF (i32) to 0b11111111",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0o377i32;",
            "Convert 0xFF (i32) to 0o377",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 255i32;",
            "Convert 0xFF (i32) to 255",
        );
    }

    #[test]
    fn convert_binary_integer_with_underscores_and_suffix() {
        let before = "const _: i32 = 0b1111_1111i32<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0o377i32;",
            "Convert 0b11111111 (i32) to 0o377",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 255i32;",
            "Convert 0b11111111 (i32) to 255",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0xFFi32;",
            "Convert 0b11111111 (i32) to 0xFF",
        );
    }

    #[test]
    fn convert_octal_integer_with_underscores_and_suffix() {
        let before = "const _: i32 = 0o3_77i32<|>;";

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0b11111111i32;",
            "Convert 0o377 (i32) to 0b11111111",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 255i32;",
            "Convert 0o377 (i32) to 255",
        );

        check_assist_by_label(
            convert_integer_literal,
            before,
            "const _: i32 = 0xFFi32;",
            "Convert 0o377 (i32) to 0xFF",
        );
    }
}
<|endoftext|>


<commit_before><commit_msg>Added missing logger.rs file<commit_after><|endoftext|>


<commit_before><commit_msg>Fix flakiness of simple_server_wallet test<commit_after><|endoftext|>


<commit_before>use hyper;
use hyper::Client;
use hyper::header::{Headers, Accept, Authorization, Connection, UserAgent, qitem};
use regex::Regex;
use std::io::prelude::*;
use std::process;

use say;
use github;

header! { (XRateLimitRemaining, "X-RateLimit-Remaining") => [u32] }

header! { (Link, "Link") => [String] }

/// The result of processing a response.
pub struct Page {
    pub content: String,
    pub next: Option<String>,
    pub ratelimit: u32,
}

impl Page {
    pub fn new(url: &str, token: &str) -> Page {
        let mut res = get_page(url.to_string(), token);
        let mut body = String::new();
        res.read_to_string(&mut body).unwrap();

        Page {content: body,
              next: next_url(link(&res.headers)),
              ratelimit: ratelimit(&res.headers)}
    }

    pub fn warn(&self) {
        if self.next.is_none() {
            println!("{} {} {}", say::warn(), self.ratelimit, "Remaining requests");
        }
    }
}

fn get_page(url: String, token: &str) -> hyper::client::Response {
    println!("{} {} {}", say::info(), "Fetching", url);

    let client = Client::new();
    let res = client.get(&*url.clone())
                    .header(UserAgent(format!("nerve/{}", env!("CARGO_PKG_VERSION"))))
                    .header(Authorization(format!("token {}", token)))
                    .header(Accept(vec![qitem(github::mime())]))
                    .header(Connection::close())
                    .send().unwrap_or_else(|_| process::exit(1));

    match res.status {
        hyper::Ok => {

        }
        _ => {
            println!("{} {}", say::error(), "Unable to parse the response from Github");
            process::exit(1)
        }
    }

    res
}

pub fn ratelimit(headers: &Headers) -> u32 {
    match headers.get() {
        Some(&XRateLimitRemaining(x)) => x,
        None => 0
    }
}

// A Link header is not present if the requested collection has less than
// _pagesize_.
pub fn link(headers: &hyper::header::Headers) -> String {
    match headers.get() {
        Some(&Link(ref x)) => x.to_string(),
        None => "".to_string()
    }
}

fn next_url(link: String) -> Option<String> {
    let re = Regex::new(r"<([^;]+)>;\s*rel=.next.").unwrap();
    match re.captures(&link) {
        None => None,
        Some(cs) => cs.at(1).as_ref().map(|x| x.to_string())
    }
}
<commit_msg>Clean indentation<commit_after>use hyper;
use hyper::Client;
use hyper::header::{Headers, Accept, Authorization, Connection, UserAgent, qitem};
use regex::Regex;
use std::io::prelude::*;
use std::process;

use say;
use github;

header! { (XRateLimitRemaining, "X-RateLimit-Remaining") => [u32] }

header! { (Link, "Link") => [String] }

/// The result of processing a response.
pub struct Page {
    pub content: String,
    pub next: Option<String>,
    pub ratelimit: u32,
}

impl Page {
    pub fn new(url: &str, token: &str) -> Page {
        let mut res = get_page(url.to_string(), token);
        let mut body = String::new();
        res.read_to_string(&mut body).unwrap();

        Page {content: body,
              next: next_url(link(&res.headers)),
              ratelimit: ratelimit(&res.headers)}
    }

    pub fn warn(&self) {
        if self.next.is_none() {
            println!("{} {} {}", say::warn(), self.ratelimit, "Remaining requests");
        }
    }
}

fn get_page(url: String, token: &str) -> hyper::client::Response {
    println!("{} {} {}", say::info(), "Fetching", url);

    let client = Client::new();
    let res = client.get(&*url.clone())
                    .header(UserAgent(format!("nerve/{}", env!("CARGO_PKG_VERSION"))))
                    .header(Authorization(format!("token {}", token)))
                    .header(Accept(vec![qitem(github::mime())]))
                    .header(Connection::close())
                    .send().unwrap_or_else(|_| process::exit(1));

    match res.status {
        hyper::Ok => {}
        _ => {
            println!("{} {}", say::error(), "Unable to parse the response from Github");
            process::exit(1)
        }
    }

    res
}

pub fn ratelimit(headers: &Headers) -> u32 {
    match headers.get() {
        Some(&XRateLimitRemaining(x)) => x,
        None => 0
    }
}

// A Link header is not present if the requested collection has less than
// _pagesize_.
pub fn link(headers: &hyper::header::Headers) -> String {
    match headers.get() {
        Some(&Link(ref x)) => x.to_string(),
        None => "".to_string()
    }
}

fn next_url(link: String) -> Option<String> {
    let re = Regex::new(r"<([^;]+)>;\s*rel=.next.").unwrap();
    match re.captures(&link) {
        None => None,
        Some(cs) => cs.at(1).as_ref().map(|x| x.to_string())
    }
}
<|endoftext|>


<commit_before>/* diosix supervisor kernel entry code and main loop
 *
 * (c) Chris Williams, 2019.
 *
 * See LICENSE for usage and copying.
 */

#[link_section = ".sshared"]
#[no_mangle]
pub extern "C" fn sentry()
{
    unsafe { asm!("ecall"); }
    // unsafe { let var = 0x90000000 as *mut usize; *var = *var + 1; }
    unsafe { asm!("ecall"); }

    loop { }
}
<commit_msg>Take out deliberate supervisor crash test dummy.<commit_after>/* diosix supervisor kernel entry code and main loop
 *
 * (c) Chris Williams, 2019.
 *
 * See LICENSE for usage and copying.
 */

#[link_section = ".sshared"]
#[no_mangle]
pub extern "C" fn sentry()
{
    unsafe { asm!("ecall"); }

    loop { }
}
<|endoftext|>