Тестирование сигнатур функций с помощью ParameterTypeTuple

Я пишу модуль с шаблонами примесей, чтобы предоставить функцию main для модульного тестирования. Использование выглядит следующим образом:

/* For modules without their own main, e.g. libraries.
 * main is conditionally supplied using version(unittest).
 */
mixin Main;

/* For executable modules defining function "realMain".
 * Generated main has the same signature and return type
 * as realMain, and transfers control to it.  Additionally,
 * main exits without calling realMain for version (unittest).
 */
mixin Main!realMain;

Идея состоит в том, что каждый мой модуль соответствующим образом смешивается с main, так что:

  • Библиотекам не нужно, чтобы --main передавалось в rdmd, потому что
  • Кажется, нет хорошего способа решить не передавать --main для модулей, которые определяют свои собственные, при автоматическом запуске модульных тестов для каждого файла в иерархии каталогов — код выхода из rdmd такой же, как и для не удалось скомпилировать.

Я использую std.traits для определения допустимости realMain в качестве функции main и удостоверяюсь, что моя сгенерированная main имеет ту же подпись. Вроде все работает, но думаю можно было бы почище. В настоящее время мой шаблон для проверки допустимых аргументов main выглядит следующим образом:

template isMainArgTypes(alias main)
{
    static if (is(ParameterTypeTuple!main == TypeTuple!()))
        enum isMainArgTypes = true;
    else static if (ParameterTypeTuple!main.length == 1
        && is(ParameterTypeTuple!main[0] T : const T[]))
    {
        enum isMainArgTypes = is(T : const char[]);
    }
    else
        enum isMainArgTypes = false;
}

Я уверен, что должен быть какой-то способ сжать промежуточное условие в одно выражение is, без явного тестирования длины кортежа и отдельной проверки типа строки, но до сих пор мое зарождающееся фу метапрограммирования терпело неудачу.

Есть идеи, волшебники D?


person anton.burger    schedule 01.08.2010    source источник


Ответы (1)


Вы можете попробовать сравнить его с типом функции:

enum isMainArgTypes = is(typeof(&main) == int function()) || 
                      is(typeof(&main) == void function()) || 
                      is(typeof(&main) == int function(string[])) || 
                      is(typeof(&main) == void function(string[]));

Не короче, но выглядит чище, так как не требует static if

person BCS    schedule 01.08.2010
comment
Спасибо за ответ. Преимущество отсутствия специального тестирования функций заключается в том, что вы можете использовать другие виды вызываемых значений, но я согласен, это чище. Также кажется, что наиболее близкие нам примеры идиоматического D на данный момент взяты из источника Фобоса :) - person anton.burger; 25.08.2010