Diff
Not logged in

Differences From Artifact [cc1b586b87325960]:

To Artifact [00969146488cc3dc]:


95 // shiyo- desu. Don't use in this way. 95 // shiyo- desu. Don't use in this way. 96 // Tamp tries to call new Tomp(real) (because it only sees Tomp's memb 96 // Tamp tries to call new Tomp(real) (because it only sees Tomp's memb 97 // but it fails because Tomp takes (int,string,real). 97 // but it fails because Tomp takes (int,string,real). 98 assert( !__traits(compiles, { 98 assert( !__traits(compiles, { 99 class Tamp : Tomp { mixin SimpleConstructor; } 99 class Tamp : Tomp { mixin SimpleConstructor; } 100 }) ); 100 }) ); 101 } 101 } > 102 > 103 hash_t structuralHash(T)(T x) > 104 { > 105 alias SC_Unqual!(T) UCT; > 106 > 107 static if(is(UCT == class)) > 108 return (cast(UCT)x).toHash(); > 109 else > 110 static if(SC_HasGoodHash!(UCT)) > 111 { return typeid(UCT).getHash(&x); } > 112 else > 113 static if(is(UCT T == T[])) > 114 { hash_t h; foreach(e; x) h+=structuralHash(e); return h; } > 115 else > 116 static if(is(UCT == struct)) > 117 static if(__traits(compiles, std.bigint.BigInt)) > 118 static if(is(UCT == std.bigint.BigInt)) > 119 return cast(hash_t) x.toInt(); > 120 else > 121 static assert(false, "should not use struct.toHa > 122 else > 123 static assert(false, "should not use struct.toHash"); > 124 else > 125 static assert(false, "nonhashable datatype "~UCT.stringof); > 126 } > 127 > 128 alias std.traits.Unqual SC_Unqual; > 129 > 130 template SC_HasGoodHash(T) > 131 { > 132 enum SC_HasGoodHash = > 133 is(T : bool) || isNumeric!(T) || isSomeString!(T) || isSomeChar! > 134 } 102 135 103 /// Mixing-in the MOST-DERIVED-member-wise comparator for a class 136 /// Mixing-in the MOST-DERIVED-member-wise comparator for a class > 137 /// BE SURE THAT THIS IS CONSISTENT WITH opCmp and opEquals 104 138 105 template SimpleToHash() 139 template SimpleToHash() 106 { 140 { 107 override hash_t toHash() const /// member-by-member hash 141 override hash_t toHash() const /// member-by-member hash 108 { 142 { 109 hash_t h = 0; 143 hash_t h = 0; 110 foreach(mem; this.tupleof) 144 foreach(mem; this.tupleof) 111 h += typeid(mem).getHash(&mem); | 145 h += structuralHash(mem); 112 return h; 146 return h; 113 } 147 } 114 } 148 } > 149 > 150 /// Mixing-in the MOST-DERIVED-member-wise comparator for a class > 151 > 152 template SimpleCompareWithoutToHash() > 153 { > 154 override bool opEquals(Object rhs) const /// member-by-member equality > 155 { > 156 return opCmp(rhs) == 0; > 157 } > 158 > 159 override int opCmp(Object rhs_) const /// member-by-member compare > 160 { > 161 if( rhs_ is null ) > 162 return -1; > 163 if( auto rhs = cast(typeof(this))rhs_ ) > 164 { > 165 foreach(i,_; this.tupleof) > 166 { > 167 static if(is(typeof(_) == struct)) > 168 auto c = (cast(SC_Unqual!(typeof(_)))thi > 169 else > 170 auto c = typeid(_).compare(&this.tupleof > 171 if(c) > 172 return c; > 173 } > 174 return 0; > 175 } > 176 return typeid(this).opCmp(typeid(rhs_)); > 177 } > 178 } 115 179 116 /// Mixing-in the MOST-DERIVED-member-wise comparator for a class 180 /// Mixing-in the MOST-DERIVED-member-wise comparator for a class 117 181 118 /*mixin*/ 182 /*mixin*/ 119 template SimpleCompare() 183 template SimpleCompare() 120 { 184 { 121 override bool opEquals(Object rhs_) const /// member-by-member equality < 122 { < 123 if( auto rhs = cast(typeof(this))rhs_ ) < 124 { < 125 foreach(i,_; this.tupleof) < 126 if( this.tupleof[i] != (cast(const)rhs).tupleof[ < 127 return false; < 128 return true; < 129 } < 130 assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), < 131 } < 132 < 133 mixin SimpleToHash; 185 mixin SimpleToHash; 134 < 135 override int opCmp(Object rhs_) const /// member-by-member compare < 136 { < 137 if( auto rhs = cast(typeof(this))rhs_ ) < 138 { < 139 foreach(i,_; this.tupleof) < 140 if( this.tupleof[i] != (cast(const)rhs).tupleof[ < 141 auto a = (cast(SC_Unqual!(typeof(this))) < 142 auto b = rhs.tupleof[i]; < 143 return a < b ? -1 : +1; < 144 } < 145 // not work well for structures??????? < 146 // if(auto c = typeid(_).compare(&this.tupleof[i],& < 147 // return c; < 148 return 0; < 149 } < 150 assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), < 151 } < > 186 mixin SimpleCompareWithoutToHash; 152 } 187 } 153 188 154 alias std.traits.Unqual SC_Unqual; < 155 < 156 unittest 189 unittest 157 { 190 { 158 class Temp 191 class Temp 159 { 192 { 160 int x; 193 int x; 161 string y; 194 string y; 162 mixin SimpleConstructor; 195 mixin SimpleConstructor; ................................................................................................................................................................................ 173 class TempDummy 206 class TempDummy 174 { 207 { 175 int x; 208 int x; 176 string y; 209 string y; 177 mixin SimpleConstructor; 210 mixin SimpleConstructor; 178 mixin SimpleCompare; 211 mixin SimpleCompare; 179 } 212 } 180 assert_throw!AssertError( new Temp(1,"foo") == new TempDummy(1,"foo") ); | 213 assert_ne( new Temp(1,"foo"), new TempDummy(1,"foo") ); 181 assert_throw!AssertError( new Temp(1,"foo") <= new TempDummy(1,"foo") ); | 214 assert_nothrow( new Temp(1,"foo") <= new TempDummy(1,"foo") ); 182 } 215 } 183 216 184 /// Mixing-in a simple toString method 217 /// Mixing-in a simple toString method 185 218 186 /*mixin*/ 219 /*mixin*/ 187 template SimpleToString() 220 template SimpleToString() 188 { 221 { ................................................................................................................................................................................ 222 template SimpleClass() 255 template SimpleClass() 223 { 256 { 224 mixin SimpleConstructor; 257 mixin SimpleConstructor; 225 mixin SimpleCompare; 258 mixin SimpleCompare; 226 mixin SimpleToString; 259 mixin SimpleToString; 227 } 260 } 228 261 229 /// Will be used for dynamic overload resolution pattern | 262 /// Utility 230 263 231 template firstParam(T) 264 template firstParam(T) 232 { 265 { 233 alias ParameterTypeTuple!(T)[0] firstParam; 266 alias ParameterTypeTuple!(T)[0] firstParam; 234 } 267 }