Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libcxx/docs/Status/Cxx23Papers.csv
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"`P0627R6 <https://wg21.link/P0627R6>`__","Function to mark unreachable code","2022-02 (Virtual)","|Complete|","15","`#105175 <https://github.com/llvm/llvm-project/issues/105175>`__",""
"`P1206R7 <https://wg21.link/P1206R7>`__","``ranges::to``: A function to convert any range to a container","2022-02 (Virtual)","|Complete|","17","`#105176 <https://github.com/llvm/llvm-project/issues/105176>`__",""
"`P1413R3 <https://wg21.link/P1413R3>`__","Deprecate ``std::aligned_storage`` and ``std::aligned_union``","2022-02 (Virtual)","|Complete|","","`#105177 <https://github.com/llvm/llvm-project/issues/105177>`__","``std::aligned_storage_t`` and ``std::aligned_union_t`` are marked deprecated, but clang doesn't issue a diagnostic for deprecated using template declarations."
"`P2255R2 <https://wg21.link/P2255R2>`__","A type trait to detect reference binding to temporary","2022-02 (Virtual)","|Partial|","","`#105180 <https://github.com/llvm/llvm-project/issues/105180>`__","Implemented the type traits only."
"`P2255R2 <https://wg21.link/P2255R2>`__","A type trait to detect reference binding to temporary","2022-02 (Virtual)","|Partial|","","`#105180 <https://github.com/llvm/llvm-project/issues/105180>`__","Implemented the type traits and changes to ``std::pair`` only."
"`P2273R3 <https://wg21.link/P2273R3>`__","Making ``std::unique_ptr`` constexpr","2022-02 (Virtual)","|Complete|","16","`#105182 <https://github.com/llvm/llvm-project/issues/105182>`__",""
"`P2387R3 <https://wg21.link/P2387R3>`__","Pipe support for user-defined range adaptors","2022-02 (Virtual)","|Complete|","19","`#105183 <https://github.com/llvm/llvm-project/issues/105183>`__",""
"`P2440R1 <https://wg21.link/P2440R1>`__","``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right``","2022-02 (Virtual)","|Partial|","","`#105184 <https://github.com/llvm/llvm-project/issues/105184>`__","Only ``ranges::iota`` is implemented."
Expand Down
77 changes: 69 additions & 8 deletions libcxx/include/__utility/pair.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <__config>
#include <__cstddef/size_t.h>
#include <__fwd/array.h>
#include <__fwd/complex.h>
#include <__fwd/pair.h>
#include <__fwd/tuple.h>
#include <__tuple/tuple_like_no_subrange.h>
Expand All @@ -36,6 +37,7 @@
#include <__type_traits/is_swappable.h>
#include <__type_traits/is_trivially_relocatable.h>
#include <__type_traits/nat.h>
#include <__type_traits/reference_constructs_from_temporary.h>
#include <__type_traits/unwrap_ref.h>
#include <__utility/declval.h>
#include <__utility/forward.h>
Expand Down Expand Up @@ -68,9 +70,23 @@ struct __check_pair_construction {

template <class _U1, class _U2>
static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_pair_constructible() {
# if _LIBCPP_STD_VER >= 23 && __has_builtin(__reference_constructs_from_temporary)
return is_constructible_v<_T1, _U1> && is_constructible_v<_T2, _U2> &&
!reference_constructs_from_temporary_v<_T1, _U1&&> && !reference_constructs_from_temporary_v<_T2, _U2&&>;
# else
return is_constructible<_T1, _U1>::value && is_constructible<_T2, _U2>::value;
# endif
}

# if _LIBCPP_STD_VER >= 23 && __has_builtin(__reference_constructs_from_temporary)
template <class _U1, class _U2>
static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_pair_constructor_deleted() {
return is_constructible_v<_T1, _U1> && is_constructible_v<_T2, _U2> &&
(reference_constructs_from_temporary_v<_T1, _U1&&> || reference_constructs_from_temporary_v<_T2, _U2&&>);
return is_constructible<_T1, _U1>::value && is_constructible<_T2, _U2>::value;
}
# endif

template <class _U1, class _U2>
static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_implicit() {
return is_convertible<_U1, _T1>::value && is_convertible<_U2, _T2>::value;
Expand Down Expand Up @@ -157,14 +173,20 @@ struct pair
class _U1,
class _U2,
# endif
__enable_if_t<__check_pair_construction<_T1, _T2>::template __is_pair_constructible<_U1, _U2>(), int> = 0 >
__enable_if_t<__check_pair_construction<_T1, _T2>::template __is_pair_constructible<_U1&&, _U2&&>(), int> = 0 >
_LIBCPP_HIDE_FROM_ABI
_LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!__check_pair_construction<_T1, _T2>::template __is_implicit<_U1, _U2>())
_LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!__check_pair_construction<_T1, _T2>::template __is_implicit<_U1&&, _U2&&>())
pair(_U1&& __u1, _U2&& __u2) noexcept(is_nothrow_constructible<first_type, _U1>::value &&
is_nothrow_constructible<second_type, _U2>::value)
: first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {
}

