Artifact Content
Not logged in

Artifact 16f826d18ff480bea5777db8a0becad57d199c87


     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  }