<commit_before>//! # Flexibly-sized reusable boxes
//!
//! `FlexBox` provides a reusable `Box`-like storage mechanism.  Like `Box` it
//! allows dynamic dispatch by wrapping of trait objects; however, it also
//! allows the allocated memory to be used multiple times.
//!
//! ```rust
//! use cripes::util::flex_box::{FlexBox,Ref};
//!
//! fn some_iter<'a>(dest: &'a mut FlexBox) -> Ref<'a,Iterator<Item=u8>> {
//!     dest.store(std::iter::once(42))
//! }
//!
//! fn main() {
//!     let mut flex_box = FlexBox::new();
//!     let iter = some_iter(&mut flex_box);
//!     println!("{:?}", iter.collect::<Vec<u8>>());
//! }
//! ```
use std;
use std::fmt;
use std::ptr;
use std::iter::Iterator;
use std::mem::{align_of,size_of};
use std::intrinsics::move_val_init;
use std::ops::Drop;
extern crate alloc;
use self::alloc::heap::{allocate,deallocate,reallocate};

/// A flexibly-sized, reusable `Box`-like container.
pub struct FlexBox {
    buf: *mut u8,
    capacity: usize,
    align: usize
}

impl FlexBox {
    /// Create a new FlexBox with zero capacity.
    pub fn new() -> Self {
        FlexBox{buf: ptr::null_mut(), capacity: 0, align: 0}
    }

    /// Create a new FlexBox with capacity and alignment sufficient to hold
    /// a value of the given type.
    pub fn with_capacity_for<T>() -> Self {
        let mut out = Self::new();
        if size_of::<T>() > 0 { out.ensure_capacity::<T>(); }

        out
    }

    /// Ensure that the buffer has sufficient capacity and alignment to hold
    /// a value of the specified type.
    fn ensure_capacity<T>(&mut self) {
        let size = size_of::<T>();
        let align = align_of::<T>();
        if size > 0 {
            unsafe {
                let new = if self.buf.is_null() {
                    allocate(size, align)
                } else if self.capacity < size || self.align < align {
                    reallocate(self.buf, self.capacity, size, align)
                } else {
                    // We use a null value for the new-buffer pointer to
                    // indicate that no (re)allocation is necessary.
                    ptr::null_mut()
                };

                if !new.is_null() {
                    self.buf = new;
                    self.capacity = size;
                    self.align = align;
                }
            }
        }
    }

    /// Move a value into the FlexBox, and return a reference to it.
    /// The stored value will be dropped at the same time as the returned
    /// reference is dropped.
    pub fn store<'a,T>(&'a mut self, obj: T) -> Ref<'a,T> {
        self.ensure_capacity::<T>();

        assert!(self.capacity >= size_of::<T>());
        let dest = unsafe { &mut *(self.buf as *mut T) };
        unsafe { move_val_init(dest, obj) };
        Ref(dest)
    }
}

impl Drop for FlexBox {
    fn drop(&mut self) {
        if ! self.buf.is_null() {
            unsafe { deallocate(self.buf, self.capacity, self.align); }
            self.buf = ptr::null_mut();
            self.capacity = 0;
            self.align = 0; }
    }
}

/// Reference to a live value stored in a `FlexBox`.  `Ref` directly manages
/// the lifetime of the stored value: the value is dropped at the same time as
/// the `Ref` that refers to it.
pub struct Ref<'a,T: 'a + ?Sized>(&'a mut T);

impl<'a,U: 'a + ?Sized, T: 'a + ?Sized + std::marker::Unsize<U>>
    std::ops::CoerceUnsized<Ref<'a,U>>
    for Ref<'a,T>
    {}

impl<'a,T: 'a + ?Sized> Drop for Ref<'a,T> {
    fn drop(&mut self) {
        unsafe { std::intrinsics::drop_in_place(self.0); }
    }
}

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

impl<'a,T: 'a + ?Sized> std::ops::DerefMut for Ref<'a,T> {
    fn deref_mut<'b>(&'b mut self) -> &'b mut T {
        &mut *self.0
    }
}

/* **************************************************************** */
// Utility implementations follow.

// I'll admit that this macro is a bit excessive, but it's adapted from
// something similar I had lying around anyway.
macro_rules! passthrough {
    /* (&self) */
    ($implemented: path, $method:ident(&self))
        => (fn $method(&self) { T::$method(&*self) });

    /* (&self, ...) */
    ($implemented: path, $method: ident (&self, $($arg:ident: $typ:ty),+))
        => (fn $method(&self, $($arg: $typ),+) -> $ret { T::$method(&*self, $($arg),+) });

    /* (&self) -> ... */
    ($implemented: path, $method:ident(&self) -> $ret:ty)
        => (fn $method(&self) -> $ret { T::$method(&*self) });

    /* (&self, ...) -> ... */
    ($implemented: path, $method: ident (&self, $($arg:ident: $typ:ty),+) -> $ret:ty)
        => (fn $method(&self, $($arg: $typ),+) -> $ret { T::$method(&*self, $($arg),+) });

    /* (&mut self) */
    ($implemented: path, $method:ident(&mut self))
        => (fn $method(&mut self) { T::$method(&mut *self) });

    /* (&mut self, ...) */
    ($implemented: path, $method: ident (&mut self, $($arg:ident: $typ:ty),+))
        => (fn $method(&mut self, $($arg: $typ),+) -> $ret { T::$method(&mut *self, $($arg),+) });

    /* (&mut self) -> ... */
    ($implemented: path, $method:ident(&mut self) -> $ret:ty)
        => (fn $method(&mut self) -> $ret { T::$method(&mut *self) });

    /* (&mut self, ...) -> ... */
    ($implemented: path, $method: ident (&mut self, $($arg:ident: $typ:ty),+) -> $ret:ty)
        => (fn $method(&mut self, $($arg: $typ),+) -> $ret { T::$method(&mut *self, $($arg),+) });
}

impl<'a,T: 'a + ?Sized + fmt::Debug> fmt::Debug for Ref<'a,T> {
    passthrough!(fmt::Debug, fmt(&self, f: &mut fmt::Formatter) -> fmt::Result);
}

impl<'a,T: 'a + ?Sized + fmt::Display> fmt::Display for Ref<'a,T> {
    passthrough!(fmt::Display, fmt(&self, f: &mut fmt::Formatter) -> fmt::Result);
}

impl<'a,U,T: ?Sized> Iterator for Ref<'a,T> where T: 'a + Iterator<Item=U> {
    type Item = U;

    passthrough!(Iterator, next(&mut self) -> Option<U>);
    passthrough!(Iterator, size_hint(&self) -> (usize, Option<usize>));
}
<commit_msg>util/flex_box.rs: add doc-tests to ensure safety via borrow checker<commit_after>//! # Flexibly-sized reusable boxes
//!
//! `FlexBox` provides a reusable `Box`-like storage mechanism.  Like `Box` it
//! allows dynamic dispatch by wrapping of trait objects; however, it also
//! allows the allocated memory to be used multiple times.
//!
//! ```rust
//! use cripes::util::flex_box::{FlexBox,Ref};
//!
//! fn some_iter<'a>(dest: &'a mut FlexBox) -> Ref<'a,Iterator<Item=u8>> {
//!     dest.store(std::iter::once(42))
//! }
//!
//! fn main() {
//!     let mut flex_box = FlexBox::new();
//!     let iter = some_iter(&mut flex_box);
//!     println!("{:?}", iter.collect::<Vec<u8>>());
//! }
//! ```
//!
//! It would be unsafe to store into a FlexBox that already holds a live value;
//! luckily Rust's borrow rules prevent this from happening.  The following
//! example wouldn't compile.
//!
//! ```rust,compile_fail
//! use cripes::util::flex_box::FlexBox;
//!
//! fn main() {
//!     let mut b = FlexBox::new();
//!     let x = b.store(1);
//!     let y = b.store(2);  // error: cannot borrow `b` as mutable more than once at a time
//! }
//! ```
//!
//! This, however, is fine.
//!
//! ```rust
//! use cripes::util::flex_box::FlexBox;
//!
//! fn main() {
//!     let mut b = FlexBox::new();
//!     { let x = b.store(1); }
//!     let y = b.store(2);  // okay: `x` was dropped at the end of the block statement
//! }
//! ```

use std;
use std::fmt;
use std::ptr;
use std::iter::Iterator;
use std::mem::{align_of,size_of};
use std::intrinsics::move_val_init;
use std::ops::Drop;
extern crate alloc;
use self::alloc::heap::{allocate,deallocate,reallocate};

/// A flexibly-sized, reusable `Box`-like container.
pub struct FlexBox {
    buf: *mut u8,
    capacity: usize,
    align: usize
}

impl FlexBox {
    /// Create a new FlexBox with zero capacity.
    pub fn new() -> Self {
        FlexBox{buf: ptr::null_mut(), capacity: 0, align: 0}
    }

    /// Create a new FlexBox with capacity and alignment sufficient to hold
    /// a value of the given type.
    pub fn with_capacity_for<T>() -> Self {
        let mut out = Self::new();
        if size_of::<T>() > 0 { out.ensure_capacity::<T>(); }

        out
    }

    /// Ensure that the buffer has sufficient capacity and alignment to hold
    /// a value of the specified type.
    fn ensure_capacity<T>(&mut self) {
        let size = size_of::<T>();
        let align = align_of::<T>();
        if size > 0 {
            unsafe {
                let new = if self.buf.is_null() {
                    allocate(size, align)
                } else if self.capacity < size || self.align < align {
                    reallocate(self.buf, self.capacity, size, align)
                } else {
                    // We use a null value for the new-buffer pointer to
                    // indicate that no (re)allocation is necessary.
                    ptr::null_mut()
                };

                if !new.is_null() {
                    self.buf = new;
                    self.capacity = size;
                    self.align = align;
                }
            }
        }
    }

    /// Move a value into the FlexBox, and return a reference to it.
    /// The stored value will be dropped at the same time as the returned
    /// reference is dropped.
    pub fn store<'a,T>(&'a mut self, obj: T) -> Ref<'a,T> {
        self.ensure_capacity::<T>();

        assert!(self.capacity >= size_of::<T>());
        let dest = unsafe { &mut *(self.buf as *mut T) };
        unsafe { move_val_init(dest, obj) };
        Ref(dest)
    }
}

impl Drop for FlexBox {
    fn drop(&mut self) {
        if ! self.buf.is_null() {
            unsafe { deallocate(self.buf, self.capacity, self.align); }
            self.buf = ptr::null_mut();
            self.capacity = 0;
            self.align = 0; }
    }
}

/// Reference to a live value stored in a `FlexBox`.  `Ref` directly manages
/// the lifetime of the stored value: the value is dropped at the same time as
/// the `Ref` that refers to it.
pub struct Ref<'a,T: 'a + ?Sized>(&'a mut T);

impl<'a,U: 'a + ?Sized, T: 'a + ?Sized + std::marker::Unsize<U>>
    std::ops::CoerceUnsized<Ref<'a,U>>
    for Ref<'a,T>
    {}

impl<'a,T: 'a + ?Sized> Drop for Ref<'a,T> {
    fn drop(&mut self) {
        unsafe { std::intrinsics::drop_in_place(self.0); }
    }
}

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

impl<'a,T: 'a + ?Sized> std::ops::DerefMut for Ref<'a,T> {
    fn deref_mut<'b>(&'b mut self) -> &'b mut T {
        &mut *self.0
    }
}

/* **************************************************************** */
// Utility implementations follow.

