1 /*******************************************************************************
2 
3     Utilities to manipulate array types
4 
5     NB: because this module is often used as purely compile-time dependency it
6         used built-in asserts instead of `ocean.core.Test` to reduce amount of
7         cyclic imports. `ocean.meta` modules in general are not supposed to
8         import anything outside of `ocean.meta`.
9 
10     Copyright:
11         Copyright (c) 2017 dunnhumby Germany GmbH.
12         All rights reserved.
13 
14     License:
15         Boost Software License Version 1.0. See LICENSE_BOOST.txt for details.
16         Alternatively, this file may be distributed under the terms of the Tango
17         3-Clause BSD License (see LICENSE_BSD.txt for details).
18 
19 *******************************************************************************/
20 
21 module ocean.meta.types.Arrays;
22 
23 import ocean.meta.traits.Basic;
24 
25 /*******************************************************************************
26 
27     Params:
28         T = any array type
29 
30     Returns:
31         If T is static or dynamic array, evaluates to single type which is the
32         element type of that array. If T is an associative array, return
33         templated struct with separate type aliases for `Key` and `Value`.
34 
35 *******************************************************************************/
36 
37 public template ElementTypeOf ( T )
38 {
39     static if (isArrayType!(T) == ArrayKind.Dynamic
40             || isArrayType!(T) == ArrayKind.Static)
41     {
42         static if (is(T U : U[]))
43         {
44             alias U ElementTypeOf;
45         }
46     }
47     else static if (isArrayType!(T) == ArrayKind.Associative)
48     {
49         alias AAElementType!(typeof(T.init.keys[0]), typeof(T.init.values[0]))
50             ElementTypeOf;
51     }
52     else
53     {
54         static assert (false, "T must be some array type");
55     }
56 }
57 
58 ///
59 unittest
60 {
61     static assert (is(ElementTypeOf!(int[]) == int));
62     static assert (is(ElementTypeOf!(int[5]) == int));
63     static assert (is(ElementTypeOf!(int[][10]) == int[]));
64 
65     alias ElementTypeOf!(double[int]) ElementType;
66     static assert (is(ElementType.Key == int));
67     static assert (is(ElementType.Value == double));
68 }
69 
70 /// see `ElementTypeOf`
71 public struct AAElementType ( TKey, TValue )
72 {
73     alias TKey Key;
74     alias TValue Value;
75 }
76 
77 /*******************************************************************************
78 
79     Params:
80         T = any type
81 
82     Returns:
83         If T is static or dynamic array, evaluates to single type which is the
84         element type of that array. If such element type would also be an array,
85         evaluates to its element type instead and so on recursively. In all
86         other cases evaluates to just T.
87 
88 *******************************************************************************/
89 
90 public template StripAllArrays ( T )
91 {
92     static if (isArrayType!(T) == ArrayKind.Dynamic
93             || isArrayType!(T) == ArrayKind.Static)
94     {
95         alias StripAllArrays!(ElementTypeOf!(T)) StripAllArrays;
96     }
97     else
98     {
99         alias T StripAllArrays;
100     }
101 }
102 
103 ///
104 unittest
105 {
106     static assert (is(StripAllArrays!(int[][4][][]) == int));
107     static assert (is(StripAllArrays!(int[float][4][][]) == int[float]));
108     static assert (is(StripAllArrays!(double) == double));
109 }