<commit_before>#![stable(feature = "futures_api", since = "1.36.0")]

use crate::fmt;
use crate::marker::{PhantomData, Unpin};

/// A `RawWaker` allows the implementor of a task executor to create a [`Waker`]
/// which provides customized wakeup behavior.
///
/// [vtable]: https://en.wikipedia.org/wiki/Virtual_method_table
///
/// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable] that
/// customizes the behavior of the `RawWaker`.
///
/// [`Waker`]: struct.Waker.html
#[derive(PartialEq, Debug)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct RawWaker {
    /// A data pointer, which can be used to store arbitrary data as required
    /// by the executor. This could be e.g. a type-erased pointer to an `Arc`
    /// that is associated with the task.
    /// The value of this field gets passed to all functions that are part of
    /// the vtable as the first parameter.
    data: *const (),
    /// Virtual function pointer table that customizes the behavior of this waker.
    vtable: &'static RawWakerVTable,
}

impl RawWaker {
    /// Creates a new `RawWaker` from the provided `data` pointer and `vtable`.
    ///
    /// The `data` pointer can be used to store arbitrary data as required
    /// by the executor. This could be e.g. a type-erased pointer to an `Arc`
    /// that is associated with the task.
    /// The value of this poiner will get passed to all functions that are part
    /// of the `vtable` as the first parameter.
    ///
    /// The `vtable` customizes the behavior of a `Waker` which gets created
    /// from a `RawWaker`. For each operation on the `Waker`, the associated
    /// function in the `vtable` of the underlying `RawWaker` will be called.
    #[rustc_promotable]
    #[stable(feature = "futures_api", since = "1.36.0")]
    pub const fn new(data: *const (), vtable: &'static RawWakerVTable) -> RawWaker {
        RawWaker {
            data,
            vtable,
        }
    }
}

/// A virtual function pointer table (vtable) that specifies the behavior
/// of a [`RawWaker`].
///
/// The pointer passed to all functions inside the vtable is the `data` pointer
/// from the enclosing [`RawWaker`] object.
///
/// The functions inside this struct are only intended be called on the `data`
/// pointer of a properly constructed [`RawWaker`] object from inside the
/// [`RawWaker`] implementation. Calling one of the contained functions using
/// any other `data` pointer will cause undefined behavior.
///
/// [`RawWaker`]: struct.RawWaker.html
#[stable(feature = "futures_api", since = "1.36.0")]
#[derive(PartialEq, Copy, Clone, Debug)]
pub struct RawWakerVTable {
    /// This function will be called when the [`RawWaker`] gets cloned, e.g. when
    /// the [`Waker`] in which the [`RawWaker`] is stored gets cloned.
    ///
    /// The implementation of this function must retain all resources that are
    /// required for this additional instance of a [`RawWaker`] and associated
    /// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup
    /// of the same task that would have been awoken by the original [`RawWaker`].
    ///
    /// [`Waker`]: struct.Waker.html
    /// [`RawWaker`]: struct.RawWaker.html
    clone: unsafe fn(*const ()) -> RawWaker,

    /// This function will be called when `wake` is called on the [`Waker`].
    /// It must wake up the task associated with this [`RawWaker`].
    ///
    /// The implementation of this function must make sure to release any
    /// resources that are associated with this instance of a [`RawWaker`] and
    /// associated task.
    ///
    /// [`Waker`]: struct.Waker.html
    /// [`RawWaker`]: struct.RawWaker.html
    wake: unsafe fn(*const ()),

    /// This function will be called when `wake_by_ref` is called on the [`Waker`].
    /// It must wake up the task associated with this [`RawWaker`].
    ///
    /// This function is similar to `wake`, but must not consume the provided data
    /// pointer.
    ///
    /// [`Waker`]: struct.Waker.html
    /// [`RawWaker`]: struct.RawWaker.html
    wake_by_ref: unsafe fn(*const ()),

    /// This function gets called when a [`RawWaker`] gets dropped.
    ///
    /// The implementation of this function must make sure to release any
    /// resources that are associated with this instance of a [`RawWaker`] and
    /// associated task.
    ///
    /// [`RawWaker`]: struct.RawWaker.html
    drop: unsafe fn(*const ()),
}

impl RawWakerVTable {
    /// Creates a new `RawWakerVTable` from the provided `clone`, `wake`,
    /// `wake_by_ref`, and `drop` functions.
    ///
    /// # `clone`
    ///
    /// This function will be called when the [`RawWaker`] gets cloned, e.g. when
    /// the [`Waker`] in which the [`RawWaker`] is stored gets cloned.
    ///
    /// The implementation of this function must retain all resources that are
    /// required for this additional instance of a [`RawWaker`] and associated
    /// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup
    /// of the same task that would have been awoken by the original [`RawWaker`].
    ///
    /// # `wake`
    ///
    /// This function will be called when `wake` is called on the [`Waker`].
    /// It must wake up the task associated with this [`RawWaker`].
    ///
    /// The implementation of this function must make sure to release any
    /// resources that are associated with this instance of a [`RawWaker`] and
    /// associated task.
    ///
    /// # `wake_by_ref`
    ///
    /// This function will be called when `wake_by_ref` is called on the [`Waker`].
    /// It must wake up the task associated with this [`RawWaker`].
    ///
    /// This function is similar to `wake`, but must not consume the provided data
    /// pointer.
    ///
    /// # `drop`
    ///
    /// This function gets called when a [`RawWaker`] gets dropped.
    ///
    /// The implementation of this function must make sure to release any
    /// resources that are associated with this instance of a [`RawWaker`] and
    /// associated task.
    ///
    /// [`Waker`]: struct.Waker.html
    /// [`RawWaker`]: struct.RawWaker.html
    #[rustc_promotable]
    #[stable(feature = "futures_api", since = "1.36.0")]
    // `rustc_allow_const_fn_ptr` is a hack that should not be used anywhere else
    // without first consulting with T-Lang.
    //
    // FIXME: remove whenever we have a stable way to accept fn pointers from const fn
    // (see https://github.com/rust-rfcs/const-eval/issues/19#issuecomment-472799062)
    #[rustc_allow_const_fn_ptr]
    pub const fn new(
        clone: unsafe fn(*const ()) -> RawWaker,
        wake: unsafe fn(*const ()),
        wake_by_ref: unsafe fn(*const ()),
        drop: unsafe fn(*const ()),
    ) -> Self {
        Self {
            clone,
            wake,
            wake_by_ref,
            drop,
        }
    }
}

/// The `Context` of an asynchronous task.
///
/// Currently, `Context` only serves to provide access to a `&Waker`
/// which can be used to wake the current task.
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct Context<'a> {
    waker: &'a Waker,
    // Ensure we future-proof against variance changes by forcing
    // the lifetime to be invariant (argument-position lifetimes
    // are contravariant while return-position lifetimes are
    // covariant).
    _marker: PhantomData<fn(&'a ()) -> &'a ()>,
}

impl<'a> Context<'a> {
    /// Create a new `Context` from a `&Waker`.
    #[stable(feature = "futures_api", since = "1.36.0")]
    #[inline]
    pub fn from_waker(waker: &'a Waker) -> Self {
        Context {
            waker,
            _marker: PhantomData,
        }
    }

    /// Returns a reference to the `Waker` for the current task.
    #[stable(feature = "futures_api", since = "1.36.0")]
    #[inline]
    pub fn waker(&self) -> &'a Waker {
        &self.waker
    }
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl fmt::Debug for Context<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Context")
            .field("waker", &self.waker)
            .finish()
    }
}

/// A `Waker` is a handle for waking up a task by notifying its executor that it
/// is ready to be run.
///
/// This handle encapsulates a [`RawWaker`] instance, which defines the
/// executor-specific wakeup behavior.
///
/// Implements [`Clone`], [`Send`], and [`Sync`].
///
/// [`RawWaker`]: struct.RawWaker.html
#[repr(transparent)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct Waker {
    waker: RawWaker,
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl Unpin for Waker {}
#[stable(feature = "futures_api", since = "1.36.0")]
unsafe impl Send for Waker {}
#[stable(feature = "futures_api", since = "1.36.0")]
unsafe impl Sync for Waker {}

impl Waker {
    /// Wake up the task associated with this `Waker`.
    #[inline]
    #[stable(feature = "futures_api", since = "1.36.0")]
    pub fn wake(self) {
        // The actual wakeup call is delegated through a virtual function call
        // to the implementation which is defined by the executor.
        let wake = self.waker.vtable.wake;
        let data = self.waker.data;

        // Don't call `drop` -- the waker will be consumed by `wake`.
        crate::mem::forget(self);

        // SAFETY: This is safe because `Waker::from_raw` is the only way
        // to initialize `wake` and `data` requiring the user to acknowledge
        // that the contract of `RawWaker` is upheld.
        unsafe { (wake)(data) };
    }

    /// Wake up the task associated with this `Waker` without consuming the `Waker`.
    ///
    /// This is similar to `wake`, but may be slightly less efficient in the case
    /// where an owned `Waker` is available. This method should be preferred to
    /// calling `waker.clone().wake()`.
    #[inline]
    #[stable(feature = "futures_api", since = "1.36.0")]
    pub fn wake_by_ref(&self) {
        // The actual wakeup call is delegated through a virtual function call
        // to the implementation which is defined by the executor.

        // SAFETY: see `wake`
        unsafe { (self.waker.vtable.wake_by_ref)(self.waker.data) }
    }

    /// Returns `true` if this `Waker` and another `Waker` have awoken the same task.
    ///
    /// This function works on a best-effort basis, and may return false even
    /// when the `Waker`s would awaken the same task. However, if this function
    /// returns `true`, it is guaranteed that the `Waker`s will awaken the same task.
    ///
    /// This function is primarily used for optimization purposes.
    #[inline]
    #[stable(feature = "futures_api", since = "1.36.0")]
    pub fn will_wake(&self, other: &Waker) -> bool {
        self.waker == other.waker
    }

