From: Ian Jackson Date: Fri, 20 Nov 2020 23:36:16 +0000 (+0000) Subject: fix zcoord debug - make it a newtype X-Git-Tag: otter-0.2.0~455 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=78879e082f89d16170a74ea909e630c98fa39a34;p=otter.git fix zcoord debug - make it a newtype Signed-off-by: Ian Jackson --- diff --git a/Cargo.lock.example b/Cargo.lock.example index 7a7e0f68..9727eb58 100644 --- a/Cargo.lock.example +++ b/Cargo.lock.example @@ -352,6 +352,17 @@ dependencies = [ "syn 1.0.48", ] +[[package]] +name = "derive_more" +version = "0.99.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298998b1cf6b5b2c8a7b023dfd45821825ce3ba8a8af55c921a0e734e4653f76" +dependencies = [ + "proc-macro2 1.0.24", + "quote 1.0.7", + "syn 1.0.48", +] + [[package]] name = "deunicode" version = "0.4.3" @@ -1164,6 +1175,7 @@ dependencies = [ name = "otter-zcoord" version = "0.0.1" dependencies = [ + "derive_more", "fehler", "serde", "serde_with", diff --git a/zcoord/Cargo.toml b/zcoord/Cargo.toml index f7705995..7a29c1f0 100644 --- a/zcoord/Cargo.toml +++ b/zcoord/Cargo.toml @@ -13,7 +13,8 @@ path = "zcoord.rs" [dependencies] -serde = { version = "1", features = ["derive","rc"] } +derive_more = "0.99" fehler = "1" thiserror = "1" +serde = { version = "1", features = ["derive","rc"] } serde_with = "1" diff --git a/zcoord/zcoord.rs b/zcoord/zcoord.rs index 03ca0e1e..328c6528 100644 --- a/zcoord/zcoord.rs +++ b/zcoord/zcoord.rs @@ -72,6 +72,7 @@ use std::num::{TryFromIntError, Wrapping}; use std::str; use std::str::FromStr; use fehler::{throw, throws}; +use derive_more::*; use serde::{Serialize, Deserialize}; use thiserror::Error; use serde_with::DeserializeFromStr; @@ -85,19 +86,23 @@ const BITS_PER_DIGIT : usize = 5; const DIGITS_PER_LIMB : usize = 10; type RawLimbVal = u64; -type LimbVal = Wrapping; +#[derive(Copy,Clone,Eq,PartialEq,Ord,PartialOrd)] +#[derive(Neg,Add,BitAnd,Sub,Shr,ShrAssign)] +#[derive(Debug)] +pub struct LimbVal (Wrapping); -const DELTA : LimbVal = Wrapping(0x4000_0000); -const ZERO : LimbVal = Wrapping(0); -const ONE : LimbVal = Wrapping(1); +const DELTA : LimbVal = lv(0x4000_0000); +const ZERO : LimbVal = lv(0); +const ONE : LimbVal = lv(1); +const MINUS_ONE : LimbVal = lv(-1i64 as u64); const RAW_LIMB_MODULUS : RawLimbVal = 1u64 << BITS_PER_LIMB; const BITS_PER_LIMB : usize = BITS_PER_DIGIT * DIGITS_PER_LIMB; -const DIGIT_MASK : LimbVal = Wrapping((1u64 << BITS_PER_DIGIT) - 1); +const DIGIT_MASK : LimbVal = lv((1u64 << BITS_PER_DIGIT) - 1); const TEXT_PER_LIMB : usize = DIGITS_PER_LIMB + 1; -const LIMB_MODULUS : LimbVal = Wrapping(RAW_LIMB_MODULUS); -const LIMB_MASK : LimbVal = Wrapping(RAW_LIMB_MODULUS-1); +const LIMB_MODULUS : LimbVal = lv(RAW_LIMB_MODULUS); +const LIMB_MASK : LimbVal = lv(RAW_LIMB_MODULUS-1); #[derive(DeserializeFromStr,SerializeDisplay)] pub struct ZCoord(innards::Innards); @@ -124,6 +129,18 @@ pub enum LogicError { #[error("{0}")] RangeBackwards (#[from] RangeBackwards ), } +//---------- LimbVal ---------- + +impl From for LimbVal { + fn from(raw: RawLimbVal) -> LimbVal { lv(raw) } +} + +const fn lv(raw: RawLimbVal) -> LimbVal { LimbVal(Wrapping(raw)) } + +impl LimbVal { + fn primitive(self) -> RawLimbVal { self.0.0 } +} + //---------- Mutabel ---------- #[derive(Clone,Debug)] @@ -144,7 +161,7 @@ impl Mutable { for lt in tail.chunks(TEXT_PER_LIMB) { let s = str::from_utf8(<[0..DIGITS_PER_LIMB]).unwrap(); let v = RawLimbVal::from_str_radix(s, 1 << BITS_PER_DIGIT).unwrap(); - limbs.push(Wrapping(v)); + limbs.push(v.into()); } Mutable { limbs } } @@ -184,7 +201,7 @@ impl AddSubOffset for Increment { pub struct Decrement; impl AddSubOffset for Decrement { fn init_delta(&self) -> LimbVal { -DELTA } - const CARRY_DELTA : LimbVal = Wrapping(ONE .0.wrapping_neg()); + const CARRY_DELTA : LimbVal = MINUS_ONE; const NEW_LIMBS : LimbVal = LIMB_MASK; #[throws(as Option)] fn check_underflow(_: &Mutable, i: usize, nv: LimbVal) { @@ -244,7 +261,7 @@ impl Mutable { for mut l in limbs.iter().cloned() { if l >= LIMB_MODULUS { throw!(Overflow) }; for p in w[0..DIGITS_PER_LIMB].rchunks_exact_mut(1) { - let v = (l & DIGIT_MASK).0 as u8; + let v = (l & DIGIT_MASK).primitive() as u8; p[0] = if v < 10 { b'0' + v } else { (b'a' - 10) + v }; l >>= BITS_PER_DIGIT; } @@ -314,7 +331,7 @@ impl Mutable { if la == lb { continue } let wantgaps = count+1; - let avail = (lb.0 as i64) - (la.0 as i64) + let avail = (lb.primitive() as i64) - (la.primitive() as i64) + if borrowing { RAW_LIMB_MODULUS as i64 } else { 0}; if avail < 0 { throw!(RangeBackwards) } let avail = avail as u64; @@ -339,14 +356,14 @@ impl Mutable { } else { // Not enough space here, but we can pick a unique value for // this limb, and divide the next limb evenly - current.limbs[i] = la + Wrapping(avail/2); + current.limbs[i] = la + (avail/2).into(); i += 1; step = (RAW_LIMB_MODULUS-1) / wantgaps; init = ZERO; } current.extend_to_limb(i); current.limbs[i] = init; - break 'ok ASRD { i, step: Wrapping(step) }; + break 'ok ASRD { i, step: step.into() }; } }; IteratorCore { current, aso } }