[llvm-branch-commits] [libcxx] a11f8b1 - [libc++] [P0935] [C++20] Eradicating unnecessarily explicit default constructors from the standard library.

Marek Kurdej via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Jan 18 23:27:09 PST 2021


Author: Marek Kurdej
Date: 2021-01-19T08:22:06+01:00
New Revision: a11f8b1ad66d68ca0a3a277ce776007abff9c7eb

URL: https://github.com/llvm/llvm-project/commit/a11f8b1ad66d68ca0a3a277ce776007abff9c7eb
DIFF: https://github.com/llvm/llvm-project/commit/a11f8b1ad66d68ca0a3a277ce776007abff9c7eb.diff

LOG: [libc++] [P0935] [C++20] Eradicating unnecessarily explicit default constructors from the standard library.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0935r0.html

Reviewed By: ldionne, #libc

Differential Revision: https://reviews.llvm.org/D91292

Added: 
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/ctor_real_real.pass.cpp
    libcxx/test/support/make_implicit.h

Modified: 
    libcxx/docs/Cxx2aStatusPaperStatus.csv
    libcxx/include/algorithm
    libcxx/include/locale
    libcxx/include/queue
    libcxx/include/random
    libcxx/include/regex
    libcxx/include/sstream
    libcxx/include/strstream
    libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp.pass.cpp
    libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp_container.pass.cpp
    libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp_rcontainer.pass.cpp
    libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_default.pass.cpp
    libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_container.pass.cpp
    libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_default.pass.cpp
    libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_rcontainer.pass.cpp
    libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_container.pass.cpp
    libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_default.pass.cpp
    libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_rcontainer.pass.cpp
    libcxx/test/std/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.cons/default.pass.cpp
    libcxx/test/std/input.output/string.streams/istringstream/istringstream.cons/default.pass.cpp
    libcxx/test/std/input.output/string.streams/ostringstream/ostringstream.cons/default.pass.cpp
    libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/default.pass.cpp
    libcxx/test/std/input.output/string.streams/stringstream.cons/default.pass.cpp
    libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp
    libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_codecvt.pass.cpp
    libcxx/test/std/numerics/rand/rand.device/ctor.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/ctor_double.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/ctor_int_double.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.geo/ctor_double.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/ctor_int_double.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.cauchy/ctor_double_double.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.chisq/ctor_double.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.f/ctor_double_double.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/ctor_double_double.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.normal/ctor_double_double.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.t/ctor_double.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.exp/ctor_double.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.extreme/ctor_double_double.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.gamma/ctor_double_double.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.poisson/ctor_double.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.weibull/ctor_double_double.pass.cpp
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.int/ctor_int_int.pass.cpp
    libcxx/test/std/numerics/rand/rand.eng/rand.eng.lcong/ctor_result_type.pass.cpp
    libcxx/test/std/numerics/rand/rand.eng/rand.eng.mers/ctor_result_type.pass.cpp
    libcxx/test/std/numerics/rand/rand.eng/rand.eng.sub/ctor_result_type.pass.cpp
    libcxx/test/std/re/re.results/re.results.const/default.pass.cpp

Removed: 
    libcxx/test/std/numerics/rand/rand.dis/rand.dist.uni/rand.dist.uni.real/ctor_int_int.pass.cpp


################################################################################
diff  --git a/libcxx/docs/Cxx2aStatusPaperStatus.csv b/libcxx/docs/Cxx2aStatusPaperStatus.csv
index 3747977b5d6c..495489c4c4c8 100644
--- a/libcxx/docs/Cxx2aStatusPaperStatus.csv
+++ b/libcxx/docs/Cxx2aStatusPaperStatus.csv
@@ -44,7 +44,7 @@
 "`P0887R1 <https://wg21.link/P0887R1>`__","LWG","The identity metafunction","Rapperswil","|Complete|","8.0"
 "`P0892R2 <https://wg21.link/P0892R2>`__","CWG","explicit(bool)","Rapperswil","",""
 "`P0898R3 <https://wg21.link/P0898R3>`__","LWG","Standard Library Concepts","Rapperswil","",""
-"`P0935R0 <https://wg21.link/P0935R0>`__","LWG","Eradicating unnecessarily explicit default constructors from the standard library","Rapperswil","",""
+"`P0935R0 <https://wg21.link/P0935R0>`__","LWG","Eradicating unnecessarily explicit default constructors from the standard library","Rapperswil","|Complete|","12.0"
 "`P0941R2 <https://wg21.link/P0941R2>`__","CWG","Integrating feature-test macros into the C++ WD","Rapperswil","|In Progress|",""
 "`P1023R0 <https://wg21.link/P1023R0>`__","LWG","constexpr comparison operators for std::array","Rapperswil","|Complete|","8.0"
 "`P1025R1 <https://wg21.link/P1025R1>`__","CWG","Update The Reference To The Unicode Standard","Rapperswil","",""

diff  --git a/libcxx/include/algorithm b/libcxx/include/algorithm
index fe9caf475f5a..da55e5e9add0 100644
--- a/libcxx/include/algorithm
+++ b/libcxx/include/algorithm
@@ -3029,9 +3029,17 @@ private:
 
 public:
     // constructors and reset functions
-    explicit uniform_int_distribution(result_type __a = 0,
-                                      result_type __b = numeric_limits<result_type>::max())
+#ifndef _LIBCPP_CXX03_LANG
+    uniform_int_distribution() : uniform_int_distribution(0) {}
+    explicit uniform_int_distribution(
+        result_type __a, result_type __b = numeric_limits<result_type>::max())
+        : __p_(param_type(__a, __b)) {}
+#else
+    explicit uniform_int_distribution(
+        result_type __a = 0,
+        result_type __b = numeric_limits<result_type>::max())
         : __p_(param_type(__a, __b)) {}
+#endif
     explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {}
     void reset() {}
 

diff  --git a/libcxx/include/locale b/libcxx/include/locale
index 411059befa1d..4e5dd6426bbc 100644
--- a/libcxx/include/locale
+++ b/libcxx/include/locale
@@ -92,7 +92,11 @@ public:
     typedef typename Codecvt::state_type                      state_type;
     typedef typename wide_string::traits_type::int_type       int_type;
 
-    explicit wstring_convert(Codecvt* pcvt = new Codecvt);          // explicit in C++14
+    wstring_convert(Codecvt* pcvt = new Codecvt);          // before C++14
+    explicit wstring_convert(Codecvt* pcvt = new Codecvt); // before C++20
+    wstring_convert() : wstring_convert(new Codecvt) {}    // C++20
+    explicit wstring_convert(Codecvt* pcvt);               // C++20
+
     wstring_convert(Codecvt* pcvt, state_type state);
     explicit wstring_convert(const byte_string& byte_err,           // explicit in C++14
                     const wide_string& wide_err = wide_string());
@@ -121,8 +125,14 @@ class wbuffer_convert
 public:
     typedef typename Tr::state_type state_type;
 
-    explicit wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt,
-                    state_type state = state_type());       // explicit in C++14
+    wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt,
+                    state_type state = state_type());          // before C++14
+    explicit wbuffer_convert(streambuf* bytebuf = nullptr, Codecvt* pcvt = new Codecvt,
+                            state_type state = state_type()); // before C++20
+    wbuffer_convert() : wbuffer_convert(nullptr) {} // C++20
+    explicit wbuffer_convert(streambuf* bytebuf, Codecvt* pcvt = new Codecvt,
+                            state_type state = state_type()); // C++20
+
     wbuffer_convert(const wbuffer_convert&) = delete;               // C++14
     wbuffer_convert & operator=(const wbuffer_convert &) = delete;  // C++14
     ~wbuffer_convert();                                             // C++14
@@ -3650,8 +3660,17 @@ private:
     wstring_convert(const wstring_convert& __wc);
     wstring_convert& operator=(const wstring_convert& __wc);
 public:
+#ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
-    _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(_Codecvt* __pcvt = new _Codecvt);
+    wstring_convert() : wstring_convert(new _Codecvt) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit wstring_convert(_Codecvt* __pcvt);
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_EXPLICIT_AFTER_CXX11
+    wstring_convert(_Codecvt* __pcvt = new _Codecvt);
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     wstring_convert(_Codecvt* __pcvt, state_type __state);
     _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err,
@@ -3918,9 +3937,20 @@ private:
 
     wbuffer_convert(const wbuffer_convert&);
     wbuffer_convert& operator=(const wbuffer_convert&);
+
 public:
-    _LIBCPP_EXPLICIT_AFTER_CXX11 wbuffer_convert(streambuf* __bytebuf = nullptr,
-            _Codecvt* __pcvt = new _Codecvt, state_type __state = state_type());
+#ifndef _LIBCPP_CXX03_LANG
+    wbuffer_convert() : wbuffer_convert(nullptr) {}
+    explicit wbuffer_convert(streambuf* __bytebuf,
+                             _Codecvt* __pcvt = new _Codecvt,
+                             state_type __state = state_type());
+#else
+    _LIBCPP_EXPLICIT_AFTER_CXX11
+    wbuffer_convert(streambuf* __bytebuf = nullptr,
+                    _Codecvt* __pcvt = new _Codecvt,
+                    state_type __state = state_type());
+#endif
+
     ~wbuffer_convert();
 
     _LIBCPP_INLINE_VISIBILITY

diff  --git a/libcxx/include/queue b/libcxx/include/queue
index 33c25e0dfc13..a2048c1e22cc 100644
--- a/libcxx/include/queue
+++ b/libcxx/include/queue
@@ -112,18 +112,11 @@ protected:
     Compare comp;
 
 public:
-    priority_queue() = default;
-    ~priority_queue() = default;
-
-    priority_queue(const priority_queue& q) = default;
-    priority_queue(priority_queue&& q) = default;
-
-    priority_queue& operator=(const priority_queue& q) = default;
-    priority_queue& operator=(priority_queue&& q) = default;
-
-    explicit priority_queue(const Compare& comp);
-    priority_queue(const Compare& comp, const container_type& c);
-    explicit priority_queue(const Compare& comp, container_type&& c);
+    priority_queue() : priority_queue(Compare()) {} // C++20
+    explicit priority_queue(const Compare& x) : priority_queue(x, Container()) {}
+    priority_queue(const Compare& x, const Container&);
+    explicit priority_queue(const Compare& x = Compare(), Container&&= Container()); // before C++20
+    priority_queue(const Compare& x, Container&&); // C++20
     template <class InputIterator>
         priority_queue(InputIterator first, InputIterator last,
                        const Compare& comp = Compare());
@@ -474,7 +467,7 @@ public:
     priority_queue(const value_compare& __comp, const container_type& __c);
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
-    explicit priority_queue(const value_compare& __comp, container_type&& __c);
+    priority_queue(const value_compare& __comp, container_type&& __c);
 #endif
     template <class _InputIter>
         _LIBCPP_INLINE_VISIBILITY

diff  --git a/libcxx/include/random b/libcxx/include/random
index 760a6eb2d46f..6e0d2ecb47c0 100644
--- a/libcxx/include/random
+++ b/libcxx/include/random
@@ -36,7 +36,9 @@ public:
     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<class Sseq> explicit linear_congruential_engine(Sseq& q);
     void seed(result_type s = default_seed);
     template<class Sseq> void seed(Sseq& q);
@@ -96,7 +98,9 @@ public:
     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<class Sseq> explicit mersenne_twister_engine(Sseq& q);
     void seed(result_type value = default_seed);
     template<class Sseq> void seed(Sseq& q);
@@ -154,7 +158,9 @@ public:
     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<class Sseq> explicit subtract_with_carry_engine(Sseq& q);
     void seed(result_type value = default_seed);
     template<class Sseq> void seed(Sseq& q);
