random stuff you might find useful
Downs
default_357-line at yahoo.de
Tue May 22 01:56:57 PDT 2007
Here's a collection of random stuff I made. Feel free to grab sniplets as you see fit.
module tools.Tools;
import std.string, std.thread, std.file, std.bind, std.stdio: FILE;
import std.c.stdio;
/// get the currently active thread (duh)
int getThread() { foreach (idx, thr; Thread.getAll) if (thr.isSelf) return idx; assert(false); }
// This _needs_ to be outside the function because it's a template func
Object logln_synch=null;
void _printf(T...)(char[] format, T t) { printf(toStringz(format), t); } /// tuple and C wrapper.
void _logln(T...)(T t) {
foreach (index, part; t) {
static if (is(typeof(part) : char[])) _printf("%.*s", part);
else static if (is(typeof(part)==uint)) _printf("%u", part);
else static if (is(typeof(part)==int)) _printf("%i", part);
else static if (is(typeof(part)==char)) _printf("%c", part);
else static if (is(typeof(part): Object)) _logln(part.toString);
else static if (is(typeof(part)==bool)) _logln(part?"True":"False");
else static if (isArray!(typeof(part))) {
_logln("[");
if (part.length) {
foreach (elem; part[0..$-1]) { _logln(elem); _logln(", "); }
_logln(part[$-1]);
}
_logln("]");
}
else static assert(false, "Type "~typeof(part).stringof~" not supported. Maybe you can add support for it?");
}
}
void logln(T...)(T t) {
if (!logln_synch) logln_synch=new Object;
synchronized (logln_synch) _logln("[", getThread, "] ", t, "\n");
}
T[] toArray(T)(T *ptr) { int pos=0; while (ptr[pos]) pos++; return ptr[0..pos]; }
T *toPointer(T)(T[] array) { return (array~cast(T)0).ptr; }
// This is a straight C to D translation of the improved version of the Mersenne Twister algorithm,
// as available on http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c
// Period parameters
const N=624;
const M=397;
const MATRIX_A=0x9908b0df; /* constant vector a */
const UPPER_MASK=0x80000000; /* most significant w-r bits */
const LOWER_MASK=0x7fffffff; /* least significant r bits */
struct mersenne {
ulong mt[N]; /* the array for the state vector */
int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
void init_genrand(ulong s) // initializes mt[N] with a seed
{
mt[0]=s;
foreach (idx, inout elem; mt[1..$]) elem=(1812433253*(mt[idx]^(mt[idx]>>30))+idx);
mti=mt.length;
}
/* generates a random number on [0,0xffffffff]-interval */
ulong genrand_int32()
{
ulong y;
static ulong mag01[]=[0, MATRIX_A];
/* mag01[x] = x * MATRIX_A for x=0,1 */
if (mti >= mt.length) { /* generate N words at one time */
int kk;
if (mti == N+1) /* if init_genrand() has not been called, */
init_genrand(5489); /* a default initial seed is used */
for (kk=0; kk<N-M; kk++) {
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[cast(int)y & 0x1];
}
for (;kk<N-1;kk++) {
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[cast(int)y & 0x1];
}
y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[cast(int)y & 0x1];
mti = 0;
}
y = mt[mti++];
/* Tempering */
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680;
y ^= (y << 15) & 0xefc60000;
y ^= (y >> 18);
return y;
}
/* generates a random number on [0,1]-real-interval */
real genrand_real1() {
return genrand_int32()*(1.0/4294967295.0);
/* divided by 2^32-1 */
}
/* generates a random number on [0,1)-real-interval */
real genrand_real2() {
return genrand_int32()*(1.0/4294967296.0);
/* divided by 2^32 */
}
/* generates a random number on (0,1)-real-interval */
real genrand_real3()
{
return ((cast(double)genrand_int32()) + 0.5)*(1.0/4294967296.0);
/* divided by 2^32 */
}
/* These real versions are due to Isaku Wada, 2002/01/09 added */
}
class Random { mersenne m; this() { } void seed(uint v) { m.init_genrand(v); } uint next() { return cast(uint)m.genrand_int32; } }
bool has(T, U)(T[] array, U match) { static assert(is(U: T)); foreach (elem; array) if (elem==match) return true; return false; }
void remove(T)(inout T[] array, T key, bool all=true) {
int pos=-1; foreach (i, e; array) if (e==key) { pos=i; break; }
if (pos==-1) return;
if (pos!=array.length-1) array[pos]=array[$-1];
array=array[0..$-1];
if (all) remove(array, key); /// tail recursion, theoretically
}
template isArray(T) { const isArray=false; }
template isArray(T: T[]) { const isArray=true; }
void swap(T)(inout T a, inout T b) { T c=a; a=b; b=c; }
/// if_is(myObject, (ObjectSubclass os) { os.doStuff; }, { logln("Error: can't cast myObject to subclass!"); });
void if_is(T, P)(P obj, void delegate(T) dg, call alt=null) { if (cast(T)obj) dg(cast(T)obj); else if (alt) alt(); }
void must_be(T, P) (P obj, void delegate(T) dg) { if (cast(T)obj) dg(cast(T)obj); else assert(false); }
template ArrayOf(Array) {
static if (is(Array==void)) alias void ArrayOf;
else alias Array[] ArrayOf;
}
/// int[] asciivalues=map("Test", (char e) { return cast(int)e; }); // yay waste of space
ArrayOf!(U) map(T, U)(T[] array, U delegate(T, size_t) dg) {
static if (is(U==void)) {
foreach (id, inout v; array) dg(v, id);
} else {
auto ret=new U[array.length];
foreach (id, inout v; array) ret[id]=dg(v, id);
return ret;
}
}
ArrayOf!(U) map(T, U, Bogus=void)(T[] array, U delegate(T) dg) {
static if (is(U==void)) map(array, (T t, size_t bogus) { dg(t); });
else return map(array, (T t, size_t bogus) { return dg(t); });
}
alias void delegate() call;
void delegate(call) times(int e) { return bind((int foo, call dg) { for (int i=0; i<foo; ++i) dg(); }, e, _0).ptr; }
template tuple(T...) { alias T tuple; } // basics
template ptr(T...) { // the typetuple ptr!(T) consists of pointers to the types in T
static if (T.length>1) alias tuple!(T[0]*, ptr!(T[1..$])) ptr;
else alias T[0]* ptr;
}
struct multival(T...) { /// Simple holder for multiple values
tuple!(T) val=void;
static multival!(T) opCall(T t) { multival!(T) res=void; foreach (i, e; t) res.val[i]=e; return res; }
}
struct ptrlist(T...) { /// List of pointers to variables
tuple!(ptr!(T)) v=void;
static ptrlist!(T) opCall(inout T t) {
ptrlist!(T) res=void;
foreach (i, e; t) res.v[i]=&t[i]; // Ignore e because I can't make it inout anyway.
return res;
}
void opAssign(multival!(T) res) {
foreach (i, e; res.val) *v[i]=e;
}
}
ptrlist!(T) list(T...)(inout T v) { return ptrlist!(T)(v); }
/// use that like, "multival!(char[], char[]) test() { return multival!(char[], char[])("Hello", "World"); } void main() { char[] a, b; list(a, b)=test(); }
More information about the Digitalmars-d
mailing list