# if _LIBCPP_STD_VER >= 23 && __has_builtin(__reference_constructs_from_temporary)
template <class _U1 = _T1, class _U2 = _T2>
requires(__check_pair_construction<_T1, _T2>::template __is_pair_constructor_deleted<_U1 &&, _U2 &&>())
explicit(!__check_pair_construction<_T1, _T2>::template __is_implicit<_U1&&, _U2&&>()) pair(_U1&&, _U2&&) = delete;
# endif

# if _LIBCPP_STD_VER >= 23
template <class _U1,
class _U2,
Expand All @@ -173,6 +195,12 @@ struct pair
pair(pair<_U1, _U2>& __p) noexcept((is_nothrow_constructible<first_type, _U1&>::value &&
is_nothrow_constructible<second_type, _U2&>::value))
: first(__p.first), second(__p.second) {}

# if __has_builtin(__reference_constructs_from_temporary)
template <class _U1, class _U2>
requires(__check_pair_construction<_T1, _T2>::template __is_pair_constructor_deleted<_U1&, _U2&>())
explicit(!__check_pair_construction<_T1, _T2>::template __is_implicit<_U1&, _U2&>()) pair(pair<_U1, _U2>&) = delete;
# endif
# endif

template <
Expand All @@ -186,15 +214,30 @@ struct pair
is_nothrow_constructible<second_type, _U2 const&>::value)
: first(__p.first), second(__p.second) {}

template <class _U1,
class _U2,
__enable_if_t<__check_pair_construction<_T1, _T2>::template __is_pair_constructible<_U1, _U2>(), int> = 0>
# if _LIBCPP_STD_VER >= 23 && __has_builtin(__reference_constructs_from_temporary)
template <class _U1, class _U2>
requires(__check_pair_construction<_T1, _T2>::template __is_pair_constructor_deleted<const _U1&, const _U2&>())
explicit(!__check_pair_construction<_T1, _T2>::template __is_implicit<const _U1&, const _U2&>())
pair(const pair<_U1, _U2>&) = delete;
# endif

template <
class _U1,
class _U2,
__enable_if_t<__check_pair_construction<_T1, _T2>::template __is_pair_constructible<_U1&&, _U2&&>(), int> = 0>
_LIBCPP_HIDE_FROM_ABI
_LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!__check_pair_construction<_T1, _T2>::template __is_implicit<_U1, _U2>())
_LIBCPP_CONSTEXPR_SINCE_CXX14 explicit(!__check_pair_construction<_T1, _T2>::template __is_implicit<_U1&&, _U2&&>())
pair(pair<_U1, _U2>&& __p) noexcept(is_nothrow_constructible<first_type, _U1&&>::value &&
is_nothrow_constructible<second_type, _U2&&>::value)
: first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {}

# if _LIBCPP_STD_VER >= 23 && __has_builtin(__reference_constructs_from_temporary)
template <class _U1, class _U2>
requires(__check_pair_construction<_T1, _T2>::template __is_pair_constructor_deleted<_U1 &&, _U2 &&>())
explicit(!__check_pair_construction<_T1, _T2>::template __is_implicit<_U1&&, _U2&&>())
pair(pair<_U1, _U2>&&) = delete;
# endif

