#[macro_use] extern crate try_opt;
extern crate serde;
extern crate streaming_iterator;
use std::fmt;
use std::fmt::Debug;
use std::hash::{Hash, Hasher};
use std::iter::{FromIterator, IntoIterator};
use std::marker::PhantomData;
use std::mem;
use std::ops::Index;
use std::slice;
use serde::de::{Deserialize, Deserializer, DeserializeSeed, SeqAccess, Visitor};
use serde::ser::{Serialize, Serializer, SerializeSeq};
use streaming_iterator as stream;
use streaming_iterator::StreamingIterator;
pub struct Jagged2<T> {
onsets: Box<[(*mut T, usize)]>,
}
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct Jagged2Builder<T> {
storage: Vec<T>,
onsets: Vec<(*mut T, usize)>,
}
pub struct Stream<'a, T: 'a> {
onset_iter: stream::Convert<slice::Iter<'a, (*mut T, usize)>>,
}
impl<T> Index<[usize; 2]> for Jagged2<T> {
type Output = T;
fn index(&self, index: [usize; 2]) -> &T {
self.get(index).unwrap()
}
}
impl<T> Drop for Jagged2<T> {
fn drop(&mut self) {
unsafe {
Box::from_raw(self.as_flat_slice_mut() as *mut [T]);
}
}
}
impl<T> Default for Jagged2<T> {
fn default() -> Self {
let onsets = Vec::new().into_boxed_slice();
Self{ onsets }
}
}
impl<T> Debug for Jagged2<T>
where T: Debug
{
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
if self.is_empty() {
return f.write_str("[]");
}
f.write_str("[\n")?;
let mut stream = self.stream();
while let Some(row) = stream.next() {
f.write_str(" ")?;
row.fmt(f)?;
f.write_str("\n")?;
}
f.write_str("]")?;
Ok(())
}
}
impl<T, ICol> FromIterator<ICol> for Jagged2<T>
where ICol: IntoIterator<Item=T>
{
fn from_iter<IRow>(row_iter: IRow) -> Self
where IRow: IntoIterator<Item=ICol>
{
let row_iters: Vec<_> = row_iter.into_iter().map(|i| i.into_iter()).collect();
let row_estimate = row_iters.len();
let item_estimate = row_iters.iter().map(|i| i.size_hint().0).sum();
let mut builder = Jagged2Builder::with_capacity(row_estimate, item_estimate);
for row in row_iters {
builder.extend(row);
}
builder.into()
}
}
impl<'a, T> StreamingIterator for Stream<'a, T> {
type Item = [T];
fn advance(&mut self) {
self.onset_iter.advance();
}
fn get(&self) -> Option<&Self::Item> {
let &(row_addr, row_len) = *try_opt!(self.onset_iter.get());
Some(unsafe {
slice::from_raw_parts(row_addr, row_len)
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.onset_iter.size_hint()
}
fn count(self) -> usize {
self.onset_iter.count()
}
fn nth(&mut self, n: usize) -> Option<&Self::Item> {
let &(row_addr, row_len) = *try_opt!(self.onset_iter.nth(n));
Some(unsafe {
slice::from_raw_parts(row_addr, row_len)
})
}
}
impl<T> Clone for Jagged2<T>
where T: Clone
{
fn clone(&self) -> Self {
let mut builder = Jagged2Builder::with_capacity(self.len(), self.flat_len());
let mut rows = self.stream();
while let Some(row) = rows.next() {
builder.extend(row.iter().cloned());
}
builder.into()
}
}
impl<T> PartialEq for Jagged2<T>
where T: PartialEq
{
fn eq(&self, other: &Jagged2<T>) -> bool {
if self.len() != other.len() {
return false;
}
let (mut stream_me, mut stream_other) = (self.stream(), other.stream());
while let (Some(row_me), Some(row_other)) = (stream_me.next(), stream_other.next()) {
if row_me != row_other {
return false;
}
}
true
}
}
impl<T> Eq for Jagged2<T> where T: Eq {}
impl<T> Hash for Jagged2<T>
where T: Hash
{
fn hash<H>(&self, state: &mut H)
where H: Hasher
{
let mut stream = self.stream();
while let Some(row) = stream.next() {
row.hash(state);
}
}
}
impl<T> Serialize for Jagged2<T>
where T: Serialize
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
let mut seq = serializer.serialize_seq(Some(self.len()))?;
let mut stream = self.stream();
while let Some(row) = stream.next() {
seq.serialize_element(row)?;
}
seq.end()
}
}
impl<'de, T> Deserialize<'de> for Jagged2<T>
where T: Deserialize<'de>
{
fn deserialize<D>(deserializer: D) -> Result<Jagged2<T>, D::Error>
where D: Deserializer<'de>
{
struct JaggedVisitor<T>(PhantomData<T>);
struct RowDeserializer<'a, T: 'a>(&'a mut Jagged2Builder<T>);
struct SeqAccessToIter<'a, A, E: 'a, T> {
seq: A,
result: &'a mut Result<(), E>,
phantom: PhantomData<T>,
}
impl<'de, T> Visitor<'de> for JaggedVisitor<T>
where T: Deserialize<'de>
{
type Value = Jagged2<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an array of arrays of T (i.e. [[T]])")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where A: SeqAccess<'de>
{
let mut builder = Jagged2Builder::with_capacity(seq.size_hint().unwrap_or(0), 0);
while seq.next_element_seed(RowDeserializer(&mut builder))?.is_some() {}
Ok(builder.into())
}
}
impl<'de, 'a, T> DeserializeSeed<'de> for RowDeserializer<'a, T>
where T: Deserialize<'de>
{
type Value = (); fn deserialize<D>(self, deserializer: D) -> Result<(), D::Error>
where D: Deserializer<'de>
{
deserializer.deserialize_seq(self)
}
}
impl<'de, 'a, T: 'a> Visitor<'de> for RowDeserializer<'a, T>
where T: Deserialize<'de>
{
type Value = ();
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an sequence of T (i.e. [T])")
}
fn visit_seq<A>(self, seq: A) -> Result<(), A::Error>
where A: SeqAccess<'de>
{
let mut result: Result<(), A::Error> = Ok(());
self.0.extend(SeqAccessToIter{
seq,
result: &mut result,
phantom: PhantomData
});
result
}
}
impl<'de, 'a, A, T> Iterator for SeqAccessToIter<'a, A, A::Error, T>
where A: SeqAccess<'de>,
T: Deserialize<'de>
{
type Item = T;
fn next(&mut self) -> Option<T> {
match self.seq.next_element() {
Ok(value) => value,
Err(error) => {
*self.result = Err(error);
None
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
match self.seq.size_hint() {
None => (0, None),
Some(value) => (value, Some(value)),
}
}
}
deserializer.deserialize_seq(JaggedVisitor(PhantomData))
}
}
impl<T> Jagged2<T> {
pub fn get(&self, index: [usize; 2]) -> Option<&T> {
let view = try_opt!(self.get_row(index[0]));
view.get(index[1])
}
pub fn get_mut(&mut self, index: [usize; 2]) -> Option<&mut T> {
let view = try_opt!(self.get_row_mut(index[0]));
view.get_mut(index[1])
}
pub fn get_row(&self, row: usize) -> Option<&[T]> {
let &(row_onset, row_len) = try_opt!(self.onsets.get(row));
unsafe {
Some(slice::from_raw_parts(row_onset, row_len))
}
}
pub fn get_row_mut(&mut self, row: usize) -> Option<&mut [T]> {
let &(row_onset, row_len) = try_opt!(self.onsets.get(row));
unsafe {
Some(slice::from_raw_parts_mut(row_onset, row_len))
}
}
pub fn as_flat_slice(&self) -> &[T] {
match self.onsets.get(0) {
None => &[],
Some(&(addr_start, _)) => unsafe {
slice::from_raw_parts(addr_start, self.flat_len())
}
}
}
pub fn as_flat_slice_mut(&mut self) -> &mut [T] {
match self.onsets.get(0) {
None => &mut [],
Some(&(addr_start, _)) => unsafe {
slice::from_raw_parts_mut(addr_start, self.flat_len())
}
}
}
pub fn flat_len(&self) -> usize {
if mem::size_of::<T>() == 0 {
self.onsets.iter().map(|row| row.1).sum()
} else {
let (last_addr, last_len) = match self.onsets.last() {
None => return 0,
Some(&(addr, len)) => (addr, len),
};
let first_addr = self.onsets[0].0;
(last_addr as usize - first_addr as usize) / mem::size_of::<T>() + last_len
}
}
pub fn len(&self) -> usize {
self.onsets.len()
}
pub fn is_empty(&self) -> bool {
self.onsets.is_empty()
}
pub fn stream<'a>(&'a self) -> Stream<'a, T> {
Stream{ onset_iter: stream::convert(self.onsets.iter()) }
}
pub fn into_boxed_slice(self) -> Box<[T]> {
self.into_components().0
}
fn into_components(mut self) -> (Box<[T]>, Box<[(*mut T, usize)]>) {
unsafe {
let slice = Box::from_raw(self.as_flat_slice_mut() as *mut [T]);
let onsets = mem::replace(&mut self.onsets, Vec::new().into_boxed_slice());
mem::forget(self);
(slice, onsets)
}
}
}
impl<T> Jagged2Builder<T> {
pub fn new() -> Self {
Default::default()
}
pub fn with_capacity(row_cap: usize, item_cap: usize) -> Self {
Self {
storage: Vec::with_capacity(item_cap),
onsets: Vec::with_capacity(row_cap),
}
}
pub fn len(&self) -> usize {
self.onsets.len()
}
pub fn flat_len(&self) -> usize {
self.storage.len()
}
pub fn resize(&mut self, new_len: usize) {
let onset_padding = (self.flat_len() as *mut T, 0);
self.onsets.resize(new_len, onset_padding);
let new_size = match self.onsets.last() {
None => 0, Some(&(row_start, row_length)) => (row_start as usize) + row_length,
};
self.storage.drain(new_size..);
}
}
impl<T> Default for Jagged2Builder<T> {
fn default() -> Self {
Self {
storage: Vec::new(),
onsets: Vec::new(),
}
}
}
impl<T> Extend<T> for Jagged2Builder<T> {
fn extend<I>(&mut self, row: I)
where I: IntoIterator<Item=T>
{
let row_data = row.into_iter();
let row_start = self.storage.len();
self.storage.extend(row_data);
let row_end = self.storage.len();
self.onsets.push((row_start as *mut T, row_end-row_start));
}
}
impl<'a, T> Extend<&'a T> for Jagged2Builder<T>
where T: 'a + Copy
{
fn extend<I>(&mut self, row: I)
where I: IntoIterator<Item=&'a T>
{
self.extend(row.into_iter().cloned())
}
}
impl<T> Into<Jagged2<T>> for Jagged2Builder<T> {
fn into(self) -> Jagged2<T> {
let storage = Box::into_raw(self.storage.into_boxed_slice()) as *mut T;
let mut onsets = self.onsets;
for onset in onsets.iter_mut() {
unsafe {
onset.0 = storage.offset(onset.0 as isize);
}
}
let onsets = onsets.into_boxed_slice();
Jagged2{ onsets }
}
}