1 // random TR1 header
2 #pragma once
3 #ifndef _RANDOM_
4 #define _RANDOM_
5 #ifndef RC_INVOKED
6 #include <istream>
7 #include <limits>
8 #include <vector>
9 #include <xtr1common>
10
11  #pragma pack(push,_CRT_PACKING)
12  #pragma warning(push,3)
13  #pragma warning(disable: 4127 4244 4521 6294)
14
15  #ifndef _BITS_BYTE
16   #define _BITS_BYTE    8
17  #endif /* _BITS_BYTE */
18
19  #if defined(_DEBUG) || defined(_RNG_CHECK)
20   #define _RNG_QUOTX(x) #x
21   #define _RNG_QUOT(x) _RNG_QUOTX(x)
22   #define _RNG_ASSERT(ex, msg)    \
23     ((ex) ? (void)0 : _Rng_abort(__FILE__ "(" _RNG_QUOT(__LINE__) "): " msg))
24
25  #else /* defined(_DEBUG) || defined(_RNG_CHECK) */
26   #define _RNG_ASSERT(ex, msg) ((void)0)
27  #endif /* defined(_DEBUG) || defined(_RNG_CHECK) */
28
29 _STD_BEGIN
30     namespace tr1 {    // TR1 additions
31
32     // CONSTANTS
33 static const long double _Pi = 3.14159265358979323846264338327950288;
34 static const long double _Exp1 = 2.71828182845904523536028747135266250;
35 static const long double _Two32 = 4294967296.0;
36 static const long double _Two31 = 2147483648.0;
37
38     // HELPER FUNCTIONS
39 _CRTIMP2_PURE __declspec(noreturn) void __CLRCALL_PURE_OR_CDECL
40     _Xinvalid(_In_z_ const char *_Msg = "");
41 _CRTIMP2_PURE __declspec(noreturn) void __CLRCALL_PURE_OR_CDECL
42     _Rng_abort(_In_z_ const char *_Msg);
43 _CRTIMP2_PURE float __CLRCALL_PURE_OR_CDECL _XLgamma(float);
44 _CRTIMP2_PURE double __CLRCALL_PURE_OR_CDECL _XLgamma(double);
45 _CRTIMP2_PURE long double __CLRCALL_PURE_OR_CDECL _XLgamma(long double);
46
47     // TEMPLATE FUNCTION _Nrand
48 #define _NRAND(eng, resty)    _Nrand(eng, (eng.min)(), (resty)1)
49
50 template<class _Engine,
51     class _Ety,
52     class _Rty>
53     _Rty _Nrand(_Engine& _Eng, _Ety _Emin, _Rty _Inc)
54     {    // scale random value to [0, 1), integer engine
55     return ((_Eng() - _Emin)
56         / ((_Rty)(_Eng.max)() - (_Rty)_Emin + _Inc));
57     }
58
59 template<class _Engine,
60     class _Rty>
61     _Rty _Nrand(_Engine& _Eng, float _Emin, _Rty)
62     {    // scale random value to [0, 1), float engine
63     return ((_Eng() - _Emin) / ((_Eng.max)() - _Emin));
64     }
65
66 template<class _Engine,
67     class _Rty>
68     _Rty _Nrand(_Engine& _Eng, double _Emin, _Rty)
69     {    // scale random value to [0, 1), double engine
Lines 70 ... 341 are skipped.
342
343     result_type operator()()
344         {    // return next value
345         return (_Dist(_Eng));
346         }
347
348     template<class _Ty>
349         result_type operator()(_Ty _Value)
350         {    // return next value that doesn't exceed _Value
351         return (_Dist(_Eng, _Value));
352         }
353
354     engine_value_type& engine()
355         {    // return reference to engine object
356         return (_Eng._Get());
357         }
358
359     const engine_value_type& engine() const
360         {    // return const reference to engine    object
361         return (_Eng._Get());
362         }
363
364     distribution_type& distribution()
365         {    // return reference to distribution object
366         return (_Dist);
367         }
368
369     const distribution_type& distribution() const
370         {    // return const reference to distribution object
371         return (_Dist);
372         }
373
374     result_type (min)() const
375         {    // return minimum value in distribution's range
376         return ((_Dist.min)());
377         }
378
379     result_type (max)() const
380         {    // return maximum value in distribution's range
381         return ((_Dist.max)());
382         }
383
384 private:
385     _Eng_wrapper _Eng;
386     distribution_type _Dist;
387     };
388
389     // MULTIPLE PRECISION MATH FUNCTIONS
390
391 #ifdef _ULONGLONG
392 typedef _ULONGLONG _Max_type;
393
394 #else /* _ULONGLONG */
395 typedef unsigned long _Max_type;
396 #endif /* _ULONGLONG */
397
398 static const int _MP_len = 5;
399 typedef _Max_type _MP_arr[_MP_len];
400
401 _CRTIMP2_PURE _Max_type __CLRCALL_PURE_OR_CDECL _MP_Get(_MP_arr);
402 _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _MP_Add(_MP_arr, _Max_type);
403 _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _MP_Mul(_MP_arr, _Max_type, _Max_type);
404 _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _MP_Rem(_MP_arr, _Max_type);
405
406     // TEMPLATE CLASS linear_congruential
407 template<class _Ity,
408     class _Ty,
409     _Max_type _Ax,
410     _Max_type _Cx,
411     _Max_type _Mx>
412     struct _Mul_mod
413     {    // template class for linear congruential generator where
414         // _Ty is large enough to hold intermediate result without overflow
415     _Mul_mod(_Ty _Val = 0)
416         : _Prev(_Val)
417         {    // construct
418         }
419
420     _Ty operator()()
421         {    // return next value
422         static _Ty _Zero = 0;    // to quiet diagnostics
423         _Ty _Divisor = (_Ty)_Mx;
424
425         _Prev = _Mx ? ((_Ity)_Ax * _Prev + (_Ty)_Cx) % _Divisor
426             : ((_Ity)_Ax * _Prev + (_Ty)_Cx);
427         if (_Prev < _Zero)
428             _Prev += (_Ty)_Mx;
429         return (_Prev);
430         }
431
432     _Ty _Prev;
433     };
434
435 template<class _Ty,
436     _Max_type _Ax,
437     _Max_type _Cx,
438     _Max_type _Mx>
439     class _Mult_prec
440     {    // template class for linear congruential generator using
441         // multiple precision arithmetic to avoid overflows
442 public:
443     _Mult_prec(_Ty _Val = 0)
444         : _Prev(_Val)
445         {    // construct
446         }
447
448     _Ty operator()()
449         {    // return next value
450         _MP_arr _Wx;
451         _MP_Mul(_Wx, _Prev, _Ax);
452         _MP_Add(_Wx, _Cx);
453         _MP_Rem(_Wx, _Mx);
454         _Prev = _MP_Get(_Wx);
455         return (_Prev);
456         }
457
458     _Ty _Prev;
459     };
460
461 #ifdef _ULONGLONG
462 template<class _Ty,
463     _Max_type _Ax,
464     _Max_type _Cx,
465     _Max_type _Mx,
466     bool>
467     struct _Select_ulonglong
468     {    // unsigned long long too small, use multiple precision
469     typedef _Mult_prec<_Ty, _Ax, _Cx, _Mx> _Type;
470     };
471
472 template<class _Ty,
473     _Max_type _Ax,
474     _Max_type _Cx,
475     _Max_type _Mx>
476     struct _Select_ulonglong<_Ty, _Ax, _Cx, _Mx, true>
477     {    // unsigned long long can hold intermediate result
478     typedef _Mul_mod<_ULONGLONG, _Ty, _Ax, _Cx, _Mx> _Type;
479     };
480
481 template<class _Ty,
482     _Max_type _Ax,
483     _Max_type _Cx,
484     _Max_type _Mx,
485     bool>
486     struct _Select_ulong
487     {    // unsigned long too small, try unsigned long long
488     typedef typename _Select_ulonglong<_Ty, _Ax, _Cx, _Mx,
489         _Cx < _ULLONG_MAX && _Mx <= (_ULLONG_MAX - _Cx) / _Ax>::_Type _Type;
490     };
491
492 #else /* _ULONGLONG */
493 template<class _Ty,
494     _Max_type _Ax,
495     _Max_type _Cx,
496     _Max_type _Mx,
497     bool>
498     struct _Select_ulong
499     {    // unsigned long too small, use multiple precision
500     typedef _Mult_prec<_Ty, _Ax, _Cx, _Mx> _Type;
501     };
502 #endif /* _ULONGLONG */
503
504 template<class _Ty,
505     _Max_type _Ax,
506     _Max_type _Cx,
507     _Max_type _Mx>
508     struct _Select_ulong<_Ty, _Ax, _Cx, _Mx, true>
509     {    // unsigned long can hold intermediate result
510     typedef _Mul_mod<unsigned long, _Ty, _Ax, _Cx, _Mx> _Type;
511     };
Lines 512 ... 3408 are skipped.
3409     {    // class to generate random numbers (from hardware where available)
3410 public:
3411     typedef unsigned int result_type;
3412
3413     explicit random_device(const std::string& = "")
3414         {    // construct
3415         (*this)();    // force early failure if bad engine
3416         }
3417
3418     result_type (min)() const
3419         {    // return minimum possible generated value
3420         return (0);
3421         }
3422
3423     result_type (max)() const
3424         {    // return maximum possible generated value
3425         return ((result_type)-1);
3426         }
3427
3428     double entropy()
3429         {    // return entropy of random number source
3430         return (32.0);
3431         }
3432
3433     result_type operator()()
3434         {    // return next value
3435         return (_Random_device());
3436         }
3437
3438 private:
3439     random_device(const random_device&);
3440     random_device& operator=(const random_device&);
3441     };
3442
3443     }    // namespace tr1
3444
3445 _STD_END
3446  #pragma warning(default: 4127 4244 4521 6294)
3447  #pragma warning(pop)
3448  #pragma pack(pop)
3449
3450 #endif /* RC_INVOKED */
3451 #endif /* _RANDOM_ */
3452
3453 /*
3454  * Copyright (c) 1992-2008 by P.J. Plauger.  ALL RIGHTS RESERVED.
3455  * Consult your license regarding permissions and restrictions.
3456 V5.05:0009 */
3457