public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Jonathan Wakely <redi@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org
Subject: [gcc r12-6474] libstdc++: Install <coroutine> header for freestanding [PR103726]
Date: Tue, 11 Jan 2022 13:29:38 +0000 (GMT)	[thread overview]
Message-ID: <20220111132938.211A538A9405@sourceware.org> (raw)

https://gcc.gnu.org/g:265d3e1a4e3d6c71d354f859302f023dc2d33f62

commit r12-6474-g265d3e1a4e3d6c71d354f859302f023dc2d33f62
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Mon Jan 10 20:48:53 2022 +0000

    libstdc++: Install <coroutine> header for freestanding [PR103726]
    
    The standard says that <coroutine> should be present for freestanding.
    That was intentionally left out of the initial implementation, but can
    be done without much trouble. The header should be moved to libsupc++ at
    some point in stage 1.
    
    The standard also says that <coroutine> defines a std::hash
    specialization, which was missing from our implementation. That's a
    problem for freestanding (see LWG 3653) so only do that for hosted.
    
    We can use concepts to constrain the __coroutine_traits_impl base class
    when compiled with concepts enabled. In a pure C++20 implementation we
    would not need that base class at all and could just use a constrained
    partial specialization of coroutine_traits. But the absence of the
    __coroutine_traits_impl<R, void> base would create an ABI difference
    between the non-standard C++14/C++17 support for coroutines and the same
    code compiled as C++20. If we drop support for <coroutine> pre-C++20 we
    should revisit this.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/103726
            * include/Makefile.am: Install <coroutine> for freestanding.
            * include/Makefile.in: Regenerate.
            * include/std/coroutine: Adjust headers and preprocessor
            conditions.
            (__coroutine_traits_impl): Use concepts when available.
            [_GLIBCXX_HOSTED] (hash<coroutine_handle>): Define.

Diff:
---
 libstdc++-v3/include/Makefile.am   |  4 +--
 libstdc++-v3/include/Makefile.in   |  4 +--
 libstdc++-v3/include/std/coroutine | 55 ++++++++++++++++++++++++++++----------
 3 files changed, 45 insertions(+), 18 deletions(-)

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 7afebb5c5f0..8f93bf2d7b7 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -1425,7 +1425,7 @@ endif
 # This is a subset of the full install-headers rule.  We only need <ciso646>,
 # <cstddef>, <cfloat>, <limits>, <climits>, <version>, <cstdint>, <cstdlib>,
 # <new>, <typeinfo>, <exception>, <initializer_list>, <cstdalign>, <cstdarg>,
-# <concepts>, <cstdbool>, <type_traits>, <bit>, <atomic>,
+# <concepts>, <coroutine>, <cstdbool>, <type_traits>, <bit>, <atomic>,
 # and any files which they include (and which we provide).
 # <new>, <typeinfo>, <exception>, <initializer_list> and <compare>
 # are installed by libsupc++, so only the others and the sub-includes
