SmartInt

Wrapper for any basic integral type N that uses the checked operations from smartOp and bounds checks assignments with checkedint.to().

  • policy controls the error signalling policy (see checkedint.flags).
  • bitOps may be set to No.bitOps if desired, to turn bitwise operations on this type into a compile-time error.
  1. struct SmartInt(N, IntFlagPolicy _policy, Flag!"bitOps" bitOps = Yes.bitOps)
  2. template SmartInt(N, IntFlagPolicy policy, Flag!"bitOps" bitOps = Yes.bitOps)
    template SmartInt (
    N
    Flag!"bitOps" bitOps = Yes.bitOps
    ) if (
    (
    isIntegral!N &&
    !isUnqual!N
    )
    ||
    isCheckedInt!N
    ) {}

Members

Aliases

SmartInt
alias SmartInt = SmartInt!(BasicScalar!N, policy, bitOps)
Undocumented in source.

Examples

// Mixing standard signed and unsigned types is dangerous, but...
int ba = -1;
uint bb = 0;
assert(ba > bb);

auto bc = ba + bb;
assert(is(typeof(bc) == uint));
assert(bc == 4294967295u);

// ...with SmartInt, mixed signed/unsigned operations "just work":
import checkedint.throws : SmartInt; // use IntFlagPolicy.throws

SmartInt!int ma = -1;
SmartInt!uint mb = 0;
assert(ma < mb);

auto mc = ma + mb;
assert(is(typeof(mc) == SmartInt!int));
assert(mc != 4294967295u);
assert(mc == -1);
// When IntFlagPolicy.throws is used, failed SmartInt operations will throw a CheckedIntException.
import checkedint.throws : SmartInt;

SmartInt!uint ma = 1;
SmartInt!uint mb = 0;

bool overflow = false;
try
{
    SmartInt!uint mc = mb - ma;
    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...
    SmartInt!uint mc = ma / mb;
    assert(false);
}
catch (CheckedIntException e)
{
    // ...but with SmartInt, it just throws a normal Exception.
    assert(e.intFlags == IntFlag.div0);
    div0 = true;
}
assert(div0);
// When IntFlagPolicy.sticky is used, failed SmartInt operations set one or more bits in IntFlags.local.
import checkedint.sticky : SmartInt;

SmartInt!uint ma = 1;
SmartInt!uint mb = 0;
SmartInt!uint mc;

mc = mb - ma;
assert(IntFlags.local == IntFlag.over);

// With standard integers, this would crash the program with an unrecoverable FPE...
mc = ma / mb;
// ...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.over | IntFlag.div0));
assert(!IntFlags.local);

Meta