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: Move 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 pure nothrow @safe unittest {
32 	import std.meta : AliasSeq;
33 	foreach (E; AliasSeq!(int, double))
34 	{
35 		enum n = 42;
36 		E[n] c;
37 		const result = c.map!(_ => _^^2);
38 		static assert(c.length == result.length);
39 		static assert(is(typeof(result) == const(E)[n]));
40 	}
41 }
42 
43 import nxt.traits_ex : allSameTypeRecursive;
44 
45 /** Returns: tuple `tup` to a static array.
46  *
47  * See_Also: http://dpaste.dzfl.pl/d0059e6e6c09
48  */
49 inout(T.Types[0])[T.length] toStaticArray1(T)(inout T tup) @trusted
50 if (allSameTypeRecursive!(T.Types))
51 {
52 	return *cast(T.Types[0][T.length]*)&tup; // hackish
53 }
54 
55 ///
56 pure nothrow @safe @nogc unittest {
57 	import std.typecons: tuple;
58 	const auto tup = tuple("a", "b", "c", "d");
59 	const string[4] arr = ["a", "b", "c", "d"];
60 	static assert(is(typeof(tup.toStaticArray1()) == typeof(arr)));
61 	assert(tup.toStaticArray1() == arr);
62 }