Bitwise Or Assign and some additional convenience in Hash.

This commit is contained in:
Gav Wood 2016-01-09 22:30:13 +01:00
parent 88810a5762
commit 568d28e94b
4 changed files with 35 additions and 6 deletions

View File

@ -4,7 +4,7 @@ use std::str::FromStr;
use std::fmt; use std::fmt;
use std::ops; use std::ops;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::ops::{Index, IndexMut, Deref, DerefMut, BitOr, BitAnd, BitXor}; use std::ops::{Index, IndexMut, Deref, DerefMut, BitOr, BitOrAssign, BitAnd, BitXor};
use std::cmp::{PartialOrd, Ordering}; use std::cmp::{PartialOrd, Ordering};
use rustc_serialize::hex::*; use rustc_serialize::hex::*;
use error::EthcoreError; use error::EthcoreError;
@ -19,6 +19,8 @@ use uint::U256;
/// Note: types implementing `FixedHash` must be also `BytesConvertable`. /// Note: types implementing `FixedHash` must be also `BytesConvertable`.
pub trait FixedHash: Sized + BytesConvertable + Populatable { pub trait FixedHash: Sized + BytesConvertable + Populatable {
fn new() -> Self; fn new() -> Self;
/// Synonym for `new()`. Prefer to new as it's more readable.
fn zero() -> Self;
fn random() -> Self; fn random() -> Self;
fn randomize(&mut self); fn randomize(&mut self);
fn size() -> usize; fn size() -> usize;
@ -64,6 +66,10 @@ macro_rules! impl_hash {
$from([0; $size]) $from([0; $size])
} }
fn zero() -> $from {
$from([0; $size])
}
fn random() -> $from { fn random() -> $from {
let mut hash = $from::new(); let mut hash = $from::new();
hash.randomize(); hash.randomize();
@ -299,6 +305,15 @@ macro_rules! impl_hash {
} }
} }
/// Moving BitOrAssign
impl<'a> BitOrAssign<&'a $from> for $from {
fn bitor_assign(&mut self, rhs: &'a Self) {
for i in 0..$size {
self.0[i] = self.0[i] | rhs.0[i];
}
}
}
/// BitAnd on references /// BitAnd on references
impl <'a> BitAnd for &'a $from { impl <'a> BitAnd for &'a $from {
type Output = $from; type Output = $from;
@ -417,6 +432,11 @@ impl_hash!(H520, 65);
impl_hash!(H1024, 128); impl_hash!(H1024, 128);
impl_hash!(H2048, 256); impl_hash!(H2048, 256);
/// Constant address for point 0. Often used as a default.
pub static ZERO_ADDRESS: Address = Address([0x00; 20]);
/// Constant 256-bit datum for 0. Often used as a default.
pub static ZERO_H256: H256 = H256([0x00; 32]);
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use hash::*; use hash::*;

View File

@ -1,3 +1,4 @@
#![feature(op_assign_traits)]
//! Ethcore-util library //! Ethcore-util library
//! //!
//! ### Rust version: //! ### Rust version:

View File

@ -29,11 +29,8 @@ pub fn ordered_trie_root(input: Vec<Vec<u8>>) -> H256 {
// first put elements into btree to sort them by nibbles // first put elements into btree to sort them by nibbles
// optimize it later // optimize it later
.into_iter() .into_iter()
.fold(BTreeMap::new(), | mut acc, vec | { .enumerate()
let len = acc.len(); .fold(BTreeMap::new(), | mut acc, (i, vec) | { acc.insert(rlp::encode(&i), vec); acc })
acc.insert(rlp::encode(&len), vec);
acc
})
// then move them to a vector // then move them to a vector
.into_iter() .into_iter()
.map(|(k, v)| (as_nibbles(&k), v) ) .map(|(k, v)| (as_nibbles(&k), v) )

View File

@ -424,6 +424,17 @@ macro_rules! construct_uint {
} }
} }
impl fmt::Display for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let &$name(ref data) = self;
try!(write!(f, "0x"));
for ch in data.iter().rev() {
try!(write!(f, "{:02x}", ch));
}
Ok(())
}
}
impl Hash for $name { impl Hash for $name {
fn hash<H>(&self, state: &mut H) where H: Hasher { fn hash<H>(&self, state: &mut H) where H: Hasher {
unsafe { state.write(::std::slice::from_raw_parts(self.0.as_ptr() as *mut u8, self.0.len() * 8)); } unsafe { state.write(::std::slice::from_raw_parts(self.0.as_ptr() as *mut u8, self.0.len() * 8)); }