[libcxx-commits] [libcxx] 3a49cff - [libc++] Implement P2445R1 (`std::forward_like`)

Igor Zhukov via libcxx-commits libcxx-commits at lists.llvm.org
Fri Sep 2 19:22:42 PDT 2022


Author: Igor Zhukov
Date: 2022-09-03T09:17:53+07:00
New Revision: 3a49cffe3add478c2381ed79c56e1e105dd0fa16

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

LOG: [libc++] Implement P2445R1 (`std::forward_like`)

Co-authored-by: A. Jiang <de34 at live.cn>

Reviewed By: philnik, huixie90, #libc

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

Added: 
    libcxx/include/__utility/forward_like.h
    libcxx/test/std/utilities/utility/forward_like/forward_like.msvc/test.cpp
    libcxx/test/std/utilities/utility/forward_like/forward_like.msvc/test.pass.cpp

Modified: 
    libcxx/docs/FeatureTestMacroTable.rst
    libcxx/docs/ReleaseNotes.rst
    libcxx/docs/Status/Cxx2bPapers.csv
    libcxx/include/CMakeLists.txt
    libcxx/include/module.modulemap.in
    libcxx/include/utility
    libcxx/include/version
    libcxx/test/libcxx/private_headers.verify.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/utility.version.compile.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 0ffd44dbb33c7..88605787ab839 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -314,6 +314,8 @@ Status
     ------------------------------------------------- -----------------
     ``__cpp_lib_constexpr_typeinfo``                  *unimplemented*
     ------------------------------------------------- -----------------
+    ``__cpp_lib_forward_like``                        ``202207L``
+    ------------------------------------------------- -----------------
     ``__cpp_lib_invoke_r``                            *unimplemented*
     ------------------------------------------------- -----------------
     ``__cpp_lib_is_scoped_enum``                      ``202011L``

diff  --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst
index 8d11c1bc2285d..5c1585254d820 100644
--- a/libcxx/docs/ReleaseNotes.rst
+++ b/libcxx/docs/ReleaseNotes.rst
@@ -39,6 +39,7 @@ Implemented Papers
 ------------------
 - P2499R0 - ``string_view`` range constructor should be ``explicit``
 - P2417R2 - A more constexpr bitset
+- P2445R1 - ``std::forward_like``
 
 Improvements and New Features
 -----------------------------

diff  --git a/libcxx/docs/Status/Cxx2bPapers.csv b/libcxx/docs/Status/Cxx2bPapers.csv
index 40a03bb914bf1..cbf0db4bd794e 100644
--- a/libcxx/docs/Status/Cxx2bPapers.csv
+++ b/libcxx/docs/Status/Cxx2bPapers.csv
@@ -72,7 +72,7 @@
 "`P2417R2 <https://wg21.link/P2417R2>`__","LWG","A more ``constexpr`` ``bitset``","July 2022","|Complete|","16.0"
 "`P2419R2 <https://wg21.link/P2419R2>`__","LWG","Clarify handling of encodings in localized formatting of chrono types","July 2022","",""
 "`P2438R2 <https://wg21.link/P2438R2>`__","LWG","``std::string::substr() &&``","July 2022","",""
-"`P2445R1 <https://wg21.link/P2445R1>`__","LWG","``forward_like``","July 2022","",""
+"`P2445R1 <https://wg21.link/P2445R1>`__","LWG","``forward_like``","July 2022","|Complete|","16.0"
 "`P2446R2 <https://wg21.link/P2446R2>`__","LWG","``views::as_rvalue``","July 2022","",""
 "`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","",""