@@ -385,7 +391,9 @@ public:
     static constexpr result_type max() { return numeric_limits<result_type>::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 @@ public:
 
     // constructors and reset functions
     explicit uniform_int_distribution(IntType a = 0,
-                                    IntType b = numeric_limits<IntType>::max());
+                                      IntType b = numeric_limits<IntType>::max()); // before C++20
+    uniform_int_distribution() : uniform_int_distribution(0) {}                    // C++20
+    explicit uniform_int_distribution(IntType a,
+                                      IntType b = numeric_limits<IntType>::max()); // C++20
     explicit uniform_int_distribution(const param_type& parm);
     void reset();
 
@@ -515,7 +526,9 @@ public:
     };
 
     // 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();
 
@@ -571,7 +584,9 @@ public:
     };
 
     // constructors and reset functions
-    explicit bernoulli_distribution(double p = 0.5);
+    explicit bernoulli_distribution(double p = 0.5);          // before C++20
+    bernoulli_distribution() : bernoulli_distribution(0.5) {} // C++20
+    explicit bernoulli_distribution(double p);                // C++20
     explicit bernoulli_distribution(const param_type& parm);
     void reset();
 
@@ -628,7 +643,9 @@ public:
     };
 
     // constructors and reset functions
-    explicit binomial_distribution(IntType t = 1, double p = 0.5);
+    explicit binomial_distribution(IntType t = 1, double p = 0.5); // before C++20
+    binomial_distribution() : binomial_distribution(1) {}          // C++20
+    explicit binomial_distribution(IntType t, double p = 0.5);     // C++20
     explicit binomial_distribution(const param_type& parm);
     void reset();
 
@@ -685,7 +702,9 @@ public:
     };
 
     // constructors and reset functions
-    explicit geometric_distribution(double p = 0.5);
+    explicit geometric_distribution(double p = 0.5);          // before C++20
+    geometric_distribution() : geometric_distribution(0.5) {} // C++20
+    explicit geometric_distribution(double p);                // C++20
     explicit geometric_distribution(const param_type& parm);
     void reset();
 
@@ -742,7 +761,9 @@ public:
     };
 
     // constructor and reset functions
-    explicit negative_binomial_distribution(result_type k = 1, double p = 0.5);
+    explicit negative_binomial_distribution(IntType k = 1, double p = 0.5); // before C++20
+    negative_binomial_distribution() : negative_binomial_distribution(1) {} // C++20
+    explicit negative_binomial_distribution(IntType k, double p = 0.5);     // C++20
     explicit negative_binomial_distribution(const param_type& parm);
     void reset();
 
@@ -799,7 +820,9 @@ public:
     };
 
     // constructors and reset functions
-    explicit poisson_distribution(double mean = 1.0);
+    explicit poisson_distribution(double mean = 1.0);     // before C++20
+    poisson_distribution() : poisson_distribution(1.0) {} // C++20
+    explicit poisson_distribution(double mean);           // C++20
     explicit poisson_distribution(const param_type& parm);
     void reset();
 
@@ -855,7 +878,9 @@ public:
     };
 
     // constructors and reset functions
-    explicit exponential_distribution(result_type lambda = 1.0);
+    explicit exponential_distribution(RealType lambda = 1.0);     // before C++20
+    exponential_distribution() : exponential_distribution(1.0) {} // C++20
+    explicit exponential_distribution(RealType lambda);           // C++20
     explicit exponential_distribution(const param_type& parm);
     void reset();
 
@@ -912,7 +937,9 @@ public:
     };
 
     // constructors and reset functions
-    explicit gamma_distribution(result_type alpha = 1, result_type beta = 1);
+    explicit gamma_distribution(RealType alpha = 0.0, RealType beta = 1.0); // before C++20
+    gamma_distribution() : gamma_distribution(0.0) {}                       // C++20
+    explicit gamma_distribution(RealType alpha, RealType beta = 1.0);       // C++20
     explicit gamma_distribution(const param_type& parm);
     void reset();
 
@@ -970,7 +997,9 @@ public:
     };
 
     // constructor and reset functions
-    explicit weibull_distribution(result_type a = 1, result_type b = 1);
+    explicit weibull_distribution(RealType a = 1.0, RealType b = 1.0); // before C++20
+    weibull_distribution() : weibull_distribution(1.0) {}              // C++20
+    explicit weibull_distribution(RealType a, RealType b = 1.0);       // C++20
     explicit weibull_distribution(const param_type& parm);
     void reset();
 
@@ -1028,7 +1057,9 @@ public:
     };
 
     // constructor and reset functions
-    explicit extreme_value_distribution(result_type a = 0, result_type b = 1);
+    explicit extreme_value_distribution(RealType a = 0.0, RealType b = 1.0); // before C++20
+    extreme_value_distribution() : extreme_value_distribution(0.0) {}        // C++20
+    explicit extreme_value_distribution(RealType a, RealType b = 1.0);       // C++20
     explicit extreme_value_distribution(const param_type& parm);
     void reset();
 
@@ -1086,7 +1117,9 @@ public:
     };
 
     // constructors and reset functions
-    explicit normal_distribution(result_type mean = 0, result_type stddev = 1);
+    explicit normal_distribution(RealType mean = 0.0, RealType stddev = 1.0); // before C++20
+    normal_distribution() : normal_distribution(0.0) {}                       // C++20
+    explicit normal_distribution(RealType mean, RealType stddev = 1.0);       // C++20
     explicit normal_distribution(const param_type& parm);
     void reset();
 
@@ -1144,7 +1177,9 @@ public:
     };
 
     // constructor and reset functions
-    explicit lognormal_distribution(result_type m = 0, result_type s = 1);
+    explicit lognormal_distribution(RealType mean = 0.0, RealType stddev = 1.0); // before C++20
+    lognormal_distribution() : lognormal_distribution(0.0) {}                    // C++20
+    explicit lognormal_distribution(RealType mean, RealType stddev = 1.0);       // C++20
     explicit lognormal_distribution(const param_type& parm);
     void reset();
 
@@ -1201,7 +1236,9 @@ public:
     };
 
     // constructor and reset functions
-    explicit chi_squared_distribution(result_type n = 1);
+    explicit chi_squared_distribution(RealType n = 1.0);          // before C++20
+    chi_squared_distribution() : chi_squared_distribution(1.0) {} // C++20
+    explicit chi_squared_distribution(RealType n);                // C++20
     explicit chi_squared_distribution(const param_type& parm);
     void reset();
 
@@ -1258,7 +1295,9 @@ public:
     };
 
     // constructor and reset functions
-    explicit cauchy_distribution(result_type a = 0, result_type b = 1);
+    explicit cauchy_distribution(RealType a = 0.0, RealType b = 1.0); // before C++20
+    cauchy_distribution() : cauchy_distribution(0.0) {}               // C++20
+    explicit cauchy_distribution(RealType a, RealType b = 1.0);       // C++20
     explicit cauchy_distribution(const param_type& parm);
     void reset();
 
@@ -1316,7 +1355,9 @@ public:
     };
 
     // constructor and reset functions
-    explicit fisher_f_distribution(result_type m = 1, result_type n = 1);
+    explicit fisher_f_distribution(RealType m = 1.0, RealType n = 1.0); // before C++20
+    fisher_f_distribution() : fisher_f_distribution(1.0) {}             // C++20
+    explicit fisher_f_distribution(RealType m, RealType n = 1.0);       // C++20
     explicit fisher_f_distribution(const param_type& parm);
     void reset();
 
@@ -1373,7 +1414,9 @@ public:
     };
 
     // constructor and reset functions
-    explicit student_t_distribution(result_type n = 1);
+    explicit student_t_distribution(RealType n = 1.0);        // before C++20
+    student_t_distribution() : student_t_distribution(1.0) {} // C++20
+    explicit student_t_distribution(RealType n);              // C++20
     explicit student_t_distribution(const param_type& parm);
     void reset();
 
@@ -1875,9 +1918,17 @@ public:
     static _LIBCPP_CONSTEXPR const result_type default_seed = 1u;
 
     // constructors and seeding functions
