1 /**
2  * Module to create stack allocated array literals
3  *
4  * Copyright: Copyright (C) 2011 Pavel Sountsov.  All rights reserved.
5  * License:   BSD style: $(LICENSE)
6  * Authors:   Pavel Sountsov
7  */
8 module tango.core.ArrayLiteral;
9 
10 import tango.core.Traits;
11 
12 /**
13  * Creates a static array composed of passed elements. Note that the array is allocated on the stack, so care
14  * should be taken not to let slices of it escape from functions.
15  * Returns:
16  *  Newly created static array.
17  */
18 auto ArrayLiteral(ElemTypes...)(ElemTypes elems)
19 {
20     alias CommonType!(ElemTypes) ElemT;
21     ElemT[ElemTypes.length] ret;
22 
23     foreach(idx, elem; elems)
24     {
25         alias ElemTypes[idx] OtherElemT;
26         static assert(!isStaticArrayType!(OtherElemT), "Element can't be a static array. Slice it first.");
27         static assert(is(OtherElemT : ElemT), "Incompatible types: "~ElemT.stringof~" and "~OtherElemT.stringof~".");
28         ret[idx] = elem;
29     }
30 
31     return ret;
32 }
33 
34 private template CommonType(ElemTypes...)
35 {
36     static if(ElemTypes.length > 1)
37         alias typeof(true ? ElemTypes[0] : CommonType!(ElemTypes[1..$])) CommonType;
38     else static if(ElemTypes.length == 1)
39         alias ElemTypes[0] CommonType;
40     else
41         alias void CommonType;
42 }
43 
44 debug( UnitTest )
45 {
46     unittest
47     {
48         alias ArrayLiteral AL;
49 
50         assert(AL(1, 2, 3) == [1, 2, 3]);
51         assert(AL(1, 2, 3.3) == [1, 2, 3.3]);
52         assert(AL(1.0L, 2.0f, 3) == [1.0L, 2.0f, 3]);
53         assert(AL(AL(1.0L, 2)[], AL(3.0L)[]) == [[1.0L, 2], [3.0L]]);
54 
55         static assert(is(typeof(AL()[]) == typeof([])));
56         static assert(is(typeof(AL(1, 2.0f, 3.3L)[]) == typeof([1, 2.0f, 3.3L])));
57         static assert(is(typeof(AL(AL(1.0L, 2)[], AL(3.0L)[])[]) == typeof([[1.0L, 2], [3.0L]])));
58     }
59 }