#[macro_export] macro_rules! field_common_deps {
() => {
#[macro_use] extern crate newtype_derive;
use std::fmt;
#[cfg(feature = "nightly")]
use std::convert::TryFrom;
#[cfg(feature = "nightly")]
use finite_fields::error::ConversionError;
use finite_fields::error::{DivisionError, OverflowError};
use std::cmp::Ordering;
use std::iter::{FromIterator, IntoIterator, Iterator};
use std::ops::{Add, Sub, Mul, Div, BitAnd, BitOr, BitXor, Index, IndexMut, Shl, Shr};
pub trait Peano where Self: Sized {
fn successor(&self) -> Result<Self, OverflowError>;
fn predecessor(&self) -> Result<Self, OverflowError>;
fn cmp (&self, other: &Self) -> Ordering;
}
}
}
#[macro_export] macro_rules! unit_binary_arithmetic {
() => {
impl Peano for b1 {
fn successor(&self) -> Result<b1, OverflowError> {
match self {
&ZERO => Ok(ONE),
&ONE => Err(OverflowError::Default { arg1: self.to_string(),
arg2: ONE.to_string() })
}
}
fn predecessor(&self) -> Result<b1, OverflowError> {
match self {
&ONE => Ok(ZERO),
&ZERO => Err(OverflowError::Default { arg1: self.to_string(),
arg2: ONE.to_string() })
}
}
fn cmp (&self, other: &Self) -> Ordering {
if &self == other { Ordering::Equal }
else if let &Ok(next) = &self.successor() {
if next == other { Ordering::Less }
else { Ordering::Greater }
}
else { Ordering::Greater }
}
}
impl PartialOrd for b1 {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Add for b1 {
type Output = Result<b1, OverflowError>;
fn add(self, other: b1) -> Result<b1, OverflowError> {
match other {
ZERO => Ok(self),
ONE => self.successor()
}
}
}
impl<'a> Add<b1> for &'a b1 {
type Output = Result<b1, OverflowError>;
fn add(self, other: b1) -> Result<b1, OverflowError> {
match other {
ZERO => Ok(*self),
ONE => self.successor()
}
}
}
impl<'a> Add<&'a b1> for &'a b1 {
type Output = Result<b1, OverflowError>;
fn add(self, other: &b1) -> Result<b1, OverflowError> {
match other {
&ZERO => Ok(ZERO),
&ONE => self.successor()
}
}
}
impl Sub for b1 {
type Output = Result<b1, OverflowError>;
fn sub(self, other: b1) -> Result<b1, OverflowError> {
match other {
ZERO => Ok(self),
ONE => self.predecessor()
}
}
}
impl<'a> Sub<b1> for &'a b1 {
type Output = Result<b1, OverflowError>;
fn sub(self, other: b1) -> Result<b1, OverflowError> {
match other {
ZERO => Ok(*self),
ONE => self.predecessor()
}
}
}
impl<'a> Sub<&'a b1> for &'a b1 {
type Output = Result<b1, OverflowError>;
fn sub(self, other: &b1) -> Result<b1, OverflowError> {
match other {
&ZERO => Ok(*self),
&ONE => self.predecessor()
}
}
}
impl Mul for b1 {
type Output = Result<Self, OverflowError>;
fn mul(self, other: b1) -> Result<b1, OverflowError> {
Ok(b1(self.0 && other.0))
}
}
impl<'a> Mul<b1> for &'a b1 {
type Output = Result<b1, OverflowError>;
fn mul(self, other: b1) -> Result<b1, OverflowError> {
Ok(b1(self.0 && other.0))
}
}
impl<'a> Mul<&'a b1> for &'a b1 {
type Output = Result<b1, OverflowError>;
fn mul(self, other: &b1) -> Result<b1, OverflowError> {
Ok(b1(self.0 && other.0))
}
}
impl Div for b1 {
type Output = Result<Self, DivisionError>;
fn div(self, other: b1) -> Result<b1, DivisionError> {
if other == ZERO {
Err(DivisionError::DivideByZeroError {
arg1: self.to_string()
})
} else { Ok(self) }
}
}
impl<'a> Div<b1> for &'a b1 {
type Output = Result<b1, DivisionError>;
fn div(self, other: b1) -> Result<b1, DivisionError> {
if other == ZERO {
Err(DivisionError::DivideByZeroError {
arg1: self.to_string()
})
} else { Ok(*self) }
}
}
impl<'a> Div<&'a b1> for &'a b1 {
type Output = Result<b1, DivisionError>;
fn div(self, other: &b1) -> Result<b1, DivisionError> {
if other == ZERO {
Err(DivisionError::DivideByZeroError {
arg1: self.to_string()
})
} else { Ok(*self) }
}
}
}
}
#[macro_export] macro_rules! unit_binary {
() => {
field_common_deps! {}
#[derive(Clone,Copy,Debug,PartialEq,Eq)]
pub struct b1(bool);
NewtypeFrom! {
() pub struct b1(bool);
}
impl b1 {
pub fn new(val: bool) -> b1 {
b1(val)
}
pub fn max(&self) -> usize {
1
}
}
impl fmt::Display for b1 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.0 {
false => write!(f, "{}", 0),
true => write!(f, "{}", 1)
}
}
}
#[cfg(feature = "nightly")]
impl TryFrom<usize> for b1 {
type Err = ConversionError;
fn try_from(val: usize) -> Result<Self, Self::Err> {
match val {
0 => Ok(ZERO),
1 => Ok(ONE),
_ => Err(ConversionError::OverflowError { arg1: val.to_string() })
}
}
}
impl From<b1> for usize {
fn from(val: b1) -> usize {
match val {
ZERO => 0,
ONE => 1
}
}
}
impl BitAnd for b1 {
type Output = Self;
fn bitand(self, other: b1) -> Self {
b1(self.0 & other.0)
}
}
impl BitOr for b1 {
type Output = Self;
fn bitor(self, other: b1) -> Self {
b1(self.0 | other.0)
}
}
impl BitXor for b1 {
type Output = Self;
fn bitxor(self, other: b1) -> Self {
b1(self.0 ^ other.0)
}
}
pub const ZERO: b1 = b1(false);
pub const ONE: b1 = b1(true);
impl<'a> PartialEq<b1> for &'a b1 {
fn eq(&self, other: &b1) -> bool {
self.0 == other.0
}
}
impl<'a> PartialEq<&'a b1> for b1 {
fn eq(&self, other: &&'a b1) -> bool {
self.0 == other.0
}
}
unit_binary_arithmetic! {}
}
}
#[macro_export] macro_rules! binary_type_arithmetic {
($tyname:ident, $fieldwidth:expr) => {
impl Add for $tyname {
type Output = Result<Self, OverflowError>;
fn add(self, other: $tyname) -> Result<$tyname, OverflowError> {
let mut output = $tyname([ZERO; $fieldwidth]);
let mut carry = false;
for place in (0..other.0.len()).rev() {
let augend = match carry {
false => self.0[place].clone(),
true => match self.0[place].successor() {
Ok(res) => {
res.clone()
},
Err(_) => {
ZERO
}
}
};
match augend + other.0[place] {
Ok(res) => {
output.0[place] = res;
carry = false;
}
Err(_) => {
output.0[place] = ZERO;
carry = true
}
}
}
if carry {
Err(OverflowError::Default { arg1: self.to_string(),
arg2: other.to_string() })
} else {
Ok(output)
}
}
}
impl<'a> Add<$tyname> for &'a $tyname {
type Output = Result<$tyname, OverflowError>;
fn add(self, other: $tyname) -> Result<$tyname, OverflowError> {
let mut output = $tyname([ZERO; $fieldwidth]);
let mut carry = false;
for place in (0..other.0.len()).rev() {
let augend = match carry {
false => self.0[place].clone(),
true => match self.0[place].successor() {
Ok(res) => {
res.clone()
},
Err(_) => {
ZERO
}
}
};
match augend + other.0[place] {
Ok(res) => {
output.0[place] = res;
carry = false;
}
Err(_) => {
output.0[place] = ZERO;
carry = true
}
}
}
if carry {
Err(OverflowError::Default { arg1: self.to_string(),
arg2: other.to_string() })
} else {
Ok(output)
}
}
}
impl<'a> Add<&'a $tyname> for &'a $tyname {
type Output = Result<$tyname, OverflowError>;
fn add(self, other: &$tyname) -> Result<$tyname, OverflowError> {
let mut output = $tyname([ZERO; $fieldwidth]);
let mut carry = false;
for place in (0..other.0.len()).rev() {
let augend = match carry {
false => self.0[place].clone(),
true => match self.0[place].successor() {
Ok(res) => {
res.clone()
},
Err(_) => {
ZERO
}
}
};
match augend + other.0[place] {
Ok(res) => {
output.0[place] = res;
carry = false;
}
Err(_) => {
output.0[place] = ZERO;
carry = true
}
}
}
if carry {
Err(OverflowError::Default { arg1: self.to_string(),
arg2: other.to_string() })
} else {
Ok(output)
}
}
}
impl Sub for $tyname {
type Output = Result<$tyname, OverflowError>;
fn sub(self, other: $tyname) -> Result<$tyname, OverflowError> {
let mut output = $tyname([ZERO; $fieldwidth]);
let mut carry = false;
for place in (0..other.0.len()).rev() {
let augend = match carry {
false => self.0[place],
true => match self.0[place].predecessor() {
Ok(res) => {
res
},
Err(_) => {
ZERO
}
}
};
match augend - other.0[place] {
Ok(res) => {
output.0[place] = res;
carry = false;
}
Err(_) => {
output.0[place] = ONE;
carry = true
}
}
}
if carry {
Err(OverflowError::Default { arg1: self.to_string(),
arg2: other.to_string() })
} else {
Ok(output)
}
}
}
impl<'a> Sub<$tyname> for &'a $tyname {
type Output = Result<$tyname, OverflowError>;
fn sub(self, other: $tyname) -> Result<$tyname, OverflowError> {
let mut output = $tyname([ZERO; $fieldwidth]);
let mut carry = false;
for place in (0..other.0.len()).rev() {
let augend = match carry {
false => self.0[place],
true => match self.0[place].predecessor() {
Ok(res) => {
res
},
Err(_) => {
ZERO
}
}
};
match augend - other.0[place] {
Ok(res) => {
output.0[place] = res;
carry = false;
}
Err(_) => {
output.0[place] = ONE;
carry = true
}
}
}
if carry {
Err(OverflowError::Default { arg1: self.to_string(),
arg2: other.to_string() })
} else {
Ok(output)
}
}
}
impl<'a> Sub<&'a $tyname> for &'a $tyname {
type Output = Result<$tyname, OverflowError>;
fn sub(self, other: &$tyname) -> Result<$tyname, OverflowError> {
let mut output = $tyname([ZERO; $fieldwidth]);
let mut carry = false;
for place in (0..other.0.len()).rev() {
let augend = match carry {
false => self.0[place],
true => match self.0[place].predecessor() {
Ok(res) => {
res
},
Err(_) => {
ZERO
}
}
};
match augend - other.0[place] {
Ok(res) => {
output.0[place] = res;
carry = false;
}
Err(_) => {
output.0[place] = ONE;
carry = true
}
}
}
if carry {
Err(OverflowError::Default { arg1: self.to_string(),
arg2: other.to_string() })
} else {
Ok(output)
}
}
}
impl Peano for $tyname {
fn successor(&self) -> Result<$tyname, OverflowError> {
let mut one: $tyname = $tyname([ZERO; $fieldwidth]);
one[$fieldwidth - 1] = ONE;
self + one
}
fn predecessor(&self) -> Result<$tyname, OverflowError> {
let mut one: $tyname = $tyname([ZERO; $fieldwidth]);
one[$fieldwidth - 1] = ONE;
self - one
}
fn cmp (&self, other: &Self) -> Ordering {
if *self == *other { Ordering::Equal }
else {
match *self - *other {
Ok(_) => Ordering::Greater,
Err(_) => Ordering::Less
}
}
}
}
impl PartialOrd for $tyname {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl BitAnd for $tyname {
type Output = Self;
fn bitand(self, other: $tyname) -> Self {
let mut output = $tyname([ZERO; $fieldwidth]);
for place in (0..other.0.len()).rev() {
output.0[place] = self.0[place] & other.0[place]
}
output
}
}
impl<'a> BitAnd<$tyname> for &'a $tyname {
type Output = $tyname;
fn bitand(self, other: $tyname) -> $tyname {
let mut output = $tyname([ZERO; $fieldwidth]);
for place in (0..other.0.len()).rev() {
output.0[place] = self.0[place] & other.0[place]
}
output
}
}
impl<'a> BitAnd<&'a $tyname> for &'a $tyname {
type Output = $tyname;
fn bitand(self, other: &$tyname) -> $tyname {
let mut output = $tyname([ZERO; $fieldwidth]);
for place in (0..other.0.len()).rev() {
output.0[place] = self.0[place] & other.0[place]
}
output
}
}
impl BitOr for $tyname {
type Output = Self;
fn bitor(self, other: $tyname) -> Self {
let mut output = $tyname([ZERO; $fieldwidth]);
for place in (0..other.0.len()).rev() {
output.0[place] = self.0[place] | other.0[place]
}
output
}
}
impl<'a> BitOr<$tyname> for &'a $tyname {
type Output = $tyname;
fn bitor(self, other: $tyname) -> $tyname {
let mut output = $tyname([ZERO; $fieldwidth]);
for place in (0..other.0.len()).rev() {
output.0[place] = self.0[place] | other.0[place]
}
output
}
}
impl<'a> BitOr<&'a $tyname> for &'a $tyname {
type Output = $tyname;
fn bitor(self, other: &$tyname) -> $tyname {
let mut output = $tyname([ZERO; $fieldwidth]);
for place in (0..other.0.len()).rev() {
output.0[place] = self.0[place] | other.0[place]
}
output
}
}
impl BitXor for $tyname {
type Output = Self;
fn bitxor(self, other: $tyname) -> Self {
let mut output = $tyname([ZERO; $fieldwidth]);
for place in (0..other.0.len()).rev() {
output.0[place] = self.0[place] ^ other.0[place]
}
output
}
}
impl<'a> BitXor<$tyname> for &'a $tyname {
type Output = $tyname;
fn bitxor(self, other: $tyname) -> $tyname {
let mut output = $tyname([ZERO; $fieldwidth]);
for place in (0..other.0.len()).rev() {
output.0[place] = self.0[place] ^ other.0[place]
}
output
}
}
impl<'a> BitXor<&'a $tyname> for &'a $tyname {
type Output = $tyname;
fn bitxor(self, other: &$tyname) -> $tyname {
let mut output = $tyname([ZERO; $fieldwidth]);
for place in (0..other.0.len()).rev() {
output.0[place] = self.0[place] ^ other.0[place]
}
output
}
}
impl Shr<usize> for $tyname {
type Output = Self;
fn shr(self, rhs: usize) -> Self {
let mut dest_arr = [ZERO; $fieldwidth];
for dest_ind in 0..dest_arr.len() {
if dest_ind < rhs {
dest_arr[dest_ind] = ZERO;
} else {
dest_arr[dest_ind] = self.0[dest_ind - rhs];
}
}
$tyname(dest_arr)
}
}
impl Shl<usize> for $tyname {
type Output = Self;
fn shl(self, rhs: usize) -> Self {
let mut dest_arr = [ZERO; $fieldwidth];
for dest_ind in 0..dest_arr.len() {
if dest_ind < rhs {
dest_arr[dest_ind] = self.0[dest_ind + rhs];
} else {
dest_arr[dest_ind] = ZERO;
}
}
$tyname(dest_arr)
}
}
impl Mul for $tyname {
type Output = Result<$tyname, OverflowError>;
fn mul(self, other: $tyname) -> Result<$tyname, OverflowError> {
let mut output = $tyname([ZERO; $fieldwidth]);
let mut mult_rhs = other.clone();
let mut one: $tyname = $tyname([ZERO; $fieldwidth]);
one[$fieldwidth - 1] = ONE;
let zero = $tyname([ZERO; $fieldwidth]);
while mult_rhs > zero {
if let Ok(sum) = output + self {
output = sum
} else {
return Err(OverflowError::Default { arg1: self.to_string(),
arg2: other.to_string() })
}
mult_rhs = (mult_rhs - one).unwrap();
}
Ok(output)
}
}
impl<'a> Mul<$tyname> for &'a $tyname {
type Output = Result<$tyname, OverflowError>;
fn mul(self, other: $tyname) -> Result<$tyname, OverflowError> {
let mut output = $tyname([ZERO; $fieldwidth]);
let mut mult_rhs = other.clone();
let mut one: $tyname = $tyname([ZERO; $fieldwidth]);
one[$fieldwidth - 1] = ONE;
let zero = $tyname([ZERO; $fieldwidth]);
while mult_rhs > zero {
if let Ok(sum) = output + *self {
output = sum
} else {
return Err(OverflowError::Default { arg1: self.to_string(),
arg2: other.to_string() })
}
mult_rhs = (mult_rhs - one).unwrap();
}
Ok(output)
}
}
impl<'a> Mul<&'a $tyname> for &'a $tyname {
type Output = Result<$tyname, OverflowError>;
fn mul(self, other: &$tyname) -> Result<$tyname, OverflowError> {
let mut output = $tyname([ZERO; $fieldwidth]);
let mut mult_rhs = other.clone();
let mut one: $tyname = $tyname([ZERO; $fieldwidth]);
one[$fieldwidth - 1] = ONE;
let zero = $tyname([ZERO; $fieldwidth]);
while mult_rhs > zero {
if let Ok(sum) = output + *self {
output = sum
} else {
return Err(OverflowError::Default { arg1: self.to_string(),
arg2: other.to_string() })
}
mult_rhs = (mult_rhs - one).unwrap();
}
Ok(output)
}
}
impl Div for $tyname {
type Output = Result<$tyname, DivisionError>;
fn div(self, other: $tyname) -> Result<$tyname, DivisionError> {
let mut one: $tyname = $tyname([ZERO; $fieldwidth]);
one[$fieldwidth - 1] = ONE;
let zero = $tyname([ZERO; $fieldwidth]);
if other == zero {
return Err(DivisionError::DivideByZeroError { arg1: self.to_string() })
} else if self < other {
return Err(DivisionError::OverflowError { arg1: self.to_string(),
arg2: other.to_string() })
}
let mut div_lhs = other.clone();
let mut sub_count = zero;
while div_lhs > other {
if let Ok(difference) = div_lhs - other {
div_lhs = difference;
if let Ok(sum) = sub_count + one {
sub_count = sum;
} else {
return Err(DivisionError::OverflowError { arg1: self.to_string(),
arg2: other.to_string() })
}
} else {
break;
}
}
Ok(sub_count)
}
}
impl<'a> Div<$tyname> for &'a $tyname {
type Output = Result<$tyname, DivisionError>;
fn div(self, other: $tyname) -> Result<$tyname, DivisionError> {
let mut one: $tyname = $tyname([ZERO; $fieldwidth]);
one[$fieldwidth - 1] = ONE;
let zero = $tyname([ZERO; $fieldwidth]);
if other == zero {
return Err(DivisionError::DivideByZeroError { arg1: self.to_string() })
} else if self < &other {
return Err(DivisionError::OverflowError { arg1: self.to_string(),
arg2: other.to_string() })
}
let mut div_lhs = other.clone();
let mut sub_count = zero;
while div_lhs > other {
if let Ok(difference) = div_lhs - other {
div_lhs = difference;
if let Ok(sum) = sub_count + one {
sub_count = sum;
} else {
return Err(DivisionError::OverflowError { arg1: self.to_string(),
arg2: other.to_string() })
}
} else {
break;
}
}
Ok(sub_count)
}
}
impl<'a> Div<&'a $tyname> for &'a $tyname {
type Output = Result<$tyname, DivisionError>;
fn div(self, other: &$tyname) -> Result<$tyname, DivisionError> {
let mut one: $tyname = $tyname([ZERO; $fieldwidth]);
one[$fieldwidth - 1] = ONE;
let zero = $tyname([ZERO; $fieldwidth]);
if *other == zero {
return Err(DivisionError::DivideByZeroError { arg1: self.to_string() })
} else if self < other {
return Err(DivisionError::OverflowError { arg1: self.to_string(),
arg2: other.to_string() })
}
let mut div_lhs = other.clone();
let mut sub_count = zero;
while div_lhs > *other {
if let Ok(difference) = div_lhs - *other {
div_lhs = difference;
if let Ok(sum) = sub_count + one {
sub_count = sum;
} else {
return Err(DivisionError::OverflowError { arg1: self.to_string(),
arg2: other.to_string() })
}
} else {
break;
}
}
Ok(sub_count)
}
}
}
}
#[macro_export] macro_rules! binary_type {
($tyname:ident, $fieldwidth:expr) => {
unit_binary! {}
#[derive(Clone, Copy, PartialEq, Debug)]
pub struct $tyname([b1; $fieldwidth]);
impl $tyname {
pub fn new(vals: [b1; $fieldwidth]) -> $tyname {
$tyname(vals)
}
pub fn max(&self) -> usize {
(2 as usize).pow($fieldwidth) - 1
}
pub fn len(&self) -> usize {
$fieldwidth
}
pub fn iter(self) -> Iter {
Iter { data: self, index: 0, end: self.len() }
}
pub fn bits(&self) -> [b1; $fieldwidth] {
self.0
}
pub fn shift_concat(&self, val: b1) -> $tyname {
let mut shifted_bin = *self << 1;
shifted_bin[self.len() - 1] = val;
shifted_bin
}
pub fn unshift_concat(&self, val: b1) -> $tyname {
let mut unshifted_bin = *self >> 1;
unshifted_bin[0] = val;
unshifted_bin
}
}
impl fmt::Display for $tyname {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut bit_string = String::with_capacity(self.len());
for bit in self.bits().iter() { bit_string.push_str(&bit.to_string()); }
write!(f, "{}", bit_string)
}
}
#[cfg(feature = "nightly")]
impl TryFrom<usize> for $tyname {
type Err = ConversionError;
fn try_from(val: usize) -> Result<Self, Self::Err> {
let mut out_val = $tyname::new([ZERO; $fieldwidth]);
if val > out_val.max() {
Err(ConversionError::OverflowError { arg1: val.to_string() })
} else if val == 0 {
Ok(out_val)
} else {
let mut dec = val.clone();
if dec % 2 != 0 {
out_val[$fieldwidth - 1] = ONE;
}
for place in 0..$fieldwidth {
if dec > 1 {
dec = dec / 2;
out_val[place] = ONE;
} else {
break;
}
}
Ok(out_val)
}
}
}
impl From<usize> for $tyname {
fn from(val: usize) -> Self {
let mut out_val = $tyname::new([ZERO; $fieldwidth]);
if val > out_val.max() {
panic!("Can't convert {} to $tyname, it's too big.", val);
} else if val == 0 {
out_val
} else {
let mut dec = val.clone();
if dec % 2 != 0 {
out_val[$fieldwidth - 1] = ONE;
}
for place in 0..$fieldwidth {
if dec > 1 {
dec = dec / 2;
out_val[place] = ONE;
} else {
break;
}
}
out_val
}
}
}
#[cfg(feature = "nightly")]
impl<'a> TryFrom <&'a [b1]> for $tyname {
type Err = ConversionError;
fn try_from(val: &[b1]) -> Result<Self, Self::Err> {
if val.len() != $fieldwidth {
Err(ConversionError::LengthError { arg1: val.len() })
} else {
let mut out_val = $tyname::new([ZERO; $fieldwidth]);
for place in 0..out_val.len() {
out_val[place] = val[place];
}
Ok(out_val)
}
}
}
impl From<$tyname> for usize {
fn from(val: $tyname) -> usize {
val.bits().iter()
.rev()
.enumerate()
.fold(0, |accum, (place_ind, &bit)| {
usize::from(bit) *
(2 as usize).pow((place_ind) as u32) + accum
})
}
}
impl<'a> Index<usize> for $tyname {
type Output = b1;
fn index<'b>(&'b self, idx: usize) -> &'b b1 {
&self.0[idx]
}
}
impl IndexMut<usize> for $tyname {
fn index_mut<'a>(&'a mut self, index: usize) -> &'a mut b1 {
&mut self.0[index]
}
}
pub struct Iter {
data: $tyname,
index: usize,
end: usize
}
impl Iterator for Iter {
type Item = b1;
fn next(&mut self) -> Option<b1> {
self.index += 1;
if self.index < $fieldwidth {
Some(self.data.0[self.index])
} else {
None
}
}
}
impl DoubleEndedIterator for Iter {
fn next_back(&mut self) -> Option<Self::Item> {
if self.end > 0 {
self.end -= 1;
if self.end >= self.index {
Some(self.data.0[self.end])
} else {
None
}
} else {
None
}
}
}
impl IntoIterator for $tyname {
type Item = b1;
type IntoIter = ::std::vec::IntoIter<b1>;
fn into_iter(self) -> Self::IntoIter {
self.0.to_vec().into_iter()
}
}
impl<'a> IntoIterator for &'a $tyname {
type Item = &'a b1;
type IntoIter = ::std::slice::Iter<'a,b1>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl FromIterator<b1> for $tyname {
fn from_iter<I: IntoIterator<Item=b1>>(iter: I) -> Self {
let mut collector = $tyname::new([ZERO; $fieldwidth]);
for (ind, val) in (0..collector.len()).zip(iter) {
collector[ind] = val;
}
collector
}
}
binary_type_arithmetic! { $tyname, $fieldwidth }
}
}