Я пишу модуль с шаблонами примесей, чтобы предоставить функцию 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?