Crate abstract_integers
source · [−]Expand description
This crate defines specification-friendly natural integers with an upper bound. Operations on these integers can be defined as modular (modulo the upper bound) or regular (with a panic on underflow or overflow).
As each integer gets its own Rust type, the compiler detects and prevent any mixing between all the diffent integers you would have defined.
Defining a new integer type
Here is the macro used to defined the SizeNatExample
type of this crate:
define_abstract_integer_checked!(SizeNatExample, 64);
SizeNat
is the name of the newly-created type. 64
is the number of bits of the machine
representation of the type. From the number of bits is derived an upper bound for the integer
for which all operations are checked for overflow.
The resulting integer type is copyable, and supports addition, substraction, multiplication,
integer division, remainder, comparison and equality. The from_literal
method allows you to
convert integer literals into your new type.
Refining an integer type for modular arithmetic
On top of a previously defined abstract integer, you can define another type that lets you implement modular arithmetic. For instance, this crate defines the arithmetic field over the 9th Mersenne prime with:
define_refined_modular_integer!(
SizeNatFieldExample,
SizeNatExample,
SizeNatExample::pow2(61) - SizeNatExample::from_literal(1)
);
The first argument of this new macro is the name of the newly defined refined type. The second argument is the name of the base abstract integer that will act as the representation. The third example is the modulo for all operations, defined as a value of the base type.
Example
use abstract_integers::*;
abstract_public_nat_mod!(SizeNatFieldExample, SizeNatExample, 64, "1fffffffffffffff");
let x1 = SizeNatExample::from_literal(687165654266415);
let x2 = SizeNatExample::from_literal(4298832000156);
let x3 = x1 + x2;
assert_eq!(SizeNatExample::from_literal(691464486266571), x3);
let x4 = SizeNatExample::from_literal(8151084996540);
let x5 = x3 - x4;
assert_eq!(SizeNatExample::from_literal(683313401270031), x5.into());
let x6 = x5 / SizeNatExample::from_literal(1541654268);
assert_eq!(SizeNatExample::from_literal(443233), x6.into());
let x7 : SizeNatFieldExample = SizeNatFieldExample::from_literal(2305843009213693951) + x6.into();
assert_eq!(x7, x6.into());
Modules
Macros
Defines a bounded natural integer with regular arithmetic operations, checked for overflow and underflow.
Defines a bounded natural integer with modular arithmetic operations
Structs
A big signed integer type.
A big unsigned integer type.
Implement FromResidual<Yeet<T>>
on your type to enable
do yeet expr
syntax in functions returning your type.
An error which can be returned when parsing an integer.
A (half-open) range bounded inclusively below and exclusively above
(start..end
).
A range only bounded inclusively below (start..
).
An unbounded range (..
).
A range bounded inclusively below and above (start..=end
).
A range only bounded exclusively above (..end
).
A range only bounded inclusively above (..=end
).
Enums
The result of a generator resumption.
An endpoint of a range of keys.
Used to tell an operation whether it should exit early or go on as usual.
An Ordering
is the result of a comparison between two values.
Traits
The addition operator +
.
The addition assignment operator +=
.
The bitwise AND operator &
.
The bitwise AND assignment operator &=
.
The bitwise OR operator |
.
The bitwise OR assignment operator |=
.
The bitwise XOR operator ^
.
The bitwise XOR assignment operator ^=
.
Performs subtraction that returns None
instead of wrapping around on underflow.
Trait that indicates that this is a pointer or a wrapper for one, where unsizing can be performed on the pointee.
Defines an associated constant representing the multiplicative identity
element for Self
.
Defines an associated constant representing the additive identity element
for Self
.
DispatchFromDyn
is used in the implementation of object safety checks (specifically allowing
arbitrary self types), to guarantee that a method’s receiver type can be dispatched on.
Used to specify which residuals can be converted into which crate::ops::Try
types.
The trait implemented by builtin generator types.
Used for immutable dereferencing operations, like *v
.
Used for mutable dereferencing operations, like in *v = 1;
.
The division operator /
.
The division assignment operator /=
.
Custom code within the destructor.
The version of the call operator that takes an immutable receiver.
The version of the call operator that takes a mutable receiver.
The version of the call operator that takes a by-value receiver.
Used for indexing operations (container[index]
) in immutable contexts.
Used for indexing operations (container[index]
) in mutable contexts.
The multiplication operator *
.
The multiplication assignment operator *=
.
The unary negation operator -
.
The unary logical negation operator !
.
Defines a multiplicative identity element for Self
.
OneSidedRange
is implemented for built-in range types that are unbounded
on one side. For example, a..
, ..b
and ..=c
implement OneSidedRange
,
but ..
, d..e
, and f..=g
do not.
Allows retrieving the canonical type implementing Try
that has this type
as its residual and allows it to hold an O
as its output.
The ?
operator and try {}
blocks.
RangeBounds
is implemented by Rust’s built-in range types, produced
by range syntax like ..
, a..
, ..b
, ..=c
, d..e
, or f..=g
.
The remainder operator %
.
The remainder assignment operator %=
.
The left shift operator <<
. Note that because this trait is implemented
for all integer types with multiple right-hand-side types, Rust’s type
checker has special handling for _ << _
, setting the result type for
integer operations to the type of the left-hand-side operand. This means
that though a << b
and a.shl(b)
are one and the same from an evaluation
standpoint, they are different when it comes to type inference.
The left shift assignment operator <<=
.
The right shift operator >>
. Note that because this trait is implemented
for all integer types with multiple right-hand-side types, Rust’s type
checker has special handling for _ >> _
, setting the result type for
integer operations to the type of the left-hand-side operand. This means
that though a >> b
and a.shr(b)
are one and the same from an evaluation
standpoint, they are different when it comes to type inference.
The right shift assignment operator >>=
.
The subtraction operator -
.
The subtraction assignment operator -=
.
Defines an additive identity element for Self
.