    /// Creates a new `Waker` from [`RawWaker`].
    ///
    /// The behavior of the returned `Waker` is undefined if the contract defined
    /// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
    /// Therefore this method is unsafe.
    ///
    /// [`RawWaker`]: struct.RawWaker.html
    /// [`RawWakerVTable`]: struct.RawWakerVTable.html
    #[inline]
    #[stable(feature = "futures_api", since = "1.36.0")]
    pub unsafe fn from_raw(waker: RawWaker) -> Waker {
        Waker {
            waker,
        }
    }
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl Clone for Waker {
    #[inline]
    fn clone(&self) -> Self {
        Waker {
            // SAFETY: This is safe because `Waker::from_raw` is the only way
            // to initialize `clone` and `data` requiring the user to acknowledge
            // that the contract of [`RawWaker`] is upheld.
            waker: unsafe { (self.waker.vtable.clone)(self.waker.data) },
        }
    }
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl Drop for Waker {
    #[inline]
    fn drop(&mut self) {
        // SAFETY: This is safe because `Waker::from_raw` is the only way
        // to initialize `drop` and `data` requiring the user to acknowledge
        // that the contract of `RawWaker` is upheld.
        unsafe { (self.waker.vtable.drop)(self.waker.data) }
    }
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl fmt::Debug for Waker {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let vtable_ptr = self.waker.vtable as *const RawWakerVTable;
        f.debug_struct("Waker")
            .field("data", &self.waker.data)
            .field("vtable", &vtable_ptr)
            .finish()
    }
}
<commit_msg>Fix typo in RawWaker::new documentation<commit_after>#![stable(feature = "futures_api", since = "1.36.0")]

use crate::fmt;
use crate::marker::{PhantomData, Unpin};

/// A `RawWaker` allows the implementor of a task executor to create a [`Waker`]
/// which provides customized wakeup behavior.
///
/// [vtable]: https://en.wikipedia.org/wiki/Virtual_method_table
///
/// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable] that
/// customizes the behavior of the `RawWaker`.
///
/// [`Waker`]: struct.Waker.html
#[derive(PartialEq, Debug)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct RawWaker {
    /// A data pointer, which can be used to store arbitrary data as required
    /// by the executor. This could be e.g. a type-erased pointer to an `Arc`
    /// that is associated with the task.
    /// The value of this field gets passed to all functions that are part of
    /// the vtable as the first parameter.
    data: *const (),
    /// Virtual function pointer table that customizes the behavior of this waker.
    vtable: &'static RawWakerVTable,
}

impl RawWaker {
    /// Creates a new `RawWaker` from the provided `data` pointer and `vtable`.
    ///
    /// The `data` pointer can be used to store arbitrary data as required
    /// by the executor. This could be e.g. a type-erased pointer to an `Arc`
    /// that is associated with the task.
    /// The value of this pointer will get passed to all functions that are part
    /// of the `vtable` as the first parameter.
    ///
    /// The `vtable` customizes the behavior of a `Waker` which gets created
    /// from a `RawWaker`. For each operation on the `Waker`, the associated
    /// function in the `vtable` of the underlying `RawWaker` will be called.
    #[rustc_promotable]
    #[stable(feature = "futures_api", since = "1.36.0")]
    pub const fn new(data: *const (), vtable: &'static RawWakerVTable) -> RawWaker {
        RawWaker {
            data,
            vtable,
        }
    }
}

/// A virtual function pointer table (vtable) that specifies the behavior
/// of a [`RawWaker`].
///
/// The pointer passed to all functions inside the vtable is the `data` pointer
/// from the enclosing [`RawWaker`] object.
///
/// The functions inside this struct are only intended be called on the `data`
/// pointer of a properly constructed [`RawWaker`] object from inside the
/// [`RawWaker`] implementation. Calling one of the contained functions using
/// any other `data` pointer will cause undefined behavior.
///
/// [`RawWaker`]: struct.RawWaker.html
#[stable(feature = "futures_api", since = "1.36.0")]
#[derive(PartialEq, Copy, Clone, Debug)]
pub struct RawWakerVTable {
    /// This function will be called when the [`RawWaker`] gets cloned, e.g. when
    /// the [`Waker`] in which the [`RawWaker`] is stored gets cloned.
    ///
    /// The implementation of this function must retain all resources that are
    /// required for this additional instance of a [`RawWaker`] and associated
    /// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup
    /// of the same task that would have been awoken by the original [`RawWaker`].
    ///
    /// [`Waker`]: struct.Waker.html
    /// [`RawWaker`]: struct.RawWaker.html
    clone: unsafe fn(*const ()) -> RawWaker,

    /// This function will be called when `wake` is called on the [`Waker`].
    /// It must wake up the task associated with this [`RawWaker`].
    ///
    /// The implementation of this function must make sure to release any
    /// resources that are associated with this instance of a [`RawWaker`] and
    /// associated task.
    ///
    /// [`Waker`]: struct.Waker.html
    /// [`RawWaker`]: struct.RawWaker.html
    wake: unsafe fn(*const ()),

    /// This function will be called when `wake_by_ref` is called on the [`Waker`].
    /// It must wake up the task associated with this [`RawWaker`].
    ///
    /// This function is similar to `wake`, but must not consume the provided data
    /// pointer.
    ///
    /// [`Waker`]: struct.Waker.html
    /// [`RawWaker`]: struct.RawWaker.html
    wake_by_ref: unsafe fn(*const ()),

    /// This function gets called when a [`RawWaker`] gets dropped.
    ///
    /// The implementation of this function must make sure to release any
    /// resources that are associated with this instance of a [`RawWaker`] and
    /// associated task.
    ///
    /// [`RawWaker`]: struct.RawWaker.html
    drop: unsafe fn(*const ()),
}

impl RawWakerVTable {
    /// Creates a new `RawWakerVTable` from the provided `clone`, `wake`,
    /// `wake_by_ref`, and `drop` functions.
    ///
    /// # `clone`
    ///
    /// This function will be called when the [`RawWaker`] gets cloned, e.g. when
    /// the [`Waker`] in which the [`RawWaker`] is stored gets cloned.
    ///
    /// The implementation of this function must retain all resources that are
    /// required for this additional instance of a [`RawWaker`] and associated
    /// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup
    /// of the same task that would have been awoken by the original [`RawWaker`].
    ///
    /// # `wake`
    ///
    /// This function will be called when `wake` is called on the [`Waker`].
    /// It must wake up the task associated with this [`RawWaker`].
    ///
    /// The implementation of this function must make sure to release any
    /// resources that are associated with this instance of a [`RawWaker`] and
    /// associated task.
    ///
    /// # `wake_by_ref`
    ///
    /// This function will be called when `wake_by_ref` is called on the [`Waker`].
    /// It must wake up the task associated with this [`RawWaker`].
    ///
    /// This function is similar to `wake`, but must not consume the provided data
    /// pointer.
    ///
    /// # `drop`
    ///
    /// This function gets called when a [`RawWaker`] gets dropped.
    ///
    /// The implementation of this function must make sure to release any
    /// resources that are associated with this instance of a [`RawWaker`] and
    /// associated task.
    ///
    /// [`Waker`]: struct.Waker.html
    /// [`RawWaker`]: struct.RawWaker.html
    #[rustc_promotable]
    #[stable(feature = "futures_api", since = "1.36.0")]
    // `rustc_allow_const_fn_ptr` is a hack that should not be used anywhere else
    // without first consulting with T-Lang.
    //
    // FIXME: remove whenever we have a stable way to accept fn pointers from const fn
    // (see https://github.com/rust-rfcs/const-eval/issues/19#issuecomment-472799062)
    #[rustc_allow_const_fn_ptr]
    pub const fn new(
        clone: unsafe fn(*const ()) -> RawWaker,
        wake: unsafe fn(*const ()),
        wake_by_ref: unsafe fn(*const ()),
        drop: unsafe fn(*const ()),
    ) -> Self {
        Self {
            clone,
            wake,
            wake_by_ref,
            drop,
        }
    }
}

/// The `Context` of an asynchronous task.
///
/// Currently, `Context` only serves to provide access to a `&Waker`
/// which can be used to wake the current task.
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct Context<'a> {
    waker: &'a Waker,
    // Ensure we future-proof against variance changes by forcing
    // the lifetime to be invariant (argument-position lifetimes
    // are contravariant while return-position lifetimes are
    // covariant).
    _marker: PhantomData<fn(&'a ()) -> &'a ()>,
}

impl<'a> Context<'a> {
    /// Create a new `Context` from a `&Waker`.
    #[stable(feature = "futures_api", since = "1.36.0")]
    #[inline]
    pub fn from_waker(waker: &'a Waker) -> Self {
        Context {
            waker,
            _marker: PhantomData,
        }
    }

    /// Returns a reference to the `Waker` for the current task.
    #[stable(feature = "futures_api", since = "1.36.0")]
    #[inline]
    pub fn waker(&self) -> &'a Waker {
        &self.waker
    }
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl fmt::Debug for Context<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Context")
            .field("waker", &self.waker)
            .finish()
    }
}

/// A `Waker` is a handle for waking up a task by notifying its executor that it
/// is ready to be run.
///
/// This handle encapsulates a [`RawWaker`] instance, which defines the
/// executor-specific wakeup behavior.
///
/// Implements [`Clone`], [`Send`], and [`Sync`].
///
/// [`RawWaker`]: struct.RawWaker.html
#[repr(transparent)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct Waker {
    waker: RawWaker,
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl Unpin for Waker {}
#[stable(feature = "futures_api", since = "1.36.0")]
unsafe impl Send for Waker {}
#[stable(feature = "futures_api", since = "1.36.0")]
unsafe impl Sync for Waker {}

impl Waker {
    /// Wake up the task associated with this `Waker`.
    #[inline]
    #[stable(feature = "futures_api", since = "1.36.0")]
    pub fn wake(self) {
        // The actual wakeup call is delegated through a virtual function call
        // to the implementation which is defined by the executor.
        let wake = self.waker.vtable.wake;
        let data = self.waker.data;

        // Don't call `drop` -- the waker will be consumed by `wake`.
        crate::mem::forget(self);

        // SAFETY: This is safe because `Waker::from_raw` is the only way
        // to initialize `wake` and `data` requiring the user to acknowledge
        // that the contract of `RawWaker` is upheld.
        unsafe { (wake)(data) };
    }

    /// Wake up the task associated with this `Waker` without consuming the `Waker`.
    ///
    /// This is similar to `wake`, but may be slightly less efficient in the case
    /// where an owned `Waker` is available. This method should be preferred to
    /// calling `waker.clone().wake()`.
    #[inline]
    #[stable(feature = "futures_api", since = "1.36.0")]
    pub fn wake_by_ref(&self) {
        // The actual wakeup call is delegated through a virtual function call
        // to the implementation which is defined by the executor.

        // SAFETY: see `wake`
        unsafe { (self.waker.vtable.wake_by_ref)(self.waker.data) }
    }

    /// Returns `true` if this `Waker` and another `Waker` have awoken the same task.
    ///
    /// This function works on a best-effort basis, and may return false even
    /// when the `Waker`s would awaken the same task. However, if this function
    /// returns `true`, it is guaranteed that the `Waker`s will awaken the same task.
    ///
    /// This function is primarily used for optimization purposes.
    #[inline]
    #[stable(feature = "futures_api", since = "1.36.0")]
    pub fn will_wake(&self, other: &Waker) -> bool {
        self.waker == other.waker
    }

    /// Creates a new `Waker` from [`RawWaker`].
    ///
    /// The behavior of the returned `Waker` is undefined if the contract defined
    /// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
    /// Therefore this method is unsafe.
    ///
    /// [`RawWaker`]: struct.RawWaker.html
    /// [`RawWakerVTable`]: struct.RawWakerVTable.html
    #[inline]
    #[stable(feature = "futures_api", since = "1.36.0")]
    pub unsafe fn from_raw(waker: RawWaker) -> Waker {
        Waker {
            waker,
        }
    }
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl Clone for Waker {
    #[inline]
    fn clone(&self) -> Self {
        Waker {
            // SAFETY: This is safe because `Waker::from_raw` is the only way
            // to initialize `clone` and `data` requiring the user to acknowledge
            // that the contract of [`RawWaker`] is upheld.
            waker: unsafe { (self.waker.vtable.clone)(self.waker.data) },
        }
    }
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl Drop for Waker {
    #[inline]
    fn drop(&mut self) {
        // SAFETY: This is safe because `Waker::from_raw` is the only way
        // to initialize `drop` and `data` requiring the user to acknowledge
        // that the contract of `RawWaker` is upheld.
        unsafe { (self.waker.vtable.drop)(self.waker.data) }
    }
}

#[stable(feature = "futures_api", since = "1.36.0")]
impl fmt::Debug for Waker {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let vtable_ptr = self.waker.vtable as *const RawWakerVTable;
        f.debug_struct("Waker")
            .field("data", &self.waker.data)
            .field("vtable", &vtable_ptr)
            .finish()
    }
}
<|endoftext|>


<commit_before>// See LICENSE file for copyright and license details.

use std::str::Words;
use std::io::{
  BufferedReader,
  File
};
use gl::types::GLfloat;
use cgmath::vector::{
  Vec3,
  Vec2,
};

struct Face {
  vertex: [int, ..3],
  texture: [int, ..3],
  normal: [int, ..3],
}

pub struct Model {
  coords: ~[Vec3<GLfloat>],
  normals: ~[Vec3<GLfloat>],
  texture_coords: ~[Vec2<GLfloat>],
  faces: ~[Face],
}

// TODO: unwrap() -> ...
impl Model {
  pub fn new(filename: &str) -> Model {
    let mut obj = Model {
      coords: ~[],
      normals: ~[],
      texture_coords: ~[],
      faces: ~[],
    };
    obj.read(filename);
    obj
  }

