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 <ae@cy.md> 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 private 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 private 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 private 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 private 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()); 134 135 // ************************************************************************ 136 137 private struct TestDualContext 138 { 139 struct S 140 { 141 int i; 142 void call(alias f)() 143 { 144 f(i); 145 } 146 } 147 148 static void test()() 149 { 150 int n; 151 void fun(int i) { n = i; } 152 S s; 153 s.call!fun(); 154 } 155 } 156 157 /// Does this compiler support dual context pointers? 158 /// https://github.com/dlang/dmd/pull/9282 159 version (DMD) 160 enum haveDualContext = __traits(compiles, TestDualContext.test()); 161 else 162 enum haveDualContext = false; // https://github.com/ldc-developers/ldc/commit/d93087ad90664e9be87b79cf70c0f3d26f30f107#commitcomment-35276701 163 164 // ************************************************************************ 165 166 /// Does this compiler support `static foreach`? 167 enum haveStaticForeach = is(typeof(mixin(q{(){ static foreach (x; []) {}}}))); 168 169 /// Does this compiler have UDA support? 170 enum haveUDA = __traits(compiles, __traits(getAttributes, Object));