diff --git a/stl/inc/random b/stl/inc/random index 90ae36415a5..6d6e2baa544 100644 --- a/stl/inc/random +++ b/stl/inc/random @@ -24,6 +24,7 @@ _STL_DISABLE_CLANG_WARNINGS #pragma push_macro("new") #undef new +#if _HAS_TR1_NAMESPACE // TRANSITION, GH-183 #pragma push_macro("discard_block") #pragma push_macro("linear_congruential") @@ -37,6 +38,7 @@ _STL_DISABLE_CLANG_WARNINGS #undef subtract_with_carry #undef uniform_int #undef uniform_real +#endif // _HAS_TR1_NAMESPACE #ifdef _ALLOW_RANDOM_DISTRIBUTION_CONST_OPERATOR #define _DISTRIBUTION_CONST const @@ -670,6 +672,7 @@ private: result_type _Prev; }; +#if _HAS_TR1_NAMESPACE template class _DEPRECATE_TR1_RANDOM linear_congruential { // linear congruential random engine public: @@ -757,6 +760,7 @@ public: private: _Uint _Prev; }; +#endif // _HAS_TR1_NAMESPACE template struct _Circ_buf { // holds historical values for generators @@ -959,26 +963,23 @@ struct _Swc_traits { // traits for subtract_with_carry generator static constexpr _Mod_t _Mod = _Mx; static constexpr _Ty _Max = static_cast<_Ty>(_Mx - 1); - static int _Get_wc() noexcept { // compute number of 32-bit words per element - int _Kx; - +private: + static constexpr int _Get_wc() noexcept { // compute number of 32-bit words per element if constexpr (_Mx == 0) { - _Kx = (8 * sizeof(_Ty) + 31) / 32; - } else { // compute number of 32-bit words required - unsigned long long _Val = 1ULL << 32; - for (_Kx = 1; 0 < _Val && _Val < _Mx; ++_Kx) { - _Val = _Val << 32; - } + return (8 * sizeof(_Ty) + 31) / 32; + } else if constexpr (_Mx > (1ULL << 32)) { + return 2; + } else { + return 1; } - - return _Kx; } +public: template static _Cy_t _Reset(_Gen& _Gx, _Ty* _Ax, bool _Readcy) { // set initial values of _Ax from generator _Gx // return value of _Cy from range if _Readcy is true, // otherwise compute from last value - int _Kx = _Get_wc(); + constexpr int _Kx = _Get_wc(); for (size_t _Ix = 0; _Ix < _Nw; ++_Ix) { // pack _Kx words _Ax[_Ix] = _Gx(); @@ -1011,7 +1012,7 @@ struct _Swc_traits { // traits for subtract_with_carry generator template static void _Write( basic_ostream<_Elem, _Traits>& _Ostr, const _Circ_buf<_Ty, _Nw>& _Buf, _Cy_t _Cy) { // write state to _Ostr - int _Kx = _Get_wc(); + constexpr int _Kx = _Get_wc(); for (size_t _Ix = 0; _Ix < _Nw; ++_Ix) { for (int _Jx = 0; _Jx < _Kx; ++_Jx) { // unpack into _Kx words @@ -1034,6 +1035,7 @@ struct _Swc_traits { // traits for subtract_with_carry generator } }; +#if _HAS_TR1_NAMESPACE template class _DEPRECATE_TR1_RANDOM subtract_with_carry : public _Swc_base<_Ty, _Sx, _Rx, _Swc_traits<_Ty, _Mx, _Rx>> { // subtract_with_carry generator @@ -1051,25 +1053,27 @@ public: template = 0> subtract_with_carry(_Gen& _Gx) : _Mybase(_Gx) {} }; +#endif // _HAS_TR1_NAMESPACE -_STL_DISABLE_DEPRECATED_WARNING _EXPORT_STD template class subtract_with_carry_engine - : private subtract_with_carry<_Ty, static_cast<_Ty>((_Ty{1} << (_Wx - 1)) << 1), _Sx, _Rx> { - // subtract_with_carry generator + : private _Swc_base<_Ty, _Sx, _Rx, _Swc_traits<_Ty, static_cast<_Ty>((_Ty{1} << (_Wx - 1)) << 1), _Rx>> { +private: + static constexpr _Ty _Mx = static_cast<_Ty>((_Ty{1} << (_Wx - 1)) << 1); + + using _Traits = _Swc_traits<_Ty, _Mx, _Rx>; + using _Mybase = _Swc_base<_Ty, _Sx, _Rx, _Traits>; + public: _RNG_REQUIRE_UINTTYPE(subtract_with_carry_engine, _Ty); static_assert(0U < _Sx && _Sx < _Rx && 0 < _Wx && _Wx <= numeric_limits<_Ty>::digits, "invalid template argument for subtract_with_carry_engine"); - static constexpr _Ty _Mx = static_cast<_Ty>((_Ty{1} << (_Wx - 1)) << 1); static constexpr size_t word_size = _Wx; static constexpr size_t short_lag = _Sx; static constexpr size_t long_lag = _Rx; - using _Mybase = subtract_with_carry<_Ty, _Mx, _Sx, _Rx>; - using _Traits = typename _Mybase::_Traits; using result_type = _Ty; using _Mybase::default_seed; @@ -1079,7 +1083,7 @@ public: explicit subtract_with_carry_engine(_Ty _Xx0) : _Mybase(_Xx0) {} template = 0> - explicit subtract_with_carry_engine(_Seed_seq& _Seq) : _Mybase() { + explicit subtract_with_carry_engine(_Seed_seq& _Seq) : _Mybase(0u) { seed(_Seq); } @@ -1087,12 +1091,11 @@ public: _Mybase::seed(_Value); } - static constexpr int _Kx = (8 * sizeof(_Ty) + 31) / 32; - template = 0> void seed(_Seed_seq& _Seq) { // reset sequence from seed sequence + constexpr int _Kx = (8 * sizeof(_Ty) + 31) / 32; unsigned long _Arr[_Kx * _Rx]; - _Seq.generate(&_Arr[0], &_Arr[_Kx * _Rx]); + _Seq.generate(_STD begin(_Arr), _STD end(_Arr)); size_t _Idx0 = 0; for (size_t _Ix = 0; _Ix < _Rx; ++_Ix, _Idx0 += _Kx) { // pack _Kx words @@ -1127,7 +1130,7 @@ public: #if !_HAS_CXX20 _NODISCARD friend bool operator!=( const subtract_with_carry_engine& _Left, const subtract_with_carry_engine& _Right) noexcept /* strengthened */ { - return static_cast(_Left) != static_cast(_Right); + return !(_Left == _Right); } #endif // !_HAS_CXX20 @@ -1177,7 +1180,6 @@ public: return _Istr; } }; -_STL_RESTORE_DEPRECATED_WARNING #if _HAS_TR1_NAMESPACE constexpr double _Cx_exp2(const int _Exp) noexcept { @@ -1264,7 +1266,6 @@ public: template = 0> subtract_with_carry_01(_Gen& _Gx) : _Mybase(_Gx) {} }; -#endif // _HAS_TR1_NAMESPACE template class _DEPRECATE_TR1_RANDOM mersenne_twister : public _Circ_buf<_Ty, _Nx> { // mersenne twister generator @@ -1436,14 +1437,15 @@ protected: static constexpr int _One_mod_n = 1 % _Nx; // either 0 or 1 static constexpr int _M_mod_n = _Mx % _Nx; }; +#endif // _HAS_TR1_NAMESPACE -_STL_DISABLE_DEPRECATED_WARNING _EXPORT_STD template -class mersenne_twister_engine : private mersenne_twister<_Ty, _Wx, _Nx, _Mx, _Rx, _Px, _Ux, _Sx, _Bx, _Tx, _Cx, _Lx> { -public: +class mersenne_twister_engine : private _Circ_buf<_Ty, _Nx> { +private: static constexpr unsigned long long _Max = (((1ULL << (_Wx - 1)) - 1) << 1) + 1; +public: _RNG_REQUIRE_UINTTYPE(mersenne_twister_engine, _Ty); static_assert(0 < _Mx && _Mx <= _Nx && 2U < _Wx && _Rx <= _Wx && _Ux <= _Wx && _Sx <= _Wx && _Tx <= _Wx @@ -1451,7 +1453,6 @@ public: && _Dx <= _Max && _Fx <= _Max, "invalid template argument for mersenne_twister_engine"); - using _Mybase = mersenne_twister<_Ty, _Wx, _Nx, _Mx, _Rx, _Px, _Ux, _Sx, _Bx, _Tx, _Cx, _Lx>; using result_type = _Ty; static constexpr size_t word_size = _Wx; @@ -1470,24 +1471,33 @@ public: static constexpr result_type default_seed = 5489U; - mersenne_twister_engine() : _Mybase(default_seed, _Dx, _Fx) {} + mersenne_twister_engine() { + seed(default_seed); + } - explicit mersenne_twister_engine(result_type _Xx0) : _Mybase(_Xx0, _Dx, _Fx) {} + explicit mersenne_twister_engine(result_type _Xx0) { + seed(_Xx0); + } template = 0> - explicit mersenne_twister_engine(_Seed_seq& _Seq) : _Mybase(default_seed, _Dx, _Fx) { + explicit mersenne_twister_engine(_Seed_seq& _Seq) { seed(_Seq); } void seed(result_type _Xx0 = default_seed) { // set initial values from specified value - _Mybase::seed(_Xx0, _Fx); + _Ty _Prev = this->_Ax[0] = _Xx0 & _WMSK; + for (size_t _Ix = 1; _Ix < _Nx; ++_Ix) { + _Prev = this->_Ax[_Ix] = (_Ix + _Fx * (_Prev ^ (_Prev >> (_Wx - 2)))) & _WMSK; + } + + this->_Idx = _Nx; } template = 0> void seed(_Seed_seq& _Seq) { // reset sequence from seed sequence constexpr int _Kx = (_Wx + 31) / 32; unsigned long _Arr[_Kx * _Nx]; - _Seq.generate(&_Arr[0], &_Arr[_Kx * _Nx]); + _Seq.generate(_STD begin(_Arr), _STD end(_Arr)); int _Idx0 = 0; _Ty _Sum = 0; @@ -1497,7 +1507,7 @@ public: this->_Ax[_Ix] |= static_cast<_Ty>(_Arr[_Idx0 + _Jx]) << (32 * _Jx); } - this->_Ax[_Ix] &= this->_WMSK; + this->_Ax[_Ix] &= _WMSK; if (_Ix == 0) { _Sum = this->_Ax[_Ix] >> _Rx; @@ -1518,43 +1528,127 @@ public: } _NODISCARD static constexpr result_type(max)() noexcept /* strengthened */ { - return _Mybase::_WMSK; + return _WMSK; } _NODISCARD friend bool operator==( const mersenne_twister_engine& _Left, const mersenne_twister_engine& _Right) noexcept /* strengthened */ { - return static_cast(_Left) == static_cast(_Right); + return _Left._Equals(_Right); } #if !_HAS_CXX20 _NODISCARD friend bool operator!=( const mersenne_twister_engine& _Left, const mersenne_twister_engine& _Right) noexcept /* strengthened */ { - return static_cast(_Left) != static_cast(_Right); + return !(_Left == _Right); } #endif // !_HAS_CXX20 template friend basic_istream<_Elem, _S_Traits>& operator>>( basic_istream<_Elem, _S_Traits>& _Istr, mersenne_twister_engine& _Eng) { - return _Istr >> static_cast<_Mybase&>(_Eng); + _Wrap_istream<_Elem, _S_Traits, _Ty> _Gen(_Istr); + + for (size_t _Ix = 0; _Ix < _Nx; ++_Ix) { + _Eng._Ax[_Ix] = _Gen() & _WMSK; + } + + _Eng._Idx = _Nx; + + return _Istr; } template friend basic_ostream<_Elem, _S_Traits>& operator<<( basic_ostream<_Elem, _S_Traits>& _Ostr, const mersenne_twister_engine& _Eng) { - return _Ostr << static_cast(_Eng); + _Ostr << _Eng._At(0); + + for (size_t _Ix = 1; _Ix < _Nx; ++_Ix) { + _Ostr << ' ' << _Eng._At(_Ix); + } + + return _Ostr; } _NODISCARD result_type operator()() { - return _Mybase::operator()(); + if (this->_Idx == _Nx) { + _Refill_upper(); + } else if (2 * _Nx <= this->_Idx) { + _Refill_lower(); + } + + _Ty _Res = this->_Ax[this->_Idx++] & _WMSK; + _Res ^= (_Res >> _Ux) & _Dx; + _Res ^= (_Res << _Sx) & _Bx; + _Res ^= (_Res << _Tx) & _Cx; + _Res ^= (_Res & _WMSK) >> _Lx; + return _Res; } void discard(unsigned long long _Nskip) { - _Mybase::discard(_Nskip); + for (; 0 < _Nskip; --_Nskip) { + (void) (*this)(); + } } + +private: + _Post_satisfies_(this->_Idx == 0) void _Refill_lower() { + // compute values for the lower half of the history array + constexpr size_t _Wrap_bound_one = _Nx - _One_mod_n; + constexpr size_t _Wrap_bound_m = _Nx - _M_mod_n; + + if constexpr (_M_mod_n == 0) { + for (size_t _Ix = 0; _Ix < _Wrap_bound_one; ++_Ix) { // fill in values + const _Ty _Tmp = (this->_Ax[_Ix + _Nx] & _HMSK) | (this->_Ax[_Ix + _Nx + _One_mod_n] & _LMSK); + this->_Ax[_Ix] = (_Tmp >> 1) ^ (_Tmp & 1 ? _Px : 0) ^ this->_Ax[_Ix + _Nx + _M_mod_n]; + } + + if constexpr (_One_mod_n == 1) { // fill in _Ax[_Nx - 1] + constexpr size_t _Ix = _Wrap_bound_one; + + const _Ty _Tmp = (this->_Ax[_Ix + _Nx] & _HMSK) | (this->_Ax[_Ix - _Nx + _One_mod_n] & _LMSK); + this->_Ax[_Ix] = (_Tmp >> 1) ^ (_Tmp & 1 ? _Px : 0) ^ this->_Ax[_Ix + _Nx + _M_mod_n]; + } + } else { + for (size_t _Ix = 0; _Ix < _Wrap_bound_m; ++_Ix) { // fill in lower region + const _Ty _Tmp = (this->_Ax[_Ix + _Nx] & _HMSK) | (this->_Ax[_Ix + _Nx + _One_mod_n] & _LMSK); + this->_Ax[_Ix] = (_Tmp >> 1) ^ (_Tmp & 1 ? _Px : 0) ^ this->_Ax[_Ix + _Nx + _M_mod_n]; + } + + for (size_t _Ix = _Wrap_bound_m; _Ix < _Wrap_bound_one; ++_Ix) { + // fill in upper region (avoids modulus operation) + const _Ty _Tmp = (this->_Ax[_Ix + _Nx] & _HMSK) | (this->_Ax[_Ix + _Nx + _One_mod_n] & _LMSK); + this->_Ax[_Ix] = (_Tmp >> 1) ^ (_Tmp & 1 ? _Px : 0) ^ this->_Ax[_Ix - _Nx + _M_mod_n]; + } + + if constexpr (_One_mod_n == 1) { // fill in _Ax[_Nx - 1] + constexpr size_t _Ix = _Wrap_bound_one; + + const _Ty _Tmp = (this->_Ax[_Ix + _Nx] & _HMSK) | (this->_Ax[_Ix - _Nx + _One_mod_n] & _LMSK); + this->_Ax[_Ix] = (_Tmp >> 1) ^ (_Tmp & 1 ? _Px : 0) ^ this->_Ax[_Ix - _Nx + _M_mod_n]; + } + } + + this->_Idx = 0; + } + + void _Refill_upper() { // compute values for the upper half of the history array + for (size_t _Ix = _Nx; _Ix < 2 * _Nx; ++_Ix) { // fill in values + const _Ty _Tmp = (this->_Ax[_Ix - _Nx] & _HMSK) | (this->_Ax[_Ix - _Nx + _One_mod_n] & _LMSK); + this->_Ax[_Ix] = (_Tmp >> 1) ^ (_Tmp & 1 ? _Px : 0) ^ this->_Ax[_Ix - _Nx + _M_mod_n]; + } + } + + _Ty _Dxval{_Dx}; // TRANSITION, ABI: _Dxval must be initialized to _Dx but is unused by the current implementation + + static constexpr _Ty _WMSK = ~((~_Ty{0} << (_Wx - 1)) << 1); + static constexpr _Ty _HMSK = (_WMSK << _Rx) & _WMSK; + static constexpr _Ty _LMSK = ~_HMSK & _WMSK; + + static constexpr int _One_mod_n = 1 % _Nx; // either 0 or 1 + static constexpr int _M_mod_n = _Mx % _Nx; }; -_STL_RESTORE_DEPRECATED_WARNING +#if _HAS_TR1_NAMESPACE template class _DEPRECATE_TR1_RANDOM discard_block { // discard_block compound engine public: @@ -1650,35 +1744,44 @@ private: _Engine _Eng; int _Nx; }; +#endif // _HAS_TR1_NAMESPACE + +_EXPORT_STD template +class discard_block_engine { +private: + using _Block_type = conditional_t<_Px <= INT_MAX, int, size_t>; // TRANSITION, ABI: Should always be size_t -template -class _Discard_block_base { // TRANSITION, ABI, should be merged into discard_block_engine public: + static_assert(0 < _Rx && _Rx <= _Px, "invalid template argument for discard_block_engine"); + using result_type = typename _Engine::result_type; - _Discard_block_base() : _Eng(), _Nx(0) {} + static constexpr size_t block_size = _Px; + static constexpr size_t used_block = _Rx; - explicit _Discard_block_base(const _Engine& _Ex) : _Eng(_Ex), _Nx(0) {} + discard_block_engine() : _Eng(), _Nx(0) {} - explicit _Discard_block_base(_Engine&& _Ex) : _Eng(_STD move(_Ex)), _Nx(0) {} + explicit discard_block_engine(const _Engine& _Ex) : _Eng(_Ex), _Nx(0) {} - explicit _Discard_block_base(result_type _Seed) : _Eng(_Seed), _Nx(0) {} + explicit discard_block_engine(_Engine&& _Ex) : _Eng(_STD move(_Ex)), _Nx(0) {} - template = 0> - explicit _Discard_block_base(_Seed_seq& _Seq) : _Eng(_Seq), _Nx(0) {} + explicit discard_block_engine(result_type _Xx0) : _Eng(_Xx0), _Nx(0) {} - void seed() { // seed engine from default value + template = 0> + explicit discard_block_engine(_Seed_seq& _Seq) : _Eng(_Seq), _Nx(0) {} + + void seed() { _Eng.seed(); _Nx = 0; } - void seed(result_type _Xx0) { // seed engine from specified value + void seed(result_type _Xx0) { _Eng.seed(_Xx0); _Nx = 0; } - template = 0> - void seed(_Seed_seq& _Seq) { // seed engine from seed sequence + template = 0> + void seed(_Seed_seq& _Seq) { _Eng.seed(_Seq); _Nx = 0; } @@ -1688,8 +1791,8 @@ public: } _NODISCARD result_type operator()() { - if (_Rx <= _Nx) { // discard values - while (_Nx++ < _Px) { + if (static_cast<_Block_type>(_Rx) <= _Nx) { // discard values + while (_Nx++ < static_cast<_Block_type>(_Px)) { (void) _Eng(); } @@ -1699,90 +1802,12 @@ public: return _Eng(); } - void discard(unsigned long long _Nskip) { // discard _Nskip elements + void discard(unsigned long long _Nskip) { for (; 0 < _Nskip; --_Nskip) { (void) (*this)(); } } - _NODISCARD friend bool operator==(const _Discard_block_base& _Left, const _Discard_block_base& _Right) { - return _Left._Eng == _Right._Eng && _Left._Nx == _Right._Nx; - } - -#if !_HAS_CXX20 - _NODISCARD friend bool operator!=(const _Discard_block_base& _Left, const _Discard_block_base& _Right) { - return !(_Left == _Right); - } -#endif // !_HAS_CXX20 - - template - friend basic_istream<_Elem, _Traits>& operator>>( - basic_istream<_Elem, _Traits>& _Istr, _Discard_block_base& _Eng) { // read state from _Istr - return _Istr >> _Eng._Eng >> _Eng._Nx; - } - - template - friend basic_ostream<_Elem, _Traits>& operator<<( - basic_ostream<_Elem, _Traits>& _Ostr, const _Discard_block_base& _Eng) { // write state to _Ostr - return _Ostr << _Eng._Eng << ' ' << _Eng._Nx; - } - -private: - _Engine _Eng; - size_t _Nx; -}; - -_STL_DISABLE_DEPRECATED_WARNING -_EXPORT_STD template -class discard_block_engine // discard_block_engine compound engine - : private conditional_t<_Px <= INT_MAX, discard_block<_Engine, static_cast(_Px), static_cast(_Rx)>, - _Discard_block_base<_Engine, _Px, _Rx>> { -public: - static_assert(0 < _Rx && _Rx <= _Px, "invalid template argument for discard_block_engine"); - - using _Mybase = conditional_t<_Px <= INT_MAX, discard_block<_Engine, static_cast(_Px), static_cast(_Rx)>, - _Discard_block_base<_Engine, _Px, _Rx>>; - using result_type = typename _Engine::result_type; - - static constexpr size_t block_size = _Px; - static constexpr size_t used_block = _Rx; - - discard_block_engine() : _Mybase() {} - - explicit discard_block_engine(const _Engine& _Ex) : _Mybase(_Ex) {} - - explicit discard_block_engine(_Engine&& _Ex) : _Mybase(_STD move(_Ex)) {} - - explicit discard_block_engine(result_type _Xx0) : _Mybase(_Xx0) {} - - template = 0> - explicit discard_block_engine(_Seed_seq& _Seq) : _Mybase(_Seq) {} - - void seed() { - _Mybase::seed(); - } - - void seed(result_type _Xx0) { - _Mybase::seed(_Xx0); - } - - template = 0> - void seed(_Seed_seq& _Seq) { - _Mybase::seed(_Seq); - } - - _NODISCARD const _Engine& base() const noexcept { - return _Mybase::base(); - } - - _NODISCARD result_type operator()() { - return _Mybase::operator()(); - } - - void discard(unsigned long long _Nskip) { - _Mybase::discard(_Nskip); - } - _NODISCARD static constexpr result_type(min)() noexcept /* strengthened */ { return (_Engine::min)(); } @@ -1792,27 +1817,30 @@ public: } _NODISCARD friend bool operator==(const discard_block_engine& _Left, const discard_block_engine& _Right) { - return static_cast(_Left) == static_cast(_Right); + return _Left._Eng == _Right._Eng && _Left._Nx == _Right._Nx; } #if !_HAS_CXX20 _NODISCARD friend bool operator!=(const discard_block_engine& _Left, const discard_block_engine& _Right) { - return static_cast(_Left) != static_cast(_Right); + return !(_Left == _Right); } #endif // !_HAS_CXX20 template friend basic_istream<_Elem, _Traits>& operator>>(basic_istream<_Elem, _Traits>& _Istr, discard_block_engine& _Eng) { - return _Istr >> static_cast<_Mybase&>(_Eng); + return _Istr >> _Eng._Eng >> _Eng._Nx; } template friend basic_ostream<_Elem, _Traits>& operator<<( basic_ostream<_Elem, _Traits>& _Ostr, const discard_block_engine& _Eng) { - return _Ostr << static_cast(_Eng); + return _Ostr << _Eng._Eng << ' ' << _Eng._Nx; } + +private: + _Engine _Eng; + _Block_type _Nx; }; -_STL_RESTORE_DEPRECATED_WARNING _EXPORT_STD template class independent_bits_engine { // independent_bits_engine compound engine @@ -2209,6 +2237,7 @@ private: static constexpr _Udiff _Bmask = static_cast<_Udiff>(-1) >> (_Udiff_bits - _Bits); // 2^_Bits - 1 }; +#if _HAS_TR1_NAMESPACE template class _DEPRECATE_TR1_RANDOM uniform_int { // uniform integer distribution public: @@ -2351,90 +2380,121 @@ private: param_type _Par; }; +#endif // _HAS_TR1_NAMESPACE -_STL_DISABLE_DEPRECATED_WARNING _EXPORT_STD template -class uniform_int_distribution : private uniform_int<_Ty> { // uniform integer distribution +class uniform_int_distribution { // uniform integer distribution public: _RNG_REQUIRE_INTTYPE(uniform_int_distribution, _Ty); - using _Mybase = uniform_int<_Ty>; - using _Mypbase = typename _Mybase::param_type; - using result_type = typename _Mybase::result_type; + using result_type = _Ty; - struct param_type : _Mypbase { // parameter package + struct param_type { // parameter package using distribution_type = uniform_int_distribution; - param_type() noexcept // strengthened - : _Mypbase(0, (numeric_limits<_Ty>::max)()) {} + param_type() noexcept /* strengthened */ { + _Init(0, (numeric_limits<_Ty>::max)()); + } + + explicit param_type(result_type _Min0, result_type _Max0 = (numeric_limits<_Ty>::max)()) noexcept + /* strengthened */ { + _Init(_Min0, _Max0); + } + + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) noexcept + /* strengthened */ { + return _Left._Min == _Right._Min && _Left._Max == _Right._Max; + } - explicit param_type( - result_type _Min0, result_type _Max0 = (numeric_limits<_Ty>::max)()) noexcept // strengthened - : _Mypbase(_Min0, _Max0) {} +#if !_HAS_CXX20 + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) noexcept + /* strengthened */ { + return !(_Left == _Right); + } +#endif // !_HAS_CXX20 - param_type(const _Mypbase& _Right) noexcept : _Mypbase(_Right) {} + _NODISCARD result_type a() const noexcept /* strengthened */ { + return _Min; + } + + _NODISCARD result_type b() const noexcept /* strengthened */ { + return _Max; + } + + void _Init(_Ty _Min0, _Ty _Max0) noexcept { // set internal state + _STL_ASSERT(_Min0 <= _Max0, "invalid min and max arguments for uniform_int_distribution"); + _Min = _Min0; + _Max = _Max0; + } + + result_type _Min; + result_type _Max; }; uniform_int_distribution() noexcept // strengthened - : _Mybase(0, (numeric_limits<_Ty>::max)()) {} + : _Par(0, (numeric_limits<_Ty>::max)()) {} explicit uniform_int_distribution(_Ty _Min0, _Ty _Max0 = (numeric_limits<_Ty>::max)()) noexcept // strengthened - : _Mybase(_Min0, _Max0) {} + : _Par(_Min0, _Max0) {} explicit uniform_int_distribution(const param_type& _Par0) noexcept // strengthened - : _Mybase(_Par0) {} + : _Par(_Par0) {} _NODISCARD result_type a() const noexcept /* strengthened */ { - return _Mybase::a(); + return _Par.a(); } _NODISCARD result_type b() const noexcept /* strengthened */ { - return _Mybase::b(); + return _Par.b(); } _NODISCARD param_type param() const noexcept /* strengthened */ { - return _Mybase::param(); + return _Par; } void param(const param_type& _Par0) noexcept /* strengthened */ { - _Mybase::param(_Par0); + _Par = _Par0; } _NODISCARD result_type(min)() const noexcept /* strengthened */ { - return (_Mybase::min)(); + return _Par._Min; } _NODISCARD result_type(max)() const noexcept /* strengthened */ { - return (_Mybase::max)(); + return _Par._Max; } void reset() noexcept /* strengthened */ {} template _NODISCARD result_type operator()(_Engine& _Eng) _DISTRIBUTION_CONST { - return _Mybase::operator()(_Eng); + return _Eval(_Eng, _Par._Min, _Par._Max); } template _NODISCARD result_type operator()(_Engine& _Eng, const param_type& _Par0) _DISTRIBUTION_CONST { - return _Mybase::operator()(_Eng, _Par0); + return _Eval(_Eng, _Par0._Min, _Par0._Max); } template friend basic_istream<_Elem, _Traits>& operator>>( basic_istream<_Elem, _Traits>& _Istr, uniform_int_distribution& _Dist) { - return _Istr >> static_cast<_Mybase&>(_Dist); + uniform_int_distribution::result_type _Min0; + uniform_int_distribution::result_type _Max0; + _Istr >> _Min0 >> _Max0; + _Dist._Par._Init(_Min0, _Max0); + return _Istr; } template friend basic_ostream<_Elem, _Traits>& operator<<( basic_ostream<_Elem, _Traits>& _Ostr, const uniform_int_distribution& _Dist) { - return _Ostr << static_cast(_Dist); + return _Ostr << _Dist._Par._Min << ' ' << _Dist._Par._Max; } _NODISCARD friend bool operator==( const uniform_int_distribution& _Left, const uniform_int_distribution& _Right) noexcept /* strengthened */ { - return _Left.param() == _Right.param(); + return _Left._Par == _Right._Par; } #if !_HAS_CXX20 @@ -2443,8 +2503,39 @@ public: return !(_Left == _Right); } #endif // !_HAS_CXX20 + +private: + using _Uty = make_unsigned_t<_Ty>; + + template + result_type _Eval(_Engine& _Eng, _Ty _Min, _Ty _Max) const { // compute next value in range [_Min, _Max] + _Rng_from_urng_v2<_Uty, _Engine> _Generator(_Eng); + + const _Uty _Umin = _Adjust(static_cast<_Uty>(_Min)); + const _Uty _Umax = _Adjust(static_cast<_Uty>(_Max)); + + _Uty _Uret; + + if (_Umax - _Umin == static_cast<_Uty>(-1)) { + _Uret = static_cast<_Uty>(_Generator._Get_all_bits()); + } else { + _Uret = static_cast<_Uty>(_Generator(static_cast<_Uty>(_Umax - _Umin + 1))); + } + + return static_cast<_Ty>(_Adjust(static_cast<_Uty>(_Uret + _Umin))); + } + + static _Uty _Adjust(_Uty _Uval) noexcept { // convert signed ranges to unsigned ranges and vice versa + if constexpr (is_signed_v<_Ty>) { + constexpr _Uty _Adjuster = (static_cast<_Uty>(-1) >> 1) + 1; // 2^(N-1) + return static_cast<_Uty>(_Uval ^ _Adjuster); + } else { // _Ty is already unsigned, do nothing + return _Uval; + } + } + + param_type _Par; }; -_STL_RESTORE_DEPRECATED_WARNING _EXPORT_STD class bernoulli_distribution { // class for bernoulli distribution public: @@ -3122,6 +3213,7 @@ private: param_type _Par; }; +#if _HAS_TR1_NAMESPACE template class _DEPRECATE_TR1_RANDOM uniform_real { // uniform real distribution public: @@ -3248,89 +3340,117 @@ private: param_type _Par; }; +#endif // _HAS_TR1_NAMESPACE -_STL_DISABLE_DEPRECATED_WARNING _EXPORT_STD template -class uniform_real_distribution : private uniform_real<_Ty> { // uniform real distribution +class uniform_real_distribution { // uniform real distribution public: _RNG_REQUIRE_REALTYPE(uniform_real_distribution, _Ty); - using _Mybase = uniform_real<_Ty>; - using _Mypbase = typename _Mybase::param_type; - using result_type = typename _Mybase::result_type; + using result_type = _Ty; - struct param_type : _Mypbase { // parameter package + struct param_type { // parameter package using distribution_type = uniform_real_distribution; - param_type() noexcept // strengthened - : _Mypbase(_Ty{0}, _Ty{1}) {} + param_type() noexcept /* strengthened */ { + _Init(_Ty{0}, _Ty{1}); + } + + explicit param_type(_Ty _Min0, _Ty _Max0 = _Ty{1}) noexcept /* strengthened */ { + _Init(_Min0, _Max0); + } + + _NODISCARD friend bool operator==(const param_type& _Left, const param_type& _Right) noexcept + /* strengthened */ { + return _Left._Min == _Right._Min && _Left._Max == _Right._Max; + } + +#if !_HAS_CXX20 + _NODISCARD friend bool operator!=(const param_type& _Left, const param_type& _Right) noexcept + /* strengthened */ { + return !(_Left == _Right); + } +#endif // !_HAS_CXX20 + + _NODISCARD result_type a() const noexcept /* strengthened */ { + return _Min; + } - explicit param_type(_Ty _Min0, _Ty _Max0 = _Ty{1}) noexcept // strengthened - : _Mypbase(_Min0, _Max0) {} + _NODISCARD result_type b() const noexcept /* strengthened */ { + return _Max; + } - param_type(const _Mypbase& _Right) noexcept : _Mypbase(_Right) {} + void _Init(_Ty _Min0, _Ty _Max0) noexcept { // set internal state + _STL_ASSERT(_Min0 <= _Max0 && (0 <= _Min0 || _Max0 <= _Min0 + (numeric_limits<_Ty>::max)()), + "invalid min and max arguments for uniform_real_distribution"); + _Min = _Min0; + _Max = _Max0; + } + + result_type _Min; + result_type _Max; }; uniform_real_distribution() noexcept // strengthened - : _Mybase(_Ty{0}, _Ty{1}) {} + : _Par(_Ty{0}, _Ty{1}) {} explicit uniform_real_distribution(_Ty _Min0, _Ty _Max0 = _Ty{1}) noexcept // strengthened - : _Mybase(_Min0, _Max0) {} + : _Par(_Min0, _Max0) {} explicit uniform_real_distribution(const param_type& _Par0) noexcept // strengthened - : _Mybase(_Par0) {} + : _Par(_Par0) {} _NODISCARD result_type a() const noexcept /* strengthened */ { - return _Mybase::a(); + return _Par.a(); } _NODISCARD result_type b() const noexcept /* strengthened */ { - return _Mybase::b(); + return _Par.b(); } _NODISCARD param_type param() const noexcept /* strengthened */ { - return _Mybase::param(); + return _Par; } void param(const param_type& _Par0) noexcept /* strengthened */ { - _Mybase::param(_Par0); + _Par = _Par0; } _NODISCARD result_type(min)() const noexcept /* strengthened */ { - return (_Mybase::min)(); + return _Par._Min; } _NODISCARD result_type(max)() const noexcept /* strengthened */ { - return (_Mybase::max)(); + return _Par._Max; } void reset() noexcept /* strengthened */ {} template _NODISCARD result_type operator()(_Engine& _Eng) _DISTRIBUTION_CONST { - return _Mybase::operator()(_Eng); + return _Eval(_Eng, _Par); } template _NODISCARD result_type operator()(_Engine& _Eng, const param_type& _Par0) _DISTRIBUTION_CONST { - return _Mybase::operator()(_Eng, _Par0); + return _Eval(_Eng, _Par0); } template friend basic_istream<_Elem, _Traits>& operator>>( basic_istream<_Elem, _Traits>& _Istr, uniform_real_distribution& _Dist) { - return _Istr >> static_cast<_Mybase&>(_Dist); + return _Dist._Read(_Istr); } template friend basic_ostream<_Elem, _Traits>& operator<<( basic_ostream<_Elem, _Traits>& _Ostr, const uniform_real_distribution& _Dist) { - return _Ostr << static_cast(_Dist); + return _Dist._Write(_Ostr); } _NODISCARD friend bool operator==( const uniform_real_distribution& _Left, const uniform_real_distribution& _Right) noexcept /* strengthened */ { - return _Left.param() == _Right.param(); + return _Left._Par == _Right._Par; } #if !_HAS_CXX20 @@ -3339,8 +3459,32 @@ public: return !(_Left == _Right); } #endif // !_HAS_CXX20 + +private: + template + basic_istream<_Elem, _Traits>& _Read(basic_istream<_Elem, _Traits>& _Istr) { // read state from _Istr + _Ty _Min0; + _Ty _Max0; + _In(_Istr, _Min0); + _In(_Istr, _Max0); + _Par._Init(_Min0, _Max0); + return _Istr; + } + + template + basic_ostream<_Elem, _Traits>& _Write(basic_ostream<_Elem, _Traits>& _Ostr) const { // write state to _Ostr + _Out(_Ostr, _Par._Min); + _Out(_Ostr, _Par._Max); + return _Ostr; + } + + template + result_type _Eval(_Engine& _Eng, const param_type& _Par0) const { + return _Nrand_impl<_Ty>(_Eng) * (_Par0._Max - _Par0._Min) + _Par0._Min; + } + + param_type _Par; }; -_STL_RESTORE_DEPRECATED_WARNING _EXPORT_STD template class exponential_distribution { // exponential distribution @@ -5725,6 +5869,7 @@ _STD_END #undef _DISTRIBUTION_CONST +#if _HAS_TR1_NAMESPACE // TRANSITION, GH-183 #pragma pop_macro("uniform_real") #pragma pop_macro("uniform_int") @@ -5732,6 +5877,7 @@ _STD_END #pragma pop_macro("mersenne_twister") #pragma pop_macro("linear_congruential") #pragma pop_macro("discard_block") +#endif // _HAS_TR1_NAMESPACE #pragma pop_macro("new") _STL_RESTORE_CLANG_WARNINGS diff --git a/tests/std/tests/Dev09_181509_tr1_inf_loop_uniform_int_ull/test.cpp b/tests/std/tests/Dev09_181509_tr1_inf_loop_uniform_int_ull/test.cpp index 134b48978ca..8cfb375b721 100644 --- a/tests/std/tests/Dev09_181509_tr1_inf_loop_uniform_int_ull/test.cpp +++ b/tests/std/tests/Dev09_181509_tr1_inf_loop_uniform_int_ull/test.cpp @@ -63,8 +63,8 @@ void add_tests(vector& tests) { microtest, microtest, microtest, - microtest, // Test DDB-181509 "TR1 VC9 SP1: Infinite loop in - // uniform_int::_Eval()". + microtest, // Test DDB-181509 (infinite loop in + // uniform_int_distribution) microtest, microtest, @@ -95,11 +95,11 @@ class Wacky { typedef unsigned long result_type; - static result_type min() { + static constexpr result_type min() { return 0; } - static result_type max() { + static constexpr result_type max() { return 90000; } diff --git a/tests/std/tests/P0952R2_new_generate_canonical/test.cpp b/tests/std/tests/P0952R2_new_generate_canonical/test.cpp index 527faf8aee1..3778db5d592 100644 --- a/tests/std/tests/P0952R2_new_generate_canonical/test.cpp +++ b/tests/std/tests/P0952R2_new_generate_canonical/test.cpp @@ -20,6 +20,7 @@ void test_lwg2524() { assert((generate_canonical) (mt2) < 1.0f); } +#if _HAS_TR1_NAMESPACE void test_tr1_16() { using E_std = linear_congruential_engine; using E_tr1 = linear_congruential; @@ -98,6 +99,7 @@ void test_tr1_64() { assert(dist_64(std_eng) == dist_64(tr1_eng)); } } +#endif // _HAS_TR1_NAMESPACE template Real generate_with_ibe() { @@ -197,9 +199,12 @@ int main() { assert((generate_canonical) (eng) == expected); } +#if _HAS_TR1_NAMESPACE test_tr1_16(); test_tr1_32(); test_tr1_64(); +#endif // _HAS_TR1_NAMESPACE + test_lwg2524(); return 0; diff --git a/tests/std/tests/VSO_0000000_instantiate_iterators_misc/test.compile.pass.cpp b/tests/std/tests/VSO_0000000_instantiate_iterators_misc/test.compile.pass.cpp index 8352292398b..d73e84653fc 100644 --- a/tests/std/tests/VSO_0000000_instantiate_iterators_misc/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0000000_instantiate_iterators_misc/test.compile.pass.cpp @@ -1073,12 +1073,14 @@ void engine_test_impl() { common_engine_test_impl(ss); } +#if _HAS_TR1_NAMESPACE template void tr1_engine_test_impl() { random_device rd{}; mt19937 gen(rd()); common_engine_test_impl(gen); } +#endif // _HAS_TR1_NAMESPACE void random_test() { seed_seq ss0({1, 2, 3, 4, 5, 6}); @@ -1091,22 +1093,21 @@ void random_test() { mt19937 gen(rd()); (void) generate_canonical(gen); - engine_test_impl(); // linear congruential engine - engine_test_impl(); // mersenne twister engine + engine_test_impl(); // linear_congruential_engine + engine_test_impl(); // mersenne_twister_engine engine_test_impl(); // subtract_with_carry_engine - engine_test_impl(); // discard block engine + engine_test_impl(); // discard_block_engine engine_test_impl(); // shuffle_order_engine engine_test_impl>(); engine_test_impl(); engine_test_impl(); engine_test_impl(); +#if _HAS_TR1_NAMESPACE linear_congruential minstd_rand_eng(gen); minstd_rand_eng.seed(gen); tr1_engine_test_impl>(); - -#if _HAS_TR1_NAMESPACE tr1_engine_test_impl(); tr1_engine_test_impl(); tr1_engine_test_impl(); diff --git a/tests/tr1/include/tspec_random.h b/tests/tr1/include/tspec_random.h index 9be4e7a6ba7..e600c6a8a46 100644 --- a/tests/tr1/include/tspec_random.h +++ b/tests/tr1/include/tspec_random.h @@ -129,8 +129,14 @@ void test_random() { // test all of the distributions TESTR(geometric_distribution); TESTR(normal_distribution); TESTR(poisson_distribution); + +#if _HAS_TR1_NAMESPACE TESTR(uniform_int); TESTR(uniform_real); +#else // ^^^ _HAS_TR1_NAMESPACE / !_HAS_TR1_NAMESPACE vvv + TESTR(uniform_int_distribution); + TESTR(uniform_real_distribution); +#endif // ^^^ !_HAS_TR1_NAMESPACE ^^^ TESTR(cauchy_distribution); TESTR(chi_squared_distribution); diff --git a/tests/tr1/include/tspec_random_defs.h b/tests/tr1/include/tspec_random_defs.h index d4283411993..ac01067f733 100644 --- a/tests/tr1/include/tspec_random_defs.h +++ b/tests/tr1/include/tspec_random_defs.h @@ -129,6 +129,7 @@ One_arg poisson_distribution_vals[] = { {FLIT(99.0), FLIT(0.03986496337366227799), FLIT(0.0)}, }; +#if _HAS_TR1_NAMESPACE typedef unsigned int uniform_int_type; uniform_int uniform_int_dist(10, 90); int uniform_int_smaller_ok = 0; @@ -164,6 +165,43 @@ One_arg uniform_real_vals[] = { {FLIT(88.0), FLIT(0.0), FLIT(0.0)}, {FLIT(99.0), FLIT(0.0), FLIT(0.0)}, }; +#else // ^^^ _HAS_TR1_NAMESPACE / !_HAS_TR1_NAMESPACE vvv +typedef unsigned int uniform_int_distribution_type; +uniform_int_distribution uniform_int_distribution_dist(10, 90); +int uniform_int_distribution_smaller_ok = 0; +int uniform_int_distribution_larger_ok = 0; + +One_arg uniform_int_distribution_vals[] = { + {FLIT(0.0), FLIT(0.0), FLIT(0.0)}, + {FLIT(11.0), FLIT(0.012345679012345678328), FLIT(0.0)}, + {FLIT(22.0), FLIT(0.012345679012345678328), FLIT(0.0)}, + {FLIT(33.0), FLIT(0.012345679012345678328), FLIT(0.0)}, + {FLIT(44.0), FLIT(0.012345679012345678328), FLIT(0.0)}, + {FLIT(55.0), FLIT(0.012345679012345678328), FLIT(0.0)}, + {FLIT(66.0), FLIT(0.012345679012345678328), FLIT(0.0)}, + {FLIT(77.0), FLIT(0.012345679012345678328), FLIT(0.0)}, + {FLIT(88.0), FLIT(0.012345679012345678328), FLIT(0.0)}, + {FLIT(99.0), FLIT(0.0), FLIT(0.0)}, +}; + +typedef double uniform_real_distribution_type; +uniform_real_distribution uniform_real_distribution_dist(40.2, 60.5); +int uniform_real_distribution_smaller_ok = 0; +int uniform_real_distribution_larger_ok = 0; + +One_arg uniform_real_distribution_vals[] = { + {FLIT(0.0), FLIT(0.0), FLIT(0.0)}, + {FLIT(11.0), FLIT(0.0), FLIT(0.0)}, + {FLIT(22.0), FLIT(0.0), FLIT(0.0)}, + {FLIT(33.0), FLIT(0.0), FLIT(0.0)}, + {FLIT(44.0), FLIT(0.049261083743842366821), FLIT(0.0)}, + {FLIT(55.0), FLIT(0.049261083743842366821), FLIT(0.0)}, + {FLIT(66.0), FLIT(0.0), FLIT(0.0)}, + {FLIT(77.0), FLIT(0.0), FLIT(0.0)}, + {FLIT(88.0), FLIT(0.0), FLIT(0.0)}, + {FLIT(99.0), FLIT(0.0), FLIT(0.0)}, +}; +#endif // ^^^ !_HAS_TR1_NAMESPACE ^^^ typedef double cauchy_distribution_type; cauchy_distribution cauchy_distribution_dist(50.0, 20.0); diff --git a/tests/tr1/tests/random1/test.cpp b/tests/tr1/tests/random1/test.cpp index 1a3af256c8b..e8f842a64f4 100644 --- a/tests/tr1/tests/random1/test.cpp +++ b/tests/tr1/tests/random1/test.cpp @@ -60,8 +60,12 @@ struct test_globals { // tests engine global functions } }; -static void tlinear() { // test linear_congruential +static void tlinear() { +#if _HAS_TR1_NAMESPACE typedef STD linear_congruential rng_t; +#else // ^^^ _HAS_TR1_NAMESPACE / !_HAS_TR1_NAMESPACE vvv + typedef STD linear_congruential_engine rng_t; +#endif // ^^^ !_HAS_TR1_NAMESPACE ^^^ CHECK_INT(rng_t::multiplier, 16807); CHECK_INT(rng_t::increment, 0); @@ -79,6 +83,7 @@ static void tlinear() { // test linear_congruential CHECK_INT(rng1.max(), 2147483646); CHECK_INT(rng1(), 33614); +#if _HAS_TR1_NAMESPACE generator g; Uint32 init[] = {1, 2}; g.reset(init, 2); @@ -94,6 +99,7 @@ static void tlinear() { // test linear_congruential CHECK_INT(rng3.max(), 2147483646); CHECK_INT(rng3(), 33614); CHECK_INT(g.index(), 2); +#endif // ^^^ _HAS_TR1_NAMESPACE ^^^ rng.seed(1); CHECK_INT(rng.min(), 1); @@ -105,6 +111,7 @@ static void tlinear() { // test linear_congruential CHECK_INT(rng.max(), 2147483646); CHECK_INT(rng(), 33614); +#if _HAS_TR1_NAMESPACE g.reset(init, 2); rng3.seed(g); CHECK_INT(rng3.min(), 1); @@ -117,6 +124,7 @@ static void tlinear() { // test linear_congruential CHECK_INT(rng3.max(), 2147483646); CHECK_INT(rng3(), 33614); CHECK_INT(g.index(), 2); +#endif // ^^^ _HAS_TR1_NAMESPACE ^^^ test_globals::test(); @@ -124,7 +132,11 @@ static void tlinear() { // test linear_congruential typedef unsigned long long int_type; const int_type max_val = (int_type) -1; +#if _HAS_TR1_NAMESPACE typedef STD linear_congruential rng4_t; +#else // ^^^ _HAS_TR1_NAMESPACE / !_HAS_TR1_NAMESPACE vvv + typedef STD linear_congruential_engine rng4_t; +#endif // ^^^ !_HAS_TR1_NAMESPACE ^^^ rng4_t rng4(1); CHECK(rng4() == max_val - 1); CHECK(rng4() == 1); @@ -157,11 +169,16 @@ static void tminstd_rand() { } static void tmersenne() { +#if _HAS_TR1_NAMESPACE typedef STD mersenne_twister rng_t; +#else // ^^^ _HAS_TR1_NAMESPACE / !_HAS_TR1_NAMESPACE vvv + typedef STD mt19937 rng_t; +#endif // ^^^ !_HAS_TR1_NAMESPACE ^^^ CHECK_INT(rng_t::word_size, 32); CHECK_INT(rng_t::state_size, 624); CHECK_INT(rng_t::shift_size, 397); CHECK_INT(rng_t::mask_bits, 31); +#if _HAS_TR1_NAMESPACE CHECK_INT((int) rng_t::parameter_a, (int) 0x9908b0df); CHECK_INT(rng_t::output_u, 11); CHECK_INT(rng_t::output_s, 7); @@ -169,6 +186,17 @@ static void tmersenne() { CHECK_INT(rng_t::output_t, 15); CHECK_INT((int) rng_t::output_c, (int) 0xefc60000); CHECK_INT(rng_t::output_l, 18); +#else // ^^^ _HAS_TR1_NAMESPACE / !_HAS_TR1_NAMESPACE vvv + CHECK_INT(rng_t::xor_mask, 0x9908b0df); + CHECK_INT(rng_t::tempering_u, 11); + CHECK_INT(rng_t::tempering_d, 0xffffffff); + CHECK_INT(rng_t::tempering_s, 7); + CHECK_INT(rng_t::tempering_b, 0x9d2c5680); + CHECK_INT(rng_t::tempering_t, 15); + CHECK_INT(rng_t::tempering_c, 0xefc60000); + CHECK_INT(rng_t::tempering_l, 18); + CHECK_INT(rng_t::initialization_multiplier, 1812433253); +#endif // ^^^ !_HAS_TR1_NAMESPACE ^^^ bool st = STD is_same::value; CHECK(st); @@ -182,6 +210,7 @@ static void tmersenne() { CHECK_INT(ptr_rng1->max(), 0xffffffff); CHECK_INT((*ptr_rng1)(), 1791095845); +#if _HAS_TR1_NAMESPACE STD linear_congruential init_gen(4357); const auto ptr_rng2 = STD make_unique(init_gen); @@ -193,6 +222,7 @@ static void tmersenne() { CHECK_INT(rng3.min(), 0); CHECK_INT(rng3.max(), 0xffffffff); CHECK_INT(rng3(), (int) 2649890907u); +#endif // ^^^ _HAS_TR1_NAMESPACE ^^^ rng.seed(1); CHECK_INT(rng.min(), 0); @@ -204,6 +234,7 @@ static void tmersenne() { CHECK_INT(rng.max(), 0xffffffff); CHECK_INT(rng(), 1872583848); +#if _HAS_TR1_NAMESPACE init_gen.seed(4357); rng3.seed(init_gen); CHECK_INT(rng3.min(), 0); @@ -214,6 +245,7 @@ static void tmersenne() { CHECK_INT(rng3.min(), 0); CHECK_INT(rng3.max(), 0xffffffff); CHECK_INT(rng3(), (int) 2649890907u); +#endif // ^^^ _HAS_TR1_NAMESPACE ^^^ test_globals::test(); } @@ -274,8 +306,13 @@ static void tmt19937() { } static void tsubtract() { +#if _HAS_TR1_NAMESPACE typedef STD subtract_with_carry rng_t; CHECK_INT(rng_t::modulus, 1 << 24); +#else // ^^^ _HAS_TR1_NAMESPACE / !_HAS_TR1_NAMESPACE vvv + typedef STD subtract_with_carry_engine rng_t; + CHECK_INT(rng_t::word_size, 24); +#endif // ^^^ !_HAS_TR1_NAMESPACE ^^^ CHECK_INT(rng_t::short_lag, 10); CHECK_INT(rng_t::long_lag, 24); bool st = STD is_same::value; @@ -291,6 +328,7 @@ static void tsubtract() { CHECK_INT(rng1.max(), (1 << 24) - 1); CHECK_INT(rng1(), 8871692); +#if _HAS_TR1_NAMESPACE STD linear_congruential init_gen(19780503); rng_t rng2(init_gen); @@ -302,6 +340,7 @@ static void tsubtract() { CHECK_INT(rng3.min(), 0); CHECK_INT(rng3.max(), (1 << 24) - 1); CHECK_INT(rng3(), 6319224); +#endif // ^^^ _HAS_TR1_NAMESPACE ^^^ rng.seed(1); CHECK_INT(rng.min(), 0); @@ -313,6 +352,7 @@ static void tsubtract() { CHECK_INT(rng.max(), (1 << 24) - 1); CHECK_INT(rng(), 966168); +#if _HAS_TR1_NAMESPACE init_gen.seed(19780503); rng3.seed(init_gen); CHECK_INT(rng3.min(), 0); @@ -323,6 +363,7 @@ static void tsubtract() { CHECK_INT(rng3.min(), 0); CHECK_INT(rng3.max(), (1 << 24) - 1); CHECK_INT(rng3(), 6319224); +#endif // ^^^ _HAS_TR1_NAMESPACE ^^^ test_globals::test(); } @@ -377,7 +418,11 @@ static void tsubtract_01() { CHECK_DOUBLE(rng1.max(), 1.0); CHECK_DOUBLE(rng1(), 8871692 * factor); +#if _HAS_TR1_NAMESPACE STD linear_congruential init_gen(19780503); +#else // ^^^ _HAS_TR1_NAMESPACE / !_HAS_TR1_NAMESPACE vvv + STD linear_congruential_engine init_gen(19780503); +#endif // ^^^ !_HAS_TR1_NAMESPACE ^^^ rng_t rng2(init_gen); CHECK_DOUBLE(rng2.min(), 0.0); @@ -464,8 +509,13 @@ static void tranlux4_01() { static void tdiscard() { int i; +#if _HAS_TR1_NAMESPACE typedef STD subtract_with_carry rng_base_t; typedef STD discard_block rng_t; +#else // ^^^ _HAS_TR1_NAMESPACE / !_HAS_TR1_NAMESPACE vvv + typedef STD subtract_with_carry_engine rng_base_t; + typedef STD discard_block_engine rng_t; +#endif // ^^^ !_HAS_TR1_NAMESPACE ^^^ CHECK_INT(rng_t::block_size, 223); CHECK_INT(rng_t::used_block, 24); #if _HAS_TR1_NAMESPACE @@ -481,6 +531,7 @@ static void tdiscard() { CHECK_INT(rng.max(), (1 << 24) - 1); CHECK_INT(rng(), 15039276); +#if _HAS_TR1_NAMESPACE STD linear_congruential init_gen(19780503); rng_t rng2(init_gen); @@ -503,14 +554,15 @@ static void tdiscard() { CHECK_INT(rng3.min(), 0); CHECK_INT(rng3.max(), (1 << 24) - 1); CHECK_INT(rng3(), 6319224); +#endif // ^^^ _HAS_TR1_NAMESPACE ^^^ rng_base_t rng4; rng_t rng5; - for (i = 0; i < rng_t::used_block; ++i) { + for (i = 0; i < static_cast(rng_t::used_block); ++i) { CHECK_INT(rng4(), rng5()); } CHECK(rng4() != rng5()); - for (; i < rng_t::block_size; ++i) { + for (; i < static_cast(rng_t::block_size); ++i) { (void) rng4(); } diff --git a/tests/tr1/tests/random2/test.cpp b/tests/tr1/tests/random2/test.cpp index 641605e1760..fa99589f4f6 100644 --- a/tests/tr1/tests/random2/test.cpp +++ b/tests/tr1/tests/random2/test.cpp @@ -45,17 +45,23 @@ struct test_globals { }; static void tuniform_int() { +#if _HAS_TR1_NAMESPACE typedef STD uniform_int dist_t; + constexpr int default_max = 9; +#else // ^^^ _HAS_TR1_NAMESPACE / !_HAS_TR1_NAMESPACE vvv + typedef STD uniform_int_distribution dist_t; + constexpr int default_max = STD numeric_limits::max(); +#endif // ^^^ !_HAS_TR1_NAMESPACE ^^^ bool st = STD is_same::value; CHECK(st); dist_t dist0; CHECK_INT(dist0.min(), 0); - CHECK_INT(dist0.max(), 9); + CHECK_INT(dist0.max(), default_max); dist0.reset(); dist_t dist1(1); CHECK_INT(dist1.min(), 1); - CHECK_INT(dist1.max(), 9); + CHECK_INT(dist1.max(), default_max); dist_t dist2(2, 8); CHECK_INT(dist2.min(), 2); CHECK_INT(dist2.max(), 8); @@ -63,7 +69,7 @@ static void tuniform_int() { str << dist0; str >> dist2; CHECK_INT(dist2.min(), 0); - CHECK_INT(dist2.max(), 9); + CHECK_INT(dist2.max(), default_max); test_globals::test(); } @@ -206,7 +212,11 @@ static void tbinomial_distribution() { } static void tuniform_real() { +#if _HAS_TR1_NAMESPACE typedef STD uniform_real dist_t; +#else // ^^^ _HAS_TR1_NAMESPACE / !_HAS_TR1_NAMESPACE vvv + typedef STD uniform_real_distribution dist_t; +#endif // ^^^ !_HAS_TR1_NAMESPACE ^^^ bool st = STD is_same::value; CHECK(st);