# if _LIBCPP_STD_VER >= 23
template <
class _U1,
Expand All @@ -206,16 +249,34 @@ struct pair
pair(const pair<_U1, _U2>&& __p) noexcept(is_nothrow_constructible<first_type, const _U1&&>::value &&
is_nothrow_constructible<second_type, const _U2&&>::value)
: first(std::move(__p.first)), second(std::move(__p.second)) {}

# if __has_builtin(__reference_constructs_from_temporary)
template <class _U1, class _U2>
requires(__check_pair_construction<_T1, _T2>::template __is_pair_constructor_deleted<const _U1 &&, const _U2 &&>())
explicit(!__check_pair_construction<_T1, _T2>::template __is_implicit<const _U1&&, const _U2&&>())
pair(const pair<_U1, _U2>&&) = delete;
# endif
# endif

# if _LIBCPP_STD_VER >= 23
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 &&>()))>)
requires(__check_pair_construction<_T1, _T2>::template __is_pair_constructible<
decltype(std::get<0>(std::declval<_PairLike &&>())),
decltype(std::get<1>(std::declval<_PairLike &&>()))>())
_LIBCPP_HIDE_FROM_ABI constexpr explicit(
!is_convertible_v<decltype(std::get<0>(std::declval<_PairLike&&>())), first_type> ||
!is_convertible_v<decltype(std::get<1>(std::declval<_PairLike&&>())), second_type>) pair(_PairLike&& __p)
: first(std::get<0>(std::forward<_PairLike>(__p))), second(std::get<1>(std::forward<_PairLike>(__p))) {}

# if __has_builtin(__reference_constructs_from_temporary)
template <__pair_like_no_subrange _PairLike>
requires(__check_pair_construction<_T1, _T2>::template __is_pair_constructor_deleted<
decltype(std::get<0>(std::declval<_PairLike &&>())),
decltype(std::get<1>(std::declval<_PairLike &&>()))>())
explicit(!is_convertible_v<decltype(std::get<0>(std::declval<_PairLike&&>())), first_type> ||
!is_convertible_v<decltype(std::get<1>(std::declval<_PairLike&&>())), second_type>)
pair(_PairLike&&) = delete;
# endif
# endif

template <class... _Args1, class... _Args2>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ constexpr bool test() {
assert(kc(1, 2));
assert(!kc(2, 1));
auto vc = m.value_comp();
ASSERT_SAME_TYPE(decltype(vc(std::make_pair(1, 2), std::make_pair(1, 2))), bool);
ASSERT_SAME_TYPE(decltype(vc(std::make_pair(1, '2'), std::make_pair(1, '2'))), bool);
assert(vc({1, '2'}, {2, '1'}));
assert(!vc({2, '1'}, {1, '2'}));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ constexpr bool test() {
assert(kc(1, 2));
assert(!kc(2, 1));
auto vc = m.value_comp();
ASSERT_SAME_TYPE(decltype(vc(std::make_pair(1, 2), std::make_pair(1, 2))), bool);
ASSERT_SAME_TYPE(decltype(vc(std::make_pair(1, '2'), std::make_pair(1, '2'))), bool);
assert(vc({1, '2'}, {2, '1'}));
assert(!vc({2, '1'}, {1, '2'}));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,15 @@ int main(int, char**)
}
#endif // TEST_STD_VER > 20

return 0;
// Test construction prohibition of introduced by https://wg21.link/P2255R2.
#if TEST_STD_VER >= 23 && __has_builtin(__reference_constructs_from_temporary)
test_sfinae<int&&, char, false>();
test_sfinae<const int&, char, false>();
test_sfinae<ConvertingType&&, int, false>();
test_sfinae<const ConvertingType&, char, false>();
test_sfinae<ExplicitTypes::ConvertingType&&, int, false>();
test_sfinae<const ExplicitTypes::ConvertingType&, int, false>();
#endif // TEST_STD_VER >= 23 && __has_builtin(__reference_constructs_from_temporary)

return 0;
}
Loading
Loading