Skip to main content

Module std::macros

This module holds shared implementation of macros used in std

Macro function num_max

public macro fun num_max($x: _, $y: _): _
Click to open
Implementation
public macro fun num_max($x: _, $y: _): _ {
    let x = $x;
    let y = $y;
    if (x > y) x
    else y
}

Macro function num_min

public macro fun num_min($x: _, $y: _): _
Click to open
Implementation
public macro fun num_min($x: _, $y: _): _ {
    let x = $x;
    let y = $y;
    if (x < y) x
    else y
}

Macro function num_diff

public macro fun num_diff($x: _, $y: _): _
Click to open
Implementation
public macro fun num_diff($x: _, $y: _): _ {
    let x = $x;
    let y = $y;
    if (x > y) x - y
    else y - x
}

Macro function num_divide_and_round_up

public macro fun num_divide_and_round_up($x: _, $y: _): _
Click to open
Implementation
public macro fun num_divide_and_round_up($x: _, $y: _): _ {
    let x = $x;
    let y = $y;
    if (x % y == 0) x / y
    else x / y + 1
}

Macro function num_pow

public macro fun num_pow($base: _, $exponent: u8): _
Click to open
Implementation
public macro fun num_pow($base: _, $exponent: u8): _ {
    let mut base = $base;
    let mut exponent = $exponent;
    let mut res = 1;
    while (exponent >= 1) {
        if (exponent % 2 == 0) {
            base = base * base;
            exponent = exponent / 2;
        } else {
            res = res * base;
            exponent = exponent - 1;
        }
    };
    res
}

Macro function num_sqrt

public macro fun num_sqrt<$T, $U>($x: $T, $bitsize: u8): $T
Click to open
Implementation
public macro fun num_sqrt<$T, $U>($x: $T, $bitsize: u8): $T {
    let x = $x;
    let mut bit = (1: $U) << $bitsize;
    let mut res = (0: $U);
    let mut x = x as $U;
    while (bit != 0) {
        if (x >= res + bit) {
            x = x - (res + bit);
            res = (res >> 1) + bit;
        } else {
            res = res >> 1;
        };
        bit = bit >> 2;
    };
    res as $T
}

Macro function num_to_string

public macro fun num_to_string($x: _): std::string::String
Click to open
Implementation
public macro fun num_to_string($x: _): String {
    let mut x = $x;
    if (x == 0) {
        return b"0".to_string()
    };
    let mut buffer = vector[];
    while (x != 0) {
        buffer.push_back(((48 + x % 10) as u8));
        x = x / 10;
    };
    buffer.reverse();
    buffer.to_string()
}

Macro function range_do

public macro fun range_do($start: _, $stop: _, $f: |_| -> ())
Click to open
Implementation
public macro fun range_do($start: _, $stop: _, $f: |_|) {
    let mut i = $start;
    let stop = $stop;
    while (i < stop) {
        $f(i);
        i = i + 1;
    }
}

Macro function range_do_eq

public macro fun range_do_eq($start: _, $stop: _, $f: |_| -> ())
Click to open
Implementation
public macro fun range_do_eq($start: _, $stop: _, $f: |_|) {
    let mut i = $start;
    let stop = $stop;
    // we check `i >= stop` inside the loop instead of `i <= stop` as `while` condition to avoid
    // incrementing `i` past the MAX integer value.
    // Because of this, we need to check if `i > stop` and return early--instead of letting the
    // loop bound handle it, like in the `range_do` macro.
    if (i > stop) return;
    loop {
        $f(i);
        if (i >= stop) break;
        i = i + 1;
    }
}

Macro function do

public macro fun do($stop: _, $f: |_| -> ())
Click to open
Implementation
public macro fun do($stop: _, $f: |_|) {
    range_do!(0, $stop, $f)
}

Macro function do_eq

public macro fun do_eq($stop: _, $f: |_| -> ())
Click to open
Implementation
public macro fun do_eq($stop: _, $f: |_|) {
    range_do_eq!(0, $stop, $f)
}

Macro function try_as_u8

public macro fun try_as_u8($x: _): std::option::Option<u8>
Click to open
Implementation
public macro fun try_as_u8($x: _): Option<u8> {
    let x = $x;
    if (x > 0xFF) option::none()
    else option::some(x as u8)
}

Macro function try_as_u16

public macro fun try_as_u16($x: _): std::option::Option<u16>
Click to open
Implementation
public macro fun try_as_u16($x: _): Option<u16> {
    let x = $x;
    if (x > 0xFFFF) option::none()
    else option::some(x as u16)
}

Macro function try_as_u32

public macro fun try_as_u32($x: _): std::option::Option<u32>
Click to open
Implementation
public macro fun try_as_u32($x: _): Option<u32> {
    let x = $x;
    if (x > 0xFFFF_FFFF) option::none()
    else option::some(x as u32)
}

Macro function try_as_u64

public macro fun try_as_u64($x: _): std::option::Option<u64>
Click to open
Implementation
public macro fun try_as_u64($x: _): Option<u64> {
    let x = $x;
    if (x > 0xFFFF_FFFF_FFFF_FFFF) option::none()
    else option::some(x as u64)
}

Macro function try_as_u128

public macro fun try_as_u128($x: _): std::option::Option<u128>
Click to open
Implementation
public macro fun try_as_u128($x: _): Option<u128> {
    let x = $x;
    if (x > 0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF) option::none()
    else option::some(x as u128)
}

