diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 07b5e974eaf52..b935e45151e9e 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -709,12 +709,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/__algorithm/mismatch.h b/libcxx/include/__algorithm/mismatch.h index d933a84cada9e..1cb83b01b2ebe 100644 --- a/libcxx/include/__algorithm/mismatch.h +++ b/libcxx/include/__algorithm/mismatch.h @@ -18,10 +18,12 @@ #include <__type_traits/invoke.h> #include <__type_traits/is_constant_evaluated.h> #include <__type_traits/is_equality_comparable.h> +#include <__type_traits/is_integral.h> #include <__type_traits/operation_traits.h> #include <__utility/move.h> #include <__utility/pair.h> #include <__utility/unreachable.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header diff --git a/libcxx/include/__memory/uses_allocator_construction.h b/libcxx/include/__memory/uses_allocator_construction.h index 71ae5bcd32331..9b7262bec5cf8 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>::value, - int> = 0> +template , 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 inline constexpr bool __uses_allocator_constraints = - __is_cv_std_pair<_Tp> && - (__is_specialization_of_subrange>::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 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 cfd07bc84fe8a..823c1503c22b6 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 diff --git a/libcxx/include/__ranges/subrange.h b/libcxx/include/__ranges/subrange.h index bb4411cf35549..051bc31139014 100644 --- a/libcxx/include/__ranges/subrange.h +++ b/libcxx/include/__ranges/subrange.h @@ -28,8 +28,8 @@ #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_no_subrange.h> #include <__tuple/tuple_size.h> #include <__type_traits/conditional.h> #include <__type_traits/decay.h> @@ -64,7 +64,7 @@ concept __convertible_to_non_slicing = template 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 _Pair> - requires __pair_like_convertible_from<_Pair, const _Iter&, const _Sent&> + template <__pair_like_convertible_from _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 192682dc7eb59..0000000000000 --- 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 -concept __pair_like = __tuple_like<_Tp> && tuple_size>::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 967e4a543c031..c080a3dcf1e25 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) @@ -27,29 +24,16 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 template -struct __tuple_like_impl : false_type {}; +inline constexpr bool __is_ranges_subrange_v = false; -template -struct __tuple_like_impl > : true_type {}; - -template -struct __tuple_like_impl > : true_type {}; - -template -struct __tuple_like_impl > : true_type {}; - -template -struct __tuple_like_impl > : true_type {}; - -# if _LIBCPP_STD_VER >= 26 +template +inline constexpr bool __is_ranges_subrange_v> = true; template -struct __tuple_like_impl> : true_type {}; - -# endif +concept __tuple_like = __tuple_like_no_subrange<_Tp> || __is_ranges_subrange_v>; -template -concept __tuple_like = __tuple_like_impl>::value; +// As of writing this comment every use of `pair-like` in the standard excludes `ranges::subrange`, so +// you most likely want to use `__pair_like_no_subrange` if you're looking for `pair-like`. #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 0000000000000..274b0bf188e1f --- /dev/null +++ b/libcxx/include/__tuple/tuple_like_no_subrange.h @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 20 + +template +inline constexpr bool __tuple_like_no_subrange_impl = false; + +template +inline constexpr bool __tuple_like_no_subrange_impl> = true; + +template +inline constexpr bool __tuple_like_no_subrange_impl> = true; + +template +inline constexpr bool __tuple_like_no_subrange_impl> = true; + +# if _LIBCPP_STD_VER >= 26 + +template +inline constexpr bool __tuple_like_no_subrange_impl> = true; + +# endif + +template +concept __tuple_like_no_subrange = __tuple_like_no_subrange_impl>; + +// This is equivalent to the exposition-only type trait `pair-like`, except that it is false for specializations of +// `ranges::subrange`. This is more useful than the pair-like concept in the standard because every use of `pair-like` +// excludes `ranges::subrange`. +template +concept __pair_like_no_subrange = __tuple_like_no_subrange<_Tp> && tuple_size>::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 0056806877e13..87b2f6f5e2811 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> @@ -60,14 +59,6 @@ struct __non_trivially_copyable_base { __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {} }; -#if _LIBCPP_STD_VER >= 23 -template -struct __is_specialization_of_subrange : false_type {}; - -template -struct __is_specialization_of_subrange> : true_type {}; -#endif - template struct _LIBCPP_TEMPLATE_VIS pair #if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) @@ -201,19 +192,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 _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(std::declval<_PairLike&&>())), first_type> || !is_convertible_v(std::declval<_PairLike&&>())), second_type>; } return false; } - template <__pair_like _PairLike> - requires(!__is_specialization_of_subrange>::value && - is_constructible_v(std::declval<_PairLike &&>()))> && + template <__pair_like_no_subrange _PairLike> + requires(is_constructible_v(std::declval<_PairLike &&>()))> && is_constructible_v(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))) {} @@ -306,8 +297,8 @@ struct _LIBCPP_TEMPLATE_VIS pair return *this; } - template <__pair_like _PairLike> - requires(__different_from<_PairLike, pair> && !__is_specialization_of_subrange>::value && + template <__pair_like_no_subrange _PairLike> + requires(__different_from<_PairLike, pair> && is_assignable_v(std::declval<_PairLike>()))> && is_assignable_v(std::declval<_PairLike>()))>) _LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(_PairLike&& __p) { @@ -316,8 +307,8 @@ struct _LIBCPP_TEMPLATE_VIS pair return *this; } - template <__pair_like _PairLike> - requires(__different_from<_PairLike, pair> && !__is_specialization_of_subrange>::value && + template <__pair_like_no_subrange _PairLike> + requires(__different_from<_PairLike, pair> && is_assignable_v(std::declval<_PairLike>()))> && is_assignable_v(std::declval<_PairLike>()))>) _LIBCPP_HIDE_FROM_ABI constexpr pair const& operator=(_PairLike&& __p) const { diff --git a/libcxx/include/libcxx.imp b/libcxx/include/libcxx.imp index fb446da5dc6fe..ea0ba8c5471da 100644 --- a/libcxx/include/libcxx.imp +++ b/libcxx/include/libcxx.imp @@ -705,12 +705,12 @@ { include: [ "<__thread/timed_backoff_policy.h>", "private", "", "public" ] }, { include: [ "<__tuple/find_index.h>", "private", "", "public" ] }, { include: [ "<__tuple/make_tuple_types.h>", "private", "", "public" ] }, - { include: [ "<__tuple/pair_like.h>", "private", "", "public" ] }, { include: [ "<__tuple/sfinae_helpers.h>", "private", "", "public" ] }, { include: [ "<__tuple/tuple_element.h>", "private", "", "public" ] }, { include: [ "<__tuple/tuple_indices.h>", "private", "", "public" ] }, { include: [ "<__tuple/tuple_like.h>", "private", "", "public" ] }, { include: [ "<__tuple/tuple_like_ext.h>", "private", "", "public" ] }, + { include: [ "<__tuple/tuple_like_no_subrange.h>", "private", "", "public" ] }, { include: [ "<__tuple/tuple_size.h>", "private", "", "public" ] }, { include: [ "<__tuple/tuple_types.h>", "private", "", "public" ] }, { include: [ "<__type_traits/add_const.h>", "private", "", "public" ] }, diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap index 079c6234d4105..85303d2fa62c0 100644 --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -1810,20 +1810,22 @@ 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" + export * +} +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 f5e99fc3239e8..1b5e84e954795 100644 --- a/libcxx/include/variant +++ b/libcxx/include/variant @@ -235,11 +235,13 @@ namespace std { #include <__type_traits/is_destructible.h> #include <__type_traits/is_nothrow_assignable.h> #include <__type_traits/is_nothrow_constructible.h> +#include <__type_traits/is_reference.h> #include <__type_traits/is_trivially_assignable.h> #include <__type_traits/is_trivially_constructible.h> #include <__type_traits/is_trivially_destructible.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> diff --git a/libcxx/test/libcxx/utilities/tuple/__tuple_like.compile.pass.cpp b/libcxx/test/libcxx/utilities/tuple/__tuple_like.compile.pass.cpp index b1d199865decc..2c54fb5a10e13 100644 --- a/libcxx/test/libcxx/utilities/tuple/__tuple_like.compile.pass.cpp +++ b/libcxx/test/libcxx/utilities/tuple/__tuple_like.compile.pass.cpp @@ -15,6 +15,7 @@ // template // concept tuple-like; // exposition only +#include <__tuple/tuple_like.h> #include #include #include diff --git a/libcxx/test/std/ranges/range.adaptors/range.elements/range.concept.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.elements/range.concept.compile.pass.cpp index 7de72ecc0a90c..a49e692d585da 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.elements/range.concept.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.elements/range.concept.compile.pass.cpp @@ -52,7 +52,6 @@ static_assert(!std::ranges::input_range*>>, 0>); // !tuple-like -LIBCPP_STATIC_ASSERT(!std::__tuple_like); static_assert(!HasElementsView, 1>); // !(N < tuple_size_v)