  fn read_v_or_vn(words: &mut Words) -> Vec3<GLfloat> {
    Vec3 {
      x: from_str(words.next().unwrap()).unwrap(),
      y: from_str(words.next().unwrap()).unwrap(),
      z: from_str(words.next().unwrap()).unwrap(),
    }
  }

  fn read_vt(words: &mut Words) -> Vec2<GLfloat> {
    // TODO: y = 1.0 - y; // flip vertically
    Vec2 {
      x: from_str(words.next().unwrap()).unwrap(),
      y: from_str(words.next().unwrap()).unwrap(),
    }
  }

  fn read_f(words: &mut Words) -> Face {
    let mut face = Face {
      vertex: [0, 0, 0],
      texture: [0, 0, 0],
      normal: [0, 0, 0],
    };
    let mut i = 0;
    for group in *words {
      let mut w = group.split('/');
      face.vertex[i] = from_str(w.next().unwrap()).unwrap();
      face.texture[i] = from_str(w.next().unwrap()).unwrap();
      face.normal[i] = from_str(w.next().unwrap()).unwrap();
      i += 1;
    }
    face
  }

  fn read(&mut self, filename: &str) {
    let path = Path::new(filename);
    let mut file = BufferedReader::new(File::open(&path));
    for line in file.lines() {
      let mut words = line.words(); // TODO: Remove mut
      fn is_correct_tag(tag: &str) -> bool {
        tag.len() != 0 && tag[0] != ('#' as u8)
      }
      let tag = match words.next() {
        Some(w) if is_correct_tag(w) => w,
        _ => "", // TODO: ???
      };
      match tag {
        &"v" => self.coords.push(Model::read_v_or_vn(&mut words)),
        &"vn" => self.normals.push(Model::read_v_or_vn(&mut words)),
        &"vt" => self.texture_coords.push(Model::read_vt(&mut words)),
        &"f" => self.faces.push(Model::read_f(&mut words)),
        _ => print!("."),
      }
    }
  }

  pub fn build(&self) -> ~[Vec3<GLfloat>]{
    let mut mesh = ~[];
    for face in self.faces.iter() {
      for i in range(0, 3) {
        let vertex_id = face.vertex[i] - 1;
        // let texture_coord_id = face.texture[i] - 1; // TODO
        mesh.push(self.coords[vertex_id]);
      }
    }
    mesh
  }
}

// vim: set tabstop=2 shiftwidth=2 softtabstop=2 expandtab:
<commit_msg>obj.rs: Rewritten read() method<commit_after>// See LICENSE file for copyright and license details.

use std::str::Words;
use std::io::{
  BufferedReader,
  File
};
use gl::types::GLfloat;
use cgmath::vector::{
  Vec3,
  Vec2,
};

struct Face {
  vertex: [int, ..3],
  texture: [int, ..3],
  normal: [int, ..3],
}

pub struct Model {
  coords: ~[Vec3<GLfloat>],
  normals: ~[Vec3<GLfloat>],
  texture_coords: ~[Vec2<GLfloat>],
  faces: ~[Face],
}

// TODO: unwrap() -> ...
impl Model {
  pub fn new(filename: &str) -> Model {
    let mut obj = Model {
      coords: ~[],
      normals: ~[],
      texture_coords: ~[],
      faces: ~[],
    };
    obj.read(filename);
    obj
  }

  fn read_v_or_vn(words: &mut Words) -> Vec3<GLfloat> {
    Vec3 {
      x: from_str(words.next().unwrap()).unwrap(),
      y: from_str(words.next().unwrap()).unwrap(),
      z: from_str(words.next().unwrap()).unwrap(),
    }
  }

  fn read_vt(words: &mut Words) -> Vec2<GLfloat> {
    // TODO: y = 1.0 - y; // flip vertically
    Vec2 {
      x: from_str(words.next().unwrap()).unwrap(),
      y: from_str(words.next().unwrap()).unwrap(),
    }
  }

  fn read_f(words: &mut Words) -> Face {
    let mut face = Face {
      vertex: [0, 0, 0],
      texture: [0, 0, 0],
      normal: [0, 0, 0],
    };
    let mut i = 0;
    for group in *words {
      let mut w = group.split('/');
      face.vertex[i] = from_str(w.next().unwrap()).unwrap();
      face.texture[i] = from_str(w.next().unwrap()).unwrap();
      face.normal[i] = from_str(w.next().unwrap()).unwrap();
      i += 1;
    }
    face
  }

  fn read_line(&mut self, line: &str) {
    let mut words = line.words();
    fn is_correct_tag(tag: &str) -> bool {
      tag.len() != 0 && tag[0] != ('#' as u8)
    }
    match words.next() {
      Some(tag) if is_correct_tag(tag) => {
        let w = &mut words;
        match tag {
          &"v" => self.coords.push(Model::read_v_or_vn(w)),
          &"vn" => self.normals.push(Model::read_v_or_vn(w)),
          &"vt" => self.texture_coords.push(Model::read_vt(w)),
          &"f" => self.faces.push(Model::read_f(w)),
          _ => {},
        }
      }
      _ => {},
    };
  }

  fn read(&mut self, filename: &str) {
    let path = Path::new(filename);
    let mut file = BufferedReader::new(File::open(&path));
    for line in file.lines() {
      self.read_line(line);
    }
  }

  pub fn build(&self) -> ~[Vec3<GLfloat>]{
    let mut mesh = ~[];
    for face in self.faces.iter() {
      for i in range(0, 3) {
        let vertex_id = face.vertex[i] - 1;
        // let texture_coord_id = face.texture[i] - 1; // TODO
        mesh.push(self.coords[vertex_id]);
      }
    }
    mesh
  }
}

// vim: set tabstop=2 shiftwidth=2 softtabstop=2 expandtab:
<|endoftext|>


<commit_before>use memory::Memory;
use std;

/// Like `/dev/null`.
///
/// The `NullMemory` is always 2^32 bytes large (osci’s memory size),
/// reads `0` everywhere and discards all writes.
///
/// # Examples
/// ```
/// use osciemu::memory::Memory;
/// use osciemu::memory::NullMemory;
///
/// let mut m = NullMemory::new();
/// assert_eq!(m.get(0), 0);
/// m.set(0, 1);
/// assert_eq!(m.get(0), 0);
/// ```
pub struct NullMemory;

impl NullMemory {
    pub fn new() -> NullMemory {
        NullMemory
    }
}

impl Memory for NullMemory {
    #[inline]
    fn get(&self, _: usize) -> u32 {
        0
    }

    #[inline]
    fn set(&mut self, _: usize, _: u32) {}

    #[inline]
    fn size(&self) -> usize {
        std::u32::MAX as usize
    }
}

#[cfg(test)]
mod test {
    use memory::Memory;

    #[test]
    fn read() {
        let m = super::NullMemory::new();
        assert_eq!(m.get(0), 0);
        assert_eq!(m.get(123), 0);
        assert_eq!(m.get(u32::max_value() as usize), 0);
    }

    #[test]
    fn write() {
        let mut m = super::NullMemory::new();
        assert_eq!(m.get(0), 0);
        m.set(0, 4);
        assert_eq!(m.get(0), 0);
    }
}
<commit_msg>docs(nullmemory): Adjust import styling in example<commit_after>use memory::Memory;
use std;

/// Like `/dev/null`.
///
/// The `NullMemory` is always 2^32 bytes large (osci’s memory size),
/// reads `0` everywhere and discards all writes.
///
/// # Examples
/// ```
/// use osciemu::memory::{Memory, NullMemory};
///
/// let mut m = NullMemory::new();
/// assert_eq!(m.get(0), 0);
/// m.set(0, 1);
/// assert_eq!(m.get(0), 0);
/// ```
pub struct NullMemory;

impl NullMemory {
    pub fn new() -> NullMemory {
        NullMemory
    }
}

impl Memory for NullMemory {
    #[inline]
    fn get(&self, _: usize) -> u32 {
        0
    }

    #[inline]
    fn set(&mut self, _: usize, _: u32) {}

    #[inline]
    fn size(&self) -> usize {
        std::u32::MAX as usize
    }
}

#[cfg(test)]
mod test {
    use memory::Memory;

    #[test]
    fn read() {
        let m = super::NullMemory::new();
        assert_eq!(m.get(0), 0);
        assert_eq!(m.get(123), 0);
        assert_eq!(m.get(u32::max_value() as usize), 0);
    }

    #[test]
    fn write() {
        let mut m = super::NullMemory::new();
        assert_eq!(m.get(0), 0);
        m.set(0, 4);
        assert_eq!(m.get(0), 0);
    }
}
<|endoftext|>


<commit_before>use std::fmt::{
    Display,
    Formatter,
    Result as FmtResult,
    Write as FmtWrite
};
use super::super::id::{EmojiId, RoleId};

#[cfg(all(feature = "cache", feature = "model"))]
use internal::prelude::*;
#[cfg(all(feature = "cache", feature = "model"))]
use std::mem;
#[cfg(all(feature = "cache", feature = "model"))]
use super::super::ModelError;
#[cfg(all(feature = "cache", feature = "model"))]
use super::super::id::GuildId;
#[cfg(all(feature = "cache", feature = "model"))]
use {CACHE, http};

/// Represents a custom guild emoji, which can either be created using the API,
/// or via an integration. Emojis created using the API only work within the
/// guild it was created in.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Emoji {
    /// Whether the emoji is animated.
    #[serde(default)]
    pub animated: bool,
    /// The Id of the emoji.
    pub id: EmojiId,
    /// The name of the emoji. It must be at least 2 characters long and can
    /// only contain alphanumeric characters and underscores.
    pub name: String,
    /// Whether the emoji is managed via an [`Integration`] service.
    ///
    /// [`Integration`]: struct.Integration.html
    pub managed: bool,
    /// Whether the emoji name needs to be surrounded by colons in order to be
    /// used by the client.
    pub require_colons: bool,
    /// A list of [`Role`]s that are allowed to use the emoji. If there are no
    /// roles specified, then usage is unrestricted.
    ///
    /// [`Role`]: struct.Role.html
    pub roles: Vec<RoleId>,
}

#[cfg(feature = "model")]
impl Emoji {
    /// Deletes the emoji.
    ///
    /// **Note**: The [Manage Emojis] permission is required.
    ///
    /// **Note**: Only user accounts may use this method.
    ///
    /// [Manage Emojis]:
    /// ../permissions/struct.Permissions.html#associatedconstant.MANAGE_EMOJIS
    ///
    /// # Examples
    ///
    /// Delete a given emoji:
    ///
    /// ```rust,no_run
    /// # use serenity::model::guild::Emoji;
    /// # use serenity::model::id::EmojiId;
    /// #
    /// # let mut emoji = Emoji {
    /// #     animated: false,
    /// #     id: EmojiId(7),
    /// #     name: String::from("blobface"),
    /// #     managed: false,
    /// #     require_colons: false,
    /// #     roles: vec![],
    /// # };
    /// #
    /// // assuming emoji has been set already
    /// match emoji.delete() {
    ///     Ok(()) => println!("Emoji deleted."),
    ///     Err(_) => println!("Could not delete emoji.")
    /// }
    /// ```
    #[cfg(feature = "cache")]
    pub fn delete(&self) -> Result<()> {
        match self.find_guild_id() {
            Some(guild_id) => http::delete_emoji(guild_id.0, self.id.0),
            None => Err(Error::Model(ModelError::ItemMissing)),
        }
    }

