Mixins с переменным числом строковых аргументов в D? - PullRequest
4 голосов
/ 21 июня 2011

Я работаю над некоторыми привязками D для существующей библиотеки C, и у меня есть несколько определений функций и несколько привязок для них.Например:

// Functions
void function(int) funcA;
long function() funcB;
bool function(bool) funcC;
char function(string) funcD;
// etc...

// Bindings
if(!presentInLibrary("func")) return false;
if(!bindFunction(funcA, "funcA")) return false;
if(!bindFunction(funcB, "funcB")) return false;
if(!bindFunction(funcC, "funcC")) return false;
if(!bindFunction(funcD, "funcD")) return false;
// etc...

Эта модель очень похожа на то, как Derelict обрабатывает загрузку расширения OpenGL.Тем не менее, это похоже на избыточную типизацию.Мне бы очень хотелось, чтобы вышеприведенная часть «связывания» была выражена примерно так:

BINDGROUP("func", "funcA", "funcB", "funcC", "funcD", ...); // Name of function group, then variable list of function names.

Это можно сделать с помощью миксинов?

Ответы [ 3 ]

5 голосов
/ 21 июня 2011

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

void function() a;
int function(int) b;
void function(string) c;

string bindFunctions(string[] funcs...)
{
    string ret;
    foreach (func; funcs)
    {
        ret ~= func ~ ` = cast(typeof(` ~ func ~ `))lib.getSymbol("` ~ func ~ `");`;
    }
    return ret;
}
mixin(bindFunctions("a", "b", "c"));

Здесь bindFunctions("a", "b", "c") возвращает строку, которая выглядит примерно так:

a = cast(typeof(a))lib.getSymbol("a");
b = cast(typeof(b))lib.getSymbol("b");
c = cast(typeof(c))lib.getSymbol("c");

Где lib.getSymbol() возвращает указатель от dl_open() и т. Д. Надеюсь, это поможет.

4 голосов
/ 21 июня 2011

Я считаю, что это то, что вы ищете

template BINDGROUP(string group,T...){
    alias BINDGROUP presentInLibrary("func") && BINDGROUPFUNCS!(T);
}

template BINDGROUPFUNCS(T...){
    static if(T.length)alias BINDGROUPFUNCS true; // all is successful
    else alias BINDGROUPFUNCS bindFunction(mixin(T), T) && BINDGROUPFuncts!(T[1..$]);
}

Я использую рекурсивное объявление шаблона здесь, вы также можете сделать это с помощью циклов foreach

4 голосов
/ 21 июня 2011

Полагаю, вы имели в виду струнные миксины? Вы можете просто использовать синтаксис Vararg для D:

string BINDGROUP(string functionGroup, string[] functions...)
{
    // ...
}

mixin(BINDGROUP("func", "funcA", "funcB", "funcC", "funcD"));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...