<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::cast;
use color::Color;
use select::SelectResults;
use computed::ComputedStyle;
use n::h::CssHintLength;
use n::c::ComputeFontSize;
use n::u::float_to_css_fixed;
use values::*;
use n;

struct CompleteFontSizeComputer {
    parent_computed: CompleteStyle<'static>,
    child_computed: CompleteStyle<'static>,
}

impl n::c::FontSizeComputer for CompleteFontSizeComputer {
    fn compute_font_size(&self, parent: &Option<n::h::CssHint>, child: &n::h::CssHint)
                         -> n::h::CssHint {
        match *child {
            // Handle relative units
            CssHintLength(n::t::CssUnitEm(child_em)) => {
                match *parent {
                    Some(CssHintLength(parent_unit)) => {
                        // CSS3 Values 5.1.1: Multiply parent unit by child unit.
                        let mut new_value = n::u::css_fixed_to_float(parent_unit.to_css_fixed());
                        new_value *= n::u::css_fixed_to_float(child_em);
                        let unit = parent_unit.modify(n::u::float_to_css_fixed(new_value));
                        CssHintLength(unit)
                    }
                    _ => n::h::CssHintLength(n::t::CssUnitPx(float_to_css_fixed(16.0))),
                }
            }
            CssHintLength(n::t::CssUnitPct(child_pct)) => {
                match *parent {
                    Some(CssHintLength(parent_unit)) => {
                        // CSS3 Values 5.1.1: Multiply parent unit by child unit.
                        let mut new_value = n::u::css_fixed_to_float(parent_unit.to_css_fixed());
                        new_value *= n::u::css_fixed_to_float(child_pct) / 100.0;
                        let unit = parent_unit.modify(n::u::float_to_css_fixed(new_value));
                        CssHintLength(unit)
                    }
                    _ => n::h::CssHintLength(n::t::CssUnitPx(float_to_css_fixed(16.0))),
                }
            }
            // Pass through absolute units
            CssHintLength(unit) => CssHintLength(unit),
            _ => n::h::CssHintLength(n::t::CssUnitPx(float_to_css_fixed(16.0))),
        }
    }
}

pub struct CompleteSelectResults {
    inner: SelectResults
}

struct ComputeFontSizeCallback {
    callback: ~fn(parent: &Option<n::h::CssHint>, child: &n::h::CssHint) -> n::h::CssHint,
}

impl ComputeFontSize for ComputeFontSizeCallback {
    fn compute_font_size(&self, parent: &Option<n::h::CssHint>, child: &n::h::CssHint) -> n::h::CssHint {
        (self.callback)(parent, child)
    }
}

impl<'self> CompleteSelectResults {
    pub fn new_root(root: SelectResults) -> CompleteSelectResults {
        CompleteSelectResults {
            inner: root
        }
    }

    pub fn new_from_parent(parent: &CompleteSelectResults,
                           child: SelectResults) -> CompleteSelectResults {
        // New lifetime
        {
            let font_size_computer = unsafe {
                @CompleteFontSizeComputer {
                    parent_computed: cast::transmute(parent.computed_style()),
                    child_computed: cast::transmute(child.computed_style()),
                }
            };
            //let net_parent_computed = &parent_computed.inner.inner;
            let net_child_computed = &/*mut*/ font_size_computer.child_computed.inner;
            // FIXME: Need to get real font sizes
            // XXX: Need an aliasable &mut here
            let net_result_computed: &mut n::c::CssComputedStyle = unsafe { cast::transmute(net_child_computed) };
            let net_child_computed: &mut n::c::CssComputedStyle = unsafe { cast::transmute(&font_size_computer.child_computed.inner) };
            let net_parent_computed = &font_size_computer.parent_computed.inner.inner;
            n::c::compose(net_parent_computed,
                          net_child_computed,
                          font_size_computer as @n::c::FontSizeComputer,
                          net_result_computed);
        }

        CompleteSelectResults {
            inner: child
        }
    }

    #[inline(always)]
    pub fn computed_style(&'self self) -> CompleteStyle<'self> {
        CompleteStyle {
            inner: self.inner.computed_style()
        }
    }
}

pub struct CompleteStyle<'self> {
    inner: ComputedStyle<'self>
}

impl<'self> CompleteStyle<'self> {

    // CSS 2.1, Section 8 - Box model

    #[inline(always)]
    pub fn margin_top(&self) -> CSSMargin {
        strip(self.inner.margin_top())
    }

    #[inline(always)]
    pub fn margin_right(&self) -> CSSMargin {
        strip(self.inner.margin_right())
    }

    #[inline(always)]
    pub fn margin_bottom(&self) -> CSSMargin {
        strip(self.inner.margin_bottom())
    }

    #[inline(always)]
    pub fn margin_left(&self) -> CSSMargin {
        strip(self.inner.margin_left())
    }

    #[inline(always)]
    pub fn padding_top(&self) -> CSSPadding {
        strip(self.inner.padding_top())
    }

    #[inline(always)]
    pub fn padding_right(&self) -> CSSPadding {
        strip(self.inner.padding_right())
    }

    #[inline(always)]
    pub fn padding_bottom(&self) -> CSSPadding {
        strip(self.inner.padding_bottom())
    }

    #[inline(always)]
    pub fn padding_left(&self) -> CSSPadding {
        strip(self.inner.padding_left())
    }

    #[inline(always)]
    pub fn border_top_style(&self) -> CSSBorderStyle {
        strip(self.inner.border_top_style())
    }

    #[inline(always)]
    pub fn border_right_style(&self) -> CSSBorderStyle {
        strip(self.inner.border_right_style())
    }

    #[inline(always)]
    pub fn border_bottom_style(&self) -> CSSBorderStyle {
        strip(self.inner.border_bottom_style())
    }

    #[inline(always)]
    pub fn border_left_style(&self) -> CSSBorderStyle {
        strip(self.inner.border_left_style())
    }

    #[inline(always)]
    pub fn border_top_width(&self) -> CSSBorderWidth {
        strip(self.inner.border_top_width())
    }

    #[inline(always)]
    pub fn border_right_width(&self) -> CSSBorderWidth {
        strip(self.inner.border_right_width())
    }

    #[inline(always)]
    pub fn border_bottom_width(&self) -> CSSBorderWidth {
        strip(self.inner.border_bottom_width())
    }

    #[inline(always)]
    pub fn border_left_width(&self) -> CSSBorderWidth {
        strip(self.inner.border_left_width())
    }

    #[inline(always)]
    pub fn border_top_color(&self) -> Color {
        strip(self.inner.border_top_color())
    }

    #[inline(always)]
    pub fn border_right_color(&self) -> Color {
        strip(self.inner.border_right_color())
    }

    #[inline(always)]
    pub fn border_bottom_color(&self) -> Color {
        strip(self.inner.border_bottom_color())
    }

    #[inline(always)]
    pub fn border_left_color(&self) -> Color {
        strip(self.inner.border_left_color())
    }

    // CSS 2.1, Section 9 - Visual formatting model

    #[inline(always)]
    pub fn display(&self, root: bool) -> CSSDisplay {
        strip(self.inner.display(root))
    }

    #[inline(always)]
    pub fn position(&self) -> CSSPosition {
        strip(self.inner.position())
    }

    #[inline(always)]
    pub fn float(&self) -> CSSFloat {
        strip(self.inner.float())
    }

    #[inline(always)]
    pub fn clear(&self) -> CSSClear {
        strip(self.inner.clear())
    }

    // CSS 2.1, Section 10 - Visual formatting model details

    #[inline(always)]
    pub fn width(&self) -> CSSWidth {
        strip(self.inner.width())
    }

    #[inline(always)]
    pub fn height(&self) -> CSSHeight {
        strip(self.inner.height())
    }

    #[inline(always)]
    pub fn line_height(&self) -> CSSLineHeight {
        strip(self.inner.line_height())
    }

    #[inline(always)]
    pub fn vertical_align(&self) -> CSSVerticalAlign {
        strip(self.inner.vertical_align())
    }

    // CSS 2.1, Section 11 - Visual effects

    // CSS 2.1, Section 12 - Generated content, automatic numbering, and lists

    // CSS 2.1, Section 13 - Paged media

    // CSS 2.1, Section 14 - Colors and Backgrounds

    #[inline(always)]
    pub fn background_color(&self) -> Color {
        strip(self.inner.background_color())
    }

    #[inline(always)]
    pub fn color(&self) -> Color {
        strip(self.inner.color())
    }

    // CSS 2.1, Section 15 - Fonts

    #[inline(always)]
    pub fn font_family(&self) -> ~[CSSFontFamily] {
        strip(self.inner.font_family())
    }

    #[inline(always)]
    pub fn font_style(&self) -> CSSFontStyle {
        strip(self.inner.font_style())
    }

    #[inline(always)]
    pub fn font_weight(&self) -> CSSFontWeight {
        strip(self.inner.font_weight())
    }

    #[inline(always)]
    pub fn font_size(&self) -> CSSFontSize {
        strip(self.inner.font_size())
    }

    #[inline(always)]
    pub fn text_decoration(&self) -> CSSTextDecoration{
        strip(self.inner.text_decoration())
    }

    // CSS 2.1, Section 16 - Text

    #[inline(always)]
    pub fn text_align(&self) -> CSSTextAlign {
        strip(self.inner.text_align())
    }

    // CSS 2.1, Section 17 - Tables

    // CSS 2.1, Section 18 - User interface

}

#[inline]
fn strip<T>(value: CSSValue<T>) -> T {
    match value {
        Inherit => fail!(~"unexpected 'inherit' value in complete style"),
        Specified(v) => v
    }
}

<commit_msg>Fix botched merge<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::cast;
use color::Color;
use select::SelectResults;
use computed::ComputedStyle;
use n::h::CssHintLength;
use n::u::float_to_css_fixed;
use values::*;
use n;

struct CompleteFontSizeComputer {
    parent_computed: CompleteStyle<'static>,
    child_computed: CompleteStyle<'static>,
}

impl n::c::FontSizeComputer for CompleteFontSizeComputer {
    fn compute_font_size(&self, parent: &Option<n::h::CssHint>, child: &n::h::CssHint)
                         -> n::h::CssHint {
        match *child {
            // Handle relative units
            CssHintLength(n::t::CssUnitEm(child_em)) => {
                match *parent {
                    Some(CssHintLength(parent_unit)) => {
                        // CSS3 Values 5.1.1: Multiply parent unit by child unit.
                        let mut new_value = n::u::css_fixed_to_float(parent_unit.to_css_fixed());
                        new_value *= n::u::css_fixed_to_float(child_em);
                        let unit = parent_unit.modify(n::u::float_to_css_fixed(new_value));
                        CssHintLength(unit)
                    }
                    _ => n::h::CssHintLength(n::t::CssUnitPx(float_to_css_fixed(16.0))),
                }
            }
            CssHintLength(n::t::CssUnitPct(child_pct)) => {
                match *parent {
                    Some(CssHintLength(parent_unit)) => {
                        // CSS3 Values 5.1.1: Multiply parent unit by child unit.
                        let mut new_value = n::u::css_fixed_to_float(parent_unit.to_css_fixed());
                        new_value *= n::u::css_fixed_to_float(child_pct) / 100.0;
                        let unit = parent_unit.modify(n::u::float_to_css_fixed(new_value));
                        CssHintLength(unit)
                    }
                    _ => n::h::CssHintLength(n::t::CssUnitPx(float_to_css_fixed(16.0))),
                }
            }
            // Pass through absolute units
            CssHintLength(unit) => CssHintLength(unit),
            _ => n::h::CssHintLength(n::t::CssUnitPx(float_to_css_fixed(16.0))),
        }
    }
}

