<commit_before>use sys::joystick as ll;

use SdlResult;
use get_error;
use clear_error;
use sys::event::{SDL_QUERY, SDL_ENABLE};
use std::ffi::{CString, CStr, NulError};
use std::fmt::{Display, Formatter, Error};
use libc::c_char;

/// Retreive the total number of attached joysticks *and* controllers
/// identified by SDL.
pub fn num_joysticks() -> SdlResult<i32> {
    let result = unsafe { ll::SDL_NumJoysticks() };

    if result >= 0 {
        Ok(result)
    } else {
        Err(get_error())
    }
}

/// Get the GUID for the joystick number `id`
pub fn get_device_guid(id: i32) -> SdlResult<Guid> {
    let raw = unsafe { ll::SDL_JoystickGetDeviceGUID(id) };

    let guid = Guid { raw: raw };

    if guid.is_zero() {
        Err(get_error())
    } else {
        Ok(guid)
    }
}

/// If state is `true` joystick events are processed, otherwise
/// they're ignored.
pub fn set_event_state(state: bool) {
    unsafe { ll::SDL_JoystickEventState(state as i32) };
}

/// Return `true` if joystick events are processed.
pub fn get_event_state() -> bool {
    unsafe { ll::SDL_JoystickEventState(SDL_QUERY as i32)
             == SDL_ENABLE as i32 }
}

/// Return the name of the joystick at index `id`
pub fn name_for_index(id: i32) -> SdlResult<String> {
    let name = unsafe { ll::SDL_JoystickNameForIndex(id) };

    c_str_to_string_or_err(name)
}

/// Force joystick update when not using the event loop
pub fn update() {
    unsafe { ll::SDL_JoystickUpdate() };
}

/// Wrapper around the SDL_Joystick object
pub struct Joystick {
    raw: *mut ll::SDL_Joystick,
}

impl Joystick {
    /// Attempt to open the joystick at number `id` and return it.
    pub fn open(id: i32) -> SdlResult<Joystick> {
        let joystick = unsafe { ll::SDL_JoystickOpen(id) };

        if joystick.is_null() {
            Err(get_error())
        } else {
            Ok(Joystick { raw: joystick })
        }
    }

    /// Return the name of the joystick or an empty string if no name
    /// is found.
    pub fn name(&self) -> String {
        let name = unsafe { ll::SDL_JoystickName(self.raw) };

        c_str_to_string(name)
    }

    /// Return true if the joystick has been opened and currently
    /// connected.
    pub fn get_attached(&self) -> bool {
        unsafe { ll::SDL_JoystickGetAttached(self.raw) != 0 }
    }

