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