pub struct CompleteSelectResults {
    inner: SelectResults
}

impl<'self> CompleteSelectResults {
    pub fn new_root(root: SelectResults) -> CompleteSelectResults {
        CompleteSelectResults {
            inner: root
        }
    }

    pub fn new_from_parent(parent: &CompleteSelectResults,
                           child: SelectResults) -> CompleteSelectResults {
        // New lifetime
        {
            let font_size_computer = unsafe {
                @CompleteFontSizeComputer {
                    parent_computed: cast::transmute(parent.computed_style()),
                    child_computed: cast::transmute(child.computed_style()),
                }
            };
            //let net_parent_computed = &parent_computed.inner.inner;
            let net_child_computed = &/*mut*/ font_size_computer.child_computed.inner;
            // FIXME: Need to get real font sizes
            // XXX: Need an aliasable &mut here
            let net_result_computed: &mut n::c::CssComputedStyle = unsafe { cast::transmute(net_child_computed) };
            let net_child_computed: &mut n::c::CssComputedStyle = unsafe { cast::transmute(&font_size_computer.child_computed.inner) };
            let net_parent_computed = &font_size_computer.parent_computed.inner.inner;
            n::c::compose(net_parent_computed,
                          net_child_computed,
                          font_size_computer as @n::c::FontSizeComputer,
                          net_result_computed);
        }

        CompleteSelectResults {
            inner: child
        }
    }

    #[inline(always)]
    pub fn computed_style(&'self self) -> CompleteStyle<'self> {
        CompleteStyle {
            inner: self.inner.computed_style()
        }
    }
}

pub struct CompleteStyle<'self> {
    inner: ComputedStyle<'self>
}

impl<'self> CompleteStyle<'self> {

    // CSS 2.1, Section 8 - Box model

    #[inline(always)]
    pub fn margin_top(&self) -> CSSMargin {
        strip(self.inner.margin_top())
    }

    #[inline(always)]
    pub fn margin_right(&self) -> CSSMargin {
        strip(self.inner.margin_right())
    }

    #[inline(always)]
    pub fn margin_bottom(&self) -> CSSMargin {
        strip(self.inner.margin_bottom())
    }

    #[inline(always)]
    pub fn margin_left(&self) -> CSSMargin {
        strip(self.inner.margin_left())
    }

    #[inline(always)]
    pub fn padding_top(&self) -> CSSPadding {
        strip(self.inner.padding_top())
    }

    #[inline(always)]
    pub fn padding_right(&self) -> CSSPadding {
        strip(self.inner.padding_right())
    }

    #[inline(always)]
    pub fn padding_bottom(&self) -> CSSPadding {
        strip(self.inner.padding_bottom())
    }

    #[inline(always)]
    pub fn padding_left(&self) -> CSSPadding {
        strip(self.inner.padding_left())
    }

    #[inline(always)]
    pub fn border_top_style(&self) -> CSSBorderStyle {
        strip(self.inner.border_top_style())
    }

    #[inline(always)]
    pub fn border_right_style(&self) -> CSSBorderStyle {
        strip(self.inner.border_right_style())
    }

    #[inline(always)]
    pub fn border_bottom_style(&self) -> CSSBorderStyle {
        strip(self.inner.border_bottom_style())
    }

    #[inline(always)]
    pub fn border_left_style(&self) -> CSSBorderStyle {
        strip(self.inner.border_left_style())
    }

    #[inline(always)]
    pub fn border_top_width(&self) -> CSSBorderWidth {
        strip(self.inner.border_top_width())
    }

    #[inline(always)]
    pub fn border_right_width(&self) -> CSSBorderWidth {
        strip(self.inner.border_right_width())
    }

    #[inline(always)]
    pub fn border_bottom_width(&self) -> CSSBorderWidth {
        strip(self.inner.border_bottom_width())
    }

    #[inline(always)]
    pub fn border_left_width(&self) -> CSSBorderWidth {
        strip(self.inner.border_left_width())
    }

    #[inline(always)]
    pub fn border_top_color(&self) -> Color {
        strip(self.inner.border_top_color())
    }

    #[inline(always)]
    pub fn border_right_color(&self) -> Color {
        strip(self.inner.border_right_color())
    }

    #[inline(always)]
    pub fn border_bottom_color(&self) -> Color {
        strip(self.inner.border_bottom_color())
    }

    #[inline(always)]
    pub fn border_left_color(&self) -> Color {
        strip(self.inner.border_left_color())
    }

    // CSS 2.1, Section 9 - Visual formatting model

    #[inline(always)]
    pub fn display(&self, root: bool) -> CSSDisplay {
        strip(self.inner.display(root))
    }

    #[inline(always)]
    pub fn position(&self) -> CSSPosition {
        strip(self.inner.position())
    }

    #[inline(always)]
    pub fn float(&self) -> CSSFloat {
        strip(self.inner.float())
    }

    #[inline(always)]
    pub fn clear(&self) -> CSSClear {
        strip(self.inner.clear())
    }

    // CSS 2.1, Section 10 - Visual formatting model details

    #[inline(always)]
    pub fn width(&self) -> CSSWidth {
        strip(self.inner.width())
    }

    #[inline(always)]
    pub fn height(&self) -> CSSHeight {
        strip(self.inner.height())
    }

    #[inline(always)]
    pub fn line_height(&self) -> CSSLineHeight {
        strip(self.inner.line_height())
    }

    #[inline(always)]
    pub fn vertical_align(&self) -> CSSVerticalAlign {
        strip(self.inner.vertical_align())
    }

    // CSS 2.1, Section 11 - Visual effects

    // CSS 2.1, Section 12 - Generated content, automatic numbering, and lists

    // CSS 2.1, Section 13 - Paged media

    // CSS 2.1, Section 14 - Colors and Backgrounds

    #[inline(always)]
    pub fn background_color(&self) -> Color {
        strip(self.inner.background_color())
    }

    #[inline(always)]
    pub fn color(&self) -> Color {
        strip(self.inner.color())
    }

    // CSS 2.1, Section 15 - Fonts

    #[inline(always)]
    pub fn font_family(&self) -> ~[CSSFontFamily] {
        strip(self.inner.font_family())
    }

    #[inline(always)]
    pub fn font_style(&self) -> CSSFontStyle {
        strip(self.inner.font_style())
    }

    #[inline(always)]
    pub fn font_weight(&self) -> CSSFontWeight {
        strip(self.inner.font_weight())
    }

    #[inline(always)]
    pub fn font_size(&self) -> CSSFontSize {
        strip(self.inner.font_size())
    }

    #[inline(always)]
    pub fn text_decoration(&self) -> CSSTextDecoration{
        strip(self.inner.text_decoration())
    }

    // CSS 2.1, Section 16 - Text

    #[inline(always)]
    pub fn text_align(&self) -> CSSTextAlign {
        strip(self.inner.text_align())
    }

    // CSS 2.1, Section 17 - Tables

    // CSS 2.1, Section 18 - User interface

}

#[inline]
fn strip<T>(value: CSSValue<T>) -> T {
    match value {
        Inherit => fail!(~"unexpected 'inherit' value in complete style"),
        Specified(v) => v
    }
}

<|endoftext|>


<commit_before>use core::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT};
use core::cell::UnsafeCell;
use core::marker::Sync;
use core::ops::{Drop, Deref, DerefMut};
use core::fmt;
use core::option::Option::{self, None, Some};
use core::default::Default;

use util::cpu_relax;

/// This type provides MUTual EXclusion based on spinning.
///
/// # Description
///
/// This structure behaves a lot like a normal Mutex. There are some differences:
///
/// - It may be used outside the runtime.
///   - A normal mutex will fail when used without the runtime, this will just lock
///   - When the runtime is present, it will call the deschedule function when appropriate
/// - No lock poisoning. When a fail occurs when the lock is held, no guarantees are made
///
/// When calling rust functions from bare threads, such as C `pthread`s, this lock will be very
/// helpful. In other cases however, you are encouraged to use the locks from the standard
/// library.
///
/// # Simple examples
///
/// ```
/// use spin;
/// let spin_mutex = spin::Mutex::new(0);
///
/// // Modify the data
/// {
///     let mut data = spin_mutex.lock();
///     *data = 2;
/// }
///
/// // Read the data
/// let answer =
/// {
///     let data = spin_mutex.lock();
///     *data
/// };
///
/// assert_eq!(answer, 2);
/// ```
///
/// # Thread-safety example
///
/// ```
/// use spin;
/// use std::sync::{Arc, Barrier};
///
/// let numthreads = 1000;
/// let spin_mutex = Arc::new(spin::Mutex::new(0));
///
/// // We use a barrier to ensure the readout happens after all writing
/// let barrier = Arc::new(Barrier::new(numthreads + 1));
///
/// for _ in (0..numthreads)
/// {
///     let my_barrier = barrier.clone();
///     let my_lock = spin_mutex.clone();
///     std::thread::spawn(move||
///     {
///         let mut guard = my_lock.lock();
///         *guard += 1;
///
///         // Release the lock to prevent a deadlock
///         drop(guard);
///         my_barrier.wait();
///     });
/// }
///
/// barrier.wait();
///
/// let answer = { *spin_mutex.lock() };
/// assert_eq!(answer, numthreads);
/// ```
pub struct Mutex<T: ?Sized>
{
    lock: AtomicBool,
    data: UnsafeCell<T>,
}

/// A guard to which the protected data can be accessed
///
/// When the guard falls out of scope it will release the lock.
pub struct MutexGuard<'a, T: ?Sized + 'a>
{
    lock: &'a AtomicBool,
    data: &'a mut T,
}

// Same unsafe impls as `std::sync::Mutex`
unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}

impl<T> Mutex<T>
{
    /// Creates a new spinlock wrapping the supplied data.
    ///
    /// May be used statically:
    ///
    /// ```
    /// #![feature(const_fn)]
    /// use spin;
    ///
    /// static MUTEX: spin::Mutex<()> = spin::Mutex::new(());
    ///
    /// fn demo() {
    ///     let lock = MUTEX.lock();
    ///     // do something with lock
    ///     drop(lock);
    /// }
    /// ```
    #[cfg(feature = "const_fn")]
    pub const fn new(user_data: T) -> Mutex<T>
    {
        Mutex
        {
            lock: ATOMIC_BOOL_INIT,
            data: UnsafeCell::new(user_data),
        }
    }

    /// Creates a new spinlock wrapping the supplied data.
    ///
    /// If you want to use it statically, you can use the `const_fn` feature.
    ///
    /// ```
    /// use spin;
    ///
    /// fn demo() {
    ///     let mutex = spin::Mutex::new(());
    ///     let lock = mutex.lock();
    ///     // do something with lock
    ///     drop(lock);
    /// }
    /// ```
    #[cfg(not(feature = "const_fn"))]
    pub fn new(user_data: T) -> Mutex<T>
    {
        Mutex
        {
            lock: ATOMIC_BOOL_INIT,
            data: UnsafeCell::new(user_data),
        }
    }