    pub fn get_instance_id(&self) -> i32 {
        let result = unsafe { ll::SDL_JoystickInstanceID(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result
        }
    }

    /// Retreive the joystick's GUID
    pub fn get_guid(&self) -> Guid {
        let raw = unsafe { ll::SDL_JoystickGetGUID(self.raw) };

        let guid = Guid { raw: raw };

        if guid.is_zero() {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            guid
        }
    }

    /// Retreive the number of axes for this joystick
    pub fn get_num_axes(&self) -> u32 {
        let result = unsafe { ll::SDL_JoystickNumAxes(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result as u32
        }
    }

    /// Gets the position of the given `axis`.
    ///
    /// The function will fail if the joystick doesn't have the provided axis.
    pub fn get_axis(&self, axis: u32) -> SdlResult<i16> {
        // This interface is a bit messed up: 0 is a valid position
        // but can also mean that an error occured. As far as I can
        // tell the only way to know if an error happened is to see if
        // get_error() returns a non-empty string.
        clear_error();

        let axis = try!(u32_to_int!(axis));
        let pos = unsafe { ll::SDL_JoystickGetAxis(self.raw, axis) };

        if pos != 0 {
            Ok(pos)
        } else {
            let err = get_error();

            if err.is_empty() {
                Ok(pos)
            } else {
                Err(err)
            }
        }
    }

    /// Retreive the number of buttons for this joystick
    pub fn get_num_buttons(&self) -> u32 {
        let result = unsafe { ll::SDL_JoystickNumButtons(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result as u32
        }
    }

    /// Return `Ok(true)` if `button` is pressed.
    ///
    /// The function will fail if the joystick doesn't have the provided button.
    pub fn get_button(&self, button: u32) -> SdlResult<bool> {
        // Same deal as get_axis, 0 can mean both unpressed or
        // error...
        clear_error();

        let button = try!(u32_to_int!(button));
        let pressed = unsafe { ll::SDL_JoystickGetButton(self.raw, button) };

        match pressed {
            1 => Ok(true),
            0 => {
                let err = get_error();

                if err.is_empty() {
                    // Button is not pressed
                    Ok(false)
                } else {
                    Err(err)
                }
            }
            // Should be unreachable
            _ => Err(get_error()),
        }
    }

    /// Retreive the number of balls for this joystick
    pub fn get_num_balls(&self) -> u32 {
        let result = unsafe { ll::SDL_JoystickNumBalls(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result as u32
        }
    }

    /// Return a pair `(dx, dy)` containing the difference in axis
    /// position since the last poll
    pub fn get_ball(&self, ball: u32) -> SdlResult<(i32, i32)> {
        let mut dx = 0;
        let mut dy = 0;

        let ball = try!(u32_to_int!(ball));
        let result = unsafe { ll::SDL_JoystickGetBall(self.raw, ball, &mut dx, &mut dy) };

        if result == 0 {
            Ok((dx, dy))
        } else {
            Err(get_error())
        }
    }

    /// Retreive the number of balls for this joystick
    pub fn get_num_hats(&self) -> u32 {
        let result = unsafe { ll::SDL_JoystickNumHats(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result as u32
        }
    }

    /// Return the position of `hat` for this joystick
    pub fn get_hat(&self, hat: u32) -> SdlResult<HatState> {
        // Guess what? This function as well uses 0 to report an error
        // but 0 is also a valid value (HatState::Centered). So we
        // have to use the same hack as `get_axis`...
        clear_error();

        let hat = try!(u32_to_int!(hat));
        let result = unsafe { ll::SDL_JoystickGetHat(self.raw, hat) };

        let state = HatState::from_raw(result as u8);

        if result != 0 {
            Ok(state)
        } else {
            let err = get_error();

            if err.is_empty() {
                Ok(state)
            } else {
                Err(err)
            }
        }
    }
}

impl Drop for Joystick {
    fn drop(&mut self) {
        unsafe { ll::SDL_JoystickClose(self.raw) }
    }
}

/// Wrapper around a SDL_JoystickGUID, a globally unique identifier
/// for a joystick.
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct Guid {
    raw: ll::SDL_JoystickGUID,
}

impl Guid {
    /// Create a GUID from a string representation.
    pub fn from_string(guid: &str) -> Result<Guid, NulError> {
        let guid = try!(CString::new(guid));

        let raw = unsafe { ll::SDL_JoystickGetGUIDFromString(guid.as_ptr()) };

        Ok(Guid { raw: raw })
    }

    /// Return `true` if GUID is full 0s
    pub fn is_zero(&self) -> bool {
        for &i in self.raw.data.iter() {
            if i != 0 {
                return false;
            }
        }

        return true;
    }

    /// Return a String representation of GUID
    pub fn get_string(&self) -> String {
        // Doc says "buf should supply at least 33bytes". I took that
        // to mean that 33bytes should be enough in all cases, but
        // maybe I'm wrong?
        let mut buf = [0; 33];

        let len   = buf.len() as i32;
        let c_str = buf.as_mut_ptr();

        unsafe {
            ll::SDL_JoystickGetGUIDString(self.raw, c_str, len);
        }

        // The buffer should always be NUL terminated (the
        // documentation doesn't explicitely say it but I checked the
        // code)
        c_str_to_string(c_str)
    }

    /// Return a copy of the internal SDL_JoystickGUID
    pub fn raw(self) -> ll::SDL_JoystickGUID {
        self.raw
    }
}

impl Display for Guid {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "{}", self.get_string())
    }
}

/// This is represented in SDL2 as a bitfield but obviously not all
/// combinations make sense: 5 for instance would mean up and down at
/// the same time... To simplify things I turn it into an enum which
/// is how the SDL2 docs present it anyway (using macros).
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum HatState {
    Centered  = 0,
    Up        = 0x01,
    Right     = 0x02,
    Down      = 0x04,
    Left      = 0x08,
    RightUp   = 0x02 | 0x01,
    RightDown = 0x02 | 0x04,
    LeftUp    = 0x08 | 0x01,
    Leftdown  = 0x08 | 0x04,
}

impl HatState {
    pub fn from_raw(raw: u8) -> HatState {
        match raw {
            0  => HatState::Centered,
            1  => HatState::Up,
            2  => HatState::Right,
            4  => HatState::Down,
            8  => HatState::Left,
            3  => HatState::RightUp,
            6  => HatState::RightDown,
            9  => HatState::LeftUp,
            12 => HatState::Leftdown,
            _  => panic!("Unexpected hat position: {}", raw),
        }
    }
}

/// Convert C string `c_str` to a String. Return an empty string if
/// c_str is NULL.
fn c_str_to_string(c_str: *const c_char) -> String {
    if c_str.is_null() {
        String::new()
    } else {
        let bytes = unsafe { CStr::from_ptr(c_str).to_bytes() };

        String::from_utf8_lossy(bytes).to_string()
    }
}

/// Convert C string `c_str` to a String. Return an SDL error if
/// `c_str` is NULL.
fn c_str_to_string_or_err(c_str: *const c_char) -> SdlResult<String> {
    if c_str.is_null() {
        Err(get_error())
    } else {
        let bytes = unsafe { CStr::from_ptr(c_str).to_bytes() };

        Ok(String::from_utf8_lossy(bytes).to_string())
    }
}
<commit_msg>Check whether joystick is attached before freeing<commit_after>use sys::joystick as ll;

use SdlResult;
use get_error;
use clear_error;
use sys::event::{SDL_QUERY, SDL_ENABLE};
use std::ffi::{CString, CStr, NulError};
use std::fmt::{Display, Formatter, Error};
use libc::c_char;

/// Retreive the total number of attached joysticks *and* controllers
/// identified by SDL.
pub fn num_joysticks() -> SdlResult<i32> {
    let result = unsafe { ll::SDL_NumJoysticks() };

    if result >= 0 {
        Ok(result)
    } else {
        Err(get_error())
    }
}

/// Get the GUID for the joystick number `id`
pub fn get_device_guid(id: i32) -> SdlResult<Guid> {
    let raw = unsafe { ll::SDL_JoystickGetDeviceGUID(id) };

    let guid = Guid { raw: raw };

    if guid.is_zero() {
        Err(get_error())
    } else {
        Ok(guid)
    }
}

/// If state is `true` joystick events are processed, otherwise
/// they're ignored.
pub fn set_event_state(state: bool) {
    unsafe { ll::SDL_JoystickEventState(state as i32) };
}

/// Return `true` if joystick events are processed.
pub fn get_event_state() -> bool {
    unsafe { ll::SDL_JoystickEventState(SDL_QUERY as i32)
             == SDL_ENABLE as i32 }
}

/// Return the name of the joystick at index `id`
pub fn name_for_index(id: i32) -> SdlResult<String> {
    let name = unsafe { ll::SDL_JoystickNameForIndex(id) };

    c_str_to_string_or_err(name)
}

/// Force joystick update when not using the event loop
pub fn update() {
    unsafe { ll::SDL_JoystickUpdate() };
}

/// Wrapper around the SDL_Joystick object
pub struct Joystick {
    raw: *mut ll::SDL_Joystick,
}

impl Joystick {
    /// Attempt to open the joystick at number `id` and return it.
    pub fn open(id: i32) -> SdlResult<Joystick> {
        let joystick = unsafe { ll::SDL_JoystickOpen(id) };

        if joystick.is_null() {
            Err(get_error())
        } else {
            Ok(Joystick { raw: joystick })
        }
    }

    /// Return the name of the joystick or an empty string if no name
    /// is found.
    pub fn name(&self) -> String {
        let name = unsafe { ll::SDL_JoystickName(self.raw) };

        c_str_to_string(name)
    }

    /// Return true if the joystick has been opened and currently
    /// connected.
    pub fn get_attached(&self) -> bool {
        unsafe { ll::SDL_JoystickGetAttached(self.raw) != 0 }
    }

    pub fn get_instance_id(&self) -> i32 {
        let result = unsafe { ll::SDL_JoystickInstanceID(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result
        }
    }

    /// Retreive the joystick's GUID
    pub fn get_guid(&self) -> Guid {
        let raw = unsafe { ll::SDL_JoystickGetGUID(self.raw) };

        let guid = Guid { raw: raw };

        if guid.is_zero() {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            guid
        }
    }

    /// Retreive the number of axes for this joystick
    pub fn get_num_axes(&self) -> u32 {
        let result = unsafe { ll::SDL_JoystickNumAxes(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result as u32
        }
    }

    /// Gets the position of the given `axis`.
    ///
    /// The function will fail if the joystick doesn't have the provided axis.
    pub fn get_axis(&self, axis: u32) -> SdlResult<i16> {
        // This interface is a bit messed up: 0 is a valid position
        // but can also mean that an error occured. As far as I can
        // tell the only way to know if an error happened is to see if
        // get_error() returns a non-empty string.
        clear_error();

        let axis = try!(u32_to_int!(axis));
        let pos = unsafe { ll::SDL_JoystickGetAxis(self.raw, axis) };

        if pos != 0 {
            Ok(pos)
        } else {
            let err = get_error();

            if err.is_empty() {
                Ok(pos)
            } else {
                Err(err)
            }
        }
    }

    /// Retreive the number of buttons for this joystick
    pub fn get_num_buttons(&self) -> u32 {
        let result = unsafe { ll::SDL_JoystickNumButtons(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result as u32
        }
    }

    /// Return `Ok(true)` if `button` is pressed.
    ///
    /// The function will fail if the joystick doesn't have the provided button.
    pub fn get_button(&self, button: u32) -> SdlResult<bool> {
        // Same deal as get_axis, 0 can mean both unpressed or
        // error...
        clear_error();

        let button = try!(u32_to_int!(button));
        let pressed = unsafe { ll::SDL_JoystickGetButton(self.raw, button) };

        match pressed {
            1 => Ok(true),
            0 => {
                let err = get_error();

                if err.is_empty() {
                    // Button is not pressed
                    Ok(false)
                } else {
                    Err(err)
                }
            }
            // Should be unreachable
            _ => Err(get_error()),
        }
    }

    /// Retreive the number of balls for this joystick
    pub fn get_num_balls(&self) -> u32 {
        let result = unsafe { ll::SDL_JoystickNumBalls(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result as u32
        }
    }

    /// Return a pair `(dx, dy)` containing the difference in axis
    /// position since the last poll
    pub fn get_ball(&self, ball: u32) -> SdlResult<(i32, i32)> {
        let mut dx = 0;
        let mut dy = 0;

        let ball = try!(u32_to_int!(ball));
        let result = unsafe { ll::SDL_JoystickGetBall(self.raw, ball, &mut dx, &mut dy) };

        if result == 0 {
            Ok((dx, dy))
        } else {
            Err(get_error())
        }
    }

    /// Retreive the number of balls for this joystick
    pub fn get_num_hats(&self) -> u32 {
        let result = unsafe { ll::SDL_JoystickNumHats(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result as u32
        }
    }

    /// Return the position of `hat` for this joystick
    pub fn get_hat(&self, hat: u32) -> SdlResult<HatState> {
        // Guess what? This function as well uses 0 to report an error
        // but 0 is also a valid value (HatState::Centered). So we
        // have to use the same hack as `get_axis`...
        clear_error();

        let hat = try!(u32_to_int!(hat));
        let result = unsafe { ll::SDL_JoystickGetHat(self.raw, hat) };

        let state = HatState::from_raw(result as u8);

        if result != 0 {
            Ok(state)
        } else {
            let err = get_error();

            if err.is_empty() {
                Ok(state)
            } else {
                Err(err)
            }
        }
    }
}

impl Drop for Joystick {
    fn drop(&mut self) {
        if self.get_attached() {
            unsafe { ll::SDL_JoystickClose(self.raw) }
        }
    }
}

/// Wrapper around a SDL_JoystickGUID, a globally unique identifier
/// for a joystick.
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct Guid {
    raw: ll::SDL_JoystickGUID,
}

impl Guid {
    /// Create a GUID from a string representation.
    pub fn from_string(guid: &str) -> Result<Guid, NulError> {
        let guid = try!(CString::new(guid));

        let raw = unsafe { ll::SDL_JoystickGetGUIDFromString(guid.as_ptr()) };

        Ok(Guid { raw: raw })
    }

    /// Return `true` if GUID is full 0s
    pub fn is_zero(&self) -> bool {
        for &i in self.raw.data.iter() {
            if i != 0 {
                return false;
            }
        }

        return true;
    }

    /// Return a String representation of GUID
    pub fn get_string(&self) -> String {
        // Doc says "buf should supply at least 33bytes". I took that
        // to mean that 33bytes should be enough in all cases, but
        // maybe I'm wrong?
        let mut buf = [0; 33];

        let len   = buf.len() as i32;
        let c_str = buf.as_mut_ptr();

        unsafe {
            ll::SDL_JoystickGetGUIDString(self.raw, c_str, len);
        }

        // The buffer should always be NUL terminated (the
        // documentation doesn't explicitely say it but I checked the
        // code)
        c_str_to_string(c_str)
    }

    /// Return a copy of the internal SDL_JoystickGUID
    pub fn raw(self) -> ll::SDL_JoystickGUID {
        self.raw
    }
}

impl Display for Guid {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "{}", self.get_string())
    }
}

/// This is represented in SDL2 as a bitfield but obviously not all
/// combinations make sense: 5 for instance would mean up and down at
/// the same time... To simplify things I turn it into an enum which
/// is how the SDL2 docs present it anyway (using macros).
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum HatState {
    Centered  = 0,
    Up        = 0x01,
    Right     = 0x02,
    Down      = 0x04,
    Left      = 0x08,
    RightUp   = 0x02 | 0x01,
    RightDown = 0x02 | 0x04,
    LeftUp    = 0x08 | 0x01,
    Leftdown  = 0x08 | 0x04,
}

impl HatState {
    pub fn from_raw(raw: u8) -> HatState {
        match raw {
            0  => HatState::Centered,
            1  => HatState::Up,
            2  => HatState::Right,
            4  => HatState::Down,
            8  => HatState::Left,
            3  => HatState::RightUp,
            6  => HatState::RightDown,
            9  => HatState::LeftUp,
            12 => HatState::Leftdown,
            _  => panic!("Unexpected hat position: {}", raw),
        }
    }
}

/// Convert C string `c_str` to a String. Return an empty string if
/// c_str is NULL.
fn c_str_to_string(c_str: *const c_char) -> String {
    if c_str.is_null() {
        String::new()
    } else {
        let bytes = unsafe { CStr::from_ptr(c_str).to_bytes() };

        String::from_utf8_lossy(bytes).to_string()
    }
}

/// Convert C string `c_str` to a String. Return an SDL error if
/// `c_str` is NULL.
fn c_str_to_string_or_err(c_str: *const c_char) -> SdlResult<String> {
    if c_str.is_null() {
        Err(get_error())
    } else {
        let bytes = unsafe { CStr::from_ptr(c_str).to_bytes() };

        Ok(String::from_utf8_lossy(bytes).to_string())
    }
}
<|endoftext|>


<commit_before>use std::iter::Fuse;
use alloc::collections::VecDeque;
use crate::size_hint;
use crate::PeekingNext;
#[cfg(doc)]
use crate::Itertools;

/// See [`multipeek()`] for more information.
#[derive(Clone, Debug)]
pub struct MultiPeek<I>
    where I: Iterator
{
    iter: Fuse<I>,
    buf: VecDeque<I::Item>,
    index: usize,
}

/// An iterator adaptor that allows the user to peek at multiple `.next()`
/// values without advancing the base iterator.
///
/// [`IntoIterator`] enabled version of [`Itertools::multipeek`].
pub fn multipeek<I>(iterable: I) -> MultiPeek<I::IntoIter>
    where I: IntoIterator
{
    MultiPeek {
        iter: iterable.into_iter().fuse(),
        buf: VecDeque::new(),
        index: 0,
    }
}

impl<I> MultiPeek<I>
    where I: Iterator
{
    /// Reset the peeking “cursor”
    pub fn reset_peek(&mut self) {
        self.index = 0;
    }
}

impl<I: Iterator> MultiPeek<I> {
    /// Works exactly like `.next()` with the only difference that it doesn't
    /// advance itself. `.peek()` can be called multiple times, to peek
    /// further ahead.
    /// When `.next()` is called, reset the peeking “cursor”.
    pub fn peek(&mut self) -> Option<&I::Item> {
        let ret = if self.index < self.buf.len() {
            Some(&self.buf[self.index])
        } else {
            match self.iter.next() {
                Some(x) => {
                    self.buf.push_back(x);
                    Some(&self.buf[self.index])
                }
                None => return None,
            }
        };

        self.index += 1;
        ret
    }
}

impl<I> PeekingNext for MultiPeek<I>
    where I: Iterator,
{
    fn peeking_next<F>(&mut self, accept: F) -> Option<Self::Item>
        where F: FnOnce(&Self::Item) -> bool
    {
        if self.buf.is_empty() {
            if let Some(r) = self.peek() {
                if !accept(r) { return None }
            }
        } else {
            if let Some(r) = self.buf.get(0) {
                if !accept(r) { return None }
            }
        }
        self.next()
    }
}

impl<I> Iterator for MultiPeek<I>
    where I: Iterator
{
    type Item = I::Item;

    fn next(&mut self) -> Option<Self::Item> {
        self.index = 0;
        self.buf.pop_front().or_else(|| self.iter.next())
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        size_hint::add_scalar(self.iter.size_hint(), self.buf.len())
    }
}

// Same size
impl<I> ExactSizeIterator for MultiPeek<I>
    where I: ExactSizeIterator
{}

<commit_msg>fix clippy::collapsible_else_if<commit_after>use std::iter::Fuse;
use alloc::collections::VecDeque;
use crate::size_hint;
use crate::PeekingNext;
#[cfg(doc)]
use crate::Itertools;

/// See [`multipeek()`] for more information.
#[derive(Clone, Debug)]
pub struct MultiPeek<I>
    where I: Iterator
{
    iter: Fuse<I>,
    buf: VecDeque<I::Item>,
    index: usize,
}

/// An iterator adaptor that allows the user to peek at multiple `.next()`
/// values without advancing the base iterator.
///
/// [`IntoIterator`] enabled version of [`Itertools::multipeek`].
pub fn multipeek<I>(iterable: I) -> MultiPeek<I::IntoIter>
    where I: IntoIterator
{
    MultiPeek {
        iter: iterable.into_iter().fuse(),
        buf: VecDeque::new(),
        index: 0,
    }
}

impl<I> MultiPeek<I>
    where I: Iterator
{
    /// Reset the peeking “cursor”
    pub fn reset_peek(&mut self) {
        self.index = 0;
    }
}

impl<I: Iterator> MultiPeek<I> {
    /// Works exactly like `.next()` with the only difference that it doesn't
    /// advance itself. `.peek()` can be called multiple times, to peek
    /// further ahead.
    /// When `.next()` is called, reset the peeking “cursor”.
    pub fn peek(&mut self) -> Option<&I::Item> {
        let ret = if self.index < self.buf.len() {
            Some(&self.buf[self.index])
        } else {
            match self.iter.next() {
                Some(x) => {
                    self.buf.push_back(x);
                    Some(&self.buf[self.index])
                }
                None => return None,
            }
        };

        self.index += 1;
        ret
    }
}

impl<I> PeekingNext for MultiPeek<I>
    where I: Iterator,
{
    fn peeking_next<F>(&mut self, accept: F) -> Option<Self::Item>
        where F: FnOnce(&Self::Item) -> bool
    {
        if self.buf.is_empty() {
            if let Some(r) = self.peek() {
                if !accept(r) { return None }
            }
        } else if let Some(r) = self.buf.get(0) {
            if !accept(r) { return None }
        }
        self.next()
    }
}

impl<I> Iterator for MultiPeek<I>
    where I: Iterator
{
    type Item = I::Item;

    fn next(&mut self) -> Option<Self::Item> {
        self.index = 0;
        self.buf.pop_front().or_else(|| self.iter.next())
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        size_hint::add_scalar(self.iter.size_hint(), self.buf.len())
    }
}

// Same size
impl<I> ExactSizeIterator for MultiPeek<I>
    where I: ExactSizeIterator
{}

<|endoftext|>


<commit_before>///! Selected intrusive types, including intrusive references.
///!
///! Use of intrusively-reference-counted objects allows easy creation of sharable reference
///! allows creation of references to e.g. self:
///!
///! ```rust
///! use relemon::util::intrusive
///! struct Quaternion { w: f64, x: f64, y: f64, z: f64 }
///! impl MyType {
///! fn new_on_heap(w: f64, x: f64, y: f64, z: f64) -> Ref<Quaternion>
///! }
///! ```
///!

extern crate core;
use std;
use std::fmt;
use std::mem;
use std::ptr;
use std::ptr::PtrExt;
use std::ops::{Deref, DerefMut};
use std::hash::{Hash, Hasher};

/// Interface for types that can be used with intrusive references.
pub trait RefCounted {
    // Create a reference to the current object.
    fn ref_to_self<T: RefCounted + ExplicitlySized>(&self) -> Ref<T> {
        ref_to_raw(unsafe{std::mem::transmute(&self)})
    }

    /// Fetch the object's current reference count.
    fn get_refcount(&self) -> usize;

    /// Increment the object's reference count, returning the new value.
    fn add_ref(&mut self) -> usize;

    /// Decrement the object's reference count, returning the new value.
    fn remove_ref(&mut self) -> usize;
}

/// Interface required of unsized types used with intrusive references.
pub trait ExplicitlySized {
    /// Get the underlying type's allocation size.
    fn get_type_size(&self) -> usize;

    /// Get the underlying type's allocation alignment.
    fn get_type_align(&self) -> usize;
}

/// Create a simple implementation of util::intrusive::RefCounted for a type.
#[macro_export]
macro_rules! default_refcounted_impl {
    ($target:ident, $($mbr:ident).*) => (
        impl RefCounted for $target {
            fn get_refcount(&self) -> usize { self.$($mbr).* }
            fn add_ref(&mut self) -> usize { self.$($mbr).* += 1; self.$($mbr).* }
            fn remove_ref(&mut self) -> usize { self.$($mbr).* -= 1; self.$($mbr).* }
        });
    ($target:ident<'a>, $($mbr:ident).*) => (
        impl<'a> RefCounted for $target<'a> {
            fn get_refcount(&self) -> usize { self.$($mbr).* }
            fn add_ref(&mut self) -> usize { self.$($mbr).* += 1; self.$($mbr).* }
            fn remove_ref(&mut self) -> usize { self.$($mbr).* -= 1; self.$($mbr).* }
        });
    (<$typ:ident>, $($mbr:ident).*) => (
        impl<$typ> RefCounted for $typ {
            fn get_refcount(&self) -> usize { self.$($mbr).* }
            fn add_ref(&mut self) -> usize { self.$($mbr).* += 1; self.$($mbr).* }
            fn remove_ref(&mut self) -> usize { self.$($mbr).* -= 1; self.$($mbr).* }
        });
}

/// Immutable reference to an intrusively-refcounted object.
pub struct Ref<T: RefCounted + ?Sized>(*const T);

/// Create an intrusive reference via raw pointer.
/// This method is all *kinds* of unsafe, and should **not** be used from
/// user code!
fn ref_to_raw<T: RefCounted + ExplicitlySized>(ptr: *mut T) -> Ref<T> {
    // Transmute into a mutable reference so we can increment the refcount.
    let mut_ref: &mut T = unsafe { &mut *ptr };
    panic_unless!(1 == mut_ref.add_ref(), "unexpected nonzero refcount on unowned raw pointer");
    Ref(ptr)
}

/// Move the given value into the heap, and return a Ref to it.  The value
/// should have a refcount of zero prior to this function.
///
/// # Examples
///
/// ```rust
/// #[macro_use]
/// use cripes::util::intrusive;
///
/// #[derive(Debug)]
/// struct Dog { refcount: usize }
/// default_refcounted_impl!(Dog);
/// let x = intrusive::ref_to_new(Dog{refcount: 0});   // x is an intrusive reference to the heap
/// println!("{:?}", x);
/// drop(x);                  // dropping the sole reference to that location
///                           // will free the memory.
/// ```
pub fn ref_to_new<U: RefCounted + ExplicitlySized, T: ?Sized + RefCounted + ExplicitlySized>(obj: U) -> Ref<T> {
    let mem = unsafe { mem::transmute::<_,*mut T>(std::boxed::into_raw(Box::new(obj))) };
    ref_to_raw(mem)
}

/* **************************************************************** */
impl<T: RefCounted + ExplicitlySized + ?Sized> Ref<T> {
    /// Create a null Ref.  This is probably not very safe.
    pub fn null() -> Ref<T> {
        Ref(std::mem::transmute::<_,*const T>(0))
    }

    /// Check if the ref's internal pointer is NULL.
    pub fn is_null(&self) -> bool { match *self { Ref(x) => (x == 0 as *const T) } }

    /// Get the reference count from the underlying object.
    pub fn get_refcount(&self) -> usize {
        self.deref().get_refcount()
    }

    /// Check if this refers to the same object as another Ref.
    pub fn is_same(&self, other: &Ref<T>) -> bool {
        match *self { Ref(x) => match *other { Ref(y) => (x as usize) == (y as usize) } }
    }
}

/* ================================================================
 * impl std::borrow::Borrow
 */
impl<T: RefCounted + ?Sized>  std::borrow::Borrow<T> for Ref<T> {
    fn borrow(&self) -> &T {
        self.deref()
    }
}

/* ================================================================
 * impl fmt::Display
 */
impl<T: RefCounted + fmt::Display + ?Sized> fmt::Display for Ref<T>  {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Ref(p) => { assert!(! (p == 0 as *const T));
                        self.deref().fmt(f) } }
    }
}

/* ================================================================
 * impl fmt::Debug
 */
impl<T: RefCounted + fmt::Debug + ?Sized> fmt::Debug for Ref<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Ref(value) => {
                write!(f, "Ref {{ 0x{:X}=>", (value as usize));
                self.deref().fmt(f) }
        }
    }
}

/* ================================================================
 * impl Clone
 */
impl<T: RefCounted + ?Sized> Clone for Ref<T> {
    fn clone(&self) -> Self {
        ref_to_raw(self.deref())
    }
}

/* ================================================================
 * impl Deref
 */
impl<T: RefCounted + ?Sized> Deref for Ref<T> {
    type Target = T;
    fn deref(&self) -> &T {
        if self.is_null() { panic!("tried to deref a null pointer") }
        match *self { Ref(p) =>  { &*p }
        }
    }
}

/// **FIXME:** this is NOT in ANY WAY thread-safe!
///
/// We really should have a separate MutRef<T: AtomicallyRefCounted> for types
/// that are reliably mutable in a thread-safe fashion.

// impl<T: RefCounted> DerefMut for Ref<T> {
//     fn deref_mut(&mut self) -> &'a mut T {
//         match *self {
//             Ref(None) => panic!("attempted to deref NULL reference"),
//             Ref(Some(x)) =>  {
//                 assert!(! x.is_null());
//                 unsafe { &mut *x }
//             }
//         }
//     }
// }

/* ================================================================
 * impl Drop
 */
#[unsafe_destructor]
impl<T: RefCounted + ExplicitlySized + ?Sized> Drop for Ref<T> {
    fn drop(&mut self) {
        match *self {
            Ref(x) => { assert!((x as usize) != 0);
                        let _ref: &mut T = unsafe { &mut *x };
                        if _ref.remove_ref() == 0 {
                            let boxed = unsafe { Box::from_raw(mem::transmute::<_,*mut T>(x)) };
                            drop(boxed); } }
        }
    }
}

/* ================================================================
 * impl PartialEq<T>, Eq<T>
 */
impl<T: Eq + RefCounted + ExplicitlySized + ?Sized> Eq for Ref<T> {}

impl<T: PartialEq<T> + RefCounted + ExplicitlySized + ?Sized> PartialEq<Ref<T>> for Ref<T> {
    fn eq(&self, other: &Ref<T>) -> bool {
        *(*self) == *(*other)
    }
}
impl<T: PartialEq<T> + RefCounted + ExplicitlySized + ?Sized> PartialEq<T> for Ref<T> {
    fn eq(&self, other: &T) -> bool {
        *self == *other
    }
}

/* ================================================================
 * impl Hash<H>
 */
impl<T: ?Sized + ExplicitlySized + RefCounted + Hash> Hash for Ref<T> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        match *self { Ref(..) => self.deref().hash(state) }
    }
}
<commit_msg>util::intrusive: remove some unused imports<commit_after>///! Selected intrusive types, including intrusive references.
///!
///! Use of intrusively-reference-counted objects allows easy creation of sharable reference
///! allows creation of references to e.g. self:
///!
///! ```rust
///! use relemon::util::intrusive
///! struct Quaternion { w: f64, x: f64, y: f64, z: f64 }
///! impl MyType {
///! fn new_on_heap(w: f64, x: f64, y: f64, z: f64) -> Ref<Quaternion>
///! }
///! ```
///!

