1 module nxt.static_array_algorithm;
2
3 import std.range.primitives : ElementType;
4
5 /** Overload of `std.array.array` that creates a static array of length `n`.
6 *
7 * TODO Better name: {make,array}{N,Exactly}
8 * TODO could we find a way to propagate length at compile-time?
9 */
10 ElementType!R[n] toStaticArray(size_t n, R)(R r)
11 {
12 assert(r.length == n);
13 typeof(return) dst;
14 import std.algorithm.mutation : copy;
15 r.copy(dst[]);
16 return dst;
17 }
18
19 /** Static array overload for `std.algorithm.iteration.map`.
20 *
21 * See_Also: http://forum.dlang.org/thread/rqlittlysttwxwphlnmh@forum.dlang.org
22 * TODO Add to Phobos
23 */
24 typeof(fun(E.init))[n] map(alias fun, E, size_t n)(const E[n] src)
25 {
26 import std.algorithm.iteration : map;
27 return src[].map!fun.toStaticArray!n;
28 }
29
30 ///
31 @safe pure nothrow unittest
32 {
33 import std.meta : AliasSeq;
34 foreach (E; AliasSeq!(int, double))
35 {
36 enum n = 42;
37 E[n] c;
38 const result = c.map!(_ => _^^2);
39 static assert(c.length == result.length);
40 static assert(is(typeof(result) == const(E)[n]));
41 }
42 }
43
44 import nxt.traits_ex : allSameTypeRecursive;
45
46 /** Returns: tuple `tup` to a static array.
47 *
48 * See_Also: http://dpaste.dzfl.pl/d0059e6e6c09
49 */
50 inout(T.Types[0])[T.length] toStaticArray1(T)(inout T tup) @trusted
51 if (allSameTypeRecursive!(T.Types))
52 {
53 return *cast(T.Types[0][T.length]*)&tup; // hackish
54 }
55
56 ///
57 @safe pure nothrow @nogc unittest
58 {
59 import std.typecons: tuple;
60 const auto tup = tuple("a", "b", "c", "d");
61 const string[4] arr = ["a", "b", "c", "d"];
62 static assert(is(typeof(tup.toStaticArray1()) == typeof(arr)));
63 assert(tup.toStaticArray1() == arr);
64 }