    /// Edits the emoji by updating it with a new name.
    ///
    /// **Note**: The [Manage Emojis] permission is required.
    ///
    /// **Note**: Only user accounts may use this method.
    ///
    /// [Manage Emojis]: ../permissions/struct.Permissions.html#associatedconstant.MANAGE_EMOJIS
    ///
    /// # Examples
    ///
    /// Change the name of an emoji:
    ///
    /// ```rust,no_run
    /// # use serenity::model::guild::Emoji;
    /// # use serenity::model::id::EmojiId;
    /// #
    /// # let mut emoji = Emoji {
    /// #     animated: false,
    /// #     id: EmojiId(7),
    /// #     name: String::from("blobface"),
    /// #     managed: false,
    /// #     require_colons: false,
    /// #     roles: vec![],
    /// # };
    /// #
    /// // assuming emoji has been set already
    /// let _ = emoji.edit("blobuwu");
    /// assert_eq!(emoji.name, "blobuwu");
    /// ```
    #[cfg(feature = "cache")]
    pub fn edit(&mut self, name: &str) -> Result<()> {
        match self.find_guild_id() {
            Some(guild_id) => {
                let map = json!({
                    "name": name,
                });

                match http::edit_emoji(guild_id.0, self.id.0, &map) {
                    Ok(emoji) => {
                        mem::replace(self, emoji);

                        Ok(())
                    },
                    Err(why) => Err(why),
                }
            },
            None => Err(Error::Model(ModelError::ItemMissing)),
        }
    }

    /// Finds the [`Guild`] that owns the emoji by looking through the Cache.
    ///
    /// [`Guild`]: struct.Guild.html
    ///
    /// # Examples
    ///
    /// Print the guild id that owns this emoji:
    ///
    /// ```rust,no_run
    /// # use serenity::model::guild::Emoji;
    /// # use serenity::model::id::EmojiId;
    /// #
    /// # let mut emoji = Emoji {
    /// #     animated: false,
    /// #     id: EmojiId(7),
    /// #     name: String::from("blobface"),
    /// #     managed: false,
    /// #     require_colons: false,
    /// #     roles: vec![],
    /// # };
    /// #
    /// // assuming emoji has been set already
    /// if let Some(guild_id) = emoji.find_guild_id() {
    ///     println!("{} is owned by {}", emoji.name, guild_id);
    /// }
    /// ```
    #[cfg(feature = "cache")]
    pub fn find_guild_id(&self) -> Option<GuildId> {
        for guild in CACHE.read().guilds.values() {
            let guild = guild.read();

            if guild.emojis.contains_key(&self.id) {
                return Some(guild.id);
            }
        }

        None
    }

    /// Generates a URL to the emoji's image.
    ///
    /// # Examples
    ///
    /// Print the direct link to the given emoji:
    ///
    /// ```rust,no_run
    /// # use serenity::model::guild::Emoji;
    /// # use serenity::model::id::EmojiId;
    /// #
    /// # let mut emoji = Emoji {
    /// #     animated: false,
    /// #     id: EmojiId(7),
    /// #     name: String::from("blobface"),
    /// #     managed: false,
    /// #     require_colons: false,
    /// #     roles: vec![],
    /// # };
    /// #
    /// // assuming emoji has been set already
    /// println!("Direct link to emoji image: {}", emoji.url());
    /// ```
    #[inline]
    pub fn url(&self) -> String { format!(cdn!("/emojis/{}.png"), self.id) }
}

impl Display for Emoji {
    /// Formats the emoji into a string that will cause Discord clients to
    /// render the emoji.
    ///
    /// This is in the format of: `<:NAME:EMOJI_ID>`.
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        f.write_str("<:")?;
        f.write_str(&self.name)?;
        FmtWrite::write_char(f, ':')?;
        Display::fmt(&self.id, f)?;
        FmtWrite::write_char(f, '>')
    }
}

impl From<Emoji> for EmojiId {
    /// Gets the Id of an `Emoji`.
    fn from(emoji: Emoji) -> EmojiId { emoji.id }
}

impl<'a> From<&'a Emoji> for EmojiId {
    /// Gets the Id of an `Emoji`.
    fn from(emoji: &Emoji) -> EmojiId { emoji.id }
}
<commit_msg>Fix `Emoji::url` to use .gif for animated emoji (#449)<commit_after>use std::fmt::{
    Display,
    Formatter,
    Result as FmtResult,
    Write as FmtWrite
};
use super::super::id::{EmojiId, RoleId};

#[cfg(all(feature = "cache", feature = "model"))]
use internal::prelude::*;
#[cfg(all(feature = "cache", feature = "model"))]
use std::mem;
#[cfg(all(feature = "cache", feature = "model"))]
use super::super::ModelError;
#[cfg(all(feature = "cache", feature = "model"))]
use super::super::id::GuildId;
#[cfg(all(feature = "cache", feature = "model"))]
use {CACHE, http};

/// Represents a custom guild emoji, which can either be created using the API,
/// or via an integration. Emojis created using the API only work within the
/// guild it was created in.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Emoji {
    /// Whether the emoji is animated.
    #[serde(default)]
    pub animated: bool,
    /// The Id of the emoji.
    pub id: EmojiId,
    /// The name of the emoji. It must be at least 2 characters long and can
    /// only contain alphanumeric characters and underscores.
    pub name: String,
    /// Whether the emoji is managed via an [`Integration`] service.
    ///
    /// [`Integration`]: struct.Integration.html
    pub managed: bool,
    /// Whether the emoji name needs to be surrounded by colons in order to be
    /// used by the client.
    pub require_colons: bool,
    /// A list of [`Role`]s that are allowed to use the emoji. If there are no
    /// roles specified, then usage is unrestricted.
    ///
    /// [`Role`]: struct.Role.html
    pub roles: Vec<RoleId>,
}

#[cfg(feature = "model")]
impl Emoji {
    /// Deletes the emoji.
    ///
    /// **Note**: The [Manage Emojis] permission is required.
    ///
    /// **Note**: Only user accounts may use this method.
    ///
    /// [Manage Emojis]:
    /// ../permissions/struct.Permissions.html#associatedconstant.MANAGE_EMOJIS
    ///
    /// # Examples
    ///
    /// Delete a given emoji:
    ///
    /// ```rust,no_run
    /// # use serenity::model::guild::Emoji;
    /// # use serenity::model::id::EmojiId;
    /// #
    /// # let mut emoji = Emoji {
    /// #     animated: false,
    /// #     id: EmojiId(7),
    /// #     name: String::from("blobface"),
    /// #     managed: false,
    /// #     require_colons: false,
    /// #     roles: vec![],
    /// # };
    /// #
    /// // assuming emoji has been set already
    /// match emoji.delete() {
    ///     Ok(()) => println!("Emoji deleted."),
    ///     Err(_) => println!("Could not delete emoji.")
    /// }
    /// ```
    #[cfg(feature = "cache")]
    pub fn delete(&self) -> Result<()> {
        match self.find_guild_id() {
            Some(guild_id) => http::delete_emoji(guild_id.0, self.id.0),
            None => Err(Error::Model(ModelError::ItemMissing)),
        }
    }

    /// Edits the emoji by updating it with a new name.
    ///
    /// **Note**: The [Manage Emojis] permission is required.
    ///
    /// **Note**: Only user accounts may use this method.
    ///
    /// [Manage Emojis]: ../permissions/struct.Permissions.html#associatedconstant.MANAGE_EMOJIS
    ///
    /// # Examples
    ///
    /// Change the name of an emoji:
    ///
    /// ```rust,no_run
    /// # use serenity::model::guild::Emoji;
    /// # use serenity::model::id::EmojiId;
    /// #
    /// # let mut emoji = Emoji {
    /// #     animated: false,
    /// #     id: EmojiId(7),
    /// #     name: String::from("blobface"),
    /// #     managed: false,
    /// #     require_colons: false,
    /// #     roles: vec![],
    /// # };
    /// #
    /// // assuming emoji has been set already
    /// let _ = emoji.edit("blobuwu");
    /// assert_eq!(emoji.name, "blobuwu");
    /// ```
    #[cfg(feature = "cache")]
    pub fn edit(&mut self, name: &str) -> Result<()> {
        match self.find_guild_id() {
            Some(guild_id) => {
                let map = json!({
                    "name": name,
                });

                match http::edit_emoji(guild_id.0, self.id.0, &map) {
                    Ok(emoji) => {
                        mem::replace(self, emoji);

                        Ok(())
                    },
                    Err(why) => Err(why),
                }
            },
            None => Err(Error::Model(ModelError::ItemMissing)),
        }
    }

    /// Finds the [`Guild`] that owns the emoji by looking through the Cache.
    ///
    /// [`Guild`]: struct.Guild.html
    ///
    /// # Examples
    ///
    /// Print the guild id that owns this emoji:
    ///
    /// ```rust,no_run
    /// # use serenity::model::guild::Emoji;
    /// # use serenity::model::id::EmojiId;
    /// #
    /// # let mut emoji = Emoji {
    /// #     animated: false,
    /// #     id: EmojiId(7),
    /// #     name: String::from("blobface"),
    /// #     managed: false,
    /// #     require_colons: false,
    /// #     roles: vec![],
    /// # };
    /// #
    /// // assuming emoji has been set already
    /// if let Some(guild_id) = emoji.find_guild_id() {
    ///     println!("{} is owned by {}", emoji.name, guild_id);
    /// }
    /// ```
    #[cfg(feature = "cache")]
    pub fn find_guild_id(&self) -> Option<GuildId> {
        for guild in CACHE.read().guilds.values() {
            let guild = guild.read();

            if guild.emojis.contains_key(&self.id) {
                return Some(guild.id);
            }
        }

        None
    }

    /// Generates a URL to the emoji's image.
    ///
    /// # Examples
    ///
    /// Print the direct link to the given emoji:
    ///
    /// ```rust,no_run
    /// # use serenity::model::guild::Emoji;
    /// # use serenity::model::id::EmojiId;
    /// #
    /// # let mut emoji = Emoji {
    /// #     animated: false,
    /// #     id: EmojiId(7),
    /// #     name: String::from("blobface"),
    /// #     managed: false,
    /// #     require_colons: false,
    /// #     roles: vec![],
    /// # };
    /// #
    /// // assuming emoji has been set already
    /// println!("Direct link to emoji image: {}", emoji.url());
    /// ```
    #[inline]
    pub fn url(&self) -> String {
        let extension = if self.animated {"gif"} else {"png"};
        format!(cdn!("/emojis/{}.{}"), self.id, extension)
    }
}

impl Display for Emoji {
    /// Formats the emoji into a string that will cause Discord clients to
    /// render the emoji.
    ///
    /// This is in the format of: `<:NAME:EMOJI_ID>`.
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        f.write_str("<:")?;
        f.write_str(&self.name)?;
        FmtWrite::write_char(f, ':')?;
        Display::fmt(&self.id, f)?;
        FmtWrite::write_char(f, '>')
    }
}

impl From<Emoji> for EmojiId {
    /// Gets the Id of an `Emoji`.
    fn from(emoji: Emoji) -> EmojiId { emoji.id }
}

impl<'a> From<&'a Emoji> for EmojiId {
    /// Gets the Id of an `Emoji`.
    fn from(emoji: &Emoji) -> EmojiId { emoji.id }
}
<|endoftext|>