extern crate core;
use std;
use std::fmt;
use std::mem;
use std::ptr::PtrExt;
use std::ops::Deref;
use std::hash::{Hash, Hasher};

/// Interface for types that can be used with intrusive references.
pub trait RefCounted {
    // Create a reference to the current object.
    fn ref_to_self<T: RefCounted + ExplicitlySized>(&self) -> Ref<T> {
        ref_to_raw(unsafe{std::mem::transmute(&self)})
    }

    /// Fetch the object's current reference count.
    fn get_refcount(&self) -> usize;

    /// Increment the object's reference count, returning the new value.
    fn add_ref(&mut self) -> usize;

    /// Decrement the object's reference count, returning the new value.
    fn remove_ref(&mut self) -> usize;
}

/// Interface required of unsized types used with intrusive references.
pub trait ExplicitlySized {
    /// Get the underlying type's allocation size.
    fn get_type_size(&self) -> usize;

    /// Get the underlying type's allocation alignment.
    fn get_type_align(&self) -> usize;
}

/// Create a simple implementation of util::intrusive::RefCounted for a type.
#[macro_export]
macro_rules! default_refcounted_impl {
    ($target:ident, $($mbr:ident).*) => (
        impl RefCounted for $target {
            fn get_refcount(&self) -> usize { self.$($mbr).* }
            fn add_ref(&mut self) -> usize { self.$($mbr).* += 1; self.$($mbr).* }
            fn remove_ref(&mut self) -> usize { self.$($mbr).* -= 1; self.$($mbr).* }
        });
    ($target:ident<'a>, $($mbr:ident).*) => (
        impl<'a> RefCounted for $target<'a> {
            fn get_refcount(&self) -> usize { self.$($mbr).* }
            fn add_ref(&mut self) -> usize { self.$($mbr).* += 1; self.$($mbr).* }
            fn remove_ref(&mut self) -> usize { self.$($mbr).* -= 1; self.$($mbr).* }
        });
    (<$typ:ident>, $($mbr:ident).*) => (
        impl<$typ> RefCounted for $typ {
            fn get_refcount(&self) -> usize { self.$($mbr).* }
            fn add_ref(&mut self) -> usize { self.$($mbr).* += 1; self.$($mbr).* }
            fn remove_ref(&mut self) -> usize { self.$($mbr).* -= 1; self.$($mbr).* }
        });
}

