From 910d8a782155472cf447573a94c3e1a2613fc4c8 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Wed, 4 Mar 2026 11:46:47 -0800 Subject: [PATCH] allow for `stdexec::type_info` to be expanded in the future --- .clangd | 4 +- include/stdexec/__detail/__config.hpp | 13 +++++ .../__detail/__parallel_scheduler_backend.hpp | 1 + include/stdexec/__detail/__typeinfo.hpp | 55 +++++++++++++++++-- include/stdexec/__detail/__utility.hpp | 2 +- 5 files changed, 67 insertions(+), 8 deletions(-) diff --git a/.clangd b/.clangd index b98e6d58e..fc9bf1414 100644 --- a/.clangd +++ b/.clangd @@ -40,6 +40,9 @@ CompileFlags: - "-Wno-unknown-cuda-version" - "--cuda-host-only" - "--cuda-path=/usr/local/cuda-12" + Remove: + - "-x" + - "c++-header" --- @@ -54,7 +57,6 @@ CompileFlags: - "-ftemplate-backtrace-limit=0" - "-std=c++20" - "-DSTDEXEC_CLANGD_INVOKED" - - "-stdlib=libc++" - "-Wno-unused-local-typedef" Remove: - "-stdpar*" diff --git a/include/stdexec/__detail/__config.hpp b/include/stdexec/__detail/__config.hpp index 294226160..ac7002a0d 100644 --- a/include/stdexec/__detail/__config.hpp +++ b/include/stdexec/__detail/__config.hpp @@ -602,6 +602,19 @@ namespace STDEXEC # define STDEXEC_NO_STDCPP_EXPLICIT_THIS_PARAMETER() 1 #endif +#if defined(__cpp_rtti) && __cpp_rtti >= 1997'11L +# define STDEXEC_NO_STDCPP_RTTI() 0 +#else +# define STDEXEC_NO_STDCPP_RTTI() 1 +#endif + +// MSVC always has typeid support, even when RTTI is disabled +#if STDEXEC_NO_STDCPP_RTTI() && !STDEXEC_MSVC() +# define STDEXEC_NO_STDCPP_TYPEID() 1 +#else +# define STDEXEC_NO_STDCPP_TYPEID() 0 +#endif + // Perhaps the stdlib lacks support for concepts #if __has_include() && __cpp_lib_concepts >= 2020'02L # define STDEXEC_NO_STDCPP_CONCEPTS_HEADER() 0 diff --git a/include/stdexec/__detail/__parallel_scheduler_backend.hpp b/include/stdexec/__detail/__parallel_scheduler_backend.hpp index 9f1459401..a259b014f 100644 --- a/include/stdexec/__detail/__parallel_scheduler_backend.hpp +++ b/include/stdexec/__detail/__parallel_scheduler_backend.hpp @@ -25,6 +25,7 @@ #include "__any_allocator.hpp" #include "__optional.hpp" #include "__queries.hpp" +#include "__schedulers.hpp" #include "__typeinfo.hpp" #include diff --git a/include/stdexec/__detail/__typeinfo.hpp b/include/stdexec/__detail/__typeinfo.hpp index 3a5414086..0fc6eca64 100644 --- a/include/stdexec/__detail/__typeinfo.hpp +++ b/include/stdexec/__detail/__typeinfo.hpp @@ -23,6 +23,10 @@ #include #include +#include + +STDEXEC_PRAGMA_PUSH() +STDEXEC_PRAGMA_IGNORE_GNU("-Wunused-private-field") ////////////////////////////////////////////////////////////////////////////////////////// // __type_info, __mtypeid, and __mtypeof @@ -36,12 +40,14 @@ namespace STDEXEC constexpr __type_info(__type_info &&) = delete; constexpr __type_info &operator=(__type_info &&) = delete; - constexpr explicit __type_info(std::string_view __name) noexcept + constexpr explicit __type_info(std::string_view __name, + std::type_info const *__type = nullptr) noexcept : __name_(__name) + , __type_(__type) {} [[nodiscard]] - constexpr std::string_view name() const noexcept + constexpr auto name() const noexcept -> std::string_view { return __name_; } @@ -52,17 +58,38 @@ namespace STDEXEC return this == &__other || __name_ == __other.__name_; } - constexpr auto - operator<=>(__type_info const &) const noexcept -> std::strong_ordering = default; + constexpr auto operator<=>(__type_info const &__other) const noexcept -> std::strong_ordering + { + return __name_ <=> __other.__name_; + } + +#if !STDEXEC_NO_STDCPP_TYPEID() + [[nodiscard]] + constexpr auto type() const noexcept -> std::type_info const & + { + return *__type_; + } + + [[nodiscard]] + constexpr operator std::type_info const &() const noexcept + { + return *__type_; + } +#endif private: - std::string_view __name_; + std::string_view const __name_; + std::type_info const *const __type_ = nullptr; // used only if !STDEXEC_NO_STDCPP_TYPEID() + void const *const __reserved_ = nullptr; // reserved for future use }; namespace __detail { template - inline constexpr __type_info __mtypeid_v{__mnameof<_Ty>}; + inline constexpr __type_info __mtypeid_v{ + __mnameof<_Ty> // + STDEXEC_PP_WHEN(STDEXEC_PP_NOT(STDEXEC_NO_STDCPP_TYPEID()), , &typeid(_Ty)) // + }; template inline constexpr __type_info const &__mtypeid_v<_Ty const> = __mtypeid_v<_Ty>; @@ -94,6 +121,20 @@ namespace STDEXEC return *__info_ <=> *other.__info_; } +#if !STDEXEC_NO_STDCPP_TYPEID() + [[nodiscard]] + constexpr auto type() const noexcept -> std::type_info const & + { + return (*__info_).type(); + } + + [[nodiscard]] + constexpr operator std::type_info const &() const noexcept + { + return (*__info_).type(); + } +#endif + __type_info const *__info_; }; @@ -139,3 +180,5 @@ namespace STDEXEC // Sanity check: static_assert(STDEXEC_IS_SAME(void, __mtypeof<__mtypeid>)); } // namespace STDEXEC + +STDEXEC_PRAGMA_POP() diff --git a/include/stdexec/__detail/__utility.hpp b/include/stdexec/__detail/__utility.hpp index 3cab5f038..1be46dfb2 100644 --- a/include/stdexec/__detail/__utility.hpp +++ b/include/stdexec/__detail/__utility.hpp @@ -312,7 +312,7 @@ namespace STDEXEC static_assert(std::derived_from<__value_type, _CvInterface>, "__polymorphic_downcast requires From to be a base class of To"); -#if defined(__cpp_rtti) && __cpp_rtti >= 1997'11L +#if !STDEXEC_NO_STDCPP_RTTI() STDEXEC_IF_NOT_CONSTEVAL { STDEXEC_ASSERT(dynamic_cast<__value_type*>(__from_ptr) != nullptr);