+#ifndef _LIBCPP_CXX03_LANG
+    _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<class _Sseq>
         _LIBCPP_INLINE_VISIBILITY
         explicit linear_congruential_engine(_Sseq& __q,
@@ -2124,9 +2175,17 @@ public:
     static _LIBCPP_CONSTEXPR const result_type default_seed = 5489u;
 
     // constructors and seeding functions
+#ifndef _LIBCPP_CXX03_LANG
     _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<class _Sseq>
         _LIBCPP_INLINE_VISIBILITY
         explicit mersenne_twister_engine(_Sseq& __q,
@@ -2582,9 +2641,17 @@ public:
     static _LIBCPP_CONSTEXPR const result_type default_seed = 19780503u;
 
     // constructors and seeding functions
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    subtract_with_carry_engine() : subtract_with_carry_engine(default_seed) {}
     _LIBCPP_INLINE_VISIBILITY
-    explicit subtract_with_carry_engine(result_type __sd = default_seed)
-        {seed(__sd);}
+    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<class _Sseq>
         _LIBCPP_INLINE_VISIBILITY
         explicit subtract_with_carry_engine(_Sseq& __q,
@@ -3524,7 +3591,12 @@ public:
     static _LIBCPP_CONSTEXPR result_type max() { return _Max;}
 
     // constructors
+#ifndef _LIBCPP_CXX03_LANG
+    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 +3830,16 @@ private:
 
 public:
     // constructors and reset functions
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    uniform_real_distribution() : uniform_real_distribution(0) {}
+    explicit uniform_real_distribution(result_type __a, result_type __b = 1)
+        : __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
@@ -3876,9 +3955,15 @@ private:
 
 public:
     // constructors and reset functions
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    bernoulli_distribution() : bernoulli_distribution(0.5) {}
     _LIBCPP_INLINE_VISIBILITY
-    explicit bernoulli_distribution(double __p = 0.5)
-        : __p_(param_type(__p)) {}
+    explicit bernoulli_distribution(double __p) : __p_(param_type(__p)) {}
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    explicit bernoulli_distribution(double __p = 0.5) : __p_(param_type(__p)) {}
+#endif
     _LIBCPP_INLINE_VISIBILITY
     explicit bernoulli_distribution(const param_type& __p) : __p_(__p) {}
     _LIBCPP_INLINE_VISIBILITY
@@ -3994,9 +4079,17 @@ private:
 
 public:
     // constructors and reset functions
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    binomial_distribution() : binomial_distribution(1) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit binomial_distribution(result_type __t, double __p = 0.5)
+        : __p_(param_type(__t, __p)) {}
+#else
     _LIBCPP_INLINE_VISIBILITY
     explicit binomial_distribution(result_type __t = 1, double __p = 0.5)
         : __p_(param_type(__t, __p)) {}
+#endif
     _LIBCPP_INLINE_VISIBILITY
     explicit binomial_distribution(const param_type& __p) : __p_(__p) {}
     _LIBCPP_INLINE_VISIBILITY
@@ -4176,9 +4269,17 @@ private:
 
 public:
     // constructors and reset functions
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    exponential_distribution() : exponential_distribution(1) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit exponential_distribution(result_type __lambda)
+        : __p_(param_type(__lambda)) {}
+#else
     _LIBCPP_INLINE_VISIBILITY
     explicit exponential_distribution(result_type __lambda = 1)
         : __p_(param_type(__lambda)) {}
+#endif
     _LIBCPP_INLINE_VISIBILITY
     explicit exponential_distribution(const param_type& __p) : __p_(__p) {}
     _LIBCPP_INLINE_VISIBILITY
@@ -4299,9 +4400,18 @@ private:
 
 public:
     // constructors and reset functions
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    normal_distribution() : normal_distribution(0) {}
     _LIBCPP_INLINE_VISIBILITY
-    explicit normal_distribution(result_type __mean = 0, result_type __stddev = 1)
+    explicit normal_distribution(result_type __mean, result_type __stddev = 1)
         : __p_(param_type(__mean, __stddev)), _V_hot_(false) {}
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    explicit normal_distribution(result_type __mean = 0,
+                                 result_type __stddev = 1)
+        : __p_(param_type(__mean, __stddev)), _V_hot_(false) {}
+#endif
     _LIBCPP_INLINE_VISIBILITY
     explicit normal_distribution(const param_type& __p)
         : __p_(__p), _V_hot_(false) {}
@@ -4479,9 +4589,18 @@ private:
 
 public:
     // constructor and reset functions
+#ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
-    explicit lognormal_distribution(result_type __m = 0, result_type __s = 1)
+    lognormal_distribution() : lognormal_distribution(0) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit lognormal_distribution(result_type __m, result_type __s = 1)
         : __p_(param_type(__m, __s)) {}
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    explicit lognormal_distribution(result_type __m = 0,
+                                    result_type __s = 1)
+        : __p_(param_type(__m, __s)) {}
+#endif
     _LIBCPP_INLINE_VISIBILITY
     explicit lognormal_distribution(const param_type& __p)
         : __p_(__p) {}
@@ -4599,8 +4718,17 @@ private:
 
 public:
     // constructors and reset functions
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    poisson_distribution() : poisson_distribution(1.0) {}
     _LIBCPP_INLINE_VISIBILITY
-    explicit poisson_distribution(double __mean = 1.0) : __p_(__mean) {}
+    explicit poisson_distribution(double __mean)
+        : __p_(__mean) {}
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    explicit poisson_distribution(double __mean = 1.0)
+        : __p_(__mean) {}
+#endif
     _LIBCPP_INLINE_VISIBILITY
     explicit poisson_distribution(const param_type& __p) : __p_(__p) {}
     _LIBCPP_INLINE_VISIBILITY
@@ -4828,9 +4956,17 @@ private:
 
 public:
     // constructor and reset functions
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    weibull_distribution() : weibull_distribution(1) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit weibull_distribution(result_type __a, result_type __b = 1)
+        : __p_(param_type(__a, __b)) {}
+#else
     _LIBCPP_INLINE_VISIBILITY
     explicit weibull_distribution(result_type __a = 1, result_type __b = 1)
         : __p_(param_type(__a, __b)) {}
+#endif
     _LIBCPP_INLINE_VISIBILITY
     explicit weibull_distribution(const param_type& __p)
         : __p_(__p) {}
@@ -4944,9 +5080,18 @@ private:
 
 public:
     // constructor and reset functions
+#ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
-    explicit extreme_value_distribution(result_type __a = 0, result_type __b = 1)
+    extreme_value_distribution() : extreme_value_distribution(0) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit extreme_value_distribution(result_type __a, result_type __b = 1)
         : __p_(param_type(__a, __b)) {}
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    explicit extreme_value_distribution(result_type __a = 0,
+                                        result_type __b = 1)
+        : __p_(param_type(__a, __b)) {}
+#endif
     _LIBCPP_INLINE_VISIBILITY
     explicit extreme_value_distribution(const param_type& __p)
         : __p_(__p) {}
@@ -5067,9 +5212,18 @@ private:
 
 public:
     // constructors and reset functions
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    gamma_distribution() : gamma_distribution(1) {}
     _LIBCPP_INLINE_VISIBILITY
-    explicit gamma_distribution(result_type __alpha = 1, result_type __beta = 1)
+    explicit gamma_distribution(result_type __alpha, result_type __beta = 1)
         : __p_(param_type(__alpha, __beta)) {}
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    explicit gamma_distribution(result_type __alpha = 1,
+                                result_type __beta = 1)
+        : __p_(param_type(__alpha, __beta)) {}
+#endif
     _LIBCPP_INLINE_VISIBILITY
     explicit gamma_distribution(const param_type& __p)
         : __p_(__p) {}
@@ -5241,9 +5395,18 @@ private:
 
 public:
     // constructor and reset functions
+#ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
-    explicit negative_binomial_distribution(result_type __k = 1, double __p = 0.5)
+    negative_binomial_distribution() : negative_binomial_distribution(1) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit negative_binomial_distribution(result_type __k, double __p = 0.5)
         : __p_(__k, __p) {}
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    explicit negative_binomial_distribution(result_type __k = 1,
+                                            double __p = 0.5)
+        : __p_(__k, __p) {}
+#endif
     _LIBCPP_INLINE_VISIBILITY
     explicit negative_binomial_distribution(const param_type& __p) : __p_(__p) {}
     _LIBCPP_INLINE_VISIBILITY
@@ -5374,8 +5537,17 @@ private:
 
 public:
     // constructors and reset functions
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    geometric_distribution() : geometric_distribution(0.5) {}
     _LIBCPP_INLINE_VISIBILITY
-    explicit geometric_distribution(double __p = 0.5) : __p_(__p) {}
+    explicit geometric_distribution(double __p)
+        : __p_(__p) {}
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    explicit geometric_distribution(double __p = 0.5)
+        : __p_(__p) {}
+#endif
     _LIBCPP_INLINE_VISIBILITY
     explicit geometric_distribution(const param_type& __p) : __p_(__p) {}
     _LIBCPP_INLINE_VISIBILITY
@@ -5478,9 +5650,17 @@ private:
 
 public:
     // constructor and reset functions
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    chi_squared_distribution() : chi_squared_distribution(1) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit chi_squared_distribution(result_type __n)
+        : __p_(param_type(__n)) {}
+#else
     _LIBCPP_INLINE_VISIBILITY
     explicit chi_squared_distribution(result_type __n = 1)
         : __p_(param_type(__n)) {}
+#endif
     _LIBCPP_INLINE_VISIBILITY
     explicit chi_squared_distribution(const param_type& __p)
         : __p_(__p) {}
@@ -5590,9 +5770,17 @@ private:
 
 public:
     // constructor and reset functions
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    cauchy_distribution() : cauchy_distribution(0) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit cauchy_distribution(result_type __a, result_type __b = 1)
+        : __p_(param_type(__a, __b)) {}
+#else
     _LIBCPP_INLINE_VISIBILITY
     explicit cauchy_distribution(result_type __a = 0, result_type __b = 1)
         : __p_(param_type(__a, __b)) {}
+#endif
     _LIBCPP_INLINE_VISIBILITY
     explicit cauchy_distribution(const param_type& __p)
         : __p_(__p) {}
@@ -5715,9 +5903,17 @@ private:
 
 public:
     // constructor and reset functions
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    fisher_f_distribution() : fisher_f_distribution(1) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit fisher_f_distribution(result_type __m, result_type __n = 1)
+        : __p_(param_type(__m, __n)) {}
+#else
     _LIBCPP_INLINE_VISIBILITY
     explicit fisher_f_distribution(result_type __m = 1, result_type __n = 1)
         : __p_(param_type(__m, __n)) {}
+#endif
     _LIBCPP_INLINE_VISIBILITY
     explicit fisher_f_distribution(const param_type& __p)
         : __p_(__p) {}
@@ -5836,9 +6032,17 @@ private:
 
 public:
     // constructor and reset functions
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    student_t_distribution() : student_t_distribution(1) {}
+    _LIBCPP_INLINE_VISIBILITY
+    explicit student_t_distribution(result_type __n)
+        : __p_(param_type(__n)) {}
+#else
     _LIBCPP_INLINE_VISIBILITY
     explicit student_t_distribution(result_type __n = 1)
         : __p_(param_type(__n)) {}
+#endif
     _LIBCPP_INLINE_VISIBILITY
     explicit student_t_distribution(const param_type& __p)
         : __p_(__p) {}

diff  --git a/libcxx/include/regex b/libcxx/include/regex
index 8578039bf6a2..d78e4888a619 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -455,7 +455,9 @@ public:
     typedef basic_string<char_type>                           string_type;
 
     // construct/copy/destroy:
-    explicit match_results(const Allocator& a = Allocator());
+    explicit match_results(const Allocator& a = Allocator()); // before C++20
+    match_results() : match_results(Allocator()) {}           // C++20
+    explicit match_results(const Allocator& a);               // C++20
     match_results(const match_results& m);
     match_results(match_results&& m) noexcept;
     match_results& operator=(const match_results& m);
@@ -5357,7 +5359,13 @@ public:
     typedef basic_string<char_type>                           string_type;
 
     // construct/copy/destroy:
+#ifndef _LIBCPP_CXX03_LANG
+    match_results() : match_results(allocator_type()) {}
+    explicit match_results(const allocator_type& __a);
+#else
     explicit match_results(const allocator_type& __a = allocator_type());
+#endif
+
 //    match_results(const match_results&) = default;
 //    match_results& operator=(const match_results&) = default;
 //    match_results(match_results&& __m) = default;

diff  --git a/libcxx/include/sstream b/libcxx/include/sstream
index 22cc0c350384..7ce85be6ac32 100644
--- a/libcxx/include/sstream
+++ b/libcxx/include/sstream
@@ -25,8 +25,10 @@ public:
     typedef typename traits_type::off_type off_type;
     typedef Allocator                      allocator_type;
 
-    // 27.8.1.1 Constructors:
-    explicit basic_stringbuf(ios_base::openmode which = ios_base::in | ios_base::out);
+    // 27.8.1.1 [stringbuf.cons], constructors:
+    explicit basic_stringbuf(ios_base::openmode which = ios_base::in | ios_base::out); // before C++20
+    basic_stringbuf() : basic_stringbuf(ios_base::in | ios_base::out) {}               // C++20
+    explicit basic_stringbuf(ios_base::openmode which);                                // C++20
     explicit basic_stringbuf(const basic_string<char_type, traits_type, allocator_type>& str,
                              ios_base::openmode which = ios_base::in | ios_base::out);
     basic_stringbuf(basic_stringbuf&& rhs);
@@ -71,7 +73,10 @@ public:
     typedef Allocator                      allocator_type;
 
     // 27.8.2.1 Constructors:
-    explicit basic_istringstream(ios_base::openmode which = ios_base::in);
+    explicit basic_istringstream(ios_base::openmode which = ios_base::in); // before C++20
+    basic_istringstream() : basic_istringstream(ios_base::in) {}           // C++20
+    explicit basic_istringstream(ios_base::openmode which);                // C++20
+
     explicit basic_istringstream(const basic_string<char_type, traits_type,allocator_type>& str,
                                  ios_base::openmode which = ios_base::in);
     basic_istringstream(basic_istringstream&& rhs);
@@ -107,7 +112,10 @@ public:
     typedef Allocator                      allocator_type;
 
     // 27.8.3.1 Constructors/destructor:
-    explicit basic_ostringstream(ios_base::openmode which = ios_base::out);
+    explicit basic_ostringstream(ios_base::openmode which = ios_base::out); // before C++20
+    basic_ostringstream() : basic_ostringstream(ios_base::out) {}           // C++20
+    explicit basic_ostringstream(ios_base::openmode which);                 // C++20
+
     explicit basic_ostringstream(const basic_string<char_type, traits_type, allocator_type>& str,
                                  ios_base::openmode which = ios_base::out);
     basic_ostringstream(basic_ostringstream&& rhs);
@@ -143,7 +151,10 @@ public:
     typedef Allocator                      allocator_type;
 
     // constructors/destructor
-    explicit basic_stringstream(ios_base::openmode which = ios_base::out|ios_base::in);
+    explicit basic_stringstream(ios_base::openmode which = ios_base::out | ios_base::in); // before C++20
+    basic_stringstream() : basic_stringstream(ios_base::out | ios_base::in) {}            // C++20
+    explicit basic_stringstream(ios_base::openmode which);                                // C++20
+
     explicit basic_stringstream(const basic_string<char_type, traits_type, allocator_type>& str,
                                 ios_base::openmode which = ios_base::out|ios_base::in);
     basic_stringstream(basic_stringstream&& rhs);
@@ -207,11 +218,20 @@ private:
     ios_base::openmode __mode_;
 
 public:
-    // 27.8.1.1 Constructors:
+    // 30.8.2.1 [stringbuf.cons], constructors
+#ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
-    explicit basic_stringbuf(ios_base::openmode __wch = ios_base::in | ios_base::out)
-        : __hm_(nullptr), __mode_(__wch)
-    { }
+    basic_stringbuf() : basic_stringbuf(ios_base::in | ios_base::out) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit basic_stringbuf(ios_base::openmode __wch)
+        : __hm_(nullptr), __mode_(__wch) {}
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    explicit basic_stringbuf(ios_base::openmode __wch = ios_base::in |
+                                                        ios_base::out)
+        : __hm_(nullptr), __mode_(__wch) {}
+#endif
 
     _LIBCPP_INLINE_VISIBILITY
     explicit basic_stringbuf(const string_type& __s,
@@ -622,12 +642,20 @@ private:
     basic_stringbuf<char_type, traits_type, allocator_type> __sb_;
 
 public:
-    // 27.8.2.1 Constructors:
+    // 30.8.3.1 [istringstream.cons], constructors
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    basic_istringstream() : basic_istringstream(ios_base::in) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit basic_istringstream(ios_base::openmode __wch)
+        : basic_istream<_CharT, _Traits>(&__sb_), __sb_(__wch | ios_base::in) {}
+#else
     _LIBCPP_INLINE_VISIBILITY
     explicit basic_istringstream(ios_base::openmode __wch = ios_base::in)
-        : basic_istream<_CharT, _Traits>(&__sb_)
-        , __sb_(__wch | ios_base::in)
-    { }
+        : basic_istream<_CharT, _Traits>(&__sb_), __sb_(__wch | ios_base::in) {}
+#endif
+
     _LIBCPP_INLINE_VISIBILITY
     explicit basic_istringstream(const string_type& __s,
                                  ios_base::openmode __wch = ios_base::in)
@@ -699,12 +727,21 @@ private:
     basic_stringbuf<char_type, traits_type, allocator_type> __sb_;
 
 public:
-    // 27.8.2.1 Constructors:
+    // 30.8.4.1 [ostringstream.cons], constructors
+#ifndef _LIBCPP_CXX03_LANG
+    _LIBCPP_INLINE_VISIBILITY
+    basic_ostringstream() : basic_ostringstream(ios_base::out) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit basic_ostringstream(ios_base::openmode __wch)
+        : basic_ostream<_CharT, _Traits>(&__sb_),
+          __sb_(__wch | ios_base::out) {}
+#else
     _LIBCPP_INLINE_VISIBILITY
     explicit basic_ostringstream(ios_base::openmode __wch = ios_base::out)
-        : basic_ostream<_CharT, _Traits>(&__sb_)
-        , __sb_(__wch | ios_base::out)
-    { }
+        : basic_ostream<_CharT, _Traits>(&__sb_),
+          __sb_(__wch | ios_base::out) {}
+#endif
 
     _LIBCPP_INLINE_VISIBILITY
     explicit basic_ostringstream(const string_type& __s,
@@ -778,12 +815,20 @@ private:
     basic_stringbuf<char_type, traits_type, allocator_type> __sb_;
 
 public:
-    // 27.8.2.1 Constructors:
+    // 30.8.5.1 [stringstream.cons], constructors
+#ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
-    explicit basic_stringstream(ios_base::openmode __wch = ios_base::in | ios_base::out)
-        : basic_iostream<_CharT, _Traits>(&__sb_)
-        , __sb_(__wch)
-    { }
+    basic_stringstream() : basic_stringstream(ios_base::in | ios_base::out) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    explicit basic_stringstream(ios_base::openmode __wch)
+        : basic_iostream<_CharT, _Traits>(&__sb_), __sb_(__wch) {}
+#else
+    _LIBCPP_INLINE_VISIBILITY
+    explicit basic_stringstream(ios_base::openmode __wch = ios_base::in |
+                                                           ios_base::out)
+        : basic_iostream<_CharT, _Traits>(&__sb_), __sb_(__wch) {}
+#endif
 
     _LIBCPP_INLINE_VISIBILITY
     explicit basic_stringstream(const string_type& __s,

diff  --git a/libcxx/include/strstream b/libcxx/include/strstream
index 2d18d9cdd208..0062777cd437 100644
--- a/libcxx/include/strstream
+++ b/libcxx/include/strstream
@@ -17,7 +17,10 @@ class strstreambuf
     : public basic_streambuf<char>
 {
 public:
-    explicit strstreambuf(streamsize alsize_arg = 0);
+    explicit strstreambuf(streamsize alsize_arg = 0); // before C++20
+    strstreambuf() : strstreambuf(0) {}               // C++20
+    explicit strstreambuf(streamsize alsize_arg);     // C++20
+
     strstreambuf(void* (*palloc_arg)(size_t), void (*pfree_arg)(void*));
     strstreambuf(char* gnext_arg, streamsize n, char* pbeg_arg = nullptr);
     strstreambuf(const char* gnext_arg, streamsize n);
@@ -140,7 +143,12 @@ class _LIBCPP_TYPE_VIS strstreambuf
     : public streambuf
 {
 public:
+#ifndef _LIBCPP_CXX03_LANG
+    strstreambuf() : strstreambuf(0) {}
+    explicit strstreambuf(streamsize __alsize);
+#else
     explicit strstreambuf(streamsize __alsize = 0);
+#endif
     strstreambuf(void* (*__palloc)(size_t), void (*__pfree)(void*));
     strstreambuf(char* __gnext, streamsize __n, char* __pbeg = nullptr);
     strstreambuf(const char* __gnext, streamsize __n);

diff  --git a/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp.pass.cpp b/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp.pass.cpp
index b51d96f31e8e..5c2fc5d89e9e 100644
--- a/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp.pass.cpp
@@ -15,15 +15,25 @@
 
 #include "test_macros.h"
 #include "test_allocator.h"
+#if TEST_STD_VER >= 11
+#include "test_convertible.h"
+#endif
 
 int main(int, char**)
 {
-    std::priority_queue<int, std::vector<int, limited_allocator<int, 10> > > q((std::less<int>()));
+    typedef std::vector<int, limited_allocator<int, 10> > Container;
+    typedef std::less<int> Compare;
+    typedef std::priority_queue<int, Container> Q;
+    Q q((Compare()));
     assert(q.size() == 0);
     q.push(1);
     q.push(2);
     assert(q.size() == 2);
     assert(q.top() == 2);
 
-  return 0;
+#if TEST_STD_VER >= 11
+    static_assert(!test_convertible<Q, const Compare&>(), "");
+#endif
+
+    return 0;
 }

diff  --git a/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp_container.pass.cpp b/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp_container.pass.cpp
index de395de1cdf3..07c50e38968a 100644
--- a/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp_container.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp_container.pass.cpp
@@ -8,13 +8,16 @@
 
 // <queue>
 
-// explicit priority_queue(const Compare& comp, const container_type& c);
+// priority_queue(const Compare& comp, const Container& c);
 
 #include <queue>
 #include <cassert>
 #include <functional>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "test_convertible.h"
+#endif
 
 template <class C>
 C
@@ -28,10 +31,18 @@ make(int n)
 
 int main(int, char**)
 {
-    std::vector<int> v = make<std::vector<int> >(5);
-    std::priority_queue<int, std::vector<int>, std::greater<int> > q(std::greater<int>(), v);
+    typedef std::vector<int> Container;
+    typedef std::greater<int> Compare;
+    typedef std::priority_queue<int, Container, Compare> Q;
+    Container v = make<Container>(5);
+    Q q(Compare(), v);
     assert(q.size() == 5);
     assert(q.top() == 0);
 
-  return 0;
+#if TEST_STD_VER >= 11
+    // It should be explicit, so not convertible before C++20.
+    static_assert(test_convertible<Q, const Compare&, const Container&>(), "");
+#endif
+
+    return 0;
 }

diff  --git a/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp_rcontainer.pass.cpp b/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp_rcontainer.pass.cpp
index c49deacccc54..d555ecab549c 100644
--- a/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp_rcontainer.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_comp_rcontainer.pass.cpp
@@ -10,14 +10,15 @@
 
 // <queue>
 
-// explicit priority_queue(const Compare& comp, container_type&& c);
+// explicit priority_queue(const Compare& comp, Container&& c); // before C++20
+// priority_queue(const Compare& comp, Container&& c);          // C++20
 
 #include <queue>
 #include <cassert>
 
 #include "test_macros.h"
 #include "MoveOnly.h"
-
+#include "test_convertible.h"
 
 template <class C>
 C
@@ -29,12 +30,16 @@ make(int n)
     return c;
 }
 
-
 int main(int, char**)
 {
-    std::priority_queue<MoveOnly> q(std::less<MoveOnly>(), make<std::vector<MoveOnly> >(5));
+    typedef std::vector<MoveOnly> Container;
+    typedef std::less<MoveOnly> Compare;
+    typedef std::priority_queue<MoveOnly> Q;
+    Q q(Compare(), make<Container>(5));
     assert(q.size() == 5);
     assert(q.top() == MoveOnly(4));
 
-  return 0;
+    static_assert(test_convertible<Q, const Compare&, Container&&>(), "");
+
+    return 0;
 }

diff  --git a/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_default.pass.cpp b/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_default.pass.cpp
index c50a0fbe51d6..e483763ab7b6 100644
--- a/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_default.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/ctor_default.pass.cpp
@@ -8,22 +8,34 @@
 
 // <queue>
 
-// priority_queue();
+// explicit priority_queue(const Compare& x = Compare(), Container&& = Container()); // before C++20
+// priority_queue() : priority_queue(Compare()) {}                                   // C++20
+// explicit priority_queue(const Compare& x) : priority_queue(x, Container()) {}     // C++20
 
 #include <queue>
 #include <cassert>
 
 #include "test_macros.h"
 #include "test_allocator.h"
+#if TEST_STD_VER >= 11
+#include "test_convertible.h"
+#endif
 
 int main(int, char**)
 {
-    std::priority_queue<int, std::vector<int, limited_allocator<int, 10> > > q;
+    typedef std::vector<int, limited_allocator<int, 10> > Container;
+    typedef std::priority_queue<int, Container> Q;
+    Q q;
     assert(q.size() == 0);
     q.push(1);
     q.push(2);
     assert(q.size() == 2);
     assert(q.top() == 2);
 
-  return 0;
+#if TEST_STD_VER >= 11
+    // It should be explicit, so not convertible before C++20.
+    static_assert(test_convertible<Q>(), "");
+#endif
+
+    return 0;
 }

diff  --git a/libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_container.pass.cpp b/libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_container.pass.cpp
index 8162176d14d0..588ed696c8f0 100644
--- a/libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_container.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_container.pass.cpp
@@ -15,6 +15,9 @@
 #include <cstddef>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "test_convertible.h"
+#endif
 
 template <class C>
 C
@@ -28,8 +31,10 @@ make(int n)
 
 int main(int, char**)
 {
-    std::deque<int> d = make<std::deque<int> >(5);
-    std::queue<int> q(d);
+    typedef std::deque<int> Container;
+    typedef std::queue<int> Q;
+    Container d = make<Container>(5);
+    Q q(d);
     assert(q.size() == 5);
     for (std::size_t i = 0; i < d.size(); ++i)
     {
@@ -37,5 +42,9 @@ int main(int, char**)
         q.pop();
     }
 
-  return 0;
+#if TEST_STD_VER >= 11
+    static_assert(!test_convertible<Q, const Container&>(), "");
+#endif
+
+    return 0;
 }

diff  --git a/libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_default.pass.cpp b/libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_default.pass.cpp
index 74f78ca78a43..17cb4a7936d2 100644
--- a/libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_default.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_default.pass.cpp
@@ -8,17 +8,24 @@
 
 // <queue>
 
-// queue();
+// explicit queue(Container&& = Container()); // before C++20
+// queue() : queue(Container()) {}            // C++20
+// explicit queue(Container&&);               // before C++20
 
 #include <queue>
 #include <cassert>
 
 #include "test_macros.h"
 #include "test_allocator.h"
+#if TEST_STD_VER >= 11
+#include "test_convertible.h"
+#endif
 
 int main(int, char**)
 {
-    std::queue<int, std::vector<int, limited_allocator<int, 10> > > q;
+    typedef std::vector<int, limited_allocator<int, 10> > Container;
+    typedef std::queue<int, Container> Q;
+    Q q;
     assert(q.size() == 0);
     q.push(1);
     q.push(2);
@@ -26,5 +33,10 @@ int main(int, char**)
     assert(q.front() == 1);
     assert(q.back() == 2);
 
-  return 0;
+#if TEST_STD_VER >= 11
+    // It should be explicit, so not convertible before C++20.
+    static_assert(test_convertible<Q>(), "");
+#endif
+
+    return 0;
 }

diff  --git a/libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_rcontainer.pass.cpp b/libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_rcontainer.pass.cpp
index 7169eba0d908..22470e5c68c0 100644
--- a/libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_rcontainer.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/queue/queue.cons/ctor_rcontainer.pass.cpp
@@ -10,14 +10,18 @@
 
 // <queue>
 
-// explicit queue(container_type&& c);
+// explicit queue(Container&& c = Container()); // before C++20
+// queue() : queue(Container()) {}              // C++20
+// explicit queue(Container&& c);               // C++20
 
 #include <queue>
 #include <cassert>
 
 #include "test_macros.h"
 #include "MoveOnly.h"
-
+#if TEST_STD_VER >= 11
+#include "test_convertible.h"
+#endif
 
 template <class C>
 C
@@ -29,11 +33,16 @@ make(int n)
     return c;
 }
 
-
 int main(int, char**)
 {
-    std::queue<MoveOnly> q(make<std::deque<MoveOnly> >(5));
+    typedef std::deque<MoveOnly> Container;
+    typedef std::queue<MoveOnly> Q;
+    Q q(make<std::deque<MoveOnly> >(5));
     assert(q.size() == 5);
 
-  return 0;
+#if TEST_STD_VER >= 11
+    static_assert(!test_convertible<Q, Container&&>(), "");
+#endif
+
+    return 0;
 }

diff  --git a/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_container.pass.cpp b/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_container.pass.cpp
index 50a7b338267a..b77660d4c875 100644
--- a/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_container.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_container.pass.cpp
@@ -8,13 +8,16 @@
 
 // <stack>
 
-// explicit stack(const container_type& c);
+// explicit stack(const Container&);
 
 #include <stack>
 #include <cassert>
 #include <cstddef>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "test_convertible.h"
+#endif
 
 template <class C>
 C
@@ -28,8 +31,10 @@ make(int n)
 
 int main(int, char**)
 {
-    std::deque<int> d = make<std::deque<int> >(5);
-    std::stack<int> q(d);
+    typedef std::deque<int> Container;
+    typedef std::stack<int> Q;
+    Container d = make<Container>(5);
+    Q q(d);
     assert(q.size() == 5);
     for (std::size_t i = 0; i < d.size(); ++i)
     {
@@ -37,5 +42,9 @@ int main(int, char**)
         q.pop();
     }
 
-  return 0;
+#if TEST_STD_VER >= 11
+    static_assert(!test_convertible<Q, const Container&>(), "");
+#endif
+
+    return 0;
 }

diff  --git a/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_default.pass.cpp b/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_default.pass.cpp
index acfacd4e36a5..4d5aa88e4578 100644
--- a/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_default.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_default.pass.cpp
@@ -8,7 +8,9 @@
 
 // <stack>
 
-// stack();
+// explicit stack(Container&& = Container()); // before C++20
+// stack() : stack(Container()) {}            // C++20
+// explicit stack(Container&&);               // before C++20
 
 #include <stack>
 #include <vector>
@@ -16,15 +18,25 @@
 
 #include "test_macros.h"
 #include "test_allocator.h"
+#if TEST_STD_VER >= 11
+#include "test_convertible.h"
+#endif
 
 int main(int, char**)
 {
-    std::stack<int, std::vector<int, limited_allocator<int, 10> > > q;
+    typedef std::vector<int, limited_allocator<int, 10> > Container;
+    typedef std::stack<int, Container> Q;
+    Q q;
     assert(q.size() == 0);
     q.push(1);
     q.push(2);
     assert(q.size() == 2);
     assert(q.top() == 2);
 
-  return 0;
+#if TEST_STD_VER >= 11
+    // It should be explicit, so not convertible before C++20.
+    static_assert(test_convertible<Q>(), "");
+#endif
+
+    return 0;
 }

diff  --git a/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_rcontainer.pass.cpp b/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_rcontainer.pass.cpp
index 8d1518ac7729..56dc40e4ed86 100644
--- a/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_rcontainer.pass.cpp
+++ b/libcxx/test/std/containers/container.adaptors/stack/stack.cons/ctor_rcontainer.pass.cpp
@@ -10,14 +10,18 @@
 
 // <stack>
 
-// explicit stack(container_type&& c);
+// explicit stack(Container&&= Container());  // before C++20
+// stack() : stack(Container()) {}            // C++20
+// explicit stack(Container&&);               // C++20
 
 #include <stack>
 #include <cassert>
 
 #include "test_macros.h"
 #include "MoveOnly.h"
-
+#if TEST_STD_VER >= 11
+#include "test_convertible.h"
+#endif
 
 template <class C>
 C
@@ -29,11 +33,16 @@ make(int n)
     return c;
 }
 
-
 int main(int, char**)
 {
-    std::stack<MoveOnly> q(make<std::deque<MoveOnly> >(5));
+    typedef std::deque<MoveOnly> Container;
+    typedef std::stack<MoveOnly> Q;
+    Q q(make<Container>(5));
     assert(q.size() == 5);
 
+#if TEST_STD_VER >= 11
+    static_assert(!test_convertible<Q, Container&&>(), "");
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.cons/default.pass.cpp b/libcxx/test/std/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.cons/default.pass.cpp
index 6ec30127ae59..844f31e4a454 100644
--- a/libcxx/test/std/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.cons/default.pass.cpp
+++ b/libcxx/test/std/depr/depr.str.strstreams/depr.strstreambuf/depr.strstreambuf.cons/default.pass.cpp
@@ -10,12 +10,17 @@
 
 // class strstreambuf
 
-// explicit strstreambuf(streamsize alsize_arg = 0);
+// explicit strstreambuf(streamsize alsize_arg = 0); // before C++20
+// strstreambuf() : strstreambuf(0) {}               // C++20
+// explicit strstreambuf(streamsize alsize_arg);     // C++20
 
 #include <strstream>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "test_convertible.h"
+#endif
 
 int main(int, char**)
 {
@@ -30,5 +35,13 @@ int main(int, char**)
         assert(s.pcount() == 0);
     }
 
-  return 0;
+#if TEST_STD_VER >= 11
+    {
+      typedef std::strstreambuf B;
+      static_assert(test_convertible<B>(), "");
+      static_assert(!test_convertible<B, std::streamsize>(), "");
+    }
+#endif
+
+    return 0;
 }

diff  --git a/libcxx/test/std/input.output/string.streams/istringstream/istringstream.cons/default.pass.cpp b/libcxx/test/std/input.output/string.streams/istringstream/istringstream.cons/default.pass.cpp
index 93b7cdd4376f..22a823e5c400 100644
--- a/libcxx/test/std/input.output/string.streams/istringstream/istringstream.cons/default.pass.cpp
+++ b/libcxx/test/std/input.output/string.streams/istringstream/istringstream.cons/default.pass.cpp
@@ -11,12 +11,23 @@
 // template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
 // class basic_istringstream
 
-// explicit basic_istringstream(ios_base::openmode which = ios_base::in);
+// explicit basic_istringstream(ios_base::openmode which = ios_base::in); // before C++20
+// basic_istringstream() : basic_istringstream(ios_base::in) {}           // C++20
+// explicit basic_istringstream(ios_base::openmode which);                // C++20
 
 #include <sstream>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "test_convertible.h"
+
+template <typename S>
+void test() {
+  static_assert(test_convertible<S>(), "");
+  static_assert(!test_convertible<S, std::ios_base::openmode>(), "");
+}
+#endif
 
 int main(int, char**)
 {
@@ -45,5 +56,10 @@ int main(int, char**)
         assert(ss.str() == L"");
     }
 
-  return 0;
+#if TEST_STD_VER >= 11
+    test<std::istringstream>();
+    test<std::wistringstream>();
+#endif
+
+    return 0;
 }

diff  --git a/libcxx/test/std/input.output/string.streams/ostringstream/ostringstream.cons/default.pass.cpp b/libcxx/test/std/input.output/string.streams/ostringstream/ostringstream.cons/default.pass.cpp
index b541fd35f7c2..5ce63367d1c0 100644
--- a/libcxx/test/std/input.output/string.streams/ostringstream/ostringstream.cons/default.pass.cpp
+++ b/libcxx/test/std/input.output/string.streams/ostringstream/ostringstream.cons/default.pass.cpp
@@ -11,12 +11,23 @@
 // template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
 // class basic_ostringstream
 
-// explicit basic_ostringstream(ios_base::openmode which = ios_base::in);
+// explicit basic_ostringstream(ios_base::openmode which = ios_base::out); // before C++20
+// basic_ostringstream() : basic_ostringstream(ios_base::out) {}           // C++20
+// explicit basic_ostringstream(ios_base::openmode which);                 // C++20
 
 #include <sstream>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "test_convertible.h"
+
+template <typename S>
+void test() {
+  static_assert(test_convertible<S>(), "");
+  static_assert(!test_convertible<S, std::ios_base::openmode>(), "");
+}
+#endif
 
 int main(int, char**)
 {
@@ -45,5 +56,10 @@ int main(int, char**)
         assert(ss.str() == L"");
     }
 
-  return 0;
+#if TEST_STD_VER >= 11
+    test<std::ostringstream>();
+    test<std::wostringstream>();
+#endif
+
+    return 0;
 }

diff  --git a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/default.pass.cpp b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/default.pass.cpp
index f15e75bb2114..8e87a8811449 100644
--- a/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/default.pass.cpp
+++ b/libcxx/test/std/input.output/string.streams/stringbuf/stringbuf.cons/default.pass.cpp
@@ -11,12 +11,17 @@
 // template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
 // class basic_stringbuf
 
-// explicit basic_stringbuf(ios_base::openmode which = ios_base::in | ios_base::out);
+// explicit basic_stringbuf(ios_base::openmode which = ios_base::in | ios_base::out); // before C++20
+// basic_stringbuf() : basic_stringbuf(ios_base::in | ios_base::out) {}               // C++20
+// explicit basic_stringbuf(ios_base::openmode which);                                // C++20
 
 #include <sstream>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "test_convertible.h"
+#endif
 
 template<typename CharT>
 struct testbuf
@@ -52,5 +57,13 @@ int main(int, char**)
         buf.check();
     }
 
-  return 0;
+#if TEST_STD_VER >= 11
+    {
+      typedef std::stringbuf B;
+      static_assert(test_convertible<B>(), "");
+      static_assert(!test_convertible<B, std::ios_base::openmode>(), "");
+    }
+#endif
+
+    return 0;
 }

diff  --git a/libcxx/test/std/input.output/string.streams/stringstream.cons/default.pass.cpp b/libcxx/test/std/input.output/string.streams/stringstream.cons/default.pass.cpp
index 904690894569..f0c8750699c8 100644
--- a/libcxx/test/std/input.output/string.streams/stringstream.cons/default.pass.cpp
+++ b/libcxx/test/std/input.output/string.streams/stringstream.cons/default.pass.cpp
@@ -11,12 +11,23 @@
 // template <class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
 // class basic_stringstream
 
-// explicit basic_stringstream(ios_base::openmode which = ios_base::out|ios_base::in);
+// explicit basic_stringstream(ios_base::openmode which = ios_base::out | ios_base::in); // before C++20
+// basic_stringstream() : basic_stringstream(ios_base::out | ios_base::in) {}            // C++20
+// explicit basic_stringstream(ios_base::openmode which);                                // C++20
 
 #include <sstream>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "test_convertible.h"
+
+template <typename S>
+void test() {
+  static_assert(test_convertible<S>(), "");
+  static_assert(!test_convertible<S, std::ios_base::openmode>(), "");
+}
+#endif
 
 int main(int, char**)
 {
@@ -45,5 +56,10 @@ int main(int, char**)
         assert(ss.str() == L"");
     }
 
-  return 0;
+#if TEST_STD_VER >= 11
+    test<std::stringstream>();
+    test<std::wstringstream>();
+#endif
+
+    return 0;
 }

