- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
auto objs = it.get_objects();
switch(objs.size())
{
case 1: sent = _out_stream.send_message(objs[0]);
break;
case 2: sent = _out_stream.send_message(objs[0], objs[1]);
break;
case 3: sent = _out_stream.send_message(objs[0], objs[1], objs[2]);
break;
case 4: sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3]);
break;
case 5: sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4]);
break;
case 6: sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5]);
break;
case 7: sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
objs[6]);
break;
case 8: sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
objs[6], objs[7]);
break;
case 9: sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
objs[6], objs[7], objs[8]);
break;
case 10: sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
objs[6], objs[7], objs[8], objs[9]);
break;
case 11: sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
objs[6], objs[7], objs[8], objs[9], objs[10]);
break;
case 12: sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
objs[6], objs[7], objs[8], objs[9], objs[10], objs[11]);
break;
case 13: sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
objs[6], objs[7], objs[8], objs[9], objs[10], objs[11],
objs[12]);
break;
case 14: sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
objs[6], objs[7], objs[8], objs[9], objs[10], objs[11],
objs[12], objs[13]);
break;
case 15: sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
objs[6], objs[7], objs[8], objs[9], objs[10], objs[11],
objs[12], objs[13], objs[14]);
break;
case 16: sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
objs[6], objs[7], objs[8], objs[9], objs[10], objs[11],
objs[12], objs[13], objs[14], objs[15]);
break;
case 17: sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
objs[6], objs[7], objs[8], objs[9], objs[10], objs[11],
objs[12], objs[13], objs[14], objs[15], objs[16]);
break;
case 18: sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
objs[6], objs[7], objs[8], objs[9], objs[10], objs[11],
objs[12], objs[13], objs[14], objs[15], objs[16], objs[17]);
break;
case 19: sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
objs[6], objs[7], objs[8], objs[9], objs[10], objs[11],
objs[12], objs[13], objs[14], objs[15], objs[16], objs[17],
objs[18]);
break;
case 20: sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
objs[6], objs[7], objs[8], objs[9], objs[10], objs[11],
objs[12], objs[13], objs[14], objs[15], objs[16], objs[17],
objs[18], objs[19]);
break;
default:
fprintf(stderr, "error: Too much attached objects (%lu), talk to developer\n", objs.size());
return false;
}
if (!sent)
{
fprintf(stderr, "error: Unable to send message to output pipe\n");
return false;
}
Меня заставили это сделать, потому что по задумке число вложенных объектов известно на этапе разработки, а у меня - нет.
Вот если б была гомоиконность...
А еще это можно напрограммировать на ассемблере. Зная соглашения вызовов, можно насрать в стек нужное количество хуиты через цикл (регистров наверняка не хватит)
>насрать в стек нужное количество хуиты через цикл (регистров наверняка не хватит)
Там вроде первые скокато питухов нужно пхать в реестры, а остатток можно и в ст... хотя нет... нужно насрать в вызывающем стеке и передать указатель
Ваша система сборки не это поддерживает? Я в своих говнах могу запускать произвольную программу для препроцессора. Генерю лапшу для крестов на крестах и на питоне.
У нас есть проект на жаваговне, и там сборка идет на гредлговне. Гредлговно написано на котлинговне, и потому питузикполно, и можно высрать любое говно вообще, но мы так редко делаем.
В джаваговне метапрограммирования нет от слова совсем. Вот совсем нет. Даже в C# оно есть в некотором смысле, а в джаве нет совсем вообще никакого. Потому джавушок обычно копипастит код, и течет.
В проекте на питонговне у нас бывает метапроговнирование, но в питухоне это просто, тк язык динамический весь насквозь и там в рантайме можно срать что угодно.
В растговне у нас есть пара макросов. В расте довольно мощная (где-то 60% от сишных шаблонов) макропитушня. Типобезопасная, и на расте, но я ее пока плоховато знаю
Опять в школу ((((((
Чатжпт опять обосрался.
Здесь нужно как минимум заменить закат солнца вручную index_sequence на make_index_sequence
Ещё можно превратить send_message_helper в функциональный объект с шаблонным оператором вызова (можно шаблонизированную лямбду запилить) и в свиче писать только
В дебрях Console.Write в CLR я встречал код где вместо varagrs сделали перегрузку со сторопицот аргументов, но там видимо потому, што вараргс порожет массив в куче. А в крестах-то зачем?
Что-ж, это логично.
А как тогда работают VLA и alloca? а? а? а??
Можешь. https://govnokod.ru/27525#comment648368
Хотя смотря что значит "объект"
> размер стека должен быть известен в момент компиляции?
Нет.
Кажется, до C99 это было так.
>Хотя смотря что значит "объект"
Да любая структура, похуй.
Может быть такая функция, которая возвращает "нечто" плюс размер?
Ну то-есть сначала идет usize_t, а затем сколько-то байт. Или ABI такого не позволяет?
> Ну то-есть сначала идет usize_t, а затем сколько-то байт. Или ABI такого не позволяет?
В сишке и крестоговне этого нет, но вообще сделать что-то подобное на ассемблере можно: https://govnokod.ru/25602#comment477597
Потому что кусок стека под возвращаемый объект выделяется до вызова функции, а потом на стек кладётся адрес разврата и аргументы вызываемой функции.
И да, на ассемблере можно придумать обход этого (например, вызываемая функция создаёт полиморфный объект у себя в стеке, а после возврата её фрейм «склеивается» с фреймом вызывающей функции), но ни сишные, ни крестовые ABI такого не позволяют.
Телепатически?
...
в этом месте я понял, что менять придется не только ABI, но и ISA процессора: исправлять то, как работает CALL
Но вообще, кстати, нечто подобное используется в «Winapi»: многие функции, возвращающие объекты неопределённого размера, при отсутствии или недостаточном размеры переданного им выходного буфера возвращают специальный код ашипки и размер буфера, который требуется. То есть можно сделать что-то вроде:
Понятное дело, применять это можно далеко не всегда и не везде, но сам паттерн вполне себе существует.
Перформанс!!1