Skip to content

Commit 4b50ead

Browse files
H-G-HristovZingam
authored andcommitted
[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 - cplusplus/draft#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 <[email protected]> NOKEYCHECK=True GitOrigin-RevId: 31c9c41873d06f3029ad200c04819e2e9d33c7e7
1 parent 898fd38 commit 4b50ead

File tree

10 files changed

+142
-50
lines changed

10 files changed

+142
-50
lines changed

docs/ReleaseNotes/19.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Implemented Papers
4646
- P2872R3 - Remove ``wstring_convert`` From C++26
4747
- P3142R0 - Printing Blank Lines with ``println`` (as DR against C++23)
4848
- P2944R3 - Comparisons for ``reference_wrapper`` (comparison operators for ``reference_wrapper`` only)
49+
- P2968R2 - Make ``std::ignore`` a first-class object
4950
- P2302R4 - ``std::ranges::contains``
5051
- P1659R3 - ``std::ranges::starts_with`` and ``std::ranges::ends_with``
5152
- P3029R1 - Better ``mdspan``'s CTAD
@@ -74,6 +75,9 @@ Improvements and New Features
7475

7576
- The formatting library is updated to Unicode 15.1.0.
7677

78+
- ``std::ignore``\s ``const __ignore_t& operator=(_Tp&&) const`` was changed to
79+
``const __ignore_type& operator=(const _Tp&) const noexcept`` for all language versions.
80+
7781
Deprecations and Removals
7882
-------------------------
7983

docs/Status/Cxx2cPapers.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
"`P2985R0 <https://wg21.link/P2985R0>`__","LWG","A type trait for detecting virtual base classes","St. Louis June 2024","","",""
7272
"`P0843R14 <https://wg21.link/P0843R14>`__","LWG","``inplace_vector``","St. Louis June 2024","","",""
7373
"`P3235R3 <https://wg21.link/P3235R3>`__","LWG","``std::print`` more types faster with less memory","St. Louis June 2024","","","|format| |DR|"
74-
"`P2968R2 <https://wg21.link/P2968R2>`__","LWG","Make ``std::ignore`` a first-class object","St. Louis June 2024","","",""
74+
"`P2968R2 <https://wg21.link/P2968R2>`__","LWG","Make ``std::ignore`` a first-class object","St. Louis June 2024","|Complete|","19.0",""
7575
"`P2075R6 <https://wg21.link/P2075R6>`__","LWG","Philox as an extension of the C++ RNG engines","St. Louis June 2024","","",""
7676
"`P2422R1 <https://wg21.link/P2422R1>`__","LWG","Remove ``nodiscard`` annotations from the standard library specification","St. Louis June 2024","|Complete| [#note-P2422R1]_","19.0",""
7777
"`P2300R10 <https://wg21.link/P2300R10>`__","LWG","``std::execution``","St. Louis June 2024","","",""

include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,7 @@ set(files
710710
__thread/timed_backoff_policy.h
711711
__tree
712712
__tuple/find_index.h
713+
__tuple/ignore.h
713714
__tuple/make_tuple_types.h
714715
__tuple/sfinae_helpers.h
715716
__tuple/tuple_element.h

include/__tuple/ignore.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef _LIBCPP___TUPLE_IGNORE_H
10+
#define _LIBCPP___TUPLE_IGNORE_H
11+
12+
#include <__config>
13+
14+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
15+
# pragma GCC system_header
16+
#endif
17+
18+
#ifndef _LIBCPP_CXX03_LANG
19+
20+
_LIBCPP_BEGIN_NAMESPACE_STD
21+
22+
struct __ignore_type {
23+
template <class _Tp>
24+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const __ignore_type& operator=(const _Tp&) const noexcept {
25+
return *this;
26+
}
27+
};
28+
29+
# if _LIBCPP_STD_VER >= 17
30+
inline constexpr __ignore_type ignore;
31+
# else
32+
constexpr __ignore_type ignore;
33+
# endif
34+
35+
_LIBCPP_END_NAMESPACE_STD
36+
37+
#endif // _LIBCPP_CXX03_LANG
38+
39+
#endif // _LIBCPP___TUPLE_IGNORE_H

include/module.modulemap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1840,6 +1840,7 @@ module std_private_thread_thread [system] {
18401840
module std_private_thread_timed_backoff_policy [system] { header "__thread/timed_backoff_policy.h" }
18411841

18421842
module std_private_tuple_find_index [system] { header "__tuple/find_index.h" }
1843+
module std_private_tuple_ignore [system] { header "__tuple/ignore.h" }
18431844
module std_private_tuple_make_tuple_types [system] { header "__tuple/make_tuple_types.h" }
18441845
module std_private_tuple_tuple_like_no_subrange [system] {
18451846
header "__tuple/tuple_like_no_subrange.h"

include/tuple

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,12 @@ tuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>; // since C++
132132
template <class Alloc, class ...T>
133133
tuple(allocator_arg_t, Alloc, tuple<T...>) -> tuple<T...>; // since C++17
134134
135-
inline constexpr unspecified ignore;
135+
struct ignore-type { // exposition only // Since C++26
136+
constexpr const ignore-type&
137+
operator=(const auto &) const noexcept
138+
{ return *this; }
139+
};
140+
inline constexpr ignore-type ignore;
136141
137142
template <class... T> tuple<V...> make_tuple(T&&...); // constexpr in C++14
138143
template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14
@@ -215,6 +220,7 @@ template <class... Types>
215220
#include <__memory/allocator_arg_t.h>
216221
#include <__memory/uses_allocator.h>
217222
#include <__tuple/find_index.h>
223+
#include <__tuple/ignore.h>
218224
#include <__tuple/make_tuple_types.h>
219225
#include <__tuple/sfinae_helpers.h>
220226
#include <__tuple/tuple_element.h>
@@ -1112,22 +1118,6 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<_Tp&...> tie(_T
11121118
return tuple<_Tp&...>(__t...);
11131119
}
11141120

1115-
template <class _Up>
1116-
struct __ignore_t {
1117-
template <class _Tp>
1118-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const __ignore_t& operator=(_Tp&&) const {
1119-
return *this;
1120-
}
1121-
};
1122-
1123-
# if _LIBCPP_STD_VER >= 17
1124-
inline constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
1125-
# else
1126-
namespace {
1127-
constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
1128-
} // namespace
1129-
# endif
1130-
11311121
template <class... _Tp>
11321122
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 tuple<typename __unwrap_ref_decay<_Tp>::type...>
11331123
make_tuple(_Tp&&... __t) {

include/utility

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,10 @@ template <class T>
274274
#include <compare>
275275
#include <initializer_list>
276276

277+
// [tuple.creation]
278+
279+
#include <__tuple/ignore.h>
280+
277281
// [tuple.helper]
278282
#include <__tuple/tuple_element.h>
279283
#include <__tuple/tuple_size.h>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03
10+
11+
// <tuple>
12+
13+
// inline constexpr ignore-type ignore;
14+
15+
// std::ignore should be provided by the headers <tuple> and <utility>.
16+
// This test validates its presence in <tuple>.
17+
18+
#include <tuple>
19+
20+
[[maybe_unused]] auto& ignore_v = std::ignore;

test/std/utilities/tuple/tuple.general/ignore.pass.cpp

Lines changed: 45 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,51 +6,64 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
// <tuple>
9+
// UNSUPPORTED: c++03
1010

11-
// constexpr unspecified ignore;
11+
// <tuple>
1212

13-
// UNSUPPORTED: c++03
13+
// inline constexpr ignore-type ignore;
1414

1515
#include <cassert>
16+
#include <cstdint>
1617
#include <tuple>
1718
#include <type_traits>
1819

1920
#include "test_macros.h"
2021

21-
constexpr bool test_ignore_constexpr()
22-
{
23-
#if TEST_STD_VER > 11
24-
{ // Test that std::ignore provides constexpr converting assignment.
25-
auto& res = (std::ignore = 42);
26-
assert(&res == &std::ignore);
27-
}
28-
{ // Test that std::ignore provides constexpr copy/move constructors
29-
auto copy = std::ignore;
30-
auto moved = std::move(copy);
31-
((void)moved);
32-
}
33-
{ // Test that std::ignore provides constexpr copy/move assignment
34-
auto copy = std::ignore;
35-
copy = std::ignore;
36-
auto moved = std::ignore;
37-
moved = std::move(copy);
38-
}
22+
static_assert(std::is_trivial<decltype(std::ignore)>::value, "");
23+
24+
#if TEST_STD_VER >= 17
25+
[[nodiscard]] constexpr int test_nodiscard() { return 8294; }
3926
#endif
40-
return true;
27+
28+
TEST_CONSTEXPR_CXX14 bool test() {
29+
{ [[maybe_unused]] auto& ignore_v = std::ignore; }
30+
31+
{ // Test that std::ignore provides converting assignment.
32+
auto& res = (std::ignore = 42);
33+
static_assert(noexcept(res = (std::ignore = 42)), "Must be noexcept");
34+
assert(&res == &std::ignore);
35+
}
36+
{ // Test bit-field binding.
37+
struct S {
38+
unsigned int bf : 3;
39+
};
40+
S s{0b010};
41+
auto& res = (std::ignore = s.bf);
42+
assert(&res == &std::ignore);
43+
}
44+
{ // Test that std::ignore provides copy/move constructors
45+
auto copy = std::ignore;
46+
[[maybe_unused]] auto moved = std::move(copy);
47+
}
48+
{ // Test that std::ignore provides copy/move assignment
49+
auto copy = std::ignore;
50+
copy = std::ignore;
51+
auto moved = std::ignore;
52+
moved = std::move(copy);
53+
}
54+
55+
#if TEST_STD_VER >= 17
56+
{ std::ignore = test_nodiscard(); }
57+
#endif
58+
59+
return true;
4160
}
4261

4362
int main(int, char**) {
44-
{
45-
constexpr auto& ignore_v = std::ignore;
46-
((void)ignore_v);
47-
}
48-
{
49-
static_assert(test_ignore_constexpr(), "");
50-
}
51-
{
52-
LIBCPP_STATIC_ASSERT(std::is_trivial<decltype(std::ignore)>::value, "");
53-
}
63+
test();
64+
#if TEST_STD_VER >= 14
65+
static_assert(test(), "");
66+
#endif
5467

5568
return 0;
5669
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: c++03
10+
11+
// <utility>
12+
13+
// inline constexpr ignore-type ignore;
14+
15+
// std::ignore should be provided by the headers <tuple> and <utility>.
16+
// This test validates its presence in <utility>.
17+
18+
#include <utility>
19+
20+
[[maybe_unused]] auto& ignore_v = std::ignore;

0 commit comments

Comments
 (0)