1 module d.common.qualifier; 2 3 enum Visibility { 4 Private, 5 Package, 6 Protected, 7 Public, 8 Export, 9 } 10 11 enum Linkage { 12 D, 13 C, 14 Cpp, 15 Windows, 16 System, 17 Pascal, 18 Java, 19 } 20 21 enum Storage { 22 Local, 23 Capture, 24 Static, 25 Enum, 26 } 27 28 @property 29 bool isGlobal(Storage s) { 30 return s > Storage.Capture; 31 } 32 33 @property 34 bool isLocal(Storage s) { 35 return !isGlobal(s); 36 } 37 38 unittest { 39 with (Storage) { 40 assert(Local.isGlobal == false); 41 assert(Local.isLocal == true); 42 assert(Capture.isGlobal == false); 43 assert(Capture.isLocal == true); 44 assert(Static.isGlobal == true); 45 assert(Static.isLocal == false); 46 assert(Enum.isGlobal == true); 47 assert(Enum.isLocal == false); 48 } 49 } 50 51 enum TypeQualifier { 52 Mutable, 53 Inout, 54 Const, 55 Shared, 56 ConstShared, 57 Immutable, 58 } 59 60 // XXX: operator overloading ? 61 auto add(TypeQualifier actual, TypeQualifier added) { 62 if ((actual == TypeQualifier.Shared && added == TypeQualifier.Const) 63 || (added == TypeQualifier.Shared 64 && actual == TypeQualifier.Const)) { 65 return TypeQualifier.ConstShared; 66 } 67 68 import std.algorithm; 69 return max(actual, added); 70 } 71 72 unittest { 73 import std.traits; 74 foreach (q1; EnumMembers!TypeQualifier) { 75 assert(TypeQualifier.Mutable.add(q1) == q1); 76 assert(TypeQualifier.Immutable.add(q1) == TypeQualifier.Immutable); 77 78 foreach (q2; EnumMembers!TypeQualifier) { 79 assert(q1.add(q2) == q2.add(q1)); 80 } 81 } 82 83 with (TypeQualifier) { 84 assert(Const.add(Immutable) == Immutable); 85 assert(Const.add(Inout) == Const); 86 assert(Const.add(Shared) == ConstShared); 87 assert(Const.add(ConstShared) == ConstShared); 88 89 assert(Immutable.add(Inout) == Immutable); 90 assert(Immutable.add(Shared) == Immutable); 91 assert(Immutable.add(ConstShared) == Immutable); 92 93 // assert(Inout.add(Shared) == ConstShared); 94 assert(Inout.add(ConstShared) == ConstShared); 95 96 assert(Shared.add(ConstShared) == ConstShared); 97 } 98 } 99 100 bool canConvert(TypeQualifier from, TypeQualifier to) { 101 if (from == to) { 102 return true; 103 } 104 105 final switch (to) with (TypeQualifier) { 106 case Mutable, Inout, Shared, Immutable: 107 // Some qualifier are not safely castable to. 108 return false; 109 110 case Const: 111 return from == Mutable || from == Immutable || from == Inout; 112 113 case ConstShared: 114 return from == Shared || from == Immutable; 115 } 116 } 117 118 enum ParamKind { 119 /// Regular parameter. A slot on the stack will be allocated and value 120 /// copied in it when calling the function. 121 Regular, 122 /// Final parameter. No slot on the stack is created for it, and the 123 /// parameter cannot be written to, even when mutable. 124 Final, 125 /// Ref parameter. The address of the argument is passed instead of the 126 /// argument itself and is used as if it was a regular slot on the stack. 127 Ref, 128 }