diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm --- a/libcxx/include/algorithm +++ b/libcxx/include/algorithm @@ -3029,9 +3029,17 @@ public: // constructors and reset functions - explicit uniform_int_distribution(result_type __a = 0, - result_type __b = numeric_limits::max()) +#if _LIBCPP_STD_VER > 17 + uniform_int_distribution() : uniform_int_distribution(0) {} + explicit uniform_int_distribution( + result_type __a, result_type __b = numeric_limits::max()) : __p_(param_type(__a, __b)) {} +#else + explicit uniform_int_distribution( + result_type __a = 0, + result_type __b = numeric_limits::max()) + : __p_(param_type(__a, __b)) {} +#endif explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {} void reset() {} 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,9 @@ static constexpr result_type default_seed = 5489u; // constructors and seeding functions - explicit mersenne_twister_engine(result_type value = default_seed); + explicit mersenne_twister_engine(result_type s = default_seed); // before C++20 + mersenne_twister_engine() : mersenne_twister_engine(default_seed) {} // C++20 + explicit mersenne_twister_engine(result_type s); // C++20 template explicit mersenne_twister_engine(Sseq& q); void seed(result_type value = default_seed); template void seed(Sseq& q); @@ -154,7 +158,9 @@ static constexpr result_type default_seed = 19780503u; // constructors and seeding functions - explicit subtract_with_carry_engine(result_type value = default_seed); + explicit subtract_with_carry_engine(result_type value = default_seed); // before C++20 + subtract_with_carry_engine() : subtract_with_carry_engine(default_seed) {} // C++20 + explicit subtract_with_carry_engine(result_type value); // C++20 template explicit subtract_with_carry_engine(Sseq& q); void seed(result_type value = default_seed); template void seed(Sseq& q); @@ -385,7 +391,9 @@ static constexpr result_type max() { return numeric_limits::max(); } // constructors - explicit random_device(const string& token = "/dev/urandom"); + explicit random_device(const string& token = implementation-defined); // before C++20 + random_device() : random_device(implementation-defined) {} // C++20 + explicit random_device(const string& token); // C++20 // generating functions result_type operator()(); @@ -456,7 +464,10 @@ // constructors and reset functions explicit uniform_int_distribution(IntType a = 0, - IntType b = numeric_limits::max()); + IntType b = numeric_limits::max()); // before C++20 + uniform_int_distribution() : uniform_int_distribution(0) {} // C++20 + explicit uniform_int_distribution(IntType a, + IntType b = numeric_limits::max()); // C++20 explicit uniform_int_distribution(const param_type& parm); void reset(); @@ -515,7 +526,9 @@ }; // constructors and reset functions - explicit uniform_real_distribution(RealType a = 0.0, RealType b = 1.0); + explicit uniform_real_distribution(RealType a = 0.0, RealType b = 1.0); // before C++20 + uniform_real_distribution() : uniform_real_distribution(0.0) {} // C++20 + explicit uniform_real_distribution(RealType a, RealType b = 1.0); // C++20 explicit uniform_real_distribution(const param_type& parm); void reset(); @@ -1875,9 +1888,17 @@ 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);} + explicit linear_congruential_engine(result_type __s = default_seed) { + seed(__s); + } +#endif template _LIBCPP_INLINE_VISIBILITY explicit linear_congruential_engine(_Sseq& __q, @@ -2124,9 +2145,17 @@ static _LIBCPP_CONSTEXPR const result_type default_seed = 5489u; // constructors and seeding functions +#if _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY - explicit mersenne_twister_engine(result_type __sd = default_seed) - {seed(__sd);} + mersenne_twister_engine() : mersenne_twister_engine(default_seed) {} + _LIBCPP_INLINE_VISIBILITY + explicit mersenne_twister_engine(result_type __sd) { seed(__sd); } +#else + _LIBCPP_INLINE_VISIBILITY + explicit mersenne_twister_engine(result_type __sd = default_seed) { + seed(__sd); + } +#endif template _LIBCPP_INLINE_VISIBILITY explicit mersenne_twister_engine(_Sseq& __q, @@ -2582,9 +2611,17 @@ static _LIBCPP_CONSTEXPR const result_type default_seed = 19780503u; // constructors and seeding functions +#if _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY - explicit subtract_with_carry_engine(result_type __sd = default_seed) - {seed(__sd);} + subtract_with_carry_engine() : subtract_with_carry_engine(default_seed) {} + _LIBCPP_INLINE_VISIBILITY + explicit subtract_with_carry_engine(result_type __sd) { seed(__sd); } +#else + _LIBCPP_INLINE_VISIBILITY + explicit subtract_with_carry_engine(result_type __sd = default_seed) { + seed(__sd); + } +#endif template _LIBCPP_INLINE_VISIBILITY explicit subtract_with_carry_engine(_Sseq& __q, @@ -3524,7 +3561,12 @@ static _LIBCPP_CONSTEXPR result_type max() { return _Max;} // constructors +#if _LIBCPP_STD_VER > 17 + random_device() : random_device("/dev/urandom") {} + explicit random_device(const string& __token); +#else explicit random_device(const string& __token = "/dev/urandom"); +#endif ~random_device(); // generating functions @@ -3758,9 +3800,16 @@ public: // constructors and reset functions +#if _LIBCPP_STD_VER > 17 + _LIBCPP_INLINE_VISIBILITY + uniform_real_distribution() : uniform_real_distribution(0.0) {} + explicit uniform_real_distribution(result_type __a, result_type __b = 1.0) + : __p_(param_type(__a, __b)) {} +#else _LIBCPP_INLINE_VISIBILITY explicit uniform_real_distribution(result_type __a = 0, result_type __b = 1) : __p_(param_type(__a, __b)) {} +#endif _LIBCPP_INLINE_VISIBILITY explicit uniform_real_distribution(const param_type& __p) : __p_(__p) {} _LIBCPP_INLINE_VISIBILITY diff --git a/libcxx/test/std/numerics/rand/rand.device/ctor.pass.cpp b/libcxx/test/std/numerics/rand/rand.device/ctor.pass.cpp --- a/libcxx/test/std/numerics/rand/rand.device/ctor.pass.cpp +++ b/libcxx/test/std/numerics/rand/rand.device/ctor.pass.cpp @@ -18,7 +18,9 @@ // class random_device; -// explicit random_device(const string& token = implementation-defined); +// explicit random_device(const string& token = implementation-defined); // before C++20 +// random_device() : random_device(implementation-defined) {} // C++20 +// explicit random_device(const string& token); // C++20 // For the following ctors, the standard states: "The semantics and default // value of the token parameter are implementation-defined". Implementations @@ -34,7 +36,7 @@ #endif #include "test_macros.h" - +#include "test_convertible.h" bool is_valid_random_device(const std::string &token) { #if defined(_LIBCPP_USING_DEV_RANDOM) @@ -61,7 +63,6 @@ #endif } - int main(int, char**) { { std::random_device r; @@ -100,5 +101,11 @@ } #endif // !defined(_WIN32) +#if TEST_STD_VER > 17 + static_assert(test_convertible(), ""); +#else + static_assert(!test_convertible(), ""); +#endif + return 0; } diff --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/ctor_int_int.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/ctor_int_int.pass.cpp --- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/ctor_int_int.pass.cpp +++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/ctor_int_int.pass.cpp @@ -12,12 +12,17 @@ // class uniform_int_distribution // explicit uniform_int_distribution(IntType a = 0, -// IntType b = numeric_limits::max()); +// IntType b = numeric_limits::max()); // before C++20 +// uniform_int_distribution() : uniform_int_distribution(0) {} // C++20 +// explicit uniform_int_distribution(IntType a, +// IntType b = numeric_limits::max()); // C++20 #include #include #include "test_macros.h" +#include "make_implicit.h" +#include "test_convertible.h" int main(int, char**) { @@ -40,5 +45,17 @@ assert(d.b() == 106); } - return 0; + { + using D = std::uniform_int_distribution<>; +#if TEST_STD_VER > 17 + static_assert(test_convertible(), ""); + assert(D(0) == make_implicit()); +#else + static_assert(!test_convertible(), ""); +#endif + static_assert(!test_convertible(), ""); + static_assert(!test_convertible(), ""); + } + + return 0; } diff --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/ctor_int_int.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/ctor_int_int.pass.cpp deleted file mode 100644 --- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/ctor_int_int.pass.cpp +++ /dev/null @@ -1,44 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// - -// template -// class uniform_real_distribution - -// explicit uniform_real_distribution(RealType a = 0, -// RealType b = 1); - -#include -#include - -#include "test_macros.h" - -int main(int, char**) -{ - { - typedef std::uniform_real_distribution<> D; - D d; - assert(d.a() == 0); - assert(d.b() == 1); - } - { - typedef std::uniform_real_distribution<> D; - D d(-6); - assert(d.a() == -6); - assert(d.b() == 1); - } - { - typedef std::uniform_real_distribution<> D; - D d(-6, 106); - assert(d.a() == -6); - assert(d.b() == 106); - } - - return 0; -} diff --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/ctor_real_real.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/ctor_real_real.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/ctor_real_real.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// template +// class uniform_real_distribution + +// explicit uniform_real_distribution(RealType a = 0.0, +// RealType b = 1.0); // before C++20 +// uniform_real_distribution() : uniform_real_distribution(0.0) {} // C++20 +// explicit uniform_real_distribution(RealType a, RealType b = 1.0); // C++20 + +#include +#include + +#include "test_macros.h" +#include "make_implicit.h" +#include "test_convertible.h" + +int main(int, char**) +{ + { + typedef std::uniform_real_distribution<> D; + D d; + assert(d.a() == 0.0); + assert(d.b() == 1.0); + } + { + typedef std::uniform_real_distribution<> D; + D d(-6.5); + assert(d.a() == -6.5); + assert(d.b() == 1.0); + } + { + typedef std::uniform_real_distribution<> D; + D d(-6.9, 106.1); + assert(d.a() == -6.9); + assert(d.b() == 106.1); + } + + { + using D = std::uniform_real_distribution<>; +#if TEST_STD_VER > 17 + static_assert(test_convertible(), ""); + assert(D(0) == make_implicit()); +#else + static_assert(!test_convertible(), ""); +#endif + static_assert(!test_convertible(), ""); + static_assert(!test_convertible(), ""); + } + + return 0; +} 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 @@ -21,6 +23,15 @@ #include #include "test_macros.h" +#include "make_implicit.h" +#include "test_convertible.h" + +template +std::string to_string(T const& e) { + std::ostringstream os; + os << e; + return os.str(); +} template void @@ -30,23 +41,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 +63,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 +85,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 +107,28 @@ { 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 +void test_implicit_ctor() { + using E = std::linear_congruential_engine; + assert(E(E::default_seed) == make_implicit()); +} +#endif + int main(int, char**) { test1(); @@ -156,5 +151,16 @@ test4(); test4(); - return 0; + { + typedef std::linear_congruential_engine E; +#if TEST_STD_VER > 17 + static_assert(test_convertible(), ""); + test_implicit_ctor(); +#else + static_assert(!test_convertible(), ""); +#endif + static_assert(!test_convertible(), ""); + } + + return 0; } diff --git a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/ctor_result_type.pass.cpp b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/ctor_result_type.pass.cpp --- a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/ctor_result_type.pass.cpp +++ b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/ctor_result_type.pass.cpp @@ -13,7 +13,9 @@ // UIntType b, size_t t, UIntType c, size_t l, UIntType f> // class mersenne_twister_engine; -// explicit mersenne_twister_engine(result_type s = default_seed); +// explicit mersenne_twister_engine(result_type s = default_seed); // before C++20 +// mersenne_twister_engine() : mersenne_twister_engine(default_seed) {} // C++20 +// explicit mersenne_twister_engine(result_type s); // C++20 // Serializing/deserializing the state of the RNG requires iostreams // UNSUPPORTED: libcpp-has-no-localization @@ -23,6 +25,17 @@ #include #include "test_macros.h" +#include "make_implicit.h" +#include "test_convertible.h" + +template +std::string +to_string(T const &e) +{ + std::ostringstream os; + os << e; + return os.str(); +} void test1() @@ -124,9 +137,7 @@ "3668048733 2030009470 1910839172 1234925283 3575831445 123595418 " "2362440495 3048484911 1796872496"; std::mt19937 e1(0); - std::ostringstream os; - os << e1; - assert(os.str() == a); + assert(to_string(e1) == a); } void @@ -237,15 +248,31 @@ "15150289760867914983 4931341382074091848 12635920082410445322 " "8498109357807439006 14836776625250834986"; std::mt19937_64 e1(0); - std::ostringstream os; - os << e1; - assert(os.str() == a); + assert(to_string(e1) == a); +} + +#if TEST_STD_VER > 17 +template +void test_implicit_ctor() { + assert(E(E::default_seed) == make_implicit()); } +#endif int main(int, char**) { test1(); test2(); +#if TEST_STD_VER > 17 + static_assert(test_convertible(), ""); + static_assert(test_convertible(), ""); + test_implicit_ctor(); + test_implicit_ctor(); +#else + static_assert(!test_convertible(), ""); + static_assert(!test_convertible(), ""); +#endif + static_assert(!test_convertible(), ""); + static_assert(!test_convertible(), ""); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/ctor_result_type.pass.cpp b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/ctor_result_type.pass.cpp --- a/libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/ctor_result_type.pass.cpp +++ b/libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/ctor_result_type.pass.cpp @@ -11,7 +11,9 @@ // template // class subtract_with_carry_engine; -// explicit subtract_with_carry_engine(result_type s = default_seed); +// explicit subtract_with_carry_engine(result_type s = default_seed); // before C++20 +// subtract_with_carry_engine() : subtract_with_carry_engine(default_seed) {} // C++20 +// explicit subtract_with_carry_engine(result_type s); // C++20 // Serializing/deserializing the state of the RNG requires iostreams // UNSUPPORTED: libcpp-has-no-localization @@ -21,6 +23,17 @@ #include #include "test_macros.h" +#include "make_implicit.h" +#include "test_convertible.h" + +template +std::string +to_string(T const &e) +{ + std::ostringstream os; + os << e; + return os.str(); +} void test1() @@ -30,9 +43,7 @@ "13398366 8134459 16629731 6851902 15583892 1317475 4231148 9092691 " "5707268 2355175 0"; std::ranlux24_base e1(0); - std::ostringstream os; - os << e1; - assert(os.str() == a); + assert(to_string(e1) == a); } void @@ -43,15 +54,31 @@ "34339434557790 155299155394531 29014415493780 209265474179052 " "263777435457028 0"; std::ranlux48_base e1(0); - std::ostringstream os; - os << e1; - assert(os.str() == a); + assert(to_string(e1) == a); +} + +#if TEST_STD_VER > 17 +template +void test_implicit_ctor() { + assert(E(E::default_seed) == make_implicit()); } +#endif int main(int, char**) { test1(); test2(); +#if TEST_STD_VER > 17 + static_assert(test_convertible(), ""); + static_assert(test_convertible(), ""); + test_implicit_ctor(); + test_implicit_ctor(); +#else + static_assert(!test_convertible(), ""); + static_assert(!test_convertible(), ""); + static_assert(!test_convertible(), ""); + static_assert(!test_convertible(), ""); +#endif return 0; } diff --git a/libcxx/test/support/make_implicit.h b/libcxx/test/support/make_implicit.h new file mode 100644 --- /dev/null +++ b/libcxx/test/support/make_implicit.h @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef SUPPORT_MAKE_IMPLICIT_H +#define SUPPORT_MAKE_IMPLICIT_H + +// "make_implicit(Args&&... args)" is a function to construct 'Tp' +// from 'Args...' using implicit construction. + +#include + +#include "test_macros.h" + +#if TEST_STD_VER < 11 +#error make_implicit.h requires C++11 or newer +#endif + +template +T make_implicit(Args&&... args) { + return {std::forward(args)...}; +} + +#endif // SUPPORT_MAKE_IMPLICIT_H