1 /** 2 TODO 3 4 License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). 5 Authors: Adam Búš 6 */ 7 module btl.traits.common; 8 9 import std.traits : isSomeChar, isArray; 10 11 12 13 /** 14 Type used in forward constructors. 15 */ 16 public struct Forward{} 17 18 19 20 /** 21 same as `__traits(isRef, var)`. 22 */ 23 public enum bool isRef(alias var) = __traits(isRef, var); 24 25 26 27 /** 28 TODO 29 */ 30 version(D_BetterC){ 31 public enum bool platformSupportGC = false; 32 } 33 else{ 34 public enum bool platformSupportGC = true; 35 } 36 37 38 39 /** 40 TODO 41 */ 42 template shouldAddGCRange(T){ 43 import std.traits; 44 45 enum shouldAddGCRange = true 46 && platformSupportGC 47 && hasIndirections!T; 48 } 49 50 51 52 /** 53 remove `shared` from type `T`. 54 */ 55 public alias Unshared(T) = T; 56 public alias Unshared(T: shared U, U) = U; 57 58 59 60 /** 61 Same as `std.traits.hasIndirections` but for classes. 62 */ 63 public template classHasIndirections(T){ 64 import std.traits : hasIndirections; 65 66 static if(is(T == class)){ 67 enum bool classHasIndirections = (){ 68 69 import std.traits : BaseClassesTuple; 70 import std.meta : AliasSeq; 71 72 bool has_indirection = false; 73 74 static foreach (alias B; AliasSeq!(T, BaseClassesTuple!T)) { 75 static foreach(alias Var; typeof(B.init.tupleof)){ 76 static if(hasIndirections!Var) 77 has_indirection = true; 78 } 79 } 80 81 return has_indirection; 82 }(); 83 } 84 else{ 85 enum bool classHasIndirections = false; 86 } 87 } 88 89 90 //alias to `T` if `T` is class or interface, otherwise `T*`. 91 /+public template PtrOrRef(T){ 92 static if(is(T == class) || is(T == interface)) 93 alias PtrOrRef = T; 94 else 95 alias PtrOrRef = T*; 96 }+/ 97 98 99 /** 100 `true` if `T` is class or interface. 101 */ 102 public enum bool isClassOrInterface(T) = is(T == class) || is(T == interface); 103 104 105 106 /** 107 Size of instance, if `T` is class then `__traits(classInstanceSize, T)`, otherwise `T.sizeof` 108 */ 109 public template instanceSize(T){ 110 static if(is(T == class)) 111 enum size_t instanceSize = __traits(classInstanceSize, T); 112 else 113 enum size_t instanceSize = T.sizeof; 114 } 115 116 117 /* 118 [Copy, Move] ConstructableElement: 119 */ 120 template isCopyConstructableElement(From, To = From){ 121 enum isCopyConstructableElement = true 122 && is(typeof((ref From from){ 123 To tmp = from; 124 })); 125 } 126 127 // ditto 128 template isMoveConstructableElement(From, To = From){ 129 import core.lifetime : move; 130 enum isMoveConstructableElement = true 131 && is(typeof((From from){ 132 To tmp = move(from); 133 })); 134 } 135 136 137 138 /* 139 [Copy, Move] AssignableElement: 140 */ 141 template isCopyAssignableElement(From, To = From){ 142 enum isCopyAssignableElement = true 143 && is(typeof((ref From from, ref To to){ 144 to = from; 145 })); 146 } 147 148 // ditto 149 template isMoveAssignableElement(From, To = From){ 150 import core.lifetime : move; 151 enum isMoveAssignableElement = true 152 && is(typeof((From from, ref To to){ 153 to = move(from); 154 })); 155 } 156 157 158 159 160