diff  --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp
index bf6355d17d15..d70804e6b86c 100644
--- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp
+++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.buffer/ctor.pass.cpp
@@ -10,8 +10,13 @@
 
 // wbuffer_convert<Codecvt, Elem, Tr>
 
-// wbuffer_convert(streambuf *bytebuf = 0, Codecvt *pcvt = new Codecvt,
-//                 state_type state = state_type());
+// wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt,
+//                 state_type state = state_type());          // before C++14
+// explicit wbuffer_convert(streambuf* bytebuf = nullptr, Codecvt* pcvt = new Codecvt,
+//                          state_type state = state_type()); // before C++20
+// wbuffer_convert() : wbuffer_convert(nullptr) {} // C++20
+// explicit wbuffer_convert(streambuf* bytebuf, Codecvt* pcvt = new Codecvt,
+//                          state_type state = state_type()); // C++20
 
 #include <locale>
 #include <codecvt>
@@ -20,6 +25,9 @@
 
 #include "test_macros.h"
 #include "count_new.h"
+#if TEST_STD_VER >= 11
+#include "test_convertible.h"
+#endif
 
 int main(int, char**)
 {
@@ -57,5 +65,12 @@ int main(int, char**)
     }
     assert(globalMemCounter.checkOutstandingNewEq(0));
 
