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 enum haveChildTrait = false;
20 
21 // ************************************************************************
22 
23 struct TestFieldAliasBinding
24 {
25 	static template T(alias a)
26 	{
27 		void foo()() { a = 0; }
28 	}
29 
30 	struct S(alias T)
31 	{
32 		int f;
33 		alias t = T!f;
34 	}
35 
36 	static void test()()
37 	{
38 		S!T s;
39 		s.t.foo();
40 	}
41 }
42 
43 /// Does this compiler support binding field context via alias parameters?
44 /// https://github.com/D-Programming-Language/dmd/pull/2794
45 /// Added   in 2.065.0: https://github.com/D-Programming-Language/dmd/pull/2794
46 /// Removed in 2.066.1: https://github.com/D-Programming-Language/dmd/pull/3884
47 enum haveFieldAliasBinding = __traits(compiles, TestFieldAliasBinding.test());
48 
49 // ************************************************************************
50 
51 struct TestMethodAliasBinding
52 {
53 	static template T(alias a)
54 	{
55 		void foo()() { a(); }
56 	}
57 
58 	struct S(alias T)
59 	{
60 		void m() { }
61 		alias t = T!m;
62 	}
63 
64 	static void test()()
65 	{
66 		S!T s;
67 		s.t.foo();
68 	}
69 }
70 
71 /// Does this compiler support binding method context via alias parameters?
72 /// https://github.com/D-Programming-Language/dmd/pull/3345
73 enum haveMethodAliasBinding = __traits(compiles, TestMethodAliasBinding.test());
74 
75 // ************************************************************************
76 
77 struct TestAliasCtxInference
78 {
79 	struct A
80 	{
81 		void fun() {}
82 
83 		void caller(T)(T t)
84 		{
85 			t.callee();
86 		}
87 	}
88 
89 	struct B
90 	{
91 		alias callee = A.fun;
92 	}
93 
94 	static void test()()
95 	{
96 		A a;
97 		B b;
98 		a.caller(b);
99 	}
100 }
101 
102 /// Does this compiler support inferring "this" of an aliased
103 /// method call from the current context?
104 /// https://github.com/D-Programming-Language/dmd/pull/3361
105 enum haveAliasCtxInference = __traits(compiles, TestAliasCtxInference.test());
106 
107 // ************************************************************************
108 
109 struct TestAliasStructBinding
110 {
111 	struct S(alias fun)
112 	{
113 		void call(T)(T t)
114 		{
115 			fun(t);
116 		}
117 	}
118 
119 	static void test()()
120 	{
121 		int n;
122 
123 		// Hmm, why doesn't this work?
124 		//void fun(T)(T x) { n += x; }
125 		//S!fun s;
126 
127 		S!(x => n+=x) s;
128 		s.call(42);
129 	}
130 }
131 
132 /// Does this compiler support binding lambdas via struct template alias parameters?
133 /// https://github.com/dlang/dmd/pull/5518
134 enum haveAliasStructBinding = __traits(compiles, TestAliasStructBinding.test());
135 
136 // ************************************************************************
137 
138 struct TestDualContext
139 {
140 	struct S
141 	{
142 		int i;
143 		void call(alias f)()
144 		{
145 			f(i);
146 		}
147 	}
148 
149 	static void test()()
150 	{
151 		int n;
152 		void fun(int i) { n = i; }
153 		S s;
154 		s.call!fun();
155 	}
156 }
157 
158 /// Does this compiler support dual context pointers?
159 /// https://github.com/dlang/dmd/pull/9282
160 version (DMD)
161 	enum haveDualContext = __traits(compiles, TestDualContext.test());
162 else
163 	enum haveDualContext = false; // https://github.com/ldc-developers/ldc/commit/d93087ad90664e9be87b79cf70c0f3d26f30f107#commitcomment-35276701
164 
165 // ************************************************************************
166 
167 enum haveStaticForeach = is(typeof(mixin(q{(){ static foreach (x; []) {}}})));