// I'll admit that this macro is a bit excessive, but it's adapted from
// something similar I had lying around anyway.
macro_rules! passthrough {
    /* (&self) */
    ($implemented: path, $method:ident(&self))
        => (fn $method(&self) { T::$method(&*self) });

    /* (&self, ...) */
    ($implemented: path, $method: ident (&self, $($arg:ident: $typ:ty),+))
        => (fn $method(&self, $($arg: $typ),+) -> $ret { T::$method(&*self, $($arg),+) });

    /* (&self) -> ... */
    ($implemented: path, $method:ident(&self) -> $ret:ty)
        => (fn $method(&self) -> $ret { T::$method(&*self) });

    /* (&self, ...) -> ... */
    ($implemented: path, $method: ident (&self, $($arg:ident: $typ:ty),+) -> $ret:ty)
        => (fn $method(&self, $($arg: $typ),+) -> $ret { T::$method(&*self, $($arg),+) });

    /* (&mut self) */
    ($implemented: path, $method:ident(&mut self))
        => (fn $method(&mut self) { T::$method(&mut *self) });

    /* (&mut self, ...) */
    ($implemented: path, $method: ident (&mut self, $($arg:ident: $typ:ty),+))
        => (fn $method(&mut self, $($arg: $typ),+) -> $ret { T::$method(&mut *self, $($arg),+) });

    /* (&mut self) -> ... */
    ($implemented: path, $method:ident(&mut self) -> $ret:ty)
        => (fn $method(&mut self) -> $ret { T::$method(&mut *self) });

    /* (&mut self, ...) -> ... */
    ($implemented: path, $method: ident (&mut self, $($arg:ident: $typ:ty),+) -> $ret:ty)
        => (fn $method(&mut self, $($arg: $typ),+) -> $ret { T::$method(&mut *self, $($arg),+) });
}

impl<'a,T: 'a + ?Sized + fmt::Debug> fmt::Debug for Ref<'a,T> {
    passthrough!(fmt::Debug, fmt(&self, f: &mut fmt::Formatter) -> fmt::Result);
}

impl<'a,T: 'a + ?Sized + fmt::Display> fmt::Display for Ref<'a,T> {
    passthrough!(fmt::Display, fmt(&self, f: &mut fmt::Formatter) -> fmt::Result);
}

impl<'a,U,T: ?Sized> Iterator for Ref<'a,T> where T: 'a + Iterator<Item=U> {
    type Item = U;

    passthrough!(Iterator, next(&mut self) -> Option<U>);
    passthrough!(Iterator, size_hint(&self) -> (usize, Option<usize>));
}
<|endoftext|>


<commit_before>use analysis;
use analysis::rust_type::rust_type;
use analysis::type_kind::TypeKind;
use env::Env;
use library;
use traits::*;

pub trait TranslateFromGlib {
    fn translate_from_glib_as_function(&self, env: &Env) -> (String, String);
}

//TODO: move to code for analysis::return_value::Info
impl TranslateFromGlib for library::Parameter {
    fn translate_from_glib_as_function(&self, env: &Env) -> (String, String) {
        let kind = TypeKind::of(&env.library, self.typ);
        match kind {
            TypeKind::Converted => ("from_glib(".into(), ")".into()),
            TypeKind::Direct |
                TypeKind::Enumeration => (String::new(), String::new()),
            //TODO: check gtk_dialog_get_content_area <type name="Box" c:type="GtkWidget*"/>
            TypeKind::Pointer | //Checked only for Option<String>
                TypeKind::Object => from_glib_xxx(self.transfer),
            _ => (format!("TODO {:?}:", kind), String::new()),
        }
    }
}

impl TranslateFromGlib for analysis::return_value::Info {
    fn translate_from_glib_as_function(&self, env: &Env) -> (String, String) {
        match self.parameter {
            Some(ref par) => match self.base_tid {
                Some(tid) => {
                    let rust_type = rust_type(env, tid);
                    let from_glib_xxx = from_glib_xxx(par.transfer);
                    (
                        format!("{}::{}", rust_type.as_str(), from_glib_xxx.0),
                        format!("{}.downcast_unchecked()",from_glib_xxx.1)
                    )
                }
                None => par.translate_from_glib_as_function(env)
            },
            None => (String::new(), ";".into())
        }
    }
}

fn from_glib_xxx(transfer: library::Transfer) -> (String, String) {
    use library::Transfer::*;
    match transfer {
        None => ("from_glib_none(".into(), ")".into()),
        Full => ("from_glib_full(".into(), ")".into()),
        Container => ("TODO:".into(), String::new()),
    }
}
<commit_msg>Fix downcast function for optional returns<commit_after>use analysis;
use analysis::rust_type::rust_type;
use analysis::type_kind::TypeKind;
use env::Env;
use library;
use traits::*;

pub trait TranslateFromGlib {
    fn translate_from_glib_as_function(&self, env: &Env) -> (String, String);
}

//TODO: move to code for analysis::return_value::Info
impl TranslateFromGlib for library::Parameter {
    fn translate_from_glib_as_function(&self, env: &Env) -> (String, String) {
        let kind = TypeKind::of(&env.library, self.typ);
        match kind {
            TypeKind::Converted => ("from_glib(".into(), ")".into()),
            TypeKind::Direct |
                TypeKind::Enumeration => (String::new(), String::new()),
            TypeKind::Pointer | //Checked only for Option<String>
                TypeKind::Object => from_glib_xxx(self.transfer),
            _ => (format!("TODO {:?}:", kind), String::new()),
        }
    }
}

impl TranslateFromGlib for analysis::return_value::Info {
    fn translate_from_glib_as_function(&self, env: &Env) -> (String, String) {
        match self.parameter {
            Some(ref par) => match self.base_tid {
                Some(tid) => {
                    let rust_type = rust_type(env, tid);
                    let from_glib_xxx = from_glib_xxx(par.transfer);
                    let prefix = if par.nullable {
                        format!("Option::<{}>::{}", rust_type.as_str(), from_glib_xxx.0)
                    } else {
                        format!("{}::{}", rust_type.as_str(), from_glib_xxx.0)
                    };
                    let suffix_function = if par.nullable {
                        "map(Downcast::downcast_unchecked)"
                    } else {
                        "downcast_unchecked()"
                    };
                    (
                        prefix,
                        format!("{}.{}", from_glib_xxx.1, suffix_function)
                    )
                }
                None => par.translate_from_glib_as_function(env)
            },
            None => (String::new(), ";".into())
        }
    }
}

fn from_glib_xxx(transfer: library::Transfer) -> (String, String) {
    use library::Transfer::*;
    match transfer {
        None => ("from_glib_none(".into(), ")".into()),
        Full => ("from_glib_full(".into(), ")".into()),
        Container => ("TODO:".into(), String::new()),
    }
}
<|endoftext|>


<commit_before>//! PortAudio backend!

use buffer::DspBuffer;
use portaudio::{ types, pa };
use sound_stream::SoundStream;
use sound_stream_settings::SoundStreamSettings;

/// PortAudio Stream Parameters (required to setup stream).
pub struct StreamParamsPA {
    input: types::PaStreamParameters,
    output: types::PaStreamParameters,
}

/// PortAudio Stream (for reading from and writing to real-time audio stream).
pub struct StreamPA {
    stream: pa::PaStream<f32>,
    pub is_streaming: bool
}

/// The parameters required to set up the PortAudio stream.
impl StreamParamsPA {

    /// Creates the port audio stream parameters.
    pub fn new(channels: u16) -> StreamParamsPA {

        println!("Portaudio init error : {}", pa::get_error_text(pa::initialize()));

        println!("Creating StreamParamsPA");
        let def_input = pa::device::get_default_input();
        let def_output = pa::device::get_default_output();

        println!("Creating input");
        let stream_params_in = types::PaStreamParameters {
            device: def_input,
            channel_count: channels as i32,
            sample_format: types::PaFloat32,
            suggested_latency: pa::device::get_info(def_input).unwrap().default_low_input_latency
        };
        println!("Creating output");
        let stream_params_out = types::PaStreamParameters {
            device: def_output,
            channel_count: channels as i32,
            sample_format: types::PaFloat32,
            suggested_latency: pa::device::get_info(def_output).unwrap().default_low_output_latency
        };

        StreamParamsPA {
            input: stream_params_in,
            output: stream_params_out
        }
    }

}

impl StreamPA {

    /// Constructor for the portaudio stream.
    pub fn new() -> StreamPA {
        StreamPA {
            stream: pa::PaStream::new(types::PaFloat32),
            is_streaming: true
        }
    }

    /// Setup the portaudio stream.
    pub fn setup(&mut self, settings: SoundStreamSettings) {
        let params = StreamParamsPA::new(settings.channels);
        self.stream.open(Some(&params.input),
                         Some(&params.output),
                         settings.samples_per_sec as f64,
                         settings.frames as u32,
                         types::PaClipOff);
    }

    /// Performs the audio read/write.
    pub fn callback<B: DspBuffer, T: SoundStream<B>>
    (&mut self, settings: SoundStreamSettings, stream: &mut T) {
        let mut ready = 0;
        while ready == 0 {
            ready = self.stream.get_stream_write_available();
        }
        //let empty_buffer = Vec::from_elem(settings.buffer_size(), 0f32);
        //let mut read: Vec<f32> = empty_buffer.clone();
        self.read(settings, stream);
        let mut write: B = DspBuffer::zeroed();
        self.write(&mut write, settings, stream);
    }

    /// Read audio in from stream.
    pub fn read<B: DspBuffer, T: SoundStream<B>>
    (&self, settings: SoundStreamSettings, stream: &mut T) {
        match self.stream.read(settings.frames as u32) {
            Ok(in_buffer) => {
                stream.audio_in(&in_buffer, settings);
            },
            Err(err) => {
                panic!(format!("Portaudio error read : {}", pa::get_error_text(err)));
            }
        }
    }

    /// Write audio to stream
    pub fn write<B: DspBuffer, T: SoundStream<B>>
    (&mut self, buffer: &mut B, settings: SoundStreamSettings, stream: &mut T) {
        stream.audio_out(buffer, settings);
        /*
        println!("OUT OF AUDIO_OUT, {}", buffer.len());
        let mut write = Vec::with_capacity(buffer.len());
        println!("OUT OF AUDIO_OUTx, {}", write.capacity());
        for i in range(0u, buffer.len()) {
            println!("z");
            write.push(buffer.val(i));
        }
        */

        //let write: Vec<f32> = buffer.iter().map(|f| { println!("z"); *f }).collect();
        self.stream.write(buffer.to_vec(), settings.frames as u32);
    }

    /// Start the audio stream.
    pub fn start(&mut self) {
        let err = self.stream.start();
        println!("Portaudio Start Stream : {}", pa::get_error_text(err));
    }

    /// Stop the audio stream.
    pub fn stop(&mut self) {
        let mut err = types::PaNotInitialized;
        println!("Portaudio [PaNotInitialized msg] : {}", err);
        err = self.stream.close();
        println!("Portaudio Closing Stream : {}", pa::get_error_text(err));
        println!("Portaudio Termination Message : {}", pa::get_error_text(pa::terminate()));
    }

}

/// Ensure that the stream closes properly upon object destruction.
impl Drop for StreamPA {
    fn drop(&mut self) {
        if self.is_streaming {
            self.stop();
        }
    }
}

<commit_msg>Updating to latest rust-portaudio<commit_after>//! PortAudio backend!

use buffer::DspBuffer;
use portaudio::{ types, pa };
use portaudio::error::Error;
use sound_stream::SoundStream;
use sound_stream_settings::SoundStreamSettings;

/// PortAudio Stream Parameters (required to setup stream).
pub struct StreamParamsPA {
    input: types::PaStreamParameters,
    output: types::PaStreamParameters,
}

/// PortAudio Stream (for reading from and writing to real-time audio stream).
pub struct StreamPA {
    stream: pa::PaStream<f32>,
    pub is_streaming: bool
}

fn get_result_text(res: Result<(), Error>) -> String {
    let err = match res {
        Ok(()) => Error::NoError,
        Err(e) => e,
    };
    pa::get_error_text(err)
}

/// The parameters required to set up the PortAudio stream.
impl StreamParamsPA {