    /// Consumes this mutex, returning the underlying data.
    pub fn into_inner(self) -> T {
        // We know statically that there are no outstanding references to
        // `self` so there's no need to lock.
        let Mutex { data, .. } = self;
        unsafe { data.into_inner() }
    }
}

impl<T: ?Sized> Mutex<T>
{
    fn obtain_lock(&self)
    {
        while self.lock.compare_and_swap(false, true, Ordering::Acquire) != false
        {
            cpu_relax();
        }
    }

    /// Locks the spinlock and returns a guard.
    ///
    /// The returned value may be dereferenced for data access
    /// and the lock will be dropped when the guard falls out of scope.
    ///
    /// ```
    /// let mylock = spin::Mutex::new(0);
    /// {
    ///     let mut data = mylock.lock();
    ///     // The lock is now locked and the data can be accessed
    ///     *data += 1;
    ///     // The lock is implicitly dropped
    /// }
    ///
    /// ```
    pub fn lock(&self) -> MutexGuard<T>
    {
        self.obtain_lock();
        MutexGuard
        {
            lock: &self.lock,
            data: unsafe { &mut *self.data.get() },
        }
    }

    /// Tries to lock the mutex. If it is already locked, it will return None. Otherwise it returns
    /// a guard within Some.
    fn try_lock(&self) -> Option<MutexGuard<T>>
    {
        if self.lock.compare_and_swap(false, true, Ordering::Acquire) == false
        {
            Some(
                MutexGuard {
                    lock: &self.lock,
                    data: unsafe { &mut *self.data.get() },
                }
            )
        }
        else
        {
            None
        }
    }
}

impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T>
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
    {
        match self.try_lock()
        {
            Some(guard) => write!(f, "Mutex {{ data: {:?} }}", &*guard),
            None => write!(f, "Mutex {{ <locked> }}"),
        }
    }
}

impl<T: ?Sized + Default> Default for Mutex<T> {
    fn default() -> Mutex<T> {
        Mutex::new(Default::default())
    }
}

impl<'a, T: ?Sized> Deref for MutexGuard<'a, T>
{
    type Target = T;
    fn deref<'b>(&'b self) -> &'b T { &*self.data }
}

impl<'a, T: ?Sized> DerefMut for MutexGuard<'a, T>
{
    fn deref_mut<'b>(&'b mut self) -> &'b mut T { &mut *self.data }
}

impl<'a, T: ?Sized> Drop for MutexGuard<'a, T>
{
    /// The dropping of the MutexGuard will release the lock it was created from.
    fn drop(&mut self)
    {
        self.lock.store(false, Ordering::Release);
    }
}

#[cfg(test)]
mod tests {
    use std::prelude::v1::*;

    use std::sync::mpsc::channel;
    use std::sync::Arc;
    use std::sync::atomic::{AtomicUsize, Ordering};
    use std::thread;

    use super::*;

    #[derive(Eq, PartialEq, Debug)]
    struct NonCopy(i32);

    #[test]
    fn smoke() {
        let m = Mutex::new(());
        drop(m.lock());
        drop(m.lock());
    }

    #[test]
    #[cfg(feature = "const_fn")]
    fn lots_and_lots() {
        static M: Mutex<()>  = Mutex::new(());
        static mut CNT: u32 = 0;
        const J: u32 = 1000;
        const K: u32 = 3;

        fn inc() {
            for _ in 0..J {
                unsafe {
                    let _g = M.lock();
                    CNT += 1;
                }
            }
        }

        let (tx, rx) = channel();
        for _ in 0..K {
            let tx2 = tx.clone();
            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
            let tx2 = tx.clone();
            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
        }

        drop(tx);
        for _ in 0..2 * K {
            rx.recv().unwrap();
        }
        assert_eq!(unsafe {CNT}, J * K * 2);
    }

    #[test]
    fn try_lock() {
        let mutex = Mutex::new(42);

        // First lock succeeds
        let a = mutex.try_lock();
        assert_eq!(a.as_ref().map(|r| **r), Some(42));

        // Additional lock failes
        let b = mutex.try_lock();
        assert!(b.is_none());

        // After dropping lock, it succeeds again
        ::core::mem::drop(a);
        let c = mutex.try_lock();
        assert_eq!(c.as_ref().map(|r| **r), Some(42));
    }

    #[test]
    fn test_into_inner() {
        let m = Mutex::new(NonCopy(10));
        assert_eq!(m.into_inner(), NonCopy(10));
    }

    #[test]
    fn test_into_inner_drop() {
        struct Foo(Arc<AtomicUsize>);
        impl Drop for Foo {
            fn drop(&mut self) {
                self.0.fetch_add(1, Ordering::SeqCst);
            }
        }
        let num_drops = Arc::new(AtomicUsize::new(0));
        let m = Mutex::new(Foo(num_drops.clone()));
        assert_eq!(num_drops.load(Ordering::SeqCst), 0);
        {
            let _inner = m.into_inner();
            assert_eq!(num_drops.load(Ordering::SeqCst), 0);
        }
        assert_eq!(num_drops.load(Ordering::SeqCst), 1);
    }

    #[test]
    fn test_mutex_arc_nested() {
        // Tests nested mutexes and access
        // to underlying data.
        let arc = Arc::new(Mutex::new(1));
        let arc2 = Arc::new(Mutex::new(arc));
        let (tx, rx) = channel();
        let _t = thread::spawn(move|| {
            let lock = arc2.lock();
            let lock2 = lock.lock();
            assert_eq!(*lock2, 1);
            tx.send(()).unwrap();
        });
        rx.recv().unwrap();
    }

    #[test]
    fn test_mutex_arc_access_in_unwind() {
        let arc = Arc::new(Mutex::new(1));
        let arc2 = arc.clone();
        let _ = thread::spawn(move|| -> () {
            struct Unwinder {
                i: Arc<Mutex<i32>>,
            }
            impl Drop for Unwinder {
                fn drop(&mut self) {
                    *self.i.lock() += 1;
                }
            }
            let _u = Unwinder { i: arc2 };
            panic!();
        }).join();
        let lock = arc.lock();
        assert_eq!(*lock, 2);
    }

    #[test]
    fn test_mutex_unsized() {
        let mutex: &Mutex<[i32]> = &Mutex::new([1, 2, 3]);
        {
            let b = &mut *mutex.lock();
            b[0] = 4;
            b[2] = 5;
        }
        let comp: &[i32] = &[4, 2, 5];
        assert_eq!(&*mutex.lock(), comp);
    }
}
<commit_msg>Make Mutex::try_lock public<commit_after>use core::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT};
use core::cell::UnsafeCell;
use core::marker::Sync;
use core::ops::{Drop, Deref, DerefMut};
use core::fmt;
use core::option::Option::{self, None, Some};
use core::default::Default;

use util::cpu_relax;

/// This type provides MUTual EXclusion based on spinning.
///
/// # Description
///
/// This structure behaves a lot like a normal Mutex. There are some differences:
///
/// - It may be used outside the runtime.
///   - A normal mutex will fail when used without the runtime, this will just lock
///   - When the runtime is present, it will call the deschedule function when appropriate
/// - No lock poisoning. When a fail occurs when the lock is held, no guarantees are made
///
/// When calling rust functions from bare threads, such as C `pthread`s, this lock will be very
/// helpful. In other cases however, you are encouraged to use the locks from the standard
/// library.
///
/// # Simple examples
///
/// ```
/// use spin;
/// let spin_mutex = spin::Mutex::new(0);
///
/// // Modify the data
/// {
///     let mut data = spin_mutex.lock();
///     *data = 2;
/// }
///
/// // Read the data
/// let answer =
/// {
///     let data = spin_mutex.lock();
///     *data
/// };
///
/// assert_eq!(answer, 2);
/// ```
///
/// # Thread-safety example
///
/// ```
/// use spin;
/// use std::sync::{Arc, Barrier};
///
/// let numthreads = 1000;
/// let spin_mutex = Arc::new(spin::Mutex::new(0));
///
/// // We use a barrier to ensure the readout happens after all writing
/// let barrier = Arc::new(Barrier::new(numthreads + 1));
///
/// for _ in (0..numthreads)
/// {
///     let my_barrier = barrier.clone();
///     let my_lock = spin_mutex.clone();
///     std::thread::spawn(move||
///     {
///         let mut guard = my_lock.lock();
///         *guard += 1;
///
///         // Release the lock to prevent a deadlock
///         drop(guard);
///         my_barrier.wait();
///     });
/// }
///
/// barrier.wait();
///
/// let answer = { *spin_mutex.lock() };
/// assert_eq!(answer, numthreads);
/// ```
pub struct Mutex<T: ?Sized>
{
    lock: AtomicBool,
    data: UnsafeCell<T>,
}

/// A guard to which the protected data can be accessed
///
/// When the guard falls out of scope it will release the lock.
pub struct MutexGuard<'a, T: ?Sized + 'a>
{
    lock: &'a AtomicBool,
    data: &'a mut T,
}

// Same unsafe impls as `std::sync::Mutex`
unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}

impl<T> Mutex<T>
{
    /// Creates a new spinlock wrapping the supplied data.
    ///
    /// May be used statically:
    ///
    /// ```
    /// #![feature(const_fn)]
    /// use spin;
    ///
    /// static MUTEX: spin::Mutex<()> = spin::Mutex::new(());
    ///
    /// fn demo() {
    ///     let lock = MUTEX.lock();
    ///     // do something with lock
    ///     drop(lock);
    /// }
    /// ```
    #[cfg(feature = "const_fn")]
    pub const fn new(user_data: T) -> Mutex<T>
    {
        Mutex
        {
            lock: ATOMIC_BOOL_INIT,
            data: UnsafeCell::new(user_data),
        }
    }

    /// Creates a new spinlock wrapping the supplied data.
    ///
    /// If you want to use it statically, you can use the `const_fn` feature.
    ///
    /// ```
    /// use spin;
    ///
    /// fn demo() {
    ///     let mutex = spin::Mutex::new(());
    ///     let lock = mutex.lock();
    ///     // do something with lock
    ///     drop(lock);
    /// }
    /// ```
    #[cfg(not(feature = "const_fn"))]
    pub fn new(user_data: T) -> Mutex<T>
    {
        Mutex
        {
            lock: ATOMIC_BOOL_INIT,
            data: UnsafeCell::new(user_data),
        }
    }

    /// Consumes this mutex, returning the underlying data.
    pub fn into_inner(self) -> T {
        // We know statically that there are no outstanding references to
        // `self` so there's no need to lock.
        let Mutex { data, .. } = self;
        unsafe { data.into_inner() }
    }
}

impl<T: ?Sized> Mutex<T>
{
    fn obtain_lock(&self)
    {
        while self.lock.compare_and_swap(false, true, Ordering::Acquire) != false
        {
            cpu_relax();
        }
    }

