diff --git a/stl/inc/random b/stl/inc/random index abb91f110d0..318884284ae 100644 --- a/stl/inc/random +++ b/stl/inc/random @@ -677,9 +677,9 @@ public: using _Mybase = _Circ_buf<_Ty, _Rx>; using _Seed_t = typename _Swc_Traits::_Seed_t; - static constexpr size_t short_lag = _Sx; - static constexpr size_t long_lag = _Rx; - static constexpr _Seed_t default_seed = static_cast<_Seed_t>(19780503U); + static constexpr size_t short_lag = _Sx; + static constexpr size_t long_lag = _Rx; + static constexpr uint_least32_t default_seed = 19780503u; _Swc_base() { seed(); @@ -694,8 +694,9 @@ public: seed(_Gx); } - void seed(_Seed_t _Value = default_seed, bool _Readcy = false) { // set initial values from specified seed value - linear_congruential<_Seed_t, 40014U, 0U, 2147483563U> _Lc{_Value == 0U ? default_seed : _Value}; + void seed(_Seed_t _Value = 0u, bool _Readcy = false) { // set initial values from specified seed value + linear_congruential_engine _Lc{ + static_cast(_Value == 0U ? default_seed : _Value)}; _Reset(_Lc, _Readcy); } @@ -805,7 +806,7 @@ struct _Swc_traits { // traits for subtract_with_carry generator static constexpr _Cy_t _Cy = 1; static constexpr _Mod_t _Mod = _Mx; - static constexpr _Ty _Max = _Mx - 1; + static constexpr _Ty _Max = static_cast<_Ty>(_Mx - 1); static int _Get_wc() noexcept { // compute number of 32-bit words per element int _Kx; @@ -892,7 +893,7 @@ public: using _Mybase::default_seed; - subtract_with_carry() : _Mybase(default_seed) {} + subtract_with_carry() : _Mybase(0u) {} explicit subtract_with_carry(_Ty _Xx0) : _Mybase(_Xx0) {} @@ -901,7 +902,8 @@ public: }; _EXPORT_STD template -class subtract_with_carry_engine : public subtract_with_carry<_Ty, (_Ty{1} << (_Wx - 1)) << 1, _Sx, _Rx> { +class subtract_with_carry_engine + : public subtract_with_carry<_Ty, static_cast<_Ty>((_Ty{1} << (_Wx - 1)) << 1), _Sx, _Rx> { // subtract_with_carry generator public: _RNG_REQUIRE_UINTTYPE(subtract_with_carry_engine, _Ty); @@ -909,7 +911,7 @@ public: 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 = (_Ty{1} << (_Wx - 1)) << 1; + 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; @@ -920,7 +922,7 @@ public: using _Mybase::default_seed; - subtract_with_carry_engine() : _Mybase(default_seed) {} + subtract_with_carry_engine() : _Mybase(0u) {} explicit subtract_with_carry_engine(_Ty _Xx0) : _Mybase(_Xx0) {} @@ -929,7 +931,7 @@ public: seed(_Seq); } - void seed(_Ty _Value = default_seed) { // set initial values from specified seed value + void seed(_Ty _Value = 0u) { // set initial values from specified seed value _Mybase::seed(_Value); } diff --git a/tests/std/tests/Dev11_0577418_random_seed_0/test.cpp b/tests/std/tests/Dev11_0577418_random_seed_0/test.cpp index 6cff3d0e2d8..3bfbefecbc8 100644 --- a/tests/std/tests/Dev11_0577418_random_seed_0/test.cpp +++ b/tests/std/tests/Dev11_0577418_random_seed_0/test.cpp @@ -2,7 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include +#include #include +#include + +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) using namespace std; @@ -13,20 +17,31 @@ typename Engine::result_type run_10k(Engine engine) { } int main() { - assert(run_10k(minstd_rand0()) == 1043618065UL); // N3485 26.5.5 [rand.predef]/1 - assert(run_10k(mt19937()) == 4123659995UL); // N3485 26.5.5 [rand.predef]/3 - assert(run_10k(ranlux24_base()) == 7937952UL); // N3485 26.5.5 [rand.predef]/5 + assert(run_10k(minstd_rand0()) == 1043618065UL); // N4964 [rand.predef]/1 + assert(run_10k(mt19937()) == 4123659995UL); // N4964 [rand.predef]/3 + assert(run_10k(ranlux24_base()) == 7937952UL); // N4964 [rand.predef]/5 // Also test VSO-214595 "subtract_with_carry_engine::seed should accept result_type" subtract_with_carry_engine ull_swc; ull_swc.seed(0x12341234'00000000ULL); - assert(run_10k(ull_swc) == 0x01316AEA'3646F686ULL); // libstdc++ and libc++ agree (boost 1.60.0 disagrees) + assert(run_10k(ull_swc) == 0x1DD6C263'C41EEED0ULL); // value changed by LWG-3809 - assert(minstd_rand0(0) == minstd_rand0()); // N3485 26.5.3.1 [rand.eng.lcong]/5 - assert(mt19937(0) != mt19937()); // N3485 26.5.3.2 [rand.eng.mers]/6 - assert(ranlux24_base(0) == ranlux24_base()); // N3485 26.5.3.3 [rand.eng.sub]/7 + assert(minstd_rand0(0) == minstd_rand0()); // N4964 [rand.eng.lcong]/5 + assert(mt19937(0) != mt19937()); // N4964 [rand.eng.mers]/6 + assert(ranlux24_base(0) == ranlux24_base()); // N4964 [rand.eng.sub]/7 assert(run_10k(minstd_rand0(0)) == 1043618065UL); // QED assert(run_10k(mt19937(0)) == 1543171712UL); // Boost 1.52.0 agrees assert(run_10k(ranlux24_base(0)) == 7937952UL); // QED + + // Also test LWG-3809 Is std::subtract_with_carry_engine supposed to work? + STATIC_ASSERT(is_same_v::default_seed), + const uint_least32_t>); + STATIC_ASSERT( + is_same_v::default_seed), const uint_least32_t>); + STATIC_ASSERT( + is_same_v::default_seed), const uint_least32_t>); + STATIC_ASSERT(is_same_v::default_seed), + const uint_least32_t>); + assert(run_10k(subtract_with_carry_engine{}) == 6793538734622947770ULL); }