The OpenD Programming Language

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