From 5cf028cfc3a5df03414dd0b9bc029ece0ad734b1 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 23 Jun 2023 01:00:23 +0800 Subject: [PATCH 1/7] Implement P2538R1 Driven by: test `P2609R3_relaxing_ranges_just_a_smidge` in C++20 mode. --- stl/inc/xutility | 40 +++++++++++---- tests/std/test.lst | 1 + .../P2538R1_adl_proof_std_projected/env.lst | 4 ++ .../test.compile.pass.cpp | 51 +++++++++++++++++++ .../env.lst | 2 +- 5 files changed, 86 insertions(+), 12 deletions(-) create mode 100644 tests/std/tests/P2538R1_adl_proof_std_projected/env.lst create mode 100644 tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp diff --git a/stl/inc/xutility b/stl/inc/xutility index 681fb49c0bc..b30436aae50 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -864,22 +864,40 @@ _EXPORT_STD template requires (indirectly_readable<_Its> && ...) && invocable<_Fn, iter_reference_t<_Its>...> using indirect_result_t = invoke_result_t<_Fn, iter_reference_t<_Its>...>; -_EXPORT_STD template _Proj> -struct projected { - using value_type = remove_cvref_t>; - indirect_result_t<_Proj&, _It> operator*() const { - _CSTD abort(); - } +template +struct _Project_difference_type_impl { + struct _Base {}; +}; + +template +struct _Project_difference_type_impl<_It> { + struct _Base { + using difference_type = iter_difference_t<_It>; + }; }; template -struct _Indirect_value_impl> { - using type = invoke_result_t<_Proj&, _Indirect_value_t<_It>>; +struct _Projected_impl { + struct type : _Project_difference_type_impl<_It>::_Base { + using _Iterator = _It; + using _Projection = _Proj; + + using value_type = remove_cvref_t>; + indirect_result_t<_Proj&, _It> operator*() const { + _CSTD abort(); + } + }; }; -template -struct incrementable_traits> { - using difference_type = iter_difference_t<_It>; +_EXPORT_STD template _Proj> +using projected = _Projected_impl<_It, _Proj>::type; + +template +concept _Projected_specialization = same_as<_Ty, projected>; + +template <_Projected_specialization _ProjTy> +struct _Indirect_value_impl<_ProjTy> { + using type = invoke_result_t>; }; _EXPORT_STD template diff --git a/tests/std/test.lst b/tests/std/test.lst index 3059eef1402..f0b8aed0bec 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -618,6 +618,7 @@ tests\P2474R2_views_repeat_death tests\P2494R2_move_only_range_adaptors tests\P2505R5_monadic_functions_for_std_expected tests\P2517R1_apply_conditional_noexcept +tests\P2538R1_adl_proof_std_projected tests\P2609R3_relaxing_ranges_just_a_smidge tests\VSO_0000000_allocator_propagation tests\VSO_0000000_any_calling_conventions diff --git a/tests/std/tests/P2538R1_adl_proof_std_projected/env.lst b/tests/std/tests/P2538R1_adl_proof_std_projected/env.lst new file mode 100644 index 00000000000..d6d824b5879 --- /dev/null +++ b/tests/std/tests/P2538R1_adl_proof_std_projected/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\concepts_20_matrix.lst diff --git a/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp b/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp new file mode 100644 index 00000000000..1e85d87fab3 --- /dev/null +++ b/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include +#include + +using namespace std; + +// TRANSITION, GH-1596, should use ranges::count +struct my_count_fn { + template S, class T, class Proj = identity> + requires indirect_binary_predicate, const T*> + constexpr iter_difference_t operator()(I first, S last, const T& value, Proj proj = {}) const { + iter_difference_t counter = 0; + for (; first != last; ++first) { + if (std::invoke(proj, *first) == value) { // intentionally qualified to avoid ADL + ++counter; + } + } + return counter; + } + + template + requires indirect_binary_predicate, Proj>, const T*> + constexpr ranges::range_difference_t operator()(R&& r, const T& value, Proj proj = {}) const { + return (*this)(ranges::begin(r), ranges::end(r), value, ref(proj)); + } +}; + +inline constexpr my_count_fn my_count; + +template +struct Holder { + T t; +}; +struct Incomplete; + +static_assert(std::equality_comparable*>); +static_assert(std::indirectly_comparable**, Holder**, std::equal_to<>>); +static_assert(std::sortable**>); + +constexpr bool test() { + Holder* a[10] = {}; + assert(my_count(a, a + 10, nullptr) == 10); + assert(my_count(a, nullptr) == 10); + return true; +} + +static_assert(test()); diff --git a/tests/std/tests/P2609R3_relaxing_ranges_just_a_smidge/env.lst b/tests/std/tests/P2609R3_relaxing_ranges_just_a_smidge/env.lst index 18e2d7c71ec..d6d824b5879 100644 --- a/tests/std/tests/P2609R3_relaxing_ranges_just_a_smidge/env.lst +++ b/tests/std/tests/P2609R3_relaxing_ranges_just_a_smidge/env.lst @@ -1,4 +1,4 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -RUNALL_INCLUDE ..\concepts_latest_matrix.lst +RUNALL_INCLUDE ..\concepts_20_matrix.lst From 6231936f16e95557e3b65299dcf5e789ebf9c94d Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 23 Jun 2023 11:02:55 +0800 Subject: [PATCH 2/7] Mention P2538R1 in `yvals_core.h` --- stl/inc/yvals_core.h | 1 + 1 file changed, 1 insertion(+) diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index ceb2fce5ed8..035d863f88c 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -285,6 +285,7 @@ // P2432R1 Fix istream_view // P2508R1 basic_format_string, format_string, wformat_string // P2520R0 move_iterator Should Be A Random-Access Iterator +// P2538R1 ADL-Proof projected // P2572R1 std::format Fill Character Allowances // P2588R3 barrier's Phase Completion Guarantees // P2602R2 Poison Pills Are Too Toxic From 8d263a452548d1d3939066eed8305c864dcfa7f3 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 23 Jun 2023 22:51:47 +0800 Subject: [PATCH 3/7] `` should be included in the test file --- .../tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp b/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp index 1e85d87fab3..8671a6eb6e0 100644 --- a/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp +++ b/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include using namespace std; From 3e8806d8c0dfadc6be9149da844e4f8ab6ae66be Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 25 Jun 2023 01:04:03 +0800 Subject: [PATCH 4/7] Drop `std::` whenever suitable --- .../P2538R1_adl_proof_std_projected/test.compile.pass.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp b/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp index 8671a6eb6e0..02b747e7216 100644 --- a/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp +++ b/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp @@ -38,9 +38,9 @@ struct Holder { }; struct Incomplete; -static_assert(std::equality_comparable*>); -static_assert(std::indirectly_comparable**, Holder**, std::equal_to<>>); -static_assert(std::sortable**>); +static_assert(equality_comparable*>); +static_assert(indirectly_comparable**, Holder**, equal_to<>>); +static_assert(sortable**>); constexpr bool test() { Holder* a[10] = {}; From 352be3553e69a136a5a9f52809901ef5af7118de Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 25 Jun 2023 09:11:25 +0800 Subject: [PATCH 5/7] Rename for consistency --- stl/inc/xutility | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index b30436aae50..de58dcf9aa4 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -865,12 +865,12 @@ _EXPORT_STD template using indirect_result_t = invoke_result_t<_Fn, iter_reference_t<_Its>...>; template -struct _Project_difference_type_impl { +struct _Projected_difference_type_impl { struct _Base {}; }; template -struct _Project_difference_type_impl<_It> { +struct _Projected_difference_type_impl<_It> { struct _Base { using difference_type = iter_difference_t<_It>; }; @@ -878,7 +878,7 @@ struct _Project_difference_type_impl<_It> { template struct _Projected_impl { - struct type : _Project_difference_type_impl<_It>::_Base { + struct type : _Projected_difference_type_impl<_It>::_Base { using _Iterator = _It; using _Projection = _Proj; From f20a457b30484ed59d2ef0b30fa69cea5cbf382c Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sun, 2 Jul 2023 10:33:17 +0800 Subject: [PATCH 6/7] _Uglify `type` --- stl/inc/xutility | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index de58dcf9aa4..a4312e1ba25 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -878,7 +878,7 @@ struct _Projected_difference_type_impl<_It> { template struct _Projected_impl { - struct type : _Projected_difference_type_impl<_It>::_Base { + struct _Type : _Projected_difference_type_impl<_It>::_Base { using _Iterator = _It; using _Projection = _Proj; @@ -890,7 +890,7 @@ struct _Projected_impl { }; _EXPORT_STD template _Proj> -using projected = _Projected_impl<_It, _Proj>::type; +using projected = _Projected_impl<_It, _Proj>::_Type; template concept _Projected_specialization = same_as<_Ty, projected>; From 4dd2d4d2b7b12cb0eb5991c9927935e778f4f6ff Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 13 Jul 2023 12:14:40 -0700 Subject: [PATCH 7/7] Work around VSO-1659496: /clr emits bogus error C2079 "uses undefined struct 'Incomplete'" despite std::variant's ADL defenses --- .../tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp b/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp index 02b747e7216..c1a405fc864 100644 --- a/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp +++ b/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#ifndef _M_CEE // TRANSITION, VSO-1659496 #include #include #include @@ -50,3 +51,4 @@ constexpr bool test() { } static_assert(test()); +#endif // _M_CEE