public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-10279] libstdc++: Implement P2538R1 ADL-proof std::projected
@ 2024-03-18 14:08 Jonathan Wakely
  0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2024-03-18 14:08 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

https://gcc.gnu.org/g:2d604183c99ef0cea5d7540a7a466fb1d1453a58

commit r12-10279-g2d604183c99ef0cea5d7540a7a466fb1d1453a58
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Jun 23 12:18:11 2023 +0100

    libstdc++: Implement P2538R1 ADL-proof std::projected
    
    This was recently approved for C++26, but there's no harm in
    implementing it unconditionally for C++20 and C++23. As it says in the
    paper, it doesn't change the meaning of any valid code. It only enables
    things that were previously ill-formed for questionable reasons.
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/iterator_concepts.h (projected): Replace class
            template with alias template denoting an ADL-proofed helper.
            (incremental_traits<projected<Iter, Proj>>): Remove.
            * testsuite/24_iterators/indirect_callable/projected-adl.cc:
            New test.
    
    (cherry picked from commit 6eafdfc73c21d7a5e59e18c9dee275af5bf6d979)

Diff:
---
 libstdc++-v3/include/bits/iterator_concepts.h      | 35 ++++++++++++------
 .../indirect_callable/projected-adl.cc             | 42 ++++++++++++++++++++++
 2 files changed, 67 insertions(+), 10 deletions(-)

diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h
index cf66c63f395..6e032b08eb7 100644
--- a/libstdc++-v3/include/bits/iterator_concepts.h
+++ b/libstdc++-v3/include/bits/iterator_concepts.h
@@ -771,19 +771,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       && invocable<_Fn, iter_reference_t<_Is>...>
     using indirect_result_t = invoke_result_t<_Fn, iter_reference_t<_Is>...>;
 
+  namespace __detail
+  {
+    template<typename _Iter, typename _Proj>
+      struct __projected
+      {
+	struct __type
+	{
+	  using value_type = remove_cvref_t<indirect_result_t<_Proj&, _Iter>>;
+	  indirect_result_t<_Proj&, _Iter> operator*() const; // not defined
+	};
+      };
+
+    template<weakly_incrementable _Iter, typename _Proj>
+      struct __projected<_Iter, _Proj>
+      {
+	struct __type
+	{
+	  using value_type = remove_cvref_t<indirect_result_t<_Proj&, _Iter>>;
+	  using difference_type = iter_difference_t<_Iter>;
+	  indirect_result_t<_Proj&, _Iter> operator*() const; // not defined
+	};
+      };
+  } // namespace __detail
+
   /// [projected], projected
   template<indirectly_readable _Iter,
 	   indirectly_regular_unary_invocable<_Iter> _Proj>
-    struct projected
-    {
-      using value_type = remove_cvref_t<indirect_result_t<_Proj&, _Iter>>;
-
-      indirect_result_t<_Proj&, _Iter> operator*() const; // not defined
-    };
-
-  template<weakly_incrementable _Iter, typename _Proj>
-    struct incrementable_traits<projected<_Iter, _Proj>>
-    { using difference_type = iter_difference_t<_Iter>; };
+    using projected = typename __detail::__projected<_Iter, _Proj>::__type;
 
   // [alg.req], common algorithm requirements
 
diff --git a/libstdc++-v3/testsuite/24_iterators/indirect_callable/projected-adl.cc b/libstdc++-v3/testsuite/24_iterators/indirect_callable/projected-adl.cc
new file mode 100644
index 00000000000..4c2a0955c6e
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/indirect_callable/projected-adl.cc
@@ -0,0 +1,42 @@
+// { dg-options "-std=gnu++20" }
+// { dg-do compile { target c++20 } }
+
+// P2538R1 ADL-proof std::projected
+// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2538r1.html
+
+#include <iterator>
+
+template<typename T>
+  concept has_diff_type = requires { typename T::difference_type; };
+
+static_assert( has_diff_type<std::projected<int*, void(*)(int)>> );
+
+struct Indy {
+  using value_type = int;
+  int operator*() const { return 0; }
+};
+static_assert( ! std::weakly_incrementable<Indy> );
+static_assert( ! has_diff_type<std::projected<Indy, void(*)(int)>> );
+
+
+// Examples from the paper:
+
+template<class T> struct Holder { T t; };
+struct Incomplete;
+
+void test_concepts()
+{
+  using T = Holder<Incomplete>*;
+  static_assert(std::equality_comparable<T>);
+  (void) std::indirectly_comparable<T*, T*, std::equal_to<>>;
+  (void) std::sortable<T*>;
+}
+
+#include <algorithm>
+
+void test_count()
+{
+  Holder<Incomplete>* a = nullptr;
+  (void) std::count(&a, &a, nullptr);
+  (void) std::ranges::count(&a, &a, nullptr); // { dg-bogus "." }
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-03-18 14:08 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-18 14:08 [gcc r12-10279] libstdc++: Implement P2538R1 ADL-proof std::projected Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).