Схема построения диапазона

Учитывая следующий код

import std.datetime: Clock, SysTime, Duration;
SysTime[] times;
const n = 3;
foreach (i; 0..n) times ~= Clock.currTime;

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

Бонусом было бы, когда это возможно, минимизировать копирование элементов, возможно, с помощью некоторого шаблона построения на месте.

См. также: http://forum.dlang.org/thread/[email protected]#post-yofbijaejfyftpcjdcvd:40forum.dlang.org

Обновление:

Хорошо, вот моя попытка:

enum arityMin0(alias fun) = __traits(compiles, fun());

auto apply(alias fun, N)(N n) if (isCallable!fun &&
                                  arityMin0!fun &&
                                  !is(ReturnType!fun == void) &&
                                  isIntegral!N)
{
    import std.range: iota, map;
    return n.iota.map!(n => fun);
}

называется, например,

import std.datetime: Clock;
auto times = 3.apply!(Clock.currTime).array;

Осталась одна деталь. Ограничение

arity!fun == 0

оценить до false в

auto times = 3.apply!(Clock.currTime).array;

потому что арность на самом деле здесь либо 0, либо 1.

Таким образом, arity!fun оценивается как 1 в этом случае, потому что Clock.currTime принимает аргумент по умолчанию.

Возможно, нам также нужны arityMin и arityMax в std.traits.

В этом случае я должен использовать __traits(compiles для реализации arityMin?


person Nordlöw    schedule 22.02.2014    source источник
comment
Да. Лучше тестировать возможности, а не атрибуты. Таким образом, ваш код будет более общим и будет работать, например, с функторы.   -  person Vladimir Panteleev    schedule 22.02.2014


Ответы (1)


Оценка currTime трижды:

auto times = 3.iota.map!(n => Clock.currTime).array();

Оценка currTime один раз:

auto times = Clock.currTime.repeat(3).array();
person Vladimir Panteleev    schedule 22.02.2014
comment
В порядке. Отлично. См. дополнительный вопрос выше. - person Nordlöw; 22.02.2014