threadLocal

threadLocal!Engine returns a reference to a thread-local instance of the specified random number generator allocated and seeded uniquely for each thread. Requires TLS.

threadLocalPtr!Engine is a pointer to the area of thread-local storage used by threadLocal!Engine. This function is provided because the compiler can infer it is @safe, unlike &(threadLocal!Engine). Like threadLocal!Engine this function will auto-initialize the engine. Do not share pointers returned by threadLocalPtr between threads!

threadLocalInitialized!Engine is a low-level way to explicitly change the "initialized" flag used by threadLocal!Engine to determine whether the Engine needs to be seeded. Setting this to false gives a way of forcing the next call to threadLocal!Engine to reseed. In general this is unnecessary but there are some specialized use cases where users have requested this ability.

  1. Engine threadLocal [@property getter]
    @property ref
    static if(THREAD_LOCAL_STORAGE_AVAILABLE)
    Engine
    threadLocal
    (
    Engine
    )
    ()
    if (
    is(Engine == struct)
    )
  2. template threadLocal(T)
  3. Engine* threadLocalPtr [@property getter]
  4. bool threadLocalInitialized [@property getter]

Examples

import mir.random;
import mir.random.engine.xorshift;

alias gen = threadLocal!Xorshift1024StarPhi;
double x = gen.rand!double;
size_t i = gen.randIndex(100u);
ulong a = gen.rand!ulong;
import mir.random;
//If you need a pointer to the engine, getting it like this is @safe:
Random* ptr = threadLocalPtr!Random;
import mir.random;
import mir.random.engine.xorshift;
//If you need to mark the engine as uninitialized to force a reseed,
//you can do it like this:
threadLocalInitialized!Xorshift1024StarPhi = false;
import mir.random;
import mir.random.engine.mersenne_twister;
//You can mark the engine as already initialized to skip
//automatic seeding then initialize it yourself, for instance
//if you want to use a known seed rather than a random one.
threadLocalInitialized!Mt19937 = true;
immutable uint[4] customSeed = [0x123, 0x234, 0x345, 0x456];
threadLocal!Mt19937.__ctor(customSeed);
foreach(_; 0..999)
    threadLocal!Mt19937.rand!uint;
assert(3460025646u == threadLocal!Mt19937.rand!uint);
import mir.random;
import mir.random.engine.xorshift;

alias gen = threadLocal!Xorshift1024StarPhi;

//If you want to you can call the generator's opCall instead of using
//rand!T but it is somewhat clunky because of the ambiguity of
//@property syntax: () looks like optional function parentheses.
static assert(!__traits(compiles, {ulong x0 = gen();}));//<-- Won't work
static assert(is(typeof(gen()) == Xorshift1024StarPhi));//<-- because the type is this.
ulong x1 = gen.opCall();//<-- This works though.
ulong x2 = gen()();//<-- This also works.

//But instead of any of those you should really just use gen.rand!T.
ulong x3 = gen.rand!ulong;

Meta