1 /* ----------------------------------------------------------------------------- 2 * doperators.swg 3 * 4 * Mapping of C++ operator overloading methods to D. 5 * ----------------------------------------------------------------------------- */ 6 7 #if (SWIG_D_VERSION == 1) 8 9 %pragma(d) imdmodulecode=%{ 10 template SwigOperatorDefinitions() { 11 public override int opEquals(Object o) { 12 if (auto rhs = cast(typeof(this))o) { 13 if (swigCPtr == rhs.swigCPtr) return 1; 14 static if (is(typeof(swigOpEquals(rhs)))) { 15 return swigOpEquals(rhs) ? 1 : 0; 16 } else { 17 return 0; 18 } 19 } 20 return super.opEquals(o); 21 } 22 %} 23 // opEquals is emitted in pure C mode as well to define two proxy classes 24 // pointing to the same struct as equal. 25 26 #ifdef __cplusplus 27 %rename(opPos) *::operator+(); 28 %rename(opPos) *::operator+() const; 29 %rename(opNeg) *::operator-(); 30 %rename(opNeg) *::operator-() const; 31 %rename(opCom) *::operator~(); 32 %rename(opCom) *::operator~() const; 33 34 %rename(opAdd) *::operator+; 35 %rename(opAddAssign) *::operator+=; 36 %rename(opSub) *::operator-; 37 %rename(opSubAssign) *::operator-=; 38 %rename(opMul) *::operator*; 39 %rename(opMulAssign) *::operator*=; 40 %rename(opDiv) *::operator/; 41 %rename(opDivAssign) *::operator/=; 42 %rename(opMod) *::operator%; 43 %rename(opModAssign) *::operator%=; 44 %rename(opAnd) *::operator&; 45 %rename(opAndAssign) *::operator&=; 46 %rename(opOr) *::operator|; 47 %rename(opOrAssign) *::operator|=; 48 %rename(opXor) *::operator^; 49 %rename(opXorAssign) *::operator^=; 50 %rename(opShl) *::operator<<; 51 %rename(opShlAssign) *::operator<<=; 52 %rename(opShr) *::operator>>; 53 %rename(opShrAssign) *::operator>>=; 54 55 %rename(opIndex) *::operator[](unsigned) const; 56 // opIndexAssign is not currently generated, it needs more extensive support 57 // mechanisms. 58 59 %rename(opCall) *::operator(); 60 61 // !a is not overrideable in D1. 62 %ignoreoperator(LNOT) operator!; 63 64 // opCmp is used in D. 65 %rename(swigOpEquals) *::operator==; 66 %rename(swigOpLt) *::operator<; 67 %rename(swigOpLtEquals) *::operator<=; 68 %rename(swigOpGt) *::operator>; 69 %rename(swigOpGtEquals) *::operator>=; 70 71 // a != b is rewritten as !a.opEquals(b) in D. 72 %ignoreoperator(NOTEQUAL) operator!=; 73 74 // The logic operators are not overrideable in D. 75 %ignoreoperator(LAND) operator&&; 76 %ignoreoperator(LOR) operator||; 77 78 // ++/--a is rewritten as a +/-= 1 in D1,so ignore the prefix operators. 79 %ignoreoperator(PLUSPLUS) *::operator++(); 80 %ignoreoperator(MINUSMINUS) *::operator--(); 81 %rename(swigOpInc) *::operator++(int); 82 %rename(swigOpDec) *::operator--(int); 83 84 // The C++ assignment operator does not translate well to D where the proxy 85 // classes have reference semantics. 86 %ignoreoperator(EQ) operator=; 87 88 %pragma(d) imdmodulecode=%{ 89 public override int opCmp(Object o) { 90 static if (is(typeof(swigOpLt(typeof(this).init) && 91 swigOpEquals(typeof(this).init)))) { 92 if (auto rhs = cast(typeof(this))o) { 93 if (swigOpLt(rhs)) { 94 return -1; 95 } else if (swigOpEquals(rhs)) { 96 return 0; 97 } else { 98 return 1; 99 } 100 } 101 } 102 return super.opCmp(o); 103 } 104 105 public typeof(this) opPostInc(T = int)(T unused = 0) { 106 static assert( 107 is(typeof(swigOpInc(int.init))), 108 "opPostInc called on " ~ typeof(this).stringof ~ ", but no postfix " ~ 109 "increment operator exists in the corresponding C++ class." 110 ); 111 return swigOpInc(int.init); 112 } 113 114 public typeof(this) opPostDec(T = int)(T unused = 0) { 115 static assert( 116 is(typeof(swigOpDec(int.init))), 117 "opPostInc called on " ~ typeof(this).stringof ~ ", but no postfix " ~ 118 "decrement operator exists in the corresponding C++ class." 119 ); 120 return swigOpDec(int.init); 121 } 122 %} 123 #endif 124 125 %pragma(d) imdmodulecode=%{ 126 } 127 %} 128 129 #else 130 %pragma(d) imdmodulecode=%{ 131 mixin template SwigOperatorDefinitions() { 132 public override bool opEquals(Object o) { 133 if (auto rhs = cast(typeof(this))o) { 134 if (swigCPtr == rhs.swigCPtr) return true; 135 static if (is(typeof(swigOpEquals(rhs)))) { 136 return swigOpEquals(rhs); 137 } else { 138 return false; 139 } 140 } 141 return super.opEquals(o); 142 } 143 %} 144 // opEquals is emitted in pure C mode as well to define two proxy classes 145 // pointing to the same struct as equal. 146 147 #ifdef __cplusplus 148 %rename(swigOpPos) *::operator+(); 149 %rename(swigOpPos) *::operator+() const; 150 %rename(swigOpNeg) *::operator-(); 151 %rename(swigOpNeg) *::operator-() const; 152 %rename(swigOpCom) *::operator~(); 153 %rename(swigOpCom) *::operator~() const; 154 %rename(swigOpInc) *::operator++(); 155 %rename(swigOpDec) *::operator--(); 156 %ignoreoperator(PLUSPLUS) *::operator++(int); 157 %ignoreoperator(MINUSMINUS) *::operator--(int); 158 // The postfix increment/decrement operators are ignored because they are 159 // rewritten to (auto t = e, ++e, t) in D2. The unary * operator (used for 160 // pointer dereferencing in C/C++) isn't mapped to opUnary("*") by default, 161 // despite this would be possible in D2 the difference in member access 162 // semantics would only lead to confusion in most cases. 163 164 %rename(swigOpAdd) *::operator+; 165 %rename(swigOpSub) *::operator-; 166 %rename(swigOpMul) *::operator*; 167 %rename(swigOpDiv) *::operator/; 168 %rename(swigOpMod) *::operator%; 169 %rename(swigOpAnd) *::operator&; 170 %rename(swigOpOr) *::operator|; 171 %rename(swigOpXor) *::operator^; 172 %rename(swigOpShl) *::operator<<; 173 %rename(swigOpShr) *::operator>>; 174 175 %rename(swigOpAddAssign) *::operator+=; 176 %rename(swigOpSubAssign) *::operator-=; 177 %rename(swigOpMulAssign) *::operator*=; 178 %rename(swigOpDivAssign) *::operator/=; 179 %rename(swigOpModAssign) *::operator%=; 180 %rename(swigOpAndAssign) *::operator&=; 181 %rename(swigOpOrAssign) *::operator|=; 182 %rename(swigOpXorAssign) *::operator^=; 183 %rename(swigOpShlAssign) *::operator<<=; 184 %rename(swigOpShrAssign) *::operator>>=; 185 186 %rename(opIndex) *::operator[]; 187 // opIndexAssign is not currently generated, it needs more extensive support 188 // mechanisms. 189 190 %rename(opCall) *::operator(); 191 192 %rename(swigOpEquals) *::operator==; 193 %rename(swigOpLt) *::operator<; 194 %rename(swigOpLtEquals) *::operator<=; 195 %rename(swigOpGt) *::operator>; 196 %rename(swigOpGtEquals) *::operator>=; 197 198 // a != b is rewritten as !a.opEquals(b) in D. 199 %ignoreoperator(NOTEQUAL) operator!=; 200 201 // The logic operators are not overrideable in D. 202 %ignoreoperator(LAND) operator&&; 203 %ignoreoperator(LOR) operator||; 204 205 // The C++ assignment operator does not translate well to D where the proxy 206 // classes have reference semantics. 207 %ignoreoperator(EQ) operator=; 208 209 %pragma(d) imdmodulecode=%{ 210 public override int opCmp(Object o) { 211 static if (__traits(compiles, swigOpLt(typeof(this).init) && 212 swigOpEquals(typeof(this).init))) { 213 if (auto rhs = cast(typeof(this))o) { 214 if (swigOpLt(rhs)) { 215 return -1; 216 } else if (swigOpEquals(rhs)) { 217 return 0; 218 } else { 219 return 1; 220 } 221 } 222 } 223 return super.opCmp(o); 224 } 225 226 private template swigOpBinary(string operator, string name) { 227 enum swigOpBinary = `public void opOpAssign(string op, T)(T rhs) if (op == "` ~ operator ~ 228 `" && __traits(compiles, swigOp` ~ name ~ `Assign(rhs))) { swigOp` ~ name ~ `Assign(rhs);}` ~ 229 `public auto opBinary(string op, T)(T rhs) if (op == "` ~ operator ~ 230 `" && __traits(compiles, swigOp` ~ name ~ `(rhs))) { return swigOp` ~ name ~ `(rhs);}`; 231 } 232 mixin(swigOpBinary!("+", "Add")); 233 mixin(swigOpBinary!("-", "Sub")); 234 mixin(swigOpBinary!("*", "Mul")); 235 mixin(swigOpBinary!("/", "Div")); 236 mixin(swigOpBinary!("%", "Mod")); 237 mixin(swigOpBinary!("&", "And")); 238 mixin(swigOpBinary!("|", "Or")); 239 mixin(swigOpBinary!("^", "Xor")); 240 mixin(swigOpBinary!("<<", "Shl")); 241 mixin(swigOpBinary!(">>", "Shr")); 242 243 private template swigOpUnary(string operator, string name) { 244 enum swigOpUnary = `public auto opUnary(string op)() if (op == "` ~ operator ~ 245 `" && __traits(compiles, swigOp` ~ name ~ `())) { return swigOp` ~ name ~ `();}`; 246 } 247 mixin(swigOpUnary!("+", "Pos")); 248 mixin(swigOpUnary!("-", "Neg")); 249 mixin(swigOpUnary!("~", "Com")); 250 mixin(swigOpUnary!("++", "Inc")); 251 mixin(swigOpUnary!("--", "Dec")); 252 %} 253 #endif 254 255 %pragma(d) imdmodulecode=%{ 256 } 257 %} 258 259 #endif 260