mirrored from git://gcc.gnu.org/git/gcc.git
/
random.h
2414 lines (2119 loc) · 71.4 KB
/
random.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// random number generation -*- C++ -*-
// Copyright (C) 2009-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/**
* @file tr1/random.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{tr1/random}
*/
#ifndef _GLIBCXX_TR1_RANDOM_H
#define _GLIBCXX_TR1_RANDOM_H 1
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace tr1
{
// [5.1] Random number generation
/**
* @addtogroup tr1_random Random Number Generation
* A facility for generating random numbers on selected distributions.
* @{
*/
/*
* Implementation-space details.
*/
namespace __detail
{
template<typename _UIntType, int __w,
bool = __w < std::numeric_limits<_UIntType>::digits>
struct _Shift
{ static const _UIntType __value = 0; };
template<typename _UIntType, int __w>
struct _Shift<_UIntType, __w, true>
{ static const _UIntType __value = _UIntType(1) << __w; };
template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool>
struct _Mod;
// Dispatch based on modulus value to prevent divide-by-zero compile-time
// errors when m == 0.
template<typename _Tp, _Tp __a, _Tp __c, _Tp __m>
inline _Tp
__mod(_Tp __x)
{ return _Mod<_Tp, __a, __c, __m, __m == 0>::__calc(__x); }
typedef __gnu_cxx::__conditional_type<(sizeof(unsigned) == 4),
unsigned, unsigned long>::__type _UInt32Type;
/*
* An adaptor class for converting the output of any Generator into
* the input for a specific Distribution.
*/
template<typename _Engine, typename _Distribution>
struct _Adaptor
{
typedef typename remove_reference<_Engine>::type _BEngine;
typedef typename _BEngine::result_type _Engine_result_type;
typedef typename _Distribution::input_type result_type;
public:
_Adaptor(const _Engine& __g)
: _M_g(__g) { }
result_type
min() const
{
result_type __return_value;
if (is_integral<_Engine_result_type>::value
&& is_integral<result_type>::value)
__return_value = _M_g.min();
else
__return_value = result_type(0);
return __return_value;
}
result_type
max() const
{
result_type __return_value;
if (is_integral<_Engine_result_type>::value
&& is_integral<result_type>::value)
__return_value = _M_g.max();
else if (!is_integral<result_type>::value)
__return_value = result_type(1);
else
__return_value = std::numeric_limits<result_type>::max() - 1;
return __return_value;
}
/*
* Converts a value generated by the adapted random number generator
* into a value in the input domain for the dependent random number
* distribution.
*
* Because the type traits are compile time constants only the
* appropriate clause of the if statements will actually be emitted
* by the compiler.
*/
result_type
operator()()
{
result_type __return_value;
if (is_integral<_Engine_result_type>::value
&& is_integral<result_type>::value)
__return_value = _M_g();
else if (!is_integral<_Engine_result_type>::value
&& !is_integral<result_type>::value)
__return_value = result_type(_M_g() - _M_g.min())
/ result_type(_M_g.max() - _M_g.min());
else if (is_integral<_Engine_result_type>::value
&& !is_integral<result_type>::value)
__return_value = result_type(_M_g() - _M_g.min())
/ result_type(_M_g.max() - _M_g.min() + result_type(1));
else
__return_value = (((_M_g() - _M_g.min())
/ (_M_g.max() - _M_g.min()))
* std::numeric_limits<result_type>::max());
return __return_value;
}
private:
_Engine _M_g;
};
// Specialization for _Engine*.
template<typename _Engine, typename _Distribution>
struct _Adaptor<_Engine*, _Distribution>
{
typedef typename _Engine::result_type _Engine_result_type;
typedef typename _Distribution::input_type result_type;
public:
_Adaptor(_Engine* __g)
: _M_g(__g) { }
result_type
min() const
{
result_type __return_value;
if (is_integral<_Engine_result_type>::value
&& is_integral<result_type>::value)
__return_value = _M_g->min();
else
__return_value = result_type(0);
return __return_value;
}
result_type
max() const
{
result_type __return_value;
if (is_integral<_Engine_result_type>::value
&& is_integral<result_type>::value)
__return_value = _M_g->max();
else if (!is_integral<result_type>::value)
__return_value = result_type(1);
else
__return_value = std::numeric_limits<result_type>::max() - 1;
return __return_value;
}
result_type
operator()()
{
result_type __return_value;
if (is_integral<_Engine_result_type>::value
&& is_integral<result_type>::value)
__return_value = (*_M_g)();
else if (!is_integral<_Engine_result_type>::value
&& !is_integral<result_type>::value)
__return_value = result_type((*_M_g)() - _M_g->min())
/ result_type(_M_g->max() - _M_g->min());
else if (is_integral<_Engine_result_type>::value
&& !is_integral<result_type>::value)
__return_value = result_type((*_M_g)() - _M_g->min())
/ result_type(_M_g->max() - _M_g->min() + result_type(1));
else
__return_value = ((((*_M_g)() - _M_g->min())
/ (_M_g->max() - _M_g->min()))
* std::numeric_limits<result_type>::max());
return __return_value;
}
private:
_Engine* _M_g;
};
} // namespace __detail
/**
* Produces random numbers on a given distribution function using a
* non-uniform random number generation engine.
*
* @todo the engine_value_type needs to be studied more carefully.
*/
template<typename _Engine, typename _Dist>
class variate_generator
{
// Concept requirements.
__glibcxx_class_requires(_Engine, _CopyConstructibleConcept)
// __glibcxx_class_requires(_Engine, _EngineConcept)
// __glibcxx_class_requires(_Dist, _EngineConcept)
public:
typedef _Engine engine_type;
typedef __detail::_Adaptor<_Engine, _Dist> engine_value_type;
typedef _Dist distribution_type;
typedef typename _Dist::result_type result_type;
// tr1:5.1.1 table 5.1 requirement
typedef typename __gnu_cxx::__enable_if<
is_arithmetic<result_type>::value, result_type>::__type _IsValidType;
/**
* Constructs a variate generator with the uniform random number
* generator @p __eng for the random distribution @p __dist.
*
* @throws Any exceptions which may thrown by the copy constructors of
* the @p _Engine or @p _Dist objects.
*/
variate_generator(engine_type __eng, distribution_type __dist)
: _M_engine(__eng), _M_dist(__dist) { }
/**
* Gets the next generated value on the distribution.
*/
result_type
operator()()
{ return _M_dist(_M_engine); }
/**
* WTF?
*/
template<typename _Tp>
result_type
operator()(_Tp __value)
{ return _M_dist(_M_engine, __value); }
/**
* Gets a reference to the underlying uniform random number generator
* object.
*/
engine_value_type&
engine()
{ return _M_engine; }
/**
* Gets a const reference to the underlying uniform random number
* generator object.
*/
const engine_value_type&
engine() const
{ return _M_engine; }
/**
* Gets a reference to the underlying random distribution.
*/
distribution_type&
distribution()
{ return _M_dist; }
/**
* Gets a const reference to the underlying random distribution.
*/
const distribution_type&
distribution() const
{ return _M_dist; }
/**
* Gets the closed lower bound of the distribution interval.
*/
result_type
min() const
{ return this->distribution().min(); }
/**
* Gets the closed upper bound of the distribution interval.
*/
result_type
max() const
{ return this->distribution().max(); }
private:
engine_value_type _M_engine;
distribution_type _M_dist;
};
/**
* @addtogroup tr1_random_generators Random Number Generators
* @ingroup tr1_random
*
* These classes define objects which provide random or pseudorandom
* numbers, either from a discrete or a continuous interval. The
* random number generator supplied as a part of this library are
* all uniform random number generators which provide a sequence of
* random number uniformly distributed over their range.
*
* A number generator is a function object with an operator() that
* takes zero arguments and returns a number.
*
* A compliant random number generator must satisfy the following
* requirements. <table border=1 cellpadding=10 cellspacing=0>
* <caption align=top>Random Number Generator Requirements</caption>
* <tr><td>To be documented.</td></tr> </table>
*
* @{
*/
/**
* @brief A model of a linear congruential random number generator.
*
* A random number generator that produces pseudorandom numbers using the
* linear function @f$x_{i+1}\leftarrow(ax_{i} + c) \bmod m @f$.
*
* The template parameter @p _UIntType must be an unsigned integral type
* large enough to store values up to (__m-1). If the template parameter
* @p __m is 0, the modulus @p __m used is
* std::numeric_limits<_UIntType>::max() plus 1. Otherwise, the template
* parameters @p __a and @p __c must be less than @p __m.
*
* The size of the state is @f$ 1 @f$.
*/
template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
class linear_congruential
{
__glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)
// __glibcpp_class_requires(__a < __m && __c < __m)
public:
/** The type of the generated random value. */
typedef _UIntType result_type;
/** The multiplier. */
static const _UIntType multiplier = __a;
/** An increment. */
static const _UIntType increment = __c;
/** The modulus. */
static const _UIntType modulus = __m;
/**
* Constructs a %linear_congruential random number generator engine with
* seed @p __s. The default seed value is 1.
*
* @param __s The initial seed value.
*/
explicit
linear_congruential(unsigned long __x0 = 1)
{ this->seed(__x0); }
/**
* Constructs a %linear_congruential random number generator engine
* seeded from the generator function @p __g.
*
* @param __g The seed generator function.
*/
template<class _Gen>
linear_congruential(_Gen& __g)
{ this->seed(__g); }
/**
* Reseeds the %linear_congruential random number generator engine
* sequence to the seed @g __s.
*
* @param __s The new seed.
*/
void
seed(unsigned long __s = 1);
/**
* Reseeds the %linear_congruential random number generator engine
* sequence using values from the generator function @p __g.
*
* @param __g the seed generator function.
*/
template<class _Gen>
void
seed(_Gen& __g)
{ seed(__g, typename is_fundamental<_Gen>::type()); }
/**
* Gets the smallest possible value in the output range.
*
* The minimum depends on the @p __c parameter: if it is zero, the
* minimum generated must be > 0, otherwise 0 is allowed.
*/
result_type
min() const
{ return (__detail::__mod<_UIntType, 1, 0, __m>(__c) == 0) ? 1 : 0; }
/**
* Gets the largest possible value in the output range.
*/
result_type
max() const
{ return __m - 1; }
/**
* Gets the next random number in the sequence.
*/
result_type
operator()();
/**
* Compares two linear congruential random number generator
* objects of the same type for equality.
*
* @param __lhs A linear congruential random number generator object.
* @param __rhs Another linear congruential random number generator obj.
*
* @returns true if the two objects are equal, false otherwise.
*/
friend bool
operator==(const linear_congruential& __lhs,
const linear_congruential& __rhs)
{ return __lhs._M_x == __rhs._M_x; }
/**
* Compares two linear congruential random number generator
* objects of the same type for inequality.
*
* @param __lhs A linear congruential random number generator object.
* @param __rhs Another linear congruential random number generator obj.
*
* @returns true if the two objects are not equal, false otherwise.
*/
friend bool
operator!=(const linear_congruential& __lhs,
const linear_congruential& __rhs)
{ return !(__lhs == __rhs); }
/**
* Writes the textual representation of the state x(i) of x to @p __os.
*
* @param __os The output stream.
* @param __lcr A % linear_congruential random number generator.
* @returns __os.
*/
template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
_UIntType1 __m1,
typename _CharT, typename _Traits>
friend std::basic_ostream<_CharT, _Traits>&
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
const linear_congruential<_UIntType1, __a1, __c1,
__m1>& __lcr);
/**
* Sets the state of the engine by reading its textual
* representation from @p __is.
*
* The textual representation must have been previously written using an
* output stream whose imbued locale and whose type's template
* specialization arguments _CharT and _Traits were the same as those of
* @p __is.
*
* @param __is The input stream.
* @param __lcr A % linear_congruential random number generator.
* @returns __is.
*/
template<class _UIntType1, _UIntType1 __a1, _UIntType1 __c1,
_UIntType1 __m1,
typename _CharT, typename _Traits>
friend std::basic_istream<_CharT, _Traits>&
operator>>(std::basic_istream<_CharT, _Traits>& __is,
linear_congruential<_UIntType1, __a1, __c1, __m1>& __lcr);
private:
template<class _Gen>
void
seed(_Gen& __g, true_type)
{ return seed(static_cast<unsigned long>(__g)); }
template<class _Gen>
void
seed(_Gen& __g, false_type);
_UIntType _M_x;
};
/**
* The classic Minimum Standard rand0 of Lewis, Goodman, and Miller.
*/
typedef linear_congruential<unsigned long, 16807, 0, 2147483647> minstd_rand0;
/**
* An alternative LCR (Lehmer Generator function) .
*/
typedef linear_congruential<unsigned long, 48271, 0, 2147483647> minstd_rand;
/**
* A generalized feedback shift register discrete random number generator.
*
* This algorithm avoids multiplication and division and is designed to be
* friendly to a pipelined architecture. If the parameters are chosen
* correctly, this generator will produce numbers with a very long period and
* fairly good apparent entropy, although still not cryptographically strong.
*
* The best way to use this generator is with the predefined mt19937 class.
*
* This algorithm was originally invented by Makoto Matsumoto and
* Takuji Nishimura.
*
* @var word_size The number of bits in each element of the state vector.
* @var state_size The degree of recursion.
* @var shift_size The period parameter.
* @var mask_bits The separation point bit index.
* @var parameter_a The last row of the twist matrix.
* @var output_u The first right-shift tempering matrix parameter.
* @var output_s The first left-shift tempering matrix parameter.
* @var output_b The first left-shift tempering matrix mask.
* @var output_t The second left-shift tempering matrix parameter.
* @var output_c The second left-shift tempering matrix mask.
* @var output_l The second right-shift tempering matrix parameter.
*/
template<class _UIntType, int __w, int __n, int __m, int __r,
_UIntType __a, int __u, int __s, _UIntType __b, int __t,
_UIntType __c, int __l>
class mersenne_twister
{
__glibcxx_class_requires(_UIntType, _UnsignedIntegerConcept)
public:
// types
typedef _UIntType result_type;
// parameter values
static const int word_size = __w;
static const int state_size = __n;
static const int shift_size = __m;
static const int mask_bits = __r;
static const _UIntType parameter_a = __a;
static const int output_u = __u;
static const int output_s = __s;
static const _UIntType output_b = __b;
static const int output_t = __t;
static const _UIntType output_c = __c;
static const int output_l = __l;
// constructors and member function
mersenne_twister()
{ seed(); }
explicit
mersenne_twister(unsigned long __value)
{ seed(__value); }
template<class _Gen>
mersenne_twister(_Gen& __g)
{ seed(__g); }
void
seed()
{ seed(5489UL); }
void
seed(unsigned long __value);
template<class _Gen>
void
seed(_Gen& __g)
{ seed(__g, typename is_fundamental<_Gen>::type()); }
result_type
min() const
{ return 0; }
result_type
max() const
{ return __detail::_Shift<_UIntType, __w>::__value - 1; }
result_type
operator()();
/**
* Compares two % mersenne_twister random number generator objects of
* the same type for equality.
*
* @param __lhs A % mersenne_twister random number generator object.
* @param __rhs Another % mersenne_twister random number generator
* object.
*
* @returns true if the two objects are equal, false otherwise.
*/
friend bool
operator==(const mersenne_twister& __lhs,
const mersenne_twister& __rhs)
{ return std::equal(__lhs._M_x, __lhs._M_x + state_size, __rhs._M_x); }
/**
* Compares two % mersenne_twister random number generator objects of
* the same type for inequality.
*
* @param __lhs A % mersenne_twister random number generator object.
* @param __rhs Another % mersenne_twister random number generator
* object.
*
* @returns true if the two objects are not equal, false otherwise.
*/
friend bool
operator!=(const mersenne_twister& __lhs,
const mersenne_twister& __rhs)
{ return !(__lhs == __rhs); }
/**
* Inserts the current state of a % mersenne_twister random number
* generator engine @p __x into the output stream @p __os.
*
* @param __os An output stream.
* @param __x A % mersenne_twister random number generator engine.
*
* @returns The output stream with the state of @p __x inserted or in
* an error state.
*/
template<class _UIntType1, int __w1, int __n1, int __m1, int __r1,
_UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1,
_UIntType1 __c1, int __l1,
typename _CharT, typename _Traits>
friend std::basic_ostream<_CharT, _Traits>&
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
const mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1,
__a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x);
/**
* Extracts the current state of a % mersenne_twister random number
* generator engine @p __x from the input stream @p __is.
*
* @param __is An input stream.
* @param __x A % mersenne_twister random number generator engine.
*
* @returns The input stream with the state of @p __x extracted or in
* an error state.
*/
template<class _UIntType1, int __w1, int __n1, int __m1, int __r1,
_UIntType1 __a1, int __u1, int __s1, _UIntType1 __b1, int __t1,
_UIntType1 __c1, int __l1,
typename _CharT, typename _Traits>
friend std::basic_istream<_CharT, _Traits>&
operator>>(std::basic_istream<_CharT, _Traits>& __is,
mersenne_twister<_UIntType1, __w1, __n1, __m1, __r1,
__a1, __u1, __s1, __b1, __t1, __c1, __l1>& __x);
private:
template<class _Gen>
void
seed(_Gen& __g, true_type)
{ return seed(static_cast<unsigned long>(__g)); }
template<class _Gen>
void
seed(_Gen& __g, false_type);
_UIntType _M_x[state_size];
int _M_p;
};
/**
* The classic Mersenne Twister.
*
* Reference:
* M. Matsumoto and T. Nishimura, Mersenne Twister: A 623-Dimensionally
* Equidistributed Uniform Pseudo-Random Number Generator, ACM Transactions
* on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
*/
typedef mersenne_twister<
unsigned long, 32, 624, 397, 31,
0x9908b0dful, 11, 7,
0x9d2c5680ul, 15,
0xefc60000ul, 18
> mt19937;
/**
* @brief The Marsaglia-Zaman generator.
*
* This is a model of a Generalized Fibonacci discrete random number
* generator, sometimes referred to as the SWC generator.
*
* A discrete random number generator that produces pseudorandom
* numbers using @f$x_{i}\leftarrow(x_{i - s} - x_{i - r} -
* carry_{i-1}) \bmod m @f$.
*
* The size of the state is @f$ r @f$
* and the maximum period of the generator is @f$ m^r - m^s -1 @f$.
*
* N1688[4.13] says <em>the template parameter _IntType shall denote
* an integral type large enough to store values up to m</em>.
*
* @var _M_x The state of the generator. This is a ring buffer.
* @var _M_carry The carry.
* @var _M_p Current index of x(i - r).
*/
template<typename _IntType, _IntType __m, int __s, int __r>
class subtract_with_carry
{
__glibcxx_class_requires(_IntType, _IntegerConcept)
public:
/** The type of the generated random value. */
typedef _IntType result_type;
// parameter values
static const _IntType modulus = __m;
static const int long_lag = __r;
static const int short_lag = __s;
/**
* Constructs a default-initialized % subtract_with_carry random number
* generator.
*/
subtract_with_carry()
{ this->seed(); }
/**
* Constructs an explicitly seeded % subtract_with_carry random number
* generator.
*/
explicit
subtract_with_carry(unsigned long __value)
{ this->seed(__value); }
/**
* Constructs a %subtract_with_carry random number generator engine
* seeded from the generator function @p __g.
*
* @param __g The seed generator function.
*/
template<class _Gen>
subtract_with_carry(_Gen& __g)
{ this->seed(__g); }
/**
* Seeds the initial state @f$ x_0 @f$ of the random number generator.
*
* N1688[4.19] modifies this as follows. If @p __value == 0,
* sets value to 19780503. In any case, with a linear
* congruential generator lcg(i) having parameters @f$ m_{lcg} =
* 2147483563, a_{lcg} = 40014, c_{lcg} = 0, and lcg(0) = value
* @f$, sets @f$ x_{-r} \dots x_{-1} @f$ to @f$ lcg(1) \bmod m
* \dots lcg(r) \bmod m @f$ respectively. If @f$ x_{-1} = 0 @f$
* set carry to 1, otherwise sets carry to 0.
*/
void
seed(unsigned long __value = 19780503);
/**
* Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry
* random number generator.
*/
template<class _Gen>
void
seed(_Gen& __g)
{ seed(__g, typename is_fundamental<_Gen>::type()); }
/**
* Gets the inclusive minimum value of the range of random integers
* returned by this generator.
*/
result_type
min() const
{ return 0; }
/**
* Gets the inclusive maximum value of the range of random integers
* returned by this generator.
*/
result_type
max() const
{ return this->modulus - 1; }
/**
* Gets the next random number in the sequence.
*/
result_type
operator()();
/**
* Compares two % subtract_with_carry random number generator objects of
* the same type for equality.
*
* @param __lhs A % subtract_with_carry random number generator object.
* @param __rhs Another % subtract_with_carry random number generator
* object.
*
* @returns true if the two objects are equal, false otherwise.
*/
friend bool
operator==(const subtract_with_carry& __lhs,
const subtract_with_carry& __rhs)
{ return std::equal(__lhs._M_x, __lhs._M_x + long_lag, __rhs._M_x); }
/**
* Compares two % subtract_with_carry random number generator objects of
* the same type for inequality.
*
* @param __lhs A % subtract_with_carry random number generator object.
* @param __rhs Another % subtract_with_carry random number generator
* object.
*
* @returns true if the two objects are not equal, false otherwise.
*/
friend bool
operator!=(const subtract_with_carry& __lhs,
const subtract_with_carry& __rhs)
{ return !(__lhs == __rhs); }
/**
* Inserts the current state of a % subtract_with_carry random number
* generator engine @p __x into the output stream @p __os.
*
* @param __os An output stream.
* @param __x A % subtract_with_carry random number generator engine.
*
* @returns The output stream with the state of @p __x inserted or in
* an error state.
*/
template<typename _IntType1, _IntType1 __m1, int __s1, int __r1,
typename _CharT, typename _Traits>
friend std::basic_ostream<_CharT, _Traits>&
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
const subtract_with_carry<_IntType1, __m1, __s1,
__r1>& __x);
/**
* Extracts the current state of a % subtract_with_carry random number
* generator engine @p __x from the input stream @p __is.
*
* @param __is An input stream.
* @param __x A % subtract_with_carry random number generator engine.
*
* @returns The input stream with the state of @p __x extracted or in
* an error state.
*/
template<typename _IntType1, _IntType1 __m1, int __s1, int __r1,
typename _CharT, typename _Traits>
friend std::basic_istream<_CharT, _Traits>&
operator>>(std::basic_istream<_CharT, _Traits>& __is,
subtract_with_carry<_IntType1, __m1, __s1, __r1>& __x);
private:
template<class _Gen>
void
seed(_Gen& __g, true_type)
{ return seed(static_cast<unsigned long>(__g)); }
template<class _Gen>
void
seed(_Gen& __g, false_type);
typedef typename __gnu_cxx::__add_unsigned<_IntType>::__type _UIntType;
_UIntType _M_x[long_lag];
_UIntType _M_carry;
int _M_p;
};
/**
* @brief The Marsaglia-Zaman generator (floats version).
*
* @var _M_x The state of the generator. This is a ring buffer.
* @var _M_carry The carry.
* @var _M_p Current index of x(i - r).
* @var _M_npows Precomputed negative powers of 2.
*/
template<typename _RealType, int __w, int __s, int __r>
class subtract_with_carry_01
{
public:
/** The type of the generated random value. */
typedef _RealType result_type;
// parameter values
static const int word_size = __w;
static const int long_lag = __r;
static const int short_lag = __s;
/**
* Constructs a default-initialized % subtract_with_carry_01 random
* number generator.
*/
subtract_with_carry_01()
{
this->seed();
_M_initialize_npows();
}
/**
* Constructs an explicitly seeded % subtract_with_carry_01 random number
* generator.
*/
explicit
subtract_with_carry_01(unsigned long __value)
{
this->seed(__value);
_M_initialize_npows();
}
/**
* Constructs a % subtract_with_carry_01 random number generator engine
* seeded from the generator function @p __g.
*
* @param __g The seed generator function.
*/
template<class _Gen>
subtract_with_carry_01(_Gen& __g)
{
this->seed(__g);
_M_initialize_npows();
}
/**
* Seeds the initial state @f$ x_0 @f$ of the random number generator.
*/
void
seed(unsigned long __value = 19780503);
/**
* Seeds the initial state @f$ x_0 @f$ of the % subtract_with_carry_01
* random number generator.
*/
template<class _Gen>
void
seed(_Gen& __g)
{ seed(__g, typename is_fundamental<_Gen>::type()); }
/**
* Gets the minimum value of the range of random floats
* returned by this generator.
*/
result_type
min() const
{ return 0.0; }
/**
* Gets the maximum value of the range of random floats
* returned by this generator.
*/
result_type
max() const
{ return 1.0; }
/**
* Gets the next random number in the sequence.
*/
result_type
operator()();
/**
* Compares two % subtract_with_carry_01 random number generator objects
* of the same type for equality.
*
* @param __lhs A % subtract_with_carry_01 random number
* generator object.
* @param __rhs Another % subtract_with_carry_01 random number generator
* object.
*
* @returns true if the two objects are equal, false otherwise.
*/
friend bool
operator==(const subtract_with_carry_01& __lhs,
const subtract_with_carry_01& __rhs)
{
for (int __i = 0; __i < long_lag; ++__i)
if (!std::equal(__lhs._M_x[__i], __lhs._M_x[__i] + __n,
__rhs._M_x[__i]))
return false;
return true;
}
/**
* Compares two % subtract_with_carry_01 random number generator objects
* of the same type for inequality.