/// Immutable reference to an intrusively-refcounted object.
pub struct Ref<T: RefCounted + ?Sized>(*const T);

/// Create an intrusive reference via raw pointer.
/// This method is all *kinds* of unsafe, and should **not** be used from
/// user code!
fn ref_to_raw<T: RefCounted + ExplicitlySized>(ptr: *mut T) -> Ref<T> {
    // Transmute into a mutable reference so we can increment the refcount.
    let mut_ref: &mut T = unsafe { &mut *ptr };
    panic_unless!(1 == mut_ref.add_ref(), "unexpected nonzero refcount on unowned raw pointer");
    Ref(ptr)
}

/// Move the given value into the heap, and return a Ref to it.  The value
/// should have a refcount of zero prior to this function.
///
/// # Examples
///
/// ```rust
/// #[macro_use]
/// use cripes::util::intrusive;
///
/// #[derive(Debug)]
/// struct Dog { refcount: usize }
/// default_refcounted_impl!(Dog);
/// let x = intrusive::ref_to_new(Dog{refcount: 0});   // x is an intrusive reference to the heap
/// println!("{:?}", x);
/// drop(x);                  // dropping the sole reference to that location
///                           // will free the memory.
/// ```
pub fn ref_to_new<U: RefCounted + ExplicitlySized, T: ?Sized + RefCounted + ExplicitlySized>(obj: U) -> Ref<T> {
    let mem = unsafe { mem::transmute::<_,*mut T>(std::boxed::into_raw(Box::new(obj))) };
    ref_to_raw(mem)
}

