1344cef66SArthur O'Dwyer //===----------------------------------------------------------------------===// 2344cef66SArthur O'Dwyer // 3344cef66SArthur O'Dwyer // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4344cef66SArthur O'Dwyer // See https://llvm.org/LICENSE.txt for license information. 5344cef66SArthur O'Dwyer // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6344cef66SArthur O'Dwyer // 7344cef66SArthur O'Dwyer //===----------------------------------------------------------------------===// 8344cef66SArthur O'Dwyer 9344cef66SArthur O'Dwyer #ifndef _LIBCPP___RANDOM_LINEAR_CONGRUENTIAL_ENGINE_H 10344cef66SArthur O'Dwyer #define _LIBCPP___RANDOM_LINEAR_CONGRUENTIAL_ENGINE_H 11344cef66SArthur O'Dwyer 12344cef66SArthur O'Dwyer #include <__config> 13344cef66SArthur O'Dwyer #include <__random/is_seed_sequence.h> 140a4aa8a1SNikolas Klauser #include <__type_traits/enable_if.h> 150a4aa8a1SNikolas Klauser #include <__type_traits/integral_constant.h> 160a4aa8a1SNikolas Klauser #include <__type_traits/is_unsigned.h> 17344cef66SArthur O'Dwyer #include <cstdint> 18344cef66SArthur O'Dwyer #include <iosfwd> 19344cef66SArthur O'Dwyer 20344cef66SArthur O'Dwyer #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 21344cef66SArthur O'Dwyer # pragma GCC system_header 22344cef66SArthur O'Dwyer #endif 23344cef66SArthur O'Dwyer 24344cef66SArthur O'Dwyer _LIBCPP_PUSH_MACROS 25344cef66SArthur O'Dwyer #include <__undef_macros> 26344cef66SArthur O'Dwyer 27344cef66SArthur O'Dwyer _LIBCPP_BEGIN_NAMESPACE_STD 28344cef66SArthur O'Dwyer 2941e69629SLRFLEW enum __lce_alg_type { 3041e69629SLRFLEW _LCE_Full, 3141e69629SLRFLEW _LCE_Part, 3241e69629SLRFLEW _LCE_Schrage, 3341e69629SLRFLEW _LCE_Promote, 34344cef66SArthur O'Dwyer }; 35344cef66SArthur O'Dwyer 369783f28cSLouis Dionne template <unsigned long long __a, 379783f28cSLouis Dionne unsigned long long __c, 389783f28cSLouis Dionne unsigned long long __m, 399783f28cSLouis Dionne unsigned long long _Mp, 4041e69629SLRFLEW bool _HasOverflow = (__a != 0ull && (__m & (__m - 1ull)) != 0ull), // a != 0, m != 0, m != 2^n 4141e69629SLRFLEW bool _Full = (!_HasOverflow || __m - 1ull <= (_Mp - __c) / __a), // (a * x + c) % m works 4241e69629SLRFLEW bool _Part = (!_HasOverflow || __m - 1ull <= _Mp / __a), // (a * x) % m works 4341e69629SLRFLEW bool _Schrage = (_HasOverflow && __m % __a <= __m / __a)> // r <= q 4441e69629SLRFLEW struct __lce_alg_picker { 4541e69629SLRFLEW static _LIBCPP_CONSTEXPR const __lce_alg_type __mode = 4641e69629SLRFLEW _Full ? _LCE_Full 4741e69629SLRFLEW : _Part ? _LCE_Part 4841e69629SLRFLEW : _Schrage ? _LCE_Schrage 4941e69629SLRFLEW : _LCE_Promote; 5041e69629SLRFLEW 51ba87515fSNikolas Klauser #if !_LIBCPP_HAS_INT128 5241e69629SLRFLEW static_assert(_Mp != (unsigned long long)(-1) || _Full || _Part || _Schrage, 5341e69629SLRFLEW "The current values for a, c, and m are not currently supported on platforms without __int128"); 5441e69629SLRFLEW #endif 5541e69629SLRFLEW }; 5641e69629SLRFLEW 5741e69629SLRFLEW template <unsigned long long __a, 5841e69629SLRFLEW unsigned long long __c, 5941e69629SLRFLEW unsigned long long __m, 6041e69629SLRFLEW unsigned long long _Mp, 6141e69629SLRFLEW __lce_alg_type _Mode = __lce_alg_picker<__a, __c, __m, _Mp>::__mode> 62344cef66SArthur O'Dwyer struct __lce_ta; 63344cef66SArthur O'Dwyer 64344cef66SArthur O'Dwyer // 64 65344cef66SArthur O'Dwyer 66ba87515fSNikolas Klauser #if _LIBCPP_HAS_INT128 6741e69629SLRFLEW template <unsigned long long _Ap, unsigned long long _Cp, unsigned long long _Mp> 6841e69629SLRFLEW struct __lce_ta<_Ap, _Cp, _Mp, (unsigned long long)(-1), _LCE_Promote> { 6941e69629SLRFLEW typedef unsigned long long result_type; 7041e69629SLRFLEW _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __xp) { 7141e69629SLRFLEW __extension__ using __calc_type = unsigned __int128; 7241e69629SLRFLEW const __calc_type __a = static_cast<__calc_type>(_Ap); 7341e69629SLRFLEW const __calc_type __c = static_cast<__calc_type>(_Cp); 7441e69629SLRFLEW const __calc_type __m = static_cast<__calc_type>(_Mp); 7541e69629SLRFLEW const __calc_type __x = static_cast<__calc_type>(__xp); 7641e69629SLRFLEW return static_cast<result_type>((__a * __x + __c) % __m); 7741e69629SLRFLEW } 7841e69629SLRFLEW }; 7941e69629SLRFLEW #endif 8041e69629SLRFLEW 81344cef66SArthur O'Dwyer template <unsigned long long __a, unsigned long long __c, unsigned long long __m> 8241e69629SLRFLEW struct __lce_ta<__a, __c, __m, (unsigned long long)(-1), _LCE_Schrage> { 83344cef66SArthur O'Dwyer typedef unsigned long long result_type; 849783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { 85344cef66SArthur O'Dwyer // Schrage's algorithm 86344cef66SArthur O'Dwyer const result_type __q = __m / __a; 87344cef66SArthur O'Dwyer const result_type __r = __m % __a; 88344cef66SArthur O'Dwyer const result_type __t0 = __a * (__x % __q); 89344cef66SArthur O'Dwyer const result_type __t1 = __r * (__x / __q); 90344cef66SArthur O'Dwyer __x = __t0 + (__t0 < __t1) * __m - __t1; 91344cef66SArthur O'Dwyer __x += __c - (__x >= __m - __c) * __m; 92344cef66SArthur O'Dwyer return __x; 93344cef66SArthur O'Dwyer } 94344cef66SArthur O'Dwyer }; 95344cef66SArthur O'Dwyer 96344cef66SArthur O'Dwyer template <unsigned long long __a, unsigned long long __m> 9741e69629SLRFLEW struct __lce_ta<__a, 0ull, __m, (unsigned long long)(-1), _LCE_Schrage> { 98344cef66SArthur O'Dwyer typedef unsigned long long result_type; 999783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { 100344cef66SArthur O'Dwyer // Schrage's algorithm 101344cef66SArthur O'Dwyer const result_type __q = __m / __a; 102344cef66SArthur O'Dwyer const result_type __r = __m % __a; 103344cef66SArthur O'Dwyer const result_type __t0 = __a * (__x % __q); 104344cef66SArthur O'Dwyer const result_type __t1 = __r * (__x / __q); 105344cef66SArthur O'Dwyer __x = __t0 + (__t0 < __t1) * __m - __t1; 106344cef66SArthur O'Dwyer return __x; 107344cef66SArthur O'Dwyer } 108344cef66SArthur O'Dwyer }; 109344cef66SArthur O'Dwyer 110344cef66SArthur O'Dwyer template <unsigned long long __a, unsigned long long __c, unsigned long long __m> 11141e69629SLRFLEW struct __lce_ta<__a, __c, __m, (unsigned long long)(-1), _LCE_Part> { 11241e69629SLRFLEW typedef unsigned long long result_type; 11341e69629SLRFLEW _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { 11441e69629SLRFLEW // Use (((a*x) % m) + c) % m 11541e69629SLRFLEW __x = (__a * __x) % __m; 11641e69629SLRFLEW __x += __c - (__x >= __m - __c) * __m; 11741e69629SLRFLEW return __x; 11841e69629SLRFLEW } 11941e69629SLRFLEW }; 12041e69629SLRFLEW 12141e69629SLRFLEW template <unsigned long long __a, unsigned long long __c, unsigned long long __m> 12241e69629SLRFLEW struct __lce_ta<__a, __c, __m, (unsigned long long)(-1), _LCE_Full> { 123344cef66SArthur O'Dwyer typedef unsigned long long result_type; 1249783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { return (__a * __x + __c) % __m; } 125344cef66SArthur O'Dwyer }; 126344cef66SArthur O'Dwyer 127344cef66SArthur O'Dwyer template <unsigned long long __a, unsigned long long __c> 12841e69629SLRFLEW struct __lce_ta<__a, __c, 0ull, (unsigned long long)(-1), _LCE_Full> { 129344cef66SArthur O'Dwyer typedef unsigned long long result_type; 1309783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { return __a * __x + __c; } 131344cef66SArthur O'Dwyer }; 132344cef66SArthur O'Dwyer 133344cef66SArthur O'Dwyer // 32 134344cef66SArthur O'Dwyer 13541e69629SLRFLEW template <unsigned long long __a, unsigned long long __c, unsigned long long __m> 13641e69629SLRFLEW struct __lce_ta<__a, __c, __m, unsigned(-1), _LCE_Promote> { 13741e69629SLRFLEW typedef unsigned result_type; 13841e69629SLRFLEW _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { 13941e69629SLRFLEW return static_cast<result_type>(__lce_ta<__a, __c, __m, (unsigned long long)(-1)>::next(__x)); 14041e69629SLRFLEW } 14141e69629SLRFLEW }; 14241e69629SLRFLEW 143344cef66SArthur O'Dwyer template <unsigned long long _Ap, unsigned long long _Cp, unsigned long long _Mp> 14441e69629SLRFLEW struct __lce_ta<_Ap, _Cp, _Mp, unsigned(-1), _LCE_Schrage> { 145344cef66SArthur O'Dwyer typedef unsigned result_type; 1469783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { 147344cef66SArthur O'Dwyer const result_type __a = static_cast<result_type>(_Ap); 148344cef66SArthur O'Dwyer const result_type __c = static_cast<result_type>(_Cp); 149344cef66SArthur O'Dwyer const result_type __m = static_cast<result_type>(_Mp); 150344cef66SArthur O'Dwyer // Schrage's algorithm 151344cef66SArthur O'Dwyer const result_type __q = __m / __a; 152344cef66SArthur O'Dwyer const result_type __r = __m % __a; 153344cef66SArthur O'Dwyer const result_type __t0 = __a * (__x % __q); 154344cef66SArthur O'Dwyer const result_type __t1 = __r * (__x / __q); 155344cef66SArthur O'Dwyer __x = __t0 + (__t0 < __t1) * __m - __t1; 156344cef66SArthur O'Dwyer __x += __c - (__x >= __m - __c) * __m; 157344cef66SArthur O'Dwyer return __x; 158344cef66SArthur O'Dwyer } 159344cef66SArthur O'Dwyer }; 160344cef66SArthur O'Dwyer 161344cef66SArthur O'Dwyer template <unsigned long long _Ap, unsigned long long _Mp> 16241e69629SLRFLEW struct __lce_ta<_Ap, 0ull, _Mp, unsigned(-1), _LCE_Schrage> { 163344cef66SArthur O'Dwyer typedef unsigned result_type; 1649783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { 165344cef66SArthur O'Dwyer const result_type __a = static_cast<result_type>(_Ap); 166344cef66SArthur O'Dwyer const result_type __m = static_cast<result_type>(_Mp); 167344cef66SArthur O'Dwyer // Schrage's algorithm 168344cef66SArthur O'Dwyer const result_type __q = __m / __a; 169344cef66SArthur O'Dwyer const result_type __r = __m % __a; 170344cef66SArthur O'Dwyer const result_type __t0 = __a * (__x % __q); 171344cef66SArthur O'Dwyer const result_type __t1 = __r * (__x / __q); 172344cef66SArthur O'Dwyer __x = __t0 + (__t0 < __t1) * __m - __t1; 173344cef66SArthur O'Dwyer return __x; 174344cef66SArthur O'Dwyer } 175344cef66SArthur O'Dwyer }; 176344cef66SArthur O'Dwyer 177344cef66SArthur O'Dwyer template <unsigned long long _Ap, unsigned long long _Cp, unsigned long long _Mp> 17841e69629SLRFLEW struct __lce_ta<_Ap, _Cp, _Mp, unsigned(-1), _LCE_Part> { 17941e69629SLRFLEW typedef unsigned result_type; 18041e69629SLRFLEW _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { 18141e69629SLRFLEW const result_type __a = static_cast<result_type>(_Ap); 18241e69629SLRFLEW const result_type __c = static_cast<result_type>(_Cp); 18341e69629SLRFLEW const result_type __m = static_cast<result_type>(_Mp); 18441e69629SLRFLEW // Use (((a*x) % m) + c) % m 18541e69629SLRFLEW __x = (__a * __x) % __m; 18641e69629SLRFLEW __x += __c - (__x >= __m - __c) * __m; 18741e69629SLRFLEW return __x; 18841e69629SLRFLEW } 18941e69629SLRFLEW }; 19041e69629SLRFLEW 19141e69629SLRFLEW template <unsigned long long _Ap, unsigned long long _Cp, unsigned long long _Mp> 19241e69629SLRFLEW struct __lce_ta<_Ap, _Cp, _Mp, unsigned(-1), _LCE_Full> { 193344cef66SArthur O'Dwyer typedef unsigned result_type; 1949783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { 195344cef66SArthur O'Dwyer const result_type __a = static_cast<result_type>(_Ap); 196344cef66SArthur O'Dwyer const result_type __c = static_cast<result_type>(_Cp); 197344cef66SArthur O'Dwyer const result_type __m = static_cast<result_type>(_Mp); 198344cef66SArthur O'Dwyer return (__a * __x + __c) % __m; 199344cef66SArthur O'Dwyer } 200344cef66SArthur O'Dwyer }; 201344cef66SArthur O'Dwyer 202344cef66SArthur O'Dwyer template <unsigned long long _Ap, unsigned long long _Cp> 20341e69629SLRFLEW struct __lce_ta<_Ap, _Cp, 0ull, unsigned(-1), _LCE_Full> { 204344cef66SArthur O'Dwyer typedef unsigned result_type; 2059783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { 206344cef66SArthur O'Dwyer const result_type __a = static_cast<result_type>(_Ap); 207344cef66SArthur O'Dwyer const result_type __c = static_cast<result_type>(_Cp); 208344cef66SArthur O'Dwyer return __a * __x + __c; 209344cef66SArthur O'Dwyer } 210344cef66SArthur O'Dwyer }; 211344cef66SArthur O'Dwyer 212344cef66SArthur O'Dwyer // 16 213344cef66SArthur O'Dwyer 21441e69629SLRFLEW template <unsigned long long __a, unsigned long long __c, unsigned long long __m, __lce_alg_type __mode> 21541e69629SLRFLEW struct __lce_ta<__a, __c, __m, (unsigned short)(-1), __mode> { 216344cef66SArthur O'Dwyer typedef unsigned short result_type; 2179783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static result_type next(result_type __x) { 21841e69629SLRFLEW return static_cast<result_type>(__lce_ta<__a, __c, __m, unsigned(-1)>::next(__x)); 219344cef66SArthur O'Dwyer } 220344cef66SArthur O'Dwyer }; 221344cef66SArthur O'Dwyer 222344cef66SArthur O'Dwyer template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 223344cef66SArthur O'Dwyer class _LIBCPP_TEMPLATE_VIS linear_congruential_engine; 224344cef66SArthur O'Dwyer 2259783f28cSLouis Dionne template <class _CharT, class _Traits, class _Up, _Up _Ap, _Up _Cp, _Up _Np> 2269783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& 2279783f28cSLouis Dionne operator<<(basic_ostream<_CharT, _Traits>& __os, const linear_congruential_engine<_Up, _Ap, _Cp, _Np>&); 228344cef66SArthur O'Dwyer 2299783f28cSLouis Dionne template <class _CharT, class _Traits, class _Up, _Up _Ap, _Up _Cp, _Up _Np> 23080c7e93aSNikolas Klauser _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 2319783f28cSLouis Dionne operator>>(basic_istream<_CharT, _Traits>& __is, linear_congruential_engine<_Up, _Ap, _Cp, _Np>& __x); 232344cef66SArthur O'Dwyer 233344cef66SArthur O'Dwyer template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 2349783f28cSLouis Dionne class _LIBCPP_TEMPLATE_VIS linear_congruential_engine { 235344cef66SArthur O'Dwyer public: 236344cef66SArthur O'Dwyer // types 237344cef66SArthur O'Dwyer typedef _UIntType result_type; 238344cef66SArthur O'Dwyer 239344cef66SArthur O'Dwyer private: 240344cef66SArthur O'Dwyer result_type __x_; 241344cef66SArthur O'Dwyer 24241e69629SLRFLEW static _LIBCPP_CONSTEXPR const result_type _Mp = result_type(-1); 243344cef66SArthur O'Dwyer 244344cef66SArthur O'Dwyer static_assert(__m == 0 || __a < __m, "linear_congruential_engine invalid parameters"); 245344cef66SArthur O'Dwyer static_assert(__m == 0 || __c < __m, "linear_congruential_engine invalid parameters"); 246344cef66SArthur O'Dwyer static_assert(is_unsigned<_UIntType>::value, "_UIntType must be unsigned type"); 2479783f28cSLouis Dionne 248344cef66SArthur O'Dwyer public: 249344cef66SArthur O'Dwyer static _LIBCPP_CONSTEXPR const result_type _Min = __c == 0u ? 1u : 0u; 250e39095a3SLouis Dionne static _LIBCPP_CONSTEXPR const result_type _Max = __m - _UIntType(1u); 251344cef66SArthur O'Dwyer static_assert(_Min < _Max, "linear_congruential_engine invalid parameters"); 252344cef66SArthur O'Dwyer 253344cef66SArthur O'Dwyer // engine characteristics 254*b69ddbc6SNikolas Klauser static inline _LIBCPP_CONSTEXPR const result_type multiplier = __a; 255*b69ddbc6SNikolas Klauser static inline _LIBCPP_CONSTEXPR const result_type increment = __c; 256*b69ddbc6SNikolas Klauser static inline _LIBCPP_CONSTEXPR const result_type modulus = __m; 2579783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR result_type min() { return _Min; } 2589783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR result_type max() { return _Max; } 259*b69ddbc6SNikolas Klauser static inline _LIBCPP_CONSTEXPR const result_type default_seed = 1u; 260344cef66SArthur O'Dwyer 261344cef66SArthur O'Dwyer // constructors and seeding functions 262344cef66SArthur O'Dwyer #ifndef _LIBCPP_CXX03_LANG 2639783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI linear_congruential_engine() : linear_congruential_engine(default_seed) {} 2649783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit linear_congruential_engine(result_type __s) { seed(__s); } 265344cef66SArthur O'Dwyer #else 2669783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit linear_congruential_engine(result_type __s = default_seed) { seed(__s); } 267344cef66SArthur O'Dwyer #endif 2684da76ea7SNikolas Klauser template <class _Sseq, __enable_if_t<__is_seed_sequence<_Sseq, linear_congruential_engine>::value, int> = 0> 2699783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI explicit linear_congruential_engine(_Sseq& __q) { 2709783f28cSLouis Dionne seed(__q); 2719783f28cSLouis Dionne } 2729783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void seed(result_type __s = default_seed) { 2739783f28cSLouis Dionne seed(integral_constant<bool, __m == 0>(), integral_constant<bool, __c == 0>(), __s); 2749783f28cSLouis Dionne } 275475bd19eSNikolas Klauser template <class _Sseq, __enable_if_t<__is_seed_sequence<_Sseq, linear_congruential_engine>::value, int> = 0> 2769783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void seed(_Sseq& __q) { 2779783f28cSLouis Dionne __seed( 2789783f28cSLouis Dionne __q, 2799783f28cSLouis Dionne integral_constant<unsigned, 2809783f28cSLouis Dionne 1 + (__m == 0 ? (sizeof(result_type) * __CHAR_BIT__ - 1) / 32 : (__m > 0x100000000ull))>()); 2819783f28cSLouis Dionne } 282344cef66SArthur O'Dwyer 283344cef66SArthur O'Dwyer // generating functions 2849783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI result_type operator()() { 2859783f28cSLouis Dionne return __x_ = static_cast<result_type>(__lce_ta<__a, __c, __m, _Mp>::next(__x_)); 2869783f28cSLouis Dionne } 2879783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void discard(unsigned long long __z) { 2889783f28cSLouis Dionne for (; __z; --__z) 2899783f28cSLouis Dionne operator()(); 2909783f28cSLouis Dionne } 291344cef66SArthur O'Dwyer 2929783f28cSLouis Dionne friend _LIBCPP_HIDE_FROM_ABI bool 2939783f28cSLouis Dionne operator==(const linear_congruential_engine& __x, const linear_congruential_engine& __y) { 2949783f28cSLouis Dionne return __x.__x_ == __y.__x_; 2959783f28cSLouis Dionne } 2969783f28cSLouis Dionne friend _LIBCPP_HIDE_FROM_ABI bool 2979783f28cSLouis Dionne operator!=(const linear_congruential_engine& __x, const linear_congruential_engine& __y) { 2989783f28cSLouis Dionne return !(__x == __y); 2999783f28cSLouis Dionne } 300344cef66SArthur O'Dwyer 301344cef66SArthur O'Dwyer private: 3029783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void seed(true_type, true_type, result_type __s) { __x_ = __s == 0 ? 1 : __s; } 3039783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void seed(true_type, false_type, result_type __s) { __x_ = __s; } 3049783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void seed(false_type, true_type, result_type __s) { __x_ = __s % __m == 0 ? 1 : __s % __m; } 3059783f28cSLouis Dionne _LIBCPP_HIDE_FROM_ABI void seed(false_type, false_type, result_type __s) { __x_ = __s % __m; } 306344cef66SArthur O'Dwyer 307344cef66SArthur O'Dwyer template <class _Sseq> 30883ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 1>); 309344cef66SArthur O'Dwyer template <class _Sseq> 31083ce1397SNikolas Klauser _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 2>); 311344cef66SArthur O'Dwyer 3129783f28cSLouis Dionne template <class _CharT, class _Traits, class _Up, _Up _Ap, _Up _Cp, _Up _Np> 3139783f28cSLouis Dionne friend basic_ostream<_CharT, _Traits>& 3149783f28cSLouis Dionne operator<<(basic_ostream<_CharT, _Traits>& __os, const linear_congruential_engine<_Up, _Ap, _Cp, _Np>&); 315344cef66SArthur O'Dwyer 3169783f28cSLouis Dionne template <class _CharT, class _Traits, class _Up, _Up _Ap, _Up _Cp, _Up _Np> 3179783f28cSLouis Dionne friend basic_istream<_CharT, _Traits>& 3189783f28cSLouis Dionne operator>>(basic_istream<_CharT, _Traits>& __is, linear_congruential_engine<_Up, _Ap, _Cp, _Np>& __x); 319344cef66SArthur O'Dwyer }; 320344cef66SArthur O'Dwyer 321344cef66SArthur O'Dwyer template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 322344cef66SArthur O'Dwyer template <class _Sseq> 3239783f28cSLouis Dionne void linear_congruential_engine<_UIntType, __a, __c, __m>::__seed(_Sseq& __q, integral_constant<unsigned, 1>) { 324344cef66SArthur O'Dwyer const unsigned __k = 1; 325344cef66SArthur O'Dwyer uint32_t __ar[__k + 3]; 326344cef66SArthur O'Dwyer __q.generate(__ar, __ar + __k + 3); 327344cef66SArthur O'Dwyer result_type __s = static_cast<result_type>(__ar[3] % __m); 328344cef66SArthur O'Dwyer __x_ = __c == 0 && __s == 0 ? result_type(1) : __s; 329344cef66SArthur O'Dwyer } 330344cef66SArthur O'Dwyer 331344cef66SArthur O'Dwyer template <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 332344cef66SArthur O'Dwyer template <class _Sseq> 3339783f28cSLouis Dionne void linear_congruential_engine<_UIntType, __a, __c, __m>::__seed(_Sseq& __q, integral_constant<unsigned, 2>) { 334344cef66SArthur O'Dwyer const unsigned __k = 2; 335344cef66SArthur O'Dwyer uint32_t __ar[__k + 3]; 336344cef66SArthur O'Dwyer __q.generate(__ar, __ar + __k + 3); 3379783f28cSLouis Dionne result_type __s = static_cast<result_type>((__ar[3] + ((uint64_t)__ar[4] << 32)) % __m); 338344cef66SArthur O'Dwyer __x_ = __c == 0 && __s == 0 ? result_type(1) : __s; 339344cef66SArthur O'Dwyer } 340344cef66SArthur O'Dwyer 3419783f28cSLouis Dionne template <class _CharT, class _Traits, class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 3429783f28cSLouis Dionne inline _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& 3439783f28cSLouis Dionne operator<<(basic_ostream<_CharT, _Traits>& __os, const linear_congruential_engine<_UIntType, __a, __c, __m>& __x) { 344344cef66SArthur O'Dwyer __save_flags<_CharT, _Traits> __lx(__os); 345344cef66SArthur O'Dwyer typedef basic_ostream<_CharT, _Traits> _Ostream; 346344cef66SArthur O'Dwyer __os.flags(_Ostream::dec | _Ostream::left); 347344cef66SArthur O'Dwyer __os.fill(__os.widen(' ')); 348344cef66SArthur O'Dwyer return __os << __x.__x_; 349344cef66SArthur O'Dwyer } 350344cef66SArthur O'Dwyer 3519783f28cSLouis Dionne template <class _CharT, class _Traits, class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m> 35280c7e93aSNikolas Klauser _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& 3539783f28cSLouis Dionne operator>>(basic_istream<_CharT, _Traits>& __is, linear_congruential_engine<_UIntType, __a, __c, __m>& __x) { 354344cef66SArthur O'Dwyer __save_flags<_CharT, _Traits> __lx(__is); 355344cef66SArthur O'Dwyer typedef basic_istream<_CharT, _Traits> _Istream; 356344cef66SArthur O'Dwyer __is.flags(_Istream::dec | _Istream::skipws); 357344cef66SArthur O'Dwyer _UIntType __t; 358344cef66SArthur O'Dwyer __is >> __t; 359344cef66SArthur O'Dwyer if (!__is.fail()) 360344cef66SArthur O'Dwyer __x.__x_ = __t; 361344cef66SArthur O'Dwyer return __is; 362344cef66SArthur O'Dwyer } 363344cef66SArthur O'Dwyer 3649783f28cSLouis Dionne typedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647> minstd_rand0; 3659783f28cSLouis Dionne typedef linear_congruential_engine<uint_fast32_t, 48271, 0, 2147483647> minstd_rand; 366344cef66SArthur O'Dwyer 367344cef66SArthur O'Dwyer _LIBCPP_END_NAMESPACE_STD 368344cef66SArthur O'Dwyer 369344cef66SArthur O'Dwyer _LIBCPP_POP_MACROS 370344cef66SArthur O'Dwyer 371344cef66SArthur O'Dwyer #endif // _LIBCPP___RANDOM_LINEAR_CONGRUENTIAL_ENGINE_H 372