великолепный мозголомный пиздец |
[Jun. 14th, 2015|06:49 am] |
мы имеем шаблоны, которые возвращают шаблоны, чтобы вы больше шаблоны!
struct foo {
template opDispatch(string s) {
T implementation(T) () if (is(T == int)) {
return T.init+42;
}
T implementation(T) () if (is(T == string)) {
return "wow";
}
alias opDispatch = implementation;
}
}
void main() {
foo f;
int a = f.intprop!int;
string s = f.intprop!string;
import std.stdio;
writeln(a); // 42
writeln(s); // "wow"
} fuckin' trickery!
зачем это надо? чтобы вместо f.intprop.get!string писать просто f.intprop!string .
трюк в том, что просто так вернуть результат шаблона как шаблон нельзя. обычно opDispatch пишут как eponymous template: int opDispatch(string s) () { return 42; } это то же самое, что и:
template opDispatch(string s) {
int opDispatch () { return 42; }
} сокращённая запись просто.
первым делом я подумал, что можно так:
struct foo {
template opDispatch(string s) {
T opDispatch(T) () { return T.init+42; }
}
} а вот те хуй! f.intprop!int даёт Error: no property 'intprop' for type 'foo' . это разворачивается внутри компилятора в конструкцию примерно такого типа: f.opDispatch!"intprop"!int() , и два «!» вводят его в ступор.
трюк в том, чтобы opDispatch возвращала отдельный шаблон, а не шаблонизированую функцию. тогда второй «!» превращается в первый, но для второго шаблона (ну да, вот такое вот понятное пояснение), и всё работает. но сделать просто return mytemplate нельзя: шаблон не функция, он не умеет ничего return . и вот тут‐то вступает в игру могучий alias , который хуй знает как, но работает.
на самом деле внутри всё ещё сложней выглядит (потому что в нерабочем варианте opDispatch тоже разворачивается в шаблон, и вся конструкция получается совершенно ебанутой), но этой дорогой ходить не надо, там в конце живёт дракон.
tbh, это не я придумал, этот трюк мне показал Adam D. Ruppe, очень хороший человек.
p.s. чувак в IRC долго эту хуйню наблюдал, а потом сказал: «вы все ёбнутые.» |
|
|
пилю тулкит |
[Jun. 14th, 2015|09:09 pm] |
подпилил объект стилей. раньше только так курить можно было:
ffkitStyle.setColor("background.active", "#fff");
а теперь ещё и так можно:
ffkitStyle.color.background.active = "#fff";
понятно, что все, идущее после color собирается в строку, и потом дёргается setColor с нужными аргументами. естественно, поля не предопределены, хоть color.hiu.pizda.jigurda пиши. читать тоже можно, причём ещё веселей:
string s = st.color.background.active; — ура, строка.
X11.Color c = st.color.background.active; — ура, иксовый цвет.
а в классе виджета то же самое будет последовательно дёргать стиль виджета (если есть), стиль родителя (если есть) и так далее до глобального стиля софтины. удобняшечка! |
|
|