Skip to content

Commit 26c7130

Browse files
committed
[libc++] Refactor __tuple_like and __pair_like
1 parent 6854f6f commit 26c7130

File tree

13 files changed

+105
-104
lines changed

13 files changed

+105
-104
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,12 +703,12 @@ set(files
703703
__tree
704704
__tuple/find_index.h
705705
__tuple/make_tuple_types.h
706-
__tuple/pair_like.h
707706
__tuple/sfinae_helpers.h
708707
__tuple/tuple_element.h
709708
__tuple/tuple_indices.h
710709
__tuple/tuple_like.h
711710
__tuple/tuple_like_ext.h
711+
__tuple/tuple_like_no_subrange.h
712712
__tuple/tuple_size.h
713713
__tuple/tuple_types.h
714714
__type_traits/add_const.h

libcxx/include/__memory/uses_allocator_construction.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include <__config>
1313
#include <__memory/construct_at.h>
1414
#include <__memory/uses_allocator.h>
15-
#include <__tuple/pair_like.h>
15+
#include <__tuple/tuple_like_no_subrange.h>
1616
#include <__type_traits/enable_if.h>
1717
#include <__type_traits/is_same.h>
1818
#include <__type_traits/remove_cv.h>
@@ -128,11 +128,7 @@ __uses_allocator_construction_args(const _Alloc& __alloc, const pair<_Up, _Vp>&&
128128
std::forward_as_tuple(std::get<1>(std::move(__pair))));
129129
}
130130