-  return 0;
+#if TEST_STD_VER >= 11
+    {
+      static_assert(test_convertible<B>(), "");
+      static_assert(!test_convertible<B, std::streambuf*>(), "");
+    }
+#endif
+
+    return 0;
 }

diff  --git a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_codecvt.pass.cpp b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_codecvt.pass.cpp
index 3efd26fb4ce1..bc39fd7b3897 100644
--- a/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_codecvt.pass.cpp
+++ b/libcxx/test/std/localization/locales/locale.convenience/conversions/conversions.string/ctor_codecvt.pass.cpp
@@ -10,13 +10,19 @@
 
 // wstring_convert<Codecvt, Elem, Wide_alloc, Byte_alloc>
 
-// wstring_convert(Codecvt* pcvt = new Codecvt);
+// wstring_convert(Codecvt* pcvt = new Codecvt);          // before C++14
+// explicit wstring_convert(Codecvt* pcvt = new Codecvt); // before C++20
+// wstring_convert() : wstring_convert(new Codecvt) {}    // C++20
+// explicit wstring_convert(Codecvt* pcvt);               // C++20
 
 #include <locale>
 #include <codecvt>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "test_convertible.h"
+#endif
 
 int main(int, char**)
 {
@@ -37,5 +43,14 @@ int main(int, char**)
 #endif
     }
 