    /// Locks the spinlock and returns a guard.
    ///
    /// The returned value may be dereferenced for data access
    /// and the lock will be dropped when the guard falls out of scope.
    ///
    /// ```
    /// let mylock = spin::Mutex::new(0);
    /// {
    ///     let mut data = mylock.lock();
    ///     // The lock is now locked and the data can be accessed
    ///     *data += 1;
    ///     // The lock is implicitly dropped
    /// }
    ///
    /// ```
    pub fn lock(&self) -> MutexGuard<T>
    {
        self.obtain_lock();
        MutexGuard
        {
            lock: &self.lock,
            data: unsafe { &mut *self.data.get() },
        }
    }

    /// Tries to lock the mutex. If it is already locked, it will return None. Otherwise it returns
    /// a guard within Some.
    pub fn try_lock(&self) -> Option<MutexGuard<T>>
    {
        if self.lock.compare_and_swap(false, true, Ordering::Acquire) == false
        {
            Some(
                MutexGuard {
                    lock: &self.lock,
                    data: unsafe { &mut *self.data.get() },
                }
            )
        }
        else
        {
            None
        }
    }
}

impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T>
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
    {
        match self.try_lock()
        {
            Some(guard) => write!(f, "Mutex {{ data: {:?} }}", &*guard),
            None => write!(f, "Mutex {{ <locked> }}"),
        }
    }
}

impl<T: ?Sized + Default> Default for Mutex<T> {
    fn default() -> Mutex<T> {
        Mutex::new(Default::default())
    }
}

impl<'a, T: ?Sized> Deref for MutexGuard<'a, T>
{
    type Target = T;
    fn deref<'b>(&'b self) -> &'b T { &*self.data }
}

impl<'a, T: ?Sized> DerefMut for MutexGuard<'a, T>
{
    fn deref_mut<'b>(&'b mut self) -> &'b mut T { &mut *self.data }
}

impl<'a, T: ?Sized> Drop for MutexGuard<'a, T>
{
    /// The dropping of the MutexGuard will release the lock it was created from.
    fn drop(&mut self)
    {
        self.lock.store(false, Ordering::Release);
    }
}

#[cfg(test)]
mod tests {
    use std::prelude::v1::*;

    use std::sync::mpsc::channel;
    use std::sync::Arc;
    use std::sync::atomic::{AtomicUsize, Ordering};
    use std::thread;

    use super::*;

    #[derive(Eq, PartialEq, Debug)]
    struct NonCopy(i32);

    #[test]
    fn smoke() {
        let m = Mutex::new(());
        drop(m.lock());
        drop(m.lock());
    }

    #[test]
    #[cfg(feature = "const_fn")]
    fn lots_and_lots() {
        static M: Mutex<()>  = Mutex::new(());
        static mut CNT: u32 = 0;
        const J: u32 = 1000;
        const K: u32 = 3;

        fn inc() {
            for _ in 0..J {
                unsafe {
                    let _g = M.lock();
                    CNT += 1;
                }
            }
        }

        let (tx, rx) = channel();
        for _ in 0..K {
            let tx2 = tx.clone();
            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
            let tx2 = tx.clone();
            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
        }

        drop(tx);
        for _ in 0..2 * K {
            rx.recv().unwrap();
        }
        assert_eq!(unsafe {CNT}, J * K * 2);
    }

    #[test]
    fn try_lock() {
        let mutex = Mutex::new(42);

        // First lock succeeds
        let a = mutex.try_lock();
        assert_eq!(a.as_ref().map(|r| **r), Some(42));

        // Additional lock failes
        let b = mutex.try_lock();
        assert!(b.is_none());

        // After dropping lock, it succeeds again
        ::core::mem::drop(a);
        let c = mutex.try_lock();
        assert_eq!(c.as_ref().map(|r| **r), Some(42));
    }

    #[test]
    fn test_into_inner() {
        let m = Mutex::new(NonCopy(10));
        assert_eq!(m.into_inner(), NonCopy(10));
    }

    #[test]
    fn test_into_inner_drop() {
        struct Foo(Arc<AtomicUsize>);
        impl Drop for Foo {
            fn drop(&mut self) {
                self.0.fetch_add(1, Ordering::SeqCst);
            }
        }
        let num_drops = Arc::new(AtomicUsize::new(0));
        let m = Mutex::new(Foo(num_drops.clone()));
        assert_eq!(num_drops.load(Ordering::SeqCst), 0);
        {
            let _inner = m.into_inner();
            assert_eq!(num_drops.load(Ordering::SeqCst), 0);
        }
        assert_eq!(num_drops.load(Ordering::SeqCst), 1);
    }

    #[test]
    fn test_mutex_arc_nested() {
        // Tests nested mutexes and access
        // to underlying data.
        let arc = Arc::new(Mutex::new(1));
        let arc2 = Arc::new(Mutex::new(arc));
        let (tx, rx) = channel();
        let _t = thread::spawn(move|| {
            let lock = arc2.lock();
            let lock2 = lock.lock();
            assert_eq!(*lock2, 1);
            tx.send(()).unwrap();
        });
        rx.recv().unwrap();
    }

    #[test]
    fn test_mutex_arc_access_in_unwind() {
        let arc = Arc::new(Mutex::new(1));
        let arc2 = arc.clone();
        let _ = thread::spawn(move|| -> () {
            struct Unwinder {
                i: Arc<Mutex<i32>>,
            }
            impl Drop for Unwinder {
                fn drop(&mut self) {
                    *self.i.lock() += 1;
                }
            }
            let _u = Unwinder { i: arc2 };
            panic!();
        }).join();
        let lock = arc.lock();
        assert_eq!(*lock, 2);
    }

    #[test]
    fn test_mutex_unsized() {
        let mutex: &Mutex<[i32]> = &Mutex::new([1, 2, 3]);
        {
            let b = &mut *mutex.lock();
            b[0] = 4;
            b[2] = 5;
        }
        let comp: &[i32] = &[4, 2, 5];
        assert_eq!(&*mutex.lock(), comp);
    }
}
<|endoftext|>


<commit_before>const DATA: &'static str = include_str!("../data/input_24.txt");

use std::cmp;
use std::{u64, usize};
use std::cell::Cell;

pub fn main() -> Vec<String> {
    if let Ok(mut v) = DATA.lines()
                           .map(|l| l.parse::<u64>())
                           .collect::<Result<Vec<u64>, _>>() {
        v.sort_by(|a, b| b.cmp(a));

        let weight = v.iter().sum::<u64>() / 3;
        let s1 = min_qe(&v, weight).unwrap().to_string();

        let weight = v.iter().sum::<u64>() / 4;
        let s2 = min_qe(&v, weight).unwrap().to_string();

        vec![s1, s2]
    } else {
        vec![]
    }
}

fn min_qe(data: &[u64], weight: u64) -> Option<u64> {
    let best_size: Cell<usize> = Cell::new(usize::MAX);
    let best_qe: Cell<u64> = Cell::new(u64::MAX);
    let stop = |ss: &[u64]| {
        (ss.iter().sum::<u64>() > weight) ||
        (ss.iter().product::<u64>() > best_qe.get()) ||
        (ss.len() > best_size.get())
    };
    let ps = PowerSet::with_prune_condition(&data, stop);
    let subsets = ps.filter(|ss| ss.iter().sum::<u64>() == weight)
                    .inspect(|ss| {
                        best_size.set(cmp::min(best_size.get(), ss.len()));
                        best_qe.set(cmp::min(best_qe.get(), ss.iter().product()));
                    })
                    .collect::<Vec<_>>();
    subsets.iter()
           .filter(|ss| ss.len() == best_size.get())
           .map(|ss| ss.iter().product::<u64>())
           .min()
}