131-
template < class _Pair,
132-
class _Alloc,
133-
__pair_like _PairLike,
134-
__enable_if_t<__is_cv_std_pair<_Pair> && !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value,
135-
int> = 0>
131+
template <class _Pair, class _Alloc, __pair_like_no_subrange _PairLike, __enable_if_t<__is_cv_std_pair<_Pair>, int> = 0>
136132
_LIBCPP_HIDE_FROM_ABI constexpr auto
137133
__uses_allocator_construction_args(const _Alloc& __alloc, _PairLike&& __p) noexcept {
138134
return std::__uses_allocator_construction_args<_Pair>(
@@ -161,9 +157,7 @@ inline constexpr bool __convertible_to_const_pair_ref =
161157
# if _LIBCPP_STD_VER >= 23
162158
template <class _Tp, class _Up>
163159
inline constexpr bool __uses_allocator_constraints =
164-
__is_cv_std_pair<_Tp> &&
165-
(__is_specialization_of_subrange<remove_cvref_t<_Up>>::value ||
166-
(!__pair_like<_Up> && !__convertible_to_const_pair_ref<_Up>));
160+
__is_cv_std_pair<_Tp> && !__pair_like_no_subrange<_Up> && !__convertible_to_const_pair_ref<_Up>;
167161
# else
168162
template <class _Tp, class _Up>
169163
inline constexpr bool __uses_allocator_constraints = __is_cv_std_pair<_Tp> && !__convertible_to_const_pair_ref<_Up>;

libcxx/include/__memory_resource/polymorphic_allocator.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <__assert>
1313
#include <__availability>
1414
#include <__config>
15+
#include <__fwd/pair.h>
1516
#include <__memory_resource/memory_resource.h>
1617
#include <__utility/exception_guard.h>
1718
#include <cstddef>

libcxx/include/__ranges/subrange.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@
2828
#include <__ranges/enable_borrowed_range.h>
2929
#include <__ranges/size.h>
3030
#include <__ranges/view_interface.h>
31-
#include <__tuple/pair_like.h>
3231
#include <__tuple/tuple_element.h>
32+
#include <__tuple/tuple_like.h>
33+
#include <__tuple/tuple_like_no_subrange.h>
3334
#include <__tuple/tuple_size.h>
3435
#include <__type_traits/conditional.h>
3536
#include <__type_traits/decay.h>
@@ -64,7 +65,7 @@ concept __convertible_to_non_slicing =
6465

6566
template <class _Pair, class _Iter, class _Sent>
6667
concept __pair_like_convertible_from =
67-
!range<_Pair> && __pair_like<_Pair> && constructible_from<_Pair, _Iter, _Sent> &&
68+
!range<_Pair> && __pair_like_no_subrange<_Pair> && constructible_from<_Pair, _Iter, _Sent> &&
6869
__convertible_to_non_slicing<_Iter, tuple_element_t<0, _Pair>> && convertible_to<_Sent, tuple_element_t<1, _Pair>>;
6970

7071
template <input_or_output_iterator _Iter,
@@ -125,8 +126,7 @@ class _LIBCPP_TEMPLATE_VIS subrange : public view_interface<subrange<_Iter, _Sen
125126
requires(_Kind == subrange_kind::sized)
126127
: subrange(ranges::begin(__range), ranges::end(__range), __n) {}
127128

128-
template <__different_from<subrange> _Pair>
129-
requires __pair_like_convertible_from<_Pair, const _Iter&, const _Sent&>
129+
template <__pair_like_convertible_from<const _Iter&, const _Sent&> _Pair>
130130
_LIBCPP_HIDE_FROM_ABI constexpr operator _Pair() const {
131131
return _Pair(__begin_, __end_);
132132
}

libcxx/include/__tuple/pair_like.h

Lines changed: 0 additions & 32 deletions
This file was deleted.

libcxx/include/__tuple/tuple_like.h

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,9 @@
1010
#define _LIBCPP___TUPLE_TUPLE_LIKE_H
1111

1212
#include <__config>
13-
#include <__fwd/array.h>
14-
#include <__fwd/complex.h>
15-
#include <__fwd/pair.h>
1613
#include <__fwd/subrange.h>
17-
#include <__fwd/tuple.h>
18-
#include <__type_traits/integral_constant.h>
14+
#include <__tuple/tuple_like_no_subrange.h>
15+
#include <__tuple/tuple_size.h>
1916
#include <__type_traits/remove_cvref.h>
2017

2118
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -27,29 +24,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2724
#if _LIBCPP_STD_VER >= 20
2825

2926
template <class _Tp>
30-
struct __tuple_like_impl : false_type {};
27+
inline constexpr bool __is_ranges_subrange_v = false;
3128

32-
template <class... _Tp>
33-
struct __tuple_like_impl<tuple<_Tp...> > : true_type {};
34-
35-
template <class _T1, class _T2>
36-
struct __tuple_like_impl<pair<_T1, _T2> > : true_type {};
37-
38-
template <class _Tp, size_t _Size>
39-
struct __tuple_like_impl<array<_Tp, _Size> > : true_type {};
40-
41-
template <class _Ip, class _Sp, ranges::subrange_kind _Kp>
42-
struct __tuple_like_impl<ranges::subrange<_Ip, _Sp, _Kp> > : true_type {};
43-
44-
# if _LIBCPP_STD_VER >= 26
29+
template <class _Iter, class _Sent, ranges::subrange_kind _Kind>
30+
inline constexpr bool __is_ranges_subrange_v<ranges::subrange<_Iter, _Sent, _Kind>> = true;
4531

4632
template <class _Tp>
47-
struct __tuple_like_impl<complex<_Tp>> : true_type {};
48-
49-
# endif
33+
concept __tuple_like = __tuple_like_no_subrange<_Tp> || __is_ranges_subrange_v<remove_cvref_t<_Tp>>;
5034

51-
template <class _Tp>
52-
concept __tuple_like = __tuple_like_impl<remove_cvref_t<_Tp>>::value;
35+
// If the exposition-only type trait `pair-like` is required, you most likely want __pair_like_no_subrange.
5336

5437
#endif // _LIBCPP_STD_VER >= 20
5538

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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_TUPLE_LIKE_NO_SUBRANGE_H
10+
#define _LIBCPP___TUPLE_TUPLE_LIKE_NO_SUBRANGE_H
11+
12+
#include <__config>
13+
#include <__fwd/array.h>
14+
#include <__fwd/complex.h>
15+
#include <__fwd/pair.h>
16+
#include <__fwd/tuple.h>
17+
#include <__tuple/tuple_size.h>
18+
#include <__type_traits/remove_cvref.h>
19+
#include <cstddef>
20+
21+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22+
# pragma GCC system_header
23+
#endif
24+
25+
_LIBCPP_BEGIN_NAMESPACE_STD
26+
27+
#if _LIBCPP_STD_VER >= 20
28+
29+
template <class _Tp>
30+
inline constexpr bool __tuple_like_no_subrange_impl = false;
31+
32+
template <class... _Tp>
33+
inline constexpr bool __tuple_like_no_subrange_impl<tuple<_Tp...>> = true;
34+
35+
template <class _T1, class _T2>
36+
inline constexpr bool __tuple_like_no_subrange_impl<pair<_T1, _T2>> = true;
37+
38+
template <class _Tp, size_t _Size>
39+
inline constexpr bool __tuple_like_no_subrange_impl<array<_Tp, _Size>> = true;
40+
41+
# if _LIBCPP_STD_VER >= 26
42+
43+
template <class _Tp>
44+
inline constexpr bool __tuple_like_no_subrange_impl<complex<_Tp>> = true;
45+
46+
# endif
47+
48+
template <class _Tp>
49+
concept __tuple_like_no_subrange = __tuple_like_no_subrange_impl<remove_cvref_t<_Tp>>;
50+
51+
// This is equivalent to the exposition-only type trait `pair-like`, except that it is false for specializations of
52+
// `ranges::subrange`. This is removed, because every use of `pair-like` excludes `ranges::subrange`.
53+
template <class _Tp>
54+
concept __pair_like_no_subrange = __tuple_like_no_subrange<_Tp> && tuple_size<remove_cvref_t<_Tp>>::value == 2;
55+
56+
#endif // _LIBCPP_STD_VER >= 20
57+
58+
_LIBCPP_END_NAMESPACE_STD
59+
60+
#endif // _LIBCPP___TUPLE_TUPLE_LIKE_NO_SUBRANGE_H

libcxx/include/__utility/pair.h

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,11 @@
1515
#include <__config>
1616
#include <__fwd/array.h>
1717
#include <__fwd/pair.h>
18-
#include <__fwd/subrange.h>
1918
#include <__fwd/tuple.h>
20-
#include <__tuple/pair_like.h>
2119
#include <__tuple/sfinae_helpers.h>
2220
#include <__tuple/tuple_element.h>
2321
#include <__tuple/tuple_indices.h>
22+
#include <__tuple/tuple_like_no_subrange.h>
2423
#include <__tuple/tuple_size.h>
2524
#include <__type_traits/common_reference.h>
2625
#include <__type_traits/common_type.h>
@@ -60,14 +59,6 @@ struct __non_trivially_copyable_base {
6059
__non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {}
6160
};
6261

63-
#if _LIBCPP_STD_VER >= 23
64-
template <class _Tp>
65-
struct __is_specialization_of_subrange : false_type {};
66-
67-
template <class _Iter, class _Sent, ranges::subrange_kind _Kind>
68-
struct __is_specialization_of_subrange<ranges::subrange<_Iter, _Sent, _Kind>> : true_type {};
69-
#endif
70-
7162
template <class _T1, class _T2>
7263
struct _LIBCPP_TEMPLATE_VIS pair
7364
#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
@@ -201,19 +192,19 @@ struct _LIBCPP_TEMPLATE_VIS pair
201192
# endif
202193

203194
# if _LIBCPP_STD_VER >= 23
195+
// TODO: Remove this workaround in LLVM 20. The bug got fixed in Clang 18.
204196
// This is a workaround for http://llvm.org/PR60710. We should be able to remove it once Clang is fixed.
205197
template <class _PairLike>
206198
_LIBCPP_HIDE_FROM_ABI static constexpr bool __pair_like_explicit_wknd() {
207-
if constexpr (__pair_like<_PairLike>) {
199+
if constexpr (__pair_like_no_subrange<_PairLike>) {
208200
return !is_convertible_v<decltype(std::get<0>(std::declval<_PairLike&&>())), first_type> ||
209201
!is_convertible_v<decltype(std::get<1>(std::declval<_PairLike&&>())), second_type>;
210202
}
211203
return false;
212204
}
213205

214-
template <__pair_like _PairLike>
215-
requires(!__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value &&
216-
is_constructible_v<first_type, decltype(std::get<0>(std::declval<_PairLike &&>()))> &&
206+
template <__pair_like_no_subrange _PairLike>
207+
requires(is_constructible_v<first_type, decltype(std::get<0>(std::declval<_PairLike &&>()))> &&
217208
is_constructible_v<second_type, decltype(std::get<1>(std::declval<_PairLike &&>()))>)
218209
_LIBCPP_HIDE_FROM_ABI constexpr explicit(__pair_like_explicit_wknd<_PairLike>()) pair(_PairLike&& __p)
219210
: first(std::get<0>(std::forward<_PairLike>(__p))), second(std::get<1>(std::forward<_PairLike>(__p))) {}
@@ -306,8 +297,8 @@ struct _LIBCPP_TEMPLATE_VIS pair
306297
return *this;
307298
}
308299

309-
template <__pair_like _PairLike>
310-
requires(__different_from<_PairLike, pair> && !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value &&
300+
template <__pair_like_no_subrange _PairLike>
301+
requires(__different_from<_PairLike, pair> &&
311302
is_assignable_v<first_type&, decltype(std::get<0>(std::declval<_PairLike>()))> &&
312303
is_assignable_v<second_type&, decltype(std::get<1>(std::declval<_PairLike>()))>)
313304
_LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(_PairLike&& __p) {
@@ -316,8 +307,8 @@ struct _LIBCPP_TEMPLATE_VIS pair
316307
return *this;
317308
}
318309

319-
template <__pair_like _PairLike>
320-
requires(__different_from<_PairLike, pair> && !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value &&
310+
template <__pair_like_no_subrange _PairLike>
311+
requires(__different_from<_PairLike, pair> &&
321312
is_assignable_v<first_type const&, decltype(std::get<0>(std::declval<_PairLike>()))> &&
322313
is_assignable_v<second_type const&, decltype(std::get<1>(std::declval<_PairLike>()))>)
323314
_LIBCPP_HIDE_FROM_ABI constexpr pair const& operator=(_PairLike&& __p) const {

libcxx/include/libcxx.imp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -699,12 +699,12 @@
699699
{ include: [ "<__thread/timed_backoff_policy.h>", "private", "<thread>", "public" ] },
700700
{ include: [ "<__tuple/find_index.h>", "private", "<tuple>", "public" ] },
701701
{ include: [ "<__tuple/make_tuple_types.h>", "private", "<tuple>", "public" ] },
702-
{ include: [ "<__tuple/pair_like.h>", "private", "<tuple>", "public" ] },
703702
{ include: [ "<__tuple/sfinae_helpers.h>", "private", "<tuple>", "public" ] },
704703
{ include: [ "<__tuple/tuple_element.h>", "private", "<tuple>", "public" ] },
705704
{ include: [ "<__tuple/tuple_indices.h>", "private", "<tuple>", "public" ] },
706705
{ include: [ "<__tuple/tuple_like.h>", "private", "<tuple>", "public" ] },
707706
{ include: [ "<__tuple/tuple_like_ext.h>", "private", "<tuple>", "public" ] },
707+
{ include: [ "<__tuple/tuple_like_no_subrange.h>", "private", "<tuple>", "public" ] },
708708
{ include: [ "<__tuple/tuple_size.h>", "private", "<tuple>", "public" ] },
709709
{ include: [ "<__tuple/tuple_types.h>", "private", "<tuple>", "public" ] },
710710
{ include: [ "<__type_traits/add_const.h>", "private", "<type_traits>", "public" ] },

libcxx/include/module.modulemap

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,20 +1799,22 @@ module std_private_thread_thread [system] {
17991799
}
18001800
module std_private_thread_timed_backoff_policy [system] { header "__thread/timed_backoff_policy.h" }
18011801

1802-
module std_private_tuple_find_index [system] { header "__tuple/find_index.h" }
1803-
module std_private_tuple_make_tuple_types [system] { header "__tuple/make_tuple_types.h" }
1804-
module std_private_tuple_pair_like [system] {
1805-
header "__tuple/pair_like.h"
1806-
export std_private_tuple_tuple_like
1807-
}
1808-
module std_private_tuple_sfinae_helpers [system] { header "__tuple/sfinae_helpers.h" }
1809-
module std_private_tuple_tuple_element [system] { header "__tuple/tuple_element.h" }
1810-
module std_private_tuple_tuple_fwd [system] { header "__fwd/tuple.h" }
1811-
module std_private_tuple_tuple_indices [system] { header "__tuple/tuple_indices.h" }
1812-
module std_private_tuple_tuple_like [system] { header "__tuple/tuple_like.h" }
1813-
module std_private_tuple_tuple_like_ext [system] { header "__tuple/tuple_like_ext.h" }
1814-
module std_private_tuple_tuple_size [system] { header "__tuple/tuple_size.h" }
1815-
module std_private_tuple_tuple_types [system] { header "__tuple/tuple_types.h" }
1802+
module std_private_tuple_find_index [system] { header "__tuple/find_index.h" }
1803+
module std_private_tuple_make_tuple_types [system] { header "__tuple/make_tuple_types.h" }
1804+
module std_private_tuple_tuple_like_no_subrange [system] {
1805+
header "__tuple/tuple_like_no_subrange.h"
1806+
}
1807+
module std_private_tuple_sfinae_helpers [system] { header "__tuple/sfinae_helpers.h" }
1808+
module std_private_tuple_tuple_element [system] { header "__tuple/tuple_element.h" }
1809+
module std_private_tuple_tuple_fwd [system] { header "__fwd/tuple.h" }
1810+
module std_private_tuple_tuple_indices [system] { header "__tuple/tuple_indices.h" }
1811+
module std_private_tuple_tuple_like [system] {
1812+
header "__tuple/tuple_like.h"
1813+
export *
1814+
}
1815+
module std_private_tuple_tuple_like_ext [system] { header "__tuple/tuple_like_ext.h" }
1816+
module std_private_tuple_tuple_size [system] { header "__tuple/tuple_size.h" }
1817+
module std_private_tuple_tuple_types [system] { header "__tuple/tuple_types.h" }
18161818

18171819
module std_private_type_traits_add_const [system] { header "__type_traits/add_const.h" }
18181820
module std_private_type_traits_add_cv [system] { header "__type_traits/add_cv.h" }

libcxx/include/variant

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,13 @@ namespace std {
235235
#include <__type_traits/is_destructible.h>
236236
#include <__type_traits/is_nothrow_assignable.h>
237237
#include <__type_traits/is_nothrow_constructible.h>
238+
#include <__type_traits/is_reference.h>
238239
#include <__type_traits/is_trivially_assignable.h>
239240
#include <__type_traits/is_trivially_constructible.h>
240241
#include <__type_traits/is_trivially_destructible.h>
241242
#include <__type_traits/is_void.h>
242243
#include <__type_traits/remove_const.h>
244+
#include <__type_traits/remove_cvref.h>
243245
#include <__type_traits/type_identity.h>
244246
#include <__type_traits/void_t.h>
245247
#include <__utility/declval.h>

libcxx/test/libcxx/utilities/tuple/__tuple_like.compile.pass.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
// template<class T>
1616
// concept tuple-like; // exposition only
1717

18+
#include <__tuple/tuple_like.h>
1819
#include <array>
1920
#include <complex>
2021
#include <ranges>

libcxx/test/std/ranges/range.adaptors/range.elements/range.concept.compile.pass.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ static_assert(!std::ranges::input_range<Range<cpp20_output_iterator<std::tuple<i
5252
static_assert(!HasElementsView<Range<cpp20_output_iterator<std::tuple<int>*>>, 0>);
5353

5454
// !tuple-like
55-
LIBCPP_STATIC_ASSERT(!std::__tuple_like<int>);
5655
static_assert(!HasElementsView<Range<int*>, 1>);
5756

5857
// !(N < tuple_size_v<T>)

0 commit comments

Comments
 (0)