-  return 0;
+#if TEST_STD_VER >= 11
+    {
+      typedef std::codecvt_utf8<wchar_t> Codecvt;
+      typedef std::wstring_convert<Codecvt> B;
+      static_assert(test_convertible<B>(), "");
+      static_assert(!test_convertible<B, Codecvt*>(), "");
+    }
+#endif
+
+    return 0;
 }

diff  --git a/libcxx/test/std/numerics/rand/rand.device/ctor.pass.cpp b/libcxx/test/std/numerics/rand/rand.device/ctor.pass.cpp
index b12a7bb7598b..a42fd5957307 100644
--- 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,9 @@
 #endif
 
 #include "test_macros.h"
-
+#if TEST_STD_VER >= 11
+#include "test_convertible.h"
+#endif
 
 bool is_valid_random_device(const std::string &token) {
 #if defined(_LIBCPP_USING_DEV_RANDOM)
@@ -61,7 +65,6 @@ void check_random_device_invalid(const std::string &token) {
 #endif
 }
 
-
 int main(int, char**) {
   {
     std::random_device r;
@@ -100,5 +103,9 @@ int main(int, char**) {
   }
 #endif // !defined(_WIN32)
 
+#if TEST_STD_VER >= 11
+  static_assert(test_convertible<std::random_device>(), "");
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/ctor_double.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/ctor_double.pass.cpp
index e3abdd785ec7..b0e534ee5217 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/ctor_double.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bernoulli/ctor_double.pass.cpp
@@ -10,12 +10,18 @@
 
 // class bernoulli_distribution
 
-// explicit bernoulli_distribution(double p = 0.5);
+// explicit bernoulli_distribution(double p = 0.5);          // before C++20
+// bernoulli_distribution() : bernoulli_distribution(0.5) {} // C++20
+// explicit bernoulli_distribution(double p);                // C++20
 
 #include <random>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
 
 int main(int, char**)
 {
@@ -35,5 +41,14 @@ int main(int, char**)
         assert(d.p() == 0.75);
     }
 
-  return 0;
+#if TEST_STD_VER >= 11
+    {
+      typedef std::bernoulli_distribution D;
+      static_assert(test_convertible<D>(), "");
+      assert(D(0.5) == make_implicit<D>());
+      static_assert(!test_convertible<D, double>(), "");
+    }
+#endif
+
+    return 0;
 }

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/ctor_int_double.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/ctor_int_double.pass.cpp
index 23fa5f8aed54..47e56b1463dc 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/ctor_int_double.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.bin/ctor_int_double.pass.cpp
@@ -11,12 +11,29 @@
 // template<class IntType = int>
 // class binomial_distribution
 
-// explicit binomial_distribution(IntType t = 1, double p = 0.5);
+// explicit binomial_distribution(IntType t = 1, double p = 0.5); // before C++20
+// binomial_distribution() : binomial_distribution(1) {}          // C++20
+// explicit binomial_distribution(IntType t, double p = 0.5);     // C++20
 
 #include <random>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
+
+template <class T>
+void test_implicit() {
+#if TEST_STD_VER >= 11
+  typedef std::binomial_distribution<T> D;
+  static_assert(test_convertible<D>(), "");
+  assert(D(1) == make_implicit<D>());
+  static_assert(!test_convertible<D, T>(), "");
+  static_assert(!test_convertible<D, T, double>(), "");
+#endif
+}
 
 int main(int, char**)
 {
@@ -39,5 +56,8 @@ int main(int, char**)
         assert(d.p() == 0.75);
     }
 
-  return 0;
+    test_implicit<int>();
+    test_implicit<long>();
+
+    return 0;
 }

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.geo/ctor_double.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.geo/ctor_double.pass.cpp
index 5828867bacd3..49d47dff5627 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.geo/ctor_double.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.geo/ctor_double.pass.cpp
@@ -11,12 +11,28 @@
 // template<class IntType = int>
 // class geometric_distribution
 
-// explicit geometric_distribution(double p = 0.5);
+// explicit geometric_distribution(double p = 0.5);          // before C++20
+// geometric_distribution() : geometric_distribution(0.5) {} // C++20
+// explicit geometric_distribution(double p);                // C++20
 
 #include <random>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
+
+template <class T>
+void test_implicit() {
+#if TEST_STD_VER >= 11
+  typedef std::geometric_distribution<T> D;
+  static_assert(test_convertible<D>(), "");
+  assert(D(0.5) == make_implicit<D>());
+  static_assert(!test_convertible<D, double>(), "");
+#endif
+}
 
 int main(int, char**)
 {
@@ -31,5 +47,8 @@ int main(int, char**)
         assert(d.p() == 0.75);
     }
 
-  return 0;
+    test_implicit<int>();
+    test_implicit<long>();
+
+    return 0;
 }

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/ctor_int_double.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/ctor_int_double.pass.cpp
index eee225caa054..cf49d090c975 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/ctor_int_double.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.bern/rand.dist.bern.negbin/ctor_int_double.pass.cpp
@@ -11,12 +11,29 @@
 // template<class IntType = int>
 // class negative_binomial_distribution
 
-// explicit negative_binomial_distribution(IntType t = 1, double p = 0.5);
+// explicit negative_binomial_distribution(IntType k = 1, double p = 0.5); // before C++20
+// negative_binomial_distribution() : negative_binomial_distribution(1) {} // C++20
+// explicit negative_binomial_distribution(IntType k, double p = 0.5);     // C++20
 
 #include <random>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
+
+template <class T>
+void test_implicit() {
+#if TEST_STD_VER >= 11
+  typedef std::negative_binomial_distribution<T> D;
+  static_assert(test_convertible<D>(), "");
+  assert(D(1) == make_implicit<D>());
+  static_assert(!test_convertible<D, T>(), "");
+  static_assert(!test_convertible<D, T, double>(), "");
+#endif
+}
 
 int main(int, char**)
 {
@@ -39,5 +56,8 @@ int main(int, char**)
         assert(d.p() == 0.75);
     }
 
-  return 0;
+    test_implicit<int>();
+    test_implicit<long>();
+
+    return 0;
 }

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.cauchy/ctor_double_double.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.cauchy/ctor_double_double.pass.cpp
index fedad4b4de0d..96e4e1d43957 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.cauchy/ctor_double_double.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.cauchy/ctor_double_double.pass.cpp
@@ -11,12 +11,29 @@
 // template<class RealType = double>
 // class cauchy_distribution
 
-// explicit cauchy_distribution(result_type a = 0, result_type b = 1);
+// explicit cauchy_distribution(RealType a = 0.0, RealType b = 1.0); // before C++20
+// cauchy_distribution() : cauchy_distribution(0.0) {}               // C++20
+// explicit cauchy_distribution(RealType a, RealType b = 1.0);       // C++20
 
 #include <random>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
+
+template <class T>
+void test_implicit() {
+#if TEST_STD_VER >= 11
+  typedef std::cauchy_distribution<T> D;
+  static_assert(test_convertible<D>(), "");
+  assert(D(0) == make_implicit<D>());
+  static_assert(!test_convertible<D, T>(), "");
+  static_assert(!test_convertible<D, T, T>(), "");
+#endif
+}
 
 int main(int, char**)
 {
@@ -39,5 +56,8 @@ int main(int, char**)
         assert(d.b() == 5.25);
     }
 
