4198578702 2010-11-07 kinaba: /** 4198578702 2010-11-07 kinaba: * Authors: k.inaba 4198578702 2010-11-07 kinaba: * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 4198578702 2010-11-07 kinaba: * 4198578702 2010-11-07 kinaba: * Common tricks and utilities for programming in D. 423f308350 2010-11-07 kinaba: */ 4198578702 2010-11-07 kinaba: module polemy.tricks; 423f308350 2010-11-07 kinaba: static import std.array; 423f308350 2010-11-07 kinaba: static import std.format; 423f308350 2010-11-07 kinaba: 423f308350 2010-11-07 kinaba: /// Simple Wrapper for std.format.doFormat 423f308350 2010-11-07 kinaba: 423f308350 2010-11-07 kinaba: string sprintf(string fmt, T...)(T params) 423f308350 2010-11-07 kinaba: { 423f308350 2010-11-07 kinaba: auto writer = std.array.appender!string(); 423f308350 2010-11-07 kinaba: std.format.formattedWrite(writer, fmt, params); 423f308350 2010-11-07 kinaba: return writer.data; 423f308350 2010-11-07 kinaba: } 423f308350 2010-11-07 kinaba: 423f308350 2010-11-07 kinaba: unittest 423f308350 2010-11-07 kinaba: { 423f308350 2010-11-07 kinaba: assert( sprintf!"%s == %d"("1+2", 3) == "1+2 == 3" ); 423f308350 2010-11-07 kinaba: assert( sprintf!"%s == %04d"("1+2", 3) == "1+2 == 0003" ); 423f308350 2010-11-07 kinaba: } 423f308350 2010-11-07 kinaba: 423f308350 2010-11-07 kinaba: /// Mixing-in the bean constructor for a class 423f308350 2010-11-07 kinaba: 423f308350 2010-11-07 kinaba: /*mixin*/ template SimpleConstructor() 423f308350 2010-11-07 kinaba: { 423f308350 2010-11-07 kinaba: static if( is(typeof(super) == Object) || super.tupleof.length==0 ) 423f308350 2010-11-07 kinaba: this( typeof(this.tupleof) params ) 423f308350 2010-11-07 kinaba: { 0569f7b8c2 2010-11-07 kinaba: static if(this.tupleof.length>0) 0569f7b8c2 2010-11-07 kinaba: this.tupleof = params; 423f308350 2010-11-07 kinaba: } 423f308350 2010-11-07 kinaba: else 423f308350 2010-11-07 kinaba: // this parameter list is not always desirable but should work for many cases 423f308350 2010-11-07 kinaba: this( typeof(super.tupleof) ps, typeof(this.tupleof) params ) 423f308350 2010-11-07 kinaba: { 423f308350 2010-11-07 kinaba: super(ps); 0569f7b8c2 2010-11-07 kinaba: static if(this.tupleof.length>0) 0569f7b8c2 2010-11-07 kinaba: this.tupleof = params; 423f308350 2010-11-07 kinaba: } 423f308350 2010-11-07 kinaba: } 423f308350 2010-11-07 kinaba: 820e7198cc 2010-11-07 kinaba: /// Mixing-in the MOST-DERIVED-member-wise comparator for a class 423f308350 2010-11-07 kinaba: 423f308350 2010-11-07 kinaba: /*mixin*/ template SimpleCompare() 423f308350 2010-11-07 kinaba: { 423f308350 2010-11-07 kinaba: override bool opEquals(Object rhs_) const 423f308350 2010-11-07 kinaba: { 423f308350 2010-11-07 kinaba: if( auto rhs = cast(typeof(this))rhs_ ) 423f308350 2010-11-07 kinaba: { 423f308350 2010-11-07 kinaba: foreach(i,_; this.tupleof) 423f308350 2010-11-07 kinaba: if( this.tupleof[i] != rhs.tupleof[i] ) 423f308350 2010-11-07 kinaba: return false; 423f308350 2010-11-07 kinaba: return true; 423f308350 2010-11-07 kinaba: } 423f308350 2010-11-07 kinaba: assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), typeid(rhs_))); 423f308350 2010-11-07 kinaba: } 423f308350 2010-11-07 kinaba: 423f308350 2010-11-07 kinaba: override hash_t toHash() const 423f308350 2010-11-07 kinaba: { 423f308350 2010-11-07 kinaba: hash_t h = 0; 423f308350 2010-11-07 kinaba: foreach(mem; this.tupleof) 423f308350 2010-11-07 kinaba: h += typeid(mem).getHash(&mem); 423f308350 2010-11-07 kinaba: return h; 423f308350 2010-11-07 kinaba: } 423f308350 2010-11-07 kinaba: 423f308350 2010-11-07 kinaba: override int opCmp(Object rhs_) const 423f308350 2010-11-07 kinaba: { 423f308350 2010-11-07 kinaba: if( auto rhs = cast(typeof(this))rhs_ ) 423f308350 2010-11-07 kinaba: { 423f308350 2010-11-07 kinaba: foreach(i,_; this.tupleof) 423f308350 2010-11-07 kinaba: if(auto c = typeid(_).compare(&this.tupleof[i],&rhs.tupleof[i])) 423f308350 2010-11-07 kinaba: return c; 423f308350 2010-11-07 kinaba: return 0; 423f308350 2010-11-07 kinaba: } 423f308350 2010-11-07 kinaba: assert(false, sprintf!"Cannot compare %s with %s"(typeid(this), typeid(rhs_))); 423f308350 2010-11-07 kinaba: } 423f308350 2010-11-07 kinaba: } 423f308350 2010-11-07 kinaba: 423f308350 2010-11-07 kinaba: unittest 423f308350 2010-11-07 kinaba: { 423f308350 2010-11-07 kinaba: class Temp 423f308350 2010-11-07 kinaba: { 423f308350 2010-11-07 kinaba: int x; 423f308350 2010-11-07 kinaba: string y; 423f308350 2010-11-07 kinaba: mixin SimpleConstructor; 423f308350 2010-11-07 kinaba: mixin SimpleCompare; 423f308350 2010-11-07 kinaba: } 423f308350 2010-11-07 kinaba: assert( (new Temp(1,"foo")).x == 1 ); 423f308350 2010-11-07 kinaba: assert( (new Temp(1,"foo")).y == "foo" ); 423f308350 2010-11-07 kinaba: assert( !__traits(compiles, new Temp) ); 423f308350 2010-11-07 kinaba: assert( !__traits(compiles, new Temp(1)) ); 423f308350 2010-11-07 kinaba: assert( !__traits(compiles, new Temp("foo",1)) ); 423f308350 2010-11-07 kinaba: assert( new Temp(1,"foo") == new Temp(1,"foo") ); 423f308350 2010-11-07 kinaba: assert( (new Temp(1,"foo")).toHash == (new Temp(1,"foo")).toHash ); 423f308350 2010-11-07 kinaba: assert( new Temp(1,"foo") != new Temp(2,"foo") ); 423f308350 2010-11-07 kinaba: assert( new Temp(1,"foo") != new Temp(1,"bar") ); 423f308350 2010-11-07 kinaba: assert( new Temp(1,"foo") > new Temp(1,"bar") ); 423f308350 2010-11-07 kinaba: assert( new Temp(1,"foo") < new Temp(2,"bar") ); 423f308350 2010-11-07 kinaba: }