    /// Creates the port audio stream parameters.
    pub fn new(channels: u16) -> StreamParamsPA {
        let res = pa::initialize();
        println!("Portaudio init error : {}", get_result_text(res));

        println!("Creating StreamParamsPA");
        let def_input = pa::device::get_default_input();
        let def_output = pa::device::get_default_output();

        println!("Creating input");
        let stream_params_in = types::PaStreamParameters {
            device: def_input,
            channel_count: channels as i32,
            sample_format: types::PaFloat32,
            suggested_latency: pa::device::get_info(def_input).unwrap().default_low_input_latency
        };
        println!("Creating output");
        let stream_params_out = types::PaStreamParameters {
            device: def_output,
            channel_count: channels as i32,
            sample_format: types::PaFloat32,
            suggested_latency: pa::device::get_info(def_output).unwrap().default_low_output_latency
        };

        StreamParamsPA {
            input: stream_params_in,
            output: stream_params_out
        }
    }

}

impl StreamPA {

    /// Constructor for the portaudio stream.
    pub fn new() -> StreamPA {
        StreamPA {
            stream: pa::PaStream::new(types::PaFloat32),
            is_streaming: true
        }
    }

    /// Setup the portaudio stream.
    pub fn setup(&mut self, settings: SoundStreamSettings) {
        let params = StreamParamsPA::new(settings.channels);
        self.stream.open(Some(&params.input),
                         Some(&params.output),
                         settings.samples_per_sec as f64,
                         settings.frames as u32,
                         types::PaClipOff);
    }

    /// Performs the audio read/write.
    pub fn callback<B: DspBuffer, T: SoundStream<B>>
    (&mut self, settings: SoundStreamSettings, stream: &mut T) {
        let mut ready = 0;
        while ready == 0 {
            ready = self.stream.get_stream_write_available();
        }
        //let empty_buffer = Vec::from_elem(settings.buffer_size(), 0f32);
        //let mut read: Vec<f32> = empty_buffer.clone();
        self.read(settings, stream);
        let mut write: B = DspBuffer::zeroed();
        self.write(&mut write, settings, stream);
    }

    /// Read audio in from stream.
    pub fn read<B: DspBuffer, T: SoundStream<B>>
    (&self, settings: SoundStreamSettings, stream: &mut T) {
        match self.stream.read(settings.frames as u32) {
            Ok(in_buffer) => {
                stream.audio_in(&in_buffer, settings);
            },
            Err(err) => {
                panic!(format!("Portaudio error read : {}", pa::get_error_text(err)));
            }
        }
    }

    /// Write audio to stream
    pub fn write<B: DspBuffer, T: SoundStream<B>>
    (&mut self, buffer: &mut B, settings: SoundStreamSettings, stream: &mut T) {
        stream.audio_out(buffer, settings);
        /*
        println!("OUT OF AUDIO_OUT, {}", buffer.len());
        let mut write = Vec::with_capacity(buffer.len());
        println!("OUT OF AUDIO_OUTx, {}", write.capacity());
        for i in range(0u, buffer.len()) {
            println!("z");
            write.push(buffer.val(i));
        }
        */

        //let write: Vec<f32> = buffer.iter().map(|f| { println!("z"); *f }).collect();
        self.stream.write(buffer.to_vec(), settings.frames as u32);
    }

    /// Start the audio stream.
    pub fn start(&mut self) {
        let res = self.stream.start();
        println!("Portaudio Start Stream : {}", get_result_text(res));
    }

    /// Stop the audio stream.
    pub fn stop(&mut self) {
        let mut err = Error::NotInitialized;
        println!("Portaudio [NotInitialized msg] : {}", pa::get_error_text(err));
        let res = self.stream.close();
        println!("Portaudio Closing Stream : {}", get_result_text(res));
        let res = pa::terminate();
        println!("Portaudio Termination Message : {}", get_result_text(res));
    }

}

/// Ensure that the stream closes properly upon object destruction.
impl Drop for StreamPA {
    fn drop(&mut self) {
        if self.is_streaming {
            self.stop();
        }
    }
}

<|endoftext|>


<commit_before>use std::marker::PhantomData;
use super::context::Context;
use super::vertex_data::{VertexData, VertexBytes, VertexAttribBinder};
use super::index_data::{IndexDatum};
use super::buffer::{Buffer, BufferBinding,
                    ArrayBufferBinding, ElementArrayBufferBinding};
use super::types::DrawingMode;

pub struct VertexBuffer<T: VertexData> {
    pub attrib_binder: Option<T::Binder>,
    buffer: Buffer,
    count: usize,
    phantom: PhantomData<*const T>
}

impl<T: VertexData> VertexBuffer<T> {
    pub fn build_attrib_binder(&self)
        -> <T::Binder as VertexAttribBinder>::Builder
    {
        T::build_attrib_binder()
    }

    pub fn bind(&self, gl_buffer: &ArrayBufferBinding) -> Result<(), ()> {
        match self.attrib_binder {
            Some(ref binder) => {
                binder.bind(gl_buffer);
                Ok(())
            },
            None => { Err(()) }
        }
    }

    pub fn buffer(&self) -> &Buffer {
        &self.buffer
    }

    pub fn buffer_mut(&mut self) -> &mut Buffer {
        &mut self.buffer
    }
}

pub struct VertexBufferBinding<'a, T: VertexData>
    where T: 'a, T::Binder: 'a
{
    gl_buffer: ArrayBufferBinding<'a>,
    vbo: &'a mut VertexBuffer<T>
}

impl<'a, T: VertexData> VertexBufferBinding<'a, T>
    where T: 'a, T::Binder: 'a
{
    pub fn new(gl_buffer: ArrayBufferBinding<'a>, vbo: &'a mut VertexBuffer<T>)
        -> Self
    {
        VertexBufferBinding {
            gl_buffer: gl_buffer,
            vbo: vbo
        }
    }

    pub fn buffer_data(&mut self, data: &[T], usage: super::BufferDataUsage)
        where [T]: VertexBytes
    {
        self.vbo.count = data.len();
        self.gl_buffer.buffer_bytes(data.vertex_bytes(), usage);
    }

    pub fn draw_arrays_range(&self,
                             mode: DrawingMode,
                             start: u32,
                             length: usize)
    {
        debug_assert!((start as usize) + length <= self.vbo.count);

        unsafe {
            self.gl_buffer.draw_arrays_range(mode, start, length);
        }
    }

    pub fn draw_arrays(&self, mode: DrawingMode) {
        unsafe {
            self.gl_buffer.draw_arrays_range(mode, 0, self.vbo.count);
        }
    }
}

impl Context {
    pub fn new_vertex_buffer<T: VertexData>(&self) -> VertexBuffer<T> {
        VertexBuffer {
            attrib_binder: None,
            buffer: self.gen_buffer(),
            count: 0,
            phantom: PhantomData
        }
    }
}

pub struct IndexBuffer<T: IndexDatum> {
    buffer: Buffer,
    count: usize,
    phantom: PhantomData<*const T>
}

impl<T: IndexDatum> IndexBuffer<T> {
    pub fn buffer(&self) -> &Buffer {
        &self.buffer
    }

    pub fn buffer_mut(&mut self) -> &mut Buffer {
        &mut self.buffer
    }
}

pub struct IndexBufferBinding<'a, T: IndexDatum + 'a> {
    gl_buffer: ElementArrayBufferBinding<'a>,
    ibo: &'a mut IndexBuffer<T>
}

impl Context {
    pub fn new_index_buffer<T: IndexDatum>(&self) -> IndexBuffer<T> {
        IndexBuffer {
            buffer: self.gen_buffer(),
            count: 0,
            phantom: PhantomData
        }
    }
}

#[macro_export]
macro_rules! bind_attrib_pointers {
    ($gl:expr, $vbo:expr, {
        $($field_name:ident => $field_attrib:expr),*
    }) => {
        {
            let vbo = $vbo;
            let binder = vbo.build_attrib_binder()
                            $(.$field_name($field_attrib))*
                            .unwrap($gl);
            vbo.attrib_binder = Some(binder)
        }
    }
}

#[macro_export]
macro_rules! bind_vertex_buffer {
    ($gl:expr, $vbo:expr) => {
        {
            let vbo = $vbo;

            let gl_buffer = bind_array_buffer!($gl, vbo.buffer_mut());
            vbo.bind(&gl_buffer).unwrap();
            $crate::VertexBufferBinding::new(gl_buffer, vbo)
        }
    }
}
<commit_msg>Add `IndexBufferBinding::new()`<commit_after>use std::marker::PhantomData;
use super::context::Context;
use super::vertex_data::{VertexData, VertexBytes, VertexAttribBinder};
use super::index_data::{IndexDatum};
use super::buffer::{Buffer, BufferBinding,
                    ArrayBufferBinding, ElementArrayBufferBinding};
use super::types::DrawingMode;

pub struct VertexBuffer<T: VertexData> {
    pub attrib_binder: Option<T::Binder>,
    buffer: Buffer,
    count: usize,
    phantom: PhantomData<*const T>
}

impl<T: VertexData> VertexBuffer<T> {
    pub fn build_attrib_binder(&self)
        -> <T::Binder as VertexAttribBinder>::Builder
    {
        T::build_attrib_binder()
    }

    pub fn bind(&self, gl_buffer: &ArrayBufferBinding) -> Result<(), ()> {
        match self.attrib_binder {
            Some(ref binder) => {
                binder.bind(gl_buffer);
                Ok(())
            },
            None => { Err(()) }
        }
    }

    pub fn buffer(&self) -> &Buffer {
        &self.buffer
    }

    pub fn buffer_mut(&mut self) -> &mut Buffer {
        &mut self.buffer
    }
}

pub struct VertexBufferBinding<'a, T: VertexData>
    where T: 'a, T::Binder: 'a
{
    gl_buffer: ArrayBufferBinding<'a>,
    vbo: &'a mut VertexBuffer<T>
}

impl<'a, T: VertexData> VertexBufferBinding<'a, T>
    where T: 'a, T::Binder: 'a
{
    pub fn new(gl_buffer: ArrayBufferBinding<'a>, vbo: &'a mut VertexBuffer<T>)
        -> Self
    {
        VertexBufferBinding {
            gl_buffer: gl_buffer,
            vbo: vbo
        }
    }

    pub fn buffer_data(&mut self, data: &[T], usage: super::BufferDataUsage)
        where [T]: VertexBytes
    {
        self.vbo.count = data.len();
        self.gl_buffer.buffer_bytes(data.vertex_bytes(), usage);
    }

    pub fn draw_arrays_range(&self,
                             mode: DrawingMode,
                             start: u32,
                             length: usize)
    {
        debug_assert!((start as usize) + length <= self.vbo.count);

        unsafe {
            self.gl_buffer.draw_arrays_range(mode, start, length);
        }
    }

    pub fn draw_arrays(&self, mode: DrawingMode) {
        unsafe {
            self.gl_buffer.draw_arrays_range(mode, 0, self.vbo.count);
        }
    }
}

impl Context {
    pub fn new_vertex_buffer<T: VertexData>(&self) -> VertexBuffer<T> {
        VertexBuffer {
            attrib_binder: None,
            buffer: self.gen_buffer(),
            count: 0,
            phantom: PhantomData
        }
    }
}

pub struct IndexBuffer<T: IndexDatum> {
    buffer: Buffer,
    count: usize,
    phantom: PhantomData<*const T>
}

impl<T: IndexDatum> IndexBuffer<T> {
    pub fn buffer(&self) -> &Buffer {
        &self.buffer
    }

    pub fn buffer_mut(&mut self) -> &mut Buffer {
        &mut self.buffer
    }
}

pub struct IndexBufferBinding<'a, T: IndexDatum + 'a> {
    gl_buffer: ElementArrayBufferBinding<'a>,
    ibo: &'a mut IndexBuffer<T>
}

impl<'a, T: IndexDatum + 'a> IndexBufferBinding<'a, T> {
    pub fn new(gl_buffer: ElementArrayBufferBinding<'a>,
               ibo: &'a mut IndexBuffer<T>)
        -> Self
    {
        IndexBufferBinding {
            gl_buffer: gl_buffer,
            ibo: ibo
        }
    }
}

impl Context {
    pub fn new_index_buffer<T: IndexDatum>(&self) -> IndexBuffer<T> {
        IndexBuffer {
            buffer: self.gen_buffer(),
            count: 0,
            phantom: PhantomData
        }
    }
}

