Improve this page Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using local clone. Page wiki View or edit the community-maintained wiki page associated with this page.

std.experimental.safeint

This module holds functions to safely compare integers of different sizes and signeness without any unwanted implicit casts.
Additionally, this module implements a SafeInt!T type. This type has an explicit nan value, checks binary operation for over- and underflows, checks division by zero, and checks if values to assign can be represented by T where T is any integer type.
nothrow @nogc bool equal(T, S)(in T t, in S s) if (isIntegral!T && isIntegral!S);
Compares two integer of arbitrary type for equality.
This function makes sure no implicit value propagation falsifies the result of the comparison.
Parameters:
T t an integer value
S s an integer value
Returns:
true if the value of t is equal to the value of s, false otherwise.
Examples:
assert(-1 == uint.max); // this should be false
assert(!equal(-1, uint.max));
nothrow @nogc bool notEqual(T, S)(in T t, in S s) if (isIntegral!T && isIntegral!S);
Compares two integer of arbitrary type for no-equality.
This function makes sure no implicit value propagation falsifies the result of the comparison.
Parameters:
T t an integer value
S s an integer value
Returns:
true if the value of t is not equal to the value of s, false otherwise.
Examples:
assert(notEqual(-1, uint.max));
nothrow @nogc bool less(T, S)(in T t, in S s) if (isIntegral!T && isIntegral!S);
Checks if the value of the first parameter is smaller than the value of the second parameter.
This function makes sure no implicit value propagation falsifies the result of the comparison.
Parameters:
T t an integer value
S s an integer value
Returns:
true if the value of t is smaller than the value of s, false otherwise.
Examples:
assert(less(-1, uint.max));
nothrow @nogc bool lessEqual(T, S)(in T t, in S s) if (isIntegral!T && isIntegral!S);
Checks if the value of the first parameter is less or equal to the value of the second parameter.
This function makes sure no implicit value propagation falsifies the result of the comparison.
Parameters:
T t an integer value
S s an integer value
Returns:
true if the value of t is smaller or equal than the value of s, false otherwise.
Examples:
assert(lessEqual( 0, uint.max));
assert(lessEqual(-1, ulong.max));
nothrow @nogc bool greater(T, S)(in T t, in S s) if (isIntegral!T && isIntegral!S);
Checks if the value of the first parameter is greater than the value of the second parameter.
This function makes sure no implicit value propagation falsifies the result of the comparison.
Parameters:
T t an integer value
S s an integer value
Returns:
true if the value of t is greater than the value of s, false otherwise.
Examples:
assert(greater(ulong.max, long.min));
nothrow @nogc bool greaterEqual(T, S)(in T t, in S s) if (isIntegral!T && isIntegral!S);
Checks if the value of the first parameter is greater or equal to the value of the second parameter.
This function makes sure no implicit value propagation falsifies the result of the comparison.
Parameters:
T t an integer value
S s an integer value
Returns:
true if the value of t is greater or equal than the value of s, false otherwise.
Examples:
assert(greaterEqual(ulong.max, long.min));
template SafeIntType(T)
Returns the integer type used by a SafeInt to store the value.
If an integer type is passed this type will be returned.
Examples:
static assert(is(SafeIntType!(SafeInt!int) == int));
static assert(is(SafeIntType!int == int));
template isSafeInt(T)
Checks if the passed type is a SafeInt.
Returns:
true if the passed type T is an SafeInt, false overwise.
Examples:
static assert(isSafeInt!(SafeInt!int));
static assert(!isSafeInt!int);
struct SafeInt(T) if (isIntegral!T);
SafeInt implements a safe integer type.
Safe in the sense that:
  • over and underflows are not ignored
  • no unchecked implicit casts are performed
  • assigned values are checked if they fit into the value range of the underlaying type
  • default initialization to NaN
  • no bitwise operations are implemented.

Every SafeInt must be specialized with one integer type. The integer type also defines the NaN value. For unsigned integer U the NaN value is U.max. For signed integer S the NaN value is U.min.

This limits the value ranges of SafeInt!U where U is an unsigned integer to SafeInt!U >= 0 && SafeInt!U < U.max. This limits the value ranges of SafeInt!S where S is an signed integer to SafeInt!S > S.min && SafeInt!S < S.max.
Examples:
SafeInt!uint s0 = -1;
assert(s0.isNaN);

SafeInt!int s0_1 = s0 + 4;
assert(s0_1.isNaN);
auto s1 = SafeInt!int(1);
auto s2 = s1 + 1;

SafeInt!int s2_1 = s0 = s2;
assert(!s2.isNaN);
assert(s2 == 2);
assert(s2 == 2);
assert(s2 == SafeInt!byte(2));
assert(s2 < SafeInt!byte(3));
assert(s2 > SafeInt!byte(1));
assert(s2 > 1.0);

s2 += 1;
assert(s2 == 3);

auto s3 = SafeInt!int(2);
auto s4 = s1 + s3;
static assert(is(typeof(s4) == SafeInt!int));
assert(!s4.isNaN);
assert(s4 == 3);

assert(SafeInt!int(0) == 0.0);
this(V)(in V v) if (isNumeric!V || is(V : SafeInt!S, S));
The constructor for SafeInt.
The passed value must either be an basic numeric or another SafeInt value. The value of the passed parameter must fit into the value range defined by the template specialization of the SafeInt.
Parameters:
V v the value to construct the SafeInt from.
const @property bool isNaN();
Check if this SafeInts value is NaN.
Returns:
true is value is NaN, false otherwise.
SafeInt!T opOpAssign(string op, V)(V vIn);
This implements +=, -=, %=, /=, *= for this SafeInt.
Returns:
a copy of this SafeInt.
const SafeInt!T opBinary(string op, V)(V vIn);
This implements +, -, %, /, * for this SafeInt.
If the result of the operation can not be stored by the SafeInt!T, the resulting value is nan.
Returns:
a new SafeInt!T with the result of the operation.
SafeInt!T opAssign(V)(V vIn) if (isNumeric!T && is(V : SafeInt!S, S));
Implements the assignment operation for the SafeInt type.
Every numeric value and every SafeInt can be assigned. If the passed value can not be stored by the SafeInt, the value of the SafeInt will be set to NaN.
Parameters:
V vIn the value to assign
Returns:
a copy of this SafeInt.
const bool opEquals(V)(auto ref V vIn);
Implements the equality comparison function for the SafeInt type.
Parameters:
V vIn the value to compare the SafeInt with
Returns:
true if the passed value is equal to the value stored in the SafeInt, false otherwise.
const int opCmp(V)(auto ref V vIn);
Implements the comparison function for the SafeInt type.
Parameters:
V vIn the value to compare the SafeInt with
Returns:
-1 if the SafeInt is less than vIn, 1 if the SafeInt is greater than vIn, 0 otherwise.