diff --git a/libcxx/include/random b/libcxx/include/random --- a/libcxx/include/random +++ b/libcxx/include/random @@ -36,7 +36,9 @@ static constexpr result_type default_seed = 1u; // constructors and seeding functions - explicit linear_congruential_engine(result_type s = default_seed); + explicit linear_congruential_engine(result_type s = default_seed); // before C++20 + linear_congruential_engine() : linear_congruential_engine(default_seed) {} // C++20 + explicit linear_congruential_engine(result_type s); // C++20 template explicit linear_congruential_engine(Sseq& q); void seed(result_type s = default_seed); template void seed(Sseq& q); @@ -96,7 +98,8 @@ static constexpr result_type default_seed = 5489u; // constructors and seeding functions - explicit mersenne_twister_engine(result_type value = default_seed); + mersenne_twister_engine(); + explicit mersenne_twister_engine(result_type value); template explicit mersenne_twister_engine(Sseq& q); void seed(result_type value = default_seed); template void seed(Sseq& q); @@ -154,7 +157,8 @@ static constexpr result_type default_seed = 19780503u; // constructors and seeding functions - explicit subtract_with_carry_engine(result_type value = default_seed); + subtract_with_carry_engine(); + explicit subtract_with_carry_engine(result_type value); template explicit subtract_with_carry_engine(Sseq& q); void seed(result_type value = default_seed); template void seed(Sseq& q); @@ -385,7 +389,8 @@ static constexpr result_type max() { return numeric_limits::max(); } // constructors - explicit random_device(const string& token = "/dev/urandom"); + random_device(); + explicit random_device(const string& token); // generating functions result_type operator()(); @@ -455,7 +460,8 @@ }; // constructors and reset functions - explicit uniform_int_distribution(IntType a = 0, + uniform_int_distribution(); + explicit uniform_int_distribution(IntType a, IntType b = numeric_limits::max()); explicit uniform_int_distribution(const param_type& parm); void reset(); @@ -515,7 +521,8 @@ }; // constructors and reset functions - explicit uniform_real_distribution(RealType a = 0.0, RealType b = 1.0); + uniform_real_distribution(); + explicit uniform_real_distribution(RealType a, RealType b = 1.0); explicit uniform_real_distribution(const param_type& parm); void reset(); @@ -571,7 +578,8 @@ }; // constructors and reset functions - explicit bernoulli_distribution(double p = 0.5); + bernoulli_distribution(); + explicit bernoulli_distribution(double p); explicit bernoulli_distribution(const param_type& parm); void reset(); @@ -628,7 +636,8 @@ }; // constructors and reset functions - explicit binomial_distribution(IntType t = 1, double p = 0.5); + binomial_distribution() : binomial_distribution(1) {} + explicit binomial_distribution(IntType t, double p = 0.5); explicit binomial_distribution(const param_type& parm); void reset(); @@ -685,7 +694,8 @@ }; // constructors and reset functions - explicit geometric_distribution(double p = 0.5); + geometric_distribution() : geometric_distribution(0.5) {} + explicit geometric_distribution(double p); explicit geometric_distribution(const param_type& parm); void reset(); @@ -742,7 +752,8 @@ }; // constructor and reset functions - explicit negative_binomial_distribution(result_type k = 1, double p = 0.5); + negative_binomial_distribution() : negative_binomial_distribution(1) {} + explicit negative_binomial_distribution(result_type k, double p = 0.5); explicit negative_binomial_distribution(const param_type& parm); void reset(); @@ -799,7 +810,8 @@ }; // constructors and reset functions - explicit poisson_distribution(double mean = 1.0); + poisson_distribution() : poisson_distribution(1.0) {} + explicit poisson_distribution(double mean); explicit poisson_distribution(const param_type& parm); void reset(); @@ -855,7 +867,8 @@ }; // constructors and reset functions - explicit exponential_distribution(result_type lambda = 1.0); + exponential_distribution() : exponential_distribution(1.0) {} + explicit exponential_distribution(result_type lambda); explicit exponential_distribution(const param_type& parm); void reset(); @@ -912,7 +925,8 @@ }; // constructors and reset functions - explicit gamma_distribution(result_type alpha = 1, result_type beta = 1); + gamma_distribution() : gamma_distribution(1) {} + explicit gamma_distribution(result_type alpha, result_type beta = 1); explicit gamma_distribution(const param_type& parm); void reset(); @@ -970,7 +984,8 @@ }; // constructor and reset functions - explicit weibull_distribution(result_type a = 1, result_type b = 1); + weibull_distribution() : weibull_distribution(1); + explicit weibull_distribution(result_type a, result_type b = 1); explicit weibull_distribution(const param_type& parm); void reset(); @@ -1028,7 +1043,8 @@ }; // constructor and reset functions - explicit extreme_value_distribution(result_type a = 0, result_type b = 1); + extreme_value_distribution() : extreme_value_distribution(0) {} + explicit extreme_value_distribution(result_type a, result_type b = 1); explicit extreme_value_distribution(const param_type& parm); void reset(); @@ -1086,7 +1102,8 @@ }; // constructors and reset functions - explicit normal_distribution(result_type mean = 0, result_type stddev = 1); + normal_distribution() : normal_distribution(0) {} + explicit normal_distribution(result_type mean, result_type stddev = 1); explicit normal_distribution(const param_type& parm); void reset(); @@ -1144,7 +1161,8 @@ }; // constructor and reset functions - explicit lognormal_distribution(result_type m = 0, result_type s = 1); + lognormal_distribution() : lognormal_distribution(0) {} + explicit lognormal_distribution(result_type m, result_type s = 1); explicit lognormal_distribution(const param_type& parm); void reset(); @@ -1201,7 +1219,8 @@ }; // constructor and reset functions - explicit chi_squared_distribution(result_type n = 1); + chi_squared_distribution() : chi_squared_distribution(1); + explicit chi_squared_distribution(result_type n); explicit chi_squared_distribution(const param_type& parm); void reset(); @@ -1258,7 +1277,8 @@ }; // constructor and reset functions - explicit cauchy_distribution(result_type a = 0, result_type b = 1); + cauchy_distribution() : cauchy_distribution(0) {} + explicit cauchy_distribution(result_type a, result_type b = 1); explicit cauchy_distribution(const param_type& parm); void reset(); @@ -1316,7 +1336,8 @@ }; // constructor and reset functions - explicit fisher_f_distribution(result_type m = 1, result_type n = 1); + fisher_f_distribution() : fisher_f_distribution(1) {} + explicit fisher_f_distribution(result_type m, result_type n = 1); explicit fisher_f_distribution(const param_type& parm); void reset(); @@ -1373,7 +1394,8 @@ }; // constructor and reset functions - explicit student_t_distribution(result_type n = 1); + student_t_distribution() : student_t_distribution(1) {} + explicit student_t_distribution(result_type n); explicit student_t_distribution(const param_type& parm); void reset(); @@ -1875,9 +1897,19 @@ static _LIBCPP_CONSTEXPR const result_type default_seed = 1u; // constructors and seeding functions +#if _LIBCPP_STD_VER > 17 + _LIBCPP_INLINE_VISIBILITY + linear_congruential_engine() : linear_congruential_engine(default_seed) {} + + _LIBCPP_INLINE_VISIBILITY + explicit linear_congruential_engine(result_type __s) + {seed(__s);} +#else _LIBCPP_INLINE_VISIBILITY explicit linear_congruential_engine(result_type __s = default_seed) {seed(__s);} +#endif + template _LIBCPP_INLINE_VISIBILITY explicit linear_congruential_engine(_Sseq& __q, diff --git a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/ctor_result_type.pass.cpp b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/ctor_result_type.pass.cpp --- a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/ctor_result_type.pass.cpp +++ b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/ctor_result_type.pass.cpp @@ -11,7 +11,9 @@ // template // class linear_congruential_engine; -// explicit linear_congruential_engine(result_type s = default_seed); +// explicit linear_congruential_engine(result_type s = default_seed); // before C++20 +// linear_congruential_engine() : linear_congruential_engine(default_seed) {} // C++20 +// explicit linear_congruential_engine(result_type s); // C++20 // Serializing/deserializing the state of the RNG requires iostreams // UNSUPPORTED: libcpp-has-no-localization @@ -20,8 +22,18 @@ #include #include + #include "test_macros.h" +template +std::string +to_string(T const &e) +{ + std::ostringstream os; + os << e; + return os.str(); +} + template void test1() @@ -30,23 +42,17 @@ { typedef std::linear_congruential_engine E; E e(5); - std::ostringstream os; - os << e; - assert(os.str() == "5"); + assert(to_string(e) == "5"); } { typedef std::linear_congruential_engine E; E e(5); - std::ostringstream os; - os << e; - assert(os.str() == "5"); + assert(to_string(e) == "5"); } { typedef std::linear_congruential_engine E; E e(5); - std::ostringstream os; - os << e; - assert(os.str() == "1"); + assert(to_string(e) == "1"); } } @@ -58,23 +64,17 @@ { typedef std::linear_congruential_engine E; E e(7); - std::ostringstream os; - os << e; - assert(os.str() == "0"); + assert(to_string(e) == "0"); } { typedef std::linear_congruential_engine E; E e(0); - std::ostringstream os; - os << e; - assert(os.str() == "0"); + assert(to_string(e) == "0"); } { typedef std::linear_congruential_engine E; E e(4); - std::ostringstream os; - os << e; - assert(os.str() == "0"); + assert(to_string(e) == "0"); } } @@ -86,23 +86,17 @@ { typedef std::linear_congruential_engine E; E e(3); - std::ostringstream os; - os << e; - assert(os.str() == "3"); + assert(to_string(e) == "3"); } { typedef std::linear_congruential_engine E; E e(5); - std::ostringstream os; - os << e; - assert(os.str() == "5"); + assert(to_string(e) == "5"); } { typedef std::linear_congruential_engine E; E e(7); - std::ostringstream os; - os << e; - assert(os.str() == "3"); + assert(to_string(e) == "3"); } } @@ -114,26 +108,40 @@ { typedef std::linear_congruential_engine E; E e(7); - std::ostringstream os; - os << e; - assert(os.str() == "1"); + assert(to_string(e) == "1"); } { typedef std::linear_congruential_engine E; E e(0); - std::ostringstream os; - os << e; - assert(os.str() == "1"); + assert(to_string(e) == "1"); } { typedef std::linear_congruential_engine E; E e(8); - std::ostringstream os; - os << e; - assert(os.str() == "1"); + assert(to_string(e) == "1"); } } +#if TEST_STD_VER > 17 +template +T +make_implicit(Args &&... args) +{ + return {forward(args)...}; +} + +template +void +test5() +{ + typedef std::linear_congruential_engine E; + auto e_default = make_implicit(); + auto e_1 = E(1); + assert(to_string(e_default) == to_string(e_1)); + assert(to_string(e_default) == "1"); +} +#endif + int main(int, char**) { test1(); @@ -156,5 +164,12 @@ test4(); test4(); +#if TEST_STD_VER > 17 + test5(); + test5(); + test5(); + test5(); +#endif + return 0; }