#![allow(unused_parens)]
#![cfg_attr(feature="impl_simd", feature(portable_simd))]
#![cfg_attr(not(feature="std"), no_std)]
#![allow(non_camel_case_types, non_snake_case)]
#[cfg(feature="impl_num")]
extern crate num_traits;
#[cfg(feature="impl_num")]
use num_traits as num;
#[cfg(feature="std")]
extern crate core;
#[cfg(feature="impl_serde")]
extern crate serde;
use core::{ptr, mem};
pub struct Elements<T> {
tuple: T,
index: usize
}
impl<T> Elements<T> {
#[inline(always)]
fn new(t: T) -> Elements<T> {
Elements { tuple: t, index: 0 }
}
}
pub struct IntoElements<T: TupleElements> {
tuple: Option<T>,
index: usize
}
impl<T: TupleElements> IntoElements<T> {
#[inline(always)]
fn new(t: T) -> IntoElements<T> {
IntoElements { tuple: Some(t), index: 0 }
}
}
pub unsafe trait TupleElements: Sized {
type Element;
const N: usize;
#[inline(always)]
fn elements(&self) -> Elements<&Self> { Elements::new(self) }
#[inline(always)]
fn elements_mut(&mut self) -> Elements<&mut Self> { Elements::new(self) }
#[inline(always)]
fn into_elements(self) -> IntoElements<Self> { IntoElements::new(self) }
fn get(&self, n: usize) -> Option<&Self::Element>;
fn get_mut(&mut self, n: usize) -> Option<&mut Self::Element>;
fn from_iter<I>(iter: I) -> Option<Self> where I: Iterator<Item=Self::Element>;
}
pub trait Map<T>: TupleElements {
type Output: TupleElements<Element=T>;
fn map<F>(self, f: F) -> Self::Output where F: Fn(Self::Element) -> T;
fn map_mut<F>(self, f: F) -> Self::Output where F: FnMut(Self::Element) -> T;
}
pub trait Splat<T> {
fn splat(t: T) -> Self;
}
pub trait Call<T> {
type Output;
fn call(&self, args: T) -> Self::Output;
}
pub trait CallOnce<T> {
type Output;
fn call_once(self, args: T) -> Self::Output;
}
pub trait CallMut<T> {
type Output;
fn call_mut(&mut self, args: T) -> Self::Output;
}
#[derive(Debug, Eq, PartialEq)]
pub enum ConvertError {
OutOfBounds
}
impl<'a, T> Iterator for Elements<&'a T> where T: TupleElements {
type Item = &'a T::Element;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
let t = self.tuple.get(self.index);
if let Some(_) = t {
self.index += 1;
}
t
}
}
impl<'a, T> Iterator for Elements<&'a mut T> where T: TupleElements {
type Item = &'a mut T::Element;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
if let Some(t) = self.tuple.get_mut(self.index) {
self.index += 1;
Some(unsafe { &mut *(t as *mut T::Element) })
} else {
None
}
}
}
impl<T> Iterator for IntoElements<T> where T: TupleElements {
type Item = T::Element;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
match self.tuple.as_mut().unwrap().get(self.index) {
Some(p) => {
self.index += 1; let v = unsafe { ptr::read(p) }; Some(v)
},
None => None
}
}
}
impl<T> Drop for IntoElements<T> where T: TupleElements {
#[inline(always)]
fn drop(&mut self) {
let mut tuple = self.tuple.take().unwrap();
for i in self.index .. T::N {
unsafe {
ptr::drop_in_place(tuple.get_mut(i).unwrap());
}
}
mem::forget(tuple);
}
}
pub trait OpJoin<RHS> {
type Output;
fn join(self, rhs: RHS) -> Self::Output;
}
pub trait OpSplit<L> {
type R;
fn split(self) -> (L, Self::R);
}
pub trait OpRotateLeft {
type Output;
fn rot_l(self) -> Self::Output;
}
pub trait OpRotateRight {
type Output;
fn rot_r(self) -> Self::Output;
}
pub trait OpReverse {
type Output;
fn reverse(self) -> Self::Output;
}
#[macro_use]
mod utils;
#[macro_export]
macro_rules! impl_tuple {
($def:ident) => ($def!(
T1 A1 { A.a.0 }
T2 A2 { A.a.0, B.b.1 }
T3 A3 { A.a.0, B.b.1, C.c.2 }
T4 A4 { A.a.0, B.b.1, C.c.2, D.d.3 }
T5 A5 { A.a.0, B.b.1, C.c.2, D.d.3, E.e.4 }
T6 A6 { A.a.0, B.b.1, C.c.2, D.d.3, E.e.4, F.f.5 }
T7 A7 { A.a.0, B.b.1, C.c.2, D.d.3, E.e.4, F.f.5, G.g.6 }
T8 A8 { A.a.0, B.b.1, C.c.2, D.d.3, E.e.4, F.f.5, G.g.6, H.h.7 }
T9 A9 { A.a.0, B.b.1, C.c.2, D.d.3, E.e.4, F.f.5, G.g.6, H.h.7, I.i.8 }
T10 A10 { A.a.0, B.b.1, C.c.2, D.d.3, E.e.4, F.f.5, G.g.6, H.h.7, I.i.8, J.j.9 }
T11 A11 { A.a.0, B.b.1, C.c.2, D.d.3, E.e.4, F.f.5, G.g.6, H.h.7, I.i.8, J.j.9, K.k.10 }
T12 A12 { A.a.0, B.b.1, C.c.2, D.d.3, E.e.4, F.f.5, G.g.6, H.h.7, I.i.8, J.j.9, K.k.10, L.l.11 }
T13 A13 { A.a.0, B.b.1, C.c.2, D.d.3, E.e.4, F.f.5, G.g.6, H.h.7, I.i.8, J.j.9, K.k.10, L.l.11, M.m.12 }
T14 A14 { A.a.0, B.b.1, C.c.2, D.d.3, E.e.4, F.f.5, G.g.6, H.h.7, I.i.8, J.j.9, K.k.10, L.l.11, M.m.12, N.n.13 }
T15 A15 { A.a.0, B.b.1, C.c.2, D.d.3, E.e.4, F.f.5, G.g.6, H.h.7, I.i.8, J.j.9, K.k.10, L.l.11, M.m.12, N.n.13, O.o.14 }
T16 A16 { A.a.0, B.b.1, C.c.2, D.d.3, E.e.4, F.f.5, G.g.6, H.h.7, I.i.8, J.j.9, K.k.10, L.l.11, M.m.12, N.n.13, O.o.14, P.p.15 }
);)
}
macro_rules! init {
($($Tuple:ident $Arr:ident { $($T:ident . $t:ident . $idx:tt),* } )*) => ($(
pub struct $Tuple<$($T),*>($(pub $T),*);
pub type $Arr<T> = $Tuple<$(A!(T, $T)),*>;
)*)
}
impl_tuple!(init);
mod m_init;
mod m_ops;
mod m_convert;
mod m_array;
#[cfg(feature="impl_num")]
mod m_num;
mod m_tuple;
mod m_iter;
mod m_call;
#[cfg(all(feature="impl_simd", any(target_arch="x86", target_arch="x86_64")))]
#[macro_use]
mod m_simd;
#[cfg(feature="std")]
mod m_std;
#[cfg(feature="impl_serde")]
mod m_serde;
pub fn tuple<T, I>(iter: I) -> Option<T> where
T: TupleElements, I: Iterator<Item=T::Element>
{
T::from_iter(iter)
}