types.rs
1 // Copyright (c) 2025-2026 ACDC Network 2 // This file is part of the alphavm library. 3 // 4 // Alpha Chain | Delta Chain Protocol 5 // International Monetary Graphite. 6 // 7 // Derived from Aleo (https://aleo.org) and ProvableHQ (https://provable.com). 8 // They built world-class ZK infrastructure. We installed the EASY button. 9 // Their cryptography: elegant. Our modifications: bureaucracy-compatible. 10 // Original brilliance: theirs. Robert's Rules: ours. Bugs: definitely ours. 11 // 12 // Original Aleo/ProvableHQ code subject to Apache 2.0 https://www.apache.org/licenses/LICENSE-2.0 13 // All modifications and new work: CC0 1.0 Universal Public Domain Dedication. 14 // No rights reserved. No permission required. No warranty. No refunds. 15 // 16 // https://creativecommons.org/publicdomain/zero/1.0/ 17 // SPDX-License-Identifier: CC0-1.0 18 19 use crate::prelude::*; 20 21 /// Representation of an address. 22 pub trait AddressTrait: 23 Copy 24 + Clone 25 + Compare 26 + Debug 27 + Deref 28 + Eq 29 + Equal 30 + Parser 31 + Send 32 + SizeInBits 33 + SizeInBytes 34 + Sync 35 + TypeName 36 + Visibility 37 { 38 } 39 40 /// Representation of a boolean. 41 pub trait BooleanTrait: 42 BitAndAssign 43 + BitAnd<Self, Output = Self> 44 + for<'a> BitAnd<&'a Self, Output = Self> 45 + BitOrAssign 46 + BitOr<Self, Output = Self> 47 + for<'a> BitOr<&'a Self, Output = Self> 48 + BitXorAssign 49 + BitXor<Self, Output = Self> 50 + for<'a> BitXor<&'a Self, Output = Self> 51 + Copy 52 + Clone 53 + Debug 54 + Deref 55 + Eq 56 + Equal 57 + Nand 58 + Nor 59 + Not 60 + Parser 61 + Send 62 + SizeInBits 63 + SizeInDataBits 64 + SizeInBytes 65 + Sync 66 + TypeName 67 + Uniform 68 { 69 } 70 71 /// Representation of a base field element. 72 pub trait FieldTrait: 73 'static 74 + Add<Self, Output = Self> 75 + for<'a> Add<&'a Self, Output = Self> 76 + AddAssign<Self> 77 + for<'a> AddAssign<&'a Self> 78 + Clone 79 + Copy 80 + Compare 81 + Debug 82 + Deref 83 + Div<Self, Output = Self> 84 + for<'a> Div<&'a Self, Output = Self> 85 + DivAssign<Self> 86 + for<'a> DivAssign<&'a Self> 87 + Double<Output = Self> 88 + Eq 89 + Equal 90 + FromBytes 91 + core::hash::Hash 92 + Inverse<Output = Self> 93 + Mul<Self, Output = Self> 94 + for<'a> Mul<&'a Self, Output = Self> 95 + MulAssign<Self> 96 + for<'a> MulAssign<&'a Self> 97 + Neg<Output = Self> 98 + One 99 + Ord 100 + Parser 101 + Pow<Self, Output = Self> 102 + for<'a> Pow<&'a Self, Output = Self> 103 + Product<Self> 104 + for<'a> Product<&'a Self> 105 + Send 106 + SizeInBits 107 + SizeInDataBits 108 + SizeInBytes 109 + Sync 110 + Square<Output = Self> 111 + SquareRoot<Output = Self> 112 + Sub<Self, Output = Self> 113 + for<'a> Sub<&'a Self, Output = Self> 114 + SubAssign<Self> 115 + for<'a> SubAssign<&'a Self> 116 + Sum<Self> 117 + for<'a> Sum<&'a Self> 118 + ToBytes 119 + TypeName 120 + Uniform 121 + Zero 122 { 123 } 124 125 /// Representation of a group element. 126 pub trait GroupTrait<S: ScalarTrait>: 127 'static 128 + Add<Self, Output = Self> 129 + for<'a> Add<&'a Self, Output = Self> 130 + AddAssign<Self> 131 + for<'a> AddAssign<&'a Self> 132 + Clone 133 + Copy 134 + Debug 135 + Double<Output = Self> 136 + Eq 137 + Equal 138 + Mul<S> 139 + for<'a> Mul<&'a S> 140 + MulAssign<S> 141 + for<'a> MulAssign<&'a S> 142 + Neg<Output = Self> 143 + Parser 144 + Send 145 + SizeInBits 146 + SizeInBytes 147 + Sync 148 + Sub<Self, Output = Self> 149 + for<'a> Sub<&'a Self, Output = Self> 150 + SubAssign<Self> 151 + for<'a> SubAssign<&'a Self> 152 + Sum<Self> 153 + for<'a> Sum<&'a Self> 154 + TypeName 155 + Uniform 156 + Visibility 157 + Zero 158 { 159 } 160 161 /// Representation of a scalar field element. 162 pub trait ScalarTrait: 163 'static 164 + Add<Self, Output = Self> 165 + for<'a> Add<&'a Self, Output = Self> 166 + AddAssign<Self> 167 + for<'a> AddAssign<&'a Self> 168 + Clone 169 + Copy 170 + Compare 171 + Debug 172 + Deref 173 + Div<Self, Output = Self> 174 + for<'a> Div<&'a Self, Output = Self> 175 + DivAssign<Self> 176 + for<'a> DivAssign<&'a Self> 177 + Double<Output = Self> 178 + Eq 179 + Equal 180 + Inverse<Output = Self> 181 + Mul<Self, Output = Self> 182 + for<'a> Mul<&'a Self, Output = Self> 183 + MulAssign<Self> 184 + for<'a> MulAssign<&'a Self> 185 + Neg<Output = Self> 186 + One 187 + Parser 188 + Pow<Self, Output = Self> 189 + for<'a> Pow<&'a Self, Output = Self> 190 + Product<Self> 191 + for<'a> Product<&'a Self> 192 + Send 193 + SizeInBits 194 + SizeInDataBits 195 + SizeInBytes 196 + Sync 197 + Square<Output = Self> 198 + Sub<Self, Output = Self> 199 + for<'a> Sub<&'a Self, Output = Self> 200 + SubAssign<Self> 201 + for<'a> SubAssign<&'a Self> 202 + Sum<Self> 203 + for<'a> Sum<&'a Self> 204 + TypeName 205 + Uniform 206 + Zero 207 { 208 } 209 210 /// Representation of a string. 211 pub trait StringTrait: 212 Clone + Debug + Display + Eq + Equal + FromBytes + Parser + Send + Sync + ToBytes + TypeName + Uniform 213 { 214 } 215 216 /// Representation of an integer. 217 pub trait IntegerTrait<I: integer_type::IntegerType, U8: IntegerCore<u8>, U16: IntegerCore<u16>, U32: IntegerCore<u32>>: 218 IntegerCore<I> 219 + Pow<U8, Output = Self> 220 + Shl<U8, Output = Self> 221 + for<'a> Shl<&'a U8, Output = Self> 222 + ShlChecked<U8, Output = Self> 223 + ShlWrapped<U8, Output = Self> 224 + ShlAssign<U8> 225 + Shr<U8, Output = Self> 226 + for<'a> Shr<&'a U8, Output = Self> 227 + ShrChecked<U8, Output = Self> 228 + ShrWrapped<U8, Output = Self> 229 + ShrAssign<U8> 230 + Pow<U16, Output = Self> 231 + Shl<U16, Output = Self> 232 + for<'a> Shl<&'a U16, Output = Self> 233 + ShlChecked<U16, Output = Self> 234 + ShlWrapped<U16, Output = Self> 235 + ShlAssign<U16> 236 + Shr<U16, Output = Self> 237 + for<'a> Shr<&'a U16, Output = Self> 238 + ShrChecked<U16, Output = Self> 239 + ShrWrapped<U16, Output = Self> 240 + ShrAssign<U16> 241 + Pow<U32, Output = Self> 242 + Shl<U32, Output = Self> 243 + for<'a> Shl<&'a U32, Output = Self> 244 + ShlChecked<U32, Output = Self> 245 + ShlWrapped<U32, Output = Self> 246 + ShlAssign<U32> 247 + Shr<U32, Output = Self> 248 + for<'a> Shr<&'a U32, Output = Self> 249 + ShrChecked<U32, Output = Self> 250 + ShrWrapped<U32, Output = Self> 251 + ShrAssign<U32> 252 { 253 } 254 255 pub trait IntegerCore<I: integer_type::IntegerType>: 256 'static 257 + Add<Self, Output = Self> 258 + for<'a> Add<&'a Self, Output = Self> 259 + AddAssign<Self> 260 + for<'a> AddAssign<&'a Self> 261 + BitAndAssign 262 + BitAnd<Self, Output = Self> 263 + for<'a> BitAnd<&'a Self, Output = Self> 264 + BitOrAssign 265 + BitOr<Self, Output = Self> 266 + for<'a> BitOr<&'a Self, Output = Self> 267 + BitXorAssign 268 + BitXor<Self, Output = Self> 269 + for<'a> BitXor<&'a Self, Output = Self> 270 + Copy 271 + Clone 272 + Compare 273 + Debug 274 + Deref 275 + Div<Self, Output = Self> 276 + for<'a> Div<&'a Self, Output = Self> 277 + DivAssign<Self> 278 + for<'a> DivAssign<&'a Self> 279 + Eq 280 + Equal 281 + Modulo 282 + Mul<Self, Output = Self> 283 + for<'a> Mul<&'a Self, Output = Self> 284 + MulAssign<Self> 285 + for<'a> MulAssign<&'a Self> 286 + Neg<Output = Self> 287 + Not<Output = Self> 288 + One 289 + Parser 290 + Rem<Self, Output = Self> 291 + for<'a> Rem<&'a Self, Output = Self> 292 + RemAssign<Self> 293 + for<'a> RemAssign<&'a Self> 294 + Send 295 + SizeInBits 296 + SizeInBytes 297 + Sync 298 + Sub<Self, Output = Self> 299 + for<'a> Sub<&'a Self, Output = Self> 300 + SubAssign<Self> 301 + for<'a> SubAssign<&'a Self> 302 + TypeName 303 + Uniform 304 + Visibility 305 + Zero 306 { 307 } 308 309 pub mod integer_type { 310 use alphavm_utilities::{FromBits, FromBytes, ToBits, ToBytes, Uniform}; 311 312 use core::{ 313 fmt::{Debug, Display}, 314 hash::Hash, 315 num::ParseIntError, 316 ops::{Div, Rem}, 317 str::FromStr, 318 }; 319 use num_traits::{ 320 CheckedNeg, 321 CheckedRem, 322 CheckedShr, 323 One as NumOne, 324 PrimInt, 325 ToPrimitive, 326 WrappingAdd, 327 WrappingMul, 328 WrappingNeg, 329 WrappingShl, 330 WrappingShr, 331 WrappingSub, 332 Zero as NumZero, 333 }; 334 335 /// Trait bound for integer values. Common to both signed and unsigned integers. 336 pub trait IntegerType: 337 'static 338 + CheckedAbs 339 + CheckedNeg 340 + CheckedPow 341 + CheckedRem 342 + CheckedShl 343 + CheckedShr 344 + Debug 345 + Default 346 + Display 347 + FromBits 348 + FromBytes 349 + FromStr<Err = ParseIntError> 350 + Hash 351 + Modulo 352 + NumZero 353 + NumOne 354 + PartialOrd 355 + Send 356 + Sync 357 + ToBits 358 + ToBytes 359 + ToPrimitive 360 + Uniform 361 + WrappingAbs 362 + WrappingAdd 363 + WrappingMul 364 + WrappingNeg 365 + WrappingPow 366 + WrappingRem 367 + WrappingShl 368 + WrappingShr 369 + WrappingSub 370 + WrappingDiv 371 + IntegerProperties 372 { 373 } 374 375 impl IntegerType for i8 {} 376 impl IntegerType for i16 {} 377 impl IntegerType for i32 {} 378 impl IntegerType for i64 {} 379 impl IntegerType for i128 {} 380 381 impl IntegerType for u8 {} 382 impl IntegerType for u16 {} 383 impl IntegerType for u32 {} 384 impl IntegerType for u64 {} 385 impl IntegerType for u128 {} 386 387 macro_rules! binary_impl { 388 ($trait_name:ident, $t:ty, $method:ident, $arg1: ident, $argname:ident, $arg2: ident, $rt:ty, $body:expr) => { 389 impl $trait_name for $t { 390 #[inline] 391 fn $method(&$arg1, $argname: &$arg2) -> $rt { 392 $body 393 } 394 } 395 }; 396 } 397 398 pub trait CheckedPow: Sized { 399 fn checked_pow(&self, v: &u32) -> Option<Self>; 400 } 401 402 binary_impl!(CheckedPow, u8, checked_pow, self, v, u32, Option<u8>, u8::checked_pow(*self, *v)); 403 binary_impl!(CheckedPow, u16, checked_pow, self, v, u32, Option<u16>, u16::checked_pow(*self, *v)); 404 binary_impl!(CheckedPow, u32, checked_pow, self, v, u32, Option<u32>, u32::checked_pow(*self, *v)); 405 binary_impl!(CheckedPow, u64, checked_pow, self, v, u32, Option<u64>, u64::checked_pow(*self, *v)); 406 binary_impl!(CheckedPow, u128, checked_pow, self, v, u32, Option<u128>, u128::checked_pow(*self, *v)); 407 binary_impl!(CheckedPow, i8, checked_pow, self, v, u32, Option<i8>, i8::checked_pow(*self, *v)); 408 binary_impl!(CheckedPow, i16, checked_pow, self, v, u32, Option<i16>, i16::checked_pow(*self, *v)); 409 binary_impl!(CheckedPow, i32, checked_pow, self, v, u32, Option<i32>, i32::checked_pow(*self, *v)); 410 binary_impl!(CheckedPow, i64, checked_pow, self, v, u32, Option<i64>, i64::checked_pow(*self, *v)); 411 binary_impl!(CheckedPow, i128, checked_pow, self, v, u32, Option<i128>, i128::checked_pow(*self, *v)); 412 413 pub trait CheckedShl: Sized { 414 fn checked_shl(&self, v: &u32) -> Option<Self>; 415 } 416 417 #[rustfmt::skip] 418 binary_impl!(CheckedShl, u8, checked_shl, self, v, u32, Option<u8>, u8::checked_pow(2u8, *v).and_then(|x| u8::checked_mul(*self, x))); 419 #[rustfmt::skip] 420 binary_impl!(CheckedShl, u16, checked_shl, self, v, u32, Option<u16>, u16::checked_pow(2u16, *v).and_then(|x| u16::checked_mul(*self, x))); 421 #[rustfmt::skip] 422 binary_impl!(CheckedShl, u32, checked_shl, self, v, u32, Option<u32>, u32::checked_pow(2u32, *v).and_then(|x| u32::checked_mul(*self, x))); 423 #[rustfmt::skip] 424 binary_impl!(CheckedShl, u64, checked_shl, self, v, u32, Option<u64>, u64::checked_pow(2u64, *v).and_then(|x| u64::checked_mul(*self, x))); 425 #[rustfmt::skip] 426 binary_impl!(CheckedShl, u128, checked_shl, self, v, u32, Option<u128>, u128::checked_pow(2u128, *v).and_then(|x| u128::checked_mul(*self, x))); 427 #[rustfmt::skip] 428 binary_impl!(CheckedShl, i8, checked_shl, self, v, u32, Option<i8>, u8::checked_pow(2u8, *v).and_then(|x| i8::checked_mul(if (x as i8) == i8::MIN { self.wrapping_neg() } else { *self }, x as i8))); 429 #[rustfmt::skip] 430 binary_impl!(CheckedShl, i16, checked_shl, self, v, u32, Option<i16>, u16::checked_pow(2u16, *v).and_then(|x| i16::checked_mul(if (x as i16) == i16::MIN { self.wrapping_neg() } else { *self }, x as i16))); 431 #[rustfmt::skip] 432 binary_impl!(CheckedShl, i32, checked_shl, self, v, u32, Option<i32>, u32::checked_pow(2u32, *v).and_then(|x| i32::checked_mul(if (x as i32) == i32::MIN { self.wrapping_neg() } else { *self }, x as i32))); 433 #[rustfmt::skip] 434 binary_impl!(CheckedShl, i64, checked_shl, self, v, u32, Option<i64>, u64::checked_pow(2u64, *v).and_then(|x| i64::checked_mul(if (x as i64) == i64::MIN { self.wrapping_neg() } else { *self }, x as i64))); 435 #[rustfmt::skip] 436 binary_impl!(CheckedShl, i128, checked_shl, self, v, u32, Option<i128>, u128::checked_pow(2u128, *v).and_then(|x| i128::checked_mul(if (x as i128) == i128::MIN { self.wrapping_neg() } else { *self }, x as i128))); 437 438 pub trait Modulo: Sized + Rem<Self, Output = Self> { 439 fn modulo(&self, v: &Self) -> Self; 440 } 441 442 binary_impl!(Modulo, u8, modulo, self, v, Self, u8, u8::wrapping_rem(*self, *v)); 443 binary_impl!(Modulo, u16, modulo, self, v, Self, u16, u16::wrapping_rem(*self, *v)); 444 binary_impl!(Modulo, u32, modulo, self, v, Self, u32, u32::wrapping_rem(*self, *v)); 445 binary_impl!(Modulo, u64, modulo, self, v, Self, u64, u64::wrapping_rem(*self, *v)); 446 binary_impl!(Modulo, u128, modulo, self, v, Self, u128, u128::wrapping_rem(*self, *v)); 447 #[rustfmt::skip] 448 binary_impl!(Modulo, i8, modulo, self, _v, Self, i8, panic!("modulo is not implemented for i8")); 449 #[rustfmt::skip] 450 binary_impl!(Modulo, i16, modulo, self, _v, Self, i16, panic!("modulo is not implemented for i16")); 451 #[rustfmt::skip] 452 binary_impl!(Modulo, i32, modulo, self, _v, Self, i32, panic!("modulo is not implemented for i32")); 453 #[rustfmt::skip] 454 binary_impl!(Modulo, i64, modulo, self, _v, Self, i64, panic!("modulo is not implemented for i64")); 455 #[rustfmt::skip] 456 binary_impl!(Modulo, i128, modulo, self, _v, Self, i128, panic!("modulo is not implemented for i128")); 457 458 pub trait WrappingDiv: Sized + Div<Self, Output = Self> { 459 fn wrapping_div(&self, v: &Self) -> Self; 460 } 461 462 binary_impl!(WrappingDiv, u8, wrapping_div, self, v, Self, u8, u8::wrapping_div(*self, *v)); 463 binary_impl!(WrappingDiv, u16, wrapping_div, self, v, Self, u16, u16::wrapping_div(*self, *v)); 464 binary_impl!(WrappingDiv, u32, wrapping_div, self, v, Self, u32, u32::wrapping_div(*self, *v)); 465 binary_impl!(WrappingDiv, u64, wrapping_div, self, v, Self, u64, u64::wrapping_div(*self, *v)); 466 binary_impl!(WrappingDiv, u128, wrapping_div, self, v, Self, u128, u128::wrapping_div(*self, *v)); 467 binary_impl!(WrappingDiv, i8, wrapping_div, self, v, Self, i8, i8::wrapping_div(*self, *v)); 468 binary_impl!(WrappingDiv, i16, wrapping_div, self, v, Self, i16, i16::wrapping_div(*self, *v)); 469 binary_impl!(WrappingDiv, i32, wrapping_div, self, v, Self, i32, i32::wrapping_div(*self, *v)); 470 binary_impl!(WrappingDiv, i64, wrapping_div, self, v, Self, i64, i64::wrapping_div(*self, *v)); 471 binary_impl!(WrappingDiv, i128, wrapping_div, self, v, Self, i128, i128::wrapping_div(*self, *v)); 472 473 pub trait WrappingRem: Sized + Rem<Self, Output = Self> { 474 fn wrapping_rem(&self, v: &Self) -> Self; 475 } 476 477 binary_impl!(WrappingRem, u8, wrapping_rem, self, v, Self, u8, u8::wrapping_rem(*self, *v)); 478 binary_impl!(WrappingRem, u16, wrapping_rem, self, v, Self, u16, u16::wrapping_rem(*self, *v)); 479 binary_impl!(WrappingRem, u32, wrapping_rem, self, v, Self, u32, u32::wrapping_rem(*self, *v)); 480 binary_impl!(WrappingRem, u64, wrapping_rem, self, v, Self, u64, u64::wrapping_rem(*self, *v)); 481 binary_impl!(WrappingRem, u128, wrapping_rem, self, v, Self, u128, u128::wrapping_rem(*self, *v)); 482 binary_impl!(WrappingRem, i8, wrapping_rem, self, v, Self, i8, i8::wrapping_rem(*self, *v)); 483 binary_impl!(WrappingRem, i16, wrapping_rem, self, v, Self, i16, i16::wrapping_rem(*self, *v)); 484 binary_impl!(WrappingRem, i32, wrapping_rem, self, v, Self, i32, i32::wrapping_rem(*self, *v)); 485 binary_impl!(WrappingRem, i64, wrapping_rem, self, v, Self, i64, i64::wrapping_rem(*self, *v)); 486 binary_impl!(WrappingRem, i128, wrapping_rem, self, v, Self, i128, i128::wrapping_rem(*self, *v)); 487 488 pub trait WrappingPow: Sized { 489 fn wrapping_pow(&self, v: &u32) -> Self; 490 } 491 492 binary_impl!(WrappingPow, u8, wrapping_pow, self, v, u32, u8, u8::wrapping_pow(*self, *v)); 493 binary_impl!(WrappingPow, u16, wrapping_pow, self, v, u32, u16, u16::wrapping_pow(*self, *v)); 494 binary_impl!(WrappingPow, u32, wrapping_pow, self, v, u32, u32, u32::wrapping_pow(*self, *v)); 495 binary_impl!(WrappingPow, u64, wrapping_pow, self, v, u32, u64, u64::wrapping_pow(*self, *v)); 496 binary_impl!(WrappingPow, u128, wrapping_pow, self, v, u32, u128, u128::wrapping_pow(*self, *v)); 497 binary_impl!(WrappingPow, i8, wrapping_pow, self, v, u32, i8, i8::wrapping_pow(*self, *v)); 498 binary_impl!(WrappingPow, i16, wrapping_pow, self, v, u32, i16, i16::wrapping_pow(*self, *v)); 499 binary_impl!(WrappingPow, i32, wrapping_pow, self, v, u32, i32, i32::wrapping_pow(*self, *v)); 500 binary_impl!(WrappingPow, i64, wrapping_pow, self, v, u32, i64, i64::wrapping_pow(*self, *v)); 501 binary_impl!(WrappingPow, i128, wrapping_pow, self, v, u32, i128, i128::wrapping_pow(*self, *v)); 502 503 macro_rules! unary_impl { 504 ($trait_name:ident, $t:ty, $method:ident, $arg: ident, $rt:ty, $body:expr) => { 505 impl $trait_name for $t { 506 #[inline] 507 fn $method(&$arg) -> $rt { 508 $body 509 } 510 } 511 }; 512 } 513 514 pub trait CheckedAbs: Sized { 515 fn checked_abs(&self) -> Option<Self>; 516 } 517 518 unary_impl!(CheckedAbs, u8, checked_abs, self, Option<u8>, Some(*self)); 519 unary_impl!(CheckedAbs, u16, checked_abs, self, Option<u16>, Some(*self)); 520 unary_impl!(CheckedAbs, u32, checked_abs, self, Option<u32>, Some(*self)); 521 unary_impl!(CheckedAbs, u64, checked_abs, self, Option<u64>, Some(*self)); 522 unary_impl!(CheckedAbs, u128, checked_abs, self, Option<u128>, Some(*self)); 523 unary_impl!(CheckedAbs, i8, checked_abs, self, Option<i8>, i8::checked_abs(*self)); 524 unary_impl!(CheckedAbs, i16, checked_abs, self, Option<i16>, i16::checked_abs(*self)); 525 unary_impl!(CheckedAbs, i32, checked_abs, self, Option<i32>, i32::checked_abs(*self)); 526 unary_impl!(CheckedAbs, i64, checked_abs, self, Option<i64>, i64::checked_abs(*self)); 527 unary_impl!(CheckedAbs, i128, checked_abs, self, Option<i128>, i128::checked_abs(*self)); 528 529 pub trait WrappingAbs: Sized { 530 fn wrapping_abs(&self) -> Self; 531 } 532 533 unary_impl!(WrappingAbs, u8, wrapping_abs, self, u8, *self); 534 unary_impl!(WrappingAbs, u16, wrapping_abs, self, u16, *self); 535 unary_impl!(WrappingAbs, u32, wrapping_abs, self, u32, *self); 536 unary_impl!(WrappingAbs, u64, wrapping_abs, self, u64, *self); 537 unary_impl!(WrappingAbs, u128, wrapping_abs, self, u128, *self); 538 unary_impl!(WrappingAbs, i8, wrapping_abs, self, i8, i8::wrapping_abs(*self)); 539 unary_impl!(WrappingAbs, i16, wrapping_abs, self, i16, i16::wrapping_abs(*self)); 540 unary_impl!(WrappingAbs, i32, wrapping_abs, self, i32, i32::wrapping_abs(*self)); 541 unary_impl!(WrappingAbs, i64, wrapping_abs, self, i64, i64::wrapping_abs(*self)); 542 unary_impl!(WrappingAbs, i128, wrapping_abs, self, i128, i128::wrapping_abs(*self)); 543 544 /// Properties common to all integer types. 545 pub trait IntegerProperties: PrimInt + Debug + Display { 546 type Dual: IntegerType; 547 /// Returns the number of bits required to represent this integer. 548 const BITS: u64; 549 /// Returns the maximum value representable by this integer. 550 const MAX: Self; 551 /// Returns the minimum value representable by this integer. 552 const MIN: Self; 553 554 /// Returns `true` if `Self` is a signed integer and `false` otherwise. 555 fn is_signed() -> bool; 556 557 /// Returns the name of the integer type as a string slice. (i.e. "u8") 558 fn type_name() -> &'static str; 559 560 /// Casts `self` into its dual. 561 fn into_dual(self) -> Self::Dual; 562 } 563 564 macro_rules! integer_properties_impl { 565 ($t:ty, $dual:ty, $is_signed:expr) => { 566 impl IntegerProperties for $t { 567 type Dual = $dual; 568 569 const BITS: u64 = <$t>::BITS as u64; 570 const MAX: $t = <$t>::MAX; 571 const MIN: $t = <$t>::MIN; 572 573 #[inline] 574 fn is_signed() -> bool { 575 $is_signed 576 } 577 578 #[inline] 579 fn type_name() -> &'static str { 580 std::any::type_name::<$t>() 581 } 582 583 #[inline] 584 fn into_dual(self) -> Self::Dual { 585 self as $dual 586 } 587 } 588 }; 589 } 590 591 integer_properties_impl!(u8, i8, false); 592 integer_properties_impl!(u16, i16, false); 593 integer_properties_impl!(u32, i32, false); 594 integer_properties_impl!(u64, i64, false); 595 integer_properties_impl!(u128, i128, false); 596 integer_properties_impl!(i8, u8, true); 597 integer_properties_impl!(i16, u16, true); 598 integer_properties_impl!(i32, u32, true); 599 integer_properties_impl!(i64, u64, true); 600 integer_properties_impl!(i128, u128, true); 601 } 602 603 /// Trait pattern to prevent abuse of Magnitude. 604 pub mod integer_magnitude { 605 use super::integer_type::IntegerType; 606 use num_traits::{ToPrimitive, Unsigned}; 607 608 /// Trait for integers that can be used as an unsigned magnitude. 609 /// `Magnitude`s are either used to represent an integer exponent 610 /// or the right operand in integer shift operations. 611 pub trait Magnitude: IntegerType + ToPrimitive + Unsigned {} 612 impl Magnitude for u8 {} 613 impl Magnitude for u16 {} 614 impl Magnitude for u32 {} 615 }