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
    ) {}

Examples

1 // Mixing standard signed and unsigned types is dangerous, but...
2 int ba = -1;
3 uint bb = 0;
4 assert(ba > bb);
5 
6 auto bc = ba + bb;
7 assert(is(typeof(bc) == uint));
8 assert(bc == 4294967295u);
9 
10 // ...with SmartInt, mixed signed/unsigned operations "just work":
11 import checkedint.throws : SmartInt; // use IntFlagPolicy.throws
12 
13 SmartInt!int ma = -1;
14 SmartInt!uint mb = 0;
15 assert(ma < mb);
16 
17 auto mc = ma + mb;
18 assert(is(typeof(mc) == SmartInt!int));
19 assert(mc != 4294967295u);
20 assert(mc == -1);
1 // When IntFlagPolicy.throws is used, failed SmartInt operations will throw a CheckedIntException.
2 import checkedint.throws : SmartInt;
3 
4 SmartInt!uint ma = 1;
5 SmartInt!uint mb = 0;
6 
7 bool overflow = false;
8 try
9 {
10     SmartInt!uint mc = mb - ma;
11     assert(false);
12 }
13 catch (CheckedIntException e)
14 {
15     assert(e.intFlags == IntFlag.negOver);
16     overflow = true;
17 }
18 assert(overflow);
19 
20 bool div0 = false;
21 try
22 {
23     // With standard integers, this would crash the program with an unrecoverable FPE...
24     SmartInt!uint mc = ma / mb;
25     assert(false);
26 }
27 catch (CheckedIntException e)
28 {
29     // ...but with SmartInt, it just throws a normal Exception.
30     assert(e.intFlags == IntFlag.div0);
31     div0 = true;
32 }
33 assert(div0);
1 // When IntFlagPolicy.sticky is used, failed SmartInt operations set one or more bits in IntFlags.local.
2 import checkedint.sticky : SmartInt;
3 
4 SmartInt!uint ma = 1;
5 SmartInt!uint mb = 0;
6 SmartInt!uint mc;
7 
8 mc = mb - ma;
9 assert(IntFlags.local == IntFlag.negOver);
10 
11 // With standard integers, this would crash the program with an unrecoverable FPE...
12 mc = ma / mb;
13 // ...but with SmartInt, it just sets a bit in IntFlags.local.
14 assert(IntFlags.local & IntFlag.div0);
15 
16 // Each flag will remain set until cleared:
17 assert(IntFlags.local.clear() == (IntFlag.negOver | IntFlag.div0));
18 assert(!IntFlags.local);

Meta