diff --git a/Cargo.lock b/Cargo.lock index 894f79a..19c955d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,7 +35,7 @@ dependencies = [ "jemalloc-ctl 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "jemallocator 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "modtype 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "modtype 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -210,16 +210,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "modtype" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "modtype_derive 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "modtype_derive 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "modtype_derive" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -695,8 +698,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff" "checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43" "checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" -"checksum modtype 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7bf71f32c60f674f1b998ddb1c4cb964e868dcd38b3c404701a890fea73a8613" -"checksum modtype_derive 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75bf38a727330495bdc947e427006b448f52ec44cc85ea6ce8e09b17add0d0e9" +"checksum modtype 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6bffa83fe8c98bd8eaa2ca4f4cf867d61940718049d4faeb496d9e83435e4b" +"checksum modtype_derive 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b2f5ebe9234d3ba9510165e562083b7b7ad985a37407abd4ec48ffb61066a941" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" "checksum num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db" "checksum num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "57450397855d951f1a41305e54851b1a7b8f5d2e349543a02a2effe25459f718" diff --git a/Cargo.toml b/Cargo.toml index 564db6b..76bb1ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ ordered-float = "=1.0.2" # 剰余関連。普通の整数型などと同じ感覚で扱うだけで自動的にmodを取ってくれる # 答えの整数をMで割った余りが要求される設問で便利 -modtype = "=0.6.0" +modtype = "=0.7.0" # 英数字などのASCII文字専用の文字列。文字にインデックスでアクセスしたり # substringを簡単に作ったりできる diff --git a/src/main.rs b/src/main.rs index 5f41d2f..5d22cc1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,8 +5,7 @@ type UnitResult = Result<(), Box>; fn main() -> UnitResult { run_proconio(); run_ordered_float(); - // run_modtype()?; - // run_modtype_derive(); + run_modtype()?; run_ascii()?; run_bitset_fixed(); run_permutohedron(); @@ -71,9 +70,8 @@ fn run_ordered_float() { use std::hash::{Hash, Hasher}; let mut v = [ - 8.20, -5.83, -0.21, 3.44, -7.12, 3.39, -0.72, -1.07, 9.36, NAN, - 5.16, -2.81, 1.02, -8.67, 5.77, -1.24, 0.44, 9.91, -7.06, INFINITY, - -3.93, 5.82, 9.64, -8.04, -4.53, + 8.20, -5.83, -0.21, 3.44, -7.12, 3.39, -0.72, -1.07, 9.36, NAN, 5.16, -2.81, 1.02, -8.67, + 5.77, -1.24, 0.44, 9.91, -7.06, INFINITY, -3.93, 5.82, 9.64, -8.04, -4.53, ] .iter() .map(|&n| OrderedFloat(n)) @@ -106,114 +104,112 @@ fn test_ordered_float() { } // modtype -// these codes were taken from examples at https://github.com/qryxip/modtype/tree/master/examples -// fn run_modtype() -> UnitResult { -// use modtype::use_modtype; -// -// #[use_modtype] -// type F = modtype::u64::F<1_000_000_007u64>; -// -// let mut a = "13".parse::()?; -// a += F(1_000_000_000); -// assert_eq!(a, F(6)); -// -// Ok(()) -// } - -// #[test] -// fn test_modtype() -> UnitResult { -// run_modtype() -// } - -// these codes were taken from examples at https://github.com/qryxip/modtype/blob/master/examples/derive.rs -// fn run_modtype_derive() { -// use modtype::{use_modtype, ConstValue}; -// use std::marker::PhantomData; -// -// #[use_modtype] -// type F = F_<17u32>; -// -// #[derive( -// modtype::new, -// modtype::new_unchecked, -// modtype::get, -// Default, -// Clone, -// Copy, -// PartialEq, -// Eq, -// PartialOrd, -// Ord, -// modtype::From, -// modtype::Into, -// modtype::Display, -// modtype::Debug, -// modtype::FromStr, -// modtype::Deref, -// modtype::Neg, -// modtype::Add, -// modtype::AddAssign, -// modtype::Sub, -// modtype::SubAssign, -// modtype::Mul, -// modtype::MulAssign, -// modtype::Div, -// modtype::DivAssign, -// modtype::Rem, -// modtype::RemAssign, -// modtype::Num, -// modtype::Unsigned, -// modtype::Bounded, -// modtype::Zero, -// modtype::One, -// modtype::FromPrimitive, -// modtype::Inv, -// modtype::CheckedNeg, -// modtype::CheckedAdd, -// modtype::CheckedSub, -// modtype::CheckedMul, -// modtype::CheckedDiv, -// modtype::CheckedRem, -// modtype::Pow, -// modtype::Integer, -// )] -// #[modtype( -// modulus = "M::VALUE", -// std = "std", -// num_traits = "num::traits", -// num_integer = "num::integer", -// num_bigint = "num::bigint", -// from(InnerValue, BigUint, BigInt), -// debug(SingleTuple), -// neg(for_ref = true), -// add(for_ref = true), -// add_assign(for_ref = true), -// sub(for_ref = true), -// sub_assign(for_ref = true), -// mul(for_ref = true), -// mul_assign(for_ref = true), -// div(for_ref = true), -// div_assign(for_ref = true), -// rem(for_ref = true), -// rem_assign(for_ref = true), -// inv(for_ref = true), -// pow(for_ref = true) -// )] -// struct F_> { -// #[modtype(value)] -// __value: u32, -// phantom: PhantomData M>, -// } -// assert_eq!(F(7) + F(13), F(3)); -// assert_eq!(F(5) - F(11), F(11)); -// assert_eq!(F(3), F(4) * F(5)); -// assert_eq!(F(3) / F(4), F(5)); -// } - -// #[test] -// fn test_modtype_derive() { -// run_modtype_derive(); -// } +fn run_modtype() -> UnitResult { + use modtype::cartridges::{Additive, AllowFlexibleRhs, Field, ManuallyAdjust, Multiplicative}; + use modtype::{use_modtype, Cartridge, ConstValue}; + use num::{BigInt, BigRational, CheckedDiv as _}; + + use std::marker::PhantomData; + + { + #[use_modtype] + type F = modtype::F<1_000_000_007u64>; + + assert_eq!((F(1_000_000_006) + F(2)).to_string(), "1"); + } + { + #[allow(non_snake_case)] + modtype::thread_local::F::with(1_000_000_007u64, |F| { + assert_eq!((F(1_000_000_006) + F(2)).to_string(), "1"); + }); + } + { + #[allow(non_snake_case)] + let F = modtype::non_static::F::factory(1_000_000_007u64); + + assert_eq!((F(1_000_000_006) + F(2)).to_string(), "1"); + } + { + #[use_modtype] + type F = modtype::ModType>, 1_000_000_007u64>; + + let mut x = F(1); + x += F(1); + x += 1u64; + x += 1i32; + x += 1f64; + x += BigInt::from(1u32); + x += BigRational::new(BigInt::from(1u32), BigInt::from(1u32)); + assert_eq!(x, F(7)); + } + { + #[use_modtype] + type Z = modtype::ModType, 57u32>; + + assert_eq!(Z(56) * Z(56), Z(1)); + assert_eq!(Z(1).checked_div(&Z(13)), Some(Z(22))); // 13・22 ≡ 1 (mod 57) + } + { + #[use_modtype] + type Z = modtype::ModType, 1_000_000_007u64>; + + let mut x = Z(1_000_000_006); + + x += Z(1); + assert_eq!(*x.get_mut_unchecked(), 1_000_000_007); + + x += Z(u64::max_value() / 2 - 1_000_000_007); + assert_eq!(*x.get_mut_unchecked(), u64::max_value() / 2); + + x += Z(1); + assert_eq!( + *x.get_mut_unchecked(), + (u64::max_value() / 2 + 1) % 1_000_000_007, + ); + } + { + #[use_modtype] + type Z = modtype::ModType, 1_000_000_007u64>; + + let mut x = Z(1_000_000_006); + + x += Z(u64::max_value() - 1_000_000_006); + assert_eq!(*x.get_mut_unchecked(), u64::max_value()); + + x.adjust(); + assert_eq!(*x.get_mut_unchecked(), u64::max_value() % 1_000_000_007); + } + { + #[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/3673 + #[derive(modtype::ModType)] + #[modtype(modulus = "M::VALUE", cartridge = "C")] + struct ModType, M: ConstValue> { + #[modtype(value)] + value: u64, + phantom: PhantomData (C, M)>, + } + + impl> ModType, M> { + fn new(value: u64) -> Self { + Self { + value, + phantom: PhantomData, + } + } + } + + #[use_modtype] + type F = ModType, 1_000_000_007u64>; + + assert_eq!((-F(1)).to_string(), "1000000006"); + } + Ok(()) +} + +#[test] +fn test_modtype() -> UnitResult { + run_modtype() +} // ascii fn run_ascii() -> UnitResult { @@ -226,9 +222,9 @@ fn run_ascii() -> UnitResult { let (i0, _) = ix.next().ok_or_else(|| "got none")?; let (i1, _) = ix.next().ok_or_else(|| "got none")?; - assert_eq!(s[..i0].as_str(), "2019"); + assert_eq!(s[..i0].as_str(), "2019"); assert_eq!(s[i0 + 1..i1].as_str(), "07"); - assert_eq!(s[i1 + 1..].as_str(), "01"); + assert_eq!(s[i1 + 1..].as_str(), "01"); // split is not available in ascii 0.9.1 // https://github.com/tomprogrammer/rust-ascii/issues/62