Skip to content

Commit

Permalink
Implement P2997R1 Removing The Common Reference Requirement From The …
Browse files Browse the repository at this point in the history
…Indirectly Invocable Concepts (#4816)

Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
  • Loading branch information
frederick-vs-ja and StephanTLavavej authored Jul 11, 2024
1 parent 5236e38 commit 0207572
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 25 deletions.
34 changes: 14 additions & 20 deletions stl/inc/xutility
Original file line number Diff line number Diff line change
Expand Up @@ -960,49 +960,43 @@ concept contiguous_iterator = random_access_iterator<_It>
// clang-format on

_EXPORT_STD template <class _Fn, class _It>
concept indirectly_unary_invocable =
indirectly_readable<_It> && copy_constructible<_Fn> && invocable<_Fn&, _Indirect_value_t<_It>>
&& invocable<_Fn&, iter_reference_t<_It>> && invocable<_Fn&, iter_common_reference_t<_It>>
&& common_reference_with<invoke_result_t<_Fn&, _Indirect_value_t<_It>>,
invoke_result_t<_Fn&, iter_reference_t<_It>>>;
concept indirectly_unary_invocable = indirectly_readable<_It> && copy_constructible<_Fn>
&& invocable<_Fn&, _Indirect_value_t<_It>> && invocable<_Fn&, iter_reference_t<_It>>
&& common_reference_with<invoke_result_t<_Fn&, _Indirect_value_t<_It>>,
invoke_result_t<_Fn&, iter_reference_t<_It>>>;

_EXPORT_STD template <class _Fn, class _It>
concept indirectly_regular_unary_invocable =
indirectly_readable<_It> && copy_constructible<_Fn> && regular_invocable<_Fn&, _Indirect_value_t<_It>>
&& regular_invocable<_Fn&, iter_reference_t<_It>> && regular_invocable<_Fn&, iter_common_reference_t<_It>>
&& regular_invocable<_Fn&, iter_reference_t<_It>>
&& common_reference_with<invoke_result_t<_Fn&, _Indirect_value_t<_It>>,
invoke_result_t<_Fn&, iter_reference_t<_It>>>;

_EXPORT_STD template <class _Fn, class _It>
concept indirect_unary_predicate =
indirectly_readable<_It> && copy_constructible<_Fn> && predicate<_Fn&, _Indirect_value_t<_It>>
&& predicate<_Fn&, iter_reference_t<_It>> && predicate<_Fn&, iter_common_reference_t<_It>>;
concept indirect_unary_predicate = indirectly_readable<_It> && copy_constructible<_Fn>
&& predicate<_Fn&, _Indirect_value_t<_It>> && predicate<_Fn&, iter_reference_t<_It>>;

_EXPORT_STD template <class _Fn, class _It1, class _It2>
concept indirect_binary_predicate = indirectly_readable<_It1> && indirectly_readable<_It2> && copy_constructible<_Fn>
&& predicate<_Fn&, _Indirect_value_t<_It1>, _Indirect_value_t<_It2>>
&& predicate<_Fn&, _Indirect_value_t<_It1>, iter_reference_t<_It2>>
&& predicate<_Fn&, iter_reference_t<_It1>, _Indirect_value_t<_It2>>
&& predicate<_Fn&, iter_reference_t<_It1>, iter_reference_t<_It2>>
&& predicate<_Fn&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>;
&& predicate<_Fn&, iter_reference_t<_It1>, iter_reference_t<_It2>>;

_EXPORT_STD template <class _Fn, class _It1, class _It2 = _It1>
concept indirect_equivalence_relation =
indirectly_readable<_It1> && indirectly_readable<_It2> && copy_constructible<_Fn>
&& equivalence_relation<_Fn&, _Indirect_value_t<_It1>, _Indirect_value_t<_It2>>
&& equivalence_relation<_Fn&, _Indirect_value_t<_It1>, iter_reference_t<_It2>>
&& equivalence_relation<_Fn&, iter_reference_t<_It1>, _Indirect_value_t<_It2>>
&& equivalence_relation<_Fn&, iter_reference_t<_It1>, iter_reference_t<_It2>>
&& equivalence_relation<_Fn&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>;
&& equivalence_relation<_Fn&, iter_reference_t<_It1>, iter_reference_t<_It2>>;

_EXPORT_STD template <class _Fn, class _It1, class _It2 = _It1>
concept indirect_strict_weak_order =
indirectly_readable<_It1> && indirectly_readable<_It2> && copy_constructible<_Fn>
&& strict_weak_order<_Fn&, _Indirect_value_t<_It1>, _Indirect_value_t<_It2>>
&& strict_weak_order<_Fn&, _Indirect_value_t<_It1>, iter_reference_t<_It2>>
&& strict_weak_order<_Fn&, iter_reference_t<_It1>, _Indirect_value_t<_It2>>
&& strict_weak_order<_Fn&, iter_reference_t<_It1>, iter_reference_t<_It2>>
&& strict_weak_order<_Fn&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>;
concept indirect_strict_weak_order = indirectly_readable<_It1> && indirectly_readable<_It2> && copy_constructible<_Fn>
&& strict_weak_order<_Fn&, _Indirect_value_t<_It1>, _Indirect_value_t<_It2>>
&& strict_weak_order<_Fn&, _Indirect_value_t<_It1>, iter_reference_t<_It2>>
&& strict_weak_order<_Fn&, iter_reference_t<_It1>, _Indirect_value_t<_It2>>
&& strict_weak_order<_Fn&, iter_reference_t<_It1>, iter_reference_t<_It2>>;

_EXPORT_STD template <class _Fn, class... _Its>
requires (indirectly_readable<_Its> && ...) && invocable<_Fn, iter_reference_t<_Its>...>
Expand Down
4 changes: 3 additions & 1 deletion stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@
// P2770R0 Stashing Stashing Iterators For Proper Flattening
// P2905R2 Runtime Format Strings
// P2909R4 Fix Formatting Of Code Units As Integers
// P2997R1 Removing The Common Reference Requirement From The Indirectly Invocable Concepts

// _HAS_CXX20 indirectly controls:
// P0619R4 Removing C++17-Deprecated Features
Expand Down Expand Up @@ -1837,7 +1838,8 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect
#endif

#if _HAS_CXX23
#define __cpp_lib_ranges 202302L // P2609R3 Relaxing Ranges Just A Smidge
// P2997R1 Removing The Common Reference Requirement From The Indirectly Invocable Concepts
#define __cpp_lib_ranges 202406L
#elif _HAS_CXX20
#define __cpp_lib_ranges 202110L // P2415R2 What Is A view?
#endif
Expand Down
8 changes: 8 additions & 0 deletions tests/libcxx/expected_results.txt
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,14 @@ std/language.support/support.limits/support.limits.general/mdspan.version.compil
# libc++ has not implemented P2937R0: "Freestanding Library: Remove strtok"
std/language.support/support.limits/support.limits.general/cstring.version.compile.pass.cpp FAIL

# libc++ has not implemented P2997R1: "Removing The Common Reference Requirement From The Indirectly Invocable Concepts"
std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_binary_predicate.compile.pass.cpp FAIL
std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_equivalence_relation.compile.pass.cpp FAIL
std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_strict_weak_order.compile.pass.cpp FAIL
std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirect_unary_predicate.compile.pass.cpp FAIL
std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_regular_unary_invocable.compile.pass.cpp FAIL
std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_unary_invocable.compile.pass.cpp FAIL

# Various bogosity (LLVM-D141004), warning C6011: Dereferencing NULL pointer
# Note: The :1 (ASAN) configuration doesn't run static analysis.
std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.mem/construct_pair_const_lvalue_pair.pass.cpp:0 FAIL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ namespace indirectly_unary_invocable_test {
// 2: not invocable<Fn&, iter_reference_t<simple_iter_archetype>>
void operator()(simple_reference<int>) const requires (I == 2) = delete;
// 3: not invocable<Fn&, iter_common_reference_t<simple_iter_archetype>>
// This case is made valid by P2997R1
// "Removing The Common Reference Requirement From The Indirectly Invocable Concepts".
void operator()(simple_common_reference<int>) const requires (I == 3) = delete;

// 4 : not common_reference_with<invoke_result_t<Fn&, iter_value_t<simple_iter_archetype>&>,
Expand All @@ -101,7 +103,7 @@ namespace indirectly_unary_invocable_test {
static_assert(!test<Fn<0>, simple_iter_archetype<1>>());
static_assert(!test<Fn<1>, simple_iter_archetype<1>>());
static_assert(!test<Fn<2>, simple_iter_archetype<1>>());
static_assert(!test<Fn<3>, simple_iter_archetype<1>>());
static_assert(test<Fn<3>, simple_iter_archetype<1>>());
static_assert(!test<Fn<4>, simple_iter_archetype<1>>());
static_assert(!test<Fn<5>, simple_iter_archetype<0>>());
static_assert(test<Fn<5>, simple_iter_archetype<1>>());
Expand Down Expand Up @@ -130,6 +132,8 @@ namespace indirect_unary_predicate_test {
// 2: not predicate<Fn&, iter_reference_t<simple_iter_archetype>>
void operator()(simple_reference<int>) const requires (I == 2) = delete;
// 3: not predicate<Fn&, iter_common_reference_t<simple_iter_archetype>>
// This case is made valid by P2997R1
// "Removing The Common Reference Requirement From The Indirectly Invocable Concepts".
void operator()(simple_common_reference<int>) const requires (I == 3) = delete;

// 4: all of the above
Expand All @@ -142,7 +146,7 @@ namespace indirect_unary_predicate_test {
static_assert(!indirect_unary_predicate<Fn<0>, simple_iter_archetype<1>>);
static_assert(!indirect_unary_predicate<Fn<1>, simple_iter_archetype<1>>);
static_assert(!indirect_unary_predicate<Fn<2>, simple_iter_archetype<1>>);
static_assert(!indirect_unary_predicate<Fn<3>, simple_iter_archetype<1>>);
static_assert(indirect_unary_predicate<Fn<3>, simple_iter_archetype<1>>);
static_assert(!indirect_unary_predicate<Fn<4>, simple_iter_archetype<1>>);
static_assert(!indirect_unary_predicate<Fn<5>, simple_iter_archetype<0>>);
static_assert(indirect_unary_predicate<Fn<5>, simple_iter_archetype<1>>);
Expand Down Expand Up @@ -174,6 +178,8 @@ namespace indirect_binary_predicate_test {
// 4: not predicate<Fn&, iter_reference_t<simple_iter_archetype>, iter_reference_t<simple_iter_archetype>>
void operator()(simple_reference<int>, simple_reference<int>) const requires (I == 4);
// 5: not predicate<Fn&, iter_common_reference_t</**/>, iter_common_reference_t</**/>>
// This case is made valid by P2997R1
// "Removing The Common Reference Requirement From The Indirectly Invocable Concepts".
void operator()(simple_common_reference<int>, simple_common_reference<int>) const requires (I == 5);

bool operator()(int&, int&) const requires (I != 1);
Expand Down Expand Up @@ -202,7 +208,7 @@ namespace indirect_binary_predicate_test {
static_assert(!test<2, 1, 1>());
static_assert(!test<3, 1, 1>());
static_assert(!test<4, 1, 1>());
static_assert(!test<5, 1, 1>());
static_assert(test<5, 1, 1>());

static_assert(!test<6, 0, 1>());
static_assert(!test<6, 1, 0>());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ STATIC_ASSERT(__cpp_lib_print == 202207L);
STATIC_ASSERT(__cpp_lib_quoted_string_io == 201304L);

#if _HAS_CXX23
STATIC_ASSERT(__cpp_lib_ranges == 202302L);
STATIC_ASSERT(__cpp_lib_ranges == 202406L);
#elif _HAS_CXX20
STATIC_ASSERT(__cpp_lib_ranges == 202110L);
#elif defined(__cpp_lib_ranges)
Expand Down

0 comments on commit 0207572

Please sign in to comment.