Diff
Not logged in

Differences From Artifact [004818c087feff6a]:

To Artifact [cc1b586b87325960]:


98 98 assert( !__traits(compiles, { 99 99 class Tamp : Tomp { mixin SimpleConstructor; } 100 100 }) ); 101 101 } 102 102 103 103 /// Mixing-in the MOST-DERIVED-member-wise comparator for a class 104 104 105 +template SimpleToHash() 106 +{ 107 + override hash_t toHash() const /// member-by-member hash 108 + { 109 + hash_t h = 0; 110 + foreach(mem; this.tupleof) 111 + h += typeid(mem).getHash(&mem); 112 + return h; 113 + } 114 +} 115 + 116 +/// Mixing-in the MOST-DERIVED-member-wise comparator for a class 117 + 105 118 /*mixin*/ 106 119 template SimpleCompare() 107 120 { 108 121 override bool opEquals(Object rhs_) const /// member-by-member equality 109 122 { 110 123 if( auto rhs = cast(typeof(this))rhs_ ) 111 124 { ................................................................................ 113 126 if( this.tupleof[i] != (cast(const)rhs).tupleof[i] ) 114 127 return false; 115 128 return true; 116 129 } 117 130 assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), typeid(rhs_))); 118 131 } 119 132 120 - override hash_t toHash() const /// member-by-member hash 121 - { 122 - hash_t h = 0; 123 - foreach(mem; this.tupleof) 124 - h += typeid(mem).getHash(&mem); 125 - return h; 126 - } 133 + mixin SimpleToHash; 127 134 128 135 override int opCmp(Object rhs_) const /// member-by-member compare 129 136 { 130 137 if( auto rhs = cast(typeof(this))rhs_ ) 131 138 { 132 139 foreach(i,_; this.tupleof) 133 140 if( this.tupleof[i] != (cast(const)rhs).tupleof[i] ) { ................................................................................ 215 222 template SimpleClass() 216 223 { 217 224 mixin SimpleConstructor; 218 225 mixin SimpleCompare; 219 226 mixin SimpleToString; 220 227 } 221 228 222 -/// Simple PatternMatcher 223 - 224 -/*mixin*/ 225 -template SimplePatternMatch() 226 -{ 227 - SPM_Return!(PP) match(string fn=__FILE__, size_t ln=__LINE__, PP...)(PP pts) 228 - { 229 - foreach(i,_; pts) 230 - { 231 - alias pts[i] pt; // bug? pts[i]-->pt do not work 232 - static if(__traits(compiles, SPM_isMatchTag(pt))) 233 - { 234 - if( auto v = cast(pt.dynamicType)this ) 235 - return pt(v.tupleof); 236 - } 237 - else 238 - static if(__traits(compiles, SPM_isMatchAny(pt))) 239 - { 240 - return pt(); 241 - } 242 - else 243 - { 244 - if( auto v = cast(SPM_PTT!(pt)[0])this ) 245 - return pt(v); 246 - } 247 - } 248 - SPM_throwAssertError(fn, ln, "pattern matching failure"); 249 - assert(false); 250 - } 251 -} 252 - 253 -/// Pattern case clause 254 - 255 -SPM_MatchTag!(T, fn) when(T, alias fn)() 256 -{ 257 - SPM_MatchTag!(T, fn) m; 258 - return m; 259 -} 260 - 261 -/// Pattern case clause 262 - 263 -SPM_MatchAny!(fn) otherwise(alias fn)() 264 -{ 265 - SPM_MatchAny!(fn) m; 266 - return m; 267 -} 268 - 269 -// implementation detail of SimplePatternMatch 270 - 271 -void SPM_throwAssertError(T...)(T t) { core.exception.onAssertErrorMsg(t); } 272 - 273 -struct SPM_MatchTag(T, alias fn) 274 -{ 275 - alias T dynamicType; 276 - auto opCall(typeof(T.tupleof) s) { return fn(s); } 277 -} 278 - 279 -struct SPM_MatchAny(alias fn) 280 -{ 281 - auto opCall() { return fn(); } 282 -} 283 - 284 -template SPM_PTT(alias p) 285 -{ 286 - alias ParameterTypeTuple!(p) SPM_PTT; 287 -} 288 - 289 -template SPM_Each(P) 290 -{ 291 - static if(__traits(compiles, SPM_isMatchTag(P.init))) 292 - alias typeof(P(P.dynamicType.tupleof)) SPM_Each; 293 - else 294 - static if(__traits(compiles, SPM_isMatchAny(P.init))) 295 - alias typeof(P()) SPM_Each; 296 - else 297 - alias ReturnType!(P) SPM_Each; 298 -} 299 - 300 -template SPM_aVoid(T:void, TS...) { alias SPM_aVoid!(TS) SPM_aVoid; } 301 -template SPM_aVoid(T, TS...) { alias TypeTuple!(T,SPM_aVoid!(TS)) SPM_aVoid; } 302 -template SPM_aVoid() { alias TypeTuple!() SPM_aVoid; } 303 - 304 -template SPM_Return(PP...) 305 -{ 306 - alias CommonType!(SPM_aVoid!(staticMap!(SPM_Each, PP))) SPM_Return; 307 -} 308 - 309 -void SPM_isMatchTag(T,alias fn)(SPM_MatchTag!(T,fn)){} 310 -void SPM_isMatchAny(alias fn)(SPM_MatchAny!(fn)){} 311 - 312 -unittest 313 -{ 314 - static abstract class Base { 315 - mixin SimplePatternMatch; 316 - } 317 - class D1 : Base { 318 - int x; 319 - real y; 320 - mixin SimpleConstructor; 321 - } 322 - class D2 : Base { 323 - string s; 324 - mixin SimpleConstructor; 325 - } 326 - class D3 : Base { 327 - int[int] m; 328 - mixin SimpleConstructor; 329 - } 330 - 331 - Base d1 = new D1(1, 2.3); 332 - Base d2 = new D2("foobar"); 333 - Base d3 = new D3(null); (cast(D3)d3).m[1]=10; 334 - 335 - // normal dispatch 336 - assert_eq( d1.match( 337 - (D1 x){return 1;}, 338 - (D2 x){return 2;} 339 - ), 1); 340 - assert_eq( d2.match( 341 - (D1 x){return 1;}, 342 - (D2 x){return 2;} 343 - ), 2); 344 - assert_throw!AssertError( d3.match( 345 - (D1 x){return 1;}, 346 - (D2 x){return 2;} 347 - )); 348 - assert_eq( d3.match( 349 - (D1 x){return 1;}, 350 - (D2 x){return 2;}, 351 - (Base x){return 3;} 352 - ), 3); 353 - assert_eq( d2.match( 354 - (D1 x){return 1;}, 355 - (D2 x){return 2;}, 356 - (Base x){return 3;} 357 - ), 2); 358 - assert_eq( d2.match( 359 - (D1 x){return 1;}, 360 - (Base x){return 3;}, 361 - (D2 x){return 2;} 362 - ), 3); 363 - 364 - // member decomposing match 365 - assert_eq( d1.match( 366 - when!(D1, (x, y){return x + cast(int)y;}), 367 - when!(D2, (x){return x.length;}), 368 - when!(D3, (x){return x[1];}) 369 - ), 3); 370 - assert_eq( d2.match( 371 - when!(D1, (x, y){return x + cast(int)y;}), 372 - when!(D2, (x){return x.length;}), 373 - when!(D3, (x){return x[1];}) 374 - ), 6); 375 - assert_eq( d3.match( 376 - when!(D1, (x, y){return x + cast(int)y;}), 377 - when!(D2, (x){return x.length;}), 378 - when!(D3, (x){return x[1];}) 379 - ), 10); 380 - assert_throw!AssertError( d3.match( 381 - when!(D1, (x, y){return x + cast(int)y;}), 382 - when!(D2, (x){return x.length;}) 383 - )); 384 - assert_eq( d2.match( 385 - when!(D1, (x, y){return x + cast(int)y;}), 386 - when!(D2, (x){return x.length;}), 387 - otherwise!({return 999;}) 388 - ), 6); 389 - assert_eq( d2.match( 390 - when!(D1, (x, y){return x + cast(int)y;}), 391 - otherwise!({return 999;}), 392 - when!(D2, (x){return x.length;}) 393 - ), 999); 394 -} 395 - 396 229 /// Will be used for dynamic overload resolution pattern 397 230 398 231 template firstParam(T) 399 232 { 400 233 alias ParameterTypeTuple!(T)[0] firstParam; 401 234 }