/* **************************************************************** */
impl<T: RefCounted + ExplicitlySized + ?Sized> Ref<T> {
    /// Create a null Ref.  This is probably not very safe.
    pub fn null() -> Ref<T> {
        Ref(std::mem::transmute::<_,*const T>(0))
    }

    /// Check if the ref's internal pointer is NULL.
    pub fn is_null(&self) -> bool { match *self { Ref(x) => (x == 0 as *const T) } }

    /// Get the reference count from the underlying object.
    pub fn get_refcount(&self) -> usize {
        self.deref().get_refcount()
    }

    /// Check if this refers to the same object as another Ref.
    pub fn is_same(&self, other: &Ref<T>) -> bool {
        match *self { Ref(x) => match *other { Ref(y) => (x as usize) == (y as usize) } }
    }
}

/* ================================================================
 * impl std::borrow::Borrow
 */
impl<T: RefCounted + ?Sized>  std::borrow::Borrow<T> for Ref<T> {
    fn borrow(&self) -> &T {
        self.deref()
    }
}

/* ================================================================
 * impl fmt::Display
 */
impl<T: RefCounted + fmt::Display + ?Sized> fmt::Display for Ref<T>  {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Ref(p) => { assert!(! (p == 0 as *const T));
                        self.deref().fmt(f) } }
    }
}

/* ================================================================
 * impl fmt::Debug
 */
impl<T: RefCounted + fmt::Debug + ?Sized> fmt::Debug for Ref<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Ref(value) => {
                write!(f, "Ref {{ 0x{:X}=>", (value as usize));
                self.deref().fmt(f) }
        }
    }
}

/* ================================================================
 * impl Clone
 */
impl<T: RefCounted + ?Sized> Clone for Ref<T> {
    fn clone(&self) -> Self {
        ref_to_raw(self.deref())
    }
}

/* ================================================================
 * impl Deref
 */
impl<T: RefCounted + ?Sized> Deref for Ref<T> {
    type Target = T;
    fn deref(&self) -> &T {
        if self.is_null() { panic!("tried to deref a null pointer") }
        match *self { Ref(p) =>  { &*p }
        }
    }
}

/* ================================================================
 * impl Drop
 */
#[unsafe_destructor]
impl<T: RefCounted + ExplicitlySized + ?Sized> Drop for Ref<T> {
    fn drop(&mut self) {
        match *self {
            Ref(x) => { assert!((x as usize) != 0);
                        let _ref: &mut T = unsafe { &mut *x };
                        if _ref.remove_ref() == 0 {
                            let boxed = unsafe { Box::from_raw(mem::transmute::<_,*mut T>(x)) };
                            drop(boxed); } }
        }
    }
}

/* ================================================================
 * impl PartialEq<T>, Eq<T>
 */
impl<T: Eq + RefCounted + ExplicitlySized + ?Sized> Eq for Ref<T> {}

impl<T: PartialEq<T> + RefCounted + ExplicitlySized + ?Sized> PartialEq<Ref<T>> for Ref<T> {
    fn eq(&self, other: &Ref<T>) -> bool {
        *(*self) == *(*other)
    }
}
impl<T: PartialEq<T> + RefCounted + ExplicitlySized + ?Sized> PartialEq<T> for Ref<T> {
    fn eq(&self, other: &T) -> bool {
        *self == *other
    }
}

/* ================================================================
 * impl Hash<H>
 */
impl<T: ?Sized + ExplicitlySized + RefCounted + Hash> Hash for Ref<T> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        match *self { Ref(..) => self.deref().hash(state) }
    }
}
<|endoftext|>


<commit_before>//! This module defines the data element API, which enables NIfTI
//! volume API implementations to read, write and convert data
//! elements.
use byteordered::{ByteOrdered, Endian};
use crate::NiftiType;
use crate::error::Result;
use crate::util::convert_bytes_to;
use num_traits::cast::AsPrimitive;
use safe_transmute::transmute_vec;
use std::io::Read;
use std::mem::align_of;
use std::ops::{Add, Mul};

/// Interface for linear (affine) transformations to values. Multiple
/// implementations are needed because the original type `T` may not have
/// enough precision to obtain an appropriate outcome. For example,
/// transforming a `u8` is always done through `f32`, but an `f64` is instead
/// manipulated through its own type by first converting the slope and
/// intercept arguments to `f64`.
pub trait LinearTransform<T: 'static + Copy> {
    /// Linearly transform a value with the given slope and intercept.
    fn linear_transform(value: T, slope: f32, intercept: f32) -> T;

    /// Linearly transform a sequence of values with the given slope and intercept into
    /// a vector.
    fn linear_transform_many(value: &[T], slope: f32, intercept: f32) -> Vec<T> {
        value
            .iter()
            .map(|x| Self::linear_transform(*x, slope, intercept))
            .collect()
    }

    /// Linearly transform a sequence of values inline, with the given slope and intercept.
    fn linear_transform_many_inline(value: &mut [T], slope: f32, intercept: f32) {
        for v in value.iter_mut() {
            *v = Self::linear_transform(*v, slope, intercept);
        }
    }
}

/// A linear transformation in which the value is converted to `f32` for the
/// affine transformation, then converted back to the original type. Ideal for
/// small, low precision types such as `u8` and `i16`.
#[derive(Debug)]
pub struct LinearTransformViaF32;

impl<T> LinearTransform<T> for LinearTransformViaF32
where
    T: 'static + Copy + DataElement,
{
    fn linear_transform(value: T, slope: f32, intercept: f32) -> T {
        if slope == 0. {
            return value;
        }
        T::from_f32(AsPrimitive::<f32>::as_(value) * slope + intercept)
    }
}

/// A linear transformation in which the value and parameters are converted to
/// `f64` for the affine transformation, then converted to the original type.
/// Ideal for wide integer types such as `i64`.
#[derive(Debug)]
pub struct LinearTransformViaF64;

impl<T> LinearTransform<T> for LinearTransformViaF64
where
    T: 'static + Copy + DataElement,
{
    fn linear_transform(value: T, slope: f32, intercept: f32) -> T {
        if slope == 0. {
            return value;
        }
        let slope: f64 = slope.as_();
        let intercept: f64 = intercept.as_();
        T::from_f64(AsPrimitive::<f64>::as_(value) * slope + intercept)
    }
}

