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; []) {}}})));