diff --git a/stl/inc/xutility b/stl/inc/xutility index 681fb49c0b..a4312e1ba2 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 _Projected_difference_type_impl { + struct _Base {}; +}; + +template +struct _Projected_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 : _Projected_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/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index ceb2fce5ed..035d863f88 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 diff --git a/tests/std/test.lst b/tests/std/test.lst index 3059eef140..f0b8aed0be 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 0000000000..d6d824b587 --- /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 0000000000..c1a405fc86 --- /dev/null +++ b/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef _M_CEE // TRANSITION, VSO-1659496 +#include +#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(equality_comparable*>); +static_assert(indirectly_comparable**, Holder**, equal_to<>>); +static_assert(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()); +#endif // _M_CEE 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 18e2d7c71e..d6d824b587 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