#[macro_export]
macro_rules! bind_attrib_pointers {
    ($gl:expr, $vbo:expr, {
        $($field_name:ident => $field_attrib:expr),*
    }) => {
        {
            let vbo = $vbo;
            let binder = vbo.build_attrib_binder()
                            $(.$field_name($field_attrib))*
                            .unwrap($gl);
            vbo.attrib_binder = Some(binder)
        }
    }
}

#[macro_export]
macro_rules! bind_vertex_buffer {
    ($gl:expr, $vbo:expr) => {
        {
            let vbo = $vbo;

            let gl_buffer = bind_array_buffer!($gl, vbo.buffer_mut());
            vbo.bind(&gl_buffer).unwrap();
            $crate::VertexBufferBinding::new(gl_buffer, vbo)
        }
    }
}
<|endoftext|>


<commit_before>//! Defines the `IntoIter` owned iterator for arrays.

use crate::{
    fmt,
    iter::{self, ExactSizeIterator, FusedIterator, TrustedLen},
    mem::{self, MaybeUninit},
    ops::Range,
    ptr,
};

/// A by-value [array] iterator.
#[stable(feature = "array_value_iter", since = "1.51.0")]
pub struct IntoIter<T, const N: usize> {
    /// This is the array we are iterating over.
    ///
    /// Elements with index `i` where `alive.start <= i < alive.end` have not
    /// been yielded yet and are valid array entries. Elements with indices `i
    /// < alive.start` or `i >= alive.end` have been yielded already and must
    /// not be accessed anymore! Those dead elements might even be in a
    /// completely uninitialized state!
    ///
    /// So the invariants are:
    /// - `data[alive]` is alive (i.e. contains valid elements)
    /// - `data[..alive.start]` and `data[alive.end..]` are dead (i.e. the
    ///   elements were already read and must not be touched anymore!)
    data: [MaybeUninit<T>; N],

    /// The elements in `data` that have not been yielded yet.
    ///
    /// Invariants:
    /// - `alive.start <= alive.end`
    /// - `alive.end <= N`
    alive: Range<usize>,
}

impl<T, const N: usize> IntoIter<T, N> {
    /// Creates a new iterator over the given `array`.
    ///
    /// *Note*: this method might be deprecated in the future,
    /// after [`IntoIterator` is implemented for arrays][array-into-iter].
    ///
    /// # Examples
    ///
    /// ```
    /// use std::array;
    ///
    /// for value in array::IntoIter::new([1, 2, 3, 4, 5]) {
    ///     // The type of `value` is a `i32` here, instead of `&i32`
    ///     let _: i32 = value;
    /// }
    /// ```
    /// [array-into-iter]: https://github.com/rust-lang/rust/pull/65819
    #[stable(feature = "array_value_iter", since = "1.51.0")]
    pub fn new(array: [T; N]) -> Self {
        // SAFETY: The transmute here is actually safe. The docs of `MaybeUninit`
        // promise:
        //
        // > `MaybeUninit<T>` is guaranteed to have the same size and alignment
        // > as `T`.
        //
        // The docs even show a transmute from an array of `MaybeUninit<T>` to
        // an array of `T`.
        //
        // With that, this initialization satisfies the invariants.

        // FIXME(LukasKalbertodt): actually use `mem::transmute` here, once it
        // works with const generics:
        //     `mem::transmute::<[T; N], [MaybeUninit<T>; N]>(array)`
        //
        // Until then, we can use `mem::transmute_copy` to create a bitwise copy
        // as a different type, then forget `array` so that it is not dropped.
        unsafe {
            let iter = Self { data: mem::transmute_copy(&array), alive: 0..N };
            mem::forget(array);
            iter
        }
    }

    /// Returns an immutable slice of all elements that have not been yielded
    /// yet.
    #[stable(feature = "array_value_iter", since = "1.51.0")]
    pub fn as_slice(&self) -> &[T] {
        // SAFETY: We know that all elements within `alive` are properly initialized.
        unsafe {
            let slice = self.data.get_unchecked(self.alive.clone());
            MaybeUninit::slice_assume_init_ref(slice)
        }
    }

