[libcxx-commits] [libcxx] a3f17ba - [libc++] Implement P2467R1: Support exclusive mode for fstreams
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Nov 17 14:27:38 PST 2023
Author: PragmaTwice
Date: 2023-11-17T17:27:30-05:00
New Revision: a3f17ba3febbd546f2342ffc780ac93b694fdc8d
URL: https://github.com/llvm/llvm-project/commit/a3f17ba3febbd546f2342ffc780ac93b694fdc8d
DIFF: https://github.com/llvm/llvm-project/commit/a3f17ba3febbd546f2342ffc780ac93b694fdc8d.diff
LOG: [libc++] Implement P2467R1: Support exclusive mode for fstreams
This patch brings std::ios_base::noreplace from P2467R1 to libc++.
This requires compiling the shared library in C++23 mode since otherwise
fstream::open(...) doesn't know about the new flag.
Differential Revision: https://reviews.llvm.org/D137640
Co-authored-by: Louis Dionne <ldionne.2 at gmail.com>
Added:
libcxx/test/std/language.support/support.limits/support.limits.general/ios.version.compile.pass.cpp
Modified:
libcxx/docs/FeatureTestMacroTable.rst
libcxx/docs/ReleaseNotes/18.rst
libcxx/docs/Status/Cxx23Papers.csv
libcxx/include/fstream
libcxx/include/ios
libcxx/include/version
libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/open_pointer.pass.cpp
libcxx/test/std/input.output/file.streams/fstreams/fstream.cons/pointer.pass.cpp
libcxx/test/std/input.output/file.streams/fstreams/fstream.members/open_pointer.pass.cpp
libcxx/test/std/input.output/file.streams/fstreams/ofstream.cons/pointer.pass.cpp
libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/open_pointer.pass.cpp
libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
libcxx/utils/generate_feature_test_macro_components.py
Removed:
################################################################################
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 9b4e46404d658ea..3b2dff3108b0f60 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -332,6 +332,8 @@ Status
--------------------------------------------------- -----------------
``__cpp_lib_invoke_r`` ``202106L``
--------------------------------------------------- -----------------
+ ``__cpp_lib_ios_noreplace`` ``202207L``
+ --------------------------------------------------- -----------------
``__cpp_lib_is_scoped_enum`` ``202011L``
--------------------------------------------------- -----------------
``__cpp_lib_mdspan`` ``202207L``
diff --git a/libcxx/docs/ReleaseNotes/18.rst b/libcxx/docs/ReleaseNotes/18.rst
index d5df7fde5be91af..5f5ff83ca551240 100644
--- a/libcxx/docs/ReleaseNotes/18.rst
+++ b/libcxx/docs/ReleaseNotes/18.rst
@@ -48,6 +48,7 @@ Implemented Papers
- P2538R1 - ADL-proof ``std::projected``
- P2614R2 - Deprecate ``numeric_limits::has_denorm``
- P0053R7 - C++ Synchronized Buffered Ostream (in the experimental library)
+- P2467R1 - Support exclusive mode for fstreams
Improvements and New Features
diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv
index 19b1dd8eb5a446f..a7a34f474ff575d 100644
--- a/libcxx/docs/Status/Cxx23Papers.csv
+++ b/libcxx/docs/Status/Cxx23Papers.csv
@@ -76,7 +76,7 @@
"`P2446R2 <https://wg21.link/P2446R2>`__","LWG","``views::as_rvalue``","July 2022","|Complete|","16.0","|ranges|"
"`P2460R2 <https://wg21.link/P2460R2>`__","LWG","Relax requirements on ``wchar_t`` to match existing practices","July 2022","",""
"`P2465R3 <https://wg21.link/P2465R3>`__","LWG","Standard Library Modules ``std`` and ``std.compat``","July 2022","",""
-"`P2467R1 <https://wg21.link/P2467R1>`__","LWG","Support exclusive mode for ``fstreams``","July 2022","",""
+"`P2467R1 <https://wg21.link/P2467R1>`__","LWG","Support exclusive mode for ``fstreams``","July 2022","|Complete|","18.0",""
"`P2474R2 <https://wg21.link/P2474R2>`__","LWG","``views::repeat``","July 2022","|Complete|","17.0","|ranges|"
"`P2494R2 <https://wg21.link/P2494R2>`__","LWG","Relaxing range adaptors to allow for move only types","July 2022","|Complete|","17.0","|ranges|"
"`P2499R0 <https://wg21.link/P2499R0>`__","LWG","``string_view`` range constructor should be ``explicit``","July 2022","|Complete|","16.0","|ranges|"
diff --git a/libcxx/include/fstream b/libcxx/include/fstream
index 4b777f82efb6cbe..cfe1ff82ba24468 100644
--- a/libcxx/include/fstream
+++ b/libcxx/include/fstream
@@ -552,6 +552,18 @@ const char* basic_filebuf<_CharT, _Traits>::__make_mdstring(
case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
case ios_base::in | ios_base::app | ios_base::binary:
return "a+b" _LIBCPP_FOPEN_CLOEXEC_MODE;
+#if _LIBCPP_STD_VER >= 23
+ case ios_base::out | ios_base::noreplace:
+ case ios_base::out | ios_base::trunc | ios_base::noreplace:
+ return "wx" _LIBCPP_FOPEN_CLOEXEC_MODE;
+ case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
+ return "w+x" _LIBCPP_FOPEN_CLOEXEC_MODE;
+ case ios_base::out | ios_base::binary | ios_base::noreplace:
+ case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
+ return "wbx" _LIBCPP_FOPEN_CLOEXEC_MODE;
+ case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
+ return "w+bx" _LIBCPP_FOPEN_CLOEXEC_MODE;
+#endif // _LIBCPP_STD_VER >= 23
default:
return nullptr;
}
@@ -665,6 +677,22 @@ basic_filebuf<_CharT, _Traits>::open(const wchar_t* __s, ios_base::openmode __mo
case ios_base::in | ios_base::app | ios_base::binary:
__mdstr = L"a+b";
break;
+# if _LIBCPP_STD_VER >= 23
+ case ios_base::out | ios_base::noreplace:
+ case ios_base::out | ios_base::trunc | ios_base::noreplace:
+ __mdstr = L"wx";
+ break;
+ case ios_base::in | ios_base::out | ios_base::trunc | ios_base::noreplace:
+ __mdstr = L"w+x";
+ break;
+ case ios_base::out | ios_base::binary | ios_base::noreplace:
+ case ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
+ __mdstr = L"wbx";
+ break;
+ case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary | ios_base::noreplace:
+ __mdstr = L"w+bx";
+ break;
+# endif // _LIBCPP_STD_VER >= 23
default:
__rt = nullptr;
break;
diff --git a/libcxx/include/ios b/libcxx/include/ios
index a31a558d5103f44..14e6c7f92f1e5f6 100644
--- a/libcxx/include/ios
+++ b/libcxx/include/ios
@@ -58,6 +58,7 @@ public:
static constexpr openmode ate;
static constexpr openmode binary;
static constexpr openmode in;
+ static constexpr openmode noreplace; // since C++23
static constexpr openmode out;
static constexpr openmode trunc;
@@ -277,12 +278,15 @@ public:
static const iostate goodbit = 0x0;
typedef unsigned int openmode;
- static const openmode app = 0x01;
- static const openmode ate = 0x02;
- static const openmode binary = 0x04;
- static const openmode in = 0x08;
- static const openmode out = 0x10;
- static const openmode trunc = 0x20;
+ static const openmode app = 0x01;
+ static const openmode ate = 0x02;
+ static const openmode binary = 0x04;
+ static const openmode in = 0x08;
+ static const openmode out = 0x10;
+ static const openmode trunc = 0x20;
+#if _LIBCPP_STD_VER >= 23
+ static const openmode noreplace = 0x40;
+#endif
enum seekdir {beg, cur, end};
diff --git a/libcxx/include/version b/libcxx/include/version
index 0db366af9e42e63..80f2920128da9d1 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -121,6 +121,7 @@ __cpp_lib_integral_constant_callable 201304L <type_traits>
__cpp_lib_interpolate 201902L <cmath> <numeric>
__cpp_lib_invoke 201411L <functional>
__cpp_lib_invoke_r 202106L <functional>
+__cpp_lib_ios_noreplace 202207L <ios>
__cpp_lib_is_aggregate 201703L <type_traits>
__cpp_lib_is_constant_evaluated 201811L <type_traits>
__cpp_lib_is_final 201402L <type_traits>
@@ -447,6 +448,7 @@ __cpp_lib_within_lifetime 202306L <type_traits>
// # define __cpp_lib_formatters 202302L
# define __cpp_lib_forward_like 202207L
# define __cpp_lib_invoke_r 202106L
+# define __cpp_lib_ios_noreplace 202207L
# define __cpp_lib_is_scoped_enum 202011L
# define __cpp_lib_mdspan 202207L
// # define __cpp_lib_move_only_function 202110L
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/open_pointer.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/open_pointer.pass.cpp
index 388d452a7da8a28..f070762b3b94d5e 100644
--- a/libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/open_pointer.pass.cpp
+++ b/libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/open_pointer.pass.cpp
@@ -10,6 +10,8 @@
// basic_filebuf<charT,traits>* open(const char* s, ios_base::openmode mode);
+// XFAIL: LIBCXX-AIX-FIXME
+
#include <fstream>
#include <cassert>
#include "test_macros.h"
@@ -52,5 +54,57 @@ int main(int, char**)
std::remove(temp.c_str());
#endif
- return 0;
+#if TEST_STD_VER >= 23
+ // Test all the noreplace flag combinations
+ {
+ std::ios_base::openmode modes[] = {
+ std::ios_base::out | std::ios_base::noreplace,
+ std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace,
+ std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace,
+ std::ios_base::out | std::ios_base::noreplace | std::ios_base::binary,
+ std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace | std::ios_base::binary,
+ std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace |
+ std::ios_base::binary,
+ };
+ for (auto mode : modes) {
+ std::string tmp = get_temp_file_name(); // also creates the file
+
+ {
+ std::filebuf f;
+ f.open(tmp.c_str(), mode);
+ assert(!f.is_open()); // since it already exists
+ }
+
+ {
+ std::remove(tmp.c_str());
+
+ std::filebuf f;
+ f.open(tmp.c_str(), mode);
+ assert(f.is_open()); // since it doesn't exist
+ }
+ }
+
+# ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ for (auto mode : modes) {
+ std::string tmp = get_temp_file_name(); // also creates the file
+
+ {
+ std::wfilebuf f;
+ f.open(tmp.c_str(), mode);
+ assert(!f.is_open()); // since it already exists
+ }
+
+ {
+ std::remove(tmp.c_str());
+
+ std::wfilebuf f;
+ f.open(tmp.c_str(), mode);
+ assert(f.is_open()); // since it doesn't exist
+ }
+ }
+# endif
+ }
+#endif // TEST_STD_VER >= 23
+
+ return 0;
}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/fstream.cons/pointer.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/fstream.cons/pointer.pass.cpp
index 63f8b049e69f2cf..18b22d6b214d92b 100644
--- a/libcxx/test/std/input.output/file.streams/fstreams/fstream.cons/pointer.pass.cpp
+++ b/libcxx/test/std/input.output/file.streams/fstreams/fstream.cons/pointer.pass.cpp
@@ -13,6 +13,8 @@
// explicit basic_fstream(const char* s, ios_base::openmode mode = ios_base::in | ios_base::out);
+// XFAIL: LIBCXX-AIX-FIXME
+
#include <fstream>
#include <cassert>
#include "test_macros.h"
@@ -45,5 +47,53 @@ int main(int, char**)
std::remove(temp.c_str());
#endif
- return 0;
+#if TEST_STD_VER >= 23
+ // Test all the noreplace flag combinations
+ {
+ std::ios_base::openmode modes[] = {
+ std::ios_base::out | std::ios_base::noreplace,
+ std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace,
+ std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace,
+ std::ios_base::out | std::ios_base::noreplace | std::ios_base::binary,
+ std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace | std::ios_base::binary,
+ std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace |
+ std::ios_base::binary,
+ };
+ for (auto mode : modes) {
+ std::string tmp = get_temp_file_name(); // also creates the file
+
+ {
+ std::fstream f(tmp.c_str(), mode);
+ assert(!f.is_open()); // since it already exists
+ }
+
+ {
+ std::remove(tmp.c_str());
+
+ std::fstream f(tmp.c_str(), mode);
+ assert(f.is_open()); // since it doesn't exist
+ }
+ }
+
+# ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ for (auto mode : modes) {
+ std::string tmp = get_temp_file_name(); // also creates the file
+
+ {
+ std::wfstream f(tmp.c_str(), mode);
+ assert(!f.is_open()); // since it already exists
+ }
+
+ {
+ std::remove(tmp.c_str());
+
+ std::wfstream f(tmp.c_str(), mode);
+ assert(f.is_open()); // since it doesn't exist
+ }
+ }
+# endif
+ }
+#endif // TEST_STD_VER >= 23
+
+ return 0;
}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/fstream.members/open_pointer.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/fstream.members/open_pointer.pass.cpp
index acfc282d33ef5e2..790b9ef02f90259 100644
--- a/libcxx/test/std/input.output/file.streams/fstreams/fstream.members/open_pointer.pass.cpp
+++ b/libcxx/test/std/input.output/file.streams/fstreams/fstream.members/open_pointer.pass.cpp
@@ -13,6 +13,8 @@
// void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out);
+// XFAIL: LIBCXX-AIX-FIXME
+
#include <fstream>
#include <cassert>
#include "test_macros.h"
@@ -51,5 +53,57 @@ int main(int, char**)
std::remove(temp.c_str());
#endif
- return 0;
+#if TEST_STD_VER >= 23
+ // Test all the noreplace flag combinations
+ {
+ std::ios_base::openmode modes[] = {
+ std::ios_base::out | std::ios_base::noreplace,
+ std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace,
+ std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace,
+ std::ios_base::out | std::ios_base::noreplace | std::ios_base::binary,
+ std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace | std::ios_base::binary,
+ std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace |
+ std::ios_base::binary,
+ };
+ for (auto mode : modes) {
+ std::string tmp = get_temp_file_name(); // also creates the file
+
+ {
+ std::fstream f;
+ f.open(tmp.c_str(), mode);
+ assert(!f.is_open()); // since it already exists
+ }
+
+ {
+ std::remove(tmp.c_str());
+
+ std::fstream f;
+ f.open(tmp.c_str(), mode);
+ assert(f.is_open()); // since it doesn't exist
+ }
+ }
+
+# ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ for (auto mode : modes) {
+ std::string tmp = get_temp_file_name(); // also creates the file
+
+ {
+ std::wfstream f;
+ f.open(tmp.c_str(), mode);
+ assert(!f.is_open()); // since it already exists
+ }
+
+ {
+ std::remove(tmp.c_str());
+
+ std::wfstream f;
+ f.open(tmp.c_str(), mode);
+ assert(f.is_open()); // since it doesn't exist
+ }
+ }
+# endif
+ }
+#endif // TEST_STD_VER >= 23
+
+ return 0;
}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/ofstream.cons/pointer.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/ofstream.cons/pointer.pass.cpp
index b43f0ff8ebd9f7b..23bd07a6560e803 100644
--- a/libcxx/test/std/input.output/file.streams/fstreams/ofstream.cons/pointer.pass.cpp
+++ b/libcxx/test/std/input.output/file.streams/fstreams/ofstream.cons/pointer.pass.cpp
@@ -13,6 +13,8 @@
// explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out);
+// XFAIL: LIBCXX-AIX-FIXME
+
#include <fstream>
#include <cassert>
#include "test_macros.h"
@@ -59,5 +61,53 @@ int main(int, char**)
std::remove(temp.c_str());
#endif
- return 0;
+#if TEST_STD_VER >= 23
+ // Test all the noreplace flag combinations
+ {
+ std::ios_base::openmode modes[] = {
+ std::ios_base::out | std::ios_base::noreplace,
+ std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace,
+ std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace,
+ std::ios_base::out | std::ios_base::noreplace | std::ios_base::binary,
+ std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace | std::ios_base::binary,
+ std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace |
+ std::ios_base::binary,
+ };
+ for (auto mode : modes) {
+ std::string tmp = get_temp_file_name(); // also creates the file
+
+ {
+ std::ofstream f(tmp.c_str(), mode);
+ assert(!f.is_open()); // since it already exists
+ }
+
+ {
+ std::remove(tmp.c_str());
+
+ std::ofstream f(tmp.c_str(), mode);
+ assert(f.is_open()); // since it doesn't exist
+ }
+ }
+
+# ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ for (auto mode : modes) {
+ std::string tmp = get_temp_file_name(); // also creates the file
+
+ {
+ std::wofstream f(tmp.c_str(), mode);
+ assert(!f.is_open()); // since it already exists
+ }
+
+ {
+ std::remove(tmp.c_str());
+
+ std::wofstream f(tmp.c_str(), mode);
+ assert(f.is_open()); // since it doesn't exist
+ }
+ }
+# endif
+ }
+#endif // TEST_STD_VER >= 23
+
+ return 0;
}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/open_pointer.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/open_pointer.pass.cpp
index 6b9d157ef4308b4..b0a68fd4340b759 100644
--- a/libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/open_pointer.pass.cpp
+++ b/libcxx/test/std/input.output/file.streams/fstreams/ofstream.members/open_pointer.pass.cpp
@@ -13,6 +13,8 @@
// void open(const char* s, ios_base::openmode mode = ios_base::out);
+// XFAIL: LIBCXX-AIX-FIXME
+
#include <fstream>
#include <cassert>
#include "test_macros.h"
@@ -59,5 +61,56 @@ int main(int, char**)
std::remove(temp.c_str());
#endif
- return 0;
+#if TEST_STD_VER >= 23
+ // Test all the noreplace flag combinations
+ {
+ std::ios_base::openmode modes[] = {
+ std::ios_base::out | std::ios_base::noreplace,
+ std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace,
+ std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace,
+ std::ios_base::out | std::ios_base::noreplace | std::ios_base::binary,
+ std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace | std::ios_base::binary,
+ std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::noreplace |
+ std::ios_base::binary,
+ };
+ for (auto mode : modes) {
+ std::string tmp = get_temp_file_name(); // also creates the file
+
+ {
+ std::ofstream f;
+ f.open(tmp.c_str(), mode);
+ assert(!f.is_open()); // since it already exists
+ }
+
+ {
+ std::remove(tmp.c_str());
+
+ std::ofstream f;
+ f.open(tmp.c_str(), mode);
+ assert(f.is_open()); // since it doesn't exist
+ }
+ }
+
+# ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ for (auto mode : modes) {
+ std::string tmp = get_temp_file_name(); // also creates the file
+
+ {
+ std::wofstream f;
+ f.open(tmp.c_str(), mode);
+ assert(!f.is_open()); // since it already exists
+ }
+ {
+ std::remove(tmp.c_str());
+
+ std::wofstream f;
+ f.open(tmp.c_str(), mode);
+ assert(f.is_open()); // since it doesn't exist
+ }
+ }
+# endif
+ }
+#endif // TEST_STD_VER >= 23
+
+ return 0;
}
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/ios.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/ios.version.compile.pass.cpp
new file mode 100644
index 000000000000000..f245815eaa40d1b
--- /dev/null
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/ios.version.compile.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// UNSUPPORTED: no-localization
+
+// <ios>
+
+// Test the feature test macros defined by <ios>
+
+/* Constant Value
+ __cpp_lib_ios_noreplace 202207L [C++23]
+*/
+
+#include <ios>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_ios_noreplace
+# error "__cpp_lib_ios_noreplace should not be defined before c++23"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_ios_noreplace
+# error "__cpp_lib_ios_noreplace should not be defined before c++23"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_ios_noreplace
+# error "__cpp_lib_ios_noreplace should not be defined before c++23"
+# endif
+
+#elif TEST_STD_VER == 20
+
+# ifdef __cpp_lib_ios_noreplace
+# error "__cpp_lib_ios_noreplace should not be defined before c++23"
+# endif
+
+#elif TEST_STD_VER == 23
+
+# ifndef __cpp_lib_ios_noreplace
+# error "__cpp_lib_ios_noreplace should be defined in c++23"
+# endif
+# if __cpp_lib_ios_noreplace != 202207L
+# error "__cpp_lib_ios_noreplace should have the value 202207L in c++23"
+# endif
+
+#elif TEST_STD_VER > 23
+
+# ifndef __cpp_lib_ios_noreplace
+# error "__cpp_lib_ios_noreplace should be defined in c++26"
+# endif
+# if __cpp_lib_ios_noreplace != 202207L
+# error "__cpp_lib_ios_noreplace should have the value 202207L in c++26"
+# endif
+
+#endif // TEST_STD_VER > 23
+
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index 1e4ff3b7f864a3f..783f5f6b0058e17 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -114,6 +114,7 @@
__cpp_lib_interpolate 201902L [C++20]
__cpp_lib_invoke 201411L [C++17]
__cpp_lib_invoke_r 202106L [C++23]
+ __cpp_lib_ios_noreplace 202207L [C++23]
__cpp_lib_is_aggregate 201703L [C++17]
__cpp_lib_is_constant_evaluated 201811L [C++20]
__cpp_lib_is_final 201402L [C++14]
@@ -602,6 +603,10 @@
# error "__cpp_lib_invoke_r should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ios_noreplace
+# error "__cpp_lib_ios_noreplace should not be defined before c++23"
+# endif
+
# ifdef __cpp_lib_is_aggregate
# error "__cpp_lib_is_aggregate should not be defined before c++17"
# endif
@@ -1402,6 +1407,10 @@
# error "__cpp_lib_invoke_r should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ios_noreplace
+# error "__cpp_lib_ios_noreplace should not be defined before c++23"
+# endif
+
# ifdef __cpp_lib_is_aggregate
# error "__cpp_lib_is_aggregate should not be defined before c++17"
# endif
@@ -2331,6 +2340,10 @@
# error "__cpp_lib_invoke_r should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ios_noreplace
+# error "__cpp_lib_ios_noreplace should not be defined before c++23"
+# endif
+
# ifndef __cpp_lib_is_aggregate
# error "__cpp_lib_is_aggregate should be defined in c++17"
# endif
@@ -3536,6 +3549,10 @@
# error "__cpp_lib_invoke_r should not be defined before c++23"
# endif
+# ifdef __cpp_lib_ios_noreplace
+# error "__cpp_lib_ios_noreplace should not be defined before c++23"
+# endif
+
# ifndef __cpp_lib_is_aggregate
# error "__cpp_lib_is_aggregate should be defined in c++20"
# endif
@@ -4942,6 +4959,13 @@
# error "__cpp_lib_invoke_r should have the value 202106L in c++23"
# endif
+# ifndef __cpp_lib_ios_noreplace
+# error "__cpp_lib_ios_noreplace should be defined in c++23"
+# endif
+# if __cpp_lib_ios_noreplace != 202207L
+# error "__cpp_lib_ios_noreplace should have the value 202207L in c++23"
+# endif
+
# ifndef __cpp_lib_is_aggregate
# error "__cpp_lib_is_aggregate should be defined in c++23"
# endif
@@ -6645,6 +6669,13 @@
# error "__cpp_lib_invoke_r should have the value 202106L in c++26"
# endif
+# ifndef __cpp_lib_ios_noreplace
+# error "__cpp_lib_ios_noreplace should be defined in c++26"
+# endif
+# if __cpp_lib_ios_noreplace != 202207L
+# error "__cpp_lib_ios_noreplace should have the value 202207L in c++26"
+# endif
+
# ifndef __cpp_lib_is_aggregate
# error "__cpp_lib_is_aggregate should be defined in c++26"
# endif
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 0c07ac432d7c7e4..589845a3c13d781 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -659,6 +659,11 @@ def add_version_header(tc):
"values": {"c++23": 202106},
"headers": ["functional"],
},
+ {
+ "name": "__cpp_lib_ios_noreplace",
+ "values": { "c++23": 202207 },
+ "headers": ["ios"],
+ },
{
"name": "__cpp_lib_is_aggregate",
"values": {"c++17": 201703},
More information about the libcxx-commits
mailing list