[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@outlook.com>
This commit is contained in:
parent
eb66e31bc2
commit
31c9c41873
@ -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
|
||||
-------------------------
|
||||
|
||||
|
@ -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","","",""
|
||||
|
|
@ -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
|
||||
|
39
libcxx/include/__tuple/ignore.h
Normal file
39
libcxx/include/__tuple/ignore.h
Normal file
@ -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
|
@ -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"
|
||||
|
@ -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) {
|
||||
|
@ -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>
|
||||
|
@ -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;
|
@ -6,51 +6,64 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <tuple>
|
||||
|
||||
// constexpr unspecified ignore;
|
||||
|
||||
// UNSUPPORTED: c++03
|
||||
|
||||
// <tuple>
|
||||
|
||||
// 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.
|
||||
static_assert(std::is_trivial<decltype(std::ignore)>::value, "");
|
||||
|
||||
#if TEST_STD_VER >= 17
|
||||
[[nodiscard]] constexpr int test_nodiscard() { return 8294; }
|
||||
#endif
|
||||
|
||||
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 that std::ignore provides constexpr copy/move constructors
|
||||
auto copy = std::ignore;
|
||||
auto moved = std::move(copy);
|
||||
((void)moved);
|
||||
{ // 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 constexpr copy/move assignment
|
||||
{ // 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;
|
||||
}
|
||||
|
@ -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;
|
Loading…
x
Reference in New Issue
Block a user