<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::values::*;
use vm::errors::*;

#[test]
fn locals() -> VMResult<()> {
    const LEN: usize = 4;
    let mut locals = Locals::new(LEN);
    for i in 0..LEN {
        assert!(locals.copy_loc(i).is_err());
        assert!(locals.move_loc(1).is_err());
        assert!(locals.borrow_loc(i).is_err());
    }
    locals.store_loc(1, Value::u64(42))?;

    assert!(locals.copy_loc(1)?.equals(&Value::u64(42))?);
    let r = locals.borrow_loc(1)?.value_as::<Reference>()?;
    assert!(r.read_ref()?.equals(&Value::u64(42))?);
    assert!(locals.move_loc(1)?.equals(&Value::u64(42))?);

    assert!(locals.copy_loc(1).is_err());
    assert!(locals.move_loc(1).is_err());
    assert!(locals.borrow_loc(1).is_err());

    assert!(locals.copy_loc(LEN + 1).is_err());
    assert!(locals.move_loc(LEN + 1).is_err());
    assert!(locals.borrow_loc(LEN + 1).is_err());

    Ok(())
}

#[test]
fn struct_pack_and_unpack() -> VMResult<()> {
    let vals = vec![Value::u8(10), Value::u64(20), Value::u128(30)];
    let s = Struct::pack(vec![Value::u8(10), Value::u64(20), Value::u128(30)]);
    let unpacked: Vec<_> = s.unpack()?.collect();

    assert!(vals.len() == unpacked.len());
    for (v1, v2) in vals.iter().zip(unpacked.iter()) {
        assert!(v1.equals(v2)?);
    }

    Ok(())
}

#[test]
fn struct_borrow_field() -> VMResult<()> {
    let mut locals = Locals::new(1);
    locals.store_loc(
        0,
        Value::struct_(Struct::pack(vec![Value::u8(10), Value::bool(false)])),
    )?;
    let r: StructRef = locals.borrow_loc(0)?.value_as()?;

    {
        let f: Reference = r.borrow_field(1)?.value_as()?;
        assert!(f.read_ref()?.equals(&Value::bool(false))?);
    }

    {
        let f: Reference = r.borrow_field(1)?.value_as()?;
        f.write_ref(Value::bool(true))?;
    }

    {
        let f: Reference = r.borrow_field(1)?.value_as()?;
        assert!(f.read_ref()?.equals(&Value::bool(true))?);
    }

    Ok(())
}

#[test]
fn struct_borrow_nested() -> VMResult<()> {
    let mut locals = Locals::new(1);

    fn inner(x: u64) -> Value {
        Value::struct_(Struct::pack(vec![Value::u64(x)]))
    }
    fn outer(x: u64) -> Value {
        Value::struct_(Struct::pack(vec![Value::u8(10), inner(x)]))
    }

    locals.store_loc(0, outer(20))?;
    let r1: StructRef = locals.borrow_loc(0)?.value_as()?;
    let r2: StructRef = r1.borrow_field(1)?.value_as()?;

    {
        let r3: Reference = r2.borrow_field(0)?.value_as()?;
        assert!(r3.read_ref()?.equals(&Value::u64(20))?);
    }

    {
        let r3: Reference = r2.borrow_field(0)?.value_as()?;
        r3.write_ref(Value::u64(30))?;
    }

    {
        let r3: Reference = r2.borrow_field(0)?.value_as()?;
        assert!(r3.read_ref()?.equals(&Value::u64(30))?);
    }

    assert!(r2.read_ref()?.equals(&inner(30))?);
    assert!(r1.read_ref()?.equals(&outer(30))?);

    Ok(())
}

#[test]
fn global_value_non_struct() -> VMResult<()> {
    assert!(GlobalValue::new(Value::u64(100)).is_err());
    assert!(GlobalValue::new(Value::bool(false)).is_err());

    let mut locals = Locals::new(1);
    locals.store_loc(0, Value::u8(0))?;
    let r = locals.borrow_loc(0)?;
    assert!(GlobalValue::new(r).is_err());

    Ok(())
}

#[test]
fn global_value() -> VMResult<()> {
    let gv = GlobalValue::new(Value::struct_(Struct::pack(vec![
        Value::u8(100),
        Value::u64(200),
    ])))?;

    {
        let r: StructRef = gv.borrow_global()?.value_as()?;
        let f1: Reference = r.borrow_field(0)?.value_as()?;
        let f2: Reference = r.borrow_field(1)?.value_as()?;
        assert!(f1.read_ref()?.equals(&Value::u8(100))?);
        assert!(f2.read_ref()?.equals(&Value::u64(200))?);
    }

    assert!(gv.is_clean()?);

    {
        let r: StructRef = gv.borrow_global()?.value_as()?;
        let f1: Reference = r.borrow_field(0)?.value_as()?;
        f1.write_ref(Value::u8(222))?;
    }

    assert!(gv.is_dirty()?);

    {
        let r: StructRef = gv.borrow_global()?.value_as()?;
        let f1: Reference = r.borrow_field(0)?.value_as()?;
        let f2: Reference = r.borrow_field(1)?.value_as()?;
        assert!(f1.read_ref()?.equals(&Value::u8(222))?);
        assert!(f2.read_ref()?.equals(&Value::u64(200))?);
    }

    Ok(())
}

#[test]
fn global_value_nested() -> VMResult<()> {
    let gv: GlobalValue = GlobalValue::new(Value::struct_(Struct::pack(vec![Value::struct_(
        Struct::pack(vec![Value::u64(100)]),
    )])))?;

    {
        let r1: StructRef = gv.borrow_global()?.value_as()?;
        let r2: StructRef = r1.borrow_field(0)?.value_as()?;
        let r3: Reference = r2.borrow_field(0)?.value_as()?;
        assert!(r3.read_ref()?.equals(&Value::u64(100))?);
    }

    assert!(gv.is_clean()?);

    {
        let r1: StructRef = gv.borrow_global()?.value_as()?;
        let r2: StructRef = r1.borrow_field(0)?.value_as()?;
        let r3: Reference = r2.borrow_field(0)?.value_as()?;
        r3.write_ref(Value::u64(0))?;
    }

    assert!(gv.is_dirty()?);

    {
        let r1: StructRef = gv.borrow_global()?.value_as()?;
        let r2: StructRef = r1.borrow_field(0)?.value_as()?;
        let r3: Reference = r2.borrow_field(0)?.value_as()?;
        assert!(r3.read_ref()?.equals(&Value::u64(0))?);
    }

    Ok(())
}
<commit_msg>[language] fix value_tests<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::values::*;
use vm::errors::*;

#[test]
fn locals() -> VMResult<()> {
    const LEN: usize = 4;
    let mut locals = Locals::new(LEN);
    for i in 0..LEN {
        assert!(locals.copy_loc(i).is_err());
        assert!(locals.move_loc(i).is_err());
        assert!(locals.borrow_loc(i).is_err());
    }
    locals.store_loc(1, Value::u64(42))?;

    assert!(locals.copy_loc(1)?.equals(&Value::u64(42))?);
    let r = locals.borrow_loc(1)?.value_as::<Reference>()?;
    assert!(r.read_ref()?.equals(&Value::u64(42))?);
    assert!(locals.move_loc(1)?.equals(&Value::u64(42))?);

    assert!(locals.copy_loc(1).is_err());
    assert!(locals.move_loc(1).is_err());
    assert!(locals.borrow_loc(1).is_err());

    assert!(locals.copy_loc(LEN + 1).is_err());
    assert!(locals.move_loc(LEN + 1).is_err());
    assert!(locals.borrow_loc(LEN + 1).is_err());

    Ok(())
}

#[test]
fn struct_pack_and_unpack() -> VMResult<()> {
    let vals = vec![Value::u8(10), Value::u64(20), Value::u128(30)];
    let s = Struct::pack(vec![Value::u8(10), Value::u64(20), Value::u128(30)]);
    let unpacked: Vec<_> = s.unpack()?.collect();

    assert!(vals.len() == unpacked.len());
    for (v1, v2) in vals.iter().zip(unpacked.iter()) {
        assert!(v1.equals(v2)?);
    }

    Ok(())
}

#[test]
fn struct_borrow_field() -> VMResult<()> {
    let mut locals = Locals::new(1);
    locals.store_loc(
        0,
        Value::struct_(Struct::pack(vec![Value::u8(10), Value::bool(false)])),
    )?;
    let r: StructRef = locals.borrow_loc(0)?.value_as()?;

    {
        let f: Reference = r.borrow_field(1)?.value_as()?;
        assert!(f.read_ref()?.equals(&Value::bool(false))?);
    }

    {
        let f: Reference = r.borrow_field(1)?.value_as()?;
        f.write_ref(Value::bool(true))?;
    }

    {
        let f: Reference = r.borrow_field(1)?.value_as()?;
        assert!(f.read_ref()?.equals(&Value::bool(true))?);
    }

    Ok(())
}

#[test]
fn struct_borrow_nested() -> VMResult<()> {
    let mut locals = Locals::new(1);

    fn inner(x: u64) -> Value {
        Value::struct_(Struct::pack(vec![Value::u64(x)]))
    }
    fn outer(x: u64) -> Value {
        Value::struct_(Struct::pack(vec![Value::u8(10), inner(x)]))
    }

    locals.store_loc(0, outer(20))?;
    let r1: StructRef = locals.borrow_loc(0)?.value_as()?;
    let r2: StructRef = r1.borrow_field(1)?.value_as()?;

    {
        let r3: Reference = r2.borrow_field(0)?.value_as()?;
        assert!(r3.read_ref()?.equals(&Value::u64(20))?);
    }

    {
        let r3: Reference = r2.borrow_field(0)?.value_as()?;
        r3.write_ref(Value::u64(30))?;
    }

    {
        let r3: Reference = r2.borrow_field(0)?.value_as()?;
        assert!(r3.read_ref()?.equals(&Value::u64(30))?);
    }

    assert!(r2.read_ref()?.equals(&inner(30))?);
    assert!(r1.read_ref()?.equals(&outer(30))?);

    Ok(())
}

#[test]
fn global_value_non_struct() -> VMResult<()> {
    assert!(GlobalValue::new(Value::u64(100)).is_err());
    assert!(GlobalValue::new(Value::bool(false)).is_err());

    let mut locals = Locals::new(1);
    locals.store_loc(0, Value::u8(0))?;
    let r = locals.borrow_loc(0)?;
    assert!(GlobalValue::new(r).is_err());

    Ok(())
}

#[test]
fn global_value() -> VMResult<()> {
    let gv = GlobalValue::new(Value::struct_(Struct::pack(vec![
        Value::u8(100),
        Value::u64(200),
    ])))?;

    {
        let r: StructRef = gv.borrow_global()?.value_as()?;
        let f1: Reference = r.borrow_field(0)?.value_as()?;
        let f2: Reference = r.borrow_field(1)?.value_as()?;
        assert!(f1.read_ref()?.equals(&Value::u8(100))?);
        assert!(f2.read_ref()?.equals(&Value::u64(200))?);
    }

    assert!(gv.is_clean()?);

    {
        let r: StructRef = gv.borrow_global()?.value_as()?;
        let f1: Reference = r.borrow_field(0)?.value_as()?;
        f1.write_ref(Value::u8(222))?;
    }

    assert!(gv.is_dirty()?);

    {
        let r: StructRef = gv.borrow_global()?.value_as()?;
        let f1: Reference = r.borrow_field(0)?.value_as()?;
        let f2: Reference = r.borrow_field(1)?.value_as()?;
        assert!(f1.read_ref()?.equals(&Value::u8(222))?);
        assert!(f2.read_ref()?.equals(&Value::u64(200))?);
    }

    Ok(())
}