diff  --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index c07497fdc1ae3..e72b42cd5a050 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -649,6 +649,7 @@ set(files
   __utility/declval.h
   __utility/exchange.h
   __utility/forward.h
+  __utility/forward_like.h
   __utility/in_place.h
   __utility/integer_sequence.h
   __utility/move.h

diff  --git a/libcxx/include/__utility/forward_like.h b/libcxx/include/__utility/forward_like.h
new file mode 100644
index 0000000000000..780976992b09e
--- /dev/null
+++ b/libcxx/include/__utility/forward_like.h
@@ -0,0 +1,45 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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 _LIBCPP___UTILITY_FORWARD_LIKE_H
+#define _LIBCPP___UTILITY_FORWARD_LIKE_H
+
+#include <__config>
+#include <__type_traits/conditional.h>
+#include <__type_traits/is_const.h>
+#include <__type_traits/is_reference.h>
+#include <__type_traits/remove_reference.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER > 20
+
+template <class _Ap, class _Bp>
+using _CopyConst = _If<is_const_v<_Ap>, const _Bp, _Bp>;
+
+template <class _Ap, class _Bp>
+using _OverrideRef = _If<is_rvalue_reference_v<_Ap>, remove_reference_t<_Bp>&&, _Bp&>;
+
+template <class _Ap, class _Bp>
+using _ForwardLike = _OverrideRef<_Ap&&, _CopyConst<remove_reference_t<_Ap>, remove_reference_t<_Bp>>>;
+
+template <class _Tp, class _Up>
+[[nodiscard]] constexpr auto forward_like(_Up&& __ux) noexcept -> _ForwardLike<_Tp, _Up> {
+  return static_cast<_ForwardLike<_Tp, _Up>>(__ux);
+}
+
+#endif // _LIBCPP_STD_VER > 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___UTILITY_FORWARD_LIKE_H

diff  --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 5ac7b1c1537c4..e9f8cdc82f558 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1265,6 +1265,7 @@ module std [system] {
       module declval             { private header "__utility/declval.h" }
       module exchange            { private header "__utility/exchange.h" }
       module forward             { private header "__utility/forward.h" }
+      module forward_like        { private header "__utility/forward_like.h" }
       module in_place            { private header "__utility/in_place.h" }
       module integer_sequence    { private header "__utility/integer_sequence.h" }
       module move                { private header "__utility/move.h" }

diff  --git a/libcxx/include/utility b/libcxx/include/utility
index 9462b833b07c5..d3a9aa492d4e8 100644
--- a/libcxx/include/utility
+++ b/libcxx/include/utility
@@ -42,6 +42,10 @@ swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b)));
 template <class T> T&& forward(typename remove_reference<T>::type& t) noexcept;  // constexpr in C++14
 template <class T> T&& forward(typename remove_reference<T>::type&& t) noexcept; // constexpr in C++14
 
+template <typename T>
+[[nodiscard]] constexpr
+auto forward_like(auto&& x) noexcept -> see below;                               // since C++23
+
 template <class T> typename remove_reference<T>::type&& move(T&&) noexcept;      // constexpr in C++14
 
 template <class T>
@@ -229,6 +233,7 @@ template <class T>
 #include <__utility/declval.h>
 #include <__utility/exchange.h>
 #include <__utility/forward.h>
+#include <__utility/forward_like.h>
 #include <__utility/in_place.h>
 #include <__utility/integer_sequence.h>
 #include <__utility/move.h>

diff  --git a/libcxx/include/version b/libcxx/include/version
index e0c388fc40400..3c24a6d7b9dfb 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -82,6 +82,7 @@ __cpp_lib_execution                                     201902L <execution>
                                                         201603L // C++17
 __cpp_lib_filesystem                                    201703L <filesystem>
 __cpp_lib_format                                        202106L <format>
+__cpp_lib_forward_like                                  202207L <utility>
 __cpp_lib_gcd_lcm                                       201606L <numeric>
 __cpp_lib_generic_associative_lookup                    201304L <map> <set>
 __cpp_lib_generic_unordered_lookup                      201811L <unordered_map> <unordered_set>
@@ -384,6 +385,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_constexpr_bitset                     202207L
 // # define __cpp_lib_constexpr_cmath                      202202L
 // # define __cpp_lib_constexpr_typeinfo                   202106L
+# define __cpp_lib_forward_like                         202207L
 // # define __cpp_lib_invoke_r                             202106L
 # define __cpp_lib_is_scoped_enum                       202011L
 // # define __cpp_lib_move_only_function                   202110L

diff  --git a/libcxx/test/libcxx/private_headers.verify.cpp b/libcxx/test/libcxx/private_headers.verify.cpp
index c2c42f785c24b..c822992e38c0a 100644
--- a/libcxx/test/libcxx/private_headers.verify.cpp
+++ b/libcxx/test/libcxx/private_headers.verify.cpp
@@ -660,6 +660,7 @@ END-SCRIPT
 #include <__utility/declval.h> // expected-error@*:* {{use of private header from outside its module: '__utility/declval.h'}}
 #include <__utility/exchange.h> // expected-error@*:* {{use of private header from outside its module: '__utility/exchange.h'}}
 #include <__utility/forward.h> // expected-error@*:* {{use of private header from outside its module: '__utility/forward.h'}}
