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