Assign the value of that to this SafeInt instance.
See safeOp.
See safeOp.
Assign the value of that to this SafeInt instance.
Perform a floating-point math operation.
See safeOp.
Perform a floating-point math operation.
See safeOp.
Convert this value to floating-point. This always succeeds, although some loss of precision may occur if M.sizeof <= N.sizeof.
this != 0
Convert this value to type M using checkedint.to() for bounds checking. An IntFlag will be raised if M cannot represent the current value of this SafeInt.
Perform a floating-point comparison to right.
See safeOp.
See safeOp.
Count the number of set bits using core.bitop.popcnt().
Raise this to the exp power using std.math.pow().
See safeOp.
Get a simple hashcode for this value.
Get a string representation of this value.
Get a view of this SafeInt that allows bitwise operations.
Convert this value to a type suitable for indexing an array:
checkedint.to() is used for bounds checking.
The basic integral value of this SafeInt. Accessing this directly may be useful for:
The most positive possible value of this SafeInt type.
The most negative possible value of this SafeInt type.
The error signalling policy used by this SafeInt type.
// Mixing standard signed and unsigned types is dangerous... int ba = -1; uint bb = 0; assert(ba > bb); auto bc = ba + bb; assert(is(typeof(bc) == uint)); assert(bc == 4294967295u); // ...that's why SafeInt won't let you do it. import checkedint.throws : SafeInt, to; // use IntFlagPolicy.throws SafeInt!int sa = -1; SafeInt!uint sb = 0u; static assert(!__traits(compiles, sa < sb)); static assert(!__traits(compiles, sa + sb)); // Instead, use checkedint.to() to safely convert to a common type... auto sbi = to!(SafeInt!int)(sb); assert(sa < sbi); auto sc = sa + sbi; assert(sc == -1); // (...or just switch to SmartInt.)
// When IntFlagPolicy.throws is set, SafeInt operations that fail at runtime will throw a CheckedIntException. import checkedint.throws : SafeInt; SafeInt!uint sa = 1u; SafeInt!uint sb = 0u; bool overflow = false; try { SafeInt!uint sc = sb - sa; assert(false); } catch(CheckedIntException e) { assert(e.intFlags == IntFlag.negOver); overflow = true; } assert(overflow); bool div0 = false; try { // With standard integers, this would crash the program with an unrecoverable FPE... SafeInt!uint sc = sa / sb; assert(false); } catch(CheckedIntException e) { // ...but with SafeInt, it just throws a normal Exception. assert(e.intFlags == IntFlag.div0); div0 = true; } assert(div0);
// When IntFlagPolicy.noex is set, SafeInt operations that fail at runtime set one or more bits in IntFlags.local. import checkedint.noex : SafeInt; SafeInt!uint sa = 1u; SafeInt!uint sb = 0u; SafeInt!uint sc; sc = sb - sa; assert(IntFlags.local == IntFlag.negOver); // With standard integers, this would crash the program with an unrecoverable FPE... sc = sa / sb; // ...but with SmartInt, it just sets a bit in IntFlags.local. assert(IntFlags.local & IntFlag.div0); // Each flag will remain set until cleared: assert(IntFlags.local.clear() == (IntFlag.negOver | IntFlag.div0)); assert(!IntFlags.local);
Wrapper for any basic integral type N that uses the checked operations from safeOp and rejects attempts to directly assign values that cannot be proven to be within the range representable by N. (checkedint.to() can be used to safely assign values of incompatible types, with runtime bounds checking.)
SafeInt is designed to be as interchangeable with N as possible, without compromising safety. The DebugInt template allows a variable to use SafeInt in debug mode to find bugs, and N directly in release mode for greater speed and a smaller binary.
If you're not trying to write generic code that works with both SafeInt!N and N, you should probably be using SmartInt instead. It generates far fewer error messages; mostly it "just works".