Artifact 16f826d18ff480bea5777db8a0becad57d199c87
- File
polemy/tricks.d
-
2010-11-07 14:34:29
- part of checkin
[0569f7b8c2]
on branch trunk
- - Added function literal evaluator (i.e., closure).
- Workaround for d2stacktrace's infinite-loop bug.
(when std.demangle.demangle use exception inside it,
it will go into an infinite loop. to avoid this,
I choose to unset TraceHandler during stacktrace generation.
This is far from the complete solution, but at least it should
work as expected under single-thread environment...)
(user:
kinaba)
[annotate]
1 /**
2 * Authors: k.inaba
3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/
4 *
5 * Common tricks and utilities for programming in D.
6 */
7 module polemy.tricks;
8 static import std.array;
9 static import std.format;
10
11 /// Simple Wrapper for std.format.doFormat
12
13 string sprintf(string fmt, T...)(T params)
14 {
15 auto writer = std.array.appender!string();
16 std.format.formattedWrite(writer, fmt, params);
17 return writer.data;
18 }
19
20 unittest
21 {
22 assert( sprintf!"%s == %d"("1+2", 3) == "1+2 == 3" );
23 assert( sprintf!"%s == %04d"("1+2", 3) == "1+2 == 0003" );
24 }
25
26 /// Mixing-in the bean constructor for a class
27
28 /*mixin*/ template SimpleConstructor()
29 {
30 static if( is(typeof(super) == Object) || super.tupleof.length==0 )
31 this( typeof(this.tupleof) params )
32 {
33 static if(this.tupleof.length>0)
34 this.tupleof = params;
35 }
36 else
37 // this parameter list is not always desirable but should work for many cases
38 this( typeof(super.tupleof) ps, typeof(this.tupleof) params )
39 {
40 super(ps);
41 static if(this.tupleof.length>0)
42 this.tupleof = params;
43 }
44 }
45
46 /// Mixing-in the (MOST-DERIVED) member-wise comparator for a class
47
48 /*mixin*/ template SimpleCompare()
49 {
50 override bool opEquals(Object rhs_) const
51 {
52 if( auto rhs = cast(typeof(this))rhs_ )
53 {
54 foreach(i,_; this.tupleof)
55 if( this.tupleof[i] != rhs.tupleof[i] )
56 return false;
57 return true;
58 }
59 assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), typeid(rhs_)));
60 }
61
62 override hash_t toHash() const
63 {
64 hash_t h = 0;
65 foreach(mem; this.tupleof)
66 h += typeid(mem).getHash(&mem);
67 return h;
68 }
69
70 override int opCmp(Object rhs_) const
71 {
72 if( auto rhs = cast(typeof(this))rhs_ )
73 {
74 foreach(i,_; this.tupleof)
75 if(auto c = typeid(_).compare(&this.tupleof[i],&rhs.tupleof[i]))
76 return c;
77 return 0;
78 }
79 assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), typeid(rhs_)));
80 }
81 }
82
83 unittest
84 {
85 class Temp
86 {
87 int x;
88 string y;
89 mixin SimpleConstructor;
90 mixin SimpleCompare;
91 }
92 assert( (new Temp(1,"foo")).x == 1 );
93 assert( (new Temp(1,"foo")).y == "foo" );
94 assert( !__traits(compiles, new Temp) );
95 assert( !__traits(compiles, new Temp(1)) );
96 assert( !__traits(compiles, new Temp("foo",1)) );
97 assert( new Temp(1,"foo") == new Temp(1,"foo") );
98 assert( (new Temp(1,"foo")).toHash == (new Temp(1,"foo")).toHash );
99 assert( new Temp(1,"foo") != new Temp(2,"foo") );
100 assert( new Temp(1,"foo") != new Temp(1,"bar") );
101 assert( new Temp(1,"foo") > new Temp(1,"bar") );
102 assert( new Temp(1,"foo") < new Temp(2,"bar") );
103 }