#[test]
fn global_value_nested() -> VMResult<()> {
    let gv: GlobalValue = GlobalValue::new(Value::struct_(Struct::pack(vec![Value::struct_(
        Struct::pack(vec![Value::u64(100)]),
    )])))?;

    {
        let r1: StructRef = gv.borrow_global()?.value_as()?;
        let r2: StructRef = r1.borrow_field(0)?.value_as()?;
        let r3: Reference = r2.borrow_field(0)?.value_as()?;
        assert!(r3.read_ref()?.equals(&Value::u64(100))?);
    }

    assert!(gv.is_clean()?);

    {
        let r1: StructRef = gv.borrow_global()?.value_as()?;
        let r2: StructRef = r1.borrow_field(0)?.value_as()?;
        let r3: Reference = r2.borrow_field(0)?.value_as()?;
        r3.write_ref(Value::u64(0))?;
    }

    assert!(gv.is_dirty()?);

    {
        let r1: StructRef = gv.borrow_global()?.value_as()?;
        let r2: StructRef = r1.borrow_field(0)?.value_as()?;
        let r3: Reference = r2.borrow_field(0)?.value_as()?;
        assert!(r3.read_ref()?.equals(&Value::u64(0))?);
    }

    Ok(())
}
<|endoftext|>


<commit_before>//! A semaphore implementation based on the rust Mutex<T> type

use alloc::boxed::Box;

use core::sync::atomic::{AtomicIsize, Ordering};
use core::cell::UnsafeCell;
use core::ops::{Deref, DerefMut};

use super::super::interrupts::{on,off};
use super::super::process::{ready_queue, proc_yield, ProcessQueue};

/// `Semaphore` is a much more Rustic semaphore. It returns an RAII
/// `SemaphoreGuard`, which automatically calls "up" when it goes out of
/// scope. This semaphore takes ownership of the data it is guarding, so that
/// Rust ownership and lifetime semantics can be used to guarantee safety of
/// the resource.
///
/// ```
///  // wrap resource in a semaphore with initial count 3
///  let s = Semaphore::new(resource, 3);
///
///  {
///      // acquire
///      let guard = s.clone();
///  }
///  // guard dies => release
/// ```
pub struct Semaphore<T> {
    // box the inner semaphore so it has a constant address
    // and can be safely moved
    inner: Box<StaticSemaphore>,
    data: UnsafeCell<T>,
}

/// `StaticSemaphore` is a semaphore implementation that can be used in
/// statics. It has a const constructor.
pub struct StaticSemaphore {
    count: AtomicIsize,
    queue: ProcessQueue,
}

/// RAII SemaphoreGuard
pub struct SemaphoreGuard<'semaphore, T: 'semaphore> {
    semaphore: &'semaphore mut StaticSemaphore,
    data: &'semaphore UnsafeCell<T>,
}

unsafe impl<T: Send> Send for Semaphore<T> {}
unsafe impl<T: Send> Sync for Semaphore<T> {}

impl<T> Semaphore<T> {
    /// Create a new semaphore with the the given count guarding the given value
    pub fn new(val: T, i: isize) -> Semaphore<T> {
        Semaphore {
            inner: box StaticSemaphore::new(i),
            data: UnsafeCell::new(val),
        }
    }

    /// Acquire.
    /// returns an RAII guard, so no need for up()
    pub fn down<'semaphore>(&'semaphore mut self) -> SemaphoreGuard<'semaphore, T> {
        // acquire semaphore
        self.inner.down();
        SemaphoreGuard::new(&mut *self.inner, &self.data)
    }
}

impl<T> Drop for Semaphore<T> {
    /// When the semaphore goes out of scope, it destroys the contents
    fn drop(&mut self) {
        self.inner.destroy();
    }
}

// TODO: make StaticSemaphore use an unsafe cell, so it can be used immutably
impl StaticSemaphore {
    /// Create a new `StaticSemaphore` with the given count
    pub const fn new(i: isize) -> StaticSemaphore {
        StaticSemaphore {
            count: AtomicIsize::new(i),
            queue: ProcessQueue::new(),
        }
    }

    /// Acquire
    pub fn down(&mut self) {
        off();
        if self.count.fetch_sub(1, Ordering::AcqRel) <= 0 {
            self.count.fetch_add(1, Ordering::AcqRel);
            // block
            proc_yield(Some(&mut self.queue));
        }
        on();
    }

    /// Release
    pub fn up(&mut self) {
        off();
        if let Some(next) = self.queue.pop_front() {
            ready_queue::make_ready(next);
        } else {
            self.count.fetch_add(1,Ordering::AcqRel);
        }
        on();
    }

    /// Clean up.
    /// Cannot implement Drop here because we want to be able
    /// to create a static semaphore.
    pub fn destroy(&mut self) {
        if self.queue.len() > 0 {
            // TODO: intead, just kill the processes or do zombie detection
            panic!("Semaphore destroyed with processes waiting!");
        }
    }
}

impl<'semaphore, T> SemaphoreGuard<'semaphore, T> {
    /// Create a guard referring to the given semaphore and data
    fn new(semaphore: &'semaphore mut StaticSemaphore,
               data: &'semaphore UnsafeCell<T>) -> SemaphoreGuard<'semaphore, T>{
        SemaphoreGuard {
            semaphore: semaphore,
            data: data,
        }
    }
}

impl<'semaphore, T> Drop for SemaphoreGuard<'semaphore, T> {
    /// `SemaphoreGuard` is RAII, so dropping the guard calls up
    fn drop(&mut self) {
        self.semaphore.up();
    }
}

/// Implement Deref and DerefMut to get deref coersions
impl<'semaphore, T> Deref for SemaphoreGuard<'semaphore, T> {
    type Target = T;

    fn deref(&self) -> &T {
        unsafe { &*self.data.get() }
    }
}

/// Implement Deref and DerefMut to get deref coersions
impl<'semaphore, T> DerefMut for SemaphoreGuard<'semaphore, T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.data.get() }
    }
}

<commit_msg>Minor improvements to semaphore<commit_after>//! A semaphore implementation based on the rust Mutex<T> type

use alloc::boxed::Box;

use core::sync::atomic::{AtomicIsize, Ordering};
use core::cell::UnsafeCell;
use core::ops::{Deref, DerefMut};

use super::super::interrupts::{on,off};
use super::super::process::{ready_queue, proc_yield, ProcessQueue};

/// `Semaphore` is a much more Rustic semaphore. It returns an RAII
/// `SemaphoreGuard`, which automatically calls "up" when it goes out of
/// scope. This semaphore takes ownership of the data it is guarding, so that
/// Rust ownership and lifetime semantics can be used to guarantee safety of
/// the resource.
///
/// ```
///  // wrap resource in a semaphore with initial count 3
///  let s = Semaphore::new(resource, 3);
///
///  {
///      // acquire
///      let guard = s.clone();
///  }
///  // guard dies => release
/// ```
pub struct Semaphore<T> {
    // box the inner semaphore so it has a constant address
    // and can be safely moved
    inner: Box<StaticSemaphore>,
    data: UnsafeCell<T>,
}

/// `StaticSemaphore` is a semaphore implementation that can be used in
/// statics. It has a const constructor.
pub struct StaticSemaphore {
    // Use UnsafeCells so that it the semaphore can be used immutably
    count: UnsafeCell<AtomicIsize>,
    queue: UnsafeCell<ProcessQueue>,
}

/// RAII SemaphoreGuard
pub struct SemaphoreGuard<'semaphore, T: 'semaphore> {
    semaphore: &'semaphore mut StaticSemaphore,
    data: &'semaphore UnsafeCell<T>,
}

unsafe impl<T: Send> Send for Semaphore<T> {}
unsafe impl<T: Send> Sync for Semaphore<T> {}

impl<T> Semaphore<T> {
    /// Create a new semaphore with the the given count guarding the given value
    pub fn new(val: T, i: isize) -> Semaphore<T> {
        Semaphore {
            inner: box StaticSemaphore::new(i),
            data: UnsafeCell::new(val),
        }
    }

    /// Acquire.
    /// returns an RAII guard, so no need for up()
    pub fn down<'semaphore>(&'semaphore mut self) -> SemaphoreGuard<'semaphore, T> {
        // acquire semaphore
        self.inner.down();
        SemaphoreGuard::new(&mut *self.inner, &self.data)
    }
}

impl<T> Drop for Semaphore<T> {
    /// When the semaphore goes out of scope, it destroys the contents
    fn drop(&mut self) {
        self.inner.destroy();
    }
}

impl StaticSemaphore {
    /// Create a new `StaticSemaphore` with the given count
    pub const fn new(i: isize) -> StaticSemaphore {
        StaticSemaphore {
            count: UnsafeCell::new(AtomicIsize::new(i)),
            queue: UnsafeCell::new(ProcessQueue::new()),
        }
    }

    /// Acquire
    pub fn down(&self) {
        off();
        unsafe {
            if (*self.count.get()).fetch_sub(1, Ordering::AcqRel) <= 0 {
                (*self.count.get()).fetch_add(1, Ordering::AcqRel);
                // block
                proc_yield(Some(&mut *self.queue.get()));
            }
        }
        on();
    }

    /// Release
    pub fn up(&self) {
        off();
        unsafe {
            if let Some(next) = (*self.queue.get()).pop_front() {
                ready_queue::make_ready(next);
            } else {
                (*self.count.get()).fetch_add(1,Ordering::AcqRel);
            }
        }
        on();
    }

    /// Clean up.
    /// Cannot implement Drop here because we want to be able
    /// to create a static semaphore.
    pub fn destroy(&self) {
        unsafe {
            if (*self.queue.get()).len() > 0 {
                // TODO: intead, just kill the processes or do zombie detection
                panic!("Semaphore destroyed with processes waiting!");
            }
        }
    }
}

impl<'semaphore, T> SemaphoreGuard<'semaphore, T> {
    /// Create a guard referring to the given semaphore and data
    fn new(semaphore: &'semaphore mut StaticSemaphore,
               data: &'semaphore UnsafeCell<T>) -> SemaphoreGuard<'semaphore, T>{
        SemaphoreGuard {
            semaphore: semaphore,
            data: data,
        }
    }

    pub fn up(&mut self) {
        self.semaphore.up();
    }
}

impl<'semaphore, T> Drop for SemaphoreGuard<'semaphore, T> {
    /// `SemaphoreGuard` is RAII, so dropping the guard calls up
    fn drop(&mut self) {
        self.semaphore.up();
    }
}

/// Implement Deref and DerefMut to get deref coersions
impl<'semaphore, T> Deref for SemaphoreGuard<'semaphore, T> {
    type Target = T;

    fn deref(&self) -> &T {
        unsafe { &*self.data.get() }
    }
}

/// Implement Deref and DerefMut to get deref coersions
impl<'semaphore, T> DerefMut for SemaphoreGuard<'semaphore, T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.data.get() }
    }
}

<|endoftext|>


<commit_before>// chameneos

import io::reader_util;

use std;
import std::map;
import std::map::hashmap;
import std::sort;

fn print_complements() {
    let all = ~[Blue, Red, Yellow];
    for vec::each(all) |aa| {
        for vec::each(all) |bb| {
            io::println(show_color(aa) + " + " + show_color(bb) +
                " -> " + show_color(transform(aa,bb)));
        }
    }
}

// can I combine these two lines?
enum color_e { Red, Yellow, Blue }
type color = color_e;

type creature_info = { name: uint, color: color };

fn show_color(cc: color) -> str {
    alt (cc) {
        Red    {"red"}
        Yellow {"yellow"}
        Blue   {"blue"}
    }
}