+#include <__utility/forward_like.h> // expected-error@*:* {{use of private header from outside its module: '__utility/forward_like.h'}}
 #include <__utility/in_place.h> // expected-error@*:* {{use of private header from outside its module: '__utility/in_place.h'}}
 #include <__utility/integer_sequence.h> // expected-error@*:* {{use of private header from outside its module: '__utility/integer_sequence.h'}}
 #include <__utility/move.h> // expected-error@*:* {{use of private header from outside its module: '__utility/move.h'}}

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/utility.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/utility.version.compile.pass.cpp
index 96eb793d1d2ef..a4f06bce07cd6 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/utility.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/utility.version.compile.pass.cpp
@@ -19,6 +19,7 @@
     __cpp_lib_as_const                        201510L [C++17]
     __cpp_lib_constexpr_utility               201811L [C++20]
     __cpp_lib_exchange_function               201304L [C++14]
+    __cpp_lib_forward_like                    202207L [C++2b]
     __cpp_lib_integer_comparison_functions    202002L [C++20]
     __cpp_lib_integer_sequence                201304L [C++14]
     __cpp_lib_ranges_zip                      202110L [C++2b]
@@ -44,6 +45,10 @@
 #   error "__cpp_lib_exchange_function should not be defined before c++14"
 # endif
 
+# ifdef __cpp_lib_forward_like
+#   error "__cpp_lib_forward_like should not be defined before c++2b"
+# endif
+
 # ifdef __cpp_lib_integer_comparison_functions
 #   error "__cpp_lib_integer_comparison_functions should not be defined before c++20"
 # endif
@@ -85,6 +90,10 @@
 #   error "__cpp_lib_exchange_function should have the value 201304L in c++14"
 # endif
 
+# ifdef __cpp_lib_forward_like
+#   error "__cpp_lib_forward_like should not be defined before c++2b"
+# endif
+
 # ifdef __cpp_lib_integer_comparison_functions
 #   error "__cpp_lib_integer_comparison_functions should not be defined before c++20"
 # endif
@@ -135,6 +144,10 @@
 #   error "__cpp_lib_exchange_function should have the value 201304L in c++17"
 # endif
 
+# ifdef __cpp_lib_forward_like
+#   error "__cpp_lib_forward_like should not be defined before c++2b"
+# endif
+
 # ifdef __cpp_lib_integer_comparison_functions
 #   error "__cpp_lib_integer_comparison_functions should not be defined before c++20"
 # endif
@@ -188,6 +201,10 @@
 #   error "__cpp_lib_exchange_function should have the value 201304L in c++20"
 # endif
 
+# ifdef __cpp_lib_forward_like
+#   error "__cpp_lib_forward_like should not be defined before c++2b"
+# endif
+
 # ifndef __cpp_lib_integer_comparison_functions
 #   error "__cpp_lib_integer_comparison_functions should be defined in c++20"
 # endif
@@ -244,6 +261,13 @@
 #   error "__cpp_lib_exchange_function should have the value 201304L in c++2b"
 # endif
 
+# ifndef __cpp_lib_forward_like
+#   error "__cpp_lib_forward_like should be defined in c++2b"
+# endif
+# if __cpp_lib_forward_like != 202207L
+#   error "__cpp_lib_forward_like should have the value 202207L in c++2b"
+# endif
+
 # ifndef __cpp_lib_integer_comparison_functions
 #   error "__cpp_lib_integer_comparison_functions should be defined in c++2b"
 # endif

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 8eaab46e0e5ef..d3ac7b7dc002d 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
@@ -76,6 +76,7 @@
                                                    201902L [C++20]
     __cpp_lib_filesystem                           201703L [C++17]
     __cpp_lib_format                               202106L [C++20]
+    __cpp_lib_forward_like                         202207L [C++2b]
     __cpp_lib_gcd_lcm                              201606L [C++17]
     __cpp_lib_generic_associative_lookup           201304L [C++14]
     __cpp_lib_generic_unordered_lookup             201811L [C++20]
@@ -417,6 +418,10 @@
 #   error "__cpp_lib_format should not be defined before c++20"
 # endif
 
+# ifdef __cpp_lib_forward_like
+#   error "__cpp_lib_forward_like should not be defined before c++2b"
+# endif
+
 # ifdef __cpp_lib_gcd_lcm
 #   error "__cpp_lib_gcd_lcm should not be defined before c++17"
 # endif
@@ -1052,6 +1057,10 @@
 #   error "__cpp_lib_format should not be defined before c++20"
 # endif
 
