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 /**
1776 A "good" seed for initializing random number engines. Initializing
1777 with $(D_PARAM unpredictableSeed) makes engines generate different
1778 random number sequences every run.
1779 
1780 Returns:
1781 A single unsigned integer seed value, different on each successive call
1782 Note:
1783 In general periodically 'reseeding' a PRNG does not improve its quality
1784 and in some cases may harm it. For an extreme example the Mersenne
1785 Twister has `2 ^^ 19937 - 1` distinct states but after `seed(uint)` is
1786 called it can only be in one of `2 ^^ 32` distinct states regardless of
1787 how excellent the source of entropy is.
1788 */
1789 @property uint unpredictableSeed() @trusted nothrow @nogc
1790 {
1791     version (AnyARC4Random)
1792     {
1793         return arc4random();
1794     }
1795     else
1796     {
1797         version (InlineAsm_X86_Any)
1798         {
1799             import core.cpuid : hasRdrand;
1800             if (hasRdrand)
1801             {
1802                 uint result;
1803                 asm @nogc nothrow
1804                 {
1805                     db 0x0f, 0xc7, 0xf0; // rdrand EAX
1806                     jnc LnotUsingRdrand;
1807                     mov result, EAX;
1808                     // Some AMD CPUs shipped with bugs where RDRAND could fail
1809                     // but still set the carry flag to 1. In those cases the
1810                     // output will be -1.
1811                     cmp EAX, 0xffff_ffff;
1812                     jne LusingRdrand;
1813                     // If result was -1 verify RDAND isn't constantly returning -1.
1814                     db 0x0f, 0xc7, 0xf0;
1815                     jnc LusingRdrand;
1816                     cmp EAX, 0xffff_ffff;
1817                     je LnotUsingRdrand;
1818                 }
1819             LusingRdrand:
1820                 return result;
1821             }
1822         LnotUsingRdrand:
1823         }
1824         return cast(uint) fallbackSeed();
1825     }
1826 }
1827 
1828 /// ditto
1829 template unpredictableSeed(UIntType)
1830 if (isUnsigned!UIntType)
1831 {
1832     static if (is(UIntType == uint))
1833         alias unpredictableSeed = .unpredictableSeed;
1834     else static if (!is(Unqual!UIntType == UIntType))
1835         alias unpredictableSeed = .unpredictableSeed!(Unqual!UIntType);
1836     else
1837         /// ditto
1838         @property UIntType unpredictableSeed() @nogc nothrow @trusted
1839         {
1840             version (AnyARC4Random)
1841             {
1842                 static if (UIntType.sizeof <= uint.sizeof)
1843                 {
1844                     return cast(UIntType) arc4random();
1845                 }
1846                 else
1847                 {
1848                     UIntType result = void;
1849                     arc4random_buf(&result, UIntType.sizeof);
1850                     return result;
1851                 }
1852             }
1853             else
1854             {
1855                 version (InlineAsm_X86_Any)
1856                 {
1857                     import core.cpuid : hasRdrand;
1858                     if (hasRdrand)
1859                     {
1860                         static if (UIntType.sizeof <= uint.sizeof)
1861                         {
1862                             uint result;
1863                             asm @nogc nothrow
1864                             {
1865                                 db 0x0f, 0xc7, 0xf0; // rdrand EAX
1866                                 jnc LnotUsingRdrand;
1867                                 mov result, EAX;
1868                                 // Some AMD CPUs shipped with bugs where RDRAND could fail
1869                                 // but still set the carry flag to 1. In those cases the
1870                                 // output will be -1.
1871                                 cmp EAX, 0xffff_ffff;
1872                                 jne LusingRdrand;
1873                                 // If result was -1 verify RDAND isn't constantly returning -1.
1874                                 db 0x0f, 0xc7, 0xf0;
1875                                 jnc LusingRdrand;
1876                                 cmp EAX, 0xffff_ffff;
1877                                 je LnotUsingRdrand;
1878                             }
1879                         LusingRdrand:
1880                             return cast(UIntType) result;
1881                         }
1882                         else version (D_InlineAsm_X86_64)
1883                         {
1884                             ulong result;
1885                             asm @nogc nothrow
1886                             {
1887                                 db 0x48, 0x0f, 0xc7, 0xf0; // rdrand RAX
1888                                 jnc LnotUsingRdrand;
1889                                 mov result, RAX;
1890                                 // Some AMD CPUs shipped with bugs where RDRAND could fail
1891                                 // but still set the carry flag to 1. In those cases the
1892                                 // output will be -1.
1893                                 cmp RAX, 0xffff_ffff_ffff_ffff;
1894                                 jne LusingRdrand;
1895                                 // If result was -1 verify RDAND isn't constantly returning -1.
1896                                 db 0x48, 0x0f, 0xc7, 0xf0;
1897                                 jnc LusingRdrand;
1898                                 cmp RAX, 0xffff_ffff_ffff_ffff;
1899                                 je LnotUsingRdrand;
1900                             }
1901                         LusingRdrand:
1902                             return result;
1903                         }
1904                         else
1905                         {
1906                             uint resultLow, resultHigh;
1907                             asm @nogc nothrow
1908                             {
1909                                 db 0x0f, 0xc7, 0xf0; // rdrand EAX
1910                                 jnc LnotUsingRdrand;
1911                                 mov resultLow, EAX;
1912                                 db 0x0f, 0xc7, 0xf0; // rdrand EAX
1913                                 jnc LnotUsingRdrand;
1914                                 mov resultHigh, EAX;
1915                             }
1916                             if (resultLow != uint.max || resultHigh != uint.max) // Protect against AMD RDRAND bug.
1917                                 return ((cast(ulong) resultHigh) << 32) ^ resultLow;
1918                         }
1919                     }
1920                 LnotUsingRdrand:
1921                 }
1922                 return cast(UIntType) fallbackSeed();
1923             }
1924         }
1925 }
1926 
1927 ///
1928 @safe @nogc unittest
1929 {
1930     auto rnd = Random(unpredictableSeed);
1931     auto n = rnd.front;
1932     static assert(is(typeof(n) == uint));
1933 }
1934 
1935 /**
1936 The "default", "favorite", "suggested" random number generator type on
1937 the current platform. It is an alias for one of the previously-defined
1938 generators. You may want to use it if (1) you need to generate some
1939 nice random numbers, and (2) you don't care for the minutiae of the
1940 method being used.
1941  */
1942 
1943 alias Random = Mt19937;
1944 
1945 @safe @nogc unittest
1946 {
1947     static assert(isUniformRNG!Random);
1948     static assert(isUniformRNG!(Random, uint));
1949     static assert(isSeedable!Random);
1950     static assert(isSeedable!(Random, uint));
1951 }
1952 
1953 /**
1954 Global random number generator used by various functions in this
1955 module whenever no generator is specified. It is allocated per-thread
1956 and initialized to an unpredictable value for each thread.
1957 
1958 Returns:
1959 A singleton instance of the default random number generator
1960  */
1961 @property ref Random rndGen() @safe nothrow @nogc
1962 {
1963     static Random result;
1964     static bool initialized;
1965     if (!initialized)
1966     {
1967         static if (isSeedable!(Random, ulong))
1968             result.seed(unpredictableSeed!ulong); // Avoid unnecessary copy.
1969         else static if (is(Random : MersenneTwisterEngine!Params, Params...))
1970             initMTEngine(result);
1971         else static if (isSeedable!(Random, uint))
1972             result.seed(unpredictableSeed!uint); // Avoid unnecessary copy.
1973         else
1974             result = Random(unpredictableSeed);
1975         initialized = true;
1976     }
1977     return result;
1978 }
1979 
1980 ///
1981 @safe nothrow @nogc unittest
1982 {
1983     import std.algorithm.iteration : sum;
1984     import std.range : take;
1985     auto rnd = rndGen;
1986     assert(rnd.take(3).sum > 0);
1987 }
1988 
1989 /+
1990 Initialize a 32-bit MersenneTwisterEngine from 64 bits of entropy.
1991 This is private and accepts no seed as a parameter, freeing the internal
1992 implementaton from any need for stability across releases.
1993 +/
1994 private void initMTEngine(MTEngine)(scope ref MTEngine mt)
1995 if (is(MTEngine : MersenneTwisterEngine!Params, Params...))
1996 {
1997     pragma(inline, false); // Called no more than once per thread by rndGen.
1998     ulong seed = unpredictableSeed!ulong;
1999     static if (is(typeof(mt.seed(seed))))
2000     {
2001         mt.seed(seed);
2002     }
2003     else
2004     {
2005         alias UIntType = typeof(mt.front());
2006         if (seed == 0) seed = -1; // Any number but 0 is fine.
2007         uint s0 = cast(uint) seed;
2008         uint s1 = cast(uint) (seed >> 32);
2009         foreach (ref e; mt.state.data)
2010         {
2011             //http://xoshiro.di.unimi.it/xoroshiro64starstar.c
2012             const tmp = s0 * 0x9E3779BB;
2013             e = ((tmp << 5) | (tmp >> (32 - 5))) * 5;
2014             static if (MTEngine.max != UIntType.max) { e &= MTEngine.max; }
2015 
2016             const tmp1 = s0 ^ s1;
2017             s0 = ((s0 << 26) | (s0 >> (32 - 26))) ^ tmp1 ^ (tmp1 << 9);
2018             s1 = (tmp1 << 13) | (tmp1 >> (32 - 13));
2019         }
2020 
2021         mt.state.index = mt.state.data.length - 1;
2022         // double popFront() to guarantee both `mt.state.z`
2023         // and `mt.state.front` are derived from the newly
2024         // set values in `mt.state.data`.
2025         mt.popFront();
2026         mt.popFront();
2027     }
2028 }
2029 
2030 /**
2031 Generates a number between `a` and `b`. The `boundaries`
2032 parameter controls the shape of the interval (open vs. closed on
2033 either side). Valid values for `boundaries` are `"[]"`, $(D
2034 "$(LPAREN)]"), `"[$(RPAREN)"`, and `"()"`. The default interval
2035 is closed to the left and open to the right. The version that does not
2036 take `urng` uses the default generator `rndGen`.
2037 
2038 Params:
2039     a = lower bound of the _uniform distribution
2040     b = upper bound of the _uniform distribution
2041     urng = (optional) random number generator to use;
2042            if not specified, defaults to `rndGen`
2043 
2044 Returns:
2045     A single random variate drawn from the _uniform distribution
2046     between `a` and `b`, whose type is the common type of
2047     these parameters
2048  */
2049 auto uniform(string boundaries = "[)", T1, T2)
2050 (T1 a, T2 b)
2051 if (!is(CommonType!(T1, T2) == void))
2052 {
2053     return uniform!(boundaries, T1, T2, Random)(a, b, rndGen);
2054 }
2055 
2056 ///
2057 @safe unittest
2058 {
2059     auto rnd = Random(unpredictableSeed);
2060 
2061     // Generate an integer in [0, 1023]
2062     auto a = uniform(0, 1024, rnd);
2063     assert(0 <= a && a < 1024);
2064 
2065     // Generate a float in [0, 1)
2066     auto b = uniform(0.0f, 1.0f, rnd);
2067     assert(0 <= b && b < 1);
2068 
2069     // Generate a float in [0, 1]
2070     b = uniform!"[]"(0.0f, 1.0f, rnd);
2071     assert(0 <= b && b <= 1);
2072 
2073     // Generate a float in (0, 1)
2074     b = uniform!"()"(0.0f, 1.0f, rnd);
2075     assert(0 < b && b < 1);
2076 }
2077 
2078 /// Create an array of random numbers using range functions and UFCS
2079 @safe unittest
2080 {
2081     import std.array : array;
2082     import std.range : generate, takeExactly;
2083 
2084     int[] arr = generate!(() => uniform(0, 100)).takeExactly(10).array;
2085     assert(arr.length == 10);
2086     assert(arr[0] >= 0 && arr[0] < 100);
2087 }
2088 
2089 @safe unittest
2090 {
2091     MinstdRand0 gen;
2092     foreach (i; 0 .. 20)
2093     {
2094         auto x = uniform(0.0, 15.0, gen);
2095         assert(0 <= x && x < 15);
2096     }
2097     foreach (i; 0 .. 20)
2098     {
2099         auto x = uniform!"[]"('a', 'z', gen);
2100         assert('a' <= x && x <= 'z');
2101     }
2102 
2103     foreach (i; 0 .. 20)
2104     {
2105         auto x = uniform('a', 'z', gen);
2106         assert('a' <= x && x < 'z');
2107     }
2108 
2109     foreach (i; 0 .. 20)
2110     {
2111         immutable ubyte a = 0;
2112             immutable ubyte b = 15;
2113         auto x = uniform(a, b, gen);
2114             assert(a <= x && x < b);
2115     }
2116 }
2117 
2118 // Implementation of uniform for floating-point types
2119 /// ditto
2120 auto uniform(string boundaries = "[)",
2121         T1, T2, UniformRandomNumberGenerator)
2122 (T1 a, T2 b, ref UniformRandomNumberGenerator urng)
2123 if (isFloatingPoint!(CommonType!(T1, T2)) && isUniformRNG!UniformRandomNumberGenerator)
2124 {
2125     import std.conv : text;
2126     import std.exception : enforce;
2127     alias NumberType = Unqual!(CommonType!(T1, T2));
2128     static if (boundaries[0] == '(')
2129     {
2130         import std.math.operations : nextafter;
2131         NumberType _a = nextafter(cast(NumberType) a, NumberType.infinity);
2132     }
2133     else
2134     {
2135         NumberType _a = a;
2136     }
2137     static if (boundaries[1] == ')')
2138     {
2139         import std.math.operations : nextafter;
2140         NumberType _b = nextafter(cast(NumberType) b, -NumberType.infinity);
2141     }
2142     else
2143     {
2144         NumberType _b = b;
2145     }
2146     enforce(_a <= _b,
2147             text("std.random.uniform(): invalid bounding interval ",
2148                     boundaries[0], a, ", ", b, boundaries[1]));
2149     NumberType result =
2150         _a + (_b - _a) * cast(NumberType) (urng.front - urng.min)
2151         / (urng.max - urng.min);
2152     urng.popFront();
2153     return result;
2154 }
2155 
2156 // Implementation of uniform for integral types
2157 /+ Description of algorithm and suggestion of correctness:
2158 
2159 The modulus operator maps an integer to a small, finite space. For instance, `x
2160 % 3` will map whatever x is into the range [0 .. 3). 0 maps to 0, 1 maps to 1, 2
2161 maps to 2, 3 maps to 0, and so on infinitely. As long as the integer is
2162 uniformly chosen from the infinite space of all non-negative integers then `x %
2163 3` will uniformly fall into that range.
2164 
2165 (Non-negative is important in this case because some definitions of modulus,
2166 namely the one used in computers generally, map negative numbers differently to
2167 (-3 .. 0]. `uniform` does not use negative number modulus, thus we can safely
2168 ignore that fact.)
2169 
2170 The issue with computers is that integers have a finite space they must fit in,
2171 and our uniformly chosen random number is picked in that finite space. So, that
2172 method is not sufficient. You can look at it as the integer space being divided
2173 into "buckets" and every bucket after the first bucket maps directly into that
2174 first bucket. `[0, 1, 2]`, `[3, 4, 5]`, ... When integers are finite, then the
2175 last bucket has the chance to be "incomplete": `[uint.max - 3, uint.max - 2,
2176 uint.max - 1]`, `[uint.max]` ... (the last bucket only has 1!). The issue here
2177 is that _every_ bucket maps _completely_ to the first bucket except for that
2178 last one. The last one doesn't have corresponding mappings to 1 or 2, in this
2179 case, which makes it unfair.
2180 
2181 So, the answer is to simply "reroll" if you're in that last bucket, since it's
2182 the only unfair one. Eventually you'll roll into a fair bucket. Simply, instead
2183 of the meaning of the last bucket being "maps to `[0]`", it changes to "maps to
2184 `[0, 1, 2]`", which is precisely what we want.
2185 
2186 To generalize, `upperDist` represents the size of our buckets (and, thus, the
2187 exclusive upper bound for our desired uniform number). `rnum` is a uniformly
2188 random number picked from the space of integers that a computer can hold (we'll
2189 say `UpperType` represents that type).
2190 
2191 We'll first try to do the mapping into the first bucket by doing `offset = rnum
2192 % upperDist`. We can figure out the position of the front of the bucket we're in
2193 by `bucketFront = rnum - offset`.
2194 
2195 If we start at `UpperType.max` and walk backwards `upperDist - 1` spaces, then
2196 the space we land on is the last acceptable position where a full bucket can
2197 fit:
2198 
2199 ---
2200    bucketFront     UpperType.max
2201       v                 v
2202 [..., 0, 1, 2, ..., upperDist - 1]
2203       ^~~ upperDist - 1 ~~^
2204 ---
2205 
2206 If the bucket starts any later, then it must have lost at least one number and
2207 at least that number won't be represented fairly.
2208 
2209 ---
2210                 bucketFront     UpperType.max
2211                      v                v
2212 [..., upperDist - 1, 0, 1, 2, ..., upperDist - 2]
2213           ^~~~~~~~ upperDist - 1 ~~~~~~~^
2214 ---
2215 
2216 Hence, our condition to reroll is
2217 `bucketFront > (UpperType.max - (upperDist - 1))`
2218 +/
2219 /// ditto
2220 auto uniform(string boundaries = "[)", T1, T2, RandomGen)
2221 (T1 a, T2 b, ref RandomGen rng)
2222 if ((isIntegral!(CommonType!(T1, T2)) || isSomeChar!(CommonType!(T1, T2))) &&
2223      isUniformRNG!RandomGen)
2224 {
2225     import std.conv : text, unsigned;
2226     import std.exception : enforce;
2227     alias ResultType = Unqual!(CommonType!(T1, T2));
2228     static if (boundaries[0] == '(')
2229     {
2230         enforce(a < ResultType.max,
2231                 text("std.random.uniform(): invalid left bound ", a));
2232         ResultType lower = cast(ResultType) (a + 1);
2233     }
2234     else
2235     {
2236         ResultType lower = a;
2237     }
2238 
2239     static if (boundaries[1] == ']')
2240     {
2241         enforce(lower <= b,
2242                 text("std.random.uniform(): invalid bounding interval ",
2243                         boundaries[0], a, ", ", b, boundaries[1]));
2244         /* Cannot use this next optimization with dchar, as dchar
2245          * only partially uses its full bit range
2246          */
2247         static if (!is(ResultType == dchar))
2248         {
2249             if (b == ResultType.max && lower == ResultType.min)
2250             {
2251                 // Special case - all bits are occupied
2252                 return std.random.uniform!ResultType(rng);
2253             }
2254         }
2255         auto upperDist = unsigned(b - lower) + 1u;
2256     }
2257     else
2258     {
2259         enforce(lower < b,
2260                 text("std.random.uniform(): invalid bounding interval ",
2261                         boundaries[0], a, ", ", b, boundaries[1]));
2262         auto upperDist = unsigned(b - lower);
2263     }
2264 
2265     assert(upperDist != 0);
2266 
2267     alias UpperType = typeof(upperDist);
2268     static assert(UpperType.min == 0);
2269 
2270     UpperType offset, rnum, bucketFront;
2271     do
2272     {
2273         rnum = uniform!UpperType(rng);
2274         offset = rnum % upperDist;
2275         bucketFront = rnum - offset;
2276     } // while we're in an unfair bucket...
2277     while (bucketFront > (UpperType.max - (upperDist - 1)));
2278 
2279     return cast(ResultType)(lower + offset);
2280 }
2281 
2282 ///
2283 @safe unittest
2284 {
2285     import std.conv : to;
2286     import std.meta : AliasSeq;
2287     import std.range.primitives : isForwardRange;
2288     import std.traits : isIntegral, isSomeChar;
2289 
2290     auto gen = Mt19937(123_456_789);
2291     static assert(isForwardRange!(typeof(gen)));
2292 
2293     auto a = uniform(0, 1024, gen);
2294     assert(0 <= a && a <= 1024);
2295     auto b = uniform(0.0f, 1.0f, gen);
2296     assert(0 <= b && b < 1, to!string(b));
2297     auto c = uniform(0.0, 1.0);
2298     assert(0 <= c && c < 1);
2299 
2300     static foreach (T; AliasSeq!(char, wchar, dchar, byte, ubyte, short, ushort,
2301                           int, uint, long, ulong, float, double, real))
2302     {{
2303         T lo = 0, hi = 100;
2304 
2305         // Try tests with each of the possible bounds
2306         {
2307             T init = uniform(lo, hi);
2308             size_t i = 50;
2309             while (--i && uniform(lo, hi) == init) {}
2310             assert(i > 0);
2311         }
2312         {
2313             T init = uniform!"[)"(lo, hi);
2314             size_t i = 50;
2315             while (--i && uniform(lo, hi) == init) {}
2316             assert(i > 0);
2317         }
2318         {
2319             T init = uniform!"(]"(lo, hi);
2320             size_t i = 50;
2321             while (--i && uniform(lo, hi) == init) {}
2322             assert(i > 0);
2323         }
2324         {
2325             T init = uniform!"()"(lo, hi);
2326             size_t i = 50;
2327             while (--i && uniform(lo, hi) == init) {}
2328             assert(i > 0);
2329         }
2330         {
2331             T init = uniform!"[]"(lo, hi);
2332             size_t i = 50;
2333             while (--i && uniform(lo, hi) == init) {}
2334             assert(i > 0);
2335         }
2336 
2337         /* Test case with closed boundaries covering whole range
2338          * of integral type
2339          */
2340         static if (isIntegral!T || isSomeChar!T)
2341         {
2342             foreach (immutable _; 0 .. 100)
2343             {
2344                 auto u = uniform!"[]"(T.min, T.max);
2345                 static assert(is(typeof(u) == T));
2346                 assert(T.min <= u, "Lower bound violation for uniform!\"[]\" with " ~ T.stringof);
2347                 assert(u <= T.max, "Upper bound violation for uniform!\"[]\" with " ~ T.stringof);
2348             }
2349         }
2350     }}
2351 
2352     auto reproRng = Xorshift(239842);
2353 
2354     static foreach (T; AliasSeq!(char, wchar, dchar, byte, ubyte, short,
2355                           ushort, int, uint, long, ulong))
2356     {{
2357         T lo = T.min + 10, hi = T.max - 10;
2358         T init = uniform(lo, hi, reproRng);
2359         size_t i = 50;
2360         while (--i && uniform(lo, hi, reproRng) == init) {}
2361         assert(i > 0);
2362     }}
2363 
2364     {
2365         bool sawLB = false, sawUB = false;
2366         foreach (i; 0 .. 50)
2367         {
2368             auto x = uniform!"[]"('a', 'd', reproRng);
2369             if (x == 'a') sawLB = true;
2370             if (x == 'd') sawUB = true;
2371             assert('a' <= x && x <= 'd');
2372         }
2373         assert(sawLB && sawUB);
2374     }
2375 
2376     {
2377         bool sawLB = false, sawUB = false;
2378         foreach (i; 0 .. 50)
2379         {
2380             auto x = uniform('a', 'd', reproRng);
2381             if (x == 'a') sawLB = true;
2382             if (x == 'c') sawUB = true;
2383             assert('a' <= x && x < 'd');
2384         }
2385         assert(sawLB && sawUB);
2386     }
2387 
2388     {
2389         bool sawLB = false, sawUB = false;
2390         foreach (i; 0 .. 50)
2391         {
2392             immutable int lo = -2, hi = 2;
2393             auto x = uniform!"()"(lo, hi, reproRng);
2394             if (x == (lo+1)) sawLB = true;
2395             if (x == (hi-1)) sawUB = true;
2396             assert(lo < x && x < hi);
2397         }
2398         assert(sawLB && sawUB);
2399     }
2400 
2401     {
2402         bool sawLB = false, sawUB = false;
2403         foreach (i; 0 .. 50)
2404         {
2405             immutable ubyte lo = 0, hi = 5;
2406             auto x = uniform(lo, hi, reproRng);
2407             if (x == lo) sawLB = true;
2408             if (x == (hi-1)) sawUB = true;
2409             assert(lo <= x && x < hi);
2410         }
2411         assert(sawLB && sawUB);
2412     }
2413 
2414     {
2415         foreach (i; 0 .. 30)
2416         {
2417             assert(i == uniform(i, i+1, reproRng));
2418         }
2419     }
2420 }
2421 
2422 /+
2423 Generates an unsigned integer in the half-open range `[0, k)`.
2424 Non-public because we locally guarantee `k > 0`.
2425 
2426 Params:
2427     k = unsigned exclusive upper bound; caller guarantees this is non-zero
2428     rng = random number generator to use
2429 
2430 Returns:
2431     Pseudo-random unsigned integer strictly less than `k`.
2432 +/
2433 private UInt _uniformIndex(UniformRNG, UInt = size_t)(const UInt k, ref UniformRNG rng)
2434 if (isUnsigned!UInt && isUniformRNG!UniformRNG)
2435 {
2436     alias ResultType = UInt;
2437     alias UpperType = Unsigned!(typeof(k - 0));
2438     alias upperDist = k;
2439 
2440     assert(upperDist != 0);
2441 
2442     // For backwards compatibility use same algorithm as uniform(0, k, rng).
2443     UpperType offset, rnum, bucketFront;
2444     do
2445     {
2446         rnum = uniform!UpperType(rng);
2447         offset = rnum % upperDist;
2448         bucketFront = rnum - offset;
2449     } // while we're in an unfair bucket...
2450     while (bucketFront > (UpperType.max - (upperDist - 1)));
2451 
2452     return cast(ResultType) offset;
2453 }
2454 
2455 pure @safe unittest
2456 {
2457     // For backwards compatibility check that _uniformIndex(k, rng)
2458     // has the same result as uniform(0, k, rng).
2459     auto rng1 = Xorshift(123_456_789);
2460     auto rng2 = rng1.save();
2461     const size_t k = (1U << 31) - 1;
2462     assert(_uniformIndex(k, rng1) == uniform(0, k, rng2));
2463 }
2464 
2465 /**
2466 Generates a uniformly-distributed number in the range $(D [T.min,
2467 T.max]) for any integral or character type `T`. If no random
2468 number generator is passed, uses the default `rndGen`.
2469 
2470 If an `enum` is used as type, the random variate is drawn with
2471 equal probability from any of the possible values of the enum `E`.
2472 
2473 Params:
2474     urng = (optional) random number generator to use;
2475            if not specified, defaults to `rndGen`
2476 
2477 Returns:
2478     Random variate drawn from the _uniform distribution across all
2479     possible values of the integral, character or enum type `T`.
2480  */
2481 auto uniform(T, UniformRandomNumberGenerator)
2482 (ref UniformRandomNumberGenerator urng)
2483 if (!is(T == enum) && (isIntegral!T || isSomeChar!T) && isUniformRNG!UniformRandomNumberGenerator)
2484 {
2485     /* dchar does not use its full bit range, so we must
2486      * revert to the uniform with specified bounds
2487      */
2488     static if (is(immutable T == immutable dchar))
2489     {
2490         return uniform!"[]"(T.min, T.max, urng);
2491     }
2492     else
2493     {
2494         auto r = urng.front;
2495         urng.popFront();
2496         static if (T.sizeof <= r.sizeof)
2497         {
2498             return cast(T) r;
2499         }
2500         else
2501         {
2502             static assert(T.sizeof == 8 && r.sizeof == 4);
2503             T r1 = urng.front | (cast(T) r << 32);
2504             urng.popFront();
2505             return r1;
2506         }
2507     }
2508 }
2509 
2510 /// Ditto
2511 auto uniform(T)()
2512 if (!is(T == enum) && (isIntegral!T || isSomeChar!T))
2513 {
2514     return uniform!T(rndGen);
2515 }
2516 
2517 ///
2518 @safe unittest
2519 {
2520     auto rnd = MinstdRand0(42);
2521 
2522     assert(rnd.uniform!ubyte == 102);
2523     assert(rnd.uniform!ulong == 4838462006927449017);
2524 
2525     enum Fruit { apple, mango, pear }
2526     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
2527     assert(rnd.uniform!Fruit == Fruit.mango);
2528 }
2529 
2530 @safe unittest
2531 {
2532     // https://issues.dlang.org/show_bug.cgi?id=21383
2533     auto rng1 = Xorshift32(123456789);
2534     auto rng2 = rng1.save;
2535     assert(rng1.uniform!dchar == rng2.uniform!dchar);
2536     // https://issues.dlang.org/show_bug.cgi?id=21384
2537     assert(rng1.uniform!(const shared dchar) <= dchar.max);
2538     // https://issues.dlang.org/show_bug.cgi?id=8671
2539     double t8671 = 1.0 - uniform(0.0, 1.0);
2540 }
2541 
2542 @safe unittest
2543 {
2544     static foreach (T; std.meta.AliasSeq!(char, wchar, dchar, byte, ubyte, short, ushort,
2545                           int, uint, long, ulong))
2546     {{
2547         T init = uniform!T();
2548         size_t i = 50;
2549         while (--i && uniform!T() == init) {}
2550         assert(i > 0);
2551 
2552         foreach (immutable _; 0 .. 100)
2553         {
2554             auto u = uniform!T();
2555             static assert(is(typeof(u) == T));
2556             assert(T.min <= u, "Lower bound violation for uniform!" ~ T.stringof);
2557             assert(u <= T.max, "Upper bound violation for uniform!" ~ T.stringof);
2558         }
2559     }}
2560 }
2561 
2562 /// ditto
2563 auto uniform(E, UniformRandomNumberGenerator)
2564 (ref UniformRandomNumberGenerator urng)
2565 if (is(E == enum) && isUniformRNG!UniformRandomNumberGenerator)
2566 {
2567     static immutable E[EnumMembers!E.length] members = [EnumMembers!E];
2568     return members[std.random.uniform(0, members.length, urng)];
2569 }
2570 
2571 /// Ditto
2572 auto uniform(E)()
2573 if (is(E == enum))
2574 {
2575     return uniform!E(rndGen);
2576 }
2577 
2578 @safe unittest
2579 {
2580     enum Fruit { Apple = 12, Mango = 29, Pear = 72 }
2581     foreach (_; 0 .. 100)
2582     {
2583         foreach (f; [uniform!Fruit(), rndGen.uniform!Fruit()])
2584         {
2585             assert(f == Fruit.Apple || f == Fruit.Mango || f == Fruit.Pear);
2586         }
2587     }
2588 }
2589 
2590 /**
2591  * Generates a uniformly-distributed floating point number of type
2592  * `T` in the range [0, 1$(RPAREN).  If no random number generator is
2593  * specified, the default RNG `rndGen` will be used as the source
2594  * of randomness.
2595  *
2596  * `uniform01` offers a faster generation of random variates than
2597  * the equivalent $(D uniform!"[$(RPAREN)"(0.0, 1.0)) and so may be preferred
2598  * for some applications.
2599  *
2600  * Params:
2601  *     rng = (optional) random number generator to use;
2602  *           if not specified, defaults to `rndGen`
2603  *
2604  * Returns:
2605  *     Floating-point random variate of type `T` drawn from the _uniform
2606  *     distribution across the half-open interval [0, 1$(RPAREN).
2607  *
2608  */
2609 T uniform01(T = double)()
2610 if (isFloatingPoint!T)
2611 {
2612     return uniform01!T(rndGen);
2613 }
2614 
2615 /// ditto
2616 T uniform01(T = double, UniformRNG)(ref UniformRNG rng)
2617 if (isFloatingPoint!T && isUniformRNG!UniformRNG)
2618 out (result)
2619 {
2620     assert(0 <= result);
2621     assert(result < 1);
2622 }
2623 do
2624 {
2625     alias R = typeof(rng.front);
2626     static if (isIntegral!R)
2627     {
2628         enum T factor = 1 / (T(1) + rng.max - rng.min);
2629     }
2630     else static if (isFloatingPoint!R)
2631     {
2632         enum T factor = 1 / (rng.max - rng.min);
2633     }
2634     else
2635     {
2636         static assert(false);
2637     }
2638 
2639     while (true)
2640     {
2641         immutable T u = (rng.front - rng.min) * factor;
2642         rng.popFront();
2643 
2644         static if (isIntegral!R && T.mant_dig >= (8 * R.sizeof))
2645         {
2646             /* If RNG variates are integral and T has enough precision to hold
2647              * R without loss, we're guaranteed by the definition of factor
2648              * that precisely u < 1.
2649              */
2650             return u;
2651         }
2652         else
2653         {
2654             /* Otherwise we have to check whether u is beyond the assumed range
2655              * because of the loss of precision, or for another reason, a
2656              * floating-point RNG can return a variate that is exactly equal to
2657              * its maximum.
2658              */
2659             if (u < 1)
2660             {
2661                 return u;
2662             }
2663         }
2664     }
2665 
2666     // Shouldn't ever get here.
2667     assert(false);
2668 }
2669 
2670 ///
2671 @safe @nogc unittest
2672 {
2673     import std.math.operations : feqrel;
2674 
2675     auto rnd = MinstdRand0(42);
2676 
2677     // Generate random numbers in the range in the range [0, 1)
2678     auto u1 = uniform01(rnd);
2679     assert(u1 >= 0 && u1 < 1);
2680 
2681     auto u2 = rnd.uniform01!float;
2682     assert(u2 >= 0 && u2 < 1);
2683 
2684     // Confirm that the random values with the initial seed 42 are 0.000328707 and 0.524587
2685     assert(u1.feqrel(0.000328707) > 20);
2686     assert(u2.feqrel(0.524587) > 20);
2687 }
2688 
2689 @safe @nogc unittest
2690 {
2691     import std.meta;
2692     static foreach (UniformRNG; PseudoRngTypes)
2693     {{
2694 
2695         static foreach (T; std.meta.AliasSeq!(float, double, real))
2696         {{
2697             UniformRNG rng = UniformRNG(123_456_789);
2698 
2699             auto a = uniform01();
2700             assert(is(typeof(a) == double));
2701             assert(0 <= a && a < 1);
2702 
2703             auto b = uniform01(rng);
2704             assert(is(typeof(a) == double));
2705             assert(0 <= b && b < 1);
2706 
2707             auto c = uniform01!T();
2708             assert(is(typeof(c) == T));
2709             assert(0 <= c && c < 1);
2710 
2711             auto d = uniform01!T(rng);
2712             assert(is(typeof(d) == T));
2713             assert(0 <= d && d < 1);
2714 
2715             T init = uniform01!T(rng);
2716             size_t i = 50;
2717             while (--i && uniform01!T(rng) == init) {}
2718             assert(i > 0);
2719             assert(i < 50);
2720         }}
2721     }}
2722 }
2723 
2724 /**
2725 Generates a uniform probability distribution of size `n`, i.e., an
2726 array of size `n` of positive numbers of type `F` that sum to
2727 `1`. If `useThis` is provided, it is used as storage.
2728  */
2729 F[] uniformDistribution(F = double)(size_t n, F[] useThis = null)
2730 if (isFloatingPoint!F)
2731 {
2732     import std.numeric : normalize;
2733     useThis.length = n;
2734     foreach (ref e; useThis)
2735     {
2736         e = uniform(0.0, 1);
2737     }
2738     normalize(useThis);
2739     return useThis;
2740 }
2741 
2742 ///
2743 @safe unittest
2744 {
2745     import std.algorithm.iteration : reduce;
2746     import std.math.operations : isClose;
2747 
2748     auto a = uniformDistribution(5);
2749     assert(a.length == 5);
2750     assert(isClose(reduce!"a + b"(a), 1));
2751 
2752     a = uniformDistribution(10, a);
2753     assert(a.length == 10);
2754     assert(isClose(reduce!"a + b"(a), 1));
2755 }
2756 
2757 /**
2758 Returns a random, uniformly chosen, element `e` from the supplied
2759 $(D Range range). If no random number generator is passed, the default
2760 `rndGen` is used.
2761 
2762 Params:
2763     range = a random access range that has the `length` property defined
2764     urng = (optional) random number generator to use;
2765            if not specified, defaults to `rndGen`
2766 
2767 Returns:
2768     A single random element drawn from the `range`. If it can, it will
2769     return a `ref` to the $(D range element), otherwise it will return
2770     a copy.
2771  */
2772 auto ref choice(Range, RandomGen = Random)(Range range, ref RandomGen urng)
2773 if (isRandomAccessRange!Range && hasLength!Range && isUniformRNG!RandomGen)
2774 {
2775     assert(range.length > 0,
2776            __PRETTY_FUNCTION__ ~ ": invalid Range supplied. Range cannot be empty");
2777 
2778     return range[uniform(size_t(0), $, urng)];
2779 }
2780 
2781 /// ditto
2782 auto ref choice(Range)(Range range)
2783 {
2784     return choice(range, rndGen);
2785 }
2786 
2787 /// ditto
2788 auto ref choice(Range, RandomGen = Random)(ref Range range, ref RandomGen urng)
2789 if (isRandomAccessRange!Range && hasLength!Range && isUniformRNG!RandomGen)
2790 {
2791     assert(range.length > 0,
2792            __PRETTY_FUNCTION__ ~ ": invalid Range supplied. Range cannot be empty");
2793     return range[uniform(size_t(0), $, urng)];
2794 }
2795 
2796 /// ditto
2797 auto ref choice(Range)(ref Range range)
2798 {
2799     return choice(range, rndGen);
2800 }
2801 
2802 ///
2803 @safe unittest
2804 {
2805     auto rnd = MinstdRand0(42);
2806 
2807     auto elem  = [1, 2, 3, 4, 5].choice(rnd);
2808     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
2809     assert(elem == 3);
2810 }
2811 
2812 @safe unittest
2813 {
2814     import std.algorithm.searching : canFind;
2815 
2816     static class MyTestClass
2817     {
2818         int x;
2819 
2820         this(int x)
2821         {
2822             this.x = x;
2823         }
2824     }
2825 
2826     MyTestClass[] testClass;
2827     foreach (i; 0 .. 5)
2828     {
2829         testClass ~= new MyTestClass(i);
2830     }
2831 
2832     auto elem = choice(testClass);
2833 
2834     assert(canFind!((ref MyTestClass a, ref MyTestClass b) => a.x == b.x)(testClass, elem),
2835            "Choice did not return a valid element from the given Range");
2836 }
2837 
2838 @system unittest
2839 {
2840     import std.algorithm.iteration : map;
2841     import std.algorithm.searching : canFind;
2842 
2843     auto array = [1, 2, 3, 4, 5];
2844     auto elemAddr = &choice(array);
2845 
2846     assert(array.map!((ref e) => &e).canFind(elemAddr),
2847            "Choice did not return a ref to an element from the given Range");
2848     assert(array.canFind(*(cast(int *)(elemAddr))),
2849            "Choice did not return a valid element from the given Range");
2850 }
2851 
2852 @safe unittest // https://issues.dlang.org/show_bug.cgi?id=18631
2853 {
2854     auto rng = MinstdRand0(42);
2855     const a = [0,1,2];
2856     const(int[]) b = [0, 1, 2];
2857     auto x = choice(a);
2858     auto y = choice(b);
2859     auto z = choice(cast(const)[1, 2, 3]);
2860     auto x1 = choice(a, rng);
2861     auto y1 = choice(b, rng);
2862     auto z1 = choice(cast(const)[1, 2, 3], rng);
2863 }
2864 
2865 @safe unittest // Ref range (https://issues.dlang.org/show_bug.cgi?id=18631 PR)
2866 {
2867     struct TestRange
2868     {
2869         int x;
2870         ref int front() return {return x;}
2871         ref int back() return {return x;}
2872         void popFront() {}
2873         void popBack() {}
2874         bool empty = false;
2875         TestRange save() {return this;}
2876         size_t length = 10;
2877         alias opDollar = length;
2878         ref int opIndex(size_t i) return {return x;}
2879     }
2880 
2881     TestRange r = TestRange(10);
2882     int* s = &choice(r);
2883 }
2884 
2885 /**
2886 Shuffles elements of `r` using `gen` as a shuffler. `r` must be
2887 a random-access range with length.  If no RNG is specified, `rndGen`
2888 will be used.
2889 
2890 Params:
2891     r = random-access range whose elements are to be shuffled
2892     gen = (optional) random number generator to use; if not
2893           specified, defaults to `rndGen`
2894 Returns:
2895     The shuffled random-access range.
2896 */
2897 
2898 Range randomShuffle(Range, RandomGen)(Range r, ref RandomGen gen)
2899 if (isRandomAccessRange!Range && isUniformRNG!RandomGen)
2900 {
2901     import std.algorithm.mutation : swapAt;
2902     const n = r.length;
2903     foreach (i; 0 .. n)
2904     {
2905         r.swapAt(i, i + _uniformIndex(n - i, gen));
2906     }
2907     return r;
2908 }
2909 
2910 /// ditto
2911 Range randomShuffle(Range)(Range r)
2912 if (isRandomAccessRange!Range)
2913 {
2914     return randomShuffle(r, rndGen);
2915 }
2916 
2917 ///
2918 @safe unittest
2919 {
2920     auto rnd = MinstdRand0(42);
2921 
2922     auto arr = [1, 2, 3, 4, 5].randomShuffle(rnd);
2923     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
2924     assert(arr == [3, 5, 2, 4, 1]);
2925 }
2926 
2927 @safe unittest
2928 {
2929     int[10] sa = void;
2930     int[10] sb = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
2931     import std.algorithm.sorting : sort;
2932     foreach (RandomGen; PseudoRngTypes)
2933     {
2934         sa[] = sb[];
2935         auto a = sa[];
2936         auto b = sb[];
2937         auto gen = RandomGen(123_456_789);
2938         randomShuffle(a, gen);
2939         sort(a);
2940         assert(a == b);
2941         randomShuffle(a);
2942         sort(a);
2943         assert(a == b);
2944     }
2945     // For backwards compatibility verify randomShuffle(r, gen)
2946     // is equivalent to partialShuffle(r, 0, r.length, gen).
2947     auto gen1 = Xorshift(123_456_789);
2948     auto gen2 = gen1.save();
2949     sa[] = sb[];
2950     // @nogc std.random.randomShuffle.
2951     // https://issues.dlang.org/show_bug.cgi?id=19156
2952     () @nogc nothrow pure { randomShuffle(sa[], gen1); }();
2953     partialShuffle(sb[], sb.length, gen2);
2954     assert(sa[] == sb[]);
2955 }
2956 
2957 // https://issues.dlang.org/show_bug.cgi?id=18501
2958 @safe unittest
2959 {
2960     import std.algorithm.comparison : among;
2961     auto r = randomShuffle([0,1]);
2962     assert(r.among([0,1],[1,0]));
2963 }
2964 
2965 /**
2966 Partially shuffles the elements of `r` such that upon returning $(D r[0 .. n])
2967 is a random subset of `r` and is randomly ordered.  $(D r[n .. r.length])
2968 will contain the elements not in $(D r[0 .. n]).  These will be in an undefined
2969 order, but will not be random in the sense that their order after
2970 `partialShuffle` returns will not be independent of their order before
2971 `partialShuffle` was called.
2972 
2973 `r` must be a random-access range with length.  `n` must be less than
2974 or equal to `r.length`.  If no RNG is specified, `rndGen` will be used.
2975 
2976 Params:
2977     r = random-access range whose elements are to be shuffled
2978     n = number of elements of `r` to shuffle (counting from the beginning);
2979         must be less than `r.length`
2980     gen = (optional) random number generator to use; if not
2981           specified, defaults to `rndGen`
2982 Returns:
2983     The shuffled random-access range.
2984 */
2985 Range partialShuffle(Range, RandomGen)(Range r, in size_t n, ref RandomGen gen)
2986 if (isRandomAccessRange!Range && isUniformRNG!RandomGen)
2987 {
2988     import std.algorithm.mutation : swapAt;
2989     import std.exception : enforce;
2990     enforce(n <= r.length, "n must be <= r.length for partialShuffle.");
2991     foreach (i; 0 .. n)
2992     {
2993         r.swapAt(i, uniform(i, r.length, gen));
2994     }
2995     return r;
2996 }
2997 
2998 /// ditto
2999 Range partialShuffle(Range)(Range r, in size_t n)
3000 if (isRandomAccessRange!Range)
3001 {
3002     return partialShuffle(r, n, rndGen);
3003 }
3004 
3005 ///
3006 @safe unittest
3007 {
3008     auto rnd = MinstdRand0(42);
3009 
3010     auto arr = [1, 2, 3, 4, 5, 6];
3011     arr = arr.dup.partialShuffle(1, rnd);
3012 
3013     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
3014     assert(arr == [2, 1, 3, 4, 5, 6]); // 1<->2
3015 
3016     arr = arr.dup.partialShuffle(2, rnd);
3017     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
3018     assert(arr == [1, 4, 3, 2, 5, 6]); // 1<->2, 2<->4
3019 
3020     arr = arr.dup.partialShuffle(3, rnd);
3021     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
3022     assert(arr == [5, 4, 6, 2, 1, 3]); // 1<->5, 2<->4, 3<->6
3023 }
3024 
3025 @safe unittest
3026 {
3027     import std.algorithm;
3028     foreach (RandomGen; PseudoRngTypes)
3029     {
3030         auto a = [0, 1, 1, 2, 3];
3031         auto b = a.dup;
3032 
3033         // Pick a fixed seed so that the outcome of the statistical
3034         // test below is deterministic.
3035         auto gen = RandomGen(12345);
3036 
3037         // NUM times, pick LEN elements from the array at random.
3038         immutable int LEN = 2;
3039         immutable int NUM = 750;
3040         int[][] chk;
3041         foreach (step; 0 .. NUM)
3042         {
3043             partialShuffle(a, LEN, gen);
3044             chk ~= a[0 .. LEN].dup;
3045         }
3046 
3047         // Check that each possible a[0 .. LEN] was produced at least once.
3048         // For a perfectly random RandomGen, the probability that each
3049         // particular combination failed to appear would be at most
3050         // 0.95 ^^ NUM which is approximately 1,962e-17.
3051         // As long as hardware failure (e.g. bit flip) probability
3052         // is higher, we are fine with this unittest.
3053         sort(chk);
3054         assert(equal(uniq(chk), [       [0,1], [0,2], [0,3],
3055                                  [1,0], [1,1], [1,2], [1,3],
3056                                  [2,0], [2,1],        [2,3],
3057                                  [3,0], [3,1], [3,2],      ]));
3058 
3059         // Check that all the elements are still there.
3060         sort(a);
3061         assert(equal(a, b));
3062     }
3063 }
3064 
3065 /**
3066 Get a random index into a list of weights corresponding to each index
3067 
3068 Similar to rolling a die with relative probabilities stored in `proportions`.
3069 Returns the index in `proportions` that was chosen.
3070 
3071 Note:
3072     Usually, dice are 'fair', meaning that each side has equal probability
3073     to come up, in which case `1 + uniform(0, 6)` can simply be used.
3074     In future Phobos versions, this function might get renamed to something like
3075     `weightedChoice` to avoid confusion.
3076 
3077 Params:
3078     rnd = (optional) random number generator to use; if not
3079           specified, defaults to `rndGen`
3080     proportions = forward range or list of individual values
3081                   whose elements correspond to the probabilities
3082                   with which to choose the corresponding index
3083                   value
3084 
3085 Returns:
3086     Random variate drawn from the index values
3087     [0, ... `proportions.length` - 1], with the probability
3088     of getting an individual index value `i` being proportional to
3089     `proportions[i]`.
3090 */
3091 size_t dice(Rng, Num)(ref Rng rnd, Num[] proportions...)
3092 if (isNumeric!Num && isForwardRange!Rng)
3093 {
3094     return diceImpl(rnd, proportions);
3095 }
3096 
3097 /// Ditto
3098 size_t dice(R, Range)(ref R rnd, Range proportions)
3099 if (isForwardRange!Range && isNumeric!(ElementType!Range) && !isArray!Range)
3100 {
3101     return diceImpl(rnd, proportions);
3102 }
3103 
3104 /// Ditto
3105 size_t dice(Range)(Range proportions)
3106 if (isForwardRange!Range && isNumeric!(ElementType!Range) && !isArray!Range)
3107 {
3108     return diceImpl(rndGen, proportions);
3109 }
3110 
3111 /// Ditto
3112 size_t dice(Num)(Num[] proportions...)
3113 if (isNumeric!Num)
3114 {
3115     return diceImpl(rndGen, proportions);
3116 }
3117 
3118 ///
3119 @safe unittest
3120 {
3121     auto d6  = 1 + dice(1, 1, 1, 1, 1, 1); // fair dice roll
3122     auto d6b = 1 + dice(2, 1, 1, 1, 1, 1); // double the chance to roll '1'
3123 
3124     auto x = dice(0.5, 0.5);   // x is 0 or 1 in equal proportions
3125     auto y = dice(50, 50);     // y is 0 or 1 in equal proportions
3126     auto z = dice(70, 20, 10); // z is 0 70% of the time, 1 20% of the time,
3127                                // and 2 10% of the time
3128 }
3129 
3130 ///
3131 @safe unittest
3132 {
3133     auto rnd = MinstdRand0(42);
3134     auto z = rnd.dice(70, 20, 10);
3135     assert(z == 0);
3136     z = rnd.dice(30, 20, 40, 10);
3137     assert(z == 2);
3138 }
3139 
3140 private size_t diceImpl(Rng, Range)(ref Rng rng, scope Range proportions)
3141 if (isForwardRange!Range && isNumeric!(ElementType!Range) && isForwardRange!Rng)
3142 in
3143 {
3144     import std.algorithm.searching : all;
3145     assert(proportions.save.all!"a >= 0");
3146 }
3147 do
3148 {
3149     import std.algorithm.iteration : reduce;
3150     import std.exception : enforce;
3151     double sum = reduce!"a + b"(0.0, proportions.save);
3152     enforce(sum > 0, "Proportions in a dice cannot sum to zero");
3153     immutable point = uniform(0.0, sum, rng);
3154     assert(point < sum);
3155     auto mass = 0.0;
3156 
3157     size_t i = 0;
3158     foreach (e; proportions)
3159     {
3160         mass += e;
3161         if (point < mass) return i;
3162         i++;
3163     }
3164     // this point should not be reached
3165     assert(false);
3166 }
3167 
3168 ///
3169 @safe unittest
3170 {
3171     auto rnd = Xorshift(123_456_789);
3172     auto i = dice(rnd, 0.0, 100.0);
3173     assert(i == 1);
3174     i = dice(rnd, 100.0, 0.0);
3175     assert(i == 0);
3176 
3177     i = dice(100U, 0U);
3178     assert(i == 0);
3179 }
3180 
3181 /+ @nogc bool array designed for RandomCover.
3182 - constructed with an invariable length
3183 - small length means 0 alloc and bit field (if up to 32(x86) or 64(x64) choices to cover)
3184 - bigger length means non-GC heap allocation(s) and dealloc. +/
3185 private struct RandomCoverChoices
3186 {
3187     private size_t* buffer;
3188     private immutable size_t _length;
3189     private immutable bool hasPackedBits;
3190     private enum BITS_PER_WORD = typeof(buffer[0]).sizeof * 8;
3191 
3192     void opAssign(T)(T) @disable;
3193 
3194     this(this) pure nothrow @nogc @trusted
3195     {
3196         import core.stdc.string : memcpy;
3197         import std.internal.memory : enforceMalloc;
3198 
3199         if (!hasPackedBits && buffer !is null)
3200         {
3201             const nBytesToAlloc = size_t.sizeof * (_length / BITS_PER_WORD + int(_length % BITS_PER_WORD != 0));
3202             void* nbuffer = enforceMalloc(nBytesToAlloc);
3203             buffer = cast(size_t*) memcpy(nbuffer, buffer, nBytesToAlloc);
3204         }
3205     }
3206 
3207     this(size_t numChoices) pure nothrow @nogc @trusted
3208     {
3209         import std.internal.memory : enforceCalloc;
3210 
3211         _length = numChoices;
3212         hasPackedBits = _length <= size_t.sizeof * 8;
3213         if (!hasPackedBits)
3214         {
3215             const nWordsToAlloc = _length / BITS_PER_WORD + int(_length % BITS_PER_WORD != 0);
3216             buffer = cast(size_t*) enforceCalloc(nWordsToAlloc, BITS_PER_WORD / 8);
3217         }
3218     }
3219 
3220     size_t length() const pure nothrow @nogc @safe @property {return _length;}
3221 
3222     ~this() pure nothrow @nogc @trusted
3223     {
3224         import core.memory : pureFree;
3225 
3226         if (!hasPackedBits && buffer !is null)
3227             pureFree(buffer);
3228     }
3229 
3230     bool opIndex(size_t index) const pure nothrow @nogc @trusted
3231     {
3232         assert(index < _length);
3233         import core.bitop : bt;
3234         if (!hasPackedBits)
3235             return cast(bool) bt(buffer, index);
3236         else
3237             return ((cast(size_t) buffer) >> index) & size_t(1);
3238     }
3239 
3240     void opIndexAssign(bool value, size_t index) pure nothrow @nogc @trusted
3241     {
3242         assert(index < _length);
3243         if (!hasPackedBits)
3244         {
3245             import core.bitop : btr, bts;
3246             if (value)
3247                 bts(buffer, index);
3248             else
3249                 btr(buffer, index);
3250         }
3251         else
3252         {
3253             if (value)
3254                 (*cast(size_t*) &buffer) |= size_t(1) << index;
3255             else
3256                 (*cast(size_t*) &buffer) &= ~(size_t(1) << index);
3257         }
3258     }
3259 }
3260 
3261 @safe @nogc nothrow unittest
3262 {
3263     static immutable lengths = [3, 32, 65, 256];
3264     foreach (length; lengths)
3265     {
3266         RandomCoverChoices c = RandomCoverChoices(length);
3267         assert(c.hasPackedBits == (length <= size_t.sizeof * 8));
3268         c[0] = true;
3269         c[2] = true;
3270         assert(c[0]);
3271         assert(!c[1]);
3272         assert(c[2]);
3273         c[0] = false;
3274         c[1] = true;
3275         c[2] = false;
3276         assert(!c[0]);
3277         assert(c[1]);
3278         assert(!c[2]);
3279     }
3280 }
3281 
3282 /**
3283 Covers a given range `r` in a random manner, i.e. goes through each
3284 element of `r` once and only once, just in a random order. `r`
3285 must be a random-access range with length.
3286 
3287 If no random number generator is passed to `randomCover`, the
3288 thread-global RNG rndGen will be used internally.
3289 
3290 Params:
3291     r = random-access range to cover
3292     rng = (optional) random number generator to use;
3293           if not specified, defaults to `rndGen`
3294 
3295 Returns:
3296     Range whose elements consist of the elements of `r`,
3297     in random order.  Will be a forward range if both `r` and
3298     `rng` are forward ranges, an
3299     $(REF_ALTTEXT input range, isInputRange, std,range,primitives) otherwise.
3300 */
3301 struct RandomCover(Range, UniformRNG = void)
3302 if (isRandomAccessRange!Range && (isUniformRNG!UniformRNG || is(UniformRNG == void)))
3303 {
3304     private Range _input;
3305     private RandomCoverChoices _chosen;
3306     private size_t _current;
3307     private size_t _alreadyChosen = 0;
3308     private bool _isEmpty = false;
3309 
3310     static if (is(UniformRNG == void))
3311     {
3312         this(Range input)
3313         {
3314             _input = input;
3315             _chosen = RandomCoverChoices(_input.length);
3316             if (_input.empty)
3317             {
3318                 _isEmpty = true;
3319             }
3320             else
3321             {
3322                 _current = _uniformIndex(_chosen.length, rndGen);
3323             }
3324         }
3325     }
3326     else
3327     {
3328         private UniformRNG _rng;
3329 
3330         this(Range input, ref UniformRNG rng)
3331         {
3332             _input = input;
3333             _rng = rng;
3334             _chosen = RandomCoverChoices(_input.length);
3335             if (_input.empty)
3336             {
3337                 _isEmpty = true;
3338             }
3339             else
3340             {
3341                 _current = _uniformIndex(_chosen.length, rng);
3342             }
3343         }
3344 
3345         this(Range input, UniformRNG rng)
3346         {
3347             this(input, rng);
3348         }
3349     }
3350 
3351     static if (hasLength!Range)
3352     {
3353         @property size_t length()
3354         {
3355             return _input.length - _alreadyChosen;
3356         }
3357     }
3358 
3359     @property auto ref front()
3360     {
3361         assert(!_isEmpty);
3362         return _input[_current];
3363     }
3364 
3365     void popFront()
3366     {
3367         assert(!_isEmpty);
3368 
3369         size_t k = _input.length - _alreadyChosen - 1;
3370         if (k == 0)
3371         {
3372             _isEmpty = true;
3373             ++_alreadyChosen;
3374             return;
3375         }
3376 
3377         size_t i;
3378         foreach (e; _input)
3379         {
3380             if (_chosen[i] || i == _current) { ++i; continue; }
3381             // Roll a dice with k faces
3382             static if (is(UniformRNG == void))
3383             {
3384                 auto chooseMe = _uniformIndex(k, rndGen) == 0;
3385             }
3386             else
3387             {
3388                 auto chooseMe = _uniformIndex(k, _rng) == 0;
3389             }
3390             assert(k > 1 || chooseMe);
3391             if (chooseMe)
3392             {
3393                 _chosen[_current] = true;
3394                 _current = i;
3395                 ++_alreadyChosen;
3396                 return;
3397             }
3398             --k;
3399             ++i;
3400         }
3401     }
3402 
3403     static if (isForwardRange!UniformRNG)
3404     {
3405         @property typeof(this) save()
3406         {
3407             auto ret = this;
3408             ret._input = _input.save;
3409             ret._rng = _rng.save;
3410             return ret;
3411         }
3412     }
3413 
3414     @property bool empty() const { return _isEmpty; }
3415 }
3416 
3417 /// Ditto
3418 auto randomCover(Range, UniformRNG)(Range r, auto ref UniformRNG rng)
3419 if (isRandomAccessRange!Range && isUniformRNG!UniformRNG)
3420 {
3421     return RandomCover!(Range, UniformRNG)(r, rng);
3422 }
3423 
3424 /// Ditto
3425 auto randomCover(Range)(Range r)
3426 if (isRandomAccessRange!Range)
3427 {
3428     return RandomCover!(Range, void)(r);
3429 }
3430 
3431 ///
3432 @safe unittest
3433 {
3434     import std.algorithm.comparison : equal;
3435     import std.range : iota;
3436     auto rnd = MinstdRand0(42);
3437 
3438     version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
3439     assert(10.iota.randomCover(rnd).equal([7, 4, 2, 0, 1, 6, 8, 3, 9, 5]));
3440 }
3441 
3442 @safe unittest // cover RandomCoverChoices postblit for heap storage
3443 {
3444     import std.array : array;
3445     import std.range : iota;
3446     auto a = 1337.iota.randomCover().array;
3447     assert(a.length == 1337);
3448 }
3449 
3450 @nogc nothrow pure @safe unittest
3451 {
3452     // Optionally @nogc std.random.randomCover
3453     // https://issues.dlang.org/show_bug.cgi?id=14001
3454     auto rng = Xorshift(123_456_789);
3455     static immutable int[] sa = [1, 2, 3, 4, 5];
3456     auto r = randomCover(sa, rng);
3457     assert(!r.empty);
3458     const x = r.front;
3459     r.popFront();
3460     assert(!r.empty);
3461     const y = r.front;
3462     assert(x != y);
3463 }
3464 
3465 @safe unittest
3466 {
3467     import std.algorithm;
3468     import std.conv;
3469     int[] a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ];
3470     int[] c;
3471     static foreach (UniformRNG; std.meta.AliasSeq!(void, PseudoRngTypes))
3472     {{
3473         static if (is(UniformRNG == void))
3474         {
3475             auto rc = randomCover(a);
3476             static assert(isInputRange!(typeof(rc)));
3477             static assert(!isForwardRange!(typeof(rc)));
3478         }
3479         else
3480         {
3481             auto rng = UniformRNG(123_456_789);
3482             auto rc = randomCover(a, rng);
3483             static assert(isForwardRange!(typeof(rc)));
3484             // check for constructor passed a value-type RNG
3485             auto rc2 = RandomCover!(int[], UniformRNG)(a, UniformRNG(987_654_321));
3486             static assert(isForwardRange!(typeof(rc2)));
3487             auto rcEmpty = randomCover(c, rng);
3488             assert(rcEmpty.length == 0);
3489         }
3490 
3491         int[] b = new int[9];
3492         uint i;
3493         foreach (e; rc)
3494         {
3495             //writeln(e);
3496             b[i++] = e;
3497         }
3498         sort(b);
3499         assert(a == b, text(b));
3500     }}
3501 }
3502 
3503 @safe unittest
3504 {
3505     // https://issues.dlang.org/show_bug.cgi?id=12589
3506     int[] r = [];
3507     auto rc = randomCover(r);
3508     assert(rc.length == 0);
3509     assert(rc.empty);
3510 
3511     // https://issues.dlang.org/show_bug.cgi?id=16724
3512     import std.range : iota;
3513     auto range = iota(10);
3514     auto randy = range.randomCover;
3515 
3516     for (int i=1; i <= range.length; i++)
3517     {
3518         randy.popFront;
3519         assert(randy.length == range.length - i);
3520     }
3521 }
3522 
3523 // RandomSample
3524 /**
3525 Selects a random subsample out of `r`, containing exactly `n`
3526 elements. The order of elements is the same as in the original
3527 range. The total length of `r` must be known. If `total` is
3528 passed in, the total number of sample is considered to be $(D
3529 total). Otherwise, `RandomSample` uses `r.length`.
3530 
3531 Params:
3532     r = range to sample from
3533     n = number of elements to include in the sample;
3534         must be less than or equal to the total number
3535         of elements in `r` and/or the parameter
3536         `total` (if provided)
3537     total = (semi-optional) number of elements of `r`
3538             from which to select the sample (counting from
3539             the beginning); must be less than or equal to
3540             the total number of elements in `r` itself.
3541             May be omitted if `r` has the `.length`
3542             property and the sample is to be drawn from
3543             all elements of `r`.
3544     rng = (optional) random number generator to use;
3545           if not specified, defaults to `rndGen`
3546 
3547 Returns:
3548     Range whose elements consist of a randomly selected subset of
3549     the elements of `r`, in the same order as these elements
3550     appear in `r` itself.  Will be a forward range if both `r`
3551     and `rng` are forward ranges, an input range otherwise.
3552 
3553 `RandomSample` implements Jeffrey Scott Vitter's Algorithm D
3554 (see Vitter $(HTTP dx.doi.org/10.1145/358105.893, 1984), $(HTTP
3555 dx.doi.org/10.1145/23002.23003, 1987)), which selects a sample
3556 of size `n` in O(n) steps and requiring O(n) random variates,
3557 regardless of the size of the data being sampled.  The exception
3558 to this is if traversing k elements on the input range is itself
3559 an O(k) operation (e.g. when sampling lines from an input file),
3560 in which case the sampling calculation will inevitably be of
3561 O(total).
3562 
3563 RandomSample will throw an exception if `total` is verifiably
3564 less than the total number of elements available in the input,
3565 or if $(D n > total).
3566 
3567 If no random number generator is passed to `randomSample`, the
3568 thread-global RNG rndGen will be used internally.
3569 */
3570 struct RandomSample(Range, UniformRNG = void)
3571 if (isInputRange!Range && (isUniformRNG!UniformRNG || is(UniformRNG == void)))
3572 {
3573     private size_t _available, _toSelect;
3574     private enum ushort _alphaInverse = 13; // Vitter's recommended value.
3575     private double _Vprime;
3576     private Range _input;
3577     private size_t _index;
3578     private enum Skip { None, A, D }
3579     private Skip _skip = Skip.None;
3580 
3581     // If we're using the default thread-local random number generator then
3582     // we shouldn't store a copy of it here.  UniformRNG == void is a sentinel
3583     // for this.  If we're using a user-specified generator then we have no
3584     // choice but to store a copy.
3585     static if (is(UniformRNG == void))
3586     {
3587         static if (hasLength!Range)
3588         {
3589             this(Range input, size_t howMany)
3590             {
3591                 _input = input;
3592                 initialize(howMany, input.length);
3593             }
3594         }
3595 
3596         this(Range input, size_t howMany, size_t total)
3597         {
3598             _input = input;
3599             initialize(howMany, total);
3600         }
3601     }
3602     else
3603     {
3604         UniformRNG _rng;
3605 
3606         static if (hasLength!Range)
3607         {
3608             this(Range input, size_t howMany, ref scope UniformRNG rng)
3609             {
3610                 _rng = rng;
3611                 _input = input;
3612                 initialize(howMany, input.length);
3613             }
3614 
3615             this(Range input, size_t howMany, UniformRNG rng)
3616             {
3617                 this(input, howMany, rng);
3618             }
3619         }
3620 
3621         this(Range input, size_t howMany, size_t total, ref scope UniformRNG rng)
3622         {
3623             _rng = rng;
3624             _input = input;
3625             initialize(howMany, total);
3626         }
3627 
3628         this(Range input, size_t howMany, size_t total, UniformRNG rng)
3629         {
3630             this(input, howMany, total, rng);
3631         }
3632     }
3633 
3634     private void initialize(size_t howMany, size_t total)
3635     {
3636         import std.conv : text;
3637         import std.exception : enforce;
3638         _available = total;
3639         _toSelect = howMany;
3640         enforce(_toSelect <= _available,
3641                 text("RandomSample: cannot sample ", _toSelect,
3642                      " items when only ", _available, " are available"));
3643         static if (hasLength!Range)
3644         {
3645             enforce(_available <= _input.length,
3646                     text("RandomSample: specified ", _available,
3647                          " items as available when input contains only ",
3648                          _input.length));
3649         }
3650     }
3651 
3652     private void initializeFront()
3653     {
3654         assert(_skip == Skip.None);
3655         // We can save ourselves a random variate by checking right
3656         // at the beginning if we should use Algorithm A.
3657         if ((_alphaInverse * _toSelect) > _available)
3658         {
3659             _skip = Skip.A;
3660         }
3661         else
3662         {
3663             _skip = Skip.D;
3664             _Vprime = newVprime(_toSelect);
3665         }
3666         prime();
3667     }
3668 
3669 /**
3670    Range primitives.
3671 */
3672     @property bool empty() const
3673     {
3674         return _toSelect == 0;
3675     }
3676 
3677 /// Ditto
3678     @property auto ref front()
3679     {
3680         assert(!empty);
3681         // The first sample point must be determined here to avoid
3682         // having it always correspond to the first element of the
3683         // input.  The rest of the sample points are determined each
3684         // time we call popFront().
3685         if (_skip == Skip.None)
3686         {
3687             initializeFront();
3688         }
3689         return _input.front;
3690     }
3691 
3692 /// Ditto
3693     void popFront()
3694     {
3695         // First we need to check if the sample has
3696         // been initialized in the first place.
3697         if (_skip == Skip.None)
3698         {
3699             initializeFront();
3700         }
3701 
3702         _input.popFront();
3703         --_available;
3704         --_toSelect;
3705         ++_index;
3706         prime();
3707     }
3708 
3709 /// Ditto
3710     static if (isForwardRange!Range && isForwardRange!UniformRNG)
3711     {
3712         static if (is(typeof(((const UniformRNG* p) => (*p).save)(null)) : UniformRNG)
3713             && is(typeof(((const Range* p) => (*p).save)(null)) : Range))
3714         {
3715             @property typeof(this) save() const
3716             {
3717                 auto ret = RandomSample.init;
3718                 foreach (fieldIndex, ref val; this.tupleof)
3719                 {
3720                     static if (is(typeof(val) == const(Range)) || is(typeof(val) == const(UniformRNG)))
3721                         ret.tupleof[fieldIndex] = val.save;
3722                     else
3723                         ret.tupleof[fieldIndex] = val;
3724                 }
3725                 return ret;
3726             }
3727         }
3728         else
3729         {
3730             @property typeof(this) save()
3731             {
3732                 auto ret = this;
3733                 ret._input = _input.save;
3734                 ret._rng = _rng.save;
3735                 return ret;
3736             }
3737         }
3738     }
3739 
3740 /// Ditto
3741     @property size_t length() const
3742     {
3743         return _toSelect;
3744     }
3745 
3746 /**
3747 Returns the index of the visited record.
3748  */
3749     @property size_t index()
3750     {
3751         if (_skip == Skip.None)
3752         {
3753             initializeFront();
3754         }
3755         return _index;
3756     }
3757 
3758     private size_t skip()
3759     {
3760         assert(_skip != Skip.None);
3761 
3762         // Step D1: if the number of points still to select is greater
3763         // than a certain proportion of the remaining data points, i.e.
3764         // if n >= alpha * N where alpha = 1/13, we carry out the
3765         // sampling with Algorithm A.
3766         if (_skip == Skip.A)
3767         {
3768             return skipA();
3769         }
3770         else if ((_alphaInverse * _toSelect) > _available)
3771         {
3772             // We shouldn't get here unless the current selected
3773             // algorithm is D.
3774             assert(_skip == Skip.D);
3775             _skip = Skip.A;
3776             return skipA();
3777         }
3778         else
3779         {
3780             assert(_skip == Skip.D);
3781             return skipD();
3782         }
3783     }
3784 
3785 /*
3786 Vitter's Algorithm A, used when the ratio of needed sample values
3787 to remaining data values is sufficiently large.
3788 */
3789     private size_t skipA()
3790     {
3791         size_t s;
3792         double v, quot, top;
3793 
3794         if (_toSelect == 1)
3795         {
3796             static if (is(UniformRNG == void))
3797             {
3798                 s = uniform(0, _available);
3799             }
3800             else
3801             {
3802                 s = uniform(0, _available, _rng);
3803             }
3804         }
3805         else
3806         {
3807             v = 0;
3808             top = _available - _toSelect;
3809             quot = top / _available;
3810 
3811             static if (is(UniformRNG == void))
3812             {
3813                 v = uniform!"()"(0.0, 1.0);
3814             }
3815             else
3816             {
3817                 v = uniform!"()"(0.0, 1.0, _rng);
3818             }
3819 
3820             while (quot > v)
3821             {
3822                 ++s;
3823                 quot *= (top - s) / (_available - s);
3824             }
3825         }
3826 
3827         return s;
3828     }
3829 
3830 /*
3831 Randomly reset the value of _Vprime.
3832 */
3833     private double newVprime(size_t remaining)
3834     {
3835         static if (is(UniformRNG == void))
3836         {
3837             double r = uniform!"()"(0.0, 1.0);
3838         }
3839         else
3840         {
3841             double r = uniform!"()"(0.0, 1.0, _rng);
3842         }
3843 
3844         return r ^^ (1.0 / remaining);
3845     }
3846 
3847 /*
3848 Vitter's Algorithm D.  For an extensive description of the algorithm
3849 and its rationale, see:
3850 
3851   * Vitter, J.S. (1984), "Faster methods for random sampling",
3852     Commun. ACM 27(7): 703--718
3853 
3854   * Vitter, J.S. (1987) "An efficient algorithm for sequential random
3855     sampling", ACM Trans. Math. Softw. 13(1): 58-67.
3856 
3857 Variable names are chosen to match those in Vitter's paper.
3858 */
3859     private size_t skipD()
3860     {
3861         import std.math.traits : isNaN;
3862         import std.math.rounding : trunc;
3863         // Confirm that the check in Step D1 is valid and we
3864         // haven't been sent here by mistake
3865         assert((_alphaInverse * _toSelect) <= _available);
3866 
3867         // Now it's safe to use the standard Algorithm D mechanism.
3868         if (_toSelect > 1)
3869         {
3870             size_t s;
3871             size_t qu1 = 1 + _available - _toSelect;
3872             double x, y1;
3873 
3874             assert(!_Vprime.isNaN());
3875 
3876             while (true)
3877             {
3878                 // Step D2: set values of x and u.
3879                 while (1)
3880                 {
3881                     x = _available * (1-_Vprime);
3882                     s = cast(size_t) trunc(x);
3883                     if (s < qu1)
3884                         break;
3885                     _Vprime = newVprime(_toSelect);
3886                 }
3887 
3888                 static if (is(UniformRNG == void))
3889                 {
3890                     double u = uniform!"()"(0.0, 1.0);
3891                 }
3892                 else
3893                 {
3894                     double u = uniform!"()"(0.0, 1.0, _rng);
3895                 }
3896 
3897                 y1 = (u * (cast(double) _available) / qu1) ^^ (1.0/(_toSelect - 1));
3898 
3899                 _Vprime = y1 * ((-x/_available)+1.0) * ( qu1/( (cast(double) qu1) - s ) );
3900 
3901                 // Step D3: if _Vprime <= 1.0 our work is done and we return S.
3902                 // Otherwise ...
3903                 if (_Vprime > 1.0)
3904                 {
3905                     size_t top = _available - 1, limit;
3906                     double y2 = 1.0, bottom;
3907 
3908                     if (_toSelect > (s+1))
3909                     {
3910                         bottom = _available - _toSelect;
3911                         limit = _available - s;
3912                     }
3913                     else
3914                     {
3915                         bottom = _available - (s+1);
3916                         limit = qu1;
3917                     }
3918 
3919                     foreach (size_t t; limit .. _available)
3920                     {
3921                         y2 *= top/bottom;
3922                         top--;
3923                         bottom--;
3924                     }
3925 
3926                     // Step D4: decide whether or not to accept the current value of S.
3927                     if (_available/(_available-x) < y1 * (y2 ^^ (1.0/(_toSelect-1))))
3928                     {
3929                         // If it's not acceptable, we generate a new value of _Vprime
3930                         // and go back to the start of the for (;;) loop.
3931                         _Vprime = newVprime(_toSelect);
3932                     }
3933                     else
3934                     {
3935                         // If it's acceptable we generate a new value of _Vprime
3936                         // based on the remaining number of sample points needed,
3937                         // and return S.
3938                         _Vprime = newVprime(_toSelect-1);
3939                         return s;
3940                     }
3941                 }
3942                 else
3943                 {
3944                     // Return if condition D3 satisfied.
3945                     return s;
3946                 }
3947             }
3948         }
3949         else
3950         {
3951             // If only one sample point remains to be taken ...
3952             return cast(size_t) trunc(_available * _Vprime);
3953         }
3954     }
3955 
3956     private void prime()
3957     {
3958         if (empty)
3959         {
3960             return;
3961         }
3962         assert(_available && _available >= _toSelect);
3963         immutable size_t s = skip();
3964         assert(s + _toSelect <= _available);
3965         static if (hasLength!Range)
3966         {
3967             assert(s + _toSelect <= _input.length);
3968         }
3969         assert(!_input.empty);
3970         _input.popFrontExactly(s);
3971         _index += s;
3972         _available -= s;
3973         assert(_available > 0);
3974     }
3975 }
3976 
3977 /// Ditto
3978 auto randomSample(Range)(Range r, size_t n, size_t total)
3979 if (isInputRange!Range)
3980 {
3981     return RandomSample!(Range, void)(r, n, total);
3982 }
3983 
3984 /// Ditto
3985 auto randomSample(Range)(Range r, size_t n)
3986 if (isInputRange!Range && hasLength!Range)
3987 {
3988     return RandomSample!(Range, void)(r, n, r.length);
3989 }
3990 
3991 /// Ditto
3992 auto randomSample(Range, UniformRNG)(Range r, size_t n, size_t total, auto ref UniformRNG rng)
3993 if (isInputRange!Range && isUniformRNG!UniformRNG)
3994 {
3995     return RandomSample!(Range, UniformRNG)(r, n, total, rng);
3996 }
3997 
3998 /// Ditto
3999 auto randomSample(Range, UniformRNG)(Range r, size_t n, auto ref UniformRNG rng)
4000 if (isInputRange!Range && hasLength!Range && isUniformRNG!UniformRNG)
4001 {
4002     return RandomSample!(Range, UniformRNG)(r, n, r.length, rng);
4003 }
4004 
4005 ///
4006 @safe unittest
4007 {
4008     import std.algorithm.comparison : equal;
4009     import std.range : iota;
4010     auto rnd = MinstdRand0(42);
4011     assert(10.iota.randomSample(3, rnd).equal([7, 8, 9]));
4012 }
4013 
4014 @system unittest
4015 {
4016     // @system because it takes the address of a local
4017     import std.conv : text;
4018     import std.exception;
4019     import std.range;
4020     // For test purposes, an infinite input range
4021     struct TestInputRange
4022     {
4023         private auto r = recurrence!"a[n-1] + 1"(0);
4024         bool empty() @property const pure nothrow { return r.empty; }
4025         auto front() @property pure nothrow { return r.front; }
4026         void popFront() pure nothrow { r.popFront(); }
4027     }
4028     static assert(isInputRange!TestInputRange);
4029     static assert(!isForwardRange!TestInputRange);
4030 
4031     const(int)[] a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];
4032 
4033     foreach (UniformRNG; PseudoRngTypes)
4034     (){ // avoid workaround optimizations for large functions
4035         // https://issues.dlang.org/show_bug.cgi?id=2396
4036         auto rng = UniformRNG(1234);
4037         /* First test the most general case: randomSample of input range, with and
4038          * without a specified random number generator.
4039          */
4040         static assert(isInputRange!(typeof(randomSample(TestInputRange(), 5, 10))));
4041         static assert(isInputRange!(typeof(randomSample(TestInputRange(), 5, 10, rng))));
4042         static assert(!isForwardRange!(typeof(randomSample(TestInputRange(), 5, 10))));
4043         static assert(!isForwardRange!(typeof(randomSample(TestInputRange(), 5, 10, rng))));
4044         // test case with range initialized by direct call to struct
4045         {
4046             auto sample =
4047                 RandomSample!(TestInputRange, UniformRNG)
4048                              (TestInputRange(), 5, 10, UniformRNG(987_654_321));
4049             static assert(isInputRange!(typeof(sample)));
4050             static assert(!isForwardRange!(typeof(sample)));
4051         }
4052 
4053         /* Now test the case of an input range with length.  We ignore the cases
4054          * already covered by the previous tests.
4055          */
4056         static assert(isInputRange!(typeof(randomSample(TestInputRange().takeExactly(10), 5))));
4057         static assert(isInputRange!(typeof(randomSample(TestInputRange().takeExactly(10), 5, rng))));
4058         static assert(!isForwardRange!(typeof(randomSample(TestInputRange().takeExactly(10), 5))));
4059         static assert(!isForwardRange!(typeof(randomSample(TestInputRange().takeExactly(10), 5, rng))));
4060         // test case with range initialized by direct call to struct
4061         {
4062             auto sample =
4063                 RandomSample!(typeof(TestInputRange().takeExactly(10)), UniformRNG)
4064                              (TestInputRange().takeExactly(10), 5, 10, UniformRNG(654_321_987));
4065             static assert(isInputRange!(typeof(sample)));
4066             static assert(!isForwardRange!(typeof(sample)));
4067         }
4068 
4069         // Now test the case of providing a forward range as input.
4070         static assert(!isForwardRange!(typeof(randomSample(a, 5))));
4071         static if (isForwardRange!UniformRNG)
4072         {
4073             static assert(isForwardRange!(typeof(randomSample(a, 5, rng))));
4074             // ... and test with range initialized directly
4075             {
4076                 auto sample =
4077                     RandomSample!(const(int)[], UniformRNG)
4078                                  (a, 5, UniformRNG(321_987_654));
4079                 static assert(isForwardRange!(typeof(sample)));
4080             }
4081         }
4082         else
4083         {
4084             static assert(isInputRange!(typeof(randomSample(a, 5, rng))));
4085             static assert(!isForwardRange!(typeof(randomSample(a, 5, rng))));
4086             // ... and test with range initialized directly
4087             {
4088                 auto sample =
4089                     RandomSample!(const(int)[], UniformRNG)
4090                                  (a, 5, UniformRNG(789_123_456));
4091                 static assert(isInputRange!(typeof(sample)));
4092                 static assert(!isForwardRange!(typeof(sample)));
4093             }
4094         }
4095 
4096         /* Check that randomSample will throw an error if we claim more
4097          * items are available than there actually are, or if we try to
4098          * sample more items than are available. */
4099         assert(collectExceptionMsg(
4100             randomSample(a, 5, 15)
4101         ) == "RandomSample: specified 15 items as available when input contains only 10");
4102         assert(collectExceptionMsg(
4103             randomSample(a, 15)
4104         ) == "RandomSample: cannot sample 15 items when only 10 are available");
4105         assert(collectExceptionMsg(
4106             randomSample(a, 9, 8)
4107         ) == "RandomSample: cannot sample 9 items when only 8 are available");
4108         assert(collectExceptionMsg(
4109             randomSample(TestInputRange(), 12, 11)
4110         ) == "RandomSample: cannot sample 12 items when only 11 are available");
4111 
4112         /* Check that sampling algorithm never accidentally overruns the end of
4113          * the input range.  If input is an InputRange without .length, this
4114          * relies on the user specifying the total number of available items
4115          * correctly.
4116          */
4117         {
4118             uint i = 0;
4119             foreach (e; randomSample(a, a.length))
4120             {
4121                 assert(e == i);
4122                 ++i;
4123             }
4124             assert(i == a.length);
4125 
4126             i = 0;
4127             foreach (e; randomSample(TestInputRange(), 17, 17))
4128             {
4129                 assert(e == i);
4130                 ++i;
4131             }
4132             assert(i == 17);
4133         }
4134 
4135 
4136         // Check length properties of random samples.
4137         assert(randomSample(a, 5).length == 5);
4138         assert(randomSample(a, 5, 10).length == 5);
4139         assert(randomSample(a, 5, rng).length == 5);
4140         assert(randomSample(a, 5, 10, rng).length == 5);
4141         assert(randomSample(TestInputRange(), 5, 10).length == 5);
4142         assert(randomSample(TestInputRange(), 5, 10, rng).length == 5);
4143 
4144         // ... and emptiness!
4145         assert(randomSample(a, 0).empty);
4146         assert(randomSample(a, 0, 5).empty);
4147         assert(randomSample(a, 0, rng).empty);
4148         assert(randomSample(a, 0, 5, rng).empty);
4149         assert(randomSample(TestInputRange(), 0, 10).empty);
4150         assert(randomSample(TestInputRange(), 0, 10, rng).empty);
4151 
4152         /* Test that the (lazy) evaluation of random samples works correctly.
4153          *
4154          * We cover 2 different cases: a sample where the ratio of sample points
4155          * to total points is greater than the threshold for using Algorithm, and
4156          * one where the ratio is small enough (< 1/13) for Algorithm D to be used.
4157          *
4158          * For each, we also cover the case with and without a specified RNG.
4159          */
4160         {
4161             // Small sample/source ratio, no specified RNG.
4162             uint i = 0;
4163             foreach (e; randomSample(randomCover(a), 5))
4164             {
4165                 ++i;
4166             }
4167             assert(i == 5);
4168 
4169             // Small sample/source ratio, specified RNG.
4170             i = 0;
4171             foreach (e; randomSample(randomCover(a), 5, rng))
4172             {
4173                 ++i;
4174             }
4175             assert(i == 5);
4176 
4177             // Large sample/source ratio, no specified RNG.
4178             i = 0;
4179             foreach (e; randomSample(TestInputRange(), 123, 123_456))
4180             {
4181                 ++i;
4182             }
4183             assert(i == 123);
4184 
4185             // Large sample/source ratio, specified RNG.
4186             i = 0;
4187             foreach (e; randomSample(TestInputRange(), 123, 123_456, rng))
4188             {
4189                 ++i;
4190             }
4191             assert(i == 123);
4192 
4193             /* Sample/source ratio large enough to start with Algorithm D,
4194              * small enough to switch to Algorithm A.
4195              */
4196             i = 0;
4197             foreach (e; randomSample(TestInputRange(), 10, 131))
4198             {
4199                 ++i;
4200             }
4201             assert(i == 10);
4202         }
4203 
4204         // Test that the .index property works correctly
4205         {
4206             auto sample1 = randomSample(TestInputRange(), 654, 654_321);
4207             for (; !sample1.empty; sample1.popFront())
4208             {
4209                 assert(sample1.front == sample1.index);
4210             }
4211 
4212             auto sample2 = randomSample(TestInputRange(), 654, 654_321, rng);
4213             for (; !sample2.empty; sample2.popFront())
4214             {
4215                 assert(sample2.front == sample2.index);
4216             }
4217 
4218             /* Check that it also works if .index is called before .front.
4219              * See: https://issues.dlang.org/show_bug.cgi?id=10322
4220              */
4221             auto sample3 = randomSample(TestInputRange(), 654, 654_321);
4222             for (; !sample3.empty; sample3.popFront())
4223             {
4224                 assert(sample3.index == sample3.front);
4225             }
4226 
4227             auto sample4 = randomSample(TestInputRange(), 654, 654_321, rng);
4228             for (; !sample4.empty; sample4.popFront())
4229             {
4230                 assert(sample4.index == sample4.front);
4231             }
4232         }
4233 
4234         /* Test behaviour if .popFront() is called before sample is read.
4235          * This is a rough-and-ready check that the statistical properties
4236          * are in the ballpark -- not a proper validation of statistical
4237          * quality!  This incidentally also checks for reference-type
4238          * initialization bugs, as the foreach () loop will operate on a
4239          * copy of the popFronted (and hence initialized) sample.
4240          */
4241         {
4242             size_t count0, count1, count99;
4243             foreach (_; 0 .. 50_000)
4244             {
4245                 auto sample = randomSample(iota(100), 5, &rng);
4246                 sample.popFront();
4247                 foreach (s; sample)
4248                 {
4249                     if (s == 0)
4250                     {
4251                         ++count0;
4252                     }
4253                     else if (s == 1)
4254                     {
4255                         ++count1;
4256                     }
4257                     else if (s == 99)
4258                     {
4259                         ++count99;
4260                     }
4261                 }
4262             }
4263             /* Statistical assumptions here: this is a sequential sampling process
4264              * so (i) 0 can only be the first sample point, so _can't_ be in the
4265              * remainder of the sample after .popFront() is called. (ii) By similar
4266              * token, 1 can only be in the remainder if it's the 2nd point of the
4267              * whole sample, and hence if 0 was the first; probability of 0 being
4268              * first and 1 second is 5/100 * 4/99 (thank you, Algorithm S:-) and
4269              * so the mean count of 1 should be about 202.  Finally, 99 can only
4270              * be the _last_ sample point to be picked, so its probability of
4271              * inclusion should be independent of the .popFront() and it should
4272              * occur with frequency 5/100, hence its count should be about 5000.
4273              * Unfortunately we have to set quite a high tolerance because with
4274              * sample size small enough for unittests to run in reasonable time,
4275              * the variance can be quite high.
4276              */
4277             assert(count0 == 0);
4278             assert(count1 < 150, text("1: ", count1, " > 150."));
4279             assert(2_200 < count99, text("99: ", count99, " < 2200."));
4280             assert(count99 < 2_800, text("99: ", count99, " > 2800."));
4281         }
4282 
4283         /* Odd corner-cases: RandomSample has 2 constructors that are not called
4284          * by the randomSample() helper functions, but that can be used if the
4285          * constructor is called directly.  These cover the case of the user
4286          * specifying input but not input length.
4287          */
4288         {
4289             auto input1 = TestInputRange().takeExactly(456_789);
4290             static assert(hasLength!(typeof(input1)));
4291             auto sample1 = RandomSample!(typeof(input1), void)(input1, 789);
4292             static assert(isInputRange!(typeof(sample1)));
4293             static assert(!isForwardRange!(typeof(sample1)));
4294             assert(sample1.length == 789);
4295             assert(sample1._available == 456_789);
4296             uint i = 0;
4297             for (; !sample1.empty; sample1.popFront())
4298             {
4299                 assert(sample1.front == sample1.index);
4300                 ++i;
4301             }
4302             assert(i == 789);
4303 
4304             auto input2 = TestInputRange().takeExactly(456_789);
4305             static assert(hasLength!(typeof(input2)));
4306             auto sample2 = RandomSample!(typeof(input2), typeof(rng))(input2, 789, rng);
4307             static assert(isInputRange!(typeof(sample2)));
4308             static assert(!isForwardRange!(typeof(sample2)));
4309             assert(sample2.length == 789);
4310             assert(sample2._available == 456_789);
4311             i = 0;
4312             for (; !sample2.empty; sample2.popFront())
4313             {
4314                 assert(sample2.front == sample2.index);
4315                 ++i;
4316             }
4317             assert(i == 789);
4318         }
4319 
4320         /* Test that the save property works where input is a forward range,
4321          * and RandomSample is using a (forward range) random number generator
4322          * that is not rndGen.
4323          */
4324         static if (isForwardRange!UniformRNG)
4325         {
4326             auto sample1 = randomSample(a, 5, rng);
4327             // https://issues.dlang.org/show_bug.cgi?id=15853
4328             auto sample2 = ((const ref typeof(sample1) a) => a.save)(sample1);
4329             assert(sample1.array() == sample2.array());
4330         }
4331 
4332         // https://issues.dlang.org/show_bug.cgi?id=8314
4333         {
4334             auto sample(RandomGen)(uint seed) { return randomSample(a, 1, RandomGen(seed)).front; }
4335 
4336             // Start from 1 because not all RNGs accept 0 as seed.
4337             immutable fst = sample!UniformRNG(1);
4338             uint n = 1;
4339             while (sample!UniformRNG(++n) == fst && n < n.max) {}
4340             assert(n < n.max);
4341         }
4342     }();
4343 }