/// A linear transformation in which the slope and intercept parameters are
/// converted to the value's type for the affine transformation. Ideal
/// for high precision or complex number types.
#[derive(Debug)]
pub struct LinearTransformViaOriginal;

impl<T> LinearTransform<T> for LinearTransformViaOriginal
where
    T: 'static + Copy + DataElement + Mul<Output = T> + Add<Output = T>,
{
    fn linear_transform(value: T, slope: f32, intercept: f32) -> T {
        if slope == 0. {
            return value;
        }
        let slope = T::from_f32(slope);
        let intercept = T::from_f32(intercept);
        value * slope + intercept
    }
}

/// Trait type for characterizing a NIfTI data element, implemented for
/// primitive numeric types which are used by the crate to represent voxel
/// values.
pub trait DataElement:
    'static + Sized + Copy + AsPrimitive<u8> + AsPrimitive<f32> + AsPrimitive<f64>
{
    /// The `datatype` mapped to the type T
    const DATA_TYPE: NiftiType;

    /// For defining how this element is linearly transformed to another.
    type Transform: LinearTransform<Self>;

    /// Read a single element from the given byte source.
    fn from_raw<R: Read, E>(src: R, endianness: E) -> Result<Self>
    where
        R: Read,
        E: Endian;

    /// Create a single element by converting a scalar value.
    fn from_u8(value: u8) -> Self;

    /// Create a single element by converting a scalar value.
    fn from_i8(value: i8) -> Self;

    /// Create a single element by converting a scalar value.
    fn from_u16(value: u16) -> Self;

    /// Create a single element by converting a scalar value.
    fn from_i16(value: i16) -> Self;

    /// Create a single element by converting a scalar value.
    fn from_u32(value: u32) -> Self;

    /// Create a single element by converting a scalar value.
    fn from_i32(value: i32) -> Self;

    /// Create a single element by converting a scalar value.
    fn from_u64(value: u64) -> Self;

    /// Create a single element by converting a scalar value.
    fn from_i64(value: i64) -> Self;

    /// Create a single element by converting a scalar value.
    fn from_f32(value: f32) -> Self;

    /// Create a single element by converting a scalar value.
    fn from_f64(value: f64) -> Self;

    /// Transform the given data vector into a vector of data elements.
    fn from_raw_vec<E>(vec: Vec<u8>, endianness: E) -> Result<Vec<Self>>
    where
        E: Endian,
        E: Clone,
    {
        let mut cursor: &[u8] = &vec;
        let n = align_of::<Self>();
        (0..n)
            .map(|_| Self::from_raw(&mut cursor, endianness.clone()))
            .collect()
    }
}

/// Mass-implement primitive conversions from scalar types
macro_rules! fn_from_scalar {
    ($typ: ty) => {
        fn from_u8(value: u8) -> Self {
            value as $typ
        }

        fn from_i8(value: i8) -> Self {
            value as $typ
        }

        fn from_u16(value: u16) -> Self {
            value as $typ
        }

        fn from_i16(value: i16) -> Self {
            value as $typ
        }

        fn from_u32(value: u32) -> Self {
            value as $typ
        }

        fn from_i32(value: i32) -> Self {
            value as $typ
        }

        fn from_u64(value: u64) -> Self {
            value as $typ
        }

        fn from_i64(value: i64) -> Self {
            value as $typ
        }

        fn from_f32(value: f32) -> Self {
            value as $typ
        }

        fn from_f64(value: f64) -> Self {
            value as $typ
        }
    };
}

impl DataElement for u8 {
    const DATA_TYPE: NiftiType = NiftiType::Uint8;
    type Transform = LinearTransformViaF32;
    fn from_raw_vec<E>(vec: Vec<u8>, _: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(vec)
    }
    fn from_raw<R, E>(src: R, _: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        ByteOrdered::native(src).read_u8().map_err(From::from)
    }

    fn_from_scalar!(u8);
}

impl DataElement for i8 {
    const DATA_TYPE: NiftiType = NiftiType::Int8;
    type Transform = LinearTransformViaF32;
    fn from_raw_vec<E>(vec: Vec<u8>, _: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(transmute_vec(vec).unwrap())
    }
    fn from_raw<R, E>(src: R, _: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        ByteOrdered::native(src).read_i8().map_err(From::from)
    }

    fn_from_scalar!(i8);
}

impl DataElement for u16 {
    const DATA_TYPE: NiftiType = NiftiType::Uint16;
    type Transform = LinearTransformViaF32;
    fn from_raw_vec<E>(vec: Vec<u8>, e: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(convert_bytes_to(vec, e))
    }
    fn from_raw<R, E>(src: R, e: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        e.read_u16(src).map_err(From::from)
    }

    fn_from_scalar!(u16);
}

impl DataElement for i16 {
    const DATA_TYPE: NiftiType = NiftiType::Int16;
    type Transform = LinearTransformViaF32;
    fn from_raw_vec<E>(vec: Vec<u8>, e: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(convert_bytes_to(vec, e))
    }
    fn from_raw<R, E>(src: R, e: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        e.read_i16(src).map_err(From::from)
    }

    fn_from_scalar!(i16);
}

impl DataElement for u32 {
    const DATA_TYPE: NiftiType = NiftiType::Uint32;
    type Transform = LinearTransformViaF32;
    fn from_raw_vec<E>(vec: Vec<u8>, e: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(convert_bytes_to(vec, e))
    }
    fn from_raw<R, E>(src: R, e: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        e.read_u32(src).map_err(From::from)
    }

    fn_from_scalar!(u32);
}

impl DataElement for i32 {
    const DATA_TYPE: NiftiType = NiftiType::Int32;
    type Transform = LinearTransformViaF32;
    fn from_raw_vec<E>(vec: Vec<u8>, e: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(convert_bytes_to(vec, e))
    }
    fn from_raw<R, E>(src: R, e: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        e.read_i32(src).map_err(From::from)
    }

    fn_from_scalar!(i32);
}

impl DataElement for u64 {
    const DATA_TYPE: NiftiType = NiftiType::Uint64;
    type Transform = LinearTransformViaF64;
    fn from_raw_vec<E>(vec: Vec<u8>, e: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(convert_bytes_to(vec, e))
    }
    fn from_raw<R, E>(src: R, e: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        e.read_u64(src).map_err(From::from)
    }

    fn_from_scalar!(u64);
}

impl DataElement for i64 {
    const DATA_TYPE: NiftiType = NiftiType::Int64;
    type Transform = LinearTransformViaF64;
    fn from_raw_vec<E>(vec: Vec<u8>, e: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(convert_bytes_to(vec, e))
    }
    fn from_raw<R, E>(src: R, e: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        e.read_i64(src).map_err(From::from)
    }

    fn_from_scalar!(i64);
}

impl DataElement for f32 {
    const DATA_TYPE: NiftiType = NiftiType::Float32;
    type Transform = LinearTransformViaOriginal;
    fn from_raw_vec<E>(vec: Vec<u8>, e: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(convert_bytes_to(vec, e))
    }
    fn from_raw<R, E>(src: R, e: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        e.read_f32(src).map_err(From::from)
    }

    fn_from_scalar!(f32);
}

impl DataElement for f64 {
    const DATA_TYPE: NiftiType = NiftiType::Float64;
    type Transform = LinearTransformViaOriginal;
    fn from_raw_vec<E>(vec: Vec<u8>, e: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(convert_bytes_to(vec, e))
    }
    fn from_raw<R, E>(src: R, e: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        e.read_f64(src).map_err(From::from)
    }

    fn_from_scalar!(f64);
}
<commit_msg>format element.rs<commit_after>//! This module defines the data element API, which enables NIfTI
//! volume API implementations to read, write and convert data
//! elements.
use crate::error::Result;
use crate::util::convert_bytes_to;
use crate::NiftiType;
use byteordered::{ByteOrdered, Endian};
use num_traits::cast::AsPrimitive;
use safe_transmute::transmute_vec;
use std::io::Read;
use std::mem::align_of;
use std::ops::{Add, Mul};

/// Interface for linear (affine) transformations to values. Multiple
/// implementations are needed because the original type `T` may not have
/// enough precision to obtain an appropriate outcome. For example,
/// transforming a `u8` is always done through `f32`, but an `f64` is instead
/// manipulated through its own type by first converting the slope and
/// intercept arguments to `f64`.
pub trait LinearTransform<T: 'static + Copy> {
    /// Linearly transform a value with the given slope and intercept.
    fn linear_transform(value: T, slope: f32, intercept: f32) -> T;

    /// Linearly transform a sequence of values with the given slope and intercept into
    /// a vector.
    fn linear_transform_many(value: &[T], slope: f32, intercept: f32) -> Vec<T> {
        value
            .iter()
            .map(|x| Self::linear_transform(*x, slope, intercept))
            .collect()
    }

    /// Linearly transform a sequence of values inline, with the given slope and intercept.
    fn linear_transform_many_inline(value: &mut [T], slope: f32, intercept: f32) {
        for v in value.iter_mut() {
            *v = Self::linear_transform(*v, slope, intercept);
        }
    }
}