fn show_color_list(set: ~[color]) -> str {
    let mut out = "";
    for vec::eachi(set) |_ii, col| {
        out += " ";
        out += show_color(col);
    }
    ret out;
}

fn show_digit(nn: uint) -> str {
    alt (nn) {
        0 {"zero"}
        1 {"one"}
        2 {"two"}
        3 {"three"}
        4 {"four"}
        5 {"five"}
        6 {"six"}
        7 {"seven"}
        8 {"eight"}
        9 {"nine"}
        _ {fail "expected digits from 0 to 9..."}
    }
}

fn show_number(nn: uint) -> str {
    let mut out = "";
    let mut num = nn;
    let mut dig;

    if num == 0 { out = show_digit(0) };

    while num != 0 {
        dig = num % 10;
        num = num / 10;
        out = show_digit(dig) + " " + out;
    }

    ret out;
}

fn transform(aa: color, bb: color) -> color {
    alt (aa, bb) {
        (Red,    Red   ) { Red    }
        (Red,    Yellow) { Blue   }
        (Red,    Blue  ) { Yellow }
        (Yellow, Red   ) { Blue   }
        (Yellow, Yellow) { Yellow }
        (Yellow, Blue  ) { Red    }
        (Blue,   Red   ) { Yellow }
        (Blue,   Yellow) { Red    }
        (Blue,   Blue  ) { Blue   }
    }
}

fn creature(
    name: uint,
    color: color,
    from_rendezvous: comm::port<option<creature_info>>,
    to_rendezvous: comm::chan<creature_info>,
    to_rendezvous_log: comm::chan<str>
) {
    let mut color = color;
    let mut creatures_met = 0;
    let mut evil_clones_met = 0;

    loop {
        // ask for a pairing
        comm::send(to_rendezvous, {name: name, color: color});
        let resp = comm::recv(from_rendezvous);

        // log and change, or print and quit
        alt resp {
            option::some(other_creature) {
                color = transform(color, other_creature.color);

                // track some statistics
                creatures_met += 1;
                if other_creature.name == name {
                   evil_clones_met += 1;
                }
            }
            option::none {
                // log creatures met and evil clones of self
                let report = #fmt("%u", creatures_met) + " " +
                             show_number(evil_clones_met);
                comm::send(to_rendezvous_log, report);
                break;
            }
        }
    }
}

fn rendezvous(nn: uint, set: ~[color]) {
    let from_creatures:     comm::port<creature_info> = comm::port();
    let from_creatures_log: comm::port<str> = comm::port();
    let to_rendezvous     = comm::chan(from_creatures);
    let to_rendezvous_log = comm::chan(from_creatures_log);
    let to_creature: ~[comm::chan<option<creature_info>>] =
        vec::mapi(set,
            fn@(ii: uint, col: color) -> comm::chan<option<creature_info>> {
                ret do task::spawn_listener |from_rendezvous| {
                    creature(ii, col, from_rendezvous, to_rendezvous,
                             to_rendezvous_log);
                };
            }
        );

    let mut meetings = 0;
    let mut creatures_met = 0;
    let mut creatures_present = 0;

    // use option type instead of initializing to junk?
    let mut first_creature  = { name: 0, color: Red };
    let mut second_creature = { name: 0, color: Red };

    // set up meetings...
    while meetings < nn {
        let creature_req: creature_info = comm::recv(from_creatures);
        creatures_met += 1;

        alt creatures_present {
            0 {
                first_creature = creature_req;
                creatures_present = 1;
              }
            1 {
                second_creature = creature_req;
                comm::send(to_creature[first_creature.name],
                           some(second_creature));
                comm::send(to_creature[second_creature.name],
                           some(first_creature));
                creatures_present = 0;
                meetings += 1;
              }
            _ { fail "too many creatures are here!" }
        }
    }

    // tell each creature to stop
    for vec::eachi(to_creature) |_ii, to_one| {
        comm::send(to_one, none);
    }

    // save each creature's meeting stats
    let mut report = ~[];
    for vec::each(to_creature) |_to_one| {
        vec::push(report, comm::recv(from_creatures_log));
    }

    // print each color in the set
    io::println(show_color_list(set));

    // print each creature's stats
    for vec::each(report) |rep| {
        io::println(rep);
    }

    // print the total number of creatures met
    io::println(show_number(creatures_met));
}

fn main(args: ~[str]) {
    let args = if os::getenv("RUST_BENCH").is_some() || args.len() <= 1u {
        ~["", "600"]
    } else {
        args
    };

    let nn = uint::from_str(args[1]).get();

    print_complements();
    io::println("");

    rendezvous(nn, ~[Blue, Red, Yellow]);
    io::println("");

    rendezvous(nn,
        ~[Blue, Red, Yellow, Red, Yellow, Blue, Red, Yellow, Red, Blue]);
}

<commit_msg>Add improvements suggested by erickt and bblum<commit_after>// chameneos

import io::reader_util;

use std;
import std::map;
import std::map::hashmap;
import std::sort;

fn print_complements() {
    let all = ~[Blue, Red, Yellow];
    for vec::each(all) |aa| {
        for vec::each(all) |bb| {
            io::println(show_color(aa) + " + " + show_color(bb) +
                " -> " + show_color(transform(aa,bb)));
        }
    }
}

enum color { Red, Yellow, Blue }

type creature_info = { name: uint, color: color };

fn show_color(cc: color) -> str {
    alt (cc) {
        Red    {"red"}
        Yellow {"yellow"}
        Blue   {"blue"}
    }
}

fn show_color_list(set: ~[color]) -> str {
    let mut out = "";
    for vec::eachi(set) |_ii, col| {
        out += " ";
        out += show_color(col);
    }
    ret out;
}

fn show_digit(nn: uint) -> str {
    alt (nn) {
        0 {"zero"}
        1 {"one"}
        2 {"two"}
        3 {"three"}
        4 {"four"}
        5 {"five"}
        6 {"six"}
        7 {"seven"}
        8 {"eight"}
        9 {"nine"}
        _ {fail "expected digits from 0 to 9..."}
    }
}

fn show_number(nn: uint) -> str {
    let mut out = "";
    let mut num = nn;
    let mut dig;

    if num == 0 { out = show_digit(0) };

    while num != 0 {
        dig = num % 10;
        num = num / 10;
        out = show_digit(dig) + " " + out;
    }

    ret out;
}

fn transform(aa: color, bb: color) -> color {
    alt (aa, bb) {
        (Red,    Red   ) { Red    }
        (Red,    Yellow) { Blue   }
        (Red,    Blue  ) { Yellow }
        (Yellow, Red   ) { Blue   }
        (Yellow, Yellow) { Yellow }
        (Yellow, Blue  ) { Red    }
        (Blue,   Red   ) { Yellow }
        (Blue,   Yellow) { Red    }
        (Blue,   Blue  ) { Blue   }
    }
}

fn creature(
    name: uint,
    color: color,
    from_rendezvous: comm::port<option<creature_info>>,
    to_rendezvous: comm::chan<creature_info>,
    to_rendezvous_log: comm::chan<str>
) {
    let mut color = color;
    let mut creatures_met = 0;
    let mut evil_clones_met = 0;

    loop {
        // ask for a pairing
        comm::send(to_rendezvous, {name: name, color: color});
        let resp = comm::recv(from_rendezvous);

        // log and change, or print and quit
        alt resp {
            option::some(other_creature) {
                color = transform(color, other_creature.color);

                // track some statistics
                creatures_met += 1;
                if other_creature.name == name {
                   evil_clones_met += 1;
                }
            }
            option::none {
                // log creatures met and evil clones of self
                let report = #fmt("%u", creatures_met) + " " +
                             show_number(evil_clones_met);
                comm::send(to_rendezvous_log, report);
                break;
            }
        }
    }
}

fn rendezvous(nn: uint, set: ~[color]) {
    // these ports will allow us to hear from the creatures
    let from_creatures:     comm::port<creature_info> = comm::port();
    let from_creatures_log: comm::port<str> = comm::port();

    // these channels will be passed to the creatures so they can talk to us
    let to_rendezvous     = comm::chan(from_creatures);
    let to_rendezvous_log = comm::chan(from_creatures_log);

    // these channels will allow us to talk to each creature by 'name'/index
    let to_creature: ~[comm::chan<option<creature_info>>] =
        vec::mapi(set,
            fn@(ii: uint, col: color) -> comm::chan<option<creature_info>> {
                // create each creature as a listener with a port, and
                // give us a channel to talk to each
                ret do task::spawn_listener |from_rendezvous| {
                    creature(ii, col, from_rendezvous, to_rendezvous,
                             to_rendezvous_log);
                };
            }
        );

    let mut creatures_met = 0;

    // set up meetings...
    for nn.times {
        let fst_creature: creature_info = comm::recv(from_creatures);
        let snd_creature: creature_info = comm::recv(from_creatures);

        creatures_met += 2;

        comm::send(to_creature[fst_creature.name], some(snd_creature));
        comm::send(to_creature[snd_creature.name], some(fst_creature));
    }

    // tell each creature to stop
    for vec::eachi(to_creature) |_ii, to_one| {
        comm::send(to_one, none);
    }

    // save each creature's meeting stats
    let mut report = ~[];
    for vec::each(to_creature) |_to_one| {
        vec::push(report, comm::recv(from_creatures_log));
    }

    // print each color in the set
    io::println(show_color_list(set));

    // print each creature's stats
    for vec::each(report) |rep| {
        io::println(rep);
    }

    // print the total number of creatures met
    io::println(show_number(creatures_met));
}

fn main(args: ~[str]) {
    let args = if os::getenv("RUST_BENCH").is_some() || args.len() <= 1u {
        ~["", "600"]
    } else {
        args
    };

    let nn = uint::from_str(args[1]).get();

    print_complements();
    io::println("");

    rendezvous(nn, ~[Blue, Red, Yellow]);
    io::println("");

    rendezvous(nn,
        ~[Blue, Red, Yellow, Red, Yellow, Blue, Red, Yellow, Red, Blue]);
}

<|endoftext|>


<commit_before>#![feature(rustc_attrs)]
#![deny(const_err)]

fn black_box<T>(_: T) {
    unimplemented!()
}

fn main() {
    let b = 200u8 + 200u8 + 200u8;
    //~^ ERROR const_err
    let c = 200u8 * 4;
    //~^ ERROR const_err
    let d = 42u8 - (42u8 + 1);
    //~^ ERROR const_err
    let _e = [5u8][1];
    //~^ ERROR const_err
    black_box(b);
    black_box(c);
    black_box(d);
}
<commit_msg>fix compile-fail<commit_after>#![feature(rustc_attrs)]
#![deny(const_err)]

fn black_box<T>(_: T) {
    unimplemented!()
}

fn main() {
    let b = 200u8 + 200u8 + 200u8;
    //~^ ERROR overflow
    let c = 200u8 * 4;
    //~^ ERROR overflow
    let d = 42u8 - (42u8 + 1);
    //~^ ERROR overflow
    let _e = [5u8][1];
    //~^ ERROR panic
    black_box(b);
    black_box(c);
    black_box(d);
}
<|endoftext|>


<commit_before>//! FBX binary parser.

use std::fmt;
use std::io::Read;

pub use self::error::{Result, Error, Warning};
pub use self::event::{Event, FbxHeader, FbxFooter, StartNode};
use self::event::EventBuilder;
use self::event::read_fbx_header;
use self::reader::CountReader;

mod error;
mod event;
mod reader;

