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<$T>($x: $T, $y: $T): $T

Implementation

public macro fun num_max<$T>($x: $T, $y: $T): $T { let x = $x; let y = $y; if (x > y) x else y }

Macro function num_min

public macro fun num_min<$T>($x: $T, $y: $T): $T

Implementation

public macro fun num_min<$T>($x: $T, $y: $T): $T { let x = $x; let y = $y; if (x < y) x else y }

Macro function num_diff

public macro fun num_diff<$T>($x: $T, $y: $T): $T

Implementation

public macro fun num_diff<$T>($x: $T, $y: $T): $T { 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<$T>($x: $T, $y: $T): $T

Implementation

public macro fun num_divide_and_round_up<$T>($x: $T, $y: $T): $T { 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): _

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

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

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<$T, $R: drop>($start: $T, $stop: $T, $f: |$T| -> $R)

Implementation

public macro fun range_do<$T, $R: drop>($start: $T, $stop: $T, $f: |$T| -> $R) { 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<$T, $R: drop>($start: $T, $stop: $T, $f: |$T| -> $R)

Implementation

public macro fun range_do_eq<$T, $R: drop>($start: $T, $stop: $T, $f: |$T| -> $R) { let mut i = $start; let stop = $stop; // we check i &gt;= stop inside the loop instead of i &lt;= stop as <b>while</b> condition to avoid // incrementing i past the MAX integer value. // Because of this, we need to check if i &gt; stop and return early--instead of letting the // loop bound handle it, like in the <Link to="../std/macros#std_macros_range_do">range_do</Link> macro. if (i > stop) return; loop { $f(i); if (i >= stop) break; i = i + 1; } }

Macro function do

public macro fun do<$T, $R: drop>($stop: $T, $f: |$T| -> $R)

Implementation

public macro fun do<$T, $R: drop>($stop: $T, $f: |$T| -> $R) { range_do!(0, $stop, $f) }

Macro function do_eq

public macro fun do_eq<$T, $R: drop>($stop: $T, $f: |$T| -> $R)

Implementation

public macro fun do_eq<$T, $R: drop>($stop: $T, $f: |$T| -> $R) { range_do_eq!(0, $stop, $f) }

Macro function try_as_u8

public macro fun try_as_u8($x: _): std::option::Option<u8>

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>

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>

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>

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>

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. $T is the underlying integer type for the fixed-point value, where $T has $t_bits bits. $U is the type used for intermediate calculations, where $U is the next larger integer type. $max_t is the maximum value that can be represented by $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

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

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

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

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

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

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

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 }