Macro function uq_from_quotient

Creates a fixed-point value from a quotient specified by its numerator and denominator. Tistheunderlyingintegertypeforthefixedpointvalue,whereT is the underlying integer type for the fixed-point value, where T has tbitsbits.t_bits bits. U is the type used for intermediate calculations, where Uisthenextlargerintegertype.U is the next larger integer type. max_t is the maximum value that can be represented by T.T. t_bits (as mentioned above) is the total number of bits in the fixed-point value (integer plus fractional). $fractional_bits is the number of fractional bits in the fixed-point value.

public macro fun uq_from_quotient<$T, $U>($numerator: $T, $denominator: $T, $max_t: $T, $t_bits: u8, $fractional_bits: u8, $abort_denominator: _, $abort_quotient_too_small: _, $abort_quotient_too_large: _): $T
Click to open
Implementation
public macro fun uq_from_quotient<$T, $U>(
    $numerator: $T,
    $denominator: $T,
    $max_t: $T,
    $t_bits: u8,
    $fractional_bits: u8,
    $abort_denominator: _,
    $abort_quotient_too_small: _,
    $abort_quotient_too_large: _,
): $T {
    let numerator = $numerator;
    let denominator = $denominator;
    if (denominator == 0) $abort_denominator;
    // Scale the numerator to have `$t_bits` fractional bits and the denominator to have
    // `$t_bits - $fractional_bits` fractional bits, so that the quotient will have
    // `$fractional_bits` fractional bits.
    let scaled_numerator = numerator as $U << $t_bits;
    let scaled_denominator = denominator as $U << ($t_bits - $fractional_bits);
    let quotient = scaled_numerator / scaled_denominator;
    // The quotient can only be zero if the numerator is also zero.
    if (quotient == 0 && numerator != 0) $abort_quotient_too_small;
    // Return the quotient as a fixed-point number. We first need to check whether the cast
    // can succeed.
    if (quotient > $max_t as $U) $abort_quotient_too_large;
    quotient as $T
}

Macro function uq_from_int

public macro fun uq_from_int<$T, $U>($integer: $T, $fractional_bits: u8): $U
Click to open
Implementation
public macro fun uq_from_int<$T, $U>($integer: $T, $fractional_bits: u8): $U {
    ($integer as $U) << $fractional_bits
}

Macro function uq_add

public macro fun uq_add<$T, $U>($a: $T, $b: $T, $max_t: $T, $abort_overflow: _): $T
Click to open
Implementation
public macro fun uq_add<$T, $U>($a: $T, $b: $T, $max_t: $T, $abort_overflow: _): $T {
    let sum = $a as $U + ($b as $U);
    if (sum > $max_t as $U) $abort_overflow;
    sum as $T
}

Macro function uq_sub

public macro fun uq_sub<$T>($a: $T, $b: $T, $abort_overflow: _): $T
Click to open
Implementation
public macro fun uq_sub<$T>($a: $T, $b: $T, $abort_overflow: _): $T {
    let a = $a;
    let b = $b;
    if (a < b) $abort_overflow;
    a - b
}

Macro function uq_to_int

public macro fun uq_to_int<$T, $U>($a: $U, $fractional_bits: u8): $T
Click to open
Implementation
public macro fun uq_to_int<$T, $U>($a: $U, $fractional_bits: u8): $T {
    ($a >> $fractional_bits) as $T
}

Macro function uq_int_mul

public macro fun uq_int_mul<$T, $U>($val: $T, $multiplier: $T, $max_t: $T, $fractional_bits: u8, $abort_overflow: _): $T
Click to open
Implementation
public macro fun uq_int_mul<$T, $U>(
    $val: $T,
    $multiplier: $T,
    $max_t: $T,
    $fractional_bits: u8,
    $abort_overflow: _,
): $T {
    // The product of two `$T` bit values has the same number of bits as `$U`, so perform the
    // multiplication with `$U` types and keep the full `$U` bit product
    // to avoid losing accuracy.
    let unscaled_product = $val as $U * ($multiplier as $U);
    // The unscaled product has `$fractional_bits` fractional bits (from the multiplier)
    // so rescale it by shifting away the low bits.
    let product = unscaled_product >> $fractional_bits;
    // Check whether the value is too large.
    if (product > $max_t as $U) $abort_overflow;
    product as $T
}

Macro function uq_int_div

public macro fun uq_int_div<$T, $U>($val: $T, $divisor: $T, $max_t: $T, $fractional_bits: u8, $abort_division_by_zero: _, $abort_overflow: _): $T
Click to open
Implementation
public macro fun uq_int_div<$T, $U>(
    $val: $T,
    $divisor: $T,
    $max_t: $T,
    $fractional_bits: u8,
    $abort_division_by_zero: _,
    $abort_overflow: _,
): $T {
    let val = $val;
    let divisor = $divisor;
    // Check for division by zero.
    if (divisor == 0) $abort_division_by_zero;
    // First convert to $U to increase the number of bits to the next integer size
    // and then shift left to add `$fractional_bits` fractional zero bits to the dividend.
    let scaled_value = val as $U << $fractional_bits;
    let quotient = scaled_value / (divisor as $U);
    // Check whether the value is too large.
    if (quotient > $max_t as $U) $abort_overflow;
    quotient as $T
}