Skip to main content

value_cast

An explicit conversion between numeric types. value_cast<T>(expr) returns T. value_cast?<T>(expr) returns Optional<T>, and is none when the value does not fit.

const narrow: int16 = 42;

const wide: int32 = value_cast<int32>(narrow);
const checked: Optional<int8> = value_cast?<int8>(narrow);

Casting​

Flex has no implicit conversion between numeric types, which is what makes the cast the only route.

  • Source and target must both be numeric: an intN, a uintN, a float32, or a float64.
  • value_cast<T> requires a widening pair — uintN to uintM for M at least N, intN to intM for M at least N, uintN to intM for M greater than N, and float32 to float64. Every other pair needs value_cast?.
  • value_cast?<T> returns Optional<T> and is the form for a pair value_cast will not take.
  • float64 to float32 goes through the float64to32 built-in, which is a function rather than a cast because it loses precision.
  • A cast is not subject to the wrapping rule that governs arithmetic. It either widens losslessly or reports absence.
const narrow: int16 = 42;

value_cast<int32>(narrow)                       // => 42
value_cast<float64>((0.5: float32))             // => 0.5
value_cast?<int8>((127: int16))                 // => some(127)
value_cast?<int8>((128: int16))                 // => none
getOrElse(value_cast?<uint8>((42: int8)), 0)    // => 42
float64to32((0.5: float64))                     // => 0.5

Errors​

A source that is not numeric​

const flag: bit = true;

const code: int32 = value_cast<int32>(flag);   // error: value-cast-source-type

A target that is not numeric​

const label: string = value_cast<string>((42: int32));   // error: value-cast-target-type

A narrowing conversion asked for infallibly​

value_cast promises a value of the target type, which it cannot do for a pair that may not fit.

const narrow: int8 = value_cast<int8>((128: int16));   // error: value-cast-widening

A float64 narrowed to a float32​

float64to32 is the supported narrowing, and it is a built-in function rather than a cast.

const ratio: float32 = value_cast<float32>((0.5: float64));   // error: value-cast-target-type, value-cast-widening
  • primitives — the numeric types and their assignability rule.
  • optional — what the fallible form returns.
  • operators — the wrapping arithmetic a cast is exempt from.
  • builtin functions — float64to32, and the other conversions that are functions.