[libcxx-commits] [libcxx] [libc++] Refactor __tuple_like and __pair_like (PR #85206)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Mar 17 12:07:43 PDT 2024
https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/85206
>From 04af17fe0e7002c59f80497cde7ca60a3436bb46 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Thu, 14 Mar 2024 12:10:03 +0100
Subject: [PATCH] [libc++] Refactor __tuple_like and __pair_like
---
libcxx/include/CMakeLists.txt | 2 +-
.../__memory/uses_allocator_construction.h | 12 +---
.../__memory_resource/polymorphic_allocator.h | 1 +
libcxx/include/__ranges/subrange.h | 8 +--
libcxx/include/__tuple/pair_like.h | 32 ----------
libcxx/include/__tuple/tuple_like.h | 33 +++-------
.../include/__tuple/tuple_like_no_subrange.h | 60 +++++++++++++++++++
libcxx/include/__utility/pair.h | 27 +++------
libcxx/include/module.modulemap | 27 ++++-----
libcxx/include/variant | 1 +
10 files changed, 101 insertions(+), 102 deletions(-)
delete mode 100644 libcxx/include/__tuple/pair_like.h
create mode 100644 libcxx/include/__tuple/tuple_like_no_subrange.h
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 63adc03fae2980..6a142ae0f69853 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -703,12 +703,12 @@ set(files
__tree
__tuple/find_index.h
__tuple/make_tuple_types.h
- __tuple/pair_like.h
__tuple/sfinae_helpers.h
__tuple/tuple_element.h
__tuple/tuple_indices.h
__tuple/tuple_like.h
__tuple/tuple_like_ext.h
+ __tuple/tuple_like_no_subrange.h
__tuple/tuple_size.h
__tuple/tuple_types.h
__type_traits/add_const.h
diff --git a/libcxx/include/__memory/uses_allocator_construction.h b/libcxx/include/__memory/uses_allocator_construction.h
index 71ae5bcd323315..9b7262bec5cf8b 100644
--- a/libcxx/include/__memory/uses_allocator_construction.h
+++ b/libcxx/include/__memory/uses_allocator_construction.h
@@ -12,7 +12,7 @@
#include <__config>
#include <__memory/construct_at.h>
#include <__memory/uses_allocator.h>
-#include <__tuple/pair_like.h>
+#include <__tuple/tuple_like_no_subrange.h>
#include <__type_traits/enable_if.h>
#include <__type_traits/is_same.h>
#include <__type_traits/remove_cv.h>
@@ -128,11 +128,7 @@ __uses_allocator_construction_args(const _Alloc& __alloc, const pair<_Up, _Vp>&&
std::forward_as_tuple(std::get<1>(std::move(__pair))));
}
-template < class _Pair,
- class _Alloc,
- __pair_like _PairLike,
- __enable_if_t<__is_cv_std_pair<_Pair> && !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value,
- int> = 0>
+template <class _Pair, class _Alloc, __pair_like_no_subrange _PairLike, __enable_if_t<__is_cv_std_pair<_Pair>, int> = 0>
_LIBCPP_HIDE_FROM_ABI constexpr auto
__uses_allocator_construction_args(const _Alloc& __alloc, _PairLike&& __p) noexcept {
return std::__uses_allocator_construction_args<_Pair>(
@@ -161,9 +157,7 @@ inline constexpr bool __convertible_to_const_pair_ref =
# if _LIBCPP_STD_VER >= 23
template <class _Tp, class _Up>
inline constexpr bool __uses_allocator_constraints =
- __is_cv_std_pair<_Tp> &&
- (__is_specialization_of_subrange<remove_cvref_t<_Up>>::value ||
- (!__pair_like<_Up> && !__convertible_to_const_pair_ref<_Up>));
+ __is_cv_std_pair<_Tp> && !__pair_like_no_subrange<_Up> && !__convertible_to_const_pair_ref<_Up>;
# else
template <class _Tp, class _Up>
inline constexpr bool __uses_allocator_constraints = __is_cv_std_pair<_Tp> && !__convertible_to_const_pair_ref<_Up>;
diff --git a/libcxx/include/__memory_resource/polymorphic_allocator.h b/libcxx/include/__memory_resource/polymorphic_allocator.h
index cfd07bc84fe8aa..823c1503c22b65 100644
--- a/libcxx/include/__memory_resource/polymorphic_allocator.h
+++ b/libcxx/include/__memory_resource/polymorphic_allocator.h
@@ -12,6 +12,7 @@
#include <__assert>
#include <__availability>
#include <__config>
+#include <__fwd/pair.h>
#include <__memory_resource/memory_resource.h>
#include <__utility/exception_guard.h>
#include <cstddef>
diff --git a/libcxx/include/__ranges/subrange.h b/libcxx/include/__ranges/subrange.h
index bb4411cf355497..f356f86ee0b4b5 100644
--- a/libcxx/include/__ranges/subrange.h
+++ b/libcxx/include/__ranges/subrange.h
@@ -28,8 +28,9 @@
#include <__ranges/enable_borrowed_range.h>
#include <__ranges/size.h>
#include <__ranges/view_interface.h>
-#include <__tuple/pair_like.h>
#include <__tuple/tuple_element.h>
+#include <__tuple/tuple_like.h>
+#include <__tuple/tuple_like_no_subrange.h>
#include <__tuple/tuple_size.h>
#include <__type_traits/conditional.h>
#include <__type_traits/decay.h>
@@ -64,7 +65,7 @@ concept __convertible_to_non_slicing =
template <class _Pair, class _Iter, class _Sent>
concept __pair_like_convertible_from =
- !range<_Pair> && __pair_like<_Pair> && constructible_from<_Pair, _Iter, _Sent> &&
+ !range<_Pair> && __pair_like_no_subrange<_Pair> && constructible_from<_Pair, _Iter, _Sent> &&
__convertible_to_non_slicing<_Iter, tuple_element_t<0, _Pair>> && convertible_to<_Sent, tuple_element_t<1, _Pair>>;
template <input_or_output_iterator _Iter,
@@ -125,8 +126,7 @@ class _LIBCPP_TEMPLATE_VIS subrange : public view_interface<subrange<_Iter, _Sen
requires(_Kind == subrange_kind::sized)
: subrange(ranges::begin(__range), ranges::end(__range), __n) {}
- template <__different_from<subrange> _Pair>
- requires __pair_like_convertible_from<_Pair, const _Iter&, const _Sent&>
+ template <__pair_like_convertible_from<const _Iter&, const _Sent&> _Pair>
_LIBCPP_HIDE_FROM_ABI constexpr operator _Pair() const {
return _Pair(__begin_, __end_);
}
diff --git a/libcxx/include/__tuple/pair_like.h b/libcxx/include/__tuple/pair_like.h
deleted file mode 100644
index 192682dc7eb598..00000000000000
--- a/libcxx/include/__tuple/pair_like.h
+++ /dev/null
@@ -1,32 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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_PAIR_LIKE_H
-#define _LIBCPP___TUPLE_PAIR_LIKE_H
-
-#include <__config>
-#include <__tuple/tuple_like.h>
-#include <__tuple/tuple_size.h>
-#include <__type_traits/remove_cvref.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 _Tp>
-concept __pair_like = __tuple_like<_Tp> && tuple_size<remove_cvref_t<_Tp>>::value == 2;
-
-#endif // _LIBCPP_STD_VER >= 20
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___TUPLE_PAIR_LIKE_H
diff --git a/libcxx/include/__tuple/tuple_like.h b/libcxx/include/__tuple/tuple_like.h
index 967e4a543c0318..cc5c0ce4ba4d20 100644
--- a/libcxx/include/__tuple/tuple_like.h
+++ b/libcxx/include/__tuple/tuple_like.h
@@ -10,12 +10,9 @@
#define _LIBCPP___TUPLE_TUPLE_LIKE_H
#include <__config>
-#include <__fwd/array.h>
-#include <__fwd/complex.h>
-#include <__fwd/pair.h>
#include <__fwd/subrange.h>
-#include <__fwd/tuple.h>
-#include <__type_traits/integral_constant.h>
+#include <__tuple/tuple_like_no_subrange.h>
+#include <__tuple/tuple_size.h>
#include <__type_traits/remove_cvref.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -26,30 +23,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20
+# if _LIBCPP_STD_VER >= 23
template <class _Tp>
-struct __tuple_like_impl : false_type {};
-
-template <class... _Tp>
-struct __tuple_like_impl<tuple<_Tp...> > : true_type {};
-
-template <class _T1, class _T2>
-struct __tuple_like_impl<pair<_T1, _T2> > : true_type {};
-
-template <class _Tp, size_t _Size>
-struct __tuple_like_impl<array<_Tp, _Size> > : true_type {};
-
-template <class _Ip, class _Sp, ranges::subrange_kind _Kp>
-struct __tuple_like_impl<ranges::subrange<_Ip, _Sp, _Kp> > : true_type {};
-
-# if _LIBCPP_STD_VER >= 26
-
-template <class _Tp>
-struct __tuple_like_impl<complex<_Tp>> : true_type {};
+inline constexpr bool __is_ranges_subrange_v = false;
+template <class _Iter, class _Sent, ranges::subrange_kind _Kind>
+inline constexpr bool __is_ranges_subrange_v<ranges::subrange<_Iter, _Sent, _Kind>> = true;
# endif
template <class _Tp>
-concept __tuple_like = __tuple_like_impl<remove_cvref_t<_Tp>>::value;
+concept __tuple_like = __tuple_like_no_subrange<_Tp> || __is_ranges_subrange_v<remove_cvref_t<_Tp>>;
+
+// If the exposition-only type trait `pair-like` is required, you most likely want __pair_like_no_subrange.
#endif // _LIBCPP_STD_VER >= 20
diff --git a/libcxx/include/__tuple/tuple_like_no_subrange.h b/libcxx/include/__tuple/tuple_like_no_subrange.h
new file mode 100644
index 00000000000000..d0f97f3a107705
--- /dev/null
+++ b/libcxx/include/__tuple/tuple_like_no_subrange.h
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_TUPLE_LIKE_NO_SUBRANGE_H
+#define _LIBCPP___TUPLE_TUPLE_LIKE_NO_SUBRANGE_H
+
+#include <__config>
+#include <__fwd/array.h>
+#include <__fwd/complex.h>
+#include <__fwd/pair.h>
+#include <__fwd/tuple.h>
+#include <__tuple/tuple_size.h>
+#include <__type_traits/remove_cvref.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 20
+
+template <class _Tp>
+inline constexpr bool __tuple_like_no_subrange_impl = false;
+
+template <class... _Tp>
+inline constexpr bool __tuple_like_no_subrange_impl<tuple<_Tp...>> = true;
+
+template <class _T1, class _T2>
+inline constexpr bool __tuple_like_no_subrange_impl<pair<_T1, _T2>> = true;
+
+template <class _Tp, size_t _Size>
+inline constexpr bool __tuple_like_no_subrange_impl<array<_Tp, _Size>> = true;
+
+# if _LIBCPP_STD_VER >= 26
+
+template <class _Tp>
+inline constexpr bool __tuple_like_no_subrange_impl<complex<_Tp>> = true;
+
+# endif
+
+template <class _Tp>
+concept __tuple_like_no_subrange = __tuple_like_no_subrange_impl<remove_cvref_t<_Tp>>;
+
+// This is equivalent to the exposition-only type trait `pair-like`, except that it is false for specializations of
+// `ranges::subrange`. This is removed, because every use of `pair-like` excludes `ranges::subrange`.
+template <class _Tp>
+concept __pair_like_no_subrange = __tuple_like_no_subrange<_Tp> && tuple_size<remove_cvref_t<_Tp>>::value == 2;
+
+#endif // _LIBCPP_STD_VER >= 20
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___TUPLE_TUPLE_LIKE_NO_SUBRANGE_H
diff --git a/libcxx/include/__utility/pair.h b/libcxx/include/__utility/pair.h
index b488a9829c3849..71b3f177460357 100644
--- a/libcxx/include/__utility/pair.h
+++ b/libcxx/include/__utility/pair.h
@@ -15,12 +15,11 @@
#include <__config>
#include <__fwd/array.h>
#include <__fwd/pair.h>
-#include <__fwd/subrange.h>
#include <__fwd/tuple.h>
-#include <__tuple/pair_like.h>
#include <__tuple/sfinae_helpers.h>
#include <__tuple/tuple_element.h>
#include <__tuple/tuple_indices.h>
+#include <__tuple/tuple_like_no_subrange.h>
#include <__tuple/tuple_size.h>
#include <__type_traits/common_reference.h>
#include <__type_traits/common_type.h>
@@ -67,14 +66,6 @@ struct __non_trivially_copyable_base {
__non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {}
};
-#if _LIBCPP_STD_VER >= 23
-template <class _Tp>
-struct __is_specialization_of_subrange : false_type {};
-
-template <class _Iter, class _Sent, ranges::subrange_kind _Kind>
-struct __is_specialization_of_subrange<ranges::subrange<_Iter, _Sent, _Kind>> : true_type {};
-#endif
-
template <class _T1, class _T2>
struct _LIBCPP_TEMPLATE_VIS pair
#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
@@ -208,19 +199,19 @@ struct _LIBCPP_TEMPLATE_VIS pair
# endif
# if _LIBCPP_STD_VER >= 23
+ // TODO: Remove this workaround in LLVM 20. The bug got fixed in Clang 18.
// This is a workaround for http://llvm.org/PR60710. We should be able to remove it once Clang is fixed.
template <class _PairLike>
_LIBCPP_HIDE_FROM_ABI static constexpr bool __pair_like_explicit_wknd() {
- if constexpr (__pair_like<_PairLike>) {
+ if constexpr (__pair_like_no_subrange<_PairLike>) {
return !is_convertible_v<decltype(std::get<0>(std::declval<_PairLike&&>())), first_type> ||
!is_convertible_v<decltype(std::get<1>(std::declval<_PairLike&&>())), second_type>;
}
return false;
}
- template <__pair_like _PairLike>
- requires(!__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value &&
- is_constructible_v<first_type, decltype(std::get<0>(std::declval<_PairLike &&>()))> &&
+ template <__pair_like_no_subrange _PairLike>
+ requires(is_constructible_v<first_type, decltype(std::get<0>(std::declval<_PairLike &&>()))> &&
is_constructible_v<second_type, decltype(std::get<1>(std::declval<_PairLike &&>()))>)
_LIBCPP_HIDE_FROM_ABI constexpr explicit(__pair_like_explicit_wknd<_PairLike>()) pair(_PairLike&& __p)
: first(std::get<0>(std::forward<_PairLike>(__p))), second(std::get<1>(std::forward<_PairLike>(__p))) {}
@@ -313,8 +304,8 @@ struct _LIBCPP_TEMPLATE_VIS pair
return *this;
}
- template <__pair_like _PairLike>
- requires(__different_from<_PairLike, pair> && !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value &&
+ template <__pair_like_no_subrange _PairLike>
+ requires(__different_from<_PairLike, pair> &&
is_assignable_v<first_type&, decltype(std::get<0>(std::declval<_PairLike>()))> &&
is_assignable_v<second_type&, decltype(std::get<1>(std::declval<_PairLike>()))>)
_LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(_PairLike&& __p) {
@@ -323,8 +314,8 @@ struct _LIBCPP_TEMPLATE_VIS pair
return *this;
}
- template <__pair_like _PairLike>
- requires(__different_from<_PairLike, pair> && !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value &&
+ template <__pair_like_no_subrange _PairLike>
+ requires(__different_from<_PairLike, pair> &&
is_assignable_v<first_type const&, decltype(std::get<0>(std::declval<_PairLike>()))> &&
is_assignable_v<second_type const&, decltype(std::get<1>(std::declval<_PairLike>()))>)
_LIBCPP_HIDE_FROM_ABI constexpr pair const& operator=(_PairLike&& __p) const {
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index 0bd2831b7f159c..431d3876723061 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -1799,20 +1799,19 @@ 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_make_tuple_types [system] { header "__tuple/make_tuple_types.h" }
-module std_private_tuple_pair_like [system] {
- header "__tuple/pair_like.h"
- export std_private_tuple_tuple_like
-}
-module std_private_tuple_sfinae_helpers [system] { header "__tuple/sfinae_helpers.h" }
-module std_private_tuple_tuple_element [system] { header "__tuple/tuple_element.h" }
-module std_private_tuple_tuple_fwd [system] { header "__fwd/tuple.h" }
-module std_private_tuple_tuple_indices [system] { header "__tuple/tuple_indices.h" }
-module std_private_tuple_tuple_like [system] { header "__tuple/tuple_like.h" }
-module std_private_tuple_tuple_like_ext [system] { header "__tuple/tuple_like_ext.h" }
-module std_private_tuple_tuple_size [system] { header "__tuple/tuple_size.h" }
-module std_private_tuple_tuple_types [system] { header "__tuple/tuple_types.h" }
+module std_private_tuple_find_index [system] { header "__tuple/find_index.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"
+}
+module std_private_tuple_sfinae_helpers [system] { header "__tuple/sfinae_helpers.h" }
+module std_private_tuple_tuple_element [system] { header "__tuple/tuple_element.h" }
+module std_private_tuple_tuple_fwd [system] { header "__fwd/tuple.h" }
+module std_private_tuple_tuple_indices [system] { header "__tuple/tuple_indices.h" }
+module std_private_tuple_tuple_like [system] { header "__tuple/tuple_like.h" }
+module std_private_tuple_tuple_like_ext [system] { header "__tuple/tuple_like_ext.h" }
+module std_private_tuple_tuple_size [system] { header "__tuple/tuple_size.h" }
+module std_private_tuple_tuple_types [system] { header "__tuple/tuple_types.h" }
module std_private_type_traits_add_const [system] { header "__type_traits/add_const.h" }
module std_private_type_traits_add_cv [system] { header "__type_traits/add_cv.h" }
diff --git a/libcxx/include/variant b/libcxx/include/variant
index 25d47ec79defa7..5db66c1aa63208 100644
--- a/libcxx/include/variant
+++ b/libcxx/include/variant
@@ -242,6 +242,7 @@ namespace std {
#include <__type_traits/is_trivially_move_constructible.h>
#include <__type_traits/is_void.h>
#include <__type_traits/remove_const.h>
+#include <__type_traits/remove_cvref.h>
#include <__type_traits/type_identity.h>
#include <__type_traits/void_t.h>
#include <__utility/declval.h>
More information about the libcxx-commits
mailing list