Merge pull request #356 from elichai/2019-12-macros

Simplifying macros
This commit is contained in:
Andrew Poelstra 2020-10-08 14:05:23 +00:00 committed by GitHub
commit 7c47c9a341
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 90 deletions

View File

@ -91,75 +91,7 @@ macro_rules! impl_array_newtype {
} }
} }
impl ::std::ops::Index<usize> for $thing {
type Output = $ty;
#[inline]
fn index(&self, index: usize) -> &$ty {
let &$thing(ref dat) = self;
&dat[index]
}
}
impl_index_newtype!($thing, $ty); impl_index_newtype!($thing, $ty);
impl ::std::cmp::PartialEq for $thing {
#[inline]
fn eq(&self, other: &$thing) -> bool {
&self[..] == &other[..]
}
}
impl ::std::cmp::Eq for $thing {}
impl ::std::cmp::PartialOrd for $thing {
#[inline]
fn partial_cmp(&self, other: &$thing) -> Option<::std::cmp::Ordering> {
Some(self.cmp(&other))
}
}
impl ::std::cmp::Ord for $thing {
#[inline]
fn cmp(&self, other: &$thing) -> ::std::cmp::Ordering {
// manually implement comparison to get little-endian ordering
// (we need this for our numeric types; non-numeric ones shouldn't
// be ordered anyway except to put them in BTrees or whatever, and
// they don't care how we order as long as we're consistent).
for i in 0..$len {
if self[$len - 1 - i] < other[$len - 1 - i] { return ::std::cmp::Ordering::Less; }
if self[$len - 1 - i] > other[$len - 1 - i] { return ::std::cmp::Ordering::Greater; }
}
::std::cmp::Ordering::Equal
}
}
#[cfg_attr(feature = "clippy", allow(expl_impl_clone_on_copy))] // we don't define the `struct`, we have to explicitly impl
impl ::std::clone::Clone for $thing {
#[inline]
fn clone(&self) -> $thing {
$thing::from(&self[..])
}
}
impl ::std::marker::Copy for $thing {}
impl ::std::hash::Hash for $thing {
#[inline]
fn hash<H>(&self, state: &mut H)
where H: ::std::hash::Hasher
{
(&self[..]).hash(state);
}
fn hash_slice<H>(data: &[$thing], state: &mut H)
where H: ::std::hash::Hasher
{
for d in data.iter() {
(&d[..]).hash(state);
}
}
}
} }
} }
@ -177,6 +109,16 @@ macro_rules! impl_array_newtype_show {
/// Implements standard indexing methods for a given wrapper type /// Implements standard indexing methods for a given wrapper type
macro_rules! impl_index_newtype { macro_rules! impl_index_newtype {
($thing:ident, $ty:ty) => { ($thing:ident, $ty:ty) => {
impl ::std::ops::Index<usize> for $thing {
type Output = $ty;
#[inline]
fn index(&self, index: usize) -> &$ty {
&self.0[index]
}
}
impl ::std::ops::Index<::std::ops::Range<usize>> for $thing { impl ::std::ops::Index<::std::ops::Range<usize>> for $thing {
type Output = [$ty]; type Output = [$ty];
@ -754,14 +696,6 @@ macro_rules! user_enum {
$(#[$doc] $elem),* $(#[$doc] $elem),*
} }
impl ::std::fmt::Debug for $name {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.pad(match *self {
$($name::$elem => $txt),*
})
}
}
impl ::std::fmt::Display for $name { impl ::std::fmt::Display for $name {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.pad(match *self { f.pad(match *self {

View File

@ -46,7 +46,7 @@ pub const PROTOCOL_VERSION: u32 = 70001;
user_enum! { user_enum! {
/// The cryptocurrency to act on /// The cryptocurrency to act on
#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)] #[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Debug)]
pub enum Network { pub enum Network {
/// Classic Bitcoin /// Classic Bitcoin
Bitcoin <-> "bitcoin", Bitcoin <-> "bitcoin",

View File

@ -30,12 +30,14 @@ use util::{base58, endian};
use util::key::{PublicKey, PrivateKey}; use util::key::{PublicKey, PrivateKey};
/// A chain code /// A chain code
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ChainCode([u8; 32]); pub struct ChainCode([u8; 32]);
impl_array_newtype!(ChainCode, u8, 32); impl_array_newtype!(ChainCode, u8, 32);
impl_array_newtype_show!(ChainCode); impl_array_newtype_show!(ChainCode);
impl_bytes_newtype!(ChainCode, 32); impl_bytes_newtype!(ChainCode, 32);
/// A fingerprint /// A fingerprint
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Fingerprint([u8; 4]); pub struct Fingerprint([u8; 4]);
impl_array_newtype!(Fingerprint, u8, 4); impl_array_newtype!(Fingerprint, u8, 4);
impl_array_newtype_show!(Fingerprint); impl_array_newtype_show!(Fingerprint);

View File

@ -21,7 +21,7 @@
macro_rules! construct_uint { macro_rules! construct_uint {
($name:ident, $n_words:expr) => ( ($name:ident, $n_words:expr) => (
/// Little-endian large integer type /// Little-endian large integer type
#[repr(C)] #[derive(Copy, Clone, PartialEq, Eq, Hash, Default)]
pub struct $name(pub [u64; $n_words]); pub struct $name(pub [u64; $n_words]);
impl_array_newtype!($name, u64, $n_words); impl_array_newtype!($name, u64, $n_words);
@ -136,6 +136,27 @@ macro_rules! construct_uint {
} }
} }
impl PartialOrd for $name {
#[inline]
fn partial_cmp(&self, other: &$name) -> Option<::std::cmp::Ordering> {
Some(self.cmp(&other))
}
}
impl Ord for $name {
#[inline]
fn cmp(&self, other: &$name) -> ::std::cmp::Ordering {
// We need to manually implement ordering because we use little-endian
// and the auto derive is a lexicographic ordering(i.e. memcmp)
// which with numbers is equivilant to big-endian
for i in 0..$n_words {
if self[$n_words - 1 - i] < other[$n_words - 1 - i] { return ::std::cmp::Ordering::Less; }
if self[$n_words - 1 - i] > other[$n_words - 1 - i] { return ::std::cmp::Ordering::Greater; }
}
::std::cmp::Ordering::Equal
}
}
impl ::std::ops::Add<$name> for $name { impl ::std::ops::Add<$name> for $name {
type Output = $name; type Output = $name;
@ -232,18 +253,12 @@ macro_rules! construct_uint {
(0x40 * ($n_words - 1)) + arr[$n_words - 1].trailing_zeros() as usize (0x40 * ($n_words - 1)) + arr[$n_words - 1].trailing_zeros() as usize
} }
fn zero() -> $name { $name([0; $n_words]) } fn zero() -> $name { Default::default() }
fn one() -> $name { fn one() -> $name {
$name({ let mut ret = [0; $n_words]; ret[0] = 1; ret }) $name({ let mut ret = [0; $n_words]; ret[0] = 1; ret })
} }
} }
impl ::std::default::Default for $name {
fn default() -> $name {
$crate::util::BitArray::zero()
}
}
impl ::std::ops::BitAnd<$name> for $name { impl ::std::ops::BitAnd<$name> for $name {
type Output = $name; type Output = $name;
@ -356,11 +371,7 @@ macro_rules! construct_uint {
} }
} }
impl ::std::fmt::Display for $name { display_from_debug!($name);
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
<::std::fmt::Debug>::fmt(self, f)
}
}
impl $crate::consensus::Encodable for $name { impl $crate::consensus::Encodable for $name {
#[inline] #[inline]