-  return 0;
+    test_implicit<float>();
+    test_implicit<double>();
+
+    return 0;
 }

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.chisq/ctor_double.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.chisq/ctor_double.pass.cpp
index ba1fce65afa6..ec22816f9f6b 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.chisq/ctor_double.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.chisq/ctor_double.pass.cpp
@@ -11,12 +11,28 @@
 // template<class RealType = double>
 // class chi_squared_distribution
 
-// explicit chi_squared_distribution(result_type alpha = 0, result_type beta = 1);
+// explicit chi_squared_distribution(RealType n = 1.0);          // before C++20
+// chi_squared_distribution() : chi_squared_distribution(1.0) {} // C++20
+// explicit chi_squared_distribution(RealType n);                // C++20
 
 #include <random>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
+
+template <class T>
+void test_implicit() {
+#if TEST_STD_VER >= 11
+  typedef std::chi_squared_distribution<T> D;
+  static_assert(test_convertible<D>(), "");
+  assert(D(1) == make_implicit<D>());
+  static_assert(!test_convertible<D, T>(), "");
+#endif
+}
 
 int main(int, char**)
 {
@@ -31,5 +47,8 @@ int main(int, char**)
         assert(d.n() == 14.5);
     }
 
-  return 0;
+    test_implicit<float>();
+    test_implicit<double>();
+
+    return 0;
 }

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.f/ctor_double_double.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.f/ctor_double_double.pass.cpp
index 5e0e4410be1a..8380dfe26c26 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.f/ctor_double_double.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.f/ctor_double_double.pass.cpp
@@ -11,12 +11,29 @@
 // template<class RealType = double>
 // class fisher_f_distribution
 
-// explicit fisher_f_distribution(result_type alpha = 0, result_type beta = 1);
+// explicit fisher_f_distribution(RealType m = 1.0, RealType n = 1.0); // before C++20
+// fisher_f_distribution() : fisher_f_distribution(1.0) {}             // C++20
+// explicit fisher_f_distribution(RealType m, RealType n = 1.0);       // C++20
 
 #include <random>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
+
+template <class T>
+void test_implicit() {
+#if TEST_STD_VER >= 11
+  typedef std::fisher_f_distribution<T> D;
+  static_assert(test_convertible<D>(), "");
+  assert(D(1) == make_implicit<D>());
+  static_assert(!test_convertible<D, T>(), "");
+  static_assert(!test_convertible<D, T, T>(), "");
+#endif
+}
 
 int main(int, char**)
 {
@@ -39,5 +56,8 @@ int main(int, char**)
         assert(d.n() == 5.25);
     }
 
-  return 0;
+    test_implicit<float>();
+    test_implicit<double>();
+
+    return 0;
 }

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/ctor_double_double.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/ctor_double_double.pass.cpp
index 5d0652d60a49..47bbbff5603a 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/ctor_double_double.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/ctor_double_double.pass.cpp
@@ -11,12 +11,29 @@
 // template<class RealType = double>
 // class lognormal_distribution
 
-// explicit lognormal_distribution(result_type mean = 0, result_type stddev = 1);
+// explicit lognormal_distribution(RealType mean = 0.0, RealType stddev = 1.0); // before C++20
+// lognormal_distribution() : lognormal_distribution(0.0) {}                    // C++20
+// explicit lognormal_distribution(RealType mean, RealType stddev = 1.0);       // C++20
 
 #include <random>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
+
+template <class T>
+void test_implicit() {
+#if TEST_STD_VER >= 11
+  typedef std::lognormal_distribution<T> D;
+  static_assert(test_convertible<D>(), "");
+  assert(D(0) == make_implicit<D>());
+  static_assert(!test_convertible<D, T>(), "");
+  static_assert(!test_convertible<D, T, T>(), "");
+#endif
+}
 
 int main(int, char**)
 {
@@ -39,5 +56,8 @@ int main(int, char**)
         assert(d.s() == 5.25);
     }
 
-  return 0;
+    test_implicit<float>();
+    test_implicit<double>();
+
+    return 0;
 }

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.normal/ctor_double_double.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.normal/ctor_double_double.pass.cpp
index 3d0fb91bd73d..f6e8087abd97 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.normal/ctor_double_double.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.normal/ctor_double_double.pass.cpp
@@ -11,12 +11,29 @@
 // template<class RealType = double>
 // class normal_distribution
 
-// explicit normal_distribution(result_type mean = 0, result_type stddev = 1);
+// explicit normal_distribution(RealType mean = 0.0, RealType stddev = 1.0); // before C++20
+// normal_distribution() : normal_distribution(0.0) {}                       // C++20
+// explicit normal_distribution(RealType mean, RealType stddev = 1.0);       // C++20
 
 #include <random>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
+
+template <class T>
+void test_implicit() {
+#if TEST_STD_VER >= 11
+  typedef std::normal_distribution<T> D;
+  static_assert(test_convertible<D>(), "");
+  assert(D(0) == make_implicit<D>());
+  static_assert(!test_convertible<D, T>(), "");
+  static_assert(!test_convertible<D, T, T>(), "");
+#endif
+}
 
 int main(int, char**)
 {
@@ -39,5 +56,8 @@ int main(int, char**)
         assert(d.stddev() == 5.25);
     }
 
-  return 0;
+    test_implicit<float>();
+    test_implicit<double>();
+
+    return 0;
 }

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.t/ctor_double.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.t/ctor_double.pass.cpp
index 9ce6f61d07b4..5077d4c52bc6 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.t/ctor_double.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.t/ctor_double.pass.cpp
@@ -11,12 +11,28 @@
 // template<class RealType = double>
 // class student_t_distribution
 
-// explicit student_t_distribution(result_type alpha = 0, result_type beta = 1);
+// explicit student_t_distribution(RealType n = 1.0);        // before C++20
+// student_t_distribution() : student_t_distribution(1.0) {} // C++20
+// explicit student_t_distribution(RealType n);              // C++20
 
 #include <random>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
+
+template <class T>
+void test_implicit() {
+#if TEST_STD_VER >= 11
+  typedef std::student_t_distribution<T> D;
+  static_assert(test_convertible<D>(), "");
+  assert(D(1) == make_implicit<D>());
+  static_assert(!test_convertible<D, T>(), "");
+#endif
+}
 
 int main(int, char**)
 {
@@ -31,5 +47,8 @@ int main(int, char**)
         assert(d.n() == 14.5);
     }
 
-  return 0;
+    test_implicit<float>();
+    test_implicit<double>();
+
+    return 0;
 }

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.exp/ctor_double.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.exp/ctor_double.pass.cpp
index a085668685e1..1259a7f79bd4 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.exp/ctor_double.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.exp/ctor_double.pass.cpp
@@ -11,12 +11,28 @@
 // template<class RealType = double>
 // class exponential_distribution
 
-// explicit exponential_distribution(RealType lambda = 1.0);
+// explicit exponential_distribution(RealType lambda = 1.0);     // before C++20
+// exponential_distribution() : exponential_distribution(1.0) {} // C++20
+// explicit exponential_distribution(RealType lambda);           // C++20
 
 #include <random>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
+
+template <class T>
+void test_implicit() {
+#if TEST_STD_VER >= 11
+  typedef std::exponential_distribution<T> D;
+  static_assert(test_convertible<D>(), "");
+  assert(D(1) == make_implicit<D>());
+  static_assert(!test_convertible<D, T>(), "");
+#endif
+}
 
 int main(int, char**)
 {
@@ -31,5 +47,8 @@ int main(int, char**)
         assert(d.lambda() == 3.5);
     }
 
-  return 0;
+    test_implicit<float>();
+    test_implicit<double>();
+
+    return 0;
 }

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.extreme/ctor_double_double.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.extreme/ctor_double_double.pass.cpp
index 7d55d03ca81b..17fb9a5f0eb5 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.extreme/ctor_double_double.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.extreme/ctor_double_double.pass.cpp
@@ -11,12 +11,29 @@
 // template<class RealType = double>
 // class extreme_value_distribution
 
-// explicit extreme_value_distribution(result_type a = 0, result_type b = 1);
+// explicit extreme_value_distribution(RealType a = 0.0, RealType b = 1.0); // before C++20
+// extreme_value_distribution() : extreme_value_distribution(0.0) {}        // C++20
+// explicit extreme_value_distribution(RealType a, RealType b = 1.0);       // C++20
 
 #include <random>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
+
+template <class T>
+void test_implicit() {
+#if TEST_STD_VER >= 11
+  typedef std::extreme_value_distribution<T> D;
+  static_assert(test_convertible<D>(), "");
+  assert(D(0) == make_implicit<D>());
+  static_assert(!test_convertible<D, T>(), "");
+  static_assert(!test_convertible<D, T, T>(), "");
+#endif
+}
 
 int main(int, char**)
 {
@@ -39,5 +56,8 @@ int main(int, char**)
         assert(d.b() == 5.25);
     }
 
-  return 0;
+    test_implicit<float>();
+    test_implicit<double>();
+
+    return 0;
 }

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.gamma/ctor_double_double.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.gamma/ctor_double_double.pass.cpp
index 4bbd68d8c5f6..c0fa236d0462 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.gamma/ctor_double_double.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.gamma/ctor_double_double.pass.cpp
@@ -11,12 +11,29 @@
 // template<class RealType = double>
 // class gamma_distribution
 
-// explicit gamma_distribution(result_type alpha = 0, result_type beta = 1);
+// explicit gamma_distribution(RealType alpha = 1.0, RealType beta = 1.0); // before C++20
+// gamma_distribution() : gamma_distribution(1.0) {}                       // C++20
+// explicit gamma_distribution(RealType alpha, RealType beta = 1.0);       // C++20
 
 #include <random>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
+
+template <class T>
+void test_implicit() {
+#if TEST_STD_VER >= 11
+  typedef std::gamma_distribution<T> D;
+  static_assert(test_convertible<D>(), "");
+  assert(D(1) == make_implicit<D>());
+  static_assert(!test_convertible<D, T>(), "");
+  static_assert(!test_convertible<D, T, T>(), "");
+#endif
+}
 
 int main(int, char**)
 {
@@ -39,5 +56,8 @@ int main(int, char**)
         assert(d.beta() == 5.25);
     }
 
-  return 0;
+    test_implicit<float>();
+    test_implicit<double>();
+
+    return 0;
 }

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.poisson/ctor_double.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.poisson/ctor_double.pass.cpp
index 2b8d95770e53..a9666d776d0d 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.poisson/ctor_double.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.poisson/ctor_double.pass.cpp
@@ -11,12 +11,28 @@
 // template<class IntType = int>
 // class poisson_distribution
 
-// explicit poisson_distribution(RealType lambda = 1.0);
+// explicit poisson_distribution(double mean = 1.0);     // before C++20
+// poisson_distribution() : poisson_distribution(1.0) {} // C++20
+// explicit poisson_distribution(double mean);           // C++20
 
 #include <random>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
+
+template <class T>
+void test_implicit() {
+#if TEST_STD_VER >= 11
+  typedef std::poisson_distribution<T> D;
+  static_assert(test_convertible<D>(), "");
+  assert(D(1) == make_implicit<D>());
+  static_assert(!test_convertible<D, double>(), "");
+#endif
+}
 
 int main(int, char**)
 {
@@ -31,5 +47,8 @@ int main(int, char**)
         assert(d.mean() == 3.5);
     }
 
-  return 0;
+    test_implicit<int>();
+    test_implicit<long>();
+
+    return 0;
 }

diff  --git a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.weibull/ctor_double_double.pass.cpp b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.weibull/ctor_double_double.pass.cpp
index 41591c0c9904..9d1558c94142 100644
--- a/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.weibull/ctor_double_double.pass.cpp
+++ b/libcxx/test/std/numerics/rand/rand.dis/rand.dist.pois/rand.dist.pois.weibull/ctor_double_double.pass.cpp
@@ -11,12 +11,29 @@
 // template<class RealType = double>
 // class weibull_distribution
 