struct PowerSet<'a, T>
    where T: 'a + Copy
{
    stack: Vec<(Vec<T>, &'a [T])>,
    stop: Box<Fn(&[T]) -> bool + 'a>,
}

impl<'a, T> PowerSet<'a, T> where T: 'a + Copy
{
    fn new(data: &'a [T]) -> PowerSet<'a, T> {
        let mut stack = Vec::new();
        if let Some((selected, remaining)) = data.split_last() {
            stack.push((vec![*selected], remaining));
            stack.push((vec![], remaining));
        } else {
            stack.push((vec![], data))
        }
        PowerSet {
            stack: stack,
            stop: box |_| false,
        }
    }

    fn with_prune_condition<F>(data: &'a [T], stop: F) -> PowerSet<'a, T>
        where F: 'a + Fn(&[T]) -> bool
    {
        PowerSet { stop: box stop, ..PowerSet::new(data) }
    }
}

impl<'a, T> Iterator for PowerSet<'a, T> where T: 'a + Copy
{
    type Item = Vec<T>;

    fn next(&mut self) -> Option<Vec<T>> {
        if let Some((selected, remaining)) = self.stack.pop() {
            if let Some((sel, rem)) = remaining.split_last() {
                if !(self.stop)(&selected) {
                    let mut r = selected.clone();
                    r.push(*sel);
                    self.stack.push((r, rem));
                    self.stack.push((selected, rem));
                }
                self.next()
            } else {
                Some(selected)
            }
        } else {
            None
        }
    }
}
<commit_msg>day24: fix bug from over aggressive optimization<commit_after>const DATA: &'static str = include_str!("../data/input_24.txt");

use std::cmp;
use std::usize;
use std::cell::Cell;

pub fn main() -> Vec<String> {
    if let Ok(mut v) = DATA.lines()
                           .map(|l| l.parse::<u64>())
                           .collect::<Result<Vec<u64>, _>>() {
        v.sort_by(|a, b| b.cmp(a));

        let weight = v.iter().sum::<u64>() / 3;
        let s1 = min_qe(&v, weight).unwrap().to_string();

        let weight = v.iter().sum::<u64>() / 4;
        let s2 = min_qe(&v, weight).unwrap().to_string();

        vec![s1, s2]
    } else {
        vec![]
    }
}

fn min_qe(data: &[u64], weight: u64) -> Option<u64> {
    let best_size: Cell<usize> = Cell::new(usize::MAX);
    let stop = |ss: &[u64]| (ss.iter().sum::<u64>() > weight) || (ss.len() > best_size.get());
    let ps = PowerSet::with_prune_condition(&data, stop);
    let subsets = ps.filter(|ss| ss.iter().sum::<u64>() == weight)
                    .inspect(|ss| best_size.set(cmp::min(best_size.get(), ss.len())))
                    .collect::<Vec<_>>();
    subsets.iter()
           .filter(|ss| ss.len() == best_size.get())
           .map(|ss| ss.iter().product::<u64>())
           .min()
}

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

    #[test]
    fn example_1() {
        let data = [1, 2, 3, 4, 5, 7, 8, 9, 10, 11];
        assert_eq!(min_qe(&data, data.iter().sum::<u64>() / 3), Some(99));
    }

    #[test]
    fn example_2() {
        let data = [1, 2, 3, 4, 5, 7, 8, 9, 10, 11];
        assert_eq!(min_qe(&data, data.iter().sum::<u64>() / 4), Some(44));
    }
}

struct PowerSet<'a, T>
    where T: 'a + Copy
{
    stack: Vec<(Vec<T>, &'a [T])>,
    stop: Box<Fn(&[T]) -> bool + 'a>,
}

impl<'a, T> PowerSet<'a, T> where T: 'a + Copy
{
    fn new(data: &'a [T]) -> PowerSet<'a, T> {
        let mut stack = Vec::new();
        if let Some((selected, remaining)) = data.split_last() {
            stack.push((vec![*selected], remaining));
            stack.push((vec![], remaining));
        } else {
            stack.push((vec![], data))
        }
        PowerSet {
            stack: stack,
            stop: box |_| false,
        }
    }

    fn with_prune_condition<F>(data: &'a [T], stop: F) -> PowerSet<'a, T>
        where F: 'a + Fn(&[T]) -> bool
    {
        PowerSet { stop: box stop, ..PowerSet::new(data) }
    }
}

impl<'a, T> Iterator for PowerSet<'a, T> where T: 'a + Copy
{
    type Item = Vec<T>;

    fn next(&mut self) -> Option<Vec<T>> {
        if let Some((selected, remaining)) = self.stack.pop() {
            if let Some((sel, rem)) = remaining.split_last() {
                if !(self.stop)(&selected) {
                    let mut r = selected.clone();
                    r.push(*sel);
                    self.stack.push((r, rem));
                    self.stack.push((selected, rem));
                }
                self.next()
            } else {
                Some(selected)
            }
        } else {
            None
        }
    }
}
<|endoftext|>


<commit_before>use core::Block;
use graph::{Graph , NodeIndex};

// we could pull the vector graph out .. eg NodeData<T> and have module hold a graph ..

pub struct Module
{
    graph: Graph<Box<Block>>,
}

impl Module
{
    pub fn new() -> Module {
        Module { graph: Graph::<Box<Block>>::new() }
    }

//TODO
//    pub fn add_block(&self, block: &Block) { self.add_box_block( Box::new( *block))  }

    pub fn add_box_block(& mut self, block: Box<Block>) {  self.graph.add_node(block); }

    /// this will get WAY more complicated ..
    /// we need to handle loops which never finish , re run on completion , threading , timed and priority etc
    pub fn process_blocks(& mut self)
    {

        // new method process(n) and recurse
        self.graph.get_node(0).process();
        let successors: Vec<NodeIndex> = self.graph.successors(0).collect();

        for i in successors { self.graph.get_node(i).process(); }
    }
}

// we dont really need an interface
pub trait IModule
{
    //fn process(<Vec<O>>) -> Vec<O>;
    //(args: &[&str])
    //fn process(&[ &[O] ]) -> Vec<O>;
    fn process_blocks(&mut self) ; // or return slice
    // void LoadInputsIntoModules();
    //  void ProcessFirstBlock();
    //  INeuronBlock GetEntryBlock();
    //  INeuronBlock GetBlock(uint id);
    //  void AddRunningTasks(Task task);
    //  void RemoveRunningTasks(Task task);

}

// mod test {
//     use super::*;

    // #[test]
    // pub fn example() {
    //
    //     // N0 ---E0---> N1 ---E1---> 2
    //     // |                         ^
    //     // E2                        |
    //     // |                         |
    //     // v                         |
    //     // N3 ----------E3-----------+
    //
    //     let mut graph = Module::new();
    //
    //     let n0 = graph.add_node();
    //     let n1 = graph.add_node();
    //     let n2 = graph.add_node();
    //     let n3 = graph.add_node();
    //
    //     graph.add_edge(n0, n1); // e0
    //     graph.add_edge(n1, n2); // e1
    //     graph.add_edge(n0, n3); // e2
    //     graph.add_edge(n3, n2); // e3
    //
    //     let successors: Vec<NodeIndex> = graph.successors(n0).collect();
    //     assert_eq!(&successors[..], &[n3, n1]);
    // }
//}
<commit_msg>some module tests working<commit_after>use core::Block;
use graph::{Graph , NodeIndex};

// we could pull the vector graph out .. eg NodeData<T> and have module hold a graph ..

pub struct Module<'b>
{
    graph: Graph<Box<Block+ 'b>>,
}

impl<'b> Module<'b>
{
    pub fn new() -> Module<'b> {
        Module { graph: Graph::<Box<Block + 'b>>::new() }
    }

//TODO
//    pub fn add_block(&self, block: &Block) { self.add_box_block( Box::new( *block))  }

    pub fn add_box_block(& mut self, block: Box<Block+'b>) {  self.graph.add_node(block); }

    /// this will get WAY more complicated ..
    /// we need to handle loops which never finish , re run on completion , threading , timed and priority etc
    pub fn process_blocks(& mut self)
    {

        // new method process(n) and recurse
        self.graph.get_node(0).process();
        let successors: Vec<NodeIndex> = self.graph.successors(0).collect();

        for i in successors { self.graph.get_node(i).process(); }
    }
}

// we dont really need an interface
pub trait IModule
{
    //fn process(<Vec<O>>) -> Vec<O>;
    //(args: &[&str])
    //fn process(&[ &[O] ]) -> Vec<O>;
    fn process_blocks(&mut self) ; // or return slice
    // void LoadInputsIntoModules();
    //  void ProcessFirstBlock();
    //  INeuronBlock GetEntryBlock();
    //  INeuronBlock GetBlock(uint id);
    //  void AddRunningTasks(Task task);
    //  void RemoveRunningTasks(Task task);

}

// mod test {
//     use super::*;

    // #[test]
    // pub fn example() {
    //
    //     // N0 ---E0---> N1 ---E1---> 2
    //     // |                         ^
    //     // E2                        |
    //     // |                         |
    //     // v                         |
    //     // N3 ----------E3-----------+
    //
    //     let mut graph = Module::new();
    //
    //     let n0 = graph.add_node();
    //     let n1 = graph.add_node();
    //     let n2 = graph.add_node();
    //     let n3 = graph.add_node();
    //
    //     graph.add_edge(n0, n1); // e0
    //     graph.add_edge(n1, n2); // e1
    //     graph.add_edge(n0, n3); // e2
    //     graph.add_edge(n3, n2); // e3
    //
    //     let successors: Vec<NodeIndex> = graph.successors(n0).collect();
    //     assert_eq!(&successors[..], &[n3, n1]);
    // }
//}
<|endoftext|>


<commit_before>use super::ByteSize;

impl std::str::FromStr for ByteSize {
    type Err = String;

    fn from_str(value: &str) -> Result<Self, Self::Err> {
        match value.parse::<u64>() {
            Ok(v) => return Ok(Self(v)), // simple case, bytes
            Err(_) => {}
        };
        let number: String = value
            .chars()
            .take_while(|c| c.is_digit(10) || c == &'.')
            .collect();
        match number.parse::<f64>() {
            Ok(v) => {
                let suffix: String = value
                    .chars()
                    .skip_while(|c| c.is_whitespace() || c.is_digit(10) || c == &'.')
                    .collect();
                match suffix.parse::<Unit>() {
                    Ok(u) => Ok(Self((v * u.0 as f64) as u64)),
                    Err(error) => Err(format!(
                        "couldn't parse {:?} into a known SI unit, {}",
                        suffix, error
                    )),
                }
            }
            Err(error) => Err(format!(
                "couldn't parse {:?} into a ByteSize, {}",
                value, error
            )),
        }
    }
}

#[repr(transparent)]
struct Unit(pub(crate) u64);

impl Unit {
    const KB: u64 = super::KB;
    const KIB: u64 = super::KIB;
    const MB: u64 = super::MB;
    const MIB: u64 = super::MIB;
    const GB: u64 = super::GB;
    const GIB: u64 = super::GIB;
    const TB: u64 = super::TB;
    const TIB: u64 = super::TIB;
    const PB: u64 = super::PB;
    const PIB: u64 = super::PIB;
}

impl std::str::FromStr for Unit {
    type Err = String;

    fn from_str(unit: &str) -> Result<Self, Self::Err> {
        match unit.to_lowercase().as_str() {
            "k" | "kb" => Ok(Self(Self::KB)),
            "ki" | "kib" => Ok(Self(Self::KIB)),
            "m" | "mb" => Ok(Self(Self::MB)),
            "mi" | "mib" => Ok(Self(Self::MIB)),
            "g" | "gb" => Ok(Self(Self::GB)),
            "gi" | "gib" => Ok(Self(Self::GIB)),
            "t" | "tb" => Ok(Self(Self::TB)),
            "ti" | "tib" => Ok(Self(Self::TIB)),
            "p" | "pb" => Ok(Self(Self::PB)),
            "pi" | "pib" => Ok(Self(Self::PIB)),
            _ => Err(format!("couldn't parse unit of {:?}", unit)),
        }
    }
}

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

    #[test]
    fn when_ok() {
        // shortcut for writing test cases
        fn parse(s: &str) -> u64 {
            s.parse::<ByteSize>().unwrap().0
        }

        assert_eq!("0".parse::<ByteSize>().unwrap().0, 0);
        assert_eq!(parse("0"), 0);
        assert_eq!(parse("500"), 500);
        assert_eq!(parse("1K"), 1 * Unit::KB);
        assert_eq!(parse("1Ki"), 1 * Unit::KIB);
        assert_eq!(parse("1.5Ki"), (1.5 * Unit::KIB as f64) as u64);
        assert_eq!(parse("1KiB"), 1 * Unit::KIB);
        assert_eq!(parse("1.5KiB"), (1.5 * Unit::KIB as f64) as u64);
        assert_eq!(parse("3 MB"), 3 * Unit::MB);
        assert_eq!(parse("4 MiB"), 4 * Unit::MIB);
        assert_eq!(parse("6 GB"), 6 * Unit::GB);
        assert_eq!(parse("4 GiB"), 4 * Unit::GIB);
        assert_eq!(parse("88TB"), 88 * Unit::TB);
        assert_eq!(parse("521TiB"), 521 * Unit::TIB);
        assert_eq!(parse("8 PB"), 8 * Unit::PB);
        assert_eq!(parse("12 PiB"), 12 * Unit::PIB);
    }

    #[test]
    fn when_err() {
        // shortcut for writing test cases
        fn parse(s: &str) -> Result<ByteSize, String> {
            s.parse::<ByteSize>()
        }

        assert!(parse("").is_err());
        assert!(parse("a124GB").is_err());
    }
}
<commit_msg>add feedback test<commit_after>use super::ByteSize;

impl std::str::FromStr for ByteSize {
    type Err = String;

    fn from_str(value: &str) -> Result<Self, Self::Err> {
        match value.parse::<u64>() {
            Ok(v) => return Ok(Self(v)), // simple case, bytes
            Err(_) => {}
        };
        let number: String = value
            .chars()
            .take_while(|c| c.is_digit(10) || c == &'.')
            .collect();
        match number.parse::<f64>() {
            Ok(v) => {
                let suffix: String = value
                    .chars()
                    .skip_while(|c| c.is_whitespace() || c.is_digit(10) || c == &'.')
                    .collect();
                match suffix.parse::<Unit>() {
                    Ok(u) => Ok(Self((v * u.0 as f64) as u64)),
                    Err(error) => Err(format!(
                        "couldn't parse {:?} into a known SI unit, {}",
                        suffix, error
                    )),
                }
            }
            Err(error) => Err(format!(
                "couldn't parse {:?} into a ByteSize, {}",
                value, error
            )),
        }
    }
}

#[repr(transparent)]
struct Unit(pub(crate) u64);

impl Unit {
    const KB: u64 = super::KB;
    const KIB: u64 = super::KIB;
    const MB: u64 = super::MB;
    const MIB: u64 = super::MIB;
    const GB: u64 = super::GB;
    const GIB: u64 = super::GIB;
    const TB: u64 = super::TB;
    const TIB: u64 = super::TIB;
    const PB: u64 = super::PB;
    const PIB: u64 = super::PIB;
}

impl std::str::FromStr for Unit {
    type Err = String;

    fn from_str(unit: &str) -> Result<Self, Self::Err> {
        match unit.to_lowercase().as_str() {
            "k" | "kb" => Ok(Self(Self::KB)),
            "ki" | "kib" => Ok(Self(Self::KIB)),
            "m" | "mb" => Ok(Self(Self::MB)),
            "mi" | "mib" => Ok(Self(Self::MIB)),
            "g" | "gb" => Ok(Self(Self::GB)),
            "gi" | "gib" => Ok(Self(Self::GIB)),
            "t" | "tb" => Ok(Self(Self::TB)),
            "ti" | "tib" => Ok(Self(Self::TIB)),
            "p" | "pb" => Ok(Self(Self::PB)),
            "pi" | "pib" => Ok(Self(Self::PIB)),
            _ => Err(format!("couldn't parse unit of {:?}", unit)),
        }
    }
}

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

    #[test]
    fn when_ok() {
        // shortcut for writing test cases
        fn parse(s: &str) -> u64 {
            s.parse::<ByteSize>().unwrap().0
        }

        assert_eq!("0".parse::<ByteSize>().unwrap().0, 0);
        assert_eq!(parse("0"), 0);
        assert_eq!(parse("500"), 500);
        assert_eq!(parse("1K"), 1 * Unit::KB);
        assert_eq!(parse("1Ki"), 1 * Unit::KIB);
        assert_eq!(parse("1.5Ki"), (1.5 * Unit::KIB as f64) as u64);
        assert_eq!(parse("1KiB"), 1 * Unit::KIB);
        assert_eq!(parse("1.5KiB"), (1.5 * Unit::KIB as f64) as u64);
        assert_eq!(parse("3 MB"), 3 * Unit::MB);
        assert_eq!(parse("4 MiB"), 4 * Unit::MIB);
        assert_eq!(parse("6 GB"), 6 * Unit::GB);
        assert_eq!(parse("4 GiB"), 4 * Unit::GIB);
        assert_eq!(parse("88TB"), 88 * Unit::TB);
        assert_eq!(parse("521TiB"), 521 * Unit::TIB);
        assert_eq!(parse("8 PB"), 8 * Unit::PB);
        assert_eq!(parse("12 PiB"), 12 * Unit::PIB);
    }

    #[test]
    fn when_err() {
        // shortcut for writing test cases
        fn parse(s: &str) -> Result<ByteSize, String> {
            s.parse::<ByteSize>()
        }

        assert!(parse("").is_err());
        assert!(parse("a124GB").is_err());
    }

    #[test]
    fn to_and_from_str() {
        assert_eq!(
            format!("{}", "128GB".parse::<ByteSize>().unwrap())
                .parse::<ByteSize>()
                .unwrap()
                .0,
            128 * Unit::GB
        );
        assert_eq!(
            super::super::to_string("128.000 GiB".parse::<ByteSize>().unwrap().0, true)
                .parse::<ByteSize>()
                .unwrap()
                .0,
            128 * Unit::GIB
        );
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::fmt::{ Display, Error, Formatter };

#[derive(Debug, PartialEq)]
pub enum JsonOption {
    Object(HashMap<String, JsonOption>),
    Array(Vec<JsonOption>),
    String(String),
    Integer(i32),
    Number(f32),
    None,
}

impl Display for JsonOption {
    fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
        match *self {
            JsonOption::Object(ref object) => {
                write!(formatter, "{:?}", object)
            },
            JsonOption::Array(ref vector) => {
                write!(formatter, "{:?}", vector)
            },
            JsonOption::String(ref string) => {
                write!(formatter, "String({})", string)
            },
            JsonOption::Integer(integer) => {
                write!(formatter, "Integer({})", integer)
            },
            JsonOption::Number(number) => {
                write!(formatter, "Number({})", number)
            },
            JsonOption::None => {
                write!(formatter, "None")
            },
        }
    }
}

<commit_msg>Some quality of life improvements<commit_after>use std::collections::HashMap;
use std::fmt::{ Display, Error, Formatter };

#[derive(Debug, PartialEq)]
pub enum JsonOption {
    Object(HashMap<String, JsonOption>),
    Array(Vec<JsonOption>),
    String(String),
    Integer(i32),
    Number(f32),
    None,
}

impl JsonOption {
    pub fn object(&self) -> &Self {
        match *self {
            JsonOption::Object(_) => self,
            _ => panic!("Expecting Object got {}", self),
        }
    }

    pub fn array(&self) -> &Self {
        match *self {
            JsonOption::Array(_) => self,
            _ => panic!("Expecting Array got {}", self),
        }
    }

    pub fn string(&self) -> &Self {
        match *self {
            JsonOption::String(_) => self,
            _ => panic!("Expecting String got {}", self),
        }
    }

    pub fn integer(&self) -> &Self {
        match *self {
            JsonOption::Integer(_) => self,
            _ => panic!("Expecting Integer got {}", self),
        }
    }

    pub fn number(&self) -> &Self {
        match *self {
            JsonOption::Number(_) => self,
            _ => panic!("Expecting Number got {}", self),
        }
    }

    pub fn none(&self) -> &Self {
        match *self {
            JsonOption::None => self,
            _ => panic!("Expecting None got {}", self),
        }
    }
}

impl Display for JsonOption {
    fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
        match *self {
            JsonOption::Object(ref object) => {
                write!(formatter, "{:?}", object)
            },
            JsonOption::Array(ref vector) => {
                write!(formatter, "{:?}", vector)
            },
            JsonOption::String(ref string) => {
                write!(formatter, "String({})", string)
            },
            JsonOption::Integer(integer) => {
                write!(formatter, "Integer({})", integer)
            },
            JsonOption::Number(number) => {
                write!(formatter, "Number({})", number)
            },
            JsonOption::None => {
                write!(formatter, "None")
            },
        }
    }
}

<|endoftext|>


<commit_before>use std::os::unix::io::RawFd;
use std::slice;
use std::mem;
use std::marker::PhantomData;
use nix::sys::epoll::*;
use nix::Result;

use socket::Socket;
use event::Event;
use notification::Notification;
use registration::Registration;

static EPOLL_EVENT_SIZE: usize = 1024;

pub struct Poller<T> {
    epfd: RawFd,
    registrar: Registrar<T>,
    events: Vec<EpollEvent>
}

impl<T> Poller<T> {
    pub fn new() -> Result<Poller> {
        let epfd = try!(epoll_create());
        Ok(Poller {
            epfd: epfd,
            registrar: Registrar::new(epfd),
            events: Vec::with_capacity(EPOLL_EVENT_SIZE)
        })
    }

    pub fn get_registrar(&self) -> Registrar {
        self.registrar.clone()
    }

    /// Wait for epoll events. Return a list of notifications. Notifications contain user data
    /// registered with epoll_ctl which is extracted from the data member returned from epoll_wait.
    pub fn wait(&mut self, timeout_ms: usize) -> Result<Vec<Notification<T>>> {

        // Create a buffer to read events into
        let dst = unsafe {
            slice::from_raw_parts_mut(self.events.as_mut_ptr(), self.events.capacity())
        };

        let count = try!(epoll_wait(self.epfd, dst, timeout_ms as isize));

        // Set the length of the vector to what was filled in by the call to epoll_wait
        unsafe { self.events.set_len(count); }

        Ok(self.events.iter().map(|e| {
            let registration = unsafe {
               let registration_ptr: *mut Registration<T> = mem::transmute(e.data);
               Box::from_raw(registration_ptr)
            };

            Notification {
                event: event_from_kind(e.events),
                registration: registration
            }
        }).collect())
    }

}

#[derive(Debug)]
pub struct Registrar {
    epfd: RawFd,

    // We use PhantomData here so that this type logically requires being tied to type T.
    // Since the Registrar is tied to the Poller, which stores data of type T, we want to ensure
    // that when we register data, we only register data of type T.
    // See https://doc.rust-lang.org/std/marker/struct.PhantomData.html#unused-type-parameters
    phantom: PhantomData<T>
}

impl<T> Clone for Registrar<T> {
    fn clone(&self) -> Registrar<T> {
        Registrar {
            epfd: self.epfd.clone(),
            phantom: PhantomData
        }
    }
}

impl<T> Registrar<T> {
    fn new(epfd: RawFd) -> Registrar {
        Registrar {
            epfd: epfd
        }
    }

    /// Allocate a Registration containing a Socket and user data of type T on the heap.
    /// Cast the pointer to this object to a u64 so it can be placed in an EpollEvent and passed to
    /// the kernel with a call to `epoll_ctl`. This pointer will be returned from `epoll_wait` when
    /// the socket is ready to be used.
    ///
    /// Passing the relevant user data into the kernel allows decoupling the registration of sockets
    /// from waiting for their readyness. This means that we can register sockets on one thread and
    /// wait for them to be ready on another thread, using the kernel as the method of
    /// communication.
    ///
    /// NOTE: THIS ONLY WORKS ON 64-BIT ARCHITECTURES
    ///
    pub fn register<T>(&self, sock: Socket, event: Event, user_data: T) -> Result<()> {
        let sock_fd = sock.as_raw_fd();
        let registration = Box::new(Registration::new(sock, event.clone(), user_data));

        let registration_ptr: u64 = unsafe {
            mem::transmute(Box::into_raw(registration))
        };

        let info = EpollEvent {
            events: kind_from_event(event),
            data: registration_ptr
        };

        epoll_ctl(self.epfd, EpollOp::EpollCtlAdd, sock_fd, &info)
    }
}

fn event_from_kind(kind: EpollEventKind) -> Event {
    let mut event = Event::Read;
    if kind.contains(EPOLLIN) && kind.contains(EPOLLOUT) {
        event = Event::Both;
    } else if kind.contains(EPOLLOUT) {
        event = Event::Write;
    }
    event
}

fn kind_from_event(event: Event) -> EpollEventKind {
    let mut kind = EpollEventKind::empty();
    match event {
        Event::Read => {
            kind.insert(EPOLLIN);
        },
        Event::Write => {
            kind.insert(EPOLLOUT);
        },
        Event::Both => {
            kind.insert(EPOLLIN);
            kind.insert(EPOLLOUT);
        }
    }
    // All events are edge triggered and oneshot
    kind.insert(EPOLLET);
    kind.insert(EPOLLONESHOT);
    kind
}
<commit_msg>Fix build of epoll.rs<commit_after>use std::os::unix::io::RawFd;
use std::slice;
use std::mem;
use std::marker::PhantomData;
use nix::sys::epoll::*;
use nix::Result;

use socket::Socket;
use event::Event;
use notification::Notification;
use registration::Registration;

static EPOLL_EVENT_SIZE: usize = 1024;

pub struct Poller<T> {
    epfd: RawFd,
    registrar: Registrar<T>,
    events: Vec<EpollEvent>
}

impl<T> Poller<T> {
    pub fn new() -> Result<Poller<T>> {
        let epfd = try!(epoll_create());
        Ok(Poller {
            epfd: epfd,
            registrar: Registrar::new(epfd),
            events: Vec::with_capacity(EPOLL_EVENT_SIZE)
        })
    }

    pub fn get_registrar(&self) -> Registrar<T> {
        self.registrar.clone()
    }

    /// Wait for epoll events. Return a list of notifications. Notifications contain user data
    /// registered with epoll_ctl which is extracted from the data member returned from epoll_wait.
    pub fn wait(&mut self, timeout_ms: usize) -> Result<Vec<Notification<T>>> {

        // Create a buffer to read events into
        let dst = unsafe {
            slice::from_raw_parts_mut(self.events.as_mut_ptr(), self.events.capacity())
        };

        let count = try!(epoll_wait(self.epfd, dst, timeout_ms as isize));

        // Set the length of the vector to what was filled in by the call to epoll_wait
        unsafe { self.events.set_len(count); }

        Ok(self.events.iter().map(|e| {
            let registration = unsafe {
               let registration_ptr: *mut Registration<T> = mem::transmute(e.data);
               Box::from_raw(registration_ptr)
            };

            Notification {
                event: event_from_kind(e.events),
                registration: registration
            }
        }).collect())
    }

}

#[derive(Debug)]
pub struct Registrar<T> {
    epfd: RawFd,

    // We use PhantomData here so that this type logically requires being tied to type T.
    // Since the Registrar is tied to the Poller, which stores data of type T, we want to ensure
    // that when we register data, we only register data of type T.
    // See https://doc.rust-lang.org/std/marker/struct.PhantomData.html#unused-type-parameters
    phantom: PhantomData<T>
}

impl<T> Clone for Registrar<T> {
    fn clone(&self) -> Registrar<T> {
        Registrar {
            epfd: self.epfd.clone(),
            phantom: PhantomData
        }
    }
}

impl<T> Registrar<T> {
    fn new(epfd: RawFd) -> Registrar<T> {
        Registrar {
            epfd: epfd,
            phantom: PhantomData
        }
    }

    /// Allocate a Registration containing a Socket and user data of type T on the heap.
    /// Cast the pointer to this object to a u64 so it can be placed in an EpollEvent and passed to
    /// the kernel with a call to `epoll_ctl`. This pointer will be returned from `epoll_wait` when
    /// the socket is ready to be used.
    ///
    /// Passing the relevant user data into the kernel allows decoupling the registration of sockets
    /// from waiting for their readyness. This means that we can register sockets on one thread and
    /// wait for them to be ready on another thread, using the kernel as the method of
    /// communication.
    ///
    /// NOTE: THIS ONLY WORKS ON 64-BIT ARCHITECTURES
    ///
    pub fn register(&self, sock: Socket, event: Event, user_data: T) -> Result<()> {
        let sock_fd = sock.as_raw_fd();
        let registration = Box::new(Registration::new(sock, event.clone(), user_data));

        let registration_ptr: u64 = unsafe {
            mem::transmute(Box::into_raw(registration))
        };

        let info = EpollEvent {
            events: kind_from_event(event),
            data: registration_ptr
        };

        epoll_ctl(self.epfd, EpollOp::EpollCtlAdd, sock_fd, &info)
    }
}

fn event_from_kind(kind: EpollEventKind) -> Event {
    let mut event = Event::Read;
    if kind.contains(EPOLLIN) && kind.contains(EPOLLOUT) {
        event = Event::Both;
    } else if kind.contains(EPOLLOUT) {
        event = Event::Write;
    }
    event
}

fn kind_from_event(event: Event) -> EpollEventKind {
    let mut kind = EpollEventKind::empty();
    match event {
        Event::Read => {
            kind.insert(EPOLLIN);
        },
        Event::Write => {
            kind.insert(EPOLLOUT);
        },
        Event::Both => {
            kind.insert(EPOLLIN);
            kind.insert(EPOLLOUT);
        }
    }
    // All events are edge triggered and oneshot
    kind.insert(EPOLLET);
    kind.insert(EPOLLONESHOT);
    kind
}
<|endoftext|>


<commit_before>mod testdata;
use testdata::{
    newton,
    generate_data,
    NEWTON_ITER,
    SETLEN
};

use std::time::SystemTime;
use std::thread;
use std::thread::JoinHandle;
use std::iter::Map;
use std::slice::Chunks;
use std::sync::Arc;

const THREADS: usize = 4;

fn main() {
    let data = generate_data(SETLEN/10);
    println!("generiere {} testdaten", SETLEN/10);
    let earlier = SystemTime::now();
    let _new_data = map_data(data);
    let dur = match SystemTime::now().duration_since(earlier) {
        Ok(v) => v,
        Err(e) => {
            println!("messfehler: {}", e);
            return;
        }
    };
    println!("duration: {}.{} secs", dur.as_secs(), dur.subsec_nanos());
}

fn map_data(data: Vec<f64>) -> Vec<f64> {
    let chunklen = data.len() / THREADS + 1;
    data.chunks(chunklen)
        .map(|x: Chunks<&[f64]> | -> JoinHandle<Map<&[f64], Fn(&f64) -> f64>>{ //über slices
            //für jeden slice einen thread spawnen, der über den slice iteriert, und newton darauf anwendet.
            thread::spawn(move || x.map(|y| {
                newton(*y, NEWTON_ITER)
            })) //Rückgabewert: ThreadHandle<Map<f64>>
        })
        .map(|handle| handle.join().expect("failed to join"))
        .flat_map(|x| x)
        .collect()
}

/*fn map_data(data: Vec<f64>) -> Vec<f64> {
    let chunklen = data.len() / THREADS + 1;
    let chunks: Chunks<f64> = data.chunks(chunklen);
    chunks.map(|x: &[f64]| x);
    vec!()
}*/<commit_msg>Füge pmap2 hinzu<commit_after>mod testdata;
use testdata::{
    newton,
    generate_data,
    NEWTON_ITER,
    SETLEN
};

use std::time::SystemTime;
use std::thread;
use std::thread::JoinHandle;
use std::iter::Map;
use std::slice::Chunks;
use std::sync::Arc;

const THREADS: usize = 4;

fn main() {
    let mut data = generate_data(SETLEN);
    println!("generiere {} testdaten", SETLEN);
    let earlier = SystemTime::now();
    map_data(&mut data);
    let dur = match SystemTime::now().duration_since(earlier) {
        Ok(v) => v,
        Err(e) => {
            println!("messfehler: {}", e);
            return;
        }
    };
    println!("duration: {}.{} secs", dur.as_secs(), dur.subsec_nanos());
}

fn map_data(data: &mut Vec<f64>) {
    let chunk_size = data.len() / THREADS + 1;
    *data = {
        data.chunks(chunk_size)
            .map(|x| x.to_owned())
            .map(|x| {
                thread::spawn(move || {
                    x.into_iter().map(|x| newton(x, NEWTON_ITER))
                })
            })
            .map(|x| x.join().expect("failed to join"))
            .flat_map(|x| x)
            .collect::<Vec<f64>>()
    }
}<|endoftext|>


<commit_before>// Copyright 2018 Syn Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std;
use std::fmt::{self, Display};
use std::iter::FromIterator;

use proc_macro2::{
    Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree,
};

use buffer::Cursor;

/// The result of a Syn parser.
pub type Result<T> = std::result::Result<T, Error>;

/// Error returned when a Syn parser cannot parse the input tokens.
///
/// Refer to the [module documentation] for details about parsing in Syn.
///
/// [module documentation]: index.html
///
/// *This type is available if Syn is built with the `"parsing"` feature.*
#[derive(Debug)]
pub struct Error {
    span: Span,
    message: String,
}

impl Error {
    pub fn new<T: Display>(span: Span, message: T) -> Self {
        Error {
            span: span,
            message: message.to_string(),
        }
    }

    pub fn span(&self) -> Span {
        self.span
    }

    /// Render the error as an invocation of [`compile_error!`].
    ///
    /// The [`parse_macro_input!`] macro provides a convenient way to invoke
    /// this method correctly in a procedural macro.
    ///
    /// [`compile_error!`]: https://doc.rust-lang.org/std/macro.compile_error.html
    /// [`parse_macro_input!`]: ../macro.parse_macro_input.html
    pub fn into_compile_error(self) -> TokenStream {
        // compile_error!($message)
        TokenStream::from_iter(vec![
            TokenTree::Ident(Ident::new("compile_error", self.span)),
            TokenTree::Punct({
                let mut punct = Punct::new('!', Spacing::Alone);
                punct.set_span(self.span);
                punct
            }),
            TokenTree::Group({
                let mut group = Group::new(Delimiter::Brace, {
                    TokenStream::from_iter(vec![TokenTree::Literal({
                        let mut string = Literal::string(&self.message);
                        string.set_span(self.span);
                        string
                    })])
                });
                group.set_span(self.span);
                group
            }),
        ])
    }
}

pub fn new_at<T: Display>(scope: Span, cursor: Cursor, message: T) -> Error {
    if cursor.eof() {
        Error::new(scope, format!("unexpected end of input, {}", message))
    } else {
        Error::new(cursor.span(), message)
    }
}

impl Display for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str(&self.message)
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
        "parse error"
    }
}

impl From<LexError> for Error {
    fn from(err: LexError) -> Self {
        Error::new(Span::call_site(), format!("{:?}", err))
    }
}
<commit_msg>Document Error::new<commit_after>// Copyright 2018 Syn Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std;
use std::fmt::{self, Display};
use std::iter::FromIterator;

use proc_macro2::{
    Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree,
};

use buffer::Cursor;

/// The result of a Syn parser.
pub type Result<T> = std::result::Result<T, Error>;

/// Error returned when a Syn parser cannot parse the input tokens.
///
/// Refer to the [module documentation] for details about parsing in Syn.
///
/// [module documentation]: index.html
///
/// *This type is available if Syn is built with the `"parsing"` feature.*
#[derive(Debug)]
pub struct Error {
    span: Span,
    message: String,
}

impl Error {
    /// Usually the [`ParseStream::error`] method will be used instead, which
    /// automatically uses the correct span from the current position of the
    /// parse stream.
    ///
    /// Use `Error::new` when the error needs to be triggered on some span other
    /// than where the parse stream is currently positioned.
    ///
    /// [`ParseStream::error`]: struct.ParseBuffer.html#method.error
    ///
    /// # Example
    ///
    /// ```
    /// #[macro_use]
    /// extern crate syn;
    ///
    /// use syn::{Ident, LitStr};
    /// use syn::parse::{Error, ParseStream, Result};
    ///
    /// // Parses input that looks like `name = "string"` where the key must be
    /// // the identifier `name` and the value may be any string literal.
    /// // Returns the string literal.
    /// fn parse_name(input: ParseStream) -> Result<LitStr> {
    ///     let name_token: Ident = input.parse()?;
    ///     if name_token != "name" {
    ///         // Trigger an error not on the current position of the stream,
    ///         // but on the position of the unexpected identifier.
    ///         return Err(Error::new(name_token.span(), "expected `name`"));
    ///     }
    ///     input.parse::<Token![=]>()?;
    ///     let s: LitStr = input.parse()?;
    ///     Ok(s)
    /// }
    /// #
    /// # fn main() {}
    /// ```
    pub fn new<T: Display>(span: Span, message: T) -> Self {
        Error {
            span: span,
            message: message.to_string(),
        }
    }

    pub fn span(&self) -> Span {
        self.span
    }

    /// Render the error as an invocation of [`compile_error!`].
    ///
    /// The [`parse_macro_input!`] macro provides a convenient way to invoke
    /// this method correctly in a procedural macro.
    ///
    /// [`compile_error!`]: https://doc.rust-lang.org/std/macro.compile_error.html
    /// [`parse_macro_input!`]: ../macro.parse_macro_input.html
    pub fn into_compile_error(self) -> TokenStream {
        // compile_error!($message)
        TokenStream::from_iter(vec![
            TokenTree::Ident(Ident::new("compile_error", self.span)),
            TokenTree::Punct({
                let mut punct = Punct::new('!', Spacing::Alone);
                punct.set_span(self.span);
                punct
            }),
            TokenTree::Group({
                let mut group = Group::new(Delimiter::Brace, {
                    TokenStream::from_iter(vec![TokenTree::Literal({
                        let mut string = Literal::string(&self.message);
                        string.set_span(self.span);
                        string
                    })])
                });
                group.set_span(self.span);
                group
            }),
        ])
    }
}

pub fn new_at<T: Display>(scope: Span, cursor: Cursor, message: T) -> Error {
    if cursor.eof() {
        Error::new(scope, format!("unexpected end of input, {}", message))
    } else {
        Error::new(cursor.span(), message)
    }
}

impl Display for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str(&self.message)
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
        "parse error"
    }
}

