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)

Constructors

this
this(M that)

Assign the value of that to this SmartInt instance.

Members

Functions

abs
SmartInt!(Unsigned!N, policy, bitOps) abs()

See smartOp.

bsf
SmartInt!(ubyte, policy, bitOps) bsf()
bsr
SmartInt!(ubyte, policy, bitOps) bsr()
divPow2
auto divPow2(M exp)
ilogb
SmartInt!(ubyte, policy, bitOps) ilogb()
modPow2
auto modPow2(M exp)
mulPow2
auto mulPow2(M exp)

See smartOp.

opAssign
typeof(this) opAssign(M that)

Assign the value of that to this SmartInt instance.

opBinary
auto opBinary(M right)
opBinaryRight
auto opBinaryRight(M left)

See smartOp.

opCast
M opCast()

Convert this value to floating-point. This always succeeds, although some loss of precision may occur if M.sizeof <= N.sizeof.

opCast
M opCast()

this != 0

opCast
M opCast()

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 SmartInt.

opCmp
auto opCmp(M right)
int opCmp(M right)

Perform a mathematically correct comparison to right.

opEquals
bool opEquals(M right)

Returns true if this value is mathematically precisely equal to right.

opOpAssign
typeof(this) opOpAssign(M right)

See smartOp.

opUnary
typeof(this) opUnary()
SmartInt!(Signed!N, policy, bitOps) opUnary()

See smartOp.

popcnt
SmartInt!(int, policy, bitOps) popcnt()

Count the number of set bits using core.bitop.popcnt().

pow
auto pow(M exp)

Raise this to the exp power using std.math.pow().

pow
auto pow(M exp)

See smartOp.

toHash
size_t toHash()

Get a simple hashcode for this value.

toString
string toString()
void toString(Writer sink, FormatSpec!Char fmt)

Get a string representation of this value.

Properties

bits
inout(SmartInt!(N, policy, Yes.bitOps)) bits [@property getter]

Get a view of this SmartInt that allows bitwise operations.

bscal
inout(N) bscal [@property getter]
Undocumented in source. Be warned that the author may not have intended to support it.
idx
Select!(isSigned!N, ptrdiff_t, size_t) idx [@property getter]

Convert this value to a type suitable for indexing an array:

  • If N is signed, a ptrdiff_t is returned.
  • If N is unsigned, a size_t is returned.

checkedint.to() is used for bounds checking.

max
auto max [@property getter]
Undocumented in source. Be warned that the author may not have intended to support it.
min
auto min [@property getter]
Undocumented in source. Be warned that the author may not have intended to support it.

Variables

bits
SmartInt!(N, policy, Yes.bitOps) bits;
Undocumented in source.
bscal
N bscal;

The basic integral value of this SmartInt. Accessing this directly may be useful for:

  • Intentionally doing modular (unchecked) arithmetic, or
  • Interacting with APIs that are not checkedint aware.
max
enum SmartInt!(N, policy, bitOps) max;

The most positive possible value of this SmartInt type.

min
enum SmartInt!(N, policy, bitOps) min;

The most negative possible value of this SmartInt type.

policy
enum IntFlagPolicy policy;

The error signalling policy used by this SmartInt type.

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.noex is used, failed SmartInt operations set one or more bits in IntFlags.local.
import checkedint.noex : SmartInt;

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

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

// 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.negOver | IntFlag.div0));
assert(!IntFlags.local);

Meta