Skip to content

Instantly share code, notes, and snippets.

@AnthonyMikh
Last active September 23, 2022 20:19
Show Gist options
  • Save AnthonyMikh/c81bf79950c7da72e99fd1421c5e7ede to your computer and use it in GitHub Desktop.
Save AnthonyMikh/c81bf79950c7da72e99fd1421c5e7ede to your computer and use it in GitHub Desktop.
Реализация макроса по переводу константных числовых значений в строковые константы
macro_rules! make_literal_maker {
($name:ident : $ty:ident) => {
macro_rules! $name {
($n:expr) => {{
const fn digits_len(mut n: $ty) -> ::core::primitive::usize {
if n == 0 {
return 1;
}
let mut n_digits = 0;
#[allow(unused_comparisons)]
if n < 0 {
n_digits += 1;
}
while n != 0 {
n /= 10;
n_digits += 1;
}
n_digits
}
const VALUE: $ty = $n;
const LEN: ::core::primitive::usize = digits_len(VALUE);
type Array = [::core::primitive::u8; LEN];
const fn extract_digit(n: $ty) -> $ty {
let ret = n % 10;
#[allow(unused_comparisons)]
if ret < 0 {
0 - ret
} else {
ret
}
}
const fn to_ascii(mut n: $ty) -> Array {
let mut ret = [0; LEN];
if n == 0 {
ret[0] = b'0';
return ret
}
#[allow(unused_comparisons)]
if n < 0 {
ret[0] = b'-';
}
let mut i = LEN;
while n != 0 {
ret[i - 1] = extract_digit(n) as ::core::primitive::u8 + b'0';
n /= 10;
i -= 1;
}
ret
}
const STR_BYTES: &[::core::primitive::u8] = &to_ascii(VALUE);
#[allow(unsafe_code)]
const STR: &str = unsafe {
::core::str::from_utf8_unchecked(STR_BYTES)
};
STR
}}
}
}
}
make_literal_maker!(make_str_literal_from_usize: usize);
make_literal_maker!(make_str_literal_from_i8: i8);
const STR_UNSIGNED: &str = make_str_literal_from_usize!(41 + 3 - 2);
const STR_SIGNED: &str = make_str_literal_from_i8!(-100 - 1);
fn main() {
assert_eq!(STR_UNSIGNED, "42");
assert_eq!(STR_SIGNED, "-101");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment