diff --git a/libcxx/docs/Status/Cxx2bPapers.csv b/libcxx/docs/Status/Cxx2bPapers.csv --- a/libcxx/docs/Status/Cxx2bPapers.csv +++ b/libcxx/docs/Status/Cxx2bPapers.csv @@ -27,7 +27,7 @@ "`P0798R8 `__","LWG","Monadic operations for ``std::optional``","October 2021","","" "`P0849R8 `__","LWG","``auto(x)``: ``DECAY_COPY`` in the language","October 2021","","" "`P1072R10 `__","LWG","``basic_string::resize_and_overwrite``","October 2021","","" -"`P1147R1 `__","LWG","Printing ``volatile`` Pointers","October 2021","","" +"`P1147R1 `__","LWG","Printing ``volatile`` Pointers","October 2021","|Complete|","14.0" "`P1272R4 `__","LWG","Byteswapping for fun&&nuf","October 2021","","" "`P1675R2 `__","LWG","``rethrow_exception`` must be allowed to copy","October 2021","","" "`P2077R3 `__","LWG","Heterogeneous erasure overloads for associative containers","October 2021","","" diff --git a/libcxx/include/ostream b/libcxx/include/ostream --- a/libcxx/include/ostream +++ b/libcxx/include/ostream @@ -55,6 +55,7 @@ basic_ostream& operator<<(double f); basic_ostream& operator<<(long double f); basic_ostream& operator<<(const void* p); + basic_ostream& operator<<(const volatile void* val); basic_ostream& operator<<(basic_streambuf* sb); basic_ostream& operator<<(nullptr_t); @@ -210,6 +211,13 @@ basic_ostream& operator<<(double __f); basic_ostream& operator<<(long double __f); basic_ostream& operator<<(const void* __p); + +#if _LIBCPP_STD_VER > 20 + _LIBCPP_HIDE_FROM_ABI basic_ostream& operator<<(const volatile void* __val) { + return operator<<(const_cast(__val)); + } +#endif + basic_ostream& operator<<(basic_streambuf* __sb); _LIBCPP_INLINE_VISIBILITY diff --git a/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/pointer.pass.cpp b/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/pointer.pass.cpp --- a/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/pointer.pass.cpp +++ b/libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/pointer.pass.cpp @@ -67,6 +67,14 @@ assert(os1.good()); std::string s1(sb1.str()); +#if TEST_STD_VER > 20 + testbuf sb3; + std::ostream os3(&sb3); + os3 << static_cast(&n1); + assert(os3.good()); + std::string s3(sb3.str()); +#endif + testbuf sb2; std::ostream os2(&sb2); int n2; @@ -74,6 +82,14 @@ assert(os2.good()); std::string s2(sb2.str()); +#if TEST_STD_VER > 20 + testbuf sb4; + std::ostream os4(&sb4); + os4 << static_cast(&n2); + assert(os4.good()); + std::string s4(sb4.str()); +#endif + // %p is implementation defined. Instead of validating the // output, at least ensure that it does not generate an empty // string. Also make sure that given two distinct addresses, the @@ -81,6 +97,15 @@ assert(!s1.empty()); assert(!s2.empty()); assert(s1 != s2); + +#if TEST_STD_VER > 20 + assert(!s3.empty()); + assert(!s4.empty()); + assert(s3 != s4); + + assert(s1 == s3); + assert(s2 == s4); +#endif } { testbuf sb;