Differences From Artifact [d1500d1519df592c]:
- File
tricks/tricks.d
- 2010-11-13 05:38:21 - part of checkin [078444a806] on branch trunk - additional primitives for doing typechecking (user: kinaba) [annotate]
To Artifact [0eae6cc37f045c97]:
- File
tricks/tricks.d
- 2010-11-20 09:20:03 - part of checkin [515502e8d1] on branch trunk - table get, init, ask expressions addded (user: kinaba) [annotate]
2 2 * Authors: k.inaba
3 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/
4 4 *
5 5 * Common tricks and utilities for programming in D.
6 6 */
7 7 module tricks.tricks;
8 8 import tricks.test;
9 -import std.array : appender;
10 -import std.format : formattedWrite;
11 9 import core.exception;
10 +import std.array : appender;
11 +import std.format : formattedWrite;
12 12 import std.traits;
13 13 import std.typetuple;
14 14
15 15 /// Simple Wrapper for std.format.doFormat
16 16
17 17 string sprintf(string fmt, T...)(T params)
18 18 {
................................................................................
106 106 template SimpleCompare()
107 107 {
108 108 override bool opEquals(Object rhs_) const /// member-by-member equality
109 109 {
110 110 if( auto rhs = cast(typeof(this))rhs_ )
111 111 {
112 112 foreach(i,_; this.tupleof)
113 - if( this.tupleof[i] != rhs.tupleof[i] )
113 + if( this.tupleof[i] != (cast(const)rhs).tupleof[i] )
114 114 return false;
115 115 return true;
116 116 }
117 117 assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), typeid(rhs_)));
118 118 }
119 119
120 120 override hash_t toHash() const /// member-by-member hash
................................................................................
126 126 }
127 127
128 128 override int opCmp(Object rhs_) const /// member-by-member compare
129 129 {
130 130 if( auto rhs = cast(typeof(this))rhs_ )
131 131 {
132 132 foreach(i,_; this.tupleof)
133 - if( this.tupleof[i] != rhs.tupleof[i] ) {
134 - auto a = this.tupleof[i];
133 + if( this.tupleof[i] != (cast(const)rhs).tupleof[i] ) {
134 + auto a = (cast(SC_Unqual!(typeof(this)))this).tupleof[i];
135 135 auto b = rhs.tupleof[i];
136 - return cast(SC_Unqual!(typeof(a)))a < b ? -1 : +1;
136 + return a < b ? -1 : +1;
137 137 }
138 +// not work well for structures???????
138 139 // if(auto c = typeid(_).compare(&this.tupleof[i],&rhs.tupleof[i]))
139 140 // return c;
140 141 return 0;
141 142 }
142 143 assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), typeid(rhs_)));
143 144 }
144 145 }
................................................................................
319 320 mixin SimpleConstructor;
320 321 }
321 322 class D2 : Base {
322 323 string s;
323 324 mixin SimpleConstructor;
324 325 }
325 326 class D3 : Base {
326 - int[int]m;
327 + int[int] m;
327 328 mixin SimpleConstructor;
328 329 }
329 330
330 331 Base d1 = new D1(1, 2.3);
331 332 Base d2 = new D2("foobar");
332 333 Base d3 = new D3(null); (cast(D3)d3).m[1]=10;
333 334
334 335 // normal dispatch
335 336 assert_eq( d1.match(
336 337 (D1 x){return 1;},
337 - (D2 x){return 2;},
338 + (D2 x){return 2;}
338 339 ), 1);
339 340 assert_eq( d2.match(
340 341 (D1 x){return 1;},
341 - (D2 x){return 2;},
342 + (D2 x){return 2;}
342 343 ), 2);
343 344 assert_throw!AssertError( d3.match(
344 345 (D1 x){return 1;},
345 - (D2 x){return 2;},
346 + (D2 x){return 2;}
346 347 ));
347 348 assert_eq( d3.match(
348 349 (D1 x){return 1;},
349 350 (D2 x){return 2;},
350 - (Base x){return 3;},
351 + (Base x){return 3;}
351 352 ), 3);
352 353 assert_eq( d2.match(
353 354 (D1 x){return 1;},
354 355 (D2 x){return 2;},
355 - (Base x){return 3;},
356 + (Base x){return 3;}
356 357 ), 2);
357 358 assert_eq( d2.match(
358 359 (D1 x){return 1;},
359 360 (Base x){return 3;},
360 - (D2 x){return 2;},
361 + (D2 x){return 2;}
361 362 ), 3);
362 363
363 364 // member decomposing match
364 365 assert_eq( d1.match(
365 366 when!(D1, (x, y){return x + cast(int)y;}),
366 367 when!(D2, (x){return x.length;}),
367 - when!(D3, (x){return x[1];}),
368 + when!(D3, (x){return x[1];})
368 369 ), 3);
369 370 assert_eq( d2.match(
370 371 when!(D1, (x, y){return x + cast(int)y;}),
371 372 when!(D2, (x){return x.length;}),
372 - when!(D3, (x){return x[1];}),
373 + when!(D3, (x){return x[1];})
373 374 ), 6);
374 375 assert_eq( d3.match(
375 376 when!(D1, (x, y){return x + cast(int)y;}),
376 377 when!(D2, (x){return x.length;}),
377 - when!(D3, (x){return x[1];}),
378 + when!(D3, (x){return x[1];})
378 379 ), 10);
379 380 assert_throw!AssertError( d3.match(
380 381 when!(D1, (x, y){return x + cast(int)y;}),
381 - when!(D2, (x){return x.length;}),
382 + when!(D2, (x){return x.length;})
382 383 ));
383 384 assert_eq( d2.match(
384 385 when!(D1, (x, y){return x + cast(int)y;}),
385 386 when!(D2, (x){return x.length;}),
386 - otherwise!({return 999;}),
387 + otherwise!({return 999;})
387 388 ), 6);
388 389 assert_eq( d2.match(
389 390 when!(D1, (x, y){return x + cast(int)y;}),
390 391 otherwise!({return 999;}),
391 - when!(D2, (x){return x.length;}),
392 + when!(D2, (x){return x.length;})
392 393 ), 999);
393 394 }