+# ifdef __cpp_lib_forward_like
+#   error "__cpp_lib_forward_like should not be defined before c++2b"
+# endif
+
 # ifdef __cpp_lib_gcd_lcm
 #   error "__cpp_lib_gcd_lcm should not be defined before c++17"
 # endif
@@ -1801,6 +1810,10 @@
 #   error "__cpp_lib_format should not be defined before c++20"
 # endif
 
+# ifdef __cpp_lib_forward_like
+#   error "__cpp_lib_forward_like should not be defined before c++2b"
+# endif
+
 # ifndef __cpp_lib_gcd_lcm
 #   error "__cpp_lib_gcd_lcm should be defined in c++17"
 # endif
@@ -2847,6 +2860,10 @@
 #   endif
 # endif
 
+# ifdef __cpp_lib_forward_like
+#   error "__cpp_lib_forward_like should not be defined before c++2b"
+# endif
+
 # ifndef __cpp_lib_gcd_lcm
 #   error "__cpp_lib_gcd_lcm should be defined in c++20"
 # endif
@@ -4085,6 +4102,13 @@
 #   endif
 # endif
 
+# ifndef __cpp_lib_forward_like
+#   error "__cpp_lib_forward_like should be defined in c++2b"
+# endif
+# if __cpp_lib_forward_like != 202207L
+#   error "__cpp_lib_forward_like should have the value 202207L in c++2b"
+# endif
+
 # ifndef __cpp_lib_gcd_lcm
 #   error "__cpp_lib_gcd_lcm should be defined in c++2b"
 # endif