    /// Returns a mutable slice of all elements that have not been yielded yet.
    #[stable(feature = "array_value_iter", since = "1.51.0")]
    pub fn as_mut_slice(&mut self) -> &mut [T] {
        // SAFETY: We know that all elements within `alive` are properly initialized.
        unsafe {
            let slice = self.data.get_unchecked_mut(self.alive.clone());
            MaybeUninit::slice_assume_init_mut(slice)
        }
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> Iterator for IntoIter<T, N> {
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        // Get the next index from the front.
        //
        // Increasing `alive.start` by 1 maintains the invariant regarding
        // `alive`. However, due to this change, for a short time, the alive
        // zone is not `data[alive]` anymore, but `data[idx..alive.end]`.
        self.alive.next().map(|idx| {
            // Read the element from the array.
            // SAFETY: `idx` is an index into the former "alive" region of the
            // array. Reading this element means that `data[idx]` is regarded as
            // dead now (i.e. do not touch). As `idx` was the start of the
            // alive-zone, the alive zone is now `data[alive]` again, restoring
            // all invariants.
            unsafe { self.data.get_unchecked(idx).assume_init_read() }
        })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.len();
        (len, Some(len))
    }

    #[inline]
    fn fold<Acc, Fold>(mut self, init: Acc, mut fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        let data = &mut self.data;
        (&mut self.alive)
            .try_fold::<_, _, Result<_, !>>(init, |acc, idx| {
                // SAFETY: idx is obtained by folding over the `alive` range, which implies the
                // value is currently considered alive but as the range is being consumed each value
                // we read here will only be read once and then considered dead.
                Ok(fold(acc, unsafe { data.get_unchecked(idx).assume_init_read() }))
            })
            .unwrap()
    }

    fn count(self) -> usize {
        self.len()
    }

    fn last(mut self) -> Option<Self::Item> {
        self.next_back()
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
    fn next_back(&mut self) -> Option<Self::Item> {
        // Get the next index from the back.
        //
        // Decreasing `alive.end` by 1 maintains the invariant regarding
        // `alive`. However, due to this change, for a short time, the alive
        // zone is not `data[alive]` anymore, but `data[alive.start..=idx]`.
        self.alive.next_back().map(|idx| {
            // Read the element from the array.
            // SAFETY: `idx` is an index into the former "alive" region of the
            // array. Reading this element means that `data[idx]` is regarded as
            // dead now (i.e. do not touch). As `idx` was the end of the
            // alive-zone, the alive zone is now `data[alive]` again, restoring
            // all invariants.
            unsafe { self.data.get_unchecked(idx).assume_init_read() }
        })
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> Drop for IntoIter<T, N> {
    fn drop(&mut self) {
        // SAFETY: This is safe: `as_mut_slice` returns exactly the sub-slice
        // of elements that have not been moved out yet and that remain
        // to be dropped.
        unsafe { ptr::drop_in_place(self.as_mut_slice()) }
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> ExactSizeIterator for IntoIter<T, N> {
    fn len(&self) -> usize {
        // Will never underflow due to the invariant `alive.start <=
        // alive.end`.
        self.alive.end - self.alive.start
    }
    fn is_empty(&self) -> bool {
        self.alive.is_empty()
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> FusedIterator for IntoIter<T, N> {}

// The iterator indeed reports the correct length. The number of "alive"
// elements (that will still be yielded) is the length of the range `alive`.
// This range is decremented in length in either `next` or `next_back`. It is
// always decremented by 1 in those methods, but only if `Some(_)` is returned.
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
unsafe impl<T, const N: usize> TrustedLen for IntoIter<T, N> {}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T: Clone, const N: usize> Clone for IntoIter<T, N> {
    fn clone(&self) -> Self {
        // Note, we don't really need to match the exact same alive range, so
        // we can just clone into offset 0 regardless of where `self` is.
        let mut new = Self { data: MaybeUninit::uninit_array(), alive: 0..0 };

        // Clone all alive elements.
        for (src, dst) in iter::zip(self.as_slice(), &mut new.data) {
            // Write a clone into the new array, then update its alive range.
            // If cloning panics, we'll correctly drop the previous items.
            dst.write(src.clone());
            new.alive.end += 1;
        }

        new
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T: fmt::Debug, const N: usize> fmt::Debug for IntoIter<T, N> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // Only print the elements that were not yielded yet: we cannot
        // access the yielded elements anymore.
        f.debug_tuple("IntoIter").field(&self.as_slice()).finish()
    }
}
<commit_msg>from review: add a comment why try_fold was chosen instead of fold<commit_after>//! Defines the `IntoIter` owned iterator for arrays.

use crate::{
    fmt,
    iter::{self, ExactSizeIterator, FusedIterator, TrustedLen},
    mem::{self, MaybeUninit},
    ops::Range,
    ptr,
};

/// A by-value [array] iterator.
#[stable(feature = "array_value_iter", since = "1.51.0")]
pub struct IntoIter<T, const N: usize> {
    /// This is the array we are iterating over.
    ///
    /// Elements with index `i` where `alive.start <= i < alive.end` have not
    /// been yielded yet and are valid array entries. Elements with indices `i
    /// < alive.start` or `i >= alive.end` have been yielded already and must
    /// not be accessed anymore! Those dead elements might even be in a
    /// completely uninitialized state!
    ///
    /// So the invariants are:
    /// - `data[alive]` is alive (i.e. contains valid elements)
    /// - `data[..alive.start]` and `data[alive.end..]` are dead (i.e. the
    ///   elements were already read and must not be touched anymore!)
    data: [MaybeUninit<T>; N],

    /// The elements in `data` that have not been yielded yet.
    ///
    /// Invariants:
    /// - `alive.start <= alive.end`
    /// - `alive.end <= N`
    alive: Range<usize>,
}

impl<T, const N: usize> IntoIter<T, N> {
    /// Creates a new iterator over the given `array`.
    ///
    /// *Note*: this method might be deprecated in the future,
    /// after [`IntoIterator` is implemented for arrays][array-into-iter].
    ///
    /// # Examples
    ///
    /// ```
    /// use std::array;
    ///
    /// for value in array::IntoIter::new([1, 2, 3, 4, 5]) {
    ///     // The type of `value` is a `i32` here, instead of `&i32`
    ///     let _: i32 = value;
    /// }
    /// ```
    /// [array-into-iter]: https://github.com/rust-lang/rust/pull/65819
    #[stable(feature = "array_value_iter", since = "1.51.0")]
    pub fn new(array: [T; N]) -> Self {
        // SAFETY: The transmute here is actually safe. The docs of `MaybeUninit`
        // promise:
        //
        // > `MaybeUninit<T>` is guaranteed to have the same size and alignment
        // > as `T`.
        //
        // The docs even show a transmute from an array of `MaybeUninit<T>` to
        // an array of `T`.
        //
        // With that, this initialization satisfies the invariants.

        // FIXME(LukasKalbertodt): actually use `mem::transmute` here, once it
        // works with const generics:
        //     `mem::transmute::<[T; N], [MaybeUninit<T>; N]>(array)`
        //
        // Until then, we can use `mem::transmute_copy` to create a bitwise copy
        // as a different type, then forget `array` so that it is not dropped.
        unsafe {
            let iter = Self { data: mem::transmute_copy(&array), alive: 0..N };
            mem::forget(array);
            iter
        }
    }

    /// Returns an immutable slice of all elements that have not been yielded
    /// yet.
    #[stable(feature = "array_value_iter", since = "1.51.0")]
    pub fn as_slice(&self) -> &[T] {
        // SAFETY: We know that all elements within `alive` are properly initialized.
        unsafe {
            let slice = self.data.get_unchecked(self.alive.clone());
            MaybeUninit::slice_assume_init_ref(slice)
        }
    }

    /// Returns a mutable slice of all elements that have not been yielded yet.
    #[stable(feature = "array_value_iter", since = "1.51.0")]
    pub fn as_mut_slice(&mut self) -> &mut [T] {
        // SAFETY: We know that all elements within `alive` are properly initialized.
        unsafe {
            let slice = self.data.get_unchecked_mut(self.alive.clone());
            MaybeUninit::slice_assume_init_mut(slice)
        }
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> Iterator for IntoIter<T, N> {
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        // Get the next index from the front.
        //
        // Increasing `alive.start` by 1 maintains the invariant regarding
        // `alive`. However, due to this change, for a short time, the alive
        // zone is not `data[alive]` anymore, but `data[idx..alive.end]`.
        self.alive.next().map(|idx| {
            // Read the element from the array.
            // SAFETY: `idx` is an index into the former "alive" region of the
            // array. Reading this element means that `data[idx]` is regarded as
            // dead now (i.e. do not touch). As `idx` was the start of the
            // alive-zone, the alive zone is now `data[alive]` again, restoring
            // all invariants.
            unsafe { self.data.get_unchecked(idx).assume_init_read() }
        })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = self.len();
        (len, Some(len))
    }

    #[inline]
    fn fold<Acc, Fold>(mut self, init: Acc, mut fold: Fold) -> Acc
    where
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        let data = &mut self.data;
        // FIXME: This uses try_fold(&mut iter) instead of fold(iter) because the latter
        //  would go through the blanket `impl Iterator for &mut I` implementation
        //  which lacks inline annotations on its methods and adding those would be a larger
        //  perturbation than using try_fold here.
        //  Whether it would be beneficial to add those annotations should be investigated separately.
        (&mut self.alive)
            .try_fold::<_, _, Result<_, !>>(init, |acc, idx| {
                // SAFETY: idx is obtained by folding over the `alive` range, which implies the
                // value is currently considered alive but as the range is being consumed each value
                // we read here will only be read once and then considered dead.
                Ok(fold(acc, unsafe { data.get_unchecked(idx).assume_init_read() }))
            })
            .unwrap()
    }

    fn count(self) -> usize {
        self.len()
    }

    fn last(mut self) -> Option<Self::Item> {
        self.next_back()
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
    fn next_back(&mut self) -> Option<Self::Item> {
        // Get the next index from the back.
        //
        // Decreasing `alive.end` by 1 maintains the invariant regarding
        // `alive`. However, due to this change, for a short time, the alive
        // zone is not `data[alive]` anymore, but `data[alive.start..=idx]`.
        self.alive.next_back().map(|idx| {
            // Read the element from the array.
            // SAFETY: `idx` is an index into the former "alive" region of the
            // array. Reading this element means that `data[idx]` is regarded as
            // dead now (i.e. do not touch). As `idx` was the end of the
            // alive-zone, the alive zone is now `data[alive]` again, restoring
            // all invariants.
            unsafe { self.data.get_unchecked(idx).assume_init_read() }
        })
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> Drop for IntoIter<T, N> {
    fn drop(&mut self) {
        // SAFETY: This is safe: `as_mut_slice` returns exactly the sub-slice
        // of elements that have not been moved out yet and that remain
        // to be dropped.
        unsafe { ptr::drop_in_place(self.as_mut_slice()) }
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> ExactSizeIterator for IntoIter<T, N> {
    fn len(&self) -> usize {
        // Will never underflow due to the invariant `alive.start <=
        // alive.end`.
        self.alive.end - self.alive.start
    }
    fn is_empty(&self) -> bool {
        self.alive.is_empty()
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T, const N: usize> FusedIterator for IntoIter<T, N> {}

// The iterator indeed reports the correct length. The number of "alive"
// elements (that will still be yielded) is the length of the range `alive`.
// This range is decremented in length in either `next` or `next_back`. It is
// always decremented by 1 in those methods, but only if `Some(_)` is returned.
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
unsafe impl<T, const N: usize> TrustedLen for IntoIter<T, N> {}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T: Clone, const N: usize> Clone for IntoIter<T, N> {
    fn clone(&self) -> Self {
        // Note, we don't really need to match the exact same alive range, so
        // we can just clone into offset 0 regardless of where `self` is.
        let mut new = Self { data: MaybeUninit::uninit_array(), alive: 0..0 };

        // Clone all alive elements.
        for (src, dst) in iter::zip(self.as_slice(), &mut new.data) {
            // Write a clone into the new array, then update its alive range.
            // If cloning panics, we'll correctly drop the previous items.
            dst.write(src.clone());
            new.alive.end += 1;
        }

        new
    }
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T: fmt::Debug, const N: usize> fmt::Debug for IntoIter<T, N> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // Only print the elements that were not yielded yet: we cannot
        // access the yielded elements anymore.
        f.debug_tuple("IntoIter").field(&self.as_slice()).finish()
    }
}
<|endoftext|>


<commit_before>#[macro_use(crate_version, crate_authors)]
extern crate clap;
extern crate inspirer;

use clap::{App, Arg};

use std::fs::File;
use std::io::{Read, BufReader};
use std::io::{Write, BufWriter};

fn main() {

    // Define CLI
    let matches = App::new("aux2bib")
                        .version(crate_version!())
                        .author(crate_authors!(",\n"))
                        .about("gets BibTeX keys from Inspire")
                        .arg(Arg::with_name("INPUT")
                             .help("Sets the input file to use")
                             .index(1))
                        .arg(Arg::with_name("OUTPUT")
                            .help("Sets the output file to use")
                            .index(2))
                        .get_matches();

    // Get input from specified file or stdin
    let mut input_data = String::new();

    match matches.value_of("INPUT") {
        Some(input_file_name) => {
            println!("Reading from file: {}", input_file_name);

            let f = File::open(input_file_name).expect("File not found");
            let mut reader = BufReader::new(f);
            reader.read_to_string(&mut input_data).unwrap();
        },
        None => {
            println!("Reading from stdin");

            let stdin = std::io::stdin();
            let stdin = stdin.lock();

            let mut reader = BufReader::new(stdin);
            reader.read_to_string(&mut input_data).unwrap();
        }
    }

    // Extract BibTeX tags from document
    let keys = inspirer::aux2key(input_data);

    // Retrieve BibTeX entries from inspire.net
    println!("Retrieving entries...");
    let mut bibtex_entries: Vec<String> = Vec::new();
    for key in keys {
        if let Some(bibtex_entry) = inspirer::fetch_bibtex_with_key(key) {
            bibtex_entries.push(bibtex_entry);
        }
    }

    // Write BibTeX entries to file or stdout

    let mut stdout = std::io::stdout();
    let mut output_file: std::fs::File;

    let writer: &mut Write = match matches.value_of("OUTPUT") {
        Some(file_name) => {
            println!("Writing to file: {}", file_name);
            output_file = File::create(file_name).unwrap();
            &mut output_file
        },
        None            => {
            println!("Writing to stdout");
            // stdout.lock();
            &mut stdout
        },
    };

    let mut writer = BufWriter::new(writer);

    for bibtex_entry in bibtex_entries {
        writer.write(&bibtex_entry.as_bytes()).unwrap();
    }

    writer.flush().unwrap();
}
<commit_msg>aux2bib: Redo loading of input with trait-objects<commit_after>#[macro_use(crate_version, crate_authors)]
extern crate clap;
extern crate inspirer;

use clap::{App, Arg};

use std::fs::File;
use std::io::{Read, BufReader};
use std::io::{Write, BufWriter};

fn main() {

    // Define CLI
    let matches = App::new("aux2bib")
                        .version(crate_version!())
                        .author(crate_authors!(",\n"))
                        .about("gets BibTeX keys from Inspire")
                        .arg(Arg::with_name("INPUT")
                             .help("Sets the input file to use")
                             .index(1))
                        .arg(Arg::with_name("OUTPUT")
                            .help("Sets the output file to use")
                            .index(2))
                        .get_matches();

    // Get input from specified file or stdin
    let mut input_data = String::new();

    let mut input_file: File;
    let mut stdin = std::io::stdin();

    let reader: &mut Read = match matches.value_of("INPUT") {
        Some(file_name) => {
            println!("Reading from file: {}", file_name);
            input_file = File::open(file_name).expect("File not found");
            &mut input_file
        },
        None => {
            println!("Reading from stdin");
            &mut stdin
        },
    };
    let mut reader = BufReader::new(reader);
    reader.read_to_string(&mut input_data).unwrap();

    // Extract BibTeX tags from document
    let keys = inspirer::aux2key(input_data);

    // Retrieve BibTeX entries from inspire.net
    println!("Retrieving entries...");
    let mut bibtex_entries: Vec<String> = Vec::new();
    for key in keys {
        if let Some(bibtex_entry) = inspirer::fetch_bibtex_with_key(key) {
            bibtex_entries.push(bibtex_entry);
        }
    }

    // Write BibTeX entries to file or stdout

    let mut stdout = std::io::stdout();
    let mut output_file: std::fs::File;

    let writer: &mut Write = match matches.value_of("OUTPUT") {
        Some(file_name) => {
            println!("Writing to file: {}", file_name);
            output_file = File::create(file_name).unwrap();
            &mut output_file
        },
        None            => {
            println!("Writing to stdout");
            // stdout.lock();
            &mut stdout
        },
    };

    let mut writer = BufWriter::new(writer);

    for bibtex_entry in bibtex_entries {
        writer.write(&bibtex_entry.as_bytes()).unwrap();
    }

    writer.flush().unwrap();
}
<|endoftext|>


<commit_before>#![crate_name = "bindgen"]
#![crate_type = "bin"]

extern crate bindgen;
#[macro_use] extern crate log;
extern crate syntax;

use bindgen::{Bindings, BindgenOptions, LinkType, Logger};
use std::{io, os, path};
use std::default::Default;
use std::io::fs;

struct StdLogger;

impl Logger for StdLogger {
    fn error(&self, msg: &str) {
        error!("{}", msg);
    }

    fn warn(&self, msg: &str) {
        warn!("{}", msg);
    }
}

enum ParseResult {
    CmdUsage,
    ParseOk(BindgenOptions, Box<io::Writer+'static>),
    ParseErr(String)
}

fn parse_args(args: &[String]) -> ParseResult {
    let args_len = args.len();

    let mut options: BindgenOptions = Default::default();
    let mut out = Box::new(io::BufferedWriter::new(io::stdout())) as Box<io::Writer>;

    if args_len == 0 {
        return ParseResult::CmdUsage;
    }

    let mut ix = 0us;
    while ix < args_len {
        if args[ix].len() > 2 && args[ix].as_slice().slice_to(2) == "-l" {
            options.links.push((args[ix].as_slice().slice_from(2).to_string(), LinkType::Default));
            ix += 1;
        } else {
            match args[ix].as_slice() {
                "--help" | "-h" => {
                    return ParseResult::CmdUsage;
                }
                "-emit-clang-ast" => {
                    options.emit_ast = true;
                    ix += 1;
                }
                "-o" => {
                    if ix + 1 >= args_len {
                        return ParseResult::ParseErr("Missing output filename".to_string());
                    }
                    let path = path::Path::new(args[ix + 1].clone());
                    match fs::File::create(&path) {
                        Ok(f) => { out = Box::new(io::BufferedWriter::new(f)) as Box<io::Writer>; }
                        Err(_) => { return ParseResult::ParseErr(format!("Open {} failed", args[ix + 1])); }
                    }
                    ix += 2;
                }
                "-l" => {
                    if ix + 1 >= args_len {
                        return ParseResult::ParseErr("Missing link name".to_string());
                    }
                    options.links.push((args[ix + 1].clone(), LinkType::Default));
                    ix += 2;
                }
                "-static-link" => {
                    if ix + 1 >= args_len {
                        return ParseResult::ParseErr("Missing link name".to_string());
                    }
                    options.links.push((args[ix + 1].clone(), LinkType::Static));
                    ix += 2;
                }
                "-framework-link" => {
                    if ix + 1 >= args_len {
                        return ParseResult::ParseErr("Missing link name".to_string());
                    }
                    options.links.push((args[ix + 1].clone(), LinkType::Framework));
                    ix += 2;
                }
                "-match" => {
                    if ix + 1 >= args_len {
                        return ParseResult::ParseErr("Missing match pattern".to_string());
                    }
                    options.match_pat.push(args[ix + 1].clone());
                    ix += 2;
                }
                "-builtins" => {
                    options.builtins = true;
                    ix += 1;
                }
                "-allow-unknown-types" => {
                    options.fail_on_unknown_type = false;
                    ix += 1;
                }
                "-override-enum-type" => {
                    if ix + 1 >= args_len {
                        return ParseResult::ParseErr("Missing enum type".to_string());
                    }
                    options.override_enum_ty = args[ix + 1].clone();
                    ix += 2;
                }
                _ => {
                    options.clang_args.push(args[ix].clone());
                    ix += 1;
                }
            }
        }
    }

    return ParseResult::ParseOk(options, out);
}

fn print_usage(bin: String) {
    let mut s = format!("Usage: {} [options] input.h", bin.as_slice());
    s.push_str(
"
Options:
    -h or --help               Display help message
    -l <name> or -l<name>      Link to a dynamic library, can be proivded
                               multiple times
    -static-link <name>        Link to a static library
    -framework-link <name>     Link to a framework
    -o <output.rs>             Write bindings to <output.rs> (default stdout)
    -match <name>              Only output bindings for definitions from files
                               whose name contains <name>
                               If multiple -match options are provided, files
                               matching any rule are bound to.
    -builtins                  Output bindings for builtin definitions
                               (for example __builtin_va_list)
    -allow-unknown-types       Don't fail if we encounter types we do not support,
                               instead treat them as void
    -emit-clang-ast            Output the ast (for debugging purposes)
    -override-enum-type <type> Override enum type, type name could be
                                 uchar
                                 schar
                                 ushort
                                 sshort
                                 uint
                                 sint
                                 ulong
                                 slong
                                 ulonglong
                                 slonglong

    Options other than stated above are passed to clang.
"
    );
    io::stdio::print(s.as_slice());
}

#[main]
pub fn main() {
    let mut bind_args = os::args();
    let bin = bind_args.remove(0);

    match parse_args(bind_args.as_slice()) {
        ParseResult::ParseErr(e) => panic!(e),
        ParseResult::CmdUsage => print_usage(bin),
        ParseResult::ParseOk(options, mut out) => {
            let logger = StdLogger;
            match Bindings::generate(&options, Some(&logger as &Logger), None) {
                Ok(bindings) => match bindings.write(&mut out) {
                    Ok(()) => (),
                    Err(e) => logger.error(format!("Unable to write bindings to file. {}", e).as_slice())
                },
                Err(()) => ()
            }
        }
    }
}
<commit_msg>set return code on non-panic errors<commit_after>#![crate_name = "bindgen"]
#![crate_type = "bin"]

extern crate bindgen;
#[macro_use] extern crate log;
extern crate syntax;

use bindgen::{Bindings, BindgenOptions, LinkType, Logger};
use std::{io, os, path};
use std::default::Default;
use std::io::fs;

struct StdLogger;

impl Logger for StdLogger {
    fn error(&self, msg: &str) {
        error!("{}", msg);
    }

    fn warn(&self, msg: &str) {
        warn!("{}", msg);
    }
}

enum ParseResult {
    CmdUsage,
    ParseOk(BindgenOptions, Box<io::Writer+'static>),
    ParseErr(String)
}

fn parse_args(args: &[String]) -> ParseResult {
    let args_len = args.len();

    let mut options: BindgenOptions = Default::default();
    let mut out = Box::new(io::BufferedWriter::new(io::stdout())) as Box<io::Writer>;

    if args_len == 0 {
        return ParseResult::CmdUsage;
    }

    let mut ix = 0us;
    while ix < args_len {
        if args[ix].len() > 2 && args[ix].as_slice().slice_to(2) == "-l" {
            options.links.push((args[ix].as_slice().slice_from(2).to_string(), LinkType::Default));
            ix += 1;
        } else {
            match args[ix].as_slice() {
                "--help" | "-h" => {
                    return ParseResult::CmdUsage;
                }
                "-emit-clang-ast" => {
                    options.emit_ast = true;
                    ix += 1;
                }
                "-o" => {
                    if ix + 1 >= args_len {
                        return ParseResult::ParseErr("Missing output filename".to_string());
                    }
                    let path = path::Path::new(args[ix + 1].clone());
                    match fs::File::create(&path) {
                        Ok(f) => { out = Box::new(io::BufferedWriter::new(f)) as Box<io::Writer>; }
                        Err(_) => { return ParseResult::ParseErr(format!("Open {} failed", args[ix + 1])); }
                    }
                    ix += 2;
                }
                "-l" => {
                    if ix + 1 >= args_len {
                        return ParseResult::ParseErr("Missing link name".to_string());
                    }
                    options.links.push((args[ix + 1].clone(), LinkType::Default));
                    ix += 2;
                }
                "-static-link" => {
                    if ix + 1 >= args_len {
                        return ParseResult::ParseErr("Missing link name".to_string());
                    }
                    options.links.push((args[ix + 1].clone(), LinkType::Static));
                    ix += 2;
                }
                "-framework-link" => {
                    if ix + 1 >= args_len {
                        return ParseResult::ParseErr("Missing link name".to_string());
                    }
                    options.links.push((args[ix + 1].clone(), LinkType::Framework));
                    ix += 2;
                }
                "-match" => {
                    if ix + 1 >= args_len {
                        return ParseResult::ParseErr("Missing match pattern".to_string());
                    }
                    options.match_pat.push(args[ix + 1].clone());
                    ix += 2;
                }
                "-builtins" => {
                    options.builtins = true;
                    ix += 1;
                }
                "-allow-unknown-types" => {
                    options.fail_on_unknown_type = false;
                    ix += 1;
                }
                "-override-enum-type" => {
                    if ix + 1 >= args_len {
                        return ParseResult::ParseErr("Missing enum type".to_string());
                    }
                    options.override_enum_ty = args[ix + 1].clone();
                    ix += 2;
                }
                _ => {
                    options.clang_args.push(args[ix].clone());
                    ix += 1;
                }
            }
        }
    }

    return ParseResult::ParseOk(options, out);
}

fn print_usage(bin: String) {
    let mut s = format!("Usage: {} [options] input.h", bin.as_slice());
    s.push_str(
"
Options:
    -h or --help               Display help message
    -l <name> or -l<name>      Link to a dynamic library, can be proivded
                               multiple times
    -static-link <name>        Link to a static library
    -framework-link <name>     Link to a framework
    -o <output.rs>             Write bindings to <output.rs> (default stdout)
    -match <name>              Only output bindings for definitions from files
                               whose name contains <name>
                               If multiple -match options are provided, files
                               matching any rule are bound to.
    -builtins                  Output bindings for builtin definitions
                               (for example __builtin_va_list)
    -allow-unknown-types       Don't fail if we encounter types we do not support,
                               instead treat them as void
    -emit-clang-ast            Output the ast (for debugging purposes)
    -override-enum-type <type> Override enum type, type name could be
                                 uchar
                                 schar
                                 ushort
                                 sshort
                                 uint
                                 sint
                                 ulong
                                 slong
                                 ulonglong
                                 slonglong

    Options other than stated above are passed to clang.
"
    );
    io::stdio::print(s.as_slice());
}

#[main]
pub fn main() {
    let mut bind_args = os::args();
    let bin = bind_args.remove(0);

    match parse_args(bind_args.as_slice()) {
        ParseResult::ParseErr(e) => panic!(e),
        ParseResult::CmdUsage => print_usage(bin),
        ParseResult::ParseOk(options, mut out) => {
            let logger = StdLogger;
            match Bindings::generate(&options, Some(&logger as &Logger), None) {
                Ok(bindings) => match bindings.write(&mut out) {
                    Ok(()) => (),
                    Err(e) => {
                        logger.error(format!("Unable to write bindings to file. {}", e).as_slice());
                        os::set_exit_status(-1);
                    }
                },
                Err(()) => os::set_exit_status(-1)
            }
        }
    }
}
<|endoftext|>


<commit_before>use extra::treemap::TreeMap;
use std::vec;
use std::num::abs;

use common::*;
use monomial::*;

#[deriving(Eq, Clone)]
pub struct PolyOwning<Mon> {
  coefs: ~[R],
  mons:  ~[Mon]
}

#[deriving(Eq, Clone)]
pub struct PolyBorrowing<'self,Mon> {
  coefs: &'self [R],
  mons: &'self [Mon]
}

#[deriving(Eq, Clone)]
pub struct PolyBorrowingMons<'self,Mon> {
  coefs: ~[R],
  mons: &'self [Mon]
}

impl<Mon:Monomial> PolyOwning<Mon> {

  pub fn new(coefs: ~[R], mons: ~[Mon]) -> PolyOwning<Mon> {
    match (coefs.len(), mons.len()) {
      (0,0) => fail!("Empty arrays passed to polynomial constructor."),
      (x,y) if x != y => fail!("Arrays of different lengths passed to polynomial constructor."),
      _ => PolyOwning { coefs: coefs, mons: mons }
    }
  }

  pub fn zero() -> PolyOwning<Mon> {
    let one_mon: Mon = Monomial::one();
    PolyOwning { coefs: ~[0 as R], mons: ~[one_mon] }
  }

  pub fn zero_with_capacity(n: uint) -> PolyOwning<Mon> {
    let one_mon: Mon = Monomial::one();
    let mut coefs = vec::with_capacity(n);
    let mut mons = vec::with_capacity(n);
    coefs.push(0 as R);
    mons.push(one_mon);
    PolyOwning { coefs: coefs, mons: mons }
  }

  pub fn from_polys_lcomb<P:Polynomial<Mon>>(terms: &[(R,&P)]) -> PolyOwning<Mon> {
    let mut coefs_by_mon: TreeMap<Mon,R> = TreeMap::new();
    for &(c_p, p) in terms.iter() {
      p.each_term(|(c_m, m)| {
        if c_m != 0 as R {
          let did_update = match coefs_by_mon.find_mut(&m) {
            Some(c) => { *c += c_p * c_m; true }, None => false
          };
          if !did_update {
            coefs_by_mon.insert(m, c_p * c_m);
          }
        }
      });
    }
    let mut mons:  ~[Mon] = vec::with_capacity(coefs_by_mon.len());
    let mut coefs: ~[R] = vec::with_capacity(coefs_by_mon.len());
    for (mon, coef) in coefs_by_mon.iter() {
      if *coef != 0 as R {
        mons.push(mon.clone());
        coefs.push(*coef);
      }
    }
    PolyOwning { coefs: coefs, mons: mons }
  }

}

impl<'self,Mon:Monomial> PolyBorrowing<'self,Mon> {

  pub fn new(coefs: &'self [R], mons: &'self [Mon]) -> PolyBorrowing<'self,Mon> {
    match (coefs.len(), mons.len()) {
      (0,0) => fail!("Empty arrays passed to polynomial constructor."),
      (x,y) if x != y => fail!("Arrays of different lengths passed to polynomial constructor."),
      _ => PolyBorrowing { coefs: coefs, mons: mons }
    }
  }
}

impl<'self,Mon:Monomial> PolyBorrowingMons<'self,Mon> {

  pub fn new(coefs: ~[R], mons: &'self [Mon]) -> PolyBorrowingMons<'self,Mon> {
    match (coefs.len(), mons.len()) {
      (0,0) => fail!("Empty arrays passed to polynomial constructor."),
      (x,y) if x != y => fail!("Arrays of different lengths passed to polynomial constructor."),
      _ => PolyBorrowingMons { coefs: coefs, mons: mons }
    }
  }
}

pub trait Polynomial<Mon>: ToStr {

  fn num_terms(&self) -> uint;

  fn term(&self, n: uint) -> (R,Mon);

  fn foldl_terms<A>(&self, z: A, f: &fn(a: A, term: (R,Mon)) -> A) -> A;

  fn each_term(&self, f: &fn(term: (R,Mon)) -> ()) ->  ();

  fn canonical_form(&self) -> PolyOwning<Mon>;

  fn equiv<P: Polynomial<Mon>>(&self, other: &P) -> bool;

}

fn canonical_form_impl<Mon: Monomial>(coefs: &[R], mons: &[Mon]) -> (~[R],~[Mon]) {
  let mut coefs_by_mon: TreeMap<Mon,R> = TreeMap::new();
  for i in range(0, mons.len()) {
    let (mon, mon_coef) = (mons[i].clone(), coefs[i]);
    if mon_coef != 0 as R {
      let did_update = match coefs_by_mon.find_mut(&mon) {
        Some(coef) => { *coef += mon_coef; true }, None => false
      };
      if !did_update {
        coefs_by_mon.insert(mon, mon_coef);
      }
    }
  }
  let mut mons:  ~[Mon] = vec::with_capacity(coefs_by_mon.len());
  let mut coefs: ~[R] = vec::with_capacity(coefs_by_mon.len());
  for (mon, coef) in coefs_by_mon.iter() {
    if *coef != 0 as R {
      mons.push(mon.clone());
      coefs.push(*coef);
    }
  }
  (coefs, mons)
}

impl<Mon:Monomial> Polynomial<Mon>
               for PolyOwning<Mon> {

  #[inline]
  fn num_terms(&self) -> uint {
    self.mons.len()
  }

  #[inline]
  fn term(&self, n: uint) -> (R,Mon) {
    let coef = self.coefs[n];
    let mon = unsafe { self.mons.unsafe_get(n) }; // bounds-checked already in coef access
    (coef,mon)
  }

  fn foldl_terms<A>(&self, z: A, f: &fn(a: A, term: (R,Mon)) -> A) -> A {
    let mut acc_val = z;
    for n in range(0, self.mons.len()) {
      // let term = (self.coefs[n], self.mons[n].clone());
      let term = unsafe { (self.coefs.unsafe_get(n), self.mons.unsafe_get(n)) };
      acc_val = f(acc_val, term);
    }
    acc_val
  }

  #[inline]
  fn each_term(&self, f: &fn(term: (R,Mon)) -> ()) ->  () {
    for n in range(0, self.mons.len()) {
      unsafe { f((self.coefs.unsafe_get(n), self.mons.unsafe_get(n))) };
    }
  }

  fn canonical_form(&self) -> PolyOwning<Mon> {
    let (can_coefs, can_mons) = canonical_form_impl(self.coefs, self.mons);
    match can_mons.len() {
      0 => { let m: PolyOwning<Mon> = PolyOwning::zero(); m}
      _ => PolyOwning::new(can_coefs, can_mons)
    }
  }

  fn equiv<P: Polynomial<Mon>>(&self, other: &P) -> bool {
    let (self_can_coefs, self_can_mons) = canonical_form_impl(self.coefs, self.mons);
    let other_can = other.canonical_form();
    self_can_coefs == other_can.coefs && self_can_mons == other_can.mons
  }

}

impl<'self,Mon:Monomial> Polynomial<Mon>
                     for PolyBorrowing<'self,Mon> {

  #[inline]
  fn num_terms(&self) -> uint {
    self.mons.len()
  }

  #[inline]
  fn term(&self, n: uint) -> (R,Mon) {
    let coef = self.coefs[n];
    let mon = unsafe { self.mons.unsafe_get(n) }; // bounds-checked already in coef access
    (coef,mon)
  }

  fn foldl_terms<A>(&self, z: A, f: &fn(a: A, term: (R,Mon)) -> A) -> A {
    let mut acc_val = z;
    for n in range(0, self.mons.len()) {
      let term = unsafe { (self.coefs.unsafe_get(n), self.mons.unsafe_get(n)) };
      acc_val = f(acc_val, term);
    }
    acc_val
  }

  #[inline]
  fn each_term(&self, f: &fn(term: (R,Mon)) -> ()) ->  () {
    for n in range(0, self.mons.len()) {
      unsafe { f((self.coefs.unsafe_get(n), self.mons.unsafe_get(n))) };
    }
  }

  fn canonical_form(&self) -> PolyOwning<Mon> {
    let (can_coefs, can_mons) = canonical_form_impl(self.coefs, self.mons);
    match can_mons.len() {
      0 => { let zero: PolyOwning<Mon> = PolyOwning::zero(); zero}
      _ => PolyOwning::new(can_coefs, can_mons)
    }
  }

  fn equiv<P: Polynomial<Mon>>(&self, other: &P) -> bool {
    let (self_can_coefs, self_can_mons) = canonical_form_impl(self.coefs, self.mons);
    let other_can = other.canonical_form();
    self_can_coefs == other_can.coefs && self_can_mons == other_can.mons
  }

}

impl<'self,Mon:Monomial> Polynomial<Mon>
                     for PolyBorrowingMons<'self,Mon> {

  #[inline]
  fn num_terms(&self) -> uint {
    self.mons.len()
  }

  #[inline]
  fn term(&self, n: uint) -> (R,Mon) {
    let coef = self.coefs[n];
    let mon = unsafe { self.mons.unsafe_get(n) }; // bounds-checked already in coef access
    (coef,mon)
  }

  fn foldl_terms<A>(&self, z: A, f: &fn(a: A, term: (R,Mon)) -> A) -> A {
    let mut acc_val = z;
    for n in range(0, self.mons.len()) {
      let term = unsafe { (self.coefs.unsafe_get(n), self.mons.unsafe_get(n)) };
      acc_val = f(acc_val, term);
    }
    acc_val
  }

  #[inline]
  fn each_term(&self, f: &fn(term: (R,Mon)) -> ()) ->  () {
    for n in range(0, self.mons.len()) {
      unsafe { f((self.coefs.unsafe_get(n), self.mons.unsafe_get(n))) };
    }
  }

  fn canonical_form(&self) -> PolyOwning<Mon> {
    let (can_coefs, can_mons) = canonical_form_impl(self.coefs, self.mons);
    match can_mons.len() {
      0 => { let zero: PolyOwning<Mon> = PolyOwning::zero(); zero}
      _ => PolyOwning::new(can_coefs, can_mons)
    }
  }

  fn equiv<P: Polynomial<Mon>>(&self, other: &P) -> bool {
    let (self_can_coefs, self_can_mons) = canonical_form_impl(self.coefs, self.mons);
    let other_can = other.canonical_form();
    self_can_coefs == other_can.coefs && self_can_mons == other_can.mons
  }

}

// Implement ToStr trait.

fn to_str_impl<Mon: Monomial>(coefs: &[R], mons: &[Mon]) -> ~str {
  let term_strs = vec::from_fn(mons.len(), |i| {
    coefs[i].to_str() + " " + mons[i].to_str()
  });
  term_strs.connect(" + ")
}

impl<Mon:Monomial> ToStr
             for PolyOwning<Mon> {
  fn to_str(&self) -> ~str {
    to_str_impl(self.coefs, self.mons)
  }
}

impl<'self,Mon:Monomial> ToStr
                   for PolyBorrowing<'self,Mon> {
  fn to_str(&self) -> ~str {
    to_str_impl(self.coefs, self.mons)
  }
}

impl<'self,Mon:Monomial> ToStr
                   for PolyBorrowingMons<'self,Mon> {
  fn to_str(&self) -> ~str {
    to_str_impl(self.coefs, self.mons)
  }
}

pub trait Scalable {

  fn scaled(&self, r: R) -> Self;

  fn scale(&mut self, r: R) -> ();

}

impl<'self,Mon:Monomial> Scalable
                   for PolyBorrowingMons<'self,Mon> {
  #[inline]
  fn scaled(&self, r: R) -> PolyBorrowingMons<'self, Mon> {
    let scaled_coefs = vec::from_fn(self.coefs.len(), |i| r * self.coefs[i]);
    PolyBorrowingMons { coefs: scaled_coefs, mons: self.mons }
  }

  #[inline]
  fn scale(&mut self, r: R) -> () {
    for i in range(0, self.coefs.len()) {
      self.coefs[i] *= r;
    }
  }
}

impl<Mon:Monomial> Scalable
             for PolyOwning<Mon> {
  #[inline]
  fn scaled(&self, r: R) -> PolyOwning<Mon> {
    let scaled_coefs = vec::from_fn(self.coefs.len(), |i| r * self.coefs[i]);
    PolyOwning { coefs: scaled_coefs, mons: self.mons.clone() }
  }

  #[inline]
  fn scale(&mut self, r: R) -> () {
    for i in range(0, self.coefs.len()) {
      self.coefs[i] *= r;
    }
  }
}

pub fn mul<Mon:Monomial,P1:Polynomial<Mon>,P2:Polynomial<Mon>>(p1: &P1, p2: &P2) -> PolyOwning<Mon> {
  let n = p1.num_terms() * p2.num_terms();
  let mut mons = vec::with_capacity(n);
  let mut coefs = vec::with_capacity(n);
  p1.each_term(|(c1,m1)|
    p2.each_term(|(c2,m2)| {
      mons.push(m1 * m2);
      coefs.push(c1 * c2);
    })
  );
  PolyOwning { coefs: coefs, mons: mons }
}

// Convenience function to create polynomials in testing code. Performance critical code
// should use the ::new function implementations instead which will be more efficient.
pub fn poly<Mon:Monomial>(terms: &[(R,Mon)]) -> PolyOwning<Mon> {
  let mut coefs = vec::with_capacity(terms.len());
  let mut mons = vec::with_capacity(terms.len());
  for &(c, ref mon) in terms.iter() {
    coefs.push(c);
    mons.push(mon.clone());
  }
  PolyOwning { coefs: coefs, mons: mons }
}

pub fn approx_equiv<Mon:Monomial,P:Polynomial<Mon>>(p1: &P, p2: &P, tol: R) -> bool {
  let diff = PolyOwning::from_polys_lcomb([(1.,p1),(-1.,p2)]);
  diff.coefs.iter().all(|&c| abs(c) <= tol)
}

<commit_msg>New value_at trait function for Polynomial.<commit_after>use extra::treemap::TreeMap;
use std::vec;
use std::num::abs;

use common::*;
use monomial::*;

#[deriving(Eq, Clone)]
pub struct PolyOwning<Mon> {
  coefs: ~[R],
  mons:  ~[Mon]
}

#[deriving(Eq, Clone)]
pub struct PolyBorrowing<'self,Mon> {
  coefs: &'self [R],
  mons: &'self [Mon]
}

#[deriving(Eq, Clone)]
pub struct PolyBorrowingMons<'self,Mon> {
  coefs: ~[R],
  mons: &'self [Mon]
}

impl<Mon:Monomial> PolyOwning<Mon> {

  pub fn new(coefs: ~[R], mons: ~[Mon]) -> PolyOwning<Mon> {
    match (coefs.len(), mons.len()) {
      (0,0) => fail!("Empty arrays passed to polynomial constructor."),
      (x,y) if x != y => fail!("Arrays of different lengths passed to polynomial constructor."),
      _ => PolyOwning { coefs: coefs, mons: mons }
    }
  }

  pub fn zero() -> PolyOwning<Mon> {
    let one_mon: Mon = Monomial::one();
    PolyOwning { coefs: ~[0 as R], mons: ~[one_mon] }
  }

  pub fn zero_with_capacity(n: uint) -> PolyOwning<Mon> {
    let one_mon: Mon = Monomial::one();
    let mut coefs = vec::with_capacity(n);
    let mut mons = vec::with_capacity(n);
    coefs.push(0 as R);
    mons.push(one_mon);
    PolyOwning { coefs: coefs, mons: mons }
  }

  pub fn from_polys_lcomb<P:Polynomial<Mon>>(terms: &[(R,&P)]) -> PolyOwning<Mon> {
    let mut coefs_by_mon: TreeMap<Mon,R> = TreeMap::new();
    for &(c_p, p) in terms.iter() {
      p.each_term(|(c_m, m)| {
        if c_m != 0 as R {
          let did_update = match coefs_by_mon.find_mut(&m) {
            Some(c) => { *c += c_p * c_m; true }, None => false
          };
          if !did_update {
            coefs_by_mon.insert(m, c_p * c_m);
          }
        }
      });
    }
    let mut mons:  ~[Mon] = vec::with_capacity(coefs_by_mon.len());
    let mut coefs: ~[R] = vec::with_capacity(coefs_by_mon.len());
    for (mon, coef) in coefs_by_mon.iter() {
      if *coef != 0 as R {
        mons.push(mon.clone());
        coefs.push(*coef);
      }
    }
    PolyOwning { coefs: coefs, mons: mons }
  }

}

impl<'self,Mon:Monomial> PolyBorrowing<'self,Mon> {

  pub fn new(coefs: &'self [R], mons: &'self [Mon]) -> PolyBorrowing<'self,Mon> {
    match (coefs.len(), mons.len()) {
      (0,0) => fail!("Empty arrays passed to polynomial constructor."),
      (x,y) if x != y => fail!("Arrays of different lengths passed to polynomial constructor."),
      _ => PolyBorrowing { coefs: coefs, mons: mons }
    }
  }
}

impl<'self,Mon:Monomial> PolyBorrowingMons<'self,Mon> {

  pub fn new(coefs: ~[R], mons: &'self [Mon]) -> PolyBorrowingMons<'self,Mon> {
    match (coefs.len(), mons.len()) {
      (0,0) => fail!("Empty arrays passed to polynomial constructor."),
      (x,y) if x != y => fail!("Arrays of different lengths passed to polynomial constructor."),
      _ => PolyBorrowingMons { coefs: coefs, mons: mons }
    }
  }
}

pub trait Polynomial<Mon>: ToStr {

  fn num_terms(&self) -> uint;

  fn term(&self, n: uint) -> (R,Mon);

  fn foldl_terms<A>(&self, z: A, f: &fn(a: A, term: (R,Mon)) -> A) -> A;

  fn value_at(&self, x: &[R]) -> R;

  fn each_term(&self, f: &fn(term: (R,Mon)) -> ()) ->  ();

  fn canonical_form(&self) -> PolyOwning<Mon>;

  fn equiv<P: Polynomial<Mon>>(&self, other: &P) -> bool;

}

fn canonical_form_impl<Mon: Monomial>(coefs: &[R], mons: &[Mon]) -> (~[R],~[Mon]) {
  let mut coefs_by_mon: TreeMap<Mon,R> = TreeMap::new();
  for i in range(0, mons.len()) {
    let (mon, mon_coef) = (mons[i].clone(), coefs[i]);
    if mon_coef != 0 as R {
      let did_update = match coefs_by_mon.find_mut(&mon) {
        Some(coef) => { *coef += mon_coef; true }, None => false
      };
      if !did_update {
        coefs_by_mon.insert(mon, mon_coef);
      }
    }
  }
  let mut mons:  ~[Mon] = vec::with_capacity(coefs_by_mon.len());
  let mut coefs: ~[R] = vec::with_capacity(coefs_by_mon.len());
  for (mon, coef) in coefs_by_mon.iter() {
    if *coef != 0 as R {
      mons.push(mon.clone());
      coefs.push(*coef);
    }
  }
  (coefs, mons)
}

impl<Mon:Monomial> Polynomial<Mon>
               for PolyOwning<Mon> {

  #[inline]
  fn num_terms(&self) -> uint {
    self.mons.len()
  }

  #[inline]
  fn term(&self, n: uint) -> (R,Mon) {
    let coef = self.coefs[n];
    let mon = unsafe { self.mons.unsafe_get(n) }; // bounds-checked already in coef access
    (coef,mon)
  }

  fn foldl_terms<A>(&self, z: A, f: &fn(a: A, term: (R,Mon)) -> A) -> A {
    let mut acc_val = z;
    for n in range(0, self.mons.len()) {
      // let term = (self.coefs[n], self.mons[n].clone());
      let term = unsafe { (self.coefs.unsafe_get(n), self.mons.unsafe_get(n)) };
      acc_val = f(acc_val, term);
    }
    acc_val
  }

  #[inline]
  fn value_at(&self, x: &[R]) -> R {
    self.foldl_terms(0 as R, |sum, (c,m)| sum + c * m.value_at(x))
  }

  #[inline]
  fn each_term(&self, f: &fn(term: (R,Mon)) -> ()) ->  () {
    for n in range(0, self.mons.len()) {
      unsafe { f((self.coefs.unsafe_get(n), self.mons.unsafe_get(n))) };
    }
  }

  fn canonical_form(&self) -> PolyOwning<Mon> {
    let (can_coefs, can_mons) = canonical_form_impl(self.coefs, self.mons);
    match can_mons.len() {
      0 => { let m: PolyOwning<Mon> = PolyOwning::zero(); m}
      _ => PolyOwning::new(can_coefs, can_mons)
    }
  }

  fn equiv<P: Polynomial<Mon>>(&self, other: &P) -> bool {
    let (self_can_coefs, self_can_mons) = canonical_form_impl(self.coefs, self.mons);
    let other_can = other.canonical_form();
    self_can_coefs == other_can.coefs && self_can_mons == other_can.mons
  }

}

impl<'self,Mon:Monomial> Polynomial<Mon>
                     for PolyBorrowing<'self,Mon> {

  #[inline]
  fn num_terms(&self) -> uint {
    self.mons.len()
  }

  #[inline]
  fn term(&self, n: uint) -> (R,Mon) {
    let coef = self.coefs[n];
    let mon = unsafe { self.mons.unsafe_get(n) }; // bounds-checked already in coef access
    (coef,mon)
  }

  fn foldl_terms<A>(&self, z: A, f: &fn(a: A, term: (R,Mon)) -> A) -> A {
    let mut acc_val = z;
    for n in range(0, self.mons.len()) {
      let term = unsafe { (self.coefs.unsafe_get(n), self.mons.unsafe_get(n)) };
      acc_val = f(acc_val, term);
    }
    acc_val
  }

  #[inline]
  fn value_at(&self, x: &[R]) -> R {
    self.foldl_terms(0 as R, |sum, (c,m)| sum + c * m.value_at(x))
  }

  #[inline]
  fn each_term(&self, f: &fn(term: (R,Mon)) -> ()) ->  () {
    for n in range(0, self.mons.len()) {
      unsafe { f((self.coefs.unsafe_get(n), self.mons.unsafe_get(n))) };
    }
  }

  fn canonical_form(&self) -> PolyOwning<Mon> {
    let (can_coefs, can_mons) = canonical_form_impl(self.coefs, self.mons);
    match can_mons.len() {
      0 => { let zero: PolyOwning<Mon> = PolyOwning::zero(); zero}
      _ => PolyOwning::new(can_coefs, can_mons)
    }
  }

  fn equiv<P: Polynomial<Mon>>(&self, other: &P) -> bool {
    let (self_can_coefs, self_can_mons) = canonical_form_impl(self.coefs, self.mons);
    let other_can = other.canonical_form();
    self_can_coefs == other_can.coefs && self_can_mons == other_can.mons
  }

}

impl<'self,Mon:Monomial> Polynomial<Mon>
                     for PolyBorrowingMons<'self,Mon> {

  #[inline]
  fn num_terms(&self) -> uint {
    self.mons.len()
  }

  #[inline]
  fn term(&self, n: uint) -> (R,Mon) {
    let coef = self.coefs[n];
    let mon = unsafe { self.mons.unsafe_get(n) }; // bounds-checked already in coef access
    (coef,mon)
  }

  fn foldl_terms<A>(&self, z: A, f: &fn(a: A, term: (R,Mon)) -> A) -> A {
    let mut acc_val = z;
    for n in range(0, self.mons.len()) {
      let term = unsafe { (self.coefs.unsafe_get(n), self.mons.unsafe_get(n)) };
      acc_val = f(acc_val, term);
    }
    acc_val
  }

  #[inline]
  fn value_at(&self, x: &[R]) -> R {
    self.foldl_terms(0 as R, |sum, (c,m)| sum + c * m.value_at(x))
  }

  #[inline]
  fn each_term(&self, f: &fn(term: (R,Mon)) -> ()) ->  () {
    for n in range(0, self.mons.len()) {
      unsafe { f((self.coefs.unsafe_get(n), self.mons.unsafe_get(n))) };
    }
  }

  fn canonical_form(&self) -> PolyOwning<Mon> {
    let (can_coefs, can_mons) = canonical_form_impl(self.coefs, self.mons);
    match can_mons.len() {
      0 => { let zero: PolyOwning<Mon> = PolyOwning::zero(); zero}
      _ => PolyOwning::new(can_coefs, can_mons)
    }
  }

  fn equiv<P: Polynomial<Mon>>(&self, other: &P) -> bool {
    let (self_can_coefs, self_can_mons) = canonical_form_impl(self.coefs, self.mons);
    let other_can = other.canonical_form();
    self_can_coefs == other_can.coefs && self_can_mons == other_can.mons
  }

}

// Implement ToStr trait.

fn to_str_impl<Mon: Monomial>(coefs: &[R], mons: &[Mon]) -> ~str {
  let term_strs = vec::from_fn(mons.len(), |i| {
    coefs[i].to_str() + " " + mons[i].to_str()
  });
  term_strs.connect(" + ")
}

impl<Mon:Monomial> ToStr
             for PolyOwning<Mon> {
  fn to_str(&self) -> ~str {
    to_str_impl(self.coefs, self.mons)
  }
}

impl<'self,Mon:Monomial> ToStr
                   for PolyBorrowing<'self,Mon> {
  fn to_str(&self) -> ~str {
    to_str_impl(self.coefs, self.mons)
  }
}

impl<'self,Mon:Monomial> ToStr
                   for PolyBorrowingMons<'self,Mon> {
  fn to_str(&self) -> ~str {
    to_str_impl(self.coefs, self.mons)
  }
}

pub trait Scalable {

  fn scaled(&self, r: R) -> Self;

  fn scale(&mut self, r: R) -> ();

}

impl<'self,Mon:Monomial> Scalable
                   for PolyBorrowingMons<'self,Mon> {
  #[inline]
  fn scaled(&self, r: R) -> PolyBorrowingMons<'self, Mon> {
    let scaled_coefs = vec::from_fn(self.coefs.len(), |i| r * self.coefs[i]);
    PolyBorrowingMons { coefs: scaled_coefs, mons: self.mons }
  }

