1 // Written in the D programming language.
2 
3 /**
4 Facilities for random number generation.
5 
6 $(SCRIPT inhibitQuickIndex = 1;)
7 $(DIVC quickindex,
8 $(BOOKTABLE,
9 $(TR $(TH Category) $(TH Functions))
10 $(TR $(TD Uniform sampling) $(TD
11     $(LREF uniform)
12     $(LREF uniform01)
13     $(LREF uniformDistribution)
14 ))
15 $(TR $(TD Element sampling) $(TD
16     $(LREF choice)
17     $(LREF dice)
18 ))
19 $(TR $(TD Range sampling) $(TD
20     $(LREF randomCover)
21     $(LREF randomSample)
22 ))
23 $(TR $(TD Default Random Engines) $(TD
24     $(LREF rndGen)
25     $(LREF Random)
26     $(LREF unpredictableSeed)
27 ))
28 $(TR $(TD Linear Congruential Engines) $(TD
29     $(LREF MinstdRand)
30     $(LREF MinstdRand0)
31     $(LREF LinearCongruentialEngine)
32 ))
33 $(TR $(TD Mersenne Twister Engines) $(TD
34     $(LREF Mt19937)
35     $(LREF Mt19937_64)
36     $(LREF MersenneTwisterEngine)
37 ))
38 $(TR $(TD Xorshift Engines) $(TD
39     $(LREF Xorshift)
40     $(LREF XorshiftEngine)
41     $(LREF Xorshift32)
42     $(LREF Xorshift64)
43     $(LREF Xorshift96)
44     $(LREF Xorshift128)
45     $(LREF Xorshift160)
46     $(LREF Xorshift192)
47 ))
48 $(TR $(TD Shuffle) $(TD
49     $(LREF partialShuffle)
50     $(LREF randomShuffle)
51 ))
52 $(TR $(TD Traits) $(TD
53     $(LREF isSeedable)
54     $(LREF isUniformRNG)
55 ))
56 ))
57 
58 $(RED Disclaimer:) The random number generators and API provided in this
59 module are not designed to be cryptographically secure, and are therefore
60 unsuitable for cryptographic or security-related purposes such as generating
61 authentication tokens or network sequence numbers. For such needs, please use a
62 reputable cryptographic library instead.
63 
64 The new-style generator objects hold their own state so they are
65 immune of threading issues. The generators feature a number of
66 well-known and well-documented methods of generating random
67 numbers. An overall fast and reliable means to generate random numbers
68 is the $(D_PARAM Mt19937) generator, which derives its name from
69 "$(LINK2 https://en.wikipedia.org/wiki/Mersenne_Twister, Mersenne Twister)
70 with a period of 2 to the power of
71 19937". In memory-constrained situations,
72 $(LINK2 https://en.wikipedia.org/wiki/Linear_congruential_generator,
73 linear congruential generators) such as `MinstdRand0` and `MinstdRand` might be
74 useful. The standard library provides an alias $(D_PARAM Random) for
75 whichever generator it considers the most fit for the target
76 environment.
77 
78 In addition to random number generators, this module features
79 distributions, which skew a generator's output statistical
80 distribution in various ways. So far the uniform distribution for
81 integers and real numbers have been implemented.
82 
83 Source:    $(PHOBOSSRC std/random.d)
84 
85 Macros:
86 
87 Copyright: Copyright Andrei Alexandrescu 2008 - 2009, Joseph Rushton Wakeling 2012.
88 License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
89 Authors:   $(HTTP erdani.org, Andrei Alexandrescu)
90            Masahiro Nakagawa (Xorshift random generator)
91            $(HTTP braingam.es, Joseph Rushton Wakeling) (Algorithm D for random sampling)
92            Ilya Yaroshenko (Mersenne Twister implementation, adapted from $(HTTPS github.com/libmir/mir-random, mir-random))
93 Credits:   The entire random number library architecture is derived from the
94            excellent $(HTTP open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf, C++0X)
95            random number facility proposed by Jens Maurer and contributed to by
96            researchers at the Fermi laboratory (excluding Xorshift).
97 */
98 /*
99          Copyright Andrei Alexandrescu 2008 - 2009.
100 Distributed under the Boost Software License, Version 1.0.
101    (See accompanying file LICENSE_1_0.txt or copy at
102          http://www.boost.org/LICENSE_1_0.txt)
103 */
104 module std.random;
105 
106 
107 import std.range.primitives;
108 import std.traits;
109 
110 ///
111 @safe unittest
112 {
113     import std.algorithm.comparison : among, equal;
114     import std.range : iota;
115 
116     // seed a random generator with a constant
117     auto rnd = Random(42);
118 
119     // Generate a uniformly-distributed integer in the range [0, 14]
120     // If no random generator is passed, the global `rndGen` would be used
121     auto i = uniform(0, 15, rnd);
122     assert(i >= 0 && i < 15);
123 
124     // Generate a uniformly-distributed real in the range [0, 100)
125     auto r = uniform(0.0L, 100.0L, rnd);
126     assert(r >= 0 && r < 100);
127 
128     // Sample from a custom type
129     enum Fruit { apple, mango, pear }
130     auto f = rnd.uniform!Fruit;
131     with(Fruit)
132     assert(f.among(apple, mango, pear));
133 
134     // Generate a 32-bit random number
135     auto u = uniform!uint(rnd);
136     static assert(is(typeof(u) == uint));
137 
138     // Generate a random number in the range in the range [0, 1)
139     auto u2 = uniform01(rnd);
140     assert(u2 >= 0 && u2 < 1);
141 
142     // Select an element randomly
143     auto el = 10.iota.choice(rnd);
144     assert(0 <= el && el < 10);
145 
146     // Throw a dice with custom proportions
147     // 0: 20%, 1: 10%, 2: 60%
148     auto val = rnd.dice(0.2, 0.1, 0.6);
149     assert(0 <= val && val <= 2);
150 
151     auto rnd2 = MinstdRand0(42);
152 
153     // Select a random subsample from a range
154     assert(10.iota.randomSample(3, rnd2).equal([7, 8, 9]));
155 
156     // Cover all elements in an array in random order
157     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
158         assert(10.iota.randomCover(rnd2).equal([7, 4, 2, 0, 1, 6, 8, 3, 9, 5]));
159     else
160         assert(10.iota.randomCover(rnd2).equal([4, 8, 7, 3, 5, 9, 2, 6, 0, 1]));
161 
162     // Shuffle an array
163     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
164         assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([2, 0, 4, 5, 1]));
165     else
166         assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([4, 2, 5, 0, 1]));
167 }
168 
169 version (OSX)
170     version = Darwin;
171 else version (iOS)
172     version = Darwin;
173 else version (TVOS)
174     version = Darwin;
175 else version (WatchOS)
176     version = Darwin;
177 
178 version (D_InlineAsm_X86) version = InlineAsm_X86_Any;
179 version (D_InlineAsm_X86_64) version = InlineAsm_X86_Any;
180 
181 version (StdUnittest)
182 {
183     static import std.meta;
184     package alias Xorshift64_64 = XorshiftEngine!(ulong, 64, -12, 25, -27);
185     package alias Xorshift128_64 = XorshiftEngine!(ulong, 128, 23, -18, -5);
186     package alias PseudoRngTypes = std.meta.AliasSeq!(MinstdRand0, MinstdRand, Mt19937, Xorshift32, Xorshift64,
187                                                       Xorshift96, Xorshift128, Xorshift160, Xorshift192,
188                                                       Xorshift64_64, Xorshift128_64);
189 }
190 
191 // Segments of the code in this file Copyright (c) 1997 by Rick Booth
192 // From "Inner Loops" by Rick Booth, Addison-Wesley
193 
194 // Work derived from:
195 
196 /*
197    A C-program for MT19937, with initialization improved 2002/1/26.
198    Coded by Takuji Nishimura and Makoto Matsumoto.
199 
200    Before using, initialize the state by using init_genrand(seed)
201    or init_by_array(init_key, key_length).
202 
203    Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
204    All rights reserved.
205 
206    Redistribution and use in source and binary forms, with or without
207    modification, are permitted provided that the following conditions
208    are met:
209 
210      1. Redistributions of source code must retain the above copyright
211         notice, this list of conditions and the following disclaimer.
212 
213      2. Redistributions in binary form must reproduce the above copyright
214         notice, this list of conditions and the following disclaimer in the
215         documentation and/or other materials provided with the distribution.
216 
217      3. The names of its contributors may not be used to endorse or promote
218         products derived from this software without specific prior written
219         permission.
220 
221    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
222    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
223    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
224    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
225    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
226    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
227    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
228    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
229    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
230    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
231    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
232 
233 
234    Any feedback is very welcome.
235    http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
236    email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
237 */
238 
239 /**
240  * Test if Rng is a random-number generator. The overload
241  * taking a ElementType also makes sure that the Rng generates
242  * values of that type.
243  *
244  * A random-number generator has at least the following features:
245  * $(UL
246  *   $(LI it's an InputRange)
247  *   $(LI it has a 'bool isUniformRandom' field readable in CTFE)
248  * )
249  */
250 enum isUniformRNG(Rng, ElementType) = .isUniformRNG!Rng &&
251 	is(std.range.primitives.ElementType!Rng == ElementType);
252 
253 /**
254  * ditto
255  */
256 enum isUniformRNG(Rng) = isInputRange!Rng &&
257 	is(typeof(
258 	{
259         static assert(Rng.isUniformRandom); //tag
260     }));
261 
262 ///
263 @safe unittest
264 {
265     struct NoRng
266     {
267         @property uint front() {return 0;}
268         @property bool empty() {return false;}
269         void popFront() {}
270     }
271     static assert(!isUniformRNG!(NoRng));
272 
273     struct validRng
274     {
275         @property uint front() {return 0;}
276         @property bool empty() {return false;}
277         void popFront() {}
278 
279         enum isUniformRandom = true;
280     }
281     static assert(isUniformRNG!(validRng, uint));
282     static assert(isUniformRNG!(validRng));
283 }
284 
285 @safe unittest
286 {
287     // two-argument predicate should not require @property on `front`
288     // https://issues.dlang.org/show_bug.cgi?id=19837
289     struct Rng
290     {
291         float front() {return 0;}
292         void popFront() {}
293         enum empty = false;
294         enum isUniformRandom = true;
295     }
296     static assert(isUniformRNG!(Rng, float));
297 }
298 
299 /**
300  * Test if Rng is seedable. The overload
301  * taking a SeedType also makes sure that the Rng can be seeded with SeedType.
302  *
303  * A seedable random-number generator has the following additional features:
304  * $(UL
305  *   $(LI it has a 'seed(ElementType)' function)
306  * )
307  */
308 enum isSeedable(Rng, SeedType) = isUniformRNG!(Rng) &&
309 	is(typeof(
310     {
311         Rng r = void;              ///< can define a Rng object
312         SeedType s = void; ///< Dummy doc to silence D-scanner.
313         r.seed(s); // can seed a Rng
314     }));
315 
316 ///ditto
317 enum isSeedable(Rng) = isUniformRNG!Rng &&
318 	is(typeof(
319     {
320         Rng r = void;                     ///< can define a Rng object
321         alias SeedType = typeof(r.front);
322         SeedType s = void; ///< Dummy doc to silence D-scanner.
323         r.seed(s); // can seed a Rng
324     }));
325 
326 ///
327 @safe unittest
328 {
329     struct validRng
330     {
331         @property uint front() {return 0;}
332         @property bool empty() {return false;}
333         void popFront() {}
334 
335         enum isUniformRandom = true;
336     }
337     static assert(!isSeedable!(validRng, uint));
338     static assert(!isSeedable!(validRng));
339 
340     struct seedRng
341     {
342         @property uint front() {return 0;}
343         @property bool empty() {return false;}
344         void popFront() {}
345         void seed(uint val){}
346         enum isUniformRandom = true;
347     }
348     static assert(isSeedable!(seedRng, uint));
349     static assert(!isSeedable!(seedRng, ulong));
350     static assert(isSeedable!(seedRng));
351 }
352 
353 @safe @nogc pure nothrow unittest
354 {
355     struct NoRng
356     {
357         @property uint front() {return 0;}
358         @property bool empty() {return false;}
359         void popFront() {}
360     }
361     static assert(!isUniformRNG!(NoRng, uint));
362     static assert(!isUniformRNG!(NoRng));
363     static assert(!isSeedable!(NoRng, uint));
364     static assert(!isSeedable!(NoRng));
365 
366     struct NoRng2
367     {
368         @property uint front() {return 0;}
369         @property bool empty() {return false;}
370         void popFront() {}
371 
372         enum isUniformRandom = false;
373     }
374     static assert(!isUniformRNG!(NoRng2, uint));
375     static assert(!isUniformRNG!(NoRng2));
376     static assert(!isSeedable!(NoRng2, uint));
377     static assert(!isSeedable!(NoRng2));
378 
379     struct NoRng3
380     {
381         @property bool empty() {return false;}
382         void popFront() {}
383 
384         enum isUniformRandom = true;
385     }
386     static assert(!isUniformRNG!(NoRng3, uint));
387     static assert(!isUniformRNG!(NoRng3));
388     static assert(!isSeedable!(NoRng3, uint));
389     static assert(!isSeedable!(NoRng3));
390 
391     struct validRng
392     {
393         @property uint front() {return 0;}
394         @property bool empty() {return false;}
395         void popFront() {}
396 
397         enum isUniformRandom = true;
398     }
399     static assert(isUniformRNG!(validRng, uint));
400     static assert(isUniformRNG!(validRng));
401     static assert(!isSeedable!(validRng, uint));
402     static assert(!isSeedable!(validRng));
403 
404     struct seedRng
405     {
406         @property uint front() {return 0;}
407         @property bool empty() {return false;}
408         void popFront() {}
409         void seed(uint val){}
410         enum isUniformRandom = true;
411     }
412     static assert(isUniformRNG!(seedRng, uint));
413     static assert(isUniformRNG!(seedRng));
414     static assert(isSeedable!(seedRng, uint));
415     static assert(!isSeedable!(seedRng, ulong));
416     static assert(isSeedable!(seedRng));
417 }
418 
419 /**
420 Linear Congruential generator. When m = 0, no modulus is used.
421  */
422 struct LinearCongruentialEngine(UIntType, UIntType a, UIntType c, UIntType m)
423 if (isUnsigned!UIntType)
424 {
425     ///Mark this as a Rng
426     enum bool isUniformRandom = true;
427     /// Does this generator have a fixed range? ($(D_PARAM true)).
428     enum bool hasFixedRange = true;
429     /// Lowest generated value (`1` if $(D c == 0), `0` otherwise).
430     enum UIntType min = ( c == 0 ? 1 : 0 );
431     /// Highest generated value ($(D modulus - 1)).
432     enum UIntType max = m - 1;
433 /**
434 The parameters of this distribution. The random number is $(D_PARAM x
435 = (x * multipler + increment) % modulus).
436  */
437     enum UIntType multiplier = a;
438     ///ditto
439     enum UIntType increment = c;
440     ///ditto
441     enum UIntType modulus = m;
442 
443     static assert(isIntegral!(UIntType));
444     static assert(m == 0 || a < m);
445     static assert(m == 0 || c < m);
446     static assert(m == 0 ||
447             (cast(ulong) a * (m-1) + c) % m == (c < a ? c - a + m : c - a));
448 
449     // Check for maximum range
450     private static ulong gcd(ulong a, ulong b) @safe pure nothrow @nogc
451     {
452         while (b)
453         {
454             auto t = b;
455             b = a % b;
456             a = t;
457         }
458         return a;
459     }
460 
461     private static ulong primeFactorsOnly(ulong n) @safe pure nothrow @nogc
462     {
463         ulong result = 1;
464         ulong iter = 2;
465         for (; n >= iter * iter; iter += 2 - (iter == 2))
466         {
467             if (n % iter) continue;
468             result *= iter;
469             do
470             {
471                 n /= iter;
472             } while (n % iter == 0);
473         }
474         return result * n;
475     }
476 
477     @safe pure nothrow unittest
478     {
479         static assert(primeFactorsOnly(100) == 10);
480         //writeln(primeFactorsOnly(11));
481         static assert(primeFactorsOnly(11) == 11);
482         static assert(primeFactorsOnly(7 * 7 * 7 * 11 * 15 * 11) == 7 * 11 * 15);
483         static assert(primeFactorsOnly(129 * 2) == 129 * 2);
484         // enum x = primeFactorsOnly(7 * 7 * 7 * 11 * 15);
485         // static assert(x == 7 * 11 * 15);
486     }
487 
488     private static bool properLinearCongruentialParameters(ulong m,
489             ulong a, ulong c) @safe pure nothrow @nogc
490     {
491         if (m == 0)
492         {
493             static if (is(UIntType == uint))
494             {
495                 // Assume m is uint.max + 1
496                 m = (1uL << 32);
497             }
498             else
499             {
500                 return false;
501             }
502         }
503         // Bounds checking
504         if (a == 0 || a >= m || c >= m) return false;
505         // c and m are relatively prime
506         if (c > 0 && gcd(c, m) != 1) return false;
507         // a - 1 is divisible by all prime factors of m
508         if ((a - 1) % primeFactorsOnly(m)) return false;
509         // if a - 1 is multiple of 4, then m is a  multiple of 4 too.
510         if ((a - 1) % 4 == 0 && m % 4) return false;
511         // Passed all tests
512         return true;
513     }
514 
515     // check here
516     static assert(c == 0 || properLinearCongruentialParameters(m, a, c),
517             "Incorrect instantiation of LinearCongruentialEngine");
518 
519 /**
520 Constructs a $(D_PARAM LinearCongruentialEngine) generator seeded with
521 `x0`.
522  */
523     this(UIntType x0) @safe pure nothrow @nogc
524     {
525         seed(x0);
526     }
527 
528 /**
529    (Re)seeds the generator.
530 */
531     void seed(UIntType x0 = 1) @safe pure nothrow @nogc
532     {
533         _x = modulus ? (x0 % modulus) : x0;
534         static if (c == 0)
535         {
536             //Necessary to prevent generator from outputting an endless series of zeroes.
537             if (_x == 0)
538                 _x = max;
539         }
540         popFront();
541     }
542 
543 /**
544    Advances the random sequence.
545 */
546     void popFront() @safe pure nothrow @nogc
547     {
548         static if (m)
549         {
550             static if (is(UIntType == uint) && m == uint.max)
551             {
552                 immutable ulong
553                     x = (cast(ulong) a * _x + c),
554                     v = x >> 32,
555                     w = x & uint.max;
556                 immutable y = cast(uint)(v + w);
557                 _x = (y < v || y == uint.max) ? (y + 1) : y;
558             }
559             else static if (is(UIntType == uint) && m == int.max)
560             {
561                 immutable ulong
562                     x = (cast(ulong) a * _x + c),
563                     v = x >> 31,
564                     w = x & int.max;
565                 immutable uint y = cast(uint)(v + w);
566                 _x = (y >= int.max) ? (y - int.max) : y;
567             }
568             else
569             {
570                 _x = cast(UIntType) ((cast(ulong) a * _x + c) % m);
571             }
572         }
573         else
574         {
575             _x = a * _x + c;
576         }
577     }
578 
579 /**
580    Returns the current number in the random sequence.
581 */
582     @property UIntType front() const @safe pure nothrow @nogc
583     {
584         return _x;
585     }
586 
587 ///
588     @property typeof(this) save() const @safe pure nothrow @nogc
589     {
590         return this;
591     }
592 
593 /**
594 Always `false` (random generators are infinite ranges).
595  */
596     enum bool empty = false;
597 
598     // https://issues.dlang.org/show_bug.cgi?id=21610
599     static if (m)
600     {
601         private UIntType _x = (a + c) % m;
602     }
603     else
604     {
605         private UIntType _x = a + c;
606     }
607 }
608 
609 /// Declare your own linear congruential engine
610 @safe unittest
611 {
612     alias CPP11LCG = LinearCongruentialEngine!(uint, 48271, 0, 2_147_483_647);
613 
614     // seed with a constant
615     auto rnd = CPP11LCG(42);
616     auto n = rnd.front; // same for each run
617     assert(n == 2027382);
618 }
619 
620 /// Declare your own linear congruential engine
621 @safe unittest
622 {
623     // glibc's LCG
624     alias GLibcLCG = LinearCongruentialEngine!(uint, 1103515245, 12345, 2_147_483_648);
625 
626     // Seed with an unpredictable value
627     auto rnd = GLibcLCG(unpredictableSeed);
628     auto n = rnd.front; // different across runs
629 }
630 
631 /// Declare your own linear congruential engine
632 @safe unittest
633 {
634     // Visual C++'s LCG
635     alias MSVCLCG = LinearCongruentialEngine!(uint, 214013, 2531011, 0);
636 
637     // seed with a constant
638     auto rnd = MSVCLCG(1);
639     auto n = rnd.front; // same for each run
640     assert(n == 2745024);
641 }
642 
643 // Ensure that unseeded LCGs produce correct values
644 @safe unittest
645 {
646     alias LGE = LinearCongruentialEngine!(uint, 10000, 19682, 19683);
647 
648     LGE rnd;
649     assert(rnd.front == 9999);
650 }
651 
652 /**
653 Define $(D_PARAM LinearCongruentialEngine) generators with well-chosen
654 parameters. `MinstdRand0` implements Park and Miller's "minimal
655 standard" $(HTTP
656 wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator,
657 generator) that uses 16807 for the multiplier. `MinstdRand`
658 implements a variant that has slightly better spectral behavior by
659 using the multiplier 48271. Both generators are rather simplistic.
660  */
661 alias MinstdRand0 = LinearCongruentialEngine!(uint, 16_807, 0, 2_147_483_647);
662 /// ditto
663 alias MinstdRand = LinearCongruentialEngine!(uint, 48_271, 0, 2_147_483_647);
664 
665 ///
666 @safe @nogc unittest
667 {
668     // seed with a constant
669     auto rnd0 = MinstdRand0(1);
670     auto n = rnd0.front;
671      // same for each run
672     assert(n == 16807);
673 
674     // Seed with an unpredictable value
675     rnd0.seed(unpredictableSeed);
676     n = rnd0.front; // different across runs
677 }
678 
679 @safe @nogc unittest
680 {
681     import std.range;
682     static assert(isForwardRange!MinstdRand);
683     static assert(isUniformRNG!MinstdRand);
684     static assert(isUniformRNG!MinstdRand0);
685     static assert(isUniformRNG!(MinstdRand, uint));
686     static assert(isUniformRNG!(MinstdRand0, uint));
687     static assert(isSeedable!MinstdRand);
688     static assert(isSeedable!MinstdRand0);
689     static assert(isSeedable!(MinstdRand, uint));
690     static assert(isSeedable!(MinstdRand0, uint));
691 
692     // The correct numbers are taken from The Database of Integer Sequences
693     // http://www.research.att.com/~njas/sequences/eisBTfry00128.txt
694     enum ulong[20] checking0 = [
695         16807UL,282475249,1622650073,984943658,1144108930,470211272,
696         101027544,1457850878,1458777923,2007237709,823564440,1115438165,
697         1784484492,74243042,114807987,1137522503,1441282327,16531729,
698         823378840,143542612 ];
699     //auto rnd0 = MinstdRand0(1);
700     MinstdRand0 rnd0;
701 
702     foreach (e; checking0)
703     {
704         assert(rnd0.front == e);
705         rnd0.popFront();
706     }
707     // Test the 10000th invocation
708     // Correct value taken from:
709     // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf
710     rnd0.seed();
711     popFrontN(rnd0, 9999);
712     assert(rnd0.front == 1043618065);
713 
714     // Test MinstdRand
715     enum ulong[6] checking = [48271UL,182605794,1291394886,1914720637,2078669041,
716                      407355683];
717     //auto rnd = MinstdRand(1);
718     MinstdRand rnd;
719     foreach (e; checking)
720     {
721         assert(rnd.front == e);
722         rnd.popFront();
723     }
724 
725     // Test the 10000th invocation
726     // Correct value taken from:
727     // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf
728     rnd.seed();
729     popFrontN(rnd, 9999);
730     assert(rnd.front == 399268537);
731 
732     // Check .save works
733     static foreach (Type; std.meta.AliasSeq!(MinstdRand0, MinstdRand))
734     {{
735         auto rnd1 = Type(123_456_789);
736         rnd1.popFront();
737         // https://issues.dlang.org/show_bug.cgi?id=15853
738         auto rnd2 = ((const ref Type a) => a.save())(rnd1);
739         assert(rnd1 == rnd2);
740         // Enable next test when RNGs are reference types
741         version (none) { assert(rnd1 !is rnd2); }
742         for (auto i = 0; i < 3; i++, rnd1.popFront, rnd2.popFront)
743             assert(rnd1.front() == rnd2.front());
744     }}
745 }
746 
747 @safe @nogc unittest
748 {
749     auto rnd0 = MinstdRand0(MinstdRand0.modulus);
750     auto n = rnd0.front;
751     rnd0.popFront();
752     assert(n != rnd0.front);
753 }
754 
755 /**
756 The $(LINK2 https://en.wikipedia.org/wiki/Mersenne_Twister, Mersenne Twister) generator.
757  */
758 struct MersenneTwisterEngine(UIntType, size_t w, size_t n, size_t m, size_t r,
759                              UIntType a, size_t u, UIntType d, size_t s,
760                              UIntType b, size_t t,
761                              UIntType c, size_t l, UIntType f)
762 if (isUnsigned!UIntType)
763 {
764     static assert(0 < w && w <= UIntType.sizeof * 8);
765     static assert(1 <= m && m <= n);
766     static assert(0 <= r && 0 <= u && 0 <= s && 0 <= t && 0 <= l);
767     static assert(r <= w && u <= w && s <= w && t <= w && l <= w);
768     static assert(0 <= a && 0 <= b && 0 <= c);
769     static assert(n <= ptrdiff_t.max);
770 
771     ///Mark this as a Rng
772     enum bool isUniformRandom = true;
773 
774 /**
775 Parameters for the generator.
776 */
777     enum size_t   wordSize   = w;
778     enum size_t   stateSize  = n; /// ditto
779     enum size_t   shiftSize  = m; /// ditto
780     enum size_t   maskBits   = r; /// ditto
781     enum UIntType xorMask    = a; /// ditto
782     enum size_t   temperingU = u; /// ditto
783     enum UIntType temperingD = d; /// ditto
784     enum size_t   temperingS = s; /// ditto
785     enum UIntType temperingB = b; /// ditto
786     enum size_t   temperingT = t; /// ditto
787     enum UIntType temperingC = c; /// ditto
788     enum size_t   temperingL = l; /// ditto
789     enum UIntType initializationMultiplier = f; /// ditto
790 
791     /// Smallest generated value (0).
792     enum UIntType min = 0;
793     /// Largest generated value.
794     enum UIntType max = UIntType.max >> (UIntType.sizeof * 8u - w);
795     // note, `max` also serves as a bitmask for the lowest `w` bits
796     static assert(a <= max && b <= max && c <= max && f <= max);
797 
798     /// The default seed value.
799     enum UIntType defaultSeed = 5489u;
800 
801     // Bitmasks used in the 'twist' part of the algorithm
802     private enum UIntType lowerMask = (cast(UIntType) 1u << r) - 1,
803                           upperMask = (~lowerMask) & max;
804 
805     /*
806        Collection of all state variables
807        used by the generator
808     */
809     private struct State
810     {
811         /*
812            State array of the generator.  This
813            is iterated through backwards (from
814            last element to first), providing a
815            few extra compiler optimizations by
816            comparison to the forward iteration
817            used in most implementations.
818         */
819         UIntType[n] data;
820 
821         /*
822            Cached copy of most recently updated
823            element of `data` state array, ready
824            to be tempered to generate next
825            `front` value
826         */
827         UIntType z;
828 
829         /*
830            Most recently generated random variate
831         */
832         UIntType front;
833 
834         /*
835            Index of the entry in the `data`
836            state array that will be twisted
837            in the next `popFront()` call
838         */
839         size_t index;
840     }
841 
842     /*
843        State variables used by the generator;
844        initialized to values equivalent to
845        explicitly seeding the generator with
846        `defaultSeed`
847     */
848     private State state = defaultState();
849     /* NOTE: the above is a workaround to ensure
850        backwards compatibility with the original
851        implementation, which permitted implicit
852        construction.  With `@disable this();`
853        it would not be necessary. */
854 
855 /**
856    Constructs a MersenneTwisterEngine object.
857 */
858     this(UIntType value) @safe pure nothrow @nogc
859     {
860         seed(value);
861     }
862 
863     /**
864        Generates the default initial state for a Mersenne
865        Twister; equivalent to the internal state obtained
866        by calling `seed(defaultSeed)`
867     */
868     private static State defaultState() @safe pure nothrow @nogc
869     {
870         if (!__ctfe) assert(false);
871         State mtState;
872         seedImpl(defaultSeed, mtState);
873         return mtState;
874     }
875 
876 /**
877    Seeds a MersenneTwisterEngine object.
878    Note:
879    This seed function gives 2^w starting points (the lowest w bits of
880    the value provided will be used). To allow the RNG to be started
881    in any one of its internal states use the seed overload taking an
882    InputRange.
883 */
884     void seed()(UIntType value = defaultSeed) @safe pure nothrow @nogc
885     {
886         this.seedImpl(value, this.state);
887     }
888 
889     /**
890        Implementation of the seeding mechanism, which
891        can be used with an arbitrary `State` instance
892     */
893     private static void seedImpl(UIntType value, ref State mtState) @nogc
894     {
895         mtState.data[$ - 1] = value;
896         static if (max != UIntType.max)
897         {
898             mtState.data[$ - 1] &= max;
899         }
900 
901         foreach_reverse (size_t i, ref e; mtState.data[0 .. $ - 1])
902         {
903             e = f * (mtState.data[i + 1] ^ (mtState.data[i + 1] >> (w - 2))) + cast(UIntType)(n - (i + 1));
904             static if (max != UIntType.max)
905             {
906                 e &= max;
907             }
908         }
909 
910         mtState.index = n - 1;
911 
912         /* double popFront() to guarantee both `mtState.z`
913            and `mtState.front` are derived from the newly
914            set values in `mtState.data` */
915         MersenneTwisterEngine.popFrontImpl(mtState);
916         MersenneTwisterEngine.popFrontImpl(mtState);
917     }
918 
919 /**
920    Seeds a MersenneTwisterEngine object using an InputRange.
921 
922    Throws:
923    `Exception` if the InputRange didn't provide enough elements to seed the generator.
924    The number of elements required is the 'n' template parameter of the MersenneTwisterEngine struct.
925  */
926     void seed(T)(T range)
927     if (isInputRange!T && is(immutable ElementType!T == immutable UIntType))
928     {
929         this.seedImpl(range, this.state);
930     }
931 
932     /**
933        Implementation of the range-based seeding mechanism,
934        which can be used with an arbitrary `State` instance
935     */
936     private static void seedImpl(T)(T range, ref State mtState)
937     if (isInputRange!T && is(immutable ElementType!T == immutable UIntType))
938     {
939         size_t j;
940         for (j = 0; j < n && !range.empty; ++j, range.popFront())
941         {
942             ptrdiff_t idx = n - j - 1;
943             mtState.data[idx] = range.front;
944         }
945 
946         mtState.index = n - 1;
947 
948         if (range.empty && j < n)
949         {
950             import core.internal.string : UnsignedStringBuf, unsignedToTempString;
951 
952             UnsignedStringBuf buf = void;
953             string s = "MersenneTwisterEngine.seed: Input range didn't provide enough elements: Need ";
954             s ~= unsignedToTempString(n, buf) ~ " elements.";
955             throw new Exception(s);
956         }
957 
958         /* double popFront() to guarantee both `mtState.z`
959            and `mtState.front` are derived from the newly
960            set values in `mtState.data` */
961         MersenneTwisterEngine.popFrontImpl(mtState);
962         MersenneTwisterEngine.popFrontImpl(mtState);
963     }
964 
965 /**
966    Advances the generator.
967 */
968     void popFront() @safe pure nothrow @nogc
969     {
970         this.popFrontImpl(this.state);
971     }
972 
973     /*
974        Internal implementation of `popFront()`, which
975        can be used with an arbitrary `State` instance
976     */
977     private static void popFrontImpl(ref State mtState) @nogc
978     {
979         /* This function blends two nominally independent
980            processes: (i) calculation of the next random
981            variate `mtState.front` from the cached previous
982            `data` entry `z`, and (ii) updating the value
983            of `data[index]` and `mtState.z` and advancing
984            the `index` value to the next in sequence.
985 
986            By interweaving the steps involved in these
987            procedures, rather than performing each of
988            them separately in sequence, the variables
989            are kept 'hot' in CPU registers, allowing
990            for significantly faster performance. */
991         ptrdiff_t index = mtState.index;
992         ptrdiff_t next = index - 1;
993         if (next < 0)
994             next = n - 1;
995         auto z = mtState.z;
996         ptrdiff_t conj = index - m;
997         if (conj < 0)
998             conj = index - m + n;
999 
1000         static if (d == UIntType.max)
1001         {
1002             z ^= (z >> u);
1003         }
1004         else
1005         {
1006             z ^= (z >> u) & d;
1007         }
1008 
1009         auto q = mtState.data[index] & upperMask;
1010         auto p = mtState.data[next] & lowerMask;
1011         z ^= (z << s) & b;
1012         auto y = q | p;
1013         auto x = y >> 1;
1014         z ^= (z << t) & c;
1015         if (y & 1)
1016             x ^= a;
1017         auto e = mtState.data[conj] ^ x;
1018         z ^= (z >> l);
1019         mtState.z = mtState.data[index] = e;
1020         mtState.index = next;
1021 
1022         /* technically we should take the lowest `w`
1023            bits here, but if the tempering bitmasks
1024            `b` and `c` are set correctly, this should
1025            be unnecessary */
1026         mtState.front = z;
1027     }
1028 
1029 /**
1030    Returns the current random value.
1031  */
1032     @property UIntType front() @safe const pure nothrow @nogc
1033     {
1034         return this.state.front;
1035     }
1036 
1037 ///
1038     @property typeof(this) save() @safe const pure nothrow @nogc
1039     {
1040         return this;
1041     }
1042 
1043 /**
1044 Always `false`.
1045  */
1046     enum bool empty = false;
1047 }
1048 
1049 ///
1050 @safe unittest
1051 {
1052     // seed with a constant
1053     Mt19937 gen;
1054     auto n = gen.front; // same for each run
1055     assert(n == 3499211612);
1056 
1057     // Seed with an unpredictable value
1058     gen.seed(unpredictableSeed);
1059     n = gen.front; // different across runs
1060 }
1061 
1062 /**
1063 A `MersenneTwisterEngine` instantiated with the parameters of the
1064 original engine $(HTTP math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html,
1065 MT19937), generating uniformly-distributed 32-bit numbers with a
1066 period of 2 to the power of 19937. Recommended for random number
1067 generation unless memory is severely restricted, in which case a $(LREF
1068 LinearCongruentialEngine) would be the generator of choice.
1069  */
1070 alias Mt19937 = MersenneTwisterEngine!(uint, 32, 624, 397, 31,
1071                                        0x9908b0df, 11, 0xffffffff, 7,
1072                                        0x9d2c5680, 15,
1073                                        0xefc60000, 18, 1_812_433_253);
1074 
1075 ///
1076 @safe @nogc unittest
1077 {
1078     // seed with a constant
1079     Mt19937 gen;
1080     auto n = gen.front; // same for each run
1081     assert(n == 3499211612);
1082 
1083     // Seed with an unpredictable value
1084     gen.seed(unpredictableSeed);
1085     n = gen.front; // different across runs
1086 }
1087 
1088 @safe nothrow unittest
1089 {
1090     import std.algorithm;
1091     import std.range;
1092     static assert(isUniformRNG!Mt19937);
1093     static assert(isUniformRNG!(Mt19937, uint));
1094     static assert(isSeedable!Mt19937);
1095     static assert(isSeedable!(Mt19937, uint));
1096     static assert(isSeedable!(Mt19937, typeof(map!((a) => unpredictableSeed)(repeat(0)))));
1097     Mt19937 gen;
1098     assert(gen.front == 3499211612);
1099     popFrontN(gen, 9999);
1100     assert(gen.front == 4123659995);
1101     try { gen.seed(iota(624u)); } catch (Exception) { assert(false); }
1102     assert(gen.front == 3708921088u);
1103     popFrontN(gen, 9999);
1104     assert(gen.front == 165737292u);
1105 }
1106 
1107 /**
1108 A `MersenneTwisterEngine` instantiated with the parameters of the
1109 original engine $(HTTP en.wikipedia.org/wiki/Mersenne_Twister,
1110 MT19937-64), generating uniformly-distributed 64-bit numbers with a
1111 period of 2 to the power of 19937.
1112 */
1113 alias Mt19937_64 = MersenneTwisterEngine!(ulong, 64, 312, 156, 31,
1114                                           0xb5026f5aa96619e9, 29, 0x5555555555555555, 17,
1115                                           0x71d67fffeda60000, 37,
1116                                           0xfff7eee000000000, 43, 6_364_136_223_846_793_005);
1117 
1118 ///
1119 @safe @nogc unittest
1120 {
1121     // Seed with a constant
1122     auto gen = Mt19937_64(12345);
1123     auto n = gen.front; // same for each run
1124     assert(n == 6597103971274460346);
1125 
1126     // Seed with an unpredictable value
1127     gen.seed(unpredictableSeed!ulong);
1128     n = gen.front; // different across runs
1129 }
1130 
1131 @safe nothrow unittest
1132 {
1133     import std.algorithm;
1134     import std.range;
1135     static assert(isUniformRNG!Mt19937_64);
1136     static assert(isUniformRNG!(Mt19937_64, ulong));
1137     static assert(isSeedable!Mt19937_64);
1138     static assert(isSeedable!(Mt19937_64, ulong));
1139     static assert(isSeedable!(Mt19937_64, typeof(map!((a) => unpredictableSeed!ulong)(repeat(0)))));
1140     Mt19937_64 gen;
1141     assert(gen.front == 14514284786278117030uL);
1142     popFrontN(gen, 9999);
1143     assert(gen.front == 9981545732273789042uL);
1144     try { gen.seed(iota(312uL)); } catch (Exception) { assert(false); }
1145     assert(gen.front == 14660652410669508483uL);
1146     popFrontN(gen, 9999);
1147     assert(gen.front == 15956361063660440239uL);
1148 }
1149 
1150 @safe unittest
1151 {
1152     import std.algorithm;
1153     import std.exception;
1154     import std.range;
1155 
1156     Mt19937 gen;
1157 
1158     assertThrown(gen.seed(map!((a) => 123_456_789U)(repeat(0, 623))));
1159 
1160     gen.seed(123_456_789U.repeat(624));
1161     //infinite Range
1162     gen.seed(123_456_789U.repeat);
1163 }
1164 
1165 @safe @nogc pure nothrow unittest
1166 {
1167     uint a, b;
1168     {
1169         Mt19937 gen;
1170         a = gen.front;
1171     }
1172     {
1173         Mt19937 gen;
1174         gen.popFront();
1175         //popFrontN(gen, 1);  // skip 1 element
1176         b = gen.front;
1177     }
1178     assert(a != b);
1179 }
1180 
1181 @safe @nogc unittest
1182 {
1183     // Check .save works
1184     static foreach (Type; std.meta.AliasSeq!(Mt19937, Mt19937_64))
1185     {{
1186         auto gen1 = Type(123_456_789);
1187         gen1.popFront();
1188         // https://issues.dlang.org/show_bug.cgi?id=15853
1189         auto gen2 = ((const ref Type a) => a.save())(gen1);
1190         assert(gen1 == gen2);  // Danger, Will Robinson -- no opEquals for MT
1191         // Enable next test when RNGs are reference types
1192         version (none) { assert(gen1 !is gen2); }
1193         for (auto i = 0; i < 100; i++, gen1.popFront, gen2.popFront)
1194             assert(gen1.front() == gen2.front());
1195     }}
1196 }
1197 
1198 // https://issues.dlang.org/show_bug.cgi?id=11690
1199 @safe @nogc pure nothrow unittest
1200 {
1201     alias MT(UIntType, uint w) = MersenneTwisterEngine!(UIntType, w, 624, 397, 31,
1202                                                         0x9908b0df, 11, 0xffffffff, 7,
1203                                                         0x9d2c5680, 15,
1204                                                         0xefc60000, 18, 1812433253);
1205 
1206     static immutable ulong[] expectedFirstValue = [3499211612uL, 3499211612uL,
1207                                   171143175841277uL, 1145028863177033374uL];
1208 
1209     static immutable ulong[] expected10kValue = [4123659995uL, 4123659995uL,
1210                                 51991688252792uL, 3031481165133029945uL];
1211 
1212     static foreach (i, R; std.meta.AliasSeq!(MT!(uint, 32), MT!(ulong, 32), MT!(ulong, 48), MT!(ulong, 64)))
1213     {{
1214         auto a = R();
1215         a.seed(a.defaultSeed); // checks that some alternative paths in `seed` are utilized
1216         assert(a.front == expectedFirstValue[i]);
1217         a.popFrontN(9999);
1218         assert(a.front == expected10kValue[i]);
1219     }}
1220 }
1221 
1222 /++
1223 Xorshift generator.
1224 Implemented according to $(HTTP www.jstatsoft.org/v08/i14/paper, Xorshift RNGs)
1225 (Marsaglia, 2003) when the size is small. For larger sizes the generator
1226 uses Sebastino Vigna's optimization of using an index to avoid needing
1227 to rotate the internal array.
1228 
1229 Period is `2 ^^ nbits - 1` except for a legacy 192-bit uint version (see
1230 note below).
1231 
1232 Params:
1233     UIntType = Word size of this xorshift generator and the return type
1234                of `opCall`.
1235     nbits = The number of bits of state of this generator. This must be
1236            a positive multiple of the size in bits of UIntType. If
1237            nbits is large this struct may occupy slightly more memory
1238            than this so it can use a circular counter instead of
1239            shifting the entire array.
1240     sa = The direction and magnitude of the 1st shift. Positive
1241          means left, negative means right.
1242     sb = The direction and magnitude of the 2nd shift. Positive
1243          means left, negative means right.
1244     sc = The direction and magnitude of the 3rd shift. Positive
1245          means left, negative means right.
1246 
1247 Note:
1248 For historical compatibility when `nbits == 192` and `UIntType` is `uint`
1249 a legacy hybrid PRNG is used consisting of a 160-bit xorshift combined
1250 with a 32-bit counter. This combined generator has period equal to the
1251 least common multiple of `2^^160 - 1` and `2^^32`.
1252 
1253 Previous versions of `XorshiftEngine` did not provide any mechanism to specify
1254 the directions of the shifts, taking each shift as an unsigned magnitude.
1255 For backwards compatibility, because three shifts in the same direction
1256 cannot result in a full-period XorshiftEngine, when all three of `sa`, `sb`,
1257 `sc, are positive `XorshiftEngine` treats them as unsigned magnitudes and
1258 uses shift directions to match the old behavior of `XorshiftEngine`.
1259 
1260 Not every set of shifts results in a full-period xorshift generator.
1261 The template does not currently at compile-time perform a full check
1262 for maximum period but in a future version might reject parameters
1263 resulting in shorter periods.
1264 +/
1265 struct XorshiftEngine(UIntType, uint nbits, int sa, int sb, int sc)
1266 if (isUnsigned!UIntType && !(sa > 0 && sb > 0 && sc > 0))
1267 {
1268     static assert(nbits > 0 && nbits % (UIntType.sizeof * 8) == 0,
1269         "nbits must be an even multiple of "~UIntType.stringof
1270         ~".sizeof * 8, not "~nbits.stringof~".");
1271 
1272     static assert(!((sa >= 0) == (sb >= 0) && (sa >= 0) == (sc >= 0))
1273         && (sa * sb * sc != 0),
1274         "shifts cannot be zero and cannot all be in same direction: cannot be ["
1275         ~sa.stringof~", "~sb.stringof~", "~sc.stringof~"].");
1276 
1277     static assert(sa != sb && sb != sc,
1278         "consecutive shifts with the same magnitude and direction would partially or completely cancel!");
1279 
1280     static assert(UIntType.sizeof == uint.sizeof || UIntType.sizeof == ulong.sizeof,
1281         "XorshiftEngine currently does not support type " ~ UIntType.sizeof
1282         ~ " because it does not have a `seed` implementation for arrays "
1283         ~ " of element types other than uint and ulong.");
1284 
1285   public:
1286     ///Mark this as a Rng
1287     enum bool isUniformRandom = true;
1288     /// Always `false` (random generators are infinite ranges).
1289     enum empty = false;
1290     /// Smallest generated value.
1291     enum UIntType min = _state.length == 1 ? 1 : 0;
1292     /// Largest generated value.
1293     enum UIntType max = UIntType.max;
1294 
1295 
1296   private:
1297     // Legacy 192 bit uint hybrid counter/xorshift.
1298     enum bool isLegacy192Bit = UIntType.sizeof == uint.sizeof && nbits == 192;
1299 
1300     // Shift magnitudes.
1301     enum a = (sa < 0 ? -sa : sa);
1302     enum b = (sb < 0 ? -sb : sb);
1303     enum c = (sc < 0 ? -sc : sc);
1304 
1305     // Shift expressions to mix in.
1306     enum shiftA(string expr) = `((`~expr~`) `~(sa > 0 ? `<< a)` : ` >>> a)`);
1307     enum shiftB(string expr) = `((`~expr~`) `~(sb > 0 ? `<< b)` : ` >>> b)`);
1308     enum shiftC(string expr) = `((`~expr~`) `~(sc > 0 ? `<< c)` : ` >>> c)`);
1309 
1310     enum N = nbits / (UIntType.sizeof * 8);
1311 
1312     // For N <= 2 it is strictly worse to use an index.
1313     // Informal third-party benchmarks suggest that for `ulong` it is
1314     // faster to use an index when N == 4. For `uint` we err on the side
1315     // of not increasing the struct's size and only switch to the other
1316     // implementation when N > 4.
1317     enum useIndex = !isLegacy192Bit && (UIntType.sizeof >= ulong.sizeof ? N > 3 : N > 4);
1318     static if (useIndex)
1319     {
1320         enum initialIndex = N - 1;
1321         uint _index = initialIndex;
1322     }
1323 
1324     static if (N == 1 && UIntType.sizeof <= uint.sizeof)
1325     {
1326         UIntType[N] _state = [cast(UIntType) 2_463_534_242];
1327     }
1328     else static if (isLegacy192Bit)
1329     {
1330         UIntType[N] _state = [123_456_789, 362_436_069, 521_288_629, 88_675_123, 5_783_321, 6_615_241];
1331         UIntType       value_;
1332     }
1333     else static if (N <= 5 && UIntType.sizeof <= uint.sizeof)
1334     {
1335         UIntType[N] _state = [
1336             cast(UIntType) 123_456_789,
1337             cast(UIntType) 362_436_069,
1338             cast(UIntType) 521_288_629,
1339             cast(UIntType)  88_675_123,
1340             cast(UIntType)   5_783_321][0 .. N];
1341     }
1342     else
1343     {
1344         UIntType[N] _state = ()
1345         {
1346             static if (UIntType.sizeof < ulong.sizeof)
1347             {
1348                 uint x0 = 123_456_789;
1349                 enum uint m = 1_812_433_253U;
1350             }
1351             else static if (UIntType.sizeof <= ulong.sizeof)
1352             {
1353                 ulong x0 = 123_456_789;
1354                 enum ulong m = 6_364_136_223_846_793_005UL;
1355             }
1356             else
1357             {
1358                 static assert(0, "Phobos Error: Xorshift has no instantiation rule for "
1359                     ~ UIntType.stringof);
1360             }
1361             enum uint rshift = typeof(x0).sizeof * 8 - 2;
1362             UIntType[N] result = void;
1363             foreach (i, ref e; result)
1364             {
1365                 e = cast(UIntType) (x0 = (m * (x0 ^ (x0 >>> rshift)) + i + 1));
1366                 if (e == 0)
1367                     e = cast(UIntType) (i + 1);
1368             }
1369             return result;
1370         }();
1371     }
1372 
1373 
1374   public:
1375     /++
1376     Constructs a `XorshiftEngine` generator seeded with $(D_PARAM x0).
1377 
1378     Params:
1379         x0 = value used to deterministically initialize internal state
1380     +/
1381     this()(UIntType x0) @safe pure nothrow @nogc
1382     {
1383         seed(x0);
1384     }
1385 
1386 
1387     /++
1388     (Re)seeds the generator.
1389 
1390     Params:
1391         x0 = value used to deterministically initialize internal state
1392     +/
1393     void seed()(UIntType x0) @safe pure nothrow @nogc
1394     {
1395         static if (useIndex)
1396             _index = initialIndex;
1397 
1398         static if (UIntType.sizeof == uint.sizeof)
1399         {
1400             // Initialization routine from MersenneTwisterEngine.
1401             foreach (uint i, ref e; _state)
1402             {
1403                 e = (x0 = (1_812_433_253U * (x0 ^ (x0 >> 30)) + i + 1));
1404                 // Xorshift requires merely that not every word of the internal
1405                 // array is 0. For historical compatibility the 32-bit word version
1406                 // has the stronger requirement that not any word of the state
1407                 // array is 0 after initial seeding.
1408                 if (e == 0)
1409                     e = (i + 1);
1410             }
1411         }
1412         else static if (UIntType.sizeof == ulong.sizeof)
1413         {
1414             static if (N > 1)
1415             {
1416                 // Initialize array using splitmix64 as recommended by Sebastino Vigna.
1417                 // By construction the array will not be all zeroes.
1418                 // http://xoroshiro.di.unimi.it/splitmix64.c
1419                 foreach (ref e; _state)
1420                 {
1421                     ulong z = (x0 += 0x9e37_79b9_7f4a_7c15UL);
1422                     z = (z ^ (z >>> 30)) * 0xbf58_476d_1ce4_e5b9UL;
1423                     z = (z ^ (z >>> 27)) * 0x94d0_49bb_1331_11ebUL;
1424                     e = z ^ (z >>> 31);
1425                 }
1426             }
1427             else
1428             {
1429                 // Apply a transformation when N == 1 instead of just copying x0
1430                 // directly because it's not unlikely that a user might initialize
1431                 // a PRNG with small counting numbers (e.g. 1, 2, 3) that have the
1432                 // statistically rare property of having only 1 or 2 non-zero bits.
1433                 // Additionally we need to ensure that the internal state is not
1434                 // entirely zero.
1435                 if (x0 != 0)
1436                     _state[0] = x0 * 6_364_136_223_846_793_005UL;
1437                 else
1438                     _state[0] = typeof(this).init._state[0];
1439             }
1440         }
1441         else
1442         {
1443             static assert(0, "Phobos Error: Xorshift has no `seed` implementation for "
1444                 ~ UIntType.stringof);
1445         }
1446 
1447         popFront();
1448     }
1449 
1450 
1451     /**
1452      * Returns the current number in the random sequence.
1453      */
1454     @property
1455     UIntType front() const @safe pure nothrow @nogc
1456     {
1457         static if (isLegacy192Bit)
1458             return value_;
1459         else static if (!useIndex)
1460             return _state[N-1];
1461         else
1462             return _state[_index];
1463     }
1464 
1465 
1466     /**
1467      * Advances the random sequence.
1468      */
1469     void popFront() @safe pure nothrow @nogc
1470     {
1471         alias s = _state;
1472         static if (isLegacy192Bit)
1473         {
1474             auto x = _state[0] ^ mixin(shiftA!`s[0]`);
1475             static foreach (i; 0 .. N-2)
1476                 s[i] = s[i + 1];
1477             s[N-2] = s[N-2] ^ mixin(shiftC!`s[N-2]`) ^ x ^ mixin(shiftB!`x`);
1478             value_ = s[N-2] + (s[N-1] += 362_437);
1479         }
1480         else static if (N == 1)
1481         {
1482             s[0] ^= mixin(shiftA!`s[0]`);
1483             s[0] ^= mixin(shiftB!`s[0]`);
1484             s[0] ^= mixin(shiftC!`s[0]`);
1485         }
1486         else static if (!useIndex)
1487         {
1488             auto x = s[0] ^ mixin(shiftA!`s[0]`);
1489             static foreach (i; 0 .. N-1)
1490                 s[i] = s[i + 1];
1491             s[N-1] = s[N-1] ^ mixin(shiftC!`s[N-1]`) ^ x ^ mixin(shiftB!`x`);
1492         }
1493         else
1494         {
1495             assert(_index < N); // Invariant.
1496             const sIndexMinus1 = s[_index];
1497             static if ((N & (N - 1)) == 0)
1498                 _index = (_index + 1) & typeof(_index)(N - 1);
1499             else
1500             {
1501                 if (++_index >= N)
1502                     _index = 0;
1503             }
1504             auto x = s[_index];
1505             x ^= mixin(shiftA!`x`);
1506             s[_index] = sIndexMinus1 ^ mixin(shiftC!`sIndexMinus1`) ^ x ^ mixin(shiftB!`x`);
1507         }
1508     }
1509 
1510 
1511     /**
1512      * Captures a range state.
1513      */
1514     @property
1515     typeof(this) save() const @safe pure nothrow @nogc
1516     {
1517         return this;
1518     }
1519 
1520 private:
1521     // Workaround for a DScanner bug. If we remove this `private:` DScanner
1522     // gives erroneous warnings about missing documentation for public symbols
1523     // later in the module.
1524 }
1525 
1526 /// ditto
1527 template XorshiftEngine(UIntType, int bits, int a, int b, int c)
1528 if (isUnsigned!UIntType && a > 0 && b > 0 && c > 0)
1529 {
1530     // Compatibility with old parameterizations without explicit shift directions.
1531     static if (bits == UIntType.sizeof * 8)
1532         alias XorshiftEngine = .XorshiftEngine!(UIntType, bits, a, -b, c);//left, right, left
1533     else static if (bits == 192 && UIntType.sizeof == uint.sizeof)
1534         alias XorshiftEngine = .XorshiftEngine!(UIntType, bits, -a, b, c);//right, left, left
1535     else
1536         alias XorshiftEngine = .XorshiftEngine!(UIntType, bits, a, -b, -c);//left, right, right
1537 }
1538 
1539 ///
1540 @safe unittest
1541 {
1542     alias Xorshift96  = XorshiftEngine!(uint, 96,  10, 5,  26);
1543     auto rnd = Xorshift96(42);
1544     auto num = rnd.front;  // same for each run
1545     assert(num == 2704588748);
1546 }
1547 
1548 
1549 /**
1550  * Define `XorshiftEngine` generators with well-chosen parameters. See each bits examples of "Xorshift RNGs".
1551  * `Xorshift` is a Xorshift128's alias because 128bits implementation is mostly used.
1552  */
1553 alias Xorshift32  = XorshiftEngine!(uint, 32,  13, 17, 15) ;
1554 alias Xorshift64  = XorshiftEngine!(uint, 64,  10, 13, 10); /// ditto
1555 alias Xorshift96  = XorshiftEngine!(uint, 96,  10, 5,  26); /// ditto
1556 alias Xorshift128 = XorshiftEngine!(uint, 128, 11, 8,  19); /// ditto
1557 alias Xorshift160 = XorshiftEngine!(uint, 160, 2,  1,  4);  /// ditto
1558 alias Xorshift192 = XorshiftEngine!(uint, 192, 2,  1,  4);  /// ditto
1559 alias Xorshift    = Xorshift128;                            /// ditto
1560 
1561 ///
1562 @safe @nogc unittest
1563 {
1564     // Seed with a constant
1565     auto rnd = Xorshift(1);
1566     auto num = rnd.front;  // same for each run
1567     assert(num == 1405313047);
1568 
1569     // Seed with an unpredictable value
1570     rnd.seed(unpredictableSeed);
1571     num = rnd.front; // different across rnd
1572 }
1573 
1574 @safe @nogc unittest
1575 {
1576     import std.range;
1577     static assert(isForwardRange!Xorshift);
1578     static assert(isUniformRNG!Xorshift);
1579     static assert(isUniformRNG!(Xorshift, uint));
1580     static assert(isSeedable!Xorshift);
1581     static assert(isSeedable!(Xorshift, uint));
1582 
1583     static assert(Xorshift32.min == 1);
1584 
1585     // Result from reference implementation.
1586     static ulong[][] checking = [
1587         [2463534242UL, 901999875, 3371835698, 2675058524, 1053936272, 3811264849,
1588         472493137, 3856898176, 2131710969, 2312157505],
1589         [362436069UL, 2113136921, 19051112, 3010520417, 951284840, 1213972223,
1590         3173832558, 2611145638, 2515869689, 2245824891],
1591         [521288629UL, 1950277231, 185954712, 1582725458, 3580567609, 2303633688,
1592         2394948066, 4108622809, 1116800180, 3357585673],
1593         [88675123UL, 3701687786, 458299110, 2500872618, 3633119408, 516391518,
1594         2377269574, 2599949379, 717229868, 137866584],
1595         [5783321UL, 393427209, 1947109840, 565829276, 1006220149, 971147905,
1596         1436324242, 2800460115, 1484058076, 3823330032],
1597         [0UL, 246875399, 3690007200, 1264581005, 3906711041, 1866187943, 2481925219,
1598         2464530826, 1604040631, 3653403911],
1599         [16749904790159980466UL, 14489774923612894650UL, 148813570191443371UL,
1600             6529783008780612886UL, 10182425759614080046UL, 16549659571055687844UL,
1601             542957868271744939UL, 9459127085596028450UL, 16001049981702441780UL,
1602             7351634712593111741],
1603         [14750058843113249055UL, 17731577314455387619UL, 1314705253499959044UL,
1604             3113030620614841056UL, 9468075444678629182UL, 13962152036600088141UL,
1605             9030205609946043947UL, 1856726150434672917UL, 8098922200110395314UL,
1606             2772699174618556175UL],
1607     ];
1608 
1609     alias XorshiftTypes = std.meta.AliasSeq!(Xorshift32, Xorshift64, Xorshift96,
1610         Xorshift128, Xorshift160, Xorshift192, Xorshift64_64, Xorshift128_64);
1611 
1612     foreach (I, Type; XorshiftTypes)
1613     {
1614         Type rnd;
1615 
1616         foreach (e; checking[I])
1617         {
1618             assert(rnd.front == e);
1619             rnd.popFront();
1620         }
1621     }
1622 
1623     // Check .save works
1624     foreach (Type; XorshiftTypes)
1625     {
1626         auto rnd1 = Type(123_456_789);
1627         rnd1.popFront();
1628         // https://issues.dlang.org/show_bug.cgi?id=15853
1629         auto rnd2 = ((const ref Type a) => a.save())(rnd1);
1630         assert(rnd1 == rnd2);
1631         // Enable next test when RNGs are reference types
1632         version (none) { assert(rnd1 !is rnd2); }
1633         for (auto i = 0; i <= Type.sizeof / 4; i++, rnd1.popFront, rnd2.popFront)
1634             assert(rnd1.front() == rnd2.front());
1635     }
1636 }
1637 
1638 
1639 /* A complete list of all pseudo-random number generators implemented in
1640  * std.random.  This can be used to confirm that a given function or
1641  * object is compatible with all the pseudo-random number generators
1642  * available.  It is enabled only in unittest mode.
1643  */
1644 @safe @nogc unittest
1645 {
1646     foreach (Rng; PseudoRngTypes)
1647     {
1648         static assert(isUniformRNG!Rng);
1649         auto rng = Rng(123_456_789);
1650     }
1651 }
1652 
1653 version (CRuntime_Bionic)
1654     version = SecureARC4Random; // ChaCha20
1655 version (Darwin)
1656     version = SecureARC4Random; // AES
1657 version (OpenBSD)
1658     version = SecureARC4Random; // ChaCha20
1659 version (NetBSD)
1660     version = SecureARC4Random; // ChaCha20
1661 
1662 version (CRuntime_UClibc)
1663     version = LegacyARC4Random; // ARC4
1664 version (FreeBSD)
1665     version = LegacyARC4Random; // ARC4
1666 version (DragonFlyBSD)
1667     version = LegacyARC4Random; // ARC4
1668 version (BSD)
1669     version = LegacyARC4Random; // Unknown implementation
1670 
1671 // For the current purpose of unpredictableSeed the difference between
1672 // a secure arc4random implementation and a legacy implementation is
1673 // unimportant. The source code documents this distinction in case in the
1674 // future Phobos is altered to require cryptographically secure sources
1675 // of randomness, and also so other people reading this source code (as
1676 // Phobos is often looked to as an example of good D programming practices)
1677 // do not mistakenly use insecure versions of arc4random in contexts where
1678 // cryptographically secure sources of randomness are needed.
1679 
1680 // Performance note: ChaCha20 is about 70% faster than ARC4, contrary to
1681 // what one might assume from it being more secure.
1682 
1683 version (SecureARC4Random)
1684     version = AnyARC4Random;
1685 version (LegacyARC4Random)
1686     version = AnyARC4Random;
1687 
1688 version (AnyARC4Random)
1689 {
1690     extern(C) private @nogc nothrow
1691     {
1692         uint arc4random() @safe;
1693         void arc4random_buf(scope void* buf, size_t nbytes) @system;
1694     }
1695 }
1696 else
1697 {
1698     private ulong bootstrapSeed() @nogc nothrow
1699     {
1700         // https://issues.dlang.org/show_bug.cgi?id=19580
1701         // previously used `ulong result = void` to start with an arbitary value
1702         // but using an uninitialized variable's value is undefined behavior
1703         // and enabled unwanted optimizations on non-DMD compilers.
1704         ulong result;
1705         enum ulong m = 0xc6a4_a793_5bd1_e995UL; // MurmurHash2_64A constant.
1706         void updateResult(ulong x)
1707         {
1708             x *= m;
1709             x = (x ^ (x >>> 47)) * m;
1710             result = (result ^ x) * m;
1711         }
1712         import core.thread : getpid, Thread;
1713         import core.time : MonoTime;
1714 
1715         updateResult(cast(ulong) cast(void*) Thread.getThis());
1716         updateResult(cast(ulong) getpid());
1717         updateResult(cast(ulong) MonoTime.currTime.ticks);
1718         result = (result ^ (result >>> 47)) * m;
1719         return result ^ (result >>> 47);
1720     }
1721 
1722     // If we don't have arc4random and we don't have RDRAND fall back to this.
1723     private ulong fallbackSeed() @nogc nothrow
1724     {
1725         // Bit avalanche function from MurmurHash3.
1726         static ulong fmix64(ulong k) @nogc nothrow pure @safe
1727         {
1728             k = (k ^ (k >>> 33)) * 0xff51afd7ed558ccd;
1729             k = (k ^ (k >>> 33)) * 0xc4ceb9fe1a85ec53;
1730             return k ^ (k >>> 33);
1731         }
1732         // Using SplitMix algorithm with constant gamma.
1733         // Chosen gamma is the odd number closest to 2^^64
1734         // divided by the silver ratio (1.0L + sqrt(2.0L)).
1735         enum gamma = 0x6a09e667f3bcc909UL;
1736         import core.atomic : has64BitCAS;
1737         static if (has64BitCAS)
1738         {
1739             import core.atomic : MemoryOrder, atomicLoad, atomicOp, atomicStore, cas;
1740             shared static ulong seed;
1741             shared static bool initialized;
1742             if (0 == atomicLoad!(MemoryOrder.raw)(initialized))
1743             {
1744                 cas(&seed, 0UL, fmix64(bootstrapSeed()));
1745                 atomicStore!(MemoryOrder.rel)(initialized, true);
1746             }
1747             return fmix64(atomicOp!"+="(seed, gamma));
1748         }
1749         else
1750         {
1751             static ulong seed;
1752             static bool initialized;
1753             if (!initialized)
1754             {
1755                 seed = fmix64(bootstrapSeed());
1756                 initialized = true;
1757             }
1758             return fmix64(seed += gamma);
1759         }
1760     }
1761 }
1762 
1763 version (linux)
1764     version = SeedUseGetEntropy;
1765 version (Windows)
1766     version = SeedUseGetEntropy;
1767 
1768 /**
1769 A "good" seed for initializing random number engines. Initializing
1770 with $(D_PARAM unpredictableSeed) makes engines generate different
1771 random number sequences every run.
1772 
1773 This function utilizes the system $(I cryptographically-secure pseudo-random
1774 number generator (CSPRNG)) or $(I pseudo-random number generator (PRNG))
1775 where available and implemented (currently `arc4random` on applicable BSD
1776 systems, `getrandom` on Linux or `BCryptGenRandom` on Windows) to generate
1777 “high quality” pseudo-random numbers – if possible.
1778 As a consequence, calling it may block under certain circumstances (typically
1779 during early boot when the system's entropy pool has not yet been
1780 initialized).
1781 
1782 On x86 CPU models which support the `RDRAND` instruction, that will be used
1783 when no more specialized randomness source is implemented.
1784 
1785 In the future, further platform-specific PRNGs may be incorporated.
1786 
1787 Warning:
1788 $(B This function must not be used for cryptographic purposes.)
1789 Despite being implemented for certain targets, there are no guarantees
1790 that it sources its randomness from a CSPRNG.
1791 The implementation also includes a fallback option that provides very little
1792 randomness and is used when no better source of randomness is available or
1793 integrated on the target system.
1794 As written earlier, this function only aims to provide randomness for seeding
1795 ordinary (non-cryptographic) PRNG engines.
1796 
1797 Returns:
1798 A single unsigned integer seed value, different on each successive call
1799 Note:
1800 In general periodically 'reseeding' a PRNG does not improve its quality
1801 and in some cases may harm it. For an extreme example the Mersenne
1802 Twister has `2 ^^ 19937 - 1` distinct states but after `seed(uint)` is
1803 called it can only be in one of `2 ^^ 32` distinct states regardless of
1804 how excellent the source of entropy is.
1805 */
1806 @property uint unpredictableSeed() @trusted nothrow @nogc
1807 {
1808     version (SeedUseGetEntropy)
1809     {
1810         import std.internal.entropy : crashOnError, EntropySource, getEntropy;
1811 
1812         uint buffer;
1813         const status = (() @trusted => getEntropy(&buffer, buffer.sizeof, EntropySource.tryAll))();
1814         crashOnError(status);
1815         return buffer;
1816     }
1817     else version (AnyARC4Random)
1818     {
1819         return arc4random();
1820     }
1821     else
1822     {
1823         version (InlineAsm_X86_Any)
1824         {
1825             import core.cpuid : hasRdrand;
1826             if (hasRdrand)
1827             {
1828                 uint result;
1829                 asm @nogc nothrow
1830                 {
1831                     db 0x0f, 0xc7, 0xf0; // rdrand EAX
1832                     jnc LnotUsingRdrand;
1833                     mov result, EAX;
1834                     // Some AMD CPUs shipped with bugs where RDRAND could fail
1835                     // but still set the carry flag to 1. In those cases the
1836                     // output will be -1.
1837                     cmp EAX, 0xffff_ffff;
1838                     jne LusingRdrand;
1839                     // If result was -1 verify RDAND isn't constantly returning -1.
1840                     db 0x0f, 0xc7, 0xf0;
1841                     jnc LusingRdrand;
1842                     cmp EAX, 0xffff_ffff;
1843                     je LnotUsingRdrand;
1844                 }
1845             LusingRdrand:
1846                 return result;
1847             }
1848         LnotUsingRdrand:
1849         }
1850         return cast(uint) fallbackSeed();
1851     }
1852 }
1853 
1854 /// ditto
1855 template unpredictableSeed(UIntType)
1856 if (isUnsigned!UIntType)
1857 {
1858     static if (is(UIntType == uint))
1859         alias unpredictableSeed = .unpredictableSeed;
1860     else static if (!is(Unqual!UIntType == UIntType))
1861         alias unpredictableSeed = .unpredictableSeed!(Unqual!UIntType);
1862     else
1863         /// ditto
1864         @property UIntType unpredictableSeed() @nogc nothrow @trusted
1865         {
1866             version (SeedUseGetEntropy)
1867             {
1868                 import std.internal.entropy : crashOnError, EntropySource, getEntropy;
1869 
1870                 UIntType buffer;
1871                 const status = (() @trusted => getEntropy(&buffer, buffer.sizeof, EntropySource.tryAll))();
1872                 crashOnError(status);
1873                 return buffer;
1874             }
1875             else version (AnyARC4Random)
1876             {
1877                 static if (UIntType.sizeof <= uint.sizeof)
1878                 {
1879                     return cast(UIntType) arc4random();
1880                 }
1881                 else
1882                 {
1883                     UIntType result = void;
1884                     arc4random_buf(&result, UIntType.sizeof);
1885                     return result;
1886                 }
1887             }
1888             else
1889             {
1890                 version (InlineAsm_X86_Any)
1891                 {
1892                     import core.cpuid : hasRdrand;
1893                     if (hasRdrand)
1894                     {
1895                         static if (UIntType.sizeof <= uint.sizeof)
1896                         {
1897                             uint result;
1898                             asm @nogc nothrow
1899                             {
1900                                 db 0x0f, 0xc7, 0xf0; // rdrand EAX
1901                                 jnc LnotUsingRdrand;
1902                                 mov result, EAX;
1903                                 // Some AMD CPUs shipped with bugs where RDRAND could fail
1904                                 // but still set the carry flag to 1. In those cases the
1905                                 // output will be -1.
1906                                 cmp EAX, 0xffff_ffff;
1907                                 jne LusingRdrand;
1908                                 // If result was -1 verify RDAND isn't constantly returning -1.
1909                                 db 0x0f, 0xc7, 0xf0;
1910                                 jnc LusingRdrand;
1911                                 cmp EAX, 0xffff_ffff;
1912                                 je LnotUsingRdrand;
1913                             }
1914                         LusingRdrand:
1915                             return cast(UIntType) result;
1916                         }
1917                         else version (D_InlineAsm_X86_64)
1918                         {
1919                             ulong result;
1920                             asm @nogc nothrow
1921                             {
1922                                 db 0x48, 0x0f, 0xc7, 0xf0; // rdrand RAX
1923                                 jnc LnotUsingRdrand;
1924                                 mov result, RAX;
1925                                 // Some AMD CPUs shipped with bugs where RDRAND could fail
1926                                 // but still set the carry flag to 1. In those cases the
1927                                 // output will be -1.
1928                                 cmp RAX, 0xffff_ffff_ffff_ffff;
1929                                 jne LusingRdrand;
1930                                 // If result was -1 verify RDAND isn't constantly returning -1.
1931                                 db 0x48, 0x0f, 0xc7, 0xf0;
1932                                 jnc LusingRdrand;
1933                                 cmp RAX, 0xffff_ffff_ffff_ffff;
1934                                 je LnotUsingRdrand;
1935                             }
1936                         LusingRdrand:
1937                             return result;
1938                         }
1939                         else
1940                         {
1941                             uint resultLow, resultHigh;
1942                             asm @nogc nothrow
1943                             {
1944                                 db 0x0f, 0xc7, 0xf0; // rdrand EAX
1945                                 jnc LnotUsingRdrand;
1946                                 mov resultLow, EAX;
1947                                 db 0x0f, 0xc7, 0xf0; // rdrand EAX
1948                                 jnc LnotUsingRdrand;
1949                                 mov resultHigh, EAX;
1950                             }
1951                             if (resultLow != uint.max || resultHigh != uint.max) // Protect against AMD RDRAND bug.
1952                                 return ((cast(ulong) resultHigh) << 32) ^ resultLow;
1953                         }
1954                     }
1955                 LnotUsingRdrand:
1956                 }
1957                 return cast(UIntType) fallbackSeed();
1958             }
1959         }
1960 }
1961 
1962 ///
1963 @safe @nogc unittest
1964 {
1965     auto rnd = Random(unpredictableSeed);
1966     auto n = rnd.front;
1967     static assert(is(typeof(n) == uint));
1968 }
1969 
1970 /**
1971 The "default", "favorite", "suggested" random number generator type on
1972 the current platform. It is an alias for one of the previously-defined
1973 generators. You may want to use it if (1) you need to generate some
1974 nice random numbers, and (2) you don't care for the minutiae of the
1975 method being used.
1976  */
1977 
1978 alias Random = Mt19937;
1979 
1980 @safe @nogc unittest
1981 {
1982     static assert(isUniformRNG!Random);
1983     static assert(isUniformRNG!(Random, uint));
1984     static assert(isSeedable!Random);
1985     static assert(isSeedable!(Random, uint));
1986 }
1987 
1988 /**
1989 Global random number generator used by various functions in this
1990 module whenever no generator is specified. It is allocated per-thread
1991 and initialized to an unpredictable value for each thread.
1992 
1993 Returns:
1994 A singleton instance of the default random number generator
1995  */
1996 @property ref Random rndGen() @safe nothrow @nogc
1997 {
1998     static Random result;
1999     static bool initialized;
2000     if (!initialized)
2001     {
2002         static if (isSeedable!(Random, ulong))
2003             result.seed(unpredictableSeed!ulong); // Avoid unnecessary copy.
2004         else static if (is(Random : MersenneTwisterEngine!Params, Params...))
2005             initMTEngine(result);
2006         else static if (isSeedable!(Random, uint))
2007             result.seed(unpredictableSeed!uint); // Avoid unnecessary copy.
2008         else
2009             result = Random(unpredictableSeed);
2010         initialized = true;
2011     }
2012     return result;
2013 }
2014 
2015 ///
2016 @safe nothrow @nogc unittest
2017 {
2018     import std.algorithm.iteration : sum;
2019     import std.range : take;
2020     auto rnd = rndGen;
2021     assert(rnd.take(3).sum > 0);
2022 }
2023 
2024 /+
2025 Initialize a 32-bit MersenneTwisterEngine from 64 bits of entropy.
2026 This is private and accepts no seed as a parameter, freeing the internal
2027 implementaton from any need for stability across releases.
2028 +/
2029 private void initMTEngine(MTEngine)(scope ref MTEngine mt)
2030 if (is(MTEngine : MersenneTwisterEngine!Params, Params...))
2031 {
2032     pragma(inline, false); // Called no more than once per thread by rndGen.
2033     ulong seed = unpredictableSeed!ulong;
2034     static if (is(typeof(mt.seed(seed))))
2035     {
2036         mt.seed(seed);
2037     }
2038     else
2039     {
2040         alias UIntType = typeof(mt.front());
2041         if (seed == 0) seed = -1; // Any number but 0 is fine.
2042         uint s0 = cast(uint) seed;
2043         uint s1 = cast(uint) (seed >> 32);
2044         foreach (ref e; mt.state.data)
2045         {
2046             //http://xoshiro.di.unimi.it/xoroshiro64starstar.c
2047             const tmp = s0 * 0x9E3779BB;
2048             e = ((tmp << 5) | (tmp >> (32 - 5))) * 5;
2049             static if (MTEngine.max != UIntType.max) { e &= MTEngine.max; }
2050 
2051             const tmp1 = s0 ^ s1;
2052             s0 = ((s0 << 26) | (s0 >> (32 - 26))) ^ tmp1 ^ (tmp1 << 9);
2053             s1 = (tmp1 << 13) | (tmp1 >> (32 - 13));
2054         }
2055 
2056         mt.state.index = mt.state.data.length - 1;
2057         // double popFront() to guarantee both `mt.state.z`
2058         // and `mt.state.front` are derived from the newly
2059         // set values in `mt.state.data`.
2060         mt.popFront();
2061         mt.popFront();
2062     }
2063 }
2064 
2065 /**
2066 Generates a number between `a` and `b`. The `boundaries`
2067 parameter controls the shape of the interval (open vs. closed on
2068 either side). Valid values for `boundaries` are `"[]"`, $(D
2069 "$(LPAREN)]"), `"[$(RPAREN)"`, and `"()"`. The default interval
2070 is closed to the left and open to the right. The version that does not
2071 take `urng` uses the default generator `rndGen`.
2072 
2073 Params:
2074     a = lower bound of the _uniform distribution
2075     b = upper bound of the _uniform distribution
2076     urng = (optional) random number generator to use;
2077            if not specified, defaults to `rndGen`
2078 
2079 Returns:
2080     A single random variate drawn from the _uniform distribution
2081     between `a` and `b`, whose type is the common type of
2082     these parameters
2083  */
2084 auto uniform(string boundaries = "[)", T1, T2)
2085 (T1 a, T2 b)
2086 if (!is(CommonType!(T1, T2) == void))
2087 {
2088     return uniform!(boundaries, T1, T2, Random)(a, b, rndGen);
2089 }
2090 
2091 ///
2092 @safe unittest
2093 {
2094     auto rnd = Random(unpredictableSeed);
2095 
2096     // Generate an integer in [0, 1023]
2097     auto a = uniform(0, 1024, rnd);
2098     assert(0 <= a && a < 1024);
2099 
2100     // Generate a float in [0, 1)
2101     auto b = uniform(0.0f, 1.0f, rnd);
2102     assert(0 <= b && b < 1);
2103 
2104     // Generate a float in [0, 1]
2105     b = uniform!"[]"(0.0f, 1.0f, rnd);
2106     assert(0 <= b && b <= 1);
2107 
2108     // Generate a float in (0, 1)
2109     b = uniform!"()"(0.0f, 1.0f, rnd);
2110     assert(0 < b && b < 1);
2111 }
2112 
2113 /// Create an array of random numbers using range functions and UFCS
2114 @safe unittest
2115 {
2116     import std.array : array;
2117     import std.range : generate, takeExactly;
2118 
2119     int[] arr = generate!(() => uniform(0, 100)).takeExactly(10).array;
2120     assert(arr.length == 10);
2121     assert(arr[0] >= 0 && arr[0] < 100);
2122 }
2123 
2124 @safe unittest
2125 {
2126     MinstdRand0 gen;
2127     foreach (i; 0 .. 20)
2128     {
2129         auto x = uniform(0.0, 15.0, gen);
2130         assert(0 <= x && x < 15);
2131     }
2132     foreach (i; 0 .. 20)
2133     {
2134         auto x = uniform!"[]"('a', 'z', gen);
2135         assert('a' <= x && x <= 'z');
2136     }
2137 
2138     foreach (i; 0 .. 20)
2139     {
2140         auto x = uniform('a', 'z', gen);
2141         assert('a' <= x && x < 'z');
2142     }
2143 
2144     foreach (i; 0 .. 20)
2145     {
2146         immutable ubyte a = 0;
2147             immutable ubyte b = 15;
2148         auto x = uniform(a, b, gen);
2149             assert(a <= x && x < b);
2150     }
2151 }
2152 
2153 // Implementation of uniform for floating-point types
2154 /// ditto
2155 auto uniform(string boundaries = "[)",
2156         T1, T2, UniformRandomNumberGenerator)
2157 (T1 a, T2 b, ref UniformRandomNumberGenerator urng)
2158 if (isFloatingPoint!(CommonType!(T1, T2)) && isUniformRNG!UniformRandomNumberGenerator)
2159 {
2160     import std.conv : text;
2161     import std.exception : enforce;
2162     alias NumberType = Unqual!(CommonType!(T1, T2));
2163     static if (boundaries[0] == '(')
2164     {
2165         import std.math.operations : nextafter;
2166         NumberType _a = nextafter(cast(NumberType) a, NumberType.infinity);
2167     }
2168     else
2169     {
2170         NumberType _a = a;
2171     }
2172     static if (boundaries[1] == ')')
2173     {
2174         import std.math.operations : nextafter;
2175         NumberType _b = nextafter(cast(NumberType) b, -NumberType.infinity);
2176     }
2177     else
2178     {
2179         NumberType _b = b;
2180     }
2181     enforce(_a <= _b,
2182             text("std.random.uniform(): invalid bounding interval ",
2183                     boundaries[0], a, ", ", b, boundaries[1]));
2184     NumberType result =
2185         _a + (_b - _a) * cast(NumberType) (urng.front - urng.min)
2186         / (urng.max - urng.min);
2187     urng.popFront();
2188     return result;
2189 }
2190 
2191 // Implementation of uniform for integral types
2192 /+ Description of algorithm and suggestion of correctness:
2193 
2194 The modulus operator maps an integer to a small, finite space. For instance, `x
2195 % 3` will map whatever x is into the range [0 .. 3). 0 maps to 0, 1 maps to 1, 2
2196 maps to 2, 3 maps to 0, and so on infinitely. As long as the integer is
2197 uniformly chosen from the infinite space of all non-negative integers then `x %
2198 3` will uniformly fall into that range.
2199 
2200 (Non-negative is important in this case because some definitions of modulus,
2201 namely the one used in computers generally, map negative numbers differently to
2202 (-3 .. 0]. `uniform` does not use negative number modulus, thus we can safely
2203 ignore that fact.)
2204 
2205 The issue with computers is that integers have a finite space they must fit in,
2206 and our uniformly chosen random number is picked in that finite space. So, that
2207 method is not sufficient. You can look at it as the integer space being divided
2208 into "buckets" and every bucket after the first bucket maps directly into that
2209 first bucket. `[0, 1, 2]`, `[3, 4, 5]`, ... When integers are finite, then the
2210 last bucket has the chance to be "incomplete": `[uint.max - 3, uint.max - 2,
2211 uint.max - 1]`, `[uint.max]` ... (the last bucket only has 1!). The issue here
2212 is that _every_ bucket maps _completely_ to the first bucket except for that
2213 last one. The last one doesn't have corresponding mappings to 1 or 2, in this
2214 case, which makes it unfair.
2215 
2216 So, the answer is to simply "reroll" if you're in that last bucket, since it's
2217 the only unfair one. Eventually you'll roll into a fair bucket. Simply, instead
2218 of the meaning of the last bucket being "maps to `[0]`", it changes to "maps to
2219 `[0, 1, 2]`", which is precisely what we want.
2220 
2221 To generalize, `upperDist` represents the size of our buckets (and, thus, the
2222 exclusive upper bound for our desired uniform number). `rnum` is a uniformly
2223 random number picked from the space of integers that a computer can hold (we'll
2224 say `UpperType` represents that type).
2225 
2226 We'll first try to do the mapping into the first bucket by doing `offset = rnum
2227 % upperDist`. We can figure out the position of the front of the bucket we're in
2228 by `bucketFront = rnum - offset`.
2229 
2230 If we start at `UpperType.max` and walk backwards `upperDist - 1` spaces, then
2231 the space we land on is the last acceptable position where a full bucket can
2232 fit:
2233 
2234 ---
2235    bucketFront     UpperType.max
2236       v                 v
2237 [..., 0, 1, 2, ..., upperDist - 1]
2238       ^~~ upperDist - 1 ~~^
2239 ---
2240 
2241 If the bucket starts any later, then it must have lost at least one number and
2242 at least that number won't be represented fairly.
2243 
2244 ---
2245                 bucketFront     UpperType.max
2246                      v                v
2247 [..., upperDist - 1, 0, 1, 2, ..., upperDist - 2]
2248           ^~~~~~~~ upperDist - 1 ~~~~~~~^
2249 ---
2250 
2251 Hence, our condition to reroll is
2252 `bucketFront > (UpperType.max - (upperDist - 1))`
2253 +/
2254 /// ditto
2255 auto uniform(string boundaries = "[)", T1, T2, RandomGen)
2256 (T1 a, T2 b, ref RandomGen rng)
2257 if ((isIntegral!(CommonType!(T1, T2)) || isSomeChar!(CommonType!(T1, T2))) &&
2258      isUniformRNG!RandomGen)
2259 {
2260     import std.conv : text, unsigned;
2261     import std.exception : enforce;
2262     alias ResultType = Unqual!(CommonType!(T1, T2));
2263     static if (boundaries[0] == '(')
2264     {
2265         enforce(a < ResultType.max,
2266                 text("std.random.uniform(): invalid left bound ", a));
2267         ResultType lower = cast(ResultType) (a + 1);
2268     }
2269     else
2270     {
2271         ResultType lower = a;
2272     }
2273 
2274     static if (boundaries[1] == ']')
2275     {
2276         enforce(lower <= b,
2277                 text("std.random.uniform(): invalid bounding interval ",
2278                         boundaries[0], a, ", ", b, boundaries[1]));
2279         /* Cannot use this next optimization with dchar, as dchar
2280          * only partially uses its full bit range
2281          */
2282         static if (!is(ResultType == dchar))
2283         {
2284             if (b == ResultType.max && lower == ResultType.min)
2285             {
2286                 // Special case - all bits are occupied
2287                 return std.random.uniform!ResultType(rng);
2288             }
2289         }
2290         auto upperDist = unsigned(b - lower) + 1u;
2291     }
2292     else
2293     {
2294         enforce(lower < b,
2295                 text("std.random.uniform(): invalid bounding interval ",
2296                         boundaries[0], a, ", ", b, boundaries[1]));
2297         auto upperDist = unsigned(b - lower);
2298     }
2299 
2300     assert(upperDist != 0);
2301 
2302     alias UpperType = typeof(upperDist);
2303     static assert(UpperType.min == 0);
2304 
2305     UpperType offset, rnum, bucketFront;
2306     do
2307     {
2308         rnum = uniform!UpperType(rng);
2309         offset = rnum % upperDist;
2310         bucketFront = rnum - offset;
2311     } // while we're in an unfair bucket...
2312     while (bucketFront > (UpperType.max - (upperDist - 1)));
2313 
2314     return cast(ResultType)(lower + offset);
2315 }
2316 
2317 ///
2318 @safe unittest
2319 {
2320     import std.conv : to;
2321     import std.meta : AliasSeq;
2322     import std.range.primitives : isForwardRange;
2323     import std.traits : isIntegral, isSomeChar;
2324 
2325     auto gen = Mt19937(123_456_789);
2326     static assert(isForwardRange!(typeof(gen)));
2327 
2328     auto a = uniform(0, 1024, gen);
2329     assert(0 <= a && a <= 1024);
2330     auto b = uniform(0.0f, 1.0f, gen);
2331     assert(0 <= b && b < 1, to!string(b));
2332     auto c = uniform(0.0, 1.0);
2333     assert(0 <= c && c < 1);
2334 
2335     static foreach (T; AliasSeq!(char, wchar, dchar, byte, ubyte, short, ushort,
2336                           int, uint, long, ulong, float, double, real))
2337     {{
2338         T lo = 0, hi = 100;
2339 
2340         // Try tests with each of the possible bounds
2341         {
2342             T init = uniform(lo, hi);
2343             size_t i = 50;
2344             while (--i && uniform(lo, hi) == init) {}
2345             assert(i > 0);
2346         }
2347         {
2348             T init = uniform!"[)"(lo, hi);
2349             size_t i = 50;
2350             while (--i && uniform(lo, hi) == init) {}
2351             assert(i > 0);
2352         }
2353         {
2354             T init = uniform!"(]"(lo, hi);
2355             size_t i = 50;
2356             while (--i && uniform(lo, hi) == init) {}
2357             assert(i > 0);
2358         }
2359         {
2360             T init = uniform!"()"(lo, hi);
2361             size_t i = 50;
2362             while (--i && uniform(lo, hi) == init) {}
2363             assert(i > 0);
2364         }
2365         {
2366             T init = uniform!"[]"(lo, hi);
2367             size_t i = 50;
2368             while (--i && uniform(lo, hi) == init) {}
2369             assert(i > 0);
2370         }
2371 
2372         /* Test case with closed boundaries covering whole range
2373          * of integral type
2374          */
2375         static if (isIntegral!T || isSomeChar!T)
2376         {
2377             foreach (immutable _; 0 .. 100)
2378             {
2379                 auto u = uniform!"[]"(T.min, T.max);
2380                 static assert(is(typeof(u) == T));
2381                 assert(T.min <= u, "Lower bound violation for uniform!\"[]\" with " ~ T.stringof);
2382                 assert(u <= T.max, "Upper bound violation for uniform!\"[]\" with " ~ T.stringof);
2383             }
2384         }
2385     }}
2386 
2387     auto reproRng = Xorshift(239842);
2388 
2389     static foreach (T; AliasSeq!(char, wchar, dchar, byte, ubyte, short,
2390                           ushort, int, uint, long, ulong))
2391     {{
2392         T lo = T.min + 10, hi = T.max - 10;
2393         T init = uniform(lo, hi, reproRng);
2394         size_t i = 50;
2395         while (--i && uniform(lo, hi, reproRng) == init) {}
2396         assert(i > 0);
2397     }}
2398 
2399     {
2400         bool sawLB = false, sawUB = false;
2401         foreach (i; 0 .. 50)
2402         {
2403             auto x = uniform!"[]"('a', 'd', reproRng);
2404             if (x == 'a') sawLB = true;
2405             if (x == 'd') sawUB = true;
2406             assert('a' <= x && x <= 'd');
2407         }
2408         assert(sawLB && sawUB);
2409     }
2410 
2411     {
2412         bool sawLB = false, sawUB = false;
2413         foreach (i; 0 .. 50)
2414         {
2415             auto x = uniform('a', 'd', reproRng);
2416             if (x == 'a') sawLB = true;
2417             if (x == 'c') sawUB = true;
2418             assert('a' <= x && x < 'd');
2419         }
2420         assert(sawLB && sawUB);
2421     }
2422 
2423     {
2424         bool sawLB = false, sawUB = false;
2425         foreach (i; 0 .. 50)
2426         {
2427             immutable int lo = -2, hi = 2;
2428             auto x = uniform!"()"(lo, hi, reproRng);
2429             if (x == (lo+1)) sawLB = true;
2430             if (x == (hi-1)) sawUB = true;
2431             assert(lo < x && x < hi);
2432         }
2433         assert(sawLB && sawUB);
2434     }
2435 
2436     {
2437         bool sawLB = false, sawUB = false;
2438         foreach (i; 0 .. 50)
2439         {
2440             immutable ubyte lo = 0, hi = 5;
2441             auto x = uniform(lo, hi, reproRng);
2442             if (x == lo) sawLB = true;
2443             if (x == (hi-1)) sawUB = true;
2444             assert(lo <= x && x < hi);
2445         }
2446         assert(sawLB && sawUB);
2447     }
2448 
2449     {
2450         foreach (i; 0 .. 30)
2451         {
2452             assert(i == uniform(i, i+1, reproRng));
2453         }
2454     }
2455 }
2456 
2457 /+
2458 Generates an unsigned integer in the half-open range `[0, k)`.
2459 Non-public because we locally guarantee `k > 0`.
2460 
2461 Params:
2462     k = unsigned exclusive upper bound; caller guarantees this is non-zero
2463     rng = random number generator to use
2464 
2465 Returns:
2466     Pseudo-random unsigned integer strictly less than `k`.
2467 +/
2468 private UInt _uniformIndex(UniformRNG, UInt = size_t)(const UInt k, ref UniformRNG rng)
2469 if (isUnsigned!UInt && isUniformRNG!UniformRNG)
2470 {
2471     alias ResultType = UInt;
2472     alias UpperType = Unsigned!(typeof(k - 0));
2473     alias upperDist = k;
2474 
2475     assert(upperDist != 0);
2476 
2477     // For backwards compatibility use same algorithm as uniform(0, k, rng).
2478     UpperType offset, rnum, bucketFront;
2479     do
2480     {
2481         rnum = uniform!UpperType(rng);
2482         offset = rnum % upperDist;
2483         bucketFront = rnum - offset;
2484     } // while we're in an unfair bucket...
2485     while (bucketFront > (UpperType.max - (upperDist - 1)));
2486 
2487     return cast(ResultType) offset;
2488 }
2489 
2490 pure @safe unittest
2491 {
2492     // For backwards compatibility check that _uniformIndex(k, rng)
2493     // has the same result as uniform(0, k, rng).
2494     auto rng1 = Xorshift(123_456_789);
2495     auto rng2 = rng1.save();
2496     const size_t k = (1U << 31) - 1;
2497     assert(_uniformIndex(k, rng1) == uniform(0, k, rng2));
2498 }
2499 
2500 /**
2501 Generates a uniformly-distributed number in the range $(D [T.min,
2502 T.max]) for any integral or character type `T`. If no random
2503 number generator is passed, uses the default `rndGen`.
2504 
2505 If an `enum` is used as type, the random variate is drawn with
2506 equal probability from any of the possible values of the enum `E`.
2507 
2508 Params:
2509     urng = (optional) random number generator to use;
2510            if not specified, defaults to `rndGen`
2511 
2512 Returns:
2513     Random variate drawn from the _uniform distribution across all
2514     possible values of the integral, character or enum type `T`.
2515  */
2516 auto uniform(T, UniformRandomNumberGenerator)
2517 (ref UniformRandomNumberGenerator urng)
2518 if (!is(T == enum) && (isIntegral!T || isSomeChar!T) && isUniformRNG!UniformRandomNumberGenerator)
2519 {
2520     /* dchar does not use its full bit range, so we must
2521      * revert to the uniform with specified bounds
2522      */
2523     static if (is(immutable T == immutable dchar))
2524     {
2525         return uniform!"[]"(T.min, T.max, urng);
2526     }
2527     else
2528     {
2529         auto r = urng.front;
2530         urng.popFront();
2531         static if (T.sizeof <= r.sizeof)
2532         {
2533             return cast(T) r;
2534         }
2535         else
2536         {
2537             static assert(T.sizeof == 8 && r.sizeof == 4);
2538             T r1 = urng.front | (cast(T) r << 32);
2539             urng.popFront();
2540             return r1;
2541         }
2542     }
2543 }
2544 
2545 /// Ditto
2546 auto uniform(T)()
2547 if (!is(T == enum) && (isIntegral!T || isSomeChar!T))
2548 {
2549     return uniform!T(rndGen);
2550 }
2551 
2552 ///
2553 @safe unittest
2554 {
2555     auto rnd = MinstdRand0(42);
2556 
2557     assert(rnd.uniform!ubyte == 102);
2558     assert(rnd.uniform!ulong == 4838462006927449017);
2559 
2560     enum Fruit { apple, mango, pear }
2561     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
2562     assert(rnd.uniform!Fruit == Fruit.mango);
2563 }
2564 
2565 @safe unittest
2566 {
2567     // https://issues.dlang.org/show_bug.cgi?id=21383
2568     auto rng1 = Xorshift32(123456789);
2569     auto rng2 = rng1.save;
2570     assert(rng1.uniform!dchar == rng2.uniform!dchar);
2571     // https://issues.dlang.org/show_bug.cgi?id=21384
2572     assert(rng1.uniform!(const shared dchar) <= dchar.max);
2573     // https://issues.dlang.org/show_bug.cgi?id=8671
2574     double t8671 = 1.0 - uniform(0.0, 1.0);
2575 }
2576 
2577 @safe unittest
2578 {
2579     static foreach (T; std.meta.AliasSeq!(char, wchar, dchar, byte, ubyte, short, ushort,
2580                           int, uint, long, ulong))
2581     {{
2582         T init = uniform!T();
2583         size_t i = 50;
2584         while (--i && uniform!T() == init) {}
2585         assert(i > 0);
2586 
2587         foreach (immutable _; 0 .. 100)
2588         {
2589             auto u = uniform!T();
2590             static assert(is(typeof(u) == T));
2591             assert(T.min <= u, "Lower bound violation for uniform!" ~ T.stringof);
2592             assert(u <= T.max, "Upper bound violation for uniform!" ~ T.stringof);
2593         }
2594     }}
2595 }
2596 
2597 /// ditto
2598 auto uniform(E, UniformRandomNumberGenerator)
2599 (ref UniformRandomNumberGenerator urng)
2600 if (is(E == enum) && isUniformRNG!UniformRandomNumberGenerator)
2601 {
2602     static immutable E[EnumMembers!E.length] members = [EnumMembers!E];
2603     return members[std.random.uniform(0, members.length, urng)];
2604 }
2605 
2606 /// Ditto
2607 auto uniform(E)()
2608 if (is(E == enum))
2609 {
2610     return uniform!E(rndGen);
2611 }
2612 
2613 @safe unittest
2614 {
2615     enum Fruit { Apple = 12, Mango = 29, Pear = 72 }
2616     foreach (_; 0 .. 100)
2617     {
2618         foreach (f; [uniform!Fruit(), rndGen.uniform!Fruit()])
2619         {
2620             assert(f == Fruit.Apple || f == Fruit.Mango || f == Fruit.Pear);
2621         }
2622     }
2623 }
2624 
2625 /**
2626  * Generates a uniformly-distributed floating point number of type
2627  * `T` in the range [0, 1$(RPAREN).  If no random number generator is
2628  * specified, the default RNG `rndGen` will be used as the source
2629  * of randomness.
2630  *
2631  * `uniform01` offers a faster generation of random variates than
2632  * the equivalent $(D uniform!"[$(RPAREN)"(0.0, 1.0)) and so may be preferred
2633  * for some applications.
2634  *
2635  * Params:
2636  *     rng = (optional) random number generator to use;
2637  *           if not specified, defaults to `rndGen`
2638  *
2639  * Returns:
2640  *     Floating-point random variate of type `T` drawn from the _uniform
2641  *     distribution across the half-open interval [0, 1$(RPAREN).
2642  *
2643  */
2644 T uniform01(T = double)()
2645 if (isFloatingPoint!T)
2646 {
2647     return uniform01!T(rndGen);
2648 }
2649 
2650 /// ditto
2651 T uniform01(T = double, UniformRNG)(ref UniformRNG rng)
2652 if (isFloatingPoint!T && isUniformRNG!UniformRNG)
2653 out (result)
2654 {
2655     assert(0 <= result);
2656     assert(result < 1);
2657 }
2658 do
2659 {
2660     alias R = typeof(rng.front);
2661     static if (isIntegral!R)
2662     {
2663         enum T factor = 1 / (T(1) + rng.max - rng.min);
2664     }
2665     else static if (isFloatingPoint!R)
2666     {
2667         enum T factor = 1 / (rng.max - rng.min);
2668     }
2669     else
2670     {
2671         static assert(false);
2672     }
2673 
2674     while (true)
2675     {
2676         immutable T u = (rng.front - rng.min) * factor;
2677         rng.popFront();
2678 
2679         static if (isIntegral!R && T.mant_dig >= (8 * R.sizeof))
2680         {
2681             /* If RNG variates are integral and T has enough precision to hold
2682              * R without loss, we're guaranteed by the definition of factor
2683              * that precisely u < 1.
2684              */
2685             return u;
2686         }
2687         else
2688         {
2689             /* Otherwise we have to check whether u is beyond the assumed range
2690              * because of the loss of precision, or for another reason, a
2691              * floating-point RNG can return a variate that is exactly equal to
2692              * its maximum.
2693              */
2694             if (u < 1)
2695             {
2696                 return u;
2697             }
2698         }
2699     }
2700 
2701     // Shouldn't ever get here.
2702     assert(false);
2703 }
2704 
2705 ///
2706 @safe @nogc unittest
2707 {
2708     import std.math.operations : feqrel;
2709 
2710     auto rnd = MinstdRand0(42);
2711 
2712     // Generate random numbers in the range in the range [0, 1)
2713     auto u1 = uniform01(rnd);
2714     assert(u1 >= 0 && u1 < 1);
2715 
2716     auto u2 = rnd.uniform01!float;
2717     assert(u2 >= 0 && u2 < 1);
2718 
2719     // Confirm that the random values with the initial seed 42 are 0.000328707 and 0.524587
2720     assert(u1.feqrel(0.000328707) > 20);
2721     assert(u2.feqrel(0.524587) > 20);
2722 }
2723 
2724 @safe @nogc unittest
2725 {
2726     import std.meta;
2727     static foreach (UniformRNG; PseudoRngTypes)
2728     {{
2729 
2730         static foreach (T; std.meta.AliasSeq!(float, double, real))
2731         {{
2732             UniformRNG rng = UniformRNG(123_456_789);
2733 
2734             auto a = uniform01();
2735             assert(is(typeof(a) == double));
2736             assert(0 <= a && a < 1);
2737 
2738             auto b = uniform01(rng);
2739             assert(is(typeof(a) == double));
2740             assert(0 <= b && b < 1);
2741 
2742             auto c = uniform01!T();
2743             assert(is(typeof(c) == T));
2744             assert(0 <= c && c < 1);
2745 
2746             auto d = uniform01!T(rng);
2747             assert(is(typeof(d) == T));
2748             assert(0 <= d && d < 1);
2749 
2750             T init = uniform01!T(rng);
2751             size_t i = 50;
2752             while (--i && uniform01!T(rng) == init) {}
2753             assert(i > 0);
2754             assert(i < 50);
2755         }}
2756     }}
2757 }
2758 
2759 /**
2760 Generates a uniform probability distribution of size `n`, i.e., an
2761 array of size `n` of positive numbers of type `F` that sum to
2762 `1`. If `useThis` is provided, it is used as storage.
2763  */
2764 F[] uniformDistribution(F = double)(size_t n, F[] useThis = null)
2765 if (isFloatingPoint!F)
2766 {
2767     import std.numeric : normalize;
2768     useThis.length = n;
2769     foreach (ref e; useThis)
2770     {
2771         e = uniform(0.0, 1);
2772     }
2773     normalize(useThis);
2774     return useThis;
2775 }
2776 
2777 ///
2778 @safe unittest
2779 {
2780     import std.algorithm.iteration : reduce;
2781     import std.math.operations : isClose;
2782 
2783     auto a = uniformDistribution(5);
2784     assert(a.length == 5);
2785     assert(isClose(reduce!"a + b"(a), 1));
2786 
2787     a = uniformDistribution(10, a);
2788     assert(a.length == 10);
2789     assert(isClose(reduce!"a + b"(a), 1));
2790 }
2791 
2792 /**
2793 Returns a random, uniformly chosen, element `e` from the supplied
2794 $(D Range range). If no random number generator is passed, the default
2795 `rndGen` is used.
2796 
2797 Params:
2798     range = a random access range that has the `length` property defined
2799     urng = (optional) random number generator to use;
2800            if not specified, defaults to `rndGen`
2801 
2802 Returns:
2803     A single random element drawn from the `range`. If it can, it will
2804     return a `ref` to the $(D range element), otherwise it will return
2805     a copy.
2806  */
2807 auto ref choice(Range, RandomGen = Random)(Range range, ref RandomGen urng)
2808 if (isRandomAccessRange!Range && hasLength!Range && isUniformRNG!RandomGen)
2809 {
2810     assert(range.length > 0,
2811            __PRETTY_FUNCTION__ ~ ": invalid Range supplied. Range cannot be empty");
2812 
2813     return range[uniform(size_t(0), $, urng)];
2814 }
2815 
2816 /// ditto
2817 auto ref choice(Range)(Range range)
2818 {
2819     return choice(range, rndGen);
2820 }
2821 
2822 /// ditto
2823 auto ref choice(Range, RandomGen = Random)(ref Range range, ref RandomGen urng)
2824 if (isRandomAccessRange!Range && hasLength!Range && isUniformRNG!RandomGen)
2825 {
2826     assert(range.length > 0,
2827            __PRETTY_FUNCTION__ ~ ": invalid Range supplied. Range cannot be empty");
2828     return range[uniform(size_t(0), $, urng)];
2829 }
2830 
2831 /// ditto
2832 auto ref choice(Range)(ref Range range)
2833 {
2834     return choice(range, rndGen);
2835 }
2836 
2837 ///
2838 @safe unittest
2839 {
2840     auto rnd = MinstdRand0(42);
2841 
2842     auto elem  = [1, 2, 3, 4, 5].choice(rnd);
2843     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
2844     assert(elem == 3);
2845 }
2846 
2847 @safe unittest
2848 {
2849     import std.algorithm.searching : canFind;
2850 
2851     static class MyTestClass
2852     {
2853         int x;
2854 
2855         this(int x)
2856         {
2857             this.x = x;
2858         }
2859     }
2860 
2861     MyTestClass[] testClass;
2862     foreach (i; 0 .. 5)
2863     {
2864         testClass ~= new MyTestClass(i);
2865     }
2866 
2867     auto elem = choice(testClass);
2868 
2869     assert(canFind!((ref MyTestClass a, ref MyTestClass b) => a.x == b.x)(testClass, elem),
2870            "Choice did not return a valid element from the given Range");
2871 }
2872 
2873 @system unittest
2874 {
2875     import std.algorithm.iteration : map;
2876     import std.algorithm.searching : canFind;
2877 
2878     auto array = [1, 2, 3, 4, 5];
2879     auto elemAddr = &choice(array);
2880 
2881     assert(array.map!((ref e) => &e).canFind(elemAddr),
2882            "Choice did not return a ref to an element from the given Range");
2883     assert(array.canFind(*(cast(int *)(elemAddr))),
2884            "Choice did not return a valid element from the given Range");
2885 }
2886 
2887 @safe unittest // https://issues.dlang.org/show_bug.cgi?id=18631
2888 {
2889     auto rng = MinstdRand0(42);
2890     const a = [0,1,2];
2891     const(int[]) b = [0, 1, 2];
2892     auto x = choice(a);
2893     auto y = choice(b);
2894     auto z = choice(cast(const)[1, 2, 3]);
2895     auto x1 = choice(a, rng);
2896     auto y1 = choice(b, rng);
2897     auto z1 = choice(cast(const)[1, 2, 3], rng);
2898 }
2899 
2900 @safe unittest // Ref range (https://issues.dlang.org/show_bug.cgi?id=18631 PR)
2901 {
2902     struct TestRange
2903     {
2904         int x;
2905         ref int front() return {return x;}
2906         ref int back() return {return x;}
2907         void popFront() {}
2908         void popBack() {}
2909         bool empty = false;
2910         TestRange save() {return this;}
2911         size_t length = 10;
2912         alias opDollar = length;
2913         ref int opIndex(size_t i) return {return x;}
2914     }
2915 
2916     TestRange r = TestRange(10);
2917     int* s = &choice(r);
2918 }
2919 
2920 /**
2921 Shuffles elements of `r` using `gen` as a shuffler. `r` must be
2922 a random-access range with length.  If no RNG is specified, `rndGen`
2923 will be used.
2924 
2925 Params:
2926     r = random-access range whose elements are to be shuffled
2927     gen = (optional) random number generator to use; if not
2928           specified, defaults to `rndGen`
2929 Returns:
2930     The shuffled random-access range.
2931 */
2932 
2933 Range randomShuffle(Range, RandomGen)(Range r, ref RandomGen gen)
2934 if (isRandomAccessRange!Range && isUniformRNG!RandomGen)
2935 {
2936     import std.algorithm.mutation : swapAt;
2937     const n = r.length;
2938     foreach (i; 0 .. n)
2939     {
2940         r.swapAt(i, i + _uniformIndex(n - i, gen));
2941     }
2942     return r;
2943 }
2944 
2945 /// ditto
2946 Range randomShuffle(Range)(Range r)
2947 if (isRandomAccessRange!Range)
2948 {
2949     return randomShuffle(r, rndGen);
2950 }
2951 
2952 ///
2953 @safe unittest
2954 {
2955     auto rnd = MinstdRand0(42);
2956 
2957     auto arr = [1, 2, 3, 4, 5].randomShuffle(rnd);
2958     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
2959     assert(arr == [3, 5, 2, 4, 1]);
2960 }
2961 
2962 @safe unittest
2963 {
2964     int[10] sa = void;
2965     int[10] sb = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
2966     import std.algorithm.sorting : sort;
2967     foreach (RandomGen; PseudoRngTypes)
2968     {
2969         sa[] = sb[];
2970         auto a = sa[];
2971         auto b = sb[];
2972         auto gen = RandomGen(123_456_789);
2973         randomShuffle(a, gen);
2974         sort(a);
2975         assert(a == b);
2976         randomShuffle(a);
2977         sort(a);
2978         assert(a == b);
2979     }
2980     // For backwards compatibility verify randomShuffle(r, gen)
2981     // is equivalent to partialShuffle(r, 0, r.length, gen).
2982     auto gen1 = Xorshift(123_456_789);
2983     auto gen2 = gen1.save();
2984     sa[] = sb[];
2985     // @nogc std.random.randomShuffle.
2986     // https://issues.dlang.org/show_bug.cgi?id=19156
2987     () @nogc nothrow pure { randomShuffle(sa[], gen1); }();
2988     partialShuffle(sb[], sb.length, gen2);
2989     assert(sa[] == sb[]);
2990 }
2991 
2992 // https://issues.dlang.org/show_bug.cgi?id=18501
2993 @safe unittest
2994 {
2995     import std.algorithm.comparison : among;
2996     auto r = randomShuffle([0,1]);
2997     assert(r.among([0,1],[1,0]));
2998 }
2999 
3000 /**
3001 Partially shuffles the elements of `r` such that upon returning $(D r[0 .. n])
3002 is a random subset of `r` and is randomly ordered.  $(D r[n .. r.length])
3003 will contain the elements not in $(D r[0 .. n]).  These will be in an undefined
3004 order, but will not be random in the sense that their order after
3005 `partialShuffle` returns will not be independent of their order before
3006 `partialShuffle` was called.
3007 
3008 `r` must be a random-access range with length.  `n` must be less than
3009 or equal to `r.length`.  If no RNG is specified, `rndGen` will be used.
3010 
3011 Params:
3012     r = random-access range whose elements are to be shuffled
3013     n = number of elements of `r` to shuffle (counting from the beginning);
3014         must be less than `r.length`
3015     gen = (optional) random number generator to use; if not
3016           specified, defaults to `rndGen`
3017 Returns:
3018     The shuffled random-access range.
3019 */
3020 Range partialShuffle(Range, RandomGen)(Range r, in size_t n, ref RandomGen gen)
3021 if (isRandomAccessRange!Range && isUniformRNG!RandomGen)
3022 {
3023     import std.algorithm.mutation : swapAt;
3024     import std.exception : enforce;
3025     enforce(n <= r.length, "n must be <= r.length for partialShuffle.");
3026     foreach (i; 0 .. n)
3027     {
3028         r.swapAt(i, uniform(i, r.length, gen));
3029     }
3030     return r;
3031 }
3032 
3033 /// ditto
3034 Range partialShuffle(Range)(Range r, in size_t n)
3035 if (isRandomAccessRange!Range)
3036 {
3037     return partialShuffle(r, n, rndGen);
3038 }
3039 
3040 ///
3041 @safe unittest
3042 {
3043     auto rnd = MinstdRand0(42);
3044 
3045     auto arr = [1, 2, 3, 4, 5, 6];
3046     arr = arr.dup.partialShuffle(1, rnd);
3047 
3048     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
3049     assert(arr == [2, 1, 3, 4, 5, 6]); // 1<->2
3050 
3051     arr = arr.dup.partialShuffle(2, rnd);
3052     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
3053     assert(arr == [1, 4, 3, 2, 5, 6]); // 1<->2, 2<->4
3054 
3055     arr = arr.dup.partialShuffle(3, rnd);
3056     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
3057     assert(arr == [5, 4, 6, 2, 1, 3]); // 1<->5, 2<->4, 3<->6
3058 }
3059 
3060 @safe unittest
3061 {
3062     import std.algorithm;
3063     foreach (RandomGen; PseudoRngTypes)
3064     {
3065         auto a = [0, 1, 1, 2, 3];
3066         auto b = a.dup;
3067 
3068         // Pick a fixed seed so that the outcome of the statistical
3069         // test below is deterministic.
3070         auto gen = RandomGen(12345);
3071 
3072         // NUM times, pick LEN elements from the array at random.
3073         immutable int LEN = 2;
3074         immutable int NUM = 750;
3075         int[][] chk;
3076         foreach (step; 0 .. NUM)
3077         {
3078             partialShuffle(a, LEN, gen);
3079             chk ~= a[0 .. LEN].dup;
3080         }
3081 
3082         // Check that each possible a[0 .. LEN] was produced at least once.
3083         // For a perfectly random RandomGen, the probability that each
3084         // particular combination failed to appear would be at most
3085         // 0.95 ^^ NUM which is approximately 1,962e-17.
3086         // As long as hardware failure (e.g. bit flip) probability
3087         // is higher, we are fine with this unittest.
3088         sort(chk);
3089         assert(equal(uniq(chk), [       [0,1], [0,2], [0,3],
3090                                  [1,0], [1,1], [1,2], [1,3],
3091                                  [2,0], [2,1],        [2,3],
3092                                  [3,0], [3,1], [3,2],      ]));
3093 
3094         // Check that all the elements are still there.
3095         sort(a);
3096         assert(equal(a, b));
3097     }
3098 }
3099 
3100 /**
3101 Get a random index into a list of weights corresponding to each index
3102 
3103 Similar to rolling a die with relative probabilities stored in `proportions`.
3104 Returns the index in `proportions` that was chosen.
3105 
3106 Note:
3107     Usually, dice are 'fair', meaning that each side has equal probability
3108     to come up, in which case `1 + uniform(0, 6)` can simply be used.
3109     In future Phobos versions, this function might get renamed to something like
3110     `weightedChoice` to avoid confusion.
3111 
3112 Params:
3113     rnd = (optional) random number generator to use; if not
3114           specified, defaults to `rndGen`
3115     proportions = forward range or list of individual values
3116                   whose elements correspond to the probabilities
3117                   with which to choose the corresponding index
3118                   value
3119 
3120 Returns:
3121     Random variate drawn from the index values
3122     [0, ... `proportions.length` - 1], with the probability
3123     of getting an individual index value `i` being proportional to
3124     `proportions[i]`.
3125 */
3126 size_t dice(Rng, Num)(ref Rng rnd, Num[] proportions...)
3127 if (isNumeric!Num && isForwardRange!Rng)
3128 {
3129     return diceImpl(rnd, proportions);
3130 }
3131 
3132 /// Ditto
3133 size_t dice(R, Range)(ref R rnd, Range proportions)
3134 if (isForwardRange!Range && isNumeric!(ElementType!Range) && !isArray!Range)
3135 {
3136     return diceImpl(rnd, proportions);
3137 }
3138 
3139 /// Ditto
3140 size_t dice(Range)(Range proportions)
3141 if (isForwardRange!Range && isNumeric!(ElementType!Range) && !isArray!Range)
3142 {
3143     return diceImpl(rndGen, proportions);
3144 }
3145 
3146 /// Ditto
3147 size_t dice(Num)(Num[] proportions...)
3148 if (isNumeric!Num)
3149 {
3150     return diceImpl(rndGen, proportions);
3151 }
3152 
3153 ///
3154 @safe unittest
3155 {
3156     auto d6  = 1 + dice(1, 1, 1, 1, 1, 1); // fair dice roll
3157     auto d6b = 1 + dice(2, 1, 1, 1, 1, 1); // double the chance to roll '1'
3158 
3159     auto x = dice(0.5, 0.5);   // x is 0 or 1 in equal proportions
3160     auto y = dice(50, 50);     // y is 0 or 1 in equal proportions
3161     auto z = dice(70, 20, 10); // z is 0 70% of the time, 1 20% of the time,
3162                                // and 2 10% of the time
3163 }
3164 
3165 ///
3166 @safe unittest
3167 {
3168     auto rnd = MinstdRand0(42);
3169     auto z = rnd.dice(70, 20, 10);
3170     assert(z == 0);
3171     z = rnd.dice(30, 20, 40, 10);
3172     assert(z == 2);
3173 }
3174 
3175 private size_t diceImpl(Rng, Range)(ref Rng rng, scope Range proportions)
3176 if (isForwardRange!Range && isNumeric!(ElementType!Range) && isForwardRange!Rng)
3177 in
3178 {
3179     import std.algorithm.searching : all;
3180     assert(proportions.save.all!"a >= 0");
3181 }
3182 do
3183 {
3184     import std.algorithm.iteration : reduce;
3185     import std.exception : enforce;
3186     double sum = reduce!"a + b"(0.0, proportions.save);
3187     enforce(sum > 0, "Proportions in a dice cannot sum to zero");
3188     immutable point = uniform(0.0, sum, rng);
3189     assert(point < sum);
3190     auto mass = 0.0;
3191 
3192     size_t i = 0;
3193     foreach (e; proportions)
3194     {
3195         mass += e;
3196         if (point < mass) return i;
3197         i++;
3198     }
3199     // this point should not be reached
3200     assert(false);
3201 }
3202 
3203 ///
3204 @safe unittest
3205 {
3206     auto rnd = Xorshift(123_456_789);
3207     auto i = dice(rnd, 0.0, 100.0);
3208     assert(i == 1);
3209     i = dice(rnd, 100.0, 0.0);
3210     assert(i == 0);
3211 
3212     i = dice(100U, 0U);
3213     assert(i == 0);
3214 }
3215 
3216 /+ @nogc bool array designed for RandomCover.
3217 - constructed with an invariable length
3218 - small length means 0 alloc and bit field (if up to 32(x86) or 64(x64) choices to cover)
3219 - bigger length means non-GC heap allocation(s) and dealloc. +/
3220 private struct RandomCoverChoices
3221 {
3222     private size_t* buffer;
3223     private immutable size_t _length;
3224     private immutable bool hasPackedBits;
3225     private enum BITS_PER_WORD = typeof(buffer[0]).sizeof * 8;
3226 
3227     void opAssign(T)(T) @disable;
3228 
3229     this(this) pure nothrow @nogc @trusted
3230     {
3231         import core.stdc.string : memcpy;
3232         import std.internal.memory : enforceMalloc;
3233 
3234         if (!hasPackedBits && buffer !is null)
3235         {
3236             const nBytesToAlloc = size_t.sizeof * (_length / BITS_PER_WORD + int(_length % BITS_PER_WORD != 0));
3237             void* nbuffer = enforceMalloc(nBytesToAlloc);
3238             buffer = cast(size_t*) memcpy(nbuffer, buffer, nBytesToAlloc);
3239         }
3240     }
3241 
3242     this(size_t numChoices) pure nothrow @nogc @trusted
3243     {
3244         import std.internal.memory : enforceCalloc;
3245 
3246         _length = numChoices;
3247         hasPackedBits = _length <= size_t.sizeof * 8;
3248         if (!hasPackedBits)
3249         {
3250             const nWordsToAlloc = _length / BITS_PER_WORD + int(_length % BITS_PER_WORD != 0);
3251             buffer = cast(size_t*) enforceCalloc(nWordsToAlloc, BITS_PER_WORD / 8);
3252         }
3253     }
3254 
3255     size_t length() const pure nothrow @nogc @safe @property {return _length;}
3256 
3257     ~this() pure nothrow @nogc @trusted
3258     {
3259         import core.memory : pureFree;
3260 
3261         if (!hasPackedBits && buffer !is null)
3262             pureFree(buffer);
3263     }
3264 
3265     bool opIndex(size_t index) const pure nothrow @nogc @trusted
3266     {
3267         assert(index < _length);
3268         import core.bitop : bt;
3269         if (!hasPackedBits)
3270             return cast(bool) bt(buffer, index);
3271         else
3272             return ((cast(size_t) buffer) >> index) & size_t(1);
3273     }
3274 
3275     void opIndexAssign(bool value, size_t index) pure nothrow @nogc @trusted
3276     {
3277         assert(index < _length);
3278         if (!hasPackedBits)
3279         {
3280             import core.bitop : btr, bts;
3281             if (value)
3282                 bts(buffer, index);
3283             else
3284                 btr(buffer, index);
3285         }
3286         else
3287         {
3288             if (value)
3289                 (*cast(size_t*) &buffer) |= size_t(1) << index;
3290             else
3291                 (*cast(size_t*) &buffer) &= ~(size_t(1) << index);
3292         }
3293     }
3294 }
3295 
3296 @safe @nogc nothrow unittest
3297 {
3298     static immutable lengths = [3, 32, 65, 256];
3299     foreach (length; lengths)
3300     {
3301         RandomCoverChoices c = RandomCoverChoices(length);
3302         assert(c.hasPackedBits == (length <= size_t.sizeof * 8));
3303         c[0] = true;
3304         c[2] = true;
3305         assert(c[0]);
3306         assert(!c[1]);
3307         assert(c[2]);
3308         c[0] = false;
3309         c[1] = true;
3310         c[2] = false;
3311         assert(!c[0]);
3312         assert(c[1]);
3313         assert(!c[2]);
3314     }
3315 }
3316 
3317 /**
3318 Covers a given range `r` in a random manner, i.e. goes through each
3319 element of `r` once and only once, just in a random order. `r`
3320 must be a random-access range with length.
3321 
3322 If no random number generator is passed to `randomCover`, the
3323 thread-global RNG rndGen will be used internally.
3324 
3325 Params:
3326     r = random-access range to cover
3327     rng = (optional) random number generator to use;
3328           if not specified, defaults to `rndGen`
3329 
3330 Returns:
3331     Range whose elements consist of the elements of `r`,
3332     in random order.  Will be a forward range if both `r` and
3333     `rng` are forward ranges, an
3334     $(REF_ALTTEXT input range, isInputRange, std,range,primitives) otherwise.
3335 */
3336 struct RandomCover(Range, UniformRNG = void)
3337 if (isRandomAccessRange!Range && (isUniformRNG!UniformRNG || is(UniformRNG == void)))
3338 {
3339     private Range _input;
3340     private RandomCoverChoices _chosen;
3341     private size_t _current;
3342     private size_t _alreadyChosen = 0;
3343     private bool _isEmpty = false;
3344 
3345     static if (is(UniformRNG == void))
3346     {
3347         this(Range input)
3348         {
3349             _input = input;
3350             _chosen = RandomCoverChoices(_input.length);
3351             if (_input.empty)
3352             {
3353                 _isEmpty = true;
3354             }
3355             else
3356             {
3357                 _current = _uniformIndex(_chosen.length, rndGen);
3358             }
3359         }
3360     }
3361     else
3362     {
3363         private UniformRNG _rng;
3364 
3365         this(Range input, ref UniformRNG rng)
3366         {
3367             _input = input;
3368             _rng = rng;
3369             _chosen = RandomCoverChoices(_input.length);
3370             if (_input.empty)
3371             {
3372                 _isEmpty = true;
3373             }
3374             else
3375             {
3376                 _current = _uniformIndex(_chosen.length, rng);
3377             }
3378         }
3379 
3380         this(Range input, UniformRNG rng)
3381         {
3382             this(input, rng);
3383         }
3384     }
3385 
3386     static if (hasLength!Range)
3387     {
3388         @property size_t length()
3389         {
3390             return _input.length - _alreadyChosen;
3391         }
3392     }
3393 
3394     @property auto ref front()
3395     {
3396         assert(!_isEmpty);
3397         return _input[_current];
3398     }
3399 
3400     void popFront()
3401     {
3402         assert(!_isEmpty);
3403 
3404         size_t k = _input.length - _alreadyChosen - 1;
3405         if (k == 0)
3406         {
3407             _isEmpty = true;
3408             ++_alreadyChosen;
3409             return;
3410         }
3411 
3412         size_t i;
3413         foreach (e; _input)
3414         {
3415             if (_chosen[i] || i == _current) { ++i; continue; }
3416             // Roll a dice with k faces
3417             static if (is(UniformRNG == void))
3418             {
3419                 auto chooseMe = _uniformIndex(k, rndGen) == 0;
3420             }
3421             else
3422             {
3423                 auto chooseMe = _uniformIndex(k, _rng) == 0;
3424             }
3425             assert(k > 1 || chooseMe);
3426             if (chooseMe)
3427             {
3428                 _chosen[_current] = true;
3429                 _current = i;
3430                 ++_alreadyChosen;
3431                 return;
3432             }
3433             --k;
3434             ++i;
3435         }
3436     }
3437 
3438     static if (isForwardRange!UniformRNG)
3439     {
3440         @property typeof(this) save()
3441         {
3442             auto ret = this;
3443             ret._input = _input.save;
3444             ret._rng = _rng.save;
3445             return ret;
3446         }
3447     }
3448 
3449     @property bool empty() const { return _isEmpty; }
3450 }
3451 
3452 /// Ditto
3453 auto randomCover(Range, UniformRNG)(Range r, auto ref UniformRNG rng)
3454 if (isRandomAccessRange!Range && isUniformRNG!UniformRNG)
3455 {
3456     return RandomCover!(Range, UniformRNG)(r, rng);
3457 }
3458 
3459 /// Ditto
3460 auto randomCover(Range)(Range r)
3461 if (isRandomAccessRange!Range)
3462 {
3463     return RandomCover!(Range, void)(r);
3464 }
3465 
3466 ///
3467 @safe unittest
3468 {
3469     import std.algorithm.comparison : equal;
3470     import std.range : iota;
3471     auto rnd = MinstdRand0(42);
3472 
3473     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
3474     assert(10.iota.randomCover(rnd).equal([7, 4, 2, 0, 1, 6, 8, 3, 9, 5]));
3475 }
3476 
3477 @safe unittest // cover RandomCoverChoices postblit for heap storage
3478 {
3479     import std.array : array;
3480     import std.range : iota;
3481     auto a = 1337.iota.randomCover().array;
3482     assert(a.length == 1337);
3483 }
3484 
3485 @nogc nothrow pure @safe unittest
3486 {
3487     // Optionally @nogc std.random.randomCover
3488     // https://issues.dlang.org/show_bug.cgi?id=14001
3489     auto rng = Xorshift(123_456_789);
3490     static immutable int[] sa = [1, 2, 3, 4, 5];
3491     auto r = randomCover(sa, rng);
3492     assert(!r.empty);
3493     const x = r.front;
3494     r.popFront();
3495     assert(!r.empty);
3496     const y = r.front;
3497     assert(x != y);
3498 }
3499 
3500 @safe unittest
3501 {
3502     import std.algorithm;
3503     import std.conv;
3504     int[] a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ];
3505     int[] c;
3506     static foreach (UniformRNG; std.meta.AliasSeq!(void, PseudoRngTypes))
3507     {{
3508         static if (is(UniformRNG == void))
3509         {
3510             auto rc = randomCover(a);
3511             static assert(isInputRange!(typeof(rc)));
3512             static assert(!isForwardRange!(typeof(rc)));
3513         }
3514         else
3515         {
3516             auto rng = UniformRNG(123_456_789);
3517             auto rc = randomCover(a, rng);
3518             static assert(isForwardRange!(typeof(rc)));
3519             // check for constructor passed a value-type RNG
3520             auto rc2 = RandomCover!(int[], UniformRNG)(a, UniformRNG(987_654_321));
3521             static assert(isForwardRange!(typeof(rc2)));
3522             auto rcEmpty = randomCover(c, rng);
3523             assert(rcEmpty.length == 0);
3524         }
3525 
3526         int[] b = new int[9];
3527         uint i;
3528         foreach (e; rc)
3529         {
3530             //writeln(e);
3531             b[i++] = e;
3532         }
3533         sort(b);
3534         assert(a == b, text(b));
3535     }}
3536 }
3537 
3538 @safe unittest
3539 {
3540     // https://issues.dlang.org/show_bug.cgi?id=12589
3541     int[] r = [];
3542     auto rc = randomCover(r);
3543     assert(rc.length == 0);
3544     assert(rc.empty);
3545 
3546     // https://issues.dlang.org/show_bug.cgi?id=16724
3547     import std.range : iota;
3548     auto range = iota(10);
3549     auto randy = range.randomCover;
3550 
3551     for (int i=1; i <= range.length; i++)
3552     {
3553         randy.popFront;
3554         assert(randy.length == range.length - i);
3555     }
3556 }
3557 
3558 // RandomSample
3559 /**
3560 Selects a random subsample out of `r`, containing exactly `n`
3561 elements. The order of elements is the same as in the original
3562 range. The total length of `r` must be known. If `total` is
3563 passed in, the total number of sample is considered to be $(D
3564 total). Otherwise, `RandomSample` uses `r.length`.
3565 
3566 Params:
3567     r = range to sample from
3568     n = number of elements to include in the sample;
3569         must be less than or equal to the total number
3570         of elements in `r` and/or the parameter
3571         `total` (if provided)
3572     total = (semi-optional) number of elements of `r`
3573             from which to select the sample (counting from
3574             the beginning); must be less than or equal to
3575             the total number of elements in `r` itself.
3576             May be omitted if `r` has the `.length`
3577             property and the sample is to be drawn from
3578             all elements of `r`.
3579     rng = (optional) random number generator to use;
3580           if not specified, defaults to `rndGen`
3581 
3582 Returns:
3583     Range whose elements consist of a randomly selected subset of
3584     the elements of `r`, in the same order as these elements
3585     appear in `r` itself.  Will be a forward range if both `r`
3586     and `rng` are forward ranges, an input range otherwise.
3587 
3588 `RandomSample` implements Jeffrey Scott Vitter's Algorithm D
3589 (see Vitter $(HTTP dx.doi.org/10.1145/358105.893, 1984), $(HTTP
3590 dx.doi.org/10.1145/23002.23003, 1987)), which selects a sample
3591 of size `n` in O(n) steps and requiring O(n) random variates,
3592 regardless of the size of the data being sampled.  The exception
3593 to this is if traversing k elements on the input range is itself
3594 an O(k) operation (e.g. when sampling lines from an input file),
3595 in which case the sampling calculation will inevitably be of
3596 O(total).
3597 
3598 RandomSample will throw an exception if `total` is verifiably
3599 less than the total number of elements available in the input,
3600 or if $(D n > total).
3601 
3602 If no random number generator is passed to `randomSample`, the
3603 thread-global RNG rndGen will be used internally.
3604 */
3605 struct RandomSample(Range, UniformRNG = void)
3606 if (isInputRange!Range && (isUniformRNG!UniformRNG || is(UniformRNG == void)))
3607 {
3608     private size_t _available, _toSelect;
3609     private enum ushort _alphaInverse = 13; // Vitter's recommended value.
3610     private double _Vprime;
3611     private Range _input;
3612     private size_t _index;
3613     private enum Skip { None, A, D }
3614     private Skip _skip = Skip.None;
3615 
3616     // If we're using the default thread-local random number generator then
3617     // we shouldn't store a copy of it here.  UniformRNG == void is a sentinel
3618     // for this.  If we're using a user-specified generator then we have no
3619     // choice but to store a copy.
3620     static if (is(UniformRNG == void))
3621     {
3622         static if (hasLength!Range)
3623         {
3624             this(Range input, size_t howMany)
3625             {
3626                 _input = input;
3627                 initialize(howMany, input.length);
3628             }
3629         }
3630 
3631         this(Range input, size_t howMany, size_t total)
3632         {
3633             _input = input;
3634             initialize(howMany, total);
3635         }
3636     }
3637     else
3638     {
3639         UniformRNG _rng;
3640 
3641         static if (hasLength!Range)
3642         {
3643             this(Range input, size_t howMany, ref scope UniformRNG rng)
3644             {
3645                 _rng = rng;
3646                 _input = input;
3647                 initialize(howMany, input.length);
3648             }
3649 
3650             this(Range input, size_t howMany, UniformRNG rng)
3651             {
3652                 this(input, howMany, rng);
3653             }
3654         }
3655 
3656         this(Range input, size_t howMany, size_t total, ref scope UniformRNG rng)
3657         {
3658             _rng = rng;
3659             _input = input;
3660             initialize(howMany, total);
3661         }
3662 
3663         this(Range input, size_t howMany, size_t total, UniformRNG rng)
3664         {
3665             this(input, howMany, total, rng);
3666         }
3667     }
3668 
3669     private void initialize(size_t howMany, size_t total)
3670     {
3671         import std.conv : text;
3672         import std.exception : enforce;
3673         _available = total;
3674         _toSelect = howMany;
3675         enforce(_toSelect <= _available,
3676                 text("RandomSample: cannot sample ", _toSelect,
3677                      " items when only ", _available, " are available"));
3678         static if (hasLength!Range)
3679         {
3680             enforce(_available <= _input.length,
3681                     text("RandomSample: specified ", _available,
3682                          " items as available when input contains only ",
3683                          _input.length));
3684         }
3685     }
3686 
3687     private void initializeFront()
3688     {
3689         assert(_skip == Skip.None);
3690         // We can save ourselves a random variate by checking right
3691         // at the beginning if we should use Algorithm A.
3692         if ((_alphaInverse * _toSelect) > _available)
3693         {
3694             _skip = Skip.A;
3695         }
3696         else
3697         {
3698             _skip = Skip.D;
3699             _Vprime = newVprime(_toSelect);
3700         }
3701         prime();
3702     }
3703 
3704 /**
3705    Range primitives.
3706 */
3707     @property bool empty() const
3708     {
3709         return _toSelect == 0;
3710     }
3711 
3712 /// Ditto
3713     @property auto ref front()
3714     {
3715         assert(!empty);
3716         // The first sample point must be determined here to avoid
3717         // having it always correspond to the first element of the
3718         // input.  The rest of the sample points are determined each
3719         // time we call popFront().
3720         if (_skip == Skip.None)
3721         {
3722             initializeFront();
3723         }
3724         return _input.front;
3725     }
3726 
3727 /// Ditto
3728     void popFront()
3729     {
3730         // First we need to check if the sample has
3731         // been initialized in the first place.
3732         if (_skip == Skip.None)
3733         {
3734             initializeFront();
3735         }
3736 
3737         _input.popFront();
3738         --_available;
3739         --_toSelect;
3740         ++_index;
3741         prime();
3742     }
3743 
3744 /// Ditto
3745     static if (isForwardRange!Range && isForwardRange!UniformRNG)
3746     {
3747         static if (is(typeof(((const UniformRNG* p) => (*p).save)(null)) : UniformRNG)
3748             && is(typeof(((const Range* p) => (*p).save)(null)) : Range))
3749         {
3750             @property typeof(this) save() const
3751             {
3752                 auto ret = RandomSample.init;
3753                 foreach (fieldIndex, ref val; this.tupleof)
3754                 {
3755                     static if (is(typeof(val) == const(Range)) || is(typeof(val) == const(UniformRNG)))
3756                         ret.tupleof[fieldIndex] = val.save;
3757                     else
3758                         ret.tupleof[fieldIndex] = val;
3759                 }
3760                 return ret;
3761             }
3762         }
3763         else
3764         {
3765             @property typeof(this) save()
3766             {
3767                 auto ret = this;
3768                 ret._input = _input.save;
3769                 ret._rng = _rng.save;
3770                 return ret;
3771             }
3772         }
3773     }
3774 
3775 /// Ditto
3776     @property size_t length() const
3777     {
3778         return _toSelect;
3779     }
3780 
3781 /**
3782 Returns the index of the visited record.
3783  */
3784     @property size_t index()
3785     {
3786         if (_skip == Skip.None)
3787         {
3788             initializeFront();
3789         }
3790         return _index;
3791     }
3792 
3793     private size_t skip()
3794     {
3795         assert(_skip != Skip.None);
3796 
3797         // Step D1: if the number of points still to select is greater
3798         // than a certain proportion of the remaining data points, i.e.
3799         // if n >= alpha * N where alpha = 1/13, we carry out the
3800         // sampling with Algorithm A.
3801         if (_skip == Skip.A)
3802         {
3803             return skipA();
3804         }
3805         else if ((_alphaInverse * _toSelect) > _available)
3806         {
3807             // We shouldn't get here unless the current selected
3808             // algorithm is D.
3809             assert(_skip == Skip.D);
3810             _skip = Skip.A;
3811             return skipA();
3812         }
3813         else
3814         {
3815             assert(_skip == Skip.D);
3816             return skipD();
3817         }
3818     }
3819 
3820 /*
3821 Vitter's Algorithm A, used when the ratio of needed sample values
3822 to remaining data values is sufficiently large.
3823 */
3824     private size_t skipA()
3825     {
3826         size_t s;
3827         double v, quot, top;
3828 
3829         if (_toSelect == 1)
3830         {
3831             static if (is(UniformRNG == void))
3832             {
3833                 s = uniform(0, _available);
3834             }
3835             else
3836             {
3837                 s = uniform(0, _available, _rng);
3838             }
3839         }
3840         else
3841         {
3842             v = 0;
3843             top = _available - _toSelect;
3844             quot = top / _available;
3845 
3846             static if (is(UniformRNG == void))
3847             {
3848                 v = uniform!"()"(0.0, 1.0);
3849             }
3850             else
3851             {
3852                 v = uniform!"()"(0.0, 1.0, _rng);
3853             }
3854 
3855             while (quot > v)
3856             {
3857                 ++s;
3858                 quot *= (top - s) / (_available - s);
3859             }
3860         }
3861 
3862         return s;
3863     }
3864 
3865 /*
3866 Randomly reset the value of _Vprime.
3867 */
3868     private double newVprime(size_t remaining)
3869     {
3870         static if (is(UniformRNG == void))
3871         {
3872             double r = uniform!"()"(0.0, 1.0);
3873         }
3874         else
3875         {
3876             double r = uniform!"()"(0.0, 1.0, _rng);
3877         }
3878 
3879         return r ^^ (1.0 / remaining);
3880     }
3881 
3882 /*
3883 Vitter's Algorithm D.  For an extensive description of the algorithm
3884 and its rationale, see:
3885 
3886   * Vitter, J.S. (1984), "Faster methods for random sampling",
3887     Commun. ACM 27(7): 703--718
3888 
3889   * Vitter, J.S. (1987) "An efficient algorithm for sequential random
3890     sampling", ACM Trans. Math. Softw. 13(1): 58-67.
3891 
3892 Variable names are chosen to match those in Vitter's paper.
3893 */
3894     private size_t skipD()
3895     {
3896         import std.math.traits : isNaN;
3897         import std.math.rounding : trunc;
3898         // Confirm that the check in Step D1 is valid and we
3899         // haven't been sent here by mistake
3900         assert((_alphaInverse * _toSelect) <= _available);
3901 
3902         // Now it's safe to use the standard Algorithm D mechanism.
3903         if (_toSelect > 1)
3904         {
3905             size_t s;
3906             size_t qu1 = 1 + _available - _toSelect;
3907             double x, y1;
3908 
3909             assert(!_Vprime.isNaN());
3910 
3911             while (true)
3912             {
3913                 // Step D2: set values of x and u.
3914                 while (1)
3915                 {
3916                     x = _available * (1-_Vprime);
3917                     s = cast(size_t) trunc(x);
3918                     if (s < qu1)
3919                         break;
3920                     _Vprime = newVprime(_toSelect);
3921                 }
3922 
3923                 static if (is(UniformRNG == void))
3924                 {
3925                     double u = uniform!"()"(0.0, 1.0);
3926                 }
3927                 else
3928                 {
3929                     double u = uniform!"()"(0.0, 1.0, _rng);
3930                 }
3931 
3932                 y1 = (u * (cast(double) _available) / qu1) ^^ (1.0/(_toSelect - 1));
3933 
3934                 _Vprime = y1 * ((-x/_available)+1.0) * ( qu1/( (cast(double) qu1) - s ) );
3935 
3936                 // Step D3: if _Vprime <= 1.0 our work is done and we return S.
3937                 // Otherwise ...
3938                 if (_Vprime > 1.0)
3939                 {
3940                     size_t top = _available - 1, limit;
3941                     double y2 = 1.0, bottom;
3942 
3943                     if (_toSelect > (s+1))
3944                     {
3945                         bottom = _available - _toSelect;
3946                         limit = _available - s;
3947                     }
3948                     else
3949                     {
3950                         bottom = _available - (s+1);
3951                         limit = qu1;
3952                     }
3953 
3954                     foreach (size_t t; limit .. _available)
3955                     {
3956                         y2 *= top/bottom;
3957                         top--;
3958                         bottom--;
3959                     }
3960 
3961                     // Step D4: decide whether or not to accept the current value of S.
3962                     if (_available/(_available-x) < y1 * (y2 ^^ (1.0/(_toSelect-1))))
3963                     {
3964                         // If it's not acceptable, we generate a new value of _Vprime
3965                         // and go back to the start of the for (;;) loop.
3966                         _Vprime = newVprime(_toSelect);
3967                     }
3968                     else
3969                     {
3970                         // If it's acceptable we generate a new value of _Vprime
3971                         // based on the remaining number of sample points needed,
3972                         // and return S.
3973                         _Vprime = newVprime(_toSelect-1);
3974                         return s;
3975                     }
3976                 }
3977                 else
3978                 {
3979                     // Return if condition D3 satisfied.
3980                     return s;
3981                 }
3982             }
3983         }
3984         else
3985         {
3986             // If only one sample point remains to be taken ...
3987             return cast(size_t) trunc(_available * _Vprime);
3988         }
3989     }
3990 
3991     private void prime()
3992     {
3993         if (empty)
3994         {
3995             return;
3996         }
3997         assert(_available && _available >= _toSelect);
3998         immutable size_t s = skip();
3999         assert(s + _toSelect <= _available);
4000         static if (hasLength!Range)
4001         {
4002             assert(s + _toSelect <= _input.length);
4003         }
4004         assert(!_input.empty);
4005         _input.popFrontExactly(s);
4006         _index += s;
4007         _available -= s;
4008         assert(_available > 0);
4009     }
4010 }
4011 
4012 /// Ditto
4013 auto randomSample(Range)(Range r, size_t n, size_t total)
4014 if (isInputRange!Range)
4015 {
4016     return RandomSample!(Range, void)(r, n, total);
4017 }
4018 
4019 /// Ditto
4020 auto randomSample(Range)(Range r, size_t n)
4021 if (isInputRange!Range && hasLength!Range)
4022 {
4023     return RandomSample!(Range, void)(r, n, r.length);
4024 }
4025 
4026 /// Ditto
4027 auto randomSample(Range, UniformRNG)(Range r, size_t n, size_t total, auto ref UniformRNG rng)
4028 if (isInputRange!Range && isUniformRNG!UniformRNG)
4029 {
4030     return RandomSample!(Range, UniformRNG)(r, n, total, rng);
4031 }
4032 
4033 /// Ditto
4034 auto randomSample(Range, UniformRNG)(Range r, size_t n, auto ref UniformRNG rng)
4035 if (isInputRange!Range && hasLength!Range && isUniformRNG!UniformRNG)
4036 {
4037     return RandomSample!(Range, UniformRNG)(r, n, r.length, rng);
4038 }
4039 
4040 ///
4041 @safe unittest
4042 {
4043     import std.algorithm.comparison : equal;
4044     import std.range : iota;
4045     auto rnd = MinstdRand0(42);
4046     assert(10.iota.randomSample(3, rnd).equal([7, 8, 9]));
4047 }
4048 
4049 @system unittest
4050 {
4051     // @system because it takes the address of a local
4052     import std.conv : text;
4053     import std.exception;
4054     import std.range;
4055     // For test purposes, an infinite input range
4056     struct TestInputRange
4057     {
4058         private auto r = recurrence!"a[n-1] + 1"(0);
4059         bool empty() @property const pure nothrow { return r.empty; }
4060         auto front() @property pure nothrow { return r.front; }
4061         void popFront() pure nothrow { r.popFront(); }
4062     }
4063     static assert(isInputRange!TestInputRange);
4064     static assert(!isForwardRange!TestInputRange);
4065 
4066     const(int)[] a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];
4067 
4068     foreach (UniformRNG; PseudoRngTypes)
4069     (){ // avoid workaround optimizations for large functions
4070         // https://issues.dlang.org/show_bug.cgi?id=2396
4071         auto rng = UniformRNG(1234);
4072         /* First test the most general case: randomSample of input range, with and
4073          * without a specified random number generator.
4074          */
4075         static assert(isInputRange!(typeof(randomSample(TestInputRange(), 5, 10))));
4076         static assert(isInputRange!(typeof(randomSample(TestInputRange(), 5, 10, rng))));
4077         static assert(!isForwardRange!(typeof(randomSample(TestInputRange(), 5, 10))));
4078         static assert(!isForwardRange!(typeof(randomSample(TestInputRange(), 5, 10, rng))));
4079         // test case with range initialized by direct call to struct
4080         {
4081             auto sample =
4082                 RandomSample!(TestInputRange, UniformRNG)
4083                              (TestInputRange(), 5, 10, UniformRNG(987_654_321));
4084             static assert(isInputRange!(typeof(sample)));
4085             static assert(!isForwardRange!(typeof(sample)));
4086         }
4087 
4088         /* Now test the case of an input range with length.  We ignore the cases
4089          * already covered by the previous tests.
4090          */
4091         static assert(isInputRange!(typeof(randomSample(TestInputRange().takeExactly(10), 5))));
4092         static assert(isInputRange!(typeof(randomSample(TestInputRange().takeExactly(10), 5, rng))));
4093         static assert(!isForwardRange!(typeof(randomSample(TestInputRange().takeExactly(10), 5))));
4094         static assert(!isForwardRange!(typeof(randomSample(TestInputRange().takeExactly(10), 5, rng))));
4095         // test case with range initialized by direct call to struct
4096         {
4097             auto sample =
4098                 RandomSample!(typeof(TestInputRange().takeExactly(10)), UniformRNG)
4099                              (TestInputRange().takeExactly(10), 5, 10, UniformRNG(654_321_987));
4100             static assert(isInputRange!(typeof(sample)));
4101             static assert(!isForwardRange!(typeof(sample)));
4102         }
4103 
4104         // Now test the case of providing a forward range as input.
4105         static assert(!isForwardRange!(typeof(randomSample(a, 5))));
4106         static if (isForwardRange!UniformRNG)
4107         {
4108             static assert(isForwardRange!(typeof(randomSample(a, 5, rng))));
4109             // ... and test with range initialized directly
4110             {
4111                 auto sample =
4112                     RandomSample!(const(int)[], UniformRNG)
4113                                  (a, 5, UniformRNG(321_987_654));
4114                 static assert(isForwardRange!(typeof(sample)));
4115             }
4116         }
4117         else
4118         {
4119             static assert(isInputRange!(typeof(randomSample(a, 5, rng))));
4120             static assert(!isForwardRange!(typeof(randomSample(a, 5, rng))));
4121             // ... and test with range initialized directly
4122             {
4123                 auto sample =
4124                     RandomSample!(const(int)[], UniformRNG)
4125                                  (a, 5, UniformRNG(789_123_456));
4126                 static assert(isInputRange!(typeof(sample)));
4127                 static assert(!isForwardRange!(typeof(sample)));
4128             }
4129         }
4130 
4131         /* Check that randomSample will throw an error if we claim more
4132          * items are available than there actually are, or if we try to
4133          * sample more items than are available. */
4134         assert(collectExceptionMsg(
4135             randomSample(a, 5, 15)
4136         ) == "RandomSample: specified 15 items as available when input contains only 10");
4137         assert(collectExceptionMsg(
4138             randomSample(a, 15)
4139         ) == "RandomSample: cannot sample 15 items when only 10 are available");
4140         assert(collectExceptionMsg(
4141             randomSample(a, 9, 8)
4142         ) == "RandomSample: cannot sample 9 items when only 8 are available");
4143         assert(collectExceptionMsg(
4144             randomSample(TestInputRange(), 12, 11)
4145         ) == "RandomSample: cannot sample 12 items when only 11 are available");
4146 
4147         /* Check that sampling algorithm never accidentally overruns the end of
4148          * the input range.  If input is an InputRange without .length, this
4149          * relies on the user specifying the total number of available items
4150          * correctly.
4151          */
4152         {
4153             uint i = 0;
4154             foreach (e; randomSample(a, a.length))
4155             {
4156                 assert(e == i);
4157                 ++i;
4158             }
4159             assert(i == a.length);
4160 
4161             i = 0;
4162             foreach (e; randomSample(TestInputRange(), 17, 17))
4163             {
4164                 assert(e == i);
4165                 ++i;
4166             }
4167             assert(i == 17);
4168         }
4169 
4170 
4171         // Check length properties of random samples.
4172         assert(randomSample(a, 5).length == 5);
4173         assert(randomSample(a, 5, 10).length == 5);
4174         assert(randomSample(a, 5, rng).length == 5);
4175         assert(randomSample(a, 5, 10, rng).length == 5);
4176         assert(randomSample(TestInputRange(), 5, 10).length == 5);
4177         assert(randomSample(TestInputRange(), 5, 10, rng).length == 5);
4178 
4179         // ... and emptiness!
4180         assert(randomSample(a, 0).empty);
4181         assert(randomSample(a, 0, 5).empty);
4182         assert(randomSample(a, 0, rng).empty);
4183         assert(randomSample(a, 0, 5, rng).empty);
4184         assert(randomSample(TestInputRange(), 0, 10).empty);
4185         assert(randomSample(TestInputRange(), 0, 10, rng).empty);
4186 
4187         /* Test that the (lazy) evaluation of random samples works correctly.
4188          *
4189          * We cover 2 different cases: a sample where the ratio of sample points
4190          * to total points is greater than the threshold for using Algorithm, and
4191          * one where the ratio is small enough (< 1/13) for Algorithm D to be used.
4192          *
4193          * For each, we also cover the case with and without a specified RNG.
4194          */
4195         {
4196             // Small sample/source ratio, no specified RNG.
4197             uint i = 0;
4198             foreach (e; randomSample(randomCover(a), 5))
4199             {
4200                 ++i;
4201             }
4202             assert(i == 5);
4203 
4204             // Small sample/source ratio, specified RNG.
4205             i = 0;
4206             foreach (e; randomSample(randomCover(a), 5, rng))
4207             {
4208                 ++i;
4209             }
4210             assert(i == 5);
4211 
4212             // Large sample/source ratio, no specified RNG.
4213             i = 0;
4214             foreach (e; randomSample(TestInputRange(), 123, 123_456))
4215             {
4216                 ++i;
4217             }
4218             assert(i == 123);
4219 
4220             // Large sample/source ratio, specified RNG.
4221             i = 0;
4222             foreach (e; randomSample(TestInputRange(), 123, 123_456, rng))
4223             {
4224                 ++i;
4225             }
4226             assert(i == 123);
4227 
4228             /* Sample/source ratio large enough to start with Algorithm D,
4229              * small enough to switch to Algorithm A.
4230              */
4231             i = 0;
4232             foreach (e; randomSample(TestInputRange(), 10, 131))
4233             {
4234                 ++i;
4235             }
4236             assert(i == 10);
4237         }
4238 
4239         // Test that the .index property works correctly
4240         {
4241             auto sample1 = randomSample(TestInputRange(), 654, 654_321);
4242             for (; !sample1.empty; sample1.popFront())
4243             {
4244                 assert(sample1.front == sample1.index);
4245             }
4246 
4247             auto sample2 = randomSample(TestInputRange(), 654, 654_321, rng);
4248             for (; !sample2.empty; sample2.popFront())
4249             {
4250                 assert(sample2.front == sample2.index);
4251             }
4252 
4253             /* Check that it also works if .index is called before .front.
4254              * See: https://issues.dlang.org/show_bug.cgi?id=10322
4255              */
4256             auto sample3 = randomSample(TestInputRange(), 654, 654_321);
4257             for (; !sample3.empty; sample3.popFront())
4258             {
4259                 assert(sample3.index == sample3.front);
4260             }
4261 
4262             auto sample4 = randomSample(TestInputRange(), 654, 654_321, rng);
4263             for (; !sample4.empty; sample4.popFront())
4264             {
4265                 assert(sample4.index == sample4.front);
4266             }
4267         }
4268 
4269         /* Test behaviour if .popFront() is called before sample is read.
4270          * This is a rough-and-ready check that the statistical properties
4271          * are in the ballpark -- not a proper validation of statistical
4272          * quality!  This incidentally also checks for reference-type
4273          * initialization bugs, as the foreach () loop will operate on a
4274          * copy of the popFronted (and hence initialized) sample.
4275          */
4276         {
4277             size_t count0, count1, count99;
4278             foreach (_; 0 .. 50_000)
4279             {
4280                 auto sample = randomSample(iota(100), 5, &rng);
4281                 sample.popFront();
4282                 foreach (s; sample)
4283                 {
4284                     if (s == 0)
4285                     {
4286                         ++count0;
4287                     }
4288                     else if (s == 1)
4289                     {
4290                         ++count1;
4291                     }
4292                     else if (s == 99)
4293                     {
4294                         ++count99;
4295                     }
4296                 }
4297             }
4298             /* Statistical assumptions here: this is a sequential sampling process
4299              * so (i) 0 can only be the first sample point, so _can't_ be in the
4300              * remainder of the sample after .popFront() is called. (ii) By similar
4301              * token, 1 can only be in the remainder if it's the 2nd point of the
4302              * whole sample, and hence if 0 was the first; probability of 0 being
4303              * first and 1 second is 5/100 * 4/99 (thank you, Algorithm S:-) and
4304              * so the mean count of 1 should be about 202.  Finally, 99 can only
4305              * be the _last_ sample point to be picked, so its probability of
4306              * inclusion should be independent of the .popFront() and it should
4307              * occur with frequency 5/100, hence its count should be about 5000.
4308              * Unfortunately we have to set quite a high tolerance because with
4309              * sample size small enough for unittests to run in reasonable time,
4310              * the variance can be quite high.
4311              */
4312             assert(count0 == 0);
4313             assert(count1 < 150, text("1: ", count1, " > 150."));
4314             assert(2_200 < count99, text("99: ", count99, " < 2200."));
4315             assert(count99 < 2_800, text("99: ", count99, " > 2800."));
4316         }
4317 
4318         /* Odd corner-cases: RandomSample has 2 constructors that are not called
4319          * by the randomSample() helper functions, but that can be used if the
4320          * constructor is called directly.  These cover the case of the user
4321          * specifying input but not input length.
4322          */
4323         {
4324             auto input1 = TestInputRange().takeExactly(456_789);
4325             static assert(hasLength!(typeof(input1)));
4326             auto sample1 = RandomSample!(typeof(input1), void)(input1, 789);
4327             static assert(isInputRange!(typeof(sample1)));
4328             static assert(!isForwardRange!(typeof(sample1)));
4329             assert(sample1.length == 789);
4330             assert(sample1._available == 456_789);
4331             uint i = 0;
4332             for (; !sample1.empty; sample1.popFront())
4333             {
4334                 assert(sample1.front == sample1.index);
4335                 ++i;
4336             }
4337             assert(i == 789);
4338 
4339             auto input2 = TestInputRange().takeExactly(456_789);
4340             static assert(hasLength!(typeof(input2)));
4341             auto sample2 = RandomSample!(typeof(input2), typeof(rng))(input2, 789, rng);
4342             static assert(isInputRange!(typeof(sample2)));
4343             static assert(!isForwardRange!(typeof(sample2)));
4344             assert(sample2.length == 789);
4345             assert(sample2._available == 456_789);
4346             i = 0;
4347             for (; !sample2.empty; sample2.popFront())
4348             {
4349                 assert(sample2.front == sample2.index);
4350                 ++i;
4351             }
4352             assert(i == 789);
4353         }
4354 
4355         /* Test that the save property works where input is a forward range,
4356          * and RandomSample is using a (forward range) random number generator
4357          * that is not rndGen.
4358          */
4359         static if (isForwardRange!UniformRNG)
4360         {
4361             auto sample1 = randomSample(a, 5, rng);
4362             // https://issues.dlang.org/show_bug.cgi?id=15853
4363             auto sample2 = ((const ref typeof(sample1) a) => a.save)(sample1);
4364             assert(sample1.array() == sample2.array());
4365         }
4366 
4367         // https://issues.dlang.org/show_bug.cgi?id=8314
4368         {
4369             auto sample(RandomGen)(uint seed) { return randomSample(a, 1, RandomGen(seed)).front; }
4370 
4371             // Start from 1 because not all RNGs accept 0 as seed.
4372             immutable fst = sample!UniformRNG(1);
4373             uint n = 1;
4374             while (sample!UniformRNG(++n) == fst && n < n.max) {}
4375             assert(n < n.max);
4376         }
4377     }();
4378 }