/// A linear transformation in which the value is converted to `f32` for the
/// affine transformation, then converted back to the original type. Ideal for
/// small, low precision types such as `u8` and `i16`.
#[derive(Debug)]
pub struct LinearTransformViaF32;

impl<T> LinearTransform<T> for LinearTransformViaF32
where
    T: 'static + Copy + DataElement,
{
    fn linear_transform(value: T, slope: f32, intercept: f32) -> T {
        if slope == 0. {
            return value;
        }
        T::from_f32(AsPrimitive::<f32>::as_(value) * slope + intercept)
    }
}

/// A linear transformation in which the value and parameters are converted to
/// `f64` for the affine transformation, then converted to the original type.
/// Ideal for wide integer types such as `i64`.
#[derive(Debug)]
pub struct LinearTransformViaF64;

impl<T> LinearTransform<T> for LinearTransformViaF64
where
    T: 'static + Copy + DataElement,
{
    fn linear_transform(value: T, slope: f32, intercept: f32) -> T {
        if slope == 0. {
            return value;
        }
        let slope: f64 = slope.as_();
        let intercept: f64 = intercept.as_();
        T::from_f64(AsPrimitive::<f64>::as_(value) * slope + intercept)
    }
}

/// A linear transformation in which the slope and intercept parameters are
/// converted to the value's type for the affine transformation. Ideal
/// for high precision or complex number types.
#[derive(Debug)]
pub struct LinearTransformViaOriginal;

impl<T> LinearTransform<T> for LinearTransformViaOriginal
where
    T: 'static + Copy + DataElement + Mul<Output = T> + Add<Output = T>,
{
    fn linear_transform(value: T, slope: f32, intercept: f32) -> T {
        if slope == 0. {
            return value;
        }
        let slope = T::from_f32(slope);
        let intercept = T::from_f32(intercept);
        value * slope + intercept
    }
}

/// Trait type for characterizing a NIfTI data element, implemented for
/// primitive numeric types which are used by the crate to represent voxel
/// values.
pub trait DataElement:
    'static + Sized + Copy + AsPrimitive<u8> + AsPrimitive<f32> + AsPrimitive<f64>
{
    /// The `datatype` mapped to the type T
    const DATA_TYPE: NiftiType;

    /// For defining how this element is linearly transformed to another.
    type Transform: LinearTransform<Self>;

    /// Read a single element from the given byte source.
    fn from_raw<R: Read, E>(src: R, endianness: E) -> Result<Self>
    where
        R: Read,
        E: Endian;

    /// Create a single element by converting a scalar value.
    fn from_u8(value: u8) -> Self;

    /// Create a single element by converting a scalar value.
    fn from_i8(value: i8) -> Self;

    /// Create a single element by converting a scalar value.
    fn from_u16(value: u16) -> Self;

    /// Create a single element by converting a scalar value.
    fn from_i16(value: i16) -> Self;

    /// Create a single element by converting a scalar value.
    fn from_u32(value: u32) -> Self;

    /// Create a single element by converting a scalar value.
    fn from_i32(value: i32) -> Self;

    /// Create a single element by converting a scalar value.
    fn from_u64(value: u64) -> Self;

    /// Create a single element by converting a scalar value.
    fn from_i64(value: i64) -> Self;

    /// Create a single element by converting a scalar value.
    fn from_f32(value: f32) -> Self;

    /// Create a single element by converting a scalar value.
    fn from_f64(value: f64) -> Self;

    /// Transform the given data vector into a vector of data elements.
    fn from_raw_vec<E>(vec: Vec<u8>, endianness: E) -> Result<Vec<Self>>
    where
        E: Endian,
        E: Clone,
    {
        let mut cursor: &[u8] = &vec;
        let n = align_of::<Self>();
        (0..n)
            .map(|_| Self::from_raw(&mut cursor, endianness.clone()))
            .collect()
    }
}

/// Mass-implement primitive conversions from scalar types
macro_rules! fn_from_scalar {
    ($typ: ty) => {
        fn from_u8(value: u8) -> Self {
            value as $typ
        }

        fn from_i8(value: i8) -> Self {
            value as $typ
        }

        fn from_u16(value: u16) -> Self {
            value as $typ
        }

        fn from_i16(value: i16) -> Self {
            value as $typ
        }

        fn from_u32(value: u32) -> Self {
            value as $typ
        }

        fn from_i32(value: i32) -> Self {
            value as $typ
        }

        fn from_u64(value: u64) -> Self {
            value as $typ
        }

        fn from_i64(value: i64) -> Self {
            value as $typ
        }

        fn from_f32(value: f32) -> Self {
            value as $typ
        }

        fn from_f64(value: f64) -> Self {
            value as $typ
        }
    };
}

impl DataElement for u8 {
    const DATA_TYPE: NiftiType = NiftiType::Uint8;
    type Transform = LinearTransformViaF32;
    fn from_raw_vec<E>(vec: Vec<u8>, _: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(vec)
    }
    fn from_raw<R, E>(src: R, _: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        ByteOrdered::native(src).read_u8().map_err(From::from)
    }

    fn_from_scalar!(u8);
}

impl DataElement for i8 {
    const DATA_TYPE: NiftiType = NiftiType::Int8;
    type Transform = LinearTransformViaF32;
    fn from_raw_vec<E>(vec: Vec<u8>, _: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(transmute_vec(vec).unwrap())
    }
    fn from_raw<R, E>(src: R, _: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        ByteOrdered::native(src).read_i8().map_err(From::from)
    }

    fn_from_scalar!(i8);
}

impl DataElement for u16 {
    const DATA_TYPE: NiftiType = NiftiType::Uint16;
    type Transform = LinearTransformViaF32;
    fn from_raw_vec<E>(vec: Vec<u8>, e: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(convert_bytes_to(vec, e))
    }
    fn from_raw<R, E>(src: R, e: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        e.read_u16(src).map_err(From::from)
    }

    fn_from_scalar!(u16);
}

impl DataElement for i16 {
    const DATA_TYPE: NiftiType = NiftiType::Int16;
    type Transform = LinearTransformViaF32;
    fn from_raw_vec<E>(vec: Vec<u8>, e: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(convert_bytes_to(vec, e))
    }
    fn from_raw<R, E>(src: R, e: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        e.read_i16(src).map_err(From::from)
    }

    fn_from_scalar!(i16);
}

impl DataElement for u32 {
    const DATA_TYPE: NiftiType = NiftiType::Uint32;
    type Transform = LinearTransformViaF32;
    fn from_raw_vec<E>(vec: Vec<u8>, e: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(convert_bytes_to(vec, e))
    }
    fn from_raw<R, E>(src: R, e: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        e.read_u32(src).map_err(From::from)
    }

    fn_from_scalar!(u32);
}

impl DataElement for i32 {
    const DATA_TYPE: NiftiType = NiftiType::Int32;
    type Transform = LinearTransformViaF32;
    fn from_raw_vec<E>(vec: Vec<u8>, e: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(convert_bytes_to(vec, e))
    }
    fn from_raw<R, E>(src: R, e: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        e.read_i32(src).map_err(From::from)
    }

    fn_from_scalar!(i32);
}

impl DataElement for u64 {
    const DATA_TYPE: NiftiType = NiftiType::Uint64;
    type Transform = LinearTransformViaF64;
    fn from_raw_vec<E>(vec: Vec<u8>, e: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(convert_bytes_to(vec, e))
    }
    fn from_raw<R, E>(src: R, e: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        e.read_u64(src).map_err(From::from)
    }

    fn_from_scalar!(u64);
}

impl DataElement for i64 {
    const DATA_TYPE: NiftiType = NiftiType::Int64;
    type Transform = LinearTransformViaF64;
    fn from_raw_vec<E>(vec: Vec<u8>, e: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(convert_bytes_to(vec, e))
    }
    fn from_raw<R, E>(src: R, e: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        e.read_i64(src).map_err(From::from)
    }

    fn_from_scalar!(i64);
}

impl DataElement for f32 {
    const DATA_TYPE: NiftiType = NiftiType::Float32;
    type Transform = LinearTransformViaOriginal;
    fn from_raw_vec<E>(vec: Vec<u8>, e: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(convert_bytes_to(vec, e))
    }
    fn from_raw<R, E>(src: R, e: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        e.read_f32(src).map_err(From::from)
    }

    fn_from_scalar!(f32);
}