impl From<LexError> for Error {
    fn from(err: LexError) -> Self {
        Error::new(Span::call_site(), format!("{:?}", err))
    }
}
<|endoftext|>


<commit_before>use std::error;
use std::fmt;
use std::io;
use std::io::Write;
use std::process;

#[derive(Debug)]
pub struct Error {
    code: RoteError,
    description: String,
}

#[derive(Debug)]
pub enum RoteError {
    FileNotReadable = 1,
    Runtime,
    TaskNotFound,
    Unknown,
}

impl Error {
    /// Creates a new error with a given code and description.
    pub fn new(code: RoteError, description: &str) -> Error {
        Error {
            code: code,
            description: String::from(description),
        }
    }

    /// Creates a new error with a given description.
    pub fn new_desc(description: &str) -> Error {
        Self::new(RoteError::Unknown, description)
    }

    /// Prints the error and terminates the program, exiting with the given error code.
    pub fn die(self) {
        match writeln!(&mut io::stderr(), "error: {}.", self) {
            Ok(_) => {}
            Err(e) => panic!("Unable to write to stderr: {}", e),
        }

        process::exit(self.code as i32);
    }
}

/// Implement the standard error methods.
impl error::Error for Error {
    /// Gets the error description.
    fn description(&self) -> &str {
        &self.description
    }

