Перевод макроса препроцессора C в шаблон D или миксин - PullRequest
0 голосов
/ 26 февраля 2019

Я работаю над переводом библиотеки C на D, и мне было интересно, каков наилучший способ имитировать следующий макрос препроцессора C в D.

#define LV2_ATOM_SEQUENCE_FOREACH(seq, iter) \
for (LV2_Atom_Event* (iter) = lv2_atom_sequence_begin(&(seq).body); \
    !lv2_atom_sequence_is_end(&(seq).body, (seq).atom.size, (iter)); \
    (iter) = lv2_atom_sequence_next(iter))

Возможно ли вообще имитировать с помощью шаблонапрограммирование или миксины в D?

Пример использования макроса:

LV2_ATOM_SEQUENCE_FOREACH(self->control, event) {
    do stuff with 'event'
    ...
}

Я пытался написать шаблон, который делает что-то похожее, но мне не повезло.

Любая помощь или предложения будут оценены.

1 Ответ

0 голосов
/ 27 февраля 2019

После долгих проб и ошибок я получил его на работу.

void LV2_ATOM_OBJECT_FOREACH(const (LV2_Atom_Object*) obj, void delegate(LV2_Atom_Property_Body* prop) iterDelegate) 
{
    for (LV2_Atom_Property_Body* iter = lv2_atom_object_begin(&obj.body);
        !lv2_atom_object_is_end(&obj.body, obj.atom.size, iter);
        iter = lv2_atom_object_next(iter))
    {
        iterDelegate(iter);
    }
}

Тогда, где используется функция

LV2_ATOM_OBJECT_FOREACH(object, delegate(LV2_Atom_Property_Body* prop)
{
    ...use prop here...
});

Я все еще не уверен, что это полностью правильно.Вызывающая функция: extern(C) Если я попытаюсь сделать LV2_ATOM_OBJECT_FOREACH extern (C), я получу следующую ошибку

function dplug.lv2.atomutil.LV2_ATOM_OBJECT_FOREACH(const(LV2_Atom_Object*) obj, extern (C) void delegate(LV2_Atom_Property_Body* prop) iterDelegate) is not callable using argument types (const(LV2_Atom_Object*), void delegate(LV2_Atom_Property_Body* prop) nothrow @system)

Большое спасибо Адаму за предложения покак подойти к этой проблеме.

...