[libcxx-commits] [libcxx] 31c9c41 - [libc++][tuple][utility] P2968R2: Make `std::ignore` a first-class object (#97401)

via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jul 10 14:05:26 PDT 2024


Author: Hristo Hristov
Date: 2024-07-11T00:05:23+03:00
New Revision: 31c9c41873d06f3029ad200c04819e2e9d33c7e7

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

LOG: [libc++][tuple][utility] P2968R2: Make `std::ignore` a first-class object (#97401)

Implements:  https://wg21.link/P2968R2

References:
- https://eel.is/c++draft/tuple.general
- https://eel.is/c++draft/tuple.syn
- https://eel.is/c++draft/tuple.creation
- https://github.com/cplusplus/draft/milestone/31
- https://github.com/cplusplus/draft/pull/7109
- https://github.com/cplusplus/papers/issues/1640
- https://cplusplus.github.io/LWG/issue2933
- https://cplusplus.github.io/LWG/issue3978

---------

Co-authored-by: Hristo Hristov <zingam at outlook.com>

Added: 
    libcxx/include/__tuple/ignore.h
    libcxx/test/std/utilities/tuple/tuple.general/ignore.include.compile.pass.cpp
    libcxx/test/std/utilities/utility/ignore/ignore.include.compile.pass.cpp

Modified: 
    libcxx/docs/ReleaseNotes/19.rst
    libcxx/docs/Status/Cxx2cPapers.csv
    libcxx/include/CMakeLists.txt
    libcxx/include/module.modulemap
    libcxx/include/tuple
    libcxx/include/utility
    libcxx/test/std/utilities/tuple/tuple.general/ignore.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/ReleaseNotes/19.rst b/libcxx/docs/ReleaseNotes/19.rst
index 893e418d32d1d..b9c6bc84892c5 100644
--- a/libcxx/docs/ReleaseNotes/19.rst
+++ b/libcxx/docs/ReleaseNotes/19.rst
@@ -46,6 +46,7 @@ Implemented Papers
 - P2872R3 - Remove ``wstring_convert`` From C++26
 - P3142R0 - Printing Blank Lines with ``println`` (as DR against C++23)
 - P2944R3 - Comparisons for ``reference_wrapper`` (comparison operators for ``reference_wrapper`` only)
+- P2968R2 - Make ``std::ignore`` a first-class object
 - P2302R4 - ``std::ranges::contains``
 - P1659R3 - ``std::ranges::starts_with`` and ``std::ranges::ends_with``
 - P3029R1 - Better ``mdspan``'s CTAD
@@ -74,6 +75,9 @@ Improvements and New Features
 
 - The formatting library is updated to Unicode 15.1.0.
 
+- ``std::ignore``\s ``const __ignore_t& operator=(_Tp&&) const`` was changed to
+  ``const __ignore_type& operator=(const _Tp&) const noexcept`` for all language versions.
+
 Deprecations and Removals
 -------------------------
 

diff  --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index 48d45e24a05b2..aea413dd33588 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -71,7 +71,7 @@
 "`P2985R0 <https://wg21.link/P2985R0>`__","LWG","A type trait for detecting virtual base classes","St. Louis June 2024","","",""
 "`P0843R14 <https://wg21.link/P0843R14>`__","LWG","``inplace_vector``","St. Louis June 2024","","",""
 "`P3235R3 <https://wg21.link/P3235R3>`__","LWG","``std::print`` more types faster with less memory","St. Louis June 2024","","","|format| |DR|"
-"`P2968R2 <https://wg21.link/P2968R2>`__","LWG","Make ``std::ignore`` a first-class object","St. Louis June 2024","","",""
+"`P2968R2 <https://wg21.link/P2968R2>`__","LWG","Make ``std::ignore`` a first-class object","St. Louis June 2024","|Complete|","19.0",""
 "`P2075R6 <https://wg21.link/P2075R6>`__","LWG","Philox as an extension of the C++ RNG engines","St. Louis June 2024","","",""
 "`P2422R1 <https://wg21.link/P2422R1>`__","LWG","Remove ``nodiscard`` annotations from the standard library specification","St. Louis June 2024","|Complete| [#note-P2422R1]_","19.0",""
 "`P2300R10 <https://wg21.link/P2300R10>`__","LWG","``std::execution``","St. Louis June 2024","","",""

diff  --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 8d0ffd6ed725b..07dd25604a9c7 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -710,6 +710,7 @@ set(files
   __thread/timed_backoff_policy.h
   __tree
   __tuple/find_index.h
+  __tuple/ignore.h
   __tuple/make_tuple_types.h
   __tuple/sfinae_helpers.h
   __tuple/tuple_element.h

diff  --git a/libcxx/include/__tuple/ignore.h b/libcxx/include/__tuple/ignore.h
new file mode 100644
index 0000000000000..43cce5387411b
--- /dev/null
+++ b/libcxx/include/__tuple/ignore.h
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___TUPLE_IGNORE_H
+#define _LIBCPP___TUPLE_IGNORE_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#ifndef _LIBCPP_CXX03_LANG
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+struct __ignore_type {
+  template <class _Tp>
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const __ignore_type& operator=(const _Tp&) const noexcept {
+    return *this;
+  }
+};
+
+#  if _LIBCPP_STD_VER >= 17
+inline constexpr __ignore_type ignore;
+#  else
+constexpr __ignore_type ignore;
+#  endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_CXX03_LANG
+
+#endif // _LIBCPP___TUPLE_IGNORE_H

diff  --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index 9ffccf66ff094..4ad506781c489 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -1840,6 +1840,7 @@ module std_private_thread_thread               [system] {
 module std_private_thread_timed_backoff_policy [system] { header "__thread/timed_backoff_policy.h" }
 
 module std_private_tuple_find_index             [system] { header "__tuple/find_index.h" }
+module std_private_tuple_ignore                 [system] { header "__tuple/ignore.h" }
 module std_private_tuple_make_tuple_types       [system] { header "__tuple/make_tuple_types.h" }
 module std_private_tuple_tuple_like_no_subrange [system] {
   header "__tuple/tuple_like_no_subrange.h"

diff  --git a/libcxx/include/tuple b/libcxx/include/tuple
index 26652ffe81e9f..081b90c7bbec5 100644
--- a/libcxx/include/tuple
+++ b/libcxx/include/tuple
@@ -132,7 +132,12 @@ tuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>;       // since C++
 template <class Alloc, class ...T>
 tuple(allocator_arg_t, Alloc, tuple<T...>) -> tuple<T...>;          // since C++17
 
-inline constexpr unspecified ignore;
+struct ignore-type { // exposition only                             // Since C++26
+  constexpr const ignore-type&
+    operator=(const auto &) const noexcept
+      { return *this; }
+};
+inline constexpr ignore-type ignore;
 
 template <class... T> tuple<V...>  make_tuple(T&&...); // constexpr in C++14
 template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14
@@ -215,6 +220,7 @@ template <class... Types>
 #include <__memory/allocator_arg_t.h>
 #include <__memory/uses_allocator.h>
 #include <__tuple/find_index.h>
+#include <__tuple/ignore.h>
 #include <__tuple/make_tuple_types.h>
 #include <__tuple/sfinae_helpers.h>
 #include <__tuple/tuple_element.h>
@@ -1112,22 +1118,6 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<_Tp&...> tie(_T
   return tuple<_Tp&...>(__t...);
 }
 
-template <class _Up>
-struct __ignore_t {
-  template <class _Tp>
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const __ignore_t& operator=(_Tp&&) const {
-    return *this;
-  }
-};
-
-#  if _LIBCPP_STD_VER >= 17
-inline constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
-#  else
-namespace {
-constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
-} // namespace
-#  endif
-
 template <class... _Tp>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<typename __unwrap_ref_decay<_Tp>::type...>
 make_tuple(_Tp&&... __t) {

diff  --git a/libcxx/include/utility b/libcxx/include/utility
index 90713da621c5d..f2f0052df2755 100644
--- a/libcxx/include/utility
+++ b/libcxx/include/utility
@@ -274,6 +274,10 @@ template <class T>
 #include <compare>
 #include <initializer_list>
 
+// [tuple.creation]
+
+#include <__tuple/ignore.h>
+
 // [tuple.helper]
 #include <__tuple/tuple_element.h>
 #include <__tuple/tuple_size.h>

diff  --git a/libcxx/test/std/utilities/tuple/tuple.general/ignore.include.compile.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.general/ignore.include.compile.pass.cpp
new file mode 100644
index 0000000000000..0fdf0d0af52b9
--- /dev/null
+++ b/libcxx/test/std/utilities/tuple/tuple.general/ignore.include.compile.pass.cpp
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <tuple>
+
+// inline constexpr ignore-type ignore;
+
+// std::ignore should be provided by the headers <tuple> and <utility>.
+// This test validates its presence in <tuple>.
+
+#include <tuple>
+
+[[maybe_unused]] auto& ignore_v = std::ignore;

diff  --git a/libcxx/test/std/utilities/tuple/tuple.general/ignore.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.general/ignore.pass.cpp
index 769c55e10fc43..525ffde5cf177 100644
--- a/libcxx/test/std/utilities/tuple/tuple.general/ignore.pass.cpp
+++ b/libcxx/test/std/utilities/tuple/tuple.general/ignore.pass.cpp
@@ -6,51 +6,64 @@
 //
 //===----------------------------------------------------------------------===//
 
-// <tuple>
+// UNSUPPORTED: c++03
 
-// constexpr unspecified ignore;
+// <tuple>
 
-// UNSUPPORTED: c++03
+// inline constexpr ignore-type ignore;
 
 #include <cassert>
+#include <cstdint>
 #include <tuple>
 #include <type_traits>
 
 #include "test_macros.h"
 
-constexpr bool test_ignore_constexpr()
-{
-#if TEST_STD_VER > 11
-    { // Test that std::ignore provides constexpr converting assignment.
-        auto& res = (std::ignore = 42);
-        assert(&res == &std::ignore);
-    }
-    { // Test that std::ignore provides constexpr copy/move constructors
-        auto copy = std::ignore;
-        auto moved = std::move(copy);
-        ((void)moved);
-    }
-    { // Test that std::ignore provides constexpr copy/move assignment
-        auto copy = std::ignore;
-        copy = std::ignore;
-        auto moved = std::ignore;
-        moved = std::move(copy);
-    }
+static_assert(std::is_trivial<decltype(std::ignore)>::value, "");
+
+#if TEST_STD_VER >= 17
+[[nodiscard]] constexpr int test_nodiscard() { return 8294; }
 #endif
-    return true;
+
+TEST_CONSTEXPR_CXX14 bool test() {
+  { [[maybe_unused]] auto& ignore_v = std::ignore; }
+
+  { // Test that std::ignore provides converting assignment.
+    auto& res = (std::ignore = 42);
+    static_assert(noexcept(res = (std::ignore = 42)), "Must be noexcept");
+    assert(&res == &std::ignore);
+  }
+  { // Test bit-field binding.
+    struct S {
+      unsigned int bf : 3;
+    };
+    S s{0b010};
+    auto& res = (std::ignore = s.bf);
+    assert(&res == &std::ignore);
+  }
+  { // Test that std::ignore provides copy/move constructors
+    auto copy                   = std::ignore;
+    [[maybe_unused]] auto moved = std::move(copy);
+  }
+  { // Test that std::ignore provides copy/move assignment
+    auto copy  = std::ignore;
+    copy       = std::ignore;
+    auto moved = std::ignore;
+    moved      = std::move(copy);
+  }
+
+#if TEST_STD_VER >= 17
+  { std::ignore = test_nodiscard(); }
+#endif
+
+  return true;
 }
 
 int main(int, char**) {
-    {
-        constexpr auto& ignore_v = std::ignore;
-        ((void)ignore_v);
-    }
-    {
-        static_assert(test_ignore_constexpr(), "");
-    }
-    {
-        LIBCPP_STATIC_ASSERT(std::is_trivial<decltype(std::ignore)>::value, "");
-    }
+  test();
+#if TEST_STD_VER >= 14
+  static_assert(test(), "");
+#endif
 
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/utility/ignore/ignore.include.compile.pass.cpp b/libcxx/test/std/utilities/utility/ignore/ignore.include.compile.pass.cpp
new file mode 100644
index 0000000000000..3aa74397acf20
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/ignore/ignore.include.compile.pass.cpp
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// <utility>
+
+// inline constexpr ignore-type ignore;
+
+// std::ignore should be provided by the headers <tuple> and <utility>.
+// This test validates its presence in <utility>.
+
+#include <utility>
+
+[[maybe_unused]] auto& ignore_v = std::ignore;


        


More information about the libcxx-commits mailing list