diff  --git a/libcxx/test/std/utilities/utility/forward_like/forward_like.msvc/test.cpp b/libcxx/test/std/utilities/utility/forward_like/forward_like.msvc/test.cpp
new file mode 100644
index 0000000000000..f010e7cb674b6
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/forward_like/forward_like.msvc/test.cpp
@@ -0,0 +1,111 @@
+// Copyright (c) Microsoft Corporation.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#include <cassert>
+#include <type_traits>
+#include <utility>
+
+using namespace std;
+
+struct U {}; // class type so const-qualification is not stripped from a prvalue
+using CU = const U;
+using T  = int;
+using CT = const T;
+
+U u{};
+const U& cu = u;
+
+static_assert(is_same_v<decltype(forward_like<T>(U{})), U&&>);
+static_assert(is_same_v<decltype(forward_like<T>(CU{})), CU&&>);
+static_assert(is_same_v<decltype(forward_like<T>(u)), U&&>);
+static_assert(is_same_v<decltype(forward_like<T>(cu)), CU&&>);
+static_assert(is_same_v<decltype(forward_like<T>(std::move(u))), U&&>);
+static_assert(is_same_v<decltype(forward_like<T>(std::move(cu))), CU&&>);
+
+static_assert(is_same_v<decltype(forward_like<CT>(U{})), CU&&>);
+static_assert(is_same_v<decltype(forward_like<CT>(CU{})), CU&&>);
+static_assert(is_same_v<decltype(forward_like<CT>(u)), CU&&>);
+static_assert(is_same_v<decltype(forward_like<CT>(cu)), CU&&>);
+static_assert(is_same_v<decltype(forward_like<CT>(std::move(u))), CU&&>);
+static_assert(is_same_v<decltype(forward_like<CT>(std::move(cu))), CU&&>);
+
+static_assert(is_same_v<decltype(forward_like<T&>(U{})), U&>);
+static_assert(is_same_v<decltype(forward_like<T&>(CU{})), CU&>);
+static_assert(is_same_v<decltype(forward_like<T&>(u)), U&>);
+static_assert(is_same_v<decltype(forward_like<T&>(cu)), CU&>);
+static_assert(is_same_v<decltype(forward_like<T&>(std::move(u))), U&>);
+static_assert(is_same_v<decltype(forward_like<T&>(std::move(cu))), CU&>);
+
+static_assert(is_same_v<decltype(forward_like<CT&>(U{})), CU&>);
+static_assert(is_same_v<decltype(forward_like<CT&>(CU{})), CU&>);
+static_assert(is_same_v<decltype(forward_like<CT&>(u)), CU&>);
+static_assert(is_same_v<decltype(forward_like<CT&>(cu)), CU&>);
+static_assert(is_same_v<decltype(forward_like<CT&>(std::move(u))), CU&>);
+static_assert(is_same_v<decltype(forward_like<CT&>(std::move(cu))), CU&>);
+
+static_assert(is_same_v<decltype(forward_like<T&&>(U{})), U&&>);
+static_assert(is_same_v<decltype(forward_like<T&&>(CU{})), CU&&>);
+static_assert(is_same_v<decltype(forward_like<T&&>(u)), U&&>);
+static_assert(is_same_v<decltype(forward_like<T&&>(cu)), CU&&>);
+static_assert(is_same_v<decltype(forward_like<T&&>(std::move(u))), U&&>);
+static_assert(is_same_v<decltype(forward_like<T&&>(std::move(cu))), CU&&>);
+
+static_assert(is_same_v<decltype(forward_like<CT&&>(U{})), CU&&>);
+static_assert(is_same_v<decltype(forward_like<CT&&>(CU{})), CU&&>);
+static_assert(is_same_v<decltype(forward_like<CT&&>(u)), CU&&>);
+static_assert(is_same_v<decltype(forward_like<CT&&>(cu)), CU&&>);
+static_assert(is_same_v<decltype(forward_like<CT&&>(std::move(u))), CU&&>);
+static_assert(is_same_v<decltype(forward_like<CT&&>(std::move(cu))), CU&&>);
+
+static_assert(noexcept(forward_like<T>(u)));
+
+static_assert(is_same_v<decltype(forward_like<U&>(u)), U&>);
+static_assert(is_same_v<decltype(forward_like<CU&>(cu)), CU&>);
+static_assert(is_same_v<decltype(forward_like<U&&>(std::move(u))), U&&>);
+static_assert(is_same_v<decltype(forward_like<CU&&>(std::move(cu))), CU&&>);
+
+struct NoCtorCopyMove {
+  NoCtorCopyMove() = delete;
+  NoCtorCopyMove(const NoCtorCopyMove&) = delete;
+  NoCtorCopyMove(NoCtorCopyMove&&) = delete;
+};
+
+static_assert(is_same_v<decltype(forward_like<CT&&>(declval<NoCtorCopyMove>())), const NoCtorCopyMove&&>);
+static_assert(is_same_v<decltype(forward_like<CT&>(declval<NoCtorCopyMove>())), const NoCtorCopyMove&>);
+static_assert(is_same_v<decltype(forward_like<T&&>(declval<NoCtorCopyMove>())), NoCtorCopyMove&&>);
+static_assert(is_same_v<decltype(forward_like<T&>(declval<NoCtorCopyMove>())), NoCtorCopyMove&>);
+
+static_assert(noexcept(forward_like<T>(declval<NoCtorCopyMove>())));
+
+constexpr bool test() {
+  {
+    int val       = 1729;
+    auto&& result = forward_like<const double&>(val);
+    static_assert(is_same_v<decltype(result), const int&>);
+    assert(&result == &val);
+  }
+  {
+    int val       = 1729;
+    auto&& result = forward_like<double&>(val);
+    static_assert(is_same_v<decltype(result), int&>);
+    assert(&result == &val);
+  }
+  {
+    int val       = 1729;
+    auto&& result = forward_like<const double&&>(val);
+    static_assert(is_same_v<decltype(result), const int&&>);
+    assert(&result == &val);
+  }
+  {
+    int val       = 1729;
+    auto&& result = forward_like<double&&>(val);
+    static_assert(is_same_v<decltype(result), int&&>);
+    assert(&result == &val);
+  }
+  return true;
+}
+
+int main() {
+  assert(test());
+  static_assert(test());
+}

diff  --git a/libcxx/test/std/utilities/utility/forward_like/forward_like.msvc/test.pass.cpp b/libcxx/test/std/utilities/utility/forward_like/forward_like.msvc/test.pass.cpp
new file mode 100644
index 0000000000000..629d82fcfd79d
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/forward_like/forward_like.msvc/test.pass.cpp
@@ -0,0 +1,13 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
+
+// Includes Microsoft's test that tests the entire header.
+
+#include "test.cpp"

diff  --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 27e2d23f7da66..38b04d261e484 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -322,6 +322,10 @@ def add_version_header(tc):
     "headers": ["format"],
     "test_suite_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)",
     "libcxx_guard": "!defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)",
+  }, {
+    "name": "__cpp_lib_forward_like",
+    "values": { "c++2b": 202207 },
+    "headers": ["utility"],
   }, {
     "name": "__cpp_lib_gcd_lcm",
     "values": { "c++17": 201606 },


        


More information about the libcxx-commits mailing list