use std;
use geometry::prelude::*;
pub type Sinkf = Sink<Float>;
pub type Sink2f = Sink<Point2f>;
#[derive(Debug, Clone)]
pub struct Sink<T> {
inner: Vec<T>,
ndim: usize,
nsample: usize,
idim: usize,
isample: usize,
}
impl<T: Copy> Sink<T> {
pub fn new(ndim: usize, nsample: usize) -> Sink<T> {
let inner = unsafe {
vec![std::mem::uninitialized(); ndim * nsample]
};
Sink{
inner: inner,
ndim: ndim,
nsample: nsample,
idim: 0usize,
isample: 0usize,
}
}
#[inline]
pub fn reset(&mut self) {
self.idim = 0;
self.isample = 0;
}
#[inline]
pub fn next_dim(&mut self) -> Option<T> {
if self.idim >= self.ndim {
None
} else {
let isample = self.isample;
let idim = self.idim;
self.idim += 1usize;
Some((*self)[(isample, idim)])
}
}
#[inline]
pub fn next_sample(&mut self) -> bool {
if self.isample + 1 >= self.nsample {
false
} else {
self.isample += 1;
true
}
}
#[inline]
pub fn set_sample_index(&mut self, idx: usize) -> bool {
if idx >= self.nsample {
false
} else {
self.isample = idx;
true
}
}
#[inline]
pub fn ndim(&self) -> usize {
self.ndim
}
#[inline]
pub fn nsample(&self) -> usize {
self.nsample
}
#[inline]
#[allow(dead_code)]
pub fn idim(&self) -> usize {
self.idim
}
#[inline]
#[allow(dead_code)]
pub fn isample(&self) -> usize {
self.isample
}
}
impl<T> std::ops::Index<(usize, usize)> for Sink<T> {
type Output = T;
#[inline]
fn index(&self, index: (usize, usize)) -> &T {
&self.inner[index.0 * self.ndim + index.1]
}
}
impl<T> std::ops::IndexMut<(usize, usize)> for Sink<T> {
#[inline]
fn index_mut(&mut self, index: (usize, usize)) -> &mut T {
&mut self.inner[index.0 * self.ndim + index.1]
}
}
impl<T> std::ops::Index<usize> for Sink<T> {
type Output = [T];
#[inline]
fn index(&self, index: usize) -> &[T] {
let offset = index * self.ndim;
&self.inner[offset..(offset+self.ndim)]
}
}
impl<T> std::ops::IndexMut<usize> for Sink<T> {
#[inline]
fn index_mut(&mut self, index: usize) -> &mut [T] {
let offset = index * self.ndim;
&mut self.inner[offset..(offset+self.ndim)]
}
}