-// explicit weibull_distribution(result_type a = 0, result_type b = 1);
+// explicit weibull_distribution(RealType a = 1.0, RealType b = 1.0); // before C++20
+// weibull_distribution() : weibull_distribution(1.0) {}              // C++20
+// explicit weibull_distribution(RealType a, RealType b = 1.0);       // C++20
 
 #include <random>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
+
+template <class T>
+void test_implicit() {
+#if TEST_STD_VER >= 11
+  typedef std::weibull_distribution<T> D;
+  static_assert(test_convertible<D>(), "");
+  assert(D(1) == make_implicit<D>());
+  static_assert(!test_convertible<D, T>(), "");
+  static_assert(!test_convertible<D, T, T>(), "");
+#endif
+}
 
 int main(int, char**)
 {
@@ -39,5 +56,8 @@ int main(int, char**)
         assert(d.b() == 5.25);
     }
 
-  return 0;
+    test_implicit<float>();
+    test_implicit<double>();
+
+    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
index 1e7a35e2af52..4595b5628b3e 100644
--- 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,30 @@
 // class uniform_int_distribution
 
 // explicit uniform_int_distribution(IntType a = 0,
-//                                   IntType b = numeric_limits<IntType>::max());
+//                                   IntType b = numeric_limits<IntType>::max()); // before C++20
+// uniform_int_distribution() : uniform_int_distribution(0) {}                    // C++20
+// explicit uniform_int_distribution(IntType a,
+//                                   IntType b = numeric_limits<IntType>::max()); // C++20
 
 #include <random>
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
+
+template <class T>
+void test_implicit() {
+#if TEST_STD_VER >= 11
+  typedef std::uniform_int_distribution<> D;
+  static_assert(test_convertible<D>(), "");
+  assert(D(0) == make_implicit<D>());
+  static_assert(!test_convertible<D, T>(), "");
+  static_assert(!test_convertible<D, T, T>(), "");
+#endif
+}
 
 int main(int, char**)
 {
@@ -40,5 +58,8 @@ int main(int, char**)
         assert(d.b() == 106);
     }
 
-  return 0;
+    test_implicit<int>();
+    test_implicit<long>();
+
+    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
index d377a37432d7..000000000000
--- 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
-//
-//===----------------------------------------------------------------------===//
-
-// <random>
-
-// template<class RealType = double>
-// class uniform_real_distribution
-
-// explicit uniform_real_distribution(RealType a = 0,
-//                                    RealType b = 1);
-
-#include <random>
-#include <cassert>
-
-#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
index 000000000000..b8d32c1b647a
--- /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,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <random>
+
+// template<class RealType = double>
+// 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 <random>
+#include <cassert>
+
+#include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
+
+template <class T>
+void test_implicit() {
+#if TEST_STD_VER >= 11
+  typedef std::uniform_real_distribution<T> D;
+  static_assert(test_convertible<D>(), "");
+  assert(D(0) == make_implicit<D>());
+  static_assert(!test_convertible<D, T>(), "");
+  static_assert(!test_convertible<D, T, T>(), "");
+#endif
+}
+
+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);
+    }
+
+    test_implicit<float>();
+    test_implicit<double>();
+
+    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
index 0d84604f2744..e78bce24c22e 100644
--- 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 UIntType, UIntType a, UIntType c, UIntType m>
 //   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,17 @@
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
+
+template <class T>
+std::string to_string(T const& e) {
+  std::ostringstream os;
+  os << e;
+  return os.str();
+}
 
 template <class T>
 void
@@ -30,23 +43,17 @@ test1()
     {
         typedef std::linear_congruential_engine<T, 2, 3, 7> E;
         E e(5);
-        std::ostringstream os;
-        os << e;
-        assert(os.str() == "5");
+        assert(to_string(e) == "5");
     }
     {
         typedef std::linear_congruential_engine<T, 2, 3, 0> E;
         E e(5);
-        std::ostringstream os;
-        os << e;
-        assert(os.str() == "5");
+        assert(to_string(e) == "5");
     }
     {
         typedef std::linear_congruential_engine<T, 2, 3, 4> E;
         E e(5);
-        std::ostringstream os;
-        os << e;
-        assert(os.str() == "1");
+        assert(to_string(e) == "1");
     }
 }
 
@@ -58,23 +65,17 @@ test2()
     {
         typedef std::linear_congruential_engine<T, 2, 3, 7> E;
         E e(7);
-        std::ostringstream os;
-        os << e;
-        assert(os.str() == "0");
+        assert(to_string(e) == "0");
     }
     {
         typedef std::linear_congruential_engine<T, 2, 3, 0> E;
         E e(0);
-        std::ostringstream os;
-        os << e;
-        assert(os.str() == "0");
+        assert(to_string(e) == "0");
     }
     {
         typedef std::linear_congruential_engine<T, 2, 3, 4> E;
         E e(4);
-        std::ostringstream os;
-        os << e;
-        assert(os.str() == "0");
+        assert(to_string(e) == "0");
     }
 }
 
@@ -86,23 +87,17 @@ test3()
     {
         typedef std::linear_congruential_engine<T, 2, 0, 7> E;
         E e(3);
-        std::ostringstream os;
-        os << e;
-        assert(os.str() == "3");
+        assert(to_string(e) == "3");
     }
     {
         typedef std::linear_congruential_engine<T, 2, 0, 0> E;
         E e(5);
-        std::ostringstream os;
-        os << e;
-        assert(os.str() == "5");
+        assert(to_string(e) == "5");
     }
     {
         typedef std::linear_congruential_engine<T, 2, 0, 4> E;
         E e(7);
-        std::ostringstream os;
-        os << e;
-        assert(os.str() == "3");
+        assert(to_string(e) == "3");
     }
 }
 
@@ -114,26 +109,30 @@ test4()
     {
         typedef std::linear_congruential_engine<T, 2, 0, 7> E;
         E e(7);
-        std::ostringstream os;
-        os << e;
-        assert(os.str() == "1");
+        assert(to_string(e) == "1");
     }
     {
         typedef std::linear_congruential_engine<T, 2, 0, 0> E;
         E e(0);
-        std::ostringstream os;
-        os << e;
-        assert(os.str() == "1");
+        assert(to_string(e) == "1");
     }
     {
         typedef std::linear_congruential_engine<T, 2, 0, 4> E;
         E e(8);
-        std::ostringstream os;
-        os << e;
-        assert(os.str() == "1");
+        assert(to_string(e) == "1");
     }
 }
 
+template <class T>
+void test_implicit() {
+#if TEST_STD_VER >= 11
+  typedef std::linear_congruential_engine<T, 2, 0, 7> E;
+  static_assert(test_convertible<E>(), "");
+  assert(E(E::default_seed) == make_implicit<E>());
+  static_assert(!test_convertible<E, T>(), "");
+#endif
+}
+
 int main(int, char**)
 {
     test1<unsigned short>();
@@ -156,5 +155,7 @@ int main(int, char**)
     test4<unsigned long>();
     test4<unsigned long long>();
 
-  return 0;
+    test_implicit<unsigned short>();
+
+    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
index be8ae17222fc..22c5fa61b129 100644
--- 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,19 @@
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
+
+template <class T>
+std::string
+to_string(T const &e)
+{
+    std::ostringstream os;
+    os << e;
+    return os.str();
+}
 
 void
 test1()
@@ -124,9 +139,7 @@ test1()
     "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,9 +250,16 @@ test2()
     "15150289760867914983 4931341382074091848 12635920082410445322 "
     "8498109357807439006 14836776625250834986";
     std::mt19937_64 e1(0);
-    std::ostringstream os;
-    os << e1;
-    assert(os.str() == a);
+    assert(to_string(e1) == a);
+}
+
+template <class E, typename Arg>
+void test_implicit() {
+#if TEST_STD_VER >= 11
+  static_assert(test_convertible<E>(), "");
+  assert(E(E::default_seed) == make_implicit<E>());
+  static_assert(!test_convertible<E, Arg>(), "");
+#endif
 }
 
 int main(int, char**)
@@ -247,5 +267,8 @@ int main(int, char**)
     test1();
     test2();
 
-  return 0;
+    test_implicit<std::mt19937, uint_fast32_t>();
+    test_implicit<std::mt19937_64, uint_fast64_t>();
+
+    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
index b63d2e0afc8f..f6d1cc030650 100644
--- 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 UIntType, size_t w, size_t s, size_t r>
 // 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,19 @@
 #include <cassert>
 
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "make_implicit.h"
+#include "test_convertible.h"
+#endif
+
+template <class T>
+std::string
+to_string(T const &e)
+{
+    std::ostringstream os;
+    os << e;
+    return os.str();
+}
 
 void
 test1()
@@ -30,9 +45,7 @@ test1()
     "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 +56,29 @@ test2()
     "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 >= 11
+template <class E>
+void test_implicit_ctor() {
+  assert(E(E::default_seed) == make_implicit<E>());
 }
+#endif
 
 int main(int, char**)
 {
     test1();
     test2();
 
+#if TEST_STD_VER >= 11
+    static_assert(test_convertible<std::ranlux24_base>(), "");
+    static_assert(test_convertible<std::ranlux48_base>(), "");
+    test_implicit_ctor<std::ranlux24_base>();
+    test_implicit_ctor<std::ranlux48_base>();
+    static_assert(!test_convertible<std::ranlux24_base, uint_fast32_t>(), "");
+    static_assert(!test_convertible<std::ranlux48_base, uint_fast64_t>(), "");
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/re/re.results/re.results.const/default.pass.cpp b/libcxx/test/std/re/re.results/re.results.const/default.pass.cpp
index 783cd29423d4..52a7282c6e76 100644
--- a/libcxx/test/std/re/re.results/re.results.const/default.pass.cpp
+++ b/libcxx/test/std/re/re.results/re.results.const/default.pass.cpp
@@ -10,20 +10,37 @@
 
 // class match_results<BidirectionalIterator, Allocator>
 
-// match_results(const Allocator& a = Allocator());
+// explicit match_results(const Allocator& a = Allocator()); // before C++20
+// match_results() : match_results(Allocator()) {}           // C++20
+// explicit match_results(const Allocator& a);               // C++20
 
 #include <regex>
 #include <cassert>
 #include "test_macros.h"
+#if TEST_STD_VER >= 11
+#include "test_convertible.h"
+
+template <typename T>
+void test_implicit() {
+  static_assert(test_convertible<T>(), "");
+  static_assert(!test_convertible<T, typename T::allocator_type>(), "");
+}
+#endif
 
 template <class CharT>
 void
 test()
 {
-    std::match_results<const CharT*> m;
+    typedef std::match_results<const CharT*> M;
+    typedef std::allocator<std::sub_match<const CharT*> > Alloc;
+    M m;
     assert(m.size() == 0);
     assert(!m.ready());
-    assert(m.get_allocator() == std::allocator<std::sub_match<const CharT*> >());
+    assert(m.get_allocator() == Alloc());
+
+#if TEST_STD_VER >= 11
+    test_implicit<M>();
+#endif
 }
 
 int main(int, char**)

diff  --git a/libcxx/test/support/make_implicit.h b/libcxx/test/support/make_implicit.h
new file mode 100644
index 000000000000..8be536210195
--- /dev/null
+++ b/libcxx/test/support/make_implicit.h
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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<Tp>(Args&&... args)" is a function to construct 'Tp'
+// from 'Args...' using implicit construction.
+
+#include <utility>
+
+template <class T, class... Args>
+T make_implicit(Args&&... args) {
+  return {std::forward<Args>(args)...};
+}
+
+#endif // SUPPORT_MAKE_IMPLICIT_H


        


More information about the llvm-branch-commits mailing list