digitalmars.D - random stuff you might find useful
- Downs (156/156) May 22 2007 Here's a collection of random stuff I made. Feel free to grab sniplets a...
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(); }
May 22 2007
Small improvement (is it actually? not sure ..) to the map function. This totally breaks the one-on-one mappingness and may also contain other subtle bugs, nevermind possibly be slower, so use it with care. Works for me. No warranty. :p ArrayOf!(U) map(T, U, V=Tuple!())(T[] array, U delegate(T, size_t) dg, bool delegate(V) valid=null) { static if (!is(U==void)) static assert(is(Tuple!(V)==Tuple!(U)), "Error: "~Tuple!(V).stringof~" is not "~Tuple!(U).stringof); static if (is(U==void)) { foreach (id, inout v; array) dg(v, id); } else { auto ret=new U[array.length]; size_t i=0; foreach (id, inout v; array) { auto res=dg(v, id); static if (Tuple!(V).length) { if (!valid||valid(res)) ret[i++]=res; } else ret[i++]=res; } return ret[0..i]; } } ArrayOf!(U) map(T, U, V=Tuple!(), Bogus=void)(T[] array, U delegate(T) dg, bool delegate(V) valid=null) { static if (is(U==void)) map!(T, U, V)(array, (T t, size_t bogus) { dg(t); }, valid); else return map!(T, U, V)(array, (T t, size_t bogus) { return dg(t); }, valid); }
May 22 2007
Downs wrote: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); }<snip> From std.thread docs: static Thread getThis(); Returns a reference to the Thread for the thread that called the function. Isn't this what you're doing?
May 22 2007
torhu wrote:Downs wrote:Basically yes, but in this case I needed an index for the current thread that is more easily readable than the reference address - note that getThread returns an integer.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); }<snip> From std.thread docs: static Thread getThis(); Returns a reference to the Thread for the thread that called the function. Isn't this what you're doing?
May 22 2007