1 /**
2  * Compiler capability detection
3  *
4  * License:
5  *   This Source Code Form is subject to the terms of
6  *   the Mozilla Public License, v. 2.0. If a copy of
7  *   the MPL was not distributed with this file, You
8  *   can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * Authors:
11  *   Vladimir Panteleev <vladimir@thecybershadow.net>
12  */
13 
14 module ae.utils.meta.caps;
15 
16 /// Does this compiler support __traits(child) ?
17 /// https://github.com/D-Programming-Language/dmd/pull/3329
18 enum haveChildTrait = is(typeof({ struct S { int i; } S s; __traits(child, s, S.i) = 0; }));
19 
20 // ************************************************************************
21 
22 struct TestFieldAliasBinding
23 {
24 	static template T(alias a)
25 	{
26 		void foo()() { a = 0; }
27 	}
28 
29 	struct S(alias T)
30 	{
31 		int f;
32 		alias t = T!f;
33 	}
34 
35 	static void test()()
36 	{
37 		S!T s;
38 		s.t.foo();
39 	}
40 }
41 
42 /// Does this compiler support binding field context via alias parameters?
43 /// https://github.com/D-Programming-Language/dmd/pull/2794
44 /// Added   in 2.065.0: https://github.com/D-Programming-Language/dmd/pull/2794
45 /// Removed in 2.066.1: https://github.com/D-Programming-Language/dmd/pull/3884
46 enum haveFieldAliasBinding = __traits(compiles, TestFieldAliasBinding.test());
47 
48 // ************************************************************************
49 
50 struct TestMethodAliasBinding
51 {
52 	static template T(alias a)
53 	{
54 		void foo()() { a(); }
55 	}
56 
57 	struct S(alias T)
58 	{
59 		void m() { }
60 		alias t = T!m;
61 	}
62 
63 	static void test()()
64 	{
65 		S!T s;
66 		s.t.foo();
67 	}
68 }
69 
70 /// Does this compiler support binding method context via alias parameters?
71 /// https://github.com/D-Programming-Language/dmd/pull/3345
72 enum haveMethodAliasBinding = __traits(compiles, TestMethodAliasBinding.test());
73 
74 // ************************************************************************
75 
76 struct TestAliasCtxInference
77 {
78 	struct A
79 	{
80 		void fun() {}
81 
82 		void caller(T)(T t)
83 		{
84 			t.callee();
85 		}
86 	}
87 
88 	struct B
89 	{
90 		alias callee = A.fun;
91 	}
92 
93 	static void test()()
94 	{
95 		A a;
96 		B b;
97 		a.caller(b);
98 	}
99 }
100 
101 /// Does this compiler support inferring "this" of an aliased
102 /// method call from the current context?
103 /// https://github.com/D-Programming-Language/dmd/pull/3361
104 enum haveAliasCtxInference = __traits(compiles, TestAliasCtxInference.test());
105 
106 // ************************************************************************
107 
108 struct TestAliasStructBinding
109 {
110 	struct S(alias fun)
111 	{
112 		void call(T)(T t)
113 		{
114 			fun(t);
115 		}
116 	}
117 
118 	static void test()()
119 	{
120 		int n;
121 
122 		// Hmm, why doesn't this work?
123 		//void fun(T)(T x) { n += x; }
124 		//S!fun s;
125 
126 		S!(x => n+=x) s;
127 		s.call(42);
128 	}
129 }
130 
131 /// Does this compiler support binding lambdas via struct template alias parameters?
132 /// https://github.com/dlang/dmd/pull/5518
133 enum haveAliasStructBinding = __traits(compiles, TestAliasStructBinding.test());