/// Parser state without error.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum State {
    /// Reading file header.
    Header,
    /// A node started.
    ///
    /// This status means:
    ///
    /// - there might be some attributes remain unread, or
    /// - the most recent opened node might close without no null node header.
    NodeStarted,
    /// A node ended.
    ///
    /// This status means:
    ///
    /// - if the next event is `NodeEnd`, there must be a null node header, and
    /// - if the parser got an extra null header, it indicates end of implicit root node.
    NodeEnded,
}

/// Pull parser for FBX binary format.
// I want to use `#[derive(Debug)]` but it causes compile error for rustc-1.12(stable), 1.13(beta),
// 1.14(nightly).
// See also: #[derive] is too conservative with field trait bounds · Issue #26925 · rust-lang/rust
//           ( https://github.com/rust-lang/rust/issues/26925 ).
pub struct BinaryParser<R> {
    /// Source reader.
    source: CountReader<R>,
    /// Parser state.
    ///
    /// `Ok(State)` if the parser is working without critical error,
    /// `Err(Error)` if the parsing failed and cannot be continued.
    state: Result<State>,
    /// Warnings.
    warnings: Vec<Warning>,
    /// FBX version.
    fbx_version: Option<u32>,
}

impl<R: Read> BinaryParser<R> {
    /// Creates a new binary parser.
    pub fn new(source: R) -> Self {
        BinaryParser {
            source: CountReader::new(source),
            state: Ok(State::Header),
            warnings: Vec::new(),
            fbx_version: None,
        }
    }

    /// Returns FBX version of the reading input.
    ///
    /// Returns `None` if unknown yet.
    pub fn fbx_version(&self) -> Option<u32> {
        self.fbx_version
    }

    /// Returns the parser error if available.
    pub fn error(&self) -> Option<&Error> {
        self.state.as_ref().err()
    }

    /// Returns reference to the warnings.
    pub fn warnings(&self) -> &Vec<Warning> {
        &self.warnings
    }

    /// Parses FBX from the given stream and returns the next event.
    pub fn next_event(&mut self) -> Result<Event<R>> {
        let builder = match try!(self.state.clone()) {
            State::Header => self.read_fbx_header(),
            State::NodeStarted => self.read_after_node_start(),
            State::NodeEnded => self.read_after_node_end(),
        };
        if let Err(ref err) = builder {
            self.set_error(err);
        }
        Ok(try!(builder).build(self))
    }

    /// Set the parser state as error.
    fn set_error(&mut self, err: &Error) {
        error!("FBX binary parser error: {}", err);
        debug!("Parser: {:#?}", self);
        self.state = Err(err.clone());
    }

    /// Add warning.
    fn warn(&mut self, warning: Warning) {
        warn!("FBX binary parser warning: {}", warning);
        debug!("Parser: {:#?}", self);
        self.warnings.push(warning);
    }

    /// Reads FBX header.
    fn read_fbx_header(&mut self) -> Result<EventBuilder> {
        let header = try!(read_fbx_header(self));
        self.fbx_version = Some(header.version);
        self.state = Ok(State::NodeEnded);
        Ok(header.into())
    }

    /// Gets event after node start.
    fn read_after_node_start(&mut self) -> Result<EventBuilder> {
        unimplemented!()
    }

    /// Gets event after node end.
    fn read_after_node_end(&mut self) -> Result<EventBuilder> {
        unimplemented!()
    }
}

impl<R> fmt::Debug for BinaryParser<R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("BinaryParser")
            .field("source", &self.source)
            .field("state", &self.state)
            .field("warnings", &self.warnings)
            .field("fbx_version", &self.fbx_version)
            .finish()
    }
}
<commit_msg>Add a struct to manage nodes info which a parser read<commit_after>//! FBX binary parser.

use std::fmt;
use std::io::Read;

pub use self::error::{Result, Error, Warning};
pub use self::event::{Event, FbxHeader, FbxFooter, StartNode};
use self::event::EventBuilder;
use self::event::read_fbx_header;
use self::reader::CountReader;

mod error;
mod event;
mod reader;

/// Parser state without error.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum State {
    /// Reading file header.
    Header,
    /// A node started.
    ///
    /// This status means:
    ///
    /// - there might be some attributes remain unread, or
    /// - the most recent opened node might close without no null node header.
    NodeStarted,
    /// A node ended.
    ///
    /// This status means:
    ///
    /// - if the next event is `NodeEnd`, there must be a null node header, and
    /// - if the parser got an extra null header, it indicates end of implicit root node.
    NodeEnded,
}

/// Information about opened (but not yet closed) node.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
struct OpenNode {
    /// Start offset of the node attribute.
    ///
    /// Note that this doesn't mean start offset of node header.
    begin: u64,
    /// End offset of the node.
    end: u64,
    /// End offset of attributes of the node.
    attributes_end: u64,
}

/// Pull parser for FBX binary format.
// I want to use `#[derive(Debug)]` but it causes compile error for rustc-1.12(stable), 1.13(beta),
// 1.14(nightly).
// See also: #[derive] is too conservative with field trait bounds · Issue #26925 · rust-lang/rust
//           ( https://github.com/rust-lang/rust/issues/26925 ).
pub struct BinaryParser<R> {
    /// Source reader.
    source: CountReader<R>,
    /// Parser state.
    ///
    /// `Ok(State)` if the parser is working without critical error,
    /// `Err(Error)` if the parsing failed and cannot be continued.
    state: Result<State>,
    /// Warnings.
    warnings: Vec<Warning>,
    /// FBX version.
    fbx_version: Option<u32>,
    /// Open nodes stack.
    open_nodes: Vec<OpenNode>,
}

impl<R: Read> BinaryParser<R> {
    /// Creates a new binary parser.
    pub fn new(source: R) -> Self {
        BinaryParser {
            source: CountReader::new(source),
            state: Ok(State::Header),
            warnings: Vec::new(),
            fbx_version: None,
            open_nodes: Vec::new(),
        }
    }

    /// Returns FBX version of the reading input.
    ///
    /// Returns `None` if unknown yet.
    pub fn fbx_version(&self) -> Option<u32> {
        self.fbx_version
    }

    /// Returns the parser error if available.
    pub fn error(&self) -> Option<&Error> {
        self.state.as_ref().err()
    }

    /// Returns reference to the warnings.
    pub fn warnings(&self) -> &Vec<Warning> {
        &self.warnings
    }

    /// Parses FBX from the given stream and returns the next event.
    pub fn next_event(&mut self) -> Result<Event<R>> {
        let builder = match try!(self.state.clone()) {
            State::Header => self.read_fbx_header(),
            State::NodeStarted => self.read_after_node_start(),
            State::NodeEnded => self.read_after_node_end(),
        };
        if let Err(ref err) = builder {
            self.set_error(err);
        }
        Ok(try!(builder).build(self))
    }

    /// Set the parser state as error.
    fn set_error(&mut self, err: &Error) {
        error!("FBX binary parser error: {}", err);
        debug!("Parser: {:#?}", self);
        self.state = Err(err.clone());
    }

    /// Add warning.
    fn warn(&mut self, warning: Warning) {
        warn!("FBX binary parser warning: {}", warning);
        debug!("Parser: {:#?}", self);
        self.warnings.push(warning);
    }

    /// Reads FBX header.
    fn read_fbx_header(&mut self) -> Result<EventBuilder> {
        let header = try!(read_fbx_header(self));
        self.fbx_version = Some(header.version);
        self.state = Ok(State::NodeEnded);
        Ok(header.into())
    }

    /// Gets event after node start.
    fn read_after_node_start(&mut self) -> Result<EventBuilder> {
        unimplemented!()
    }

    /// Gets event after node end.
    fn read_after_node_end(&mut self) -> Result<EventBuilder> {
        unimplemented!()
    }
}

impl<R> fmt::Debug for BinaryParser<R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("BinaryParser")
            .field("source", &self.source)
            .field("state", &self.state)
            .field("warnings", &self.warnings)
            .field("fbx_version", &self.fbx_version)
            .field("open_nodes", &self.open_nodes)
            .finish()
    }
}
<|endoftext|>


<commit_before>// Copyright 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 std::num::Int;

extern "C" fn foo<T: Int>(a: T, b: T) -> T { a + b }

fn main() {
    assert_eq!(99u8, foo(255u8, 100u8));
    assert_eq!(99u16, foo(65535u16, 100u16));
}
<commit_msg>fix test generic-extern-mangle.rs<commit_after>// Copyright 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 std::num::Int;

extern "C" fn foo<T: WrappingOps>(a: T, b: T) -> T { a.wrapping_add(b) }

fn main() {
    assert_eq!(99u8, foo(255u8, 100u8));
    assert_eq!(99u16, foo(65535u16, 100u16));
}
<|endoftext|>


<commit_before>use std::path;
use littletest;

pub struct RunOptions {
    pub ignore_todo: bool,
    pub command: String
}

pub struct TestCase<'o> {
    pub input_path: path::PathBuf,
    pub expected_path: path::PathBuf,
    pub opts: &'o RunOptions
}

impl<'o> TestCase<'o> {
    pub fn is_todo(&self) -> bool {
        match self.input_path.to_str() {
            Some(x) => x.contains("todo"),
            None => false
        }
    }
}

impl<'a> littletest::Runnable for TestCase<'a> {
    fn run(&self) -> littletest::TestResult {
        if self.opts.ignore_todo && self.is_todo() {
            return littletest::TestResult::Skipped
        }

        littletest::TestResult::Pass
    }
}

pub fn load<'o>(spec_path: &path::Path,  opts: &'o RunOptions) -> Vec<Box<littletest::Runnable + Sync + 'o>> {
    use glob::glob;

    let input_file = "input.scss";
    let expected_file = "expected_output.css";

    let mut pattern = spec_path.to_path_buf();
    pattern.push("**");
    pattern.push(input_file);
    glob(pattern.to_str().unwrap())
        .unwrap()
        .map(|result| {
            let path = result.unwrap();
            let dir = path.parent().unwrap().to_path_buf();
            Box::new(TestCase {
                input_path: path,
                expected_path: dir.join(expected_file),
                opts: opts
            }) as Box<littletest::Runnable + Sync + 'o>
        })
        .collect()
}
<commit_msg>Tidy up includes.<commit_after>use std::path;
use littletest;

pub struct RunOptions {
    pub ignore_todo: bool,
    pub command: String
}

pub struct TestCase<'o> {
    pub input_path: path::PathBuf,
    pub expected_path: path::PathBuf,
    pub opts: &'o RunOptions
}

impl<'o> TestCase<'o> {
    pub fn is_todo(&self) -> bool {
        match self.input_path.to_str() {
            Some(x) => x.contains("todo"),
            None => false
        }
    }
}

impl<'a> littletest::Runnable for TestCase<'a> {
    fn run(&self) -> littletest::TestResult {
        use littletest::{TestResult};

        if self.opts.ignore_todo && self.is_todo() {
            return TestResult::Skipped
        }

        TestResult::Pass
    }
}

pub fn load<'o>(spec_path: &path::Path,  opts: &'o RunOptions) -> Vec<Box<littletest::Runnable + Sync + 'o>> {
    use glob::glob;

    let input_file = "input.scss";
    let expected_file = "expected_output.css";

    let mut pattern = spec_path.to_path_buf();
    pattern.push("**");
    pattern.push(input_file);
    glob(pattern.to_str().unwrap())
        .unwrap()
        .map(|result| {
            let path = result.unwrap();
            let dir = path.parent().unwrap().to_path_buf();
            Box::new(TestCase {
                input_path: path,
                expected_path: dir.join(expected_file),
                opts: opts
            }) as Box<littletest::Runnable + Sync + 'o>
        })
        .collect()
}
<|endoftext|>