    /// Gets a previous error object, if any.
    fn cause(&self) -> Option<&error::Error> {
        None
    }
}

/// Implement display formatting for the error type.
impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.description)
    }
}
<commit_msg>Error reformation<commit_after>use std::error;
use std::fmt;
use std::io::Write;
use std::process;

#[macro_export]
macro_rules! throw {
    ($e:expr) => (return Err($e))
}

/// Syntax sugar for pattern matching against multiple results.
#[macro_export]
macro_rules! try {
    {
        $body:expr;
        $(catch $pattern:pat => $catch:block)*
    } => {
        match (|| {
            $body;
            Ok(())
        })() {
            Ok(val) => val,
            Err(err) => match err {
                $($pattern => $catch),*
                _ => return Err(err)
            }
        }
    };

    ($result:expr) => {
        match $result {
            Ok(val) => val,
            Err(err) => return Err(err),
        }
    };
}

#[derive(Debug)]
pub enum Error {
    Chained(&'static error::Error),
    FileNotReadable(String),
    OptionMissing(String),
    RuntimeError(String),
    TaskNotFound(String),
}

impl Error {
    pub fn description(&self) -> &str {
        match *self {
            Error::Chained(ref err) => err.description(),
            Error::FileNotReadable(_) => "file could not be read",
            Error::OptionMissing(ref m) => m,
            Error::RuntimeError(ref message) => &message,
            Error::TaskNotFound(_) => "task not found",
        }
    }

