public import std.algorithm;
public import std.array;
public import std.conv;
public import std.range;
public import std.stdio;
public import std.string;
public import std.typecons;
public import std.math;
import std.c.stdlib;

// To avoide the following ICE:
//   src\phobos\std\algorithm.d(4552):
//     Error: function std.algorithm.count!("a == b",string,char).count
//     compiler error, parameter 'value', bugzilla 2962?
//     Assertion failure: '0' on line 717 in file 'glue.c'
int count(T,V)(T[] a, V v)
{
	int cnt = 0;
	foreach(e; a)
		if(e == v)
			++cnt;
	return cnt;
}

void application_exit() nothrow
{
	std.c.stdlib.exit(0);
}

template DeriveCreate()
{
	this(TS...)(TS params)
	{
		this.tupleof = params;
	}
}

template DeriveCompare()
{
override:
	bool opEquals(Object rhs) const
	{
		return tuple(this.tupleof) == tuple((cast(typeof(this))rhs).tupleof);
	}

	int opCmp(Object rhs) const
	{
		return tuple(this.tupleof).opCmp(tuple((cast(typeof(this))rhs).tupleof));
	}

	hash_t toHash() const
	{
		hash_t v = 0;
		foreach(mem; this.tupleof) {
			v *= 11;
			static if(__traits(compiles, v^=mem))
				v ^= mem;
			else
				v ^= typeid(mem).getHash(&mem);
		}
		return v;
	}
}

template DeriveShow()
{
override:
	string toString() const
	{
		string str = text(typeof(this).stringof, "(");
		foreach(i,mem; this.tupleof) {
			if(i) str ~= ", ";
			str = text(str, this.tupleof[i].stringof[5..$], ":",  mem);
		}
		return str ~ ")";
	}
}
