On Thursday, 20 October 2016 at 12:38:40 UTC, Nordlöw wrote:
On Wednesday, 19 October 2016 at 19:39:46 UTC, Nordlöw wrote:
On Wednesday, 19 October 2016 at 19:01:50 UTC, Meta wrote:
https://goo.gl/t9m3YK
I'm actually pretty impressed that this kind of code can be
written in D.
Thanks! Add at
https://github.com/nordlow/phobos-next/blob/master/src/algorithm_ex.d#L2234
Made it even modular by factoring out arrayN at
https://github.com/nordlow/phobos-next/blob/master/src/algorithm_ex.d#L2200
and used at
https://github.com/nordlow/phobos-next/blob/master/src/algorithm_ex.d#L2215
Code:
ElementType!R[n] arrayN(size_t n, R)(R r)
{
assert(r.length == n);
typeof(return) dst;
import std.algorithm.mutation : copy;
r.copy(dst[]);
return dst;
}
typeof(fun(E.init))[n] map(alias fun, E, size_t n)(const E[n]
src)
{
import std.algorithm.iteration : map;
return src[].map!fun.arrayN!n;
}
@safe pure nothrow unittest
{
import std.meta : AliasSeq;
foreach (E; AliasSeq!(int, double))
{
enum n = 42;
E[n] c;
const result = map!(_ => _^^2)(c);
static assert(c.length == result.length);
static assert(is(typeof(result) == const(E)[n]));
}
}
Here's my variation on the theme. The main difference being that
instead of eagerly evaluating the range I wrap it with additional
static information. Unfortunately, (AFAIK) Phobos does not take
advantage of ranges with statically known length, similarly to
how it handles ranges with `enum bool empty = false`.
void main()
{
import std.stdio;
int[3] sarr = [1, 2, 3];
auto r1 = sarr.staticLengthRange;
static assert (isInputRange!(typeof(r1)));
static assert (r1.length == 3);
writeln(r1);
auto arr = [1, 2, 3, 4];
auto r2 = arr.map!(a => a * 2).staticLengthRange!4;
static assert (r2.length == 4);
writeln(r2);
}
import std.algorithm.iteration : map;
import std.range.primitives : hasLength, isInputRange;
// Note: this overload has questionable memory safety :(
// Would be quite cool if DIP1000 could support this use case
auto staticLengthRange(T, size_t n)(ref T[n] arr)
{
return .staticLengthRange!(n, T[])(arr[]);
}
auto staticLengthRange(size_t n, R)(R range)
if (isInputRange!R && hasLength!R)
{
struct Result
{
enum size_t length = n;
R _range;
alias _range this;
}
assert (range.length == n);
return Result(range);
}
auto staticLengthRange(size_t n, R)(R range)
if (isInputRange!R && hasLength!R)
{
struct Result
{
enum size_t length = n;
R _range;
alias _range this;
}
assert (range.length == n);
return Result(range);
}