    /// Gets the error code.
    pub fn code(&self) -> i32 {
        match *self {
            Error::Chained(_) => 1,
            Error::OptionMissing(_) => 4,
            Error::FileNotReadable(_) => 66,
            Error::RuntimeError(_) => 3,
            Error::TaskNotFound(_) => 2,
        }
    }

    /// Prints the error and terminates the program, exiting with the given error code.
    pub fn die(&self) {
        error!("{}", self);
        process::exit(self.code());
    }
}

/// Implements display formatting for the error type.
impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::FileNotReadable(ref file) => write!(f, "the file \"{}\" could not be read", &file),
            Error::TaskNotFound(ref name) => write!(f, "no task or rule found for \"{}\"", &name),
            _ => write!(f, "{}", self.description())
        }
    }
}

/// And finally, Rote errors are standard errors as well.
impl error::Error for Error {
    fn description(&self) -> &str {
        (*self).description()
    }

    /// Gets a previous error object, if any.
    fn cause(&self) -> Option<&error::Error> {
        match *self {
            Error::Chained(cause) => Some(cause),
            _ => None,
        }
    }
}

/// Implement casting from other error types.
impl From<&'static error::Error> for Error {
    fn from(err: &'static error::Error) -> Error {
        Error::Chained(err)
    }
}
<|endoftext|>


<commit_before>// This file is part of tmx
// Copyright 2017 Sébastien Watteau
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::error;
use std::fmt;
use std::io;

#[derive(Debug)]
pub enum Error {
    BadXml,
    BadAxis(String),
    BadIndex(String),
    BadOrientation(String),
    BadPropertyType(String),
    BadRenderOrder(String),
    BadDrawOrder(String),
    BadProbability(f32),
    UnknownAttribute(String),
    InvalidColor(String),
    InvalidNumber(String),
    InvalidPoint(String),
    InvalidTerrain(String),
    Io(io::Error),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::BadXml => write!(f, "Invalid XML input"),
            Error::BadAxis(ref value) => {
                write!(f,
                       "Illegal value `{}` for the `staggeraxis` attribute",
                       value)
            }
            Error::BadIndex(ref value) => {
                write!(f,
                       "Illegal value `{}` for the `staggerindex` attribute",
                       value)
            }
            Error::BadOrientation(ref value) => {
                write!(f,
                       "Illegal value `{}` for the `orientation` attribute",
                       value)
            }
            Error::BadPropertyType(ref value) => {
                write!(f,
                       "Illegal value `{}` for the `type` attribute",
                       value)
            }
            Error::BadRenderOrder(ref value) => {
                write!(f,
                       "Illegal value `{}` for the `renderorder` attribute",
                       value)
            }
            Error::BadDrawOrder(ref value) => {
                write!(f,
                       "Illegal value `{}` for the `draworder` attribute",
                       value)
            }
            Error::BadProbability(ref value) => {
                write!(f,
                       "Illegal value `{}` for the `probability` attribute",
                       value)
            }
            Error::UnknownAttribute(ref attr) => write!(f, "Unknown attribute: `{}`", attr),
            Error::InvalidColor(ref color) => write!(f, "Invalid color: `{}`", color),
            Error::InvalidNumber(ref num) => write!(f, "Invalid number: `{}`", num),
            Error::InvalidPoint(ref point) => write!(f, "Invalid point: `{}`", point),
            Error::InvalidTerrain(ref terrain) => write!(f, "Invalid terrain: `{}`", terrain),
            Error::Io(ref err) => write!(f, "I/O error: {}", err),
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::BadXml => "Invalid XML input",
            Error::BadAxis(..) => "Bad axis value",
            Error::BadIndex(..) => "Bad index value",
            Error::BadOrientation(..) => "Bad orientation value",
            Error::BadPropertyType(..) => "Bad property type value",
            Error::BadRenderOrder(..) => "Bad renderorder value",
            Error::BadDrawOrder(..) => "Bad draworder value",
            Error::BadProbability(..) => "Bad probability value",
            Error::UnknownAttribute(..) => "Unknown attribute",
            Error::InvalidColor(..) => "Invalid color",
            Error::InvalidNumber(..) => "Invalid number",
            Error::InvalidPoint(..) => "Invalid point",
            Error::InvalidTerrain(..) => "Invalid terrain",
            Error::Io(ref err) => err.description(),
        }
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::Io(err)
    }
}
<commit_msg>Removed  impl of  Error::description (deprecated)<commit_after>// This file is part of tmx
// Copyright 2017 Sébastien Watteau
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::error;
use std::fmt;
use std::io;

#[derive(Debug)]
pub enum Error {
    BadXml,
    BadAxis(String),
    BadIndex(String),
    BadOrientation(String),
    BadPropertyType(String),
    BadRenderOrder(String),
    BadDrawOrder(String),
    BadProbability(f32),
    UnknownAttribute(String),
    InvalidColor(String),
    InvalidNumber(String),
    InvalidPoint(String),
    InvalidTerrain(String),
    Io(io::Error),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::BadXml => write!(f, "Invalid XML input"),
            Error::BadAxis(ref value) => {
                write!(f,
                       "Illegal value `{}` for the `staggeraxis` attribute",
                       value)
            }
            Error::BadIndex(ref value) => {
                write!(f,
                       "Illegal value `{}` for the `staggerindex` attribute",
                       value)
            }
            Error::BadOrientation(ref value) => {
                write!(f,
                       "Illegal value `{}` for the `orientation` attribute",
                       value)
            }
            Error::BadPropertyType(ref value) => {
                write!(f,
                       "Illegal value `{}` for the `type` attribute",
                       value)
            }
            Error::BadRenderOrder(ref value) => {
                write!(f,
                       "Illegal value `{}` for the `renderorder` attribute",
                       value)
            }
            Error::BadDrawOrder(ref value) => {
                write!(f,
                       "Illegal value `{}` for the `draworder` attribute",
                       value)
            }
            Error::BadProbability(ref value) => {
                write!(f,
                       "Illegal value `{}` for the `probability` attribute",
                       value)
            }
            Error::UnknownAttribute(ref attr) => write!(f, "Unknown attribute: `{}`", attr),
            Error::InvalidColor(ref color) => write!(f, "Invalid color: `{}`", color),
            Error::InvalidNumber(ref num) => write!(f, "Invalid number: `{}`", num),
            Error::InvalidPoint(ref point) => write!(f, "Invalid point: `{}`", point),
            Error::InvalidTerrain(ref terrain) => write!(f, "Invalid terrain: `{}`", terrain),
            Error::Io(ref err) => write!(f, "I/O error: {}", err),
        }
    }
}

impl error::Error for Error {}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::Io(err)
    }
}
<|endoftext|>