@@ -1440,7 +1440,7 @@ install-freestanding-headers:
 	  ${glibcxx_srcdir}/$(CPU_DEFINES_SRCDIR)/cpu_defines.h; do \
 	  $(INSTALL_DATA) $${file} $(DESTDIR)${host_installdir}; done
 	$(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${std_builddir}
-	for file in limits type_traits atomic bit concepts version; do \
+	for file in limits type_traits atomic bit concepts coroutine version; do \
 	  $(INSTALL_DATA) ${std_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${std_builddir}; done
 	$(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${c_base_builddir}
 	for file in ciso646 cstddef cfloat climits cstdint cstdlib \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 0031f54f3fa..4ab942ae666 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -1906,7 +1906,7 @@ ${pch3_output}: ${pch3_source} ${pch2_output}
 # This is a subset of the full install-headers rule.  We only need <ciso646>,
 # <cstddef>, <cfloat>, <limits>, <climits>, <version>, <cstdint>, <cstdlib>,
 # <new>, <typeinfo>, <exception>, <initializer_list>, <cstdalign>, <cstdarg>,
-# <concepts>, <cstdbool>, <type_traits>, <bit>, <atomic>,
+# <concepts>, <coroutine>, <cstdbool>, <type_traits>, <bit>, <atomic>,
 # and any files which they include (and which we provide).
 # <new>, <typeinfo>, <exception>, <initializer_list> and <compare>
 # are installed by libsupc++, so only the others and the sub-includes
@@ -1921,7 +1921,7 @@ install-freestanding-headers:
 	  ${glibcxx_srcdir}/$(CPU_DEFINES_SRCDIR)/cpu_defines.h; do \
 	  $(INSTALL_DATA) $${file} $(DESTDIR)${host_installdir}; done
 	$(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${std_builddir}
-	for file in limits type_traits atomic bit concepts version; do \
+	for file in limits type_traits atomic bit concepts coroutine version; do \
 	  $(INSTALL_DATA) ${std_builddir}/$${file} $(DESTDIR)${gxx_include_dir}/${std_builddir}; done
 	$(mkinstalldirs) $(DESTDIR)${gxx_include_dir}/${c_base_builddir}
 	for file in ciso646 cstddef cfloat climits cstdint cstdlib \
diff --git a/libstdc++-v3/include/std/coroutine b/libstdc++-v3/include/std/coroutine
index ead5dad9bf0..f4189c7e3fc 100644
--- a/libstdc++-v3/include/std/coroutine
+++ b/libstdc++-v3/include/std/coroutine
@@ -34,22 +34,23 @@
 // It is very likely that earlier versions would work, but they are untested.
 #if __cplusplus >= 201402L
 
-#include <bits/c++config.h>
+#include <type_traits>
+#if __cplusplus > 201703L
+# include <compare>
+#endif
+
+#if !defined __cpp_lib_three_way_comparison && _GLIBCXX_HOSTED
+# include <bits/stl_function.h> // for std::less
+#endif
 
 /**
  * @defgroup coroutines Coroutines
  *
  * Components for supporting coroutine implementations.
+ *
+ * @since C++20 (and since C++14 as a libstdc++ extension)
  */
 
-#if __cplusplus > 201703L && __cpp_impl_three_way_comparison >= 201907L
-#  include <compare>
-#  define _COROUTINES_USE_SPACESHIP 1
-#else
-#  include <bits/stl_function.h> // for std::less
-#  define _COROUTINES_USE_SPACESHIP 0
-#endif
-
 namespace std _GLIBCXX_VISIBILITY (default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -60,25 +61,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   inline namespace __n4861 {
 
-  // 17.12.2 coroutine traits
+  // C++20 17.12.2 coroutine traits
   /// [coroutine.traits]
   /// [coroutine.traits.primary]
   /// If _Result::promise_type is valid and denotes a type then the traits
   /// have a single publicly accessible member, otherwise they are empty.
+  template <typename _Result, typename... _ArgTypes>
+    struct coroutine_traits;
+
   template <typename _Result, typename = void>
    struct __coroutine_traits_impl {};
 
   template <typename _Result>
+#if __cpp_concepts
+    requires requires { typename _Result::promise_type; }
+    struct __coroutine_traits_impl<_Result, void>
+#else
     struct __coroutine_traits_impl<_Result,
-				    __void_t<typename _Result::promise_type>>
+				   __void_t<typename _Result::promise_type>>
+#endif
     {
       using promise_type = typename _Result::promise_type;
     };
 
-  template <typename _Result, typename...>
+  template <typename _Result, typename... _ArgTypes>
     struct coroutine_traits : __coroutine_traits_impl<_Result> {};
 
-  // 17.12.3 Class template coroutine_handle
+  // C++20 17.12.3 Class template coroutine_handle
   /// [coroutine.handle]
   template <typename _Promise = void>
     struct coroutine_handle;
@@ -139,7 +148,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return __a.address() == __b.address();
   }
 
-#if _COROUTINES_USE_SPACESHIP
+#ifdef __cpp_lib_three_way_comparison
   constexpr strong_ordering
   operator<=>(coroutine_handle<> __a, coroutine_handle<> __b) noexcept
   {
@@ -156,7 +165,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   constexpr bool
   operator<(coroutine_handle<> __a, coroutine_handle<> __b) noexcept
   {
+#if _GLIBCXX_HOSTED
     return less<void*>()(__a.address(), __b.address());
+#else
+    return (__UINTPTR_TYPE__)__a.address() < (__UINTPTR_TYPE__)__b.address();
+#endif
   }
 
   constexpr bool
@@ -330,6 +343,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   } // namespace __n4861
 
+#if _GLIBCXX_HOSTED
+  template<typename _Tp> struct hash;
+
+  template<typename _Promise>
+    struct hash<coroutine_handle<_Promise>>
+    {
+      size_t
+      operator()(const coroutine_handle<_Promise>& __h) noexcept
+      {
+	return reinterpret_cast<size_t>(__h.address());
+      }
+    };
+#endif
+
 #else
 #error "the coroutine header requires -fcoroutines"
 #endif


                 reply	other threads:[~2022-01-11 13:29 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220111132938.211A538A9405@sourceware.org \
    --to=redi@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    --cc=libstdc++-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).