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 , # , , , , , , , # , , , , , , -# , , , , , +# , , , , , , # and any files which they include (and which we provide). # , , , and # 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 , # , , , , , , , # , , , , , , -# , , , , , +# , , , , , , # and any files which they include (and which we provide). # , , , and # 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 +#include +#if __cplusplus > 201703L +# include +#endif + +#if !defined __cpp_lib_three_way_comparison && _GLIBCXX_HOSTED +# include // 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 -# define _COROUTINES_USE_SPACESHIP 1 -#else -# include // 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 + struct coroutine_traits; + template struct __coroutine_traits_impl {}; template +#if __cpp_concepts + requires requires { typename _Result::promise_type; } + struct __coroutine_traits_impl<_Result, void> +#else struct __coroutine_traits_impl<_Result, - __void_t> + __void_t> +#endif { using promise_type = typename _Result::promise_type; }; - template + template 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 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()(__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 struct hash; + + template + struct hash> + { + size_t + operator()(const coroutine_handle<_Promise>& __h) noexcept + { + return reinterpret_cast(__h.address()); + } + }; +#endif + #else #error "the coroutine header requires -fcoroutines" #endif