1 /*******************************************************************************
2 
3     Utilities to get string representations of symbols.
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. All rights reserved.
12 
13     License:
14         Boost Software License Version 1.0. See LICENSE_BOOST.txt for details.
15         Alternatively, this file may be distributed under the terms of the Tango
16         3-Clause BSD License (see LICENSE_BSD.txt for details).
17 
18 *******************************************************************************/
19 
20 module ocean.meta.codegen.Identifier;
21 
22 import ocean.meta.AliasSeq;
23 import ocean.meta.codegen.CTFE;
24 import ocean.meta.types.Qualifiers;
25 import ocean.meta.types.Function;
26 
27 version (unittest)
28 {
29     import ocean.meta.types.Typedef;
30 }
31 
32 /*******************************************************************************
33 
34     Returns "name" (identifier) of a given symbol as string
35 
36     When used with aggregate type field, will return only name of field itself,
37     without any qualification.
38 
39     Params:
40         Sym = any symbol alias
41 
42 *******************************************************************************/
43 
44 public template identifier ( alias Sym )
45 {
46     enum identifier = __traits(identifier, Sym);
47 }
48 
49 ///
50 unittest
51 {
52     class ClassName { int fieldName; }
53 
54     static assert (identifier!(ClassName) == "ClassName");
55     assert (identifier!(ClassName) == "ClassName");
56 
57     static assert (identifier!(ClassName.fieldName) == "fieldName");
58     assert (identifier!(ClassName.fieldName) == "fieldName");
59 
60     void funcName ( ) { }
61 
62     static assert (identifier!(funcName) == "funcName");
63     assert (identifier!(funcName) == "funcName");
64 
65     extern(C) static void funcNameArgs ( int a, double b ) { }
66 
67     static assert (identifier!(funcNameArgs) == "funcNameArgs");
68     assert (identifier!(funcNameArgs) == "funcNameArgs");
69 }
70 
71 /*******************************************************************************
72 
73     Template to get the name of the ith member of a struct / class.
74 
75     Used over plain `identifier` when iterating over aggregate fields with
76     `.tupleof` as compiler refuses to pass such field as template alias
77     parameter.
78 
79     Params:
80         i = index of member to get
81         T = type of compound to get member name from
82 
83     Returns:
84         name of the ith member
85 
86 *******************************************************************************/
87 
88 public template fieldIdentifier ( T, size_t i )
89 {
90     enum fieldIdentifier = identifier!(T.tupleof[i]);
91 }
92 
93 unittest
94 {
95     static struct TestStruct
96     {
97         int a;
98         double b;
99     }
100 
101     static assert (fieldIdentifier!(TestStruct, 0) == "a");
102     static assert (fieldIdentifier!(TestStruct, 1) == "b");
103 
104     assert (fieldIdentifier!(TestStruct, 0) == "a");
105     assert (fieldIdentifier!(TestStruct, 1) == "b");
106 
107     struct Foo { AliasSeq!(int, double, Object) fields; }
108     static assert (fieldIdentifier!(Foo, 0) == "__fields_field_0");
109 }