impl DataElement for f64 {
    const DATA_TYPE: NiftiType = NiftiType::Float64;
    type Transform = LinearTransformViaOriginal;
    fn from_raw_vec<E>(vec: Vec<u8>, e: E) -> Result<Vec<Self>>
    where
        E: Endian,
    {
        Ok(convert_bytes_to(vec, e))
    }
    fn from_raw<R, E>(src: R, e: E) -> Result<Self>
    where
        R: Read,
        E: Endian,
    {
        e.read_f64(src).map_err(From::from)
    }

    fn_from_scalar!(f64);
}
<|endoftext|>


<commit_before>//! Construct substrates of given types.

mod lattice;

use error::{GrafenError, Result};
use substrate::lattice::Lattice;
use system::*;

/// Configuration for constructing a substrate.
pub struct SubstrateConf {
    /// The type of lattice which will be generated.
    pub lattice: LatticeType,
    /// Base residue to generate coordinates for.
    pub residue: ResidueBase,
    /// Desired size of substrate along x and y.
    pub size: (f64, f64),
    /// Optionally use a random uniform distribution with this
    /// deviation to shift residue positions along z. The
    /// positions are shifted with the range (-std_z, +std_z)
    /// where std_z is the input devation.
    pub std_z: Option<f64>,
}

/// Lattice types which a substrate can be constructed from.
pub enum LatticeType {
    /// A hexagonal (honey comb) lattice with bond spacing `a`.
    Hexagonal { a: f64 },
    /// A triclinic lattice with base vectors of length `a` and `b`.
    /// Vector `a` is directed along the x axis and vector `b` is separated
    /// to it by the input angle `gamma` in degrees.
    Triclinic { a: f64, b: f64, gamma: f64 },
}

/// Create a substrate of input configuration. The returned system's
/// size will be adjusted to a multiple of the substrate spacing along both
/// directions. Thus the system can be periodically replicated along x and y.
///
/// # Errors
/// Returns an Error if the either of the input size are non-positive.
pub fn create_substrate(conf: &SubstrateConf) -> Result<System> {
    let (dx, dy) = conf.size;
    if dx < 0.0 || dy < 0.0 {
        return Err(
            GrafenError::RunError("cannot create a substrate of negative size".to_string())
        );
    }

    let mut lattice = match conf.lattice {
        LatticeType::Hexagonal { a } => {
            Lattice::hexagonal(a)
        },
        LatticeType::Triclinic { a, b, gamma } => {
            Lattice::triclinic(a, b, gamma.to_radians())
        },
    }.with_size(dx, dy).finalize();

    if let Some(std) = conf.std_z {
        lattice = lattice.uniform_distribution(std);
    };

    Ok(System {
        dimensions: lattice.box_size,
        residues: lattice.coords.iter().map(|&coord| conf.residue.to_residue(&coord)).collect(),
    })
}

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

    fn setup_conf() -> SubstrateConf {
        SubstrateConf {
            lattice: LatticeType::Hexagonal { a: 1.0 },
            residue: ResidueBase {
                code: "GRPH",
                atoms: vec![Atom { code: "C", position: Coord::new(0.0, 0.0, 0.0) }],
            },
            size: (10.0, 10.0),
            std_z: None,
        }
    }

    #[test]
    fn negative_sizes_return_error() {
        let mut conf = setup_conf();
        assert!(create_substrate(&conf).is_ok());

        conf.size = (-1.0, 1.0);
        assert!(create_substrate(&conf).is_err());

        conf.size = (1.0, -1.0);
        assert!(create_substrate(&conf).is_err());
    }

    #[test]
    fn uniform_distribution_is_set() {
        // The graphene is ordinarily positioned at z = 0.0
        let mut conf = setup_conf();
        let regular = create_substrate(&conf).unwrap();
        assert!(regular.residues.iter().all(|r| r.position.z == 0.0));

        conf.std_z = Some(1.0);
        let uniform = create_substrate(&conf).unwrap();

        // Non-zero variance This can fail, but it should not be common!
        // How else to assert that a distribution has been applied, though?
        assert!(uniform.residues.iter().map(|r| r.position.z).all(|z| z == 0.0) == false);

        // But no positions should exceed the input distribution max
        assert!(uniform.residues.iter().all(|r| r.position.z.abs() <= 1.0));
    }
}
<commit_msg>Document the `substrate` module<commit_after>//! Define and construct substrates.
//!
//! # Examples
//! Construct a triclinic lattice of hydrogen molecules.
//!
//! ```
//! use grafen::substrate::{create_substrate, LatticeType, SubstrateConf};
//! use grafen::system::{Atom, Coord, ResidueBase};
//!
//! // Define the molecule as a Residue.
//! let residue_base = ResidueBase {
//!     code: "HMOL",
//!     atoms: vec![
//!         Atom { code: "H1", position: Coord::new(0.0, 0.0, 0.5), },
//!         Atom { code: "H2", position: Coord::new(0.0, 0.0, -0.5), }
//!     ],
//! };
//!
//! // Define the substrate
//! let conf = SubstrateConf {
//!     lattice: LatticeType::Triclinic { a: 1.0, b: 0.5, gamma: 60.0 },
//!     residue: residue_base,
//!     size: (5.0, 10.0),
//!     std_z: None,
//! };
//!
//! // ... and create it!
//! let substrate = create_substrate(&conf).unwrap();
//! ```

mod lattice;

use error::{GrafenError, Result};
use substrate::lattice::Lattice;
use system::*;

/// Configuration for constructing a substrate.
pub struct SubstrateConf {
    /// The type of lattice which will be generated.
    pub lattice: LatticeType,
    /// Base residue to generate coordinates for.
    pub residue: ResidueBase,
    /// Desired size of substrate along x and y.
    pub size: (f64, f64),
    /// Optionally use a random uniform distribution with this
    /// deviation to shift residue positions along z. The
    /// positions are shifted with the range (-std_z, +std_z)
    /// where std_z is the input devation.
    pub std_z: Option<f64>,
}

/// Lattice types which a substrate can be constructed from.
pub enum LatticeType {
    /// A hexagonal (honey comb) lattice with bond spacing `a`.
    Hexagonal { a: f64 },
    /// A triclinic lattice with base vectors of length `a` and `b`.
    /// Vector `a` is directed along the x axis and vector `b` is separated
    /// to it by the input angle `gamma` in degrees.
    Triclinic { a: f64, b: f64, gamma: f64 },
}

/// Create a substrate of input configuration and return as a `System`.
///
/// The returned system's size will be adjusted to a multiple of the
/// substrate spacing along both directions. Thus the system can be
/// periodically replicated along x and y.
///
/// # Errors
/// Returns an Error if the either of the input size are non-positive.
pub fn create_substrate(conf: &SubstrateConf) -> Result<System> {
    let (dx, dy) = conf.size;
    if dx < 0.0 || dy < 0.0 {
        return Err(
            GrafenError::RunError("cannot create a substrate of negative size".to_string())
        );
    }

    let mut lattice = match conf.lattice {
        LatticeType::Hexagonal { a } => {
            Lattice::hexagonal(a)
        },
        LatticeType::Triclinic { a, b, gamma } => {
            Lattice::triclinic(a, b, gamma.to_radians())
        },
    }.with_size(dx, dy).finalize();

    if let Some(std) = conf.std_z {
        lattice = lattice.uniform_distribution(std);
    };

    Ok(System {
        dimensions: lattice.box_size,
        residues: lattice.coords.iter().map(|&coord| conf.residue.to_residue(&coord)).collect(),
    })
}

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

    fn setup_conf() -> SubstrateConf {
        SubstrateConf {
            lattice: LatticeType::Hexagonal { a: 1.0 },
            residue: ResidueBase {
                code: "GRPH",
                atoms: vec![Atom { code: "C", position: Coord::new(0.0, 0.0, 0.0) }],
            },
            size: (10.0, 10.0),
            std_z: None,
        }
    }

    #[test]
    fn negative_sizes_return_error() {
        let mut conf = setup_conf();
        assert!(create_substrate(&conf).is_ok());

        conf.size = (-1.0, 1.0);
        assert!(create_substrate(&conf).is_err());

        conf.size = (1.0, -1.0);
        assert!(create_substrate(&conf).is_err());
    }

    #[test]
    fn uniform_distribution_is_set() {
        // The graphene is ordinarily positioned at z = 0.0
        let mut conf = setup_conf();
        let regular = create_substrate(&conf).unwrap();
        assert!(regular.residues.iter().all(|r| r.position.z == 0.0));

        conf.std_z = Some(1.0);
        let uniform = create_substrate(&conf).unwrap();

        // Non-zero variance This can fail, but it should not be common!
        // How else to assert that a distribution has been applied, though?
        assert!(uniform.residues.iter().map(|r| r.position.z).all(|z| z == 0.0) == false);

        // But no positions should exceed the input distribution max
        assert!(uniform.residues.iter().all(|r| r.position.z.abs() <= 1.0));
    }
}
<|endoftext|>