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 }