  #[inline]
  fn scale(&mut self, r: R) -> () {
    for i in range(0, self.coefs.len()) {
      self.coefs[i] *= r;
    }
  }
}

impl<Mon:Monomial> Scalable
             for PolyOwning<Mon> {
  #[inline]
  fn scaled(&self, r: R) -> PolyOwning<Mon> {
    let scaled_coefs = vec::from_fn(self.coefs.len(), |i| r * self.coefs[i]);
    PolyOwning { coefs: scaled_coefs, mons: self.mons.clone() }
  }

  #[inline]
  fn scale(&mut self, r: R) -> () {
    for i in range(0, self.coefs.len()) {
      self.coefs[i] *= r;
    }
  }
}

pub fn mul<Mon:Monomial,P1:Polynomial<Mon>,P2:Polynomial<Mon>>(p1: &P1, p2: &P2) -> PolyOwning<Mon> {
  let n = p1.num_terms() * p2.num_terms();
  let mut mons = vec::with_capacity(n);
  let mut coefs = vec::with_capacity(n);
  p1.each_term(|(c1,m1)|
    p2.each_term(|(c2,m2)| {
      mons.push(m1 * m2);
      coefs.push(c1 * c2);
    })
  );
  PolyOwning { coefs: coefs, mons: mons }
}

// Convenience function to create polynomials in testing code. Performance critical code
// should use the ::new function implementations instead which will be more efficient.
pub fn poly<Mon:Monomial>(terms: &[(R,Mon)]) -> PolyOwning<Mon> {
  let mut coefs = vec::with_capacity(terms.len());
  let mut mons = vec::with_capacity(terms.len());
  for &(c, ref mon) in terms.iter() {
    coefs.push(c);
    mons.push(mon.clone());
  }
  PolyOwning { coefs: coefs, mons: mons }
}

pub fn approx_equiv<Mon:Monomial,P:Polynomial<Mon>>(p1: &P, p2: &P, tol: R) -> bool {
  let diff = PolyOwning::from_polys_lcomb([(1.,p1),(-1.,p2)]);
  diff.coefs.iter().all(|&c| abs(c) <= tol)
}

<|endoftext|>