1.83K subscribers
3.3K photos
132 videos
15 files
3.58K links
Блог со звёздочкой.

Много репостов, немножко программирования.

Небольшое прикольное комьюнити: @decltype_chat_ptr_t
Автор: @insert_reference_here
Download Telegram
...С другой стороны, зачем ограничиваться именно u32? Наш код вполне может работать с другими типами! Давайте это исправим:

macro_rules! make_literal {
(($n:expr) : $ty:ty) => {{
// то же, что и было, но заменяем u32 на $ty
STR: &str = ...;
STR
}}
}


Проверим:

const STR: &str = make_literal!((41 + 1): u32);

fn main() {
assert_eq!(STR, "42");
}


Оно работает! Хотя... Работает ли?

const STR: &str = make_literal!((-41 - 1): i32);

fn main() {
assert_eq!(STR, "-42");
}


И...

error: any use of this value will cause an error
--> src/main.rs:42:26
|
42 | ret[i] = (n % 10) as u8 + b'0';
| ^^^^^^^^^^^^^^^^^^^^^
| |
| attempt to compute `254_u8 + 48_u8`, which would overflow
| inside `to_ascii` at src/main.rs:42:26
| inside `DECOMPOSED` at src/main.rs:59:48


Ясно, нам нужно что-то иное: остаток от деления отрицательного числа на положительное является отрицательным, а нам нужно положительное число, у которого нужно поменять знак. Что, сделаем для этого функцию и запихнём в макрос:

const fn extract_digit(n: $ty) -> $ty {
let mut ret = n % 10;
#[allow(unused_comparisons)]
// ^ сравнение не имеет смысла для беззнаковых чисел
if ret < 0 {
// мы не можем написать ret = -ret,
// поскольку унарный минус не определён для беззнаковых
ret = 0-ret;
}
ret
}


Другие функции нам тоже нужно поменять, чтобы печатать минус:

const fn digits_len(mut n: $ty) -> usize {
if n == 0 {
return 1;
}
let mut n_digits = 0;
#[allow(unused_comparisons)]
if n < 0 {
n_digits += 1;
}
...
}
...
const fn to_ascii(mut n: $ty) -> ([u8; LEN], usize) {
#[allow(unused_comparisons)]
let is_negative = n < 0;
...
while n != 0 {
ret[i] = extract_digit(n) as u8 + b'0';
n /= 10;
i += 1;
}
if is_negative {
ret[i] = b'-';
i += 1;
}
...


Протестируем:

const STR: &str = make_literal!((-41 - 1): i32);

fn main() {
assert_eq!(STR, "-42");
}


Работает!

...Закончили ли мы на этом? Нет! Во-первых, я не хочу указывать каждый раз тип выражения. Во-вторых, из-за ограничений macro_rules! после expr нельзя ставить двоеточие, из-за чего мне пришлось внести в синтаксис раздражающие скобки. Как известно, всякую проблему можно решить ещё одним слоем абстракции, поэтому я именно этим и воспользуюсь: я сделаю макрос, который принимает имя и тип и генерирует ещё один макрос с переданным именем, который принимает выражение нужного типа и уже возвращает константу:

macro_rules! make_literal_maker {
($name:ident : $ty:ty) => {
macro_rules! $name {
($n:expr) => {{
// весь остальной код без изменений
}}
}
}
}


Проверим:

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");
}


Вот теперь всё работает. Как всегда, код в гисте.
От этого поста телеге немного поплохело: когда я перематывал поле ввода наверх, а потом обратно в конец, часть написанного в конце пропадало и было недоступно для редактирования. К счастью, этот баг был чисто визуальным — переключение между каналами вернуло набранное — но, блин, Дуров, какого хрена?
Forwarded from ps
Тут, как оказалось, есть ещё один путь: попасть в контору с си/плюсами и начать внедрять раст. Иногда это получается ещё на этапе собеседования.
Forwarded from вафля 🧇🍓
На собеседовании? Это как? :D
Forwarded from ps
Ну приходишь на собеседование на позицию девелопера, убеждаешь работодателя в том, что раст намного лучше подходит для их задачи)
Forwarded from ps
Вроде один из оргов московского раст-митапа именно так и сделал
У меня для вас две новости касательно Ильи aka @optozorax_dev.
Во-первых, он начинает карьеру фуд-блогера.
Во-вторых, у него сегодня день рождения! Поздравляю, Илья!
Forwarded from Дежурный DevOps
Скорее бы 5G. Хочу уже увидеть JavaScript фреймворки по гигабайту и рассуждения, что просто по другому сделать нельзя.
#prog #cpp #rust #article

В относительно недавней статье автор вопрошает, заслуживает ли C++ те плохие вещи, которые о нём говорят. Ответная статья показывает, что таки заслуживает.
Хочется написать compile-time крестики-нолики. Самое страшное, что я даже представляю, как это сделать, причём и на const fn, и на типах.
#prog #article #java

Статья о маленьких оптимизациях в Java (и в стандартной библиотеке, и в JVM). Статья интересная сама по себе, но я хочу обратить ваше внимание на проблемы в computeIfAbsent и removeIf, связанные с неограниченным алиасингом указателей.
#prog #go

Оно, конечно, хорошо. Непонятно только, почему это происходит лишь сейчас. А ещё — как там собираются регистры между yield-ами сохранять.
#prog #rust

Замечательно, важная веха для всей экосистемы.