Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/stdexec/__detail/__config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,12 @@ namespace STDEXEC
# define STDEXEC_NO_STDCPP_PACK_INDEXING() 1
#endif // no pack indexing

#if __cpp_impl_reflection >= 202506L && __cpp_lib_reflection >= 202506L
# define STDEXEC_NO_STDCPP_REFLECTION() 0
#else
# define STDEXEC_NO_STDCPP_REFLECTION() 1
#endif

#if STDEXEC_HAS_FEATURE(thread_sanitizer) || defined(__SANITIZE_THREAD__)
# define STDEXEC_TSAN() 1
#else
Expand Down
119 changes: 116 additions & 3 deletions include/stdexec/__detail/__get_completion_signatures.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ import stdexec;
# include "__tag_invoke.hpp"
# include "__tuple.hpp" // IWYU pragma: keep for __tuple

# if !STDEXEC_NO_STDCPP_REFLECTION()
# include <meta>
# endif

# include "__prologue.hpp"

namespace STDEXEC
Expand Down Expand Up @@ -62,6 +66,16 @@ namespace STDEXEC

struct _A_GET_COMPLETION_SIGNATURES_CUSTOMIZATION_RETURNED_A_TYPE_THAT_IS_NOT_A_COMPLETION_SIGNATURES_SPECIALIZATION;

# if !STDEXEC_NO_STDCPP_REFLECTION()
STDEXEC_MODULE_EXPORT
template <class _Sender>
consteval std::meta::info get_completion_signatures_type();

STDEXEC_MODULE_EXPORT
template <class _Sender, class _Env>
consteval std::meta::info get_completion_signatures_type();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since these are non-standard, they should be renamed __get_completion_signatures_type. We can then expose them with non-uglified names in namespace experimental::execution::.

# endif

namespace __cmplsigs
{
# define STDEXEC_GET_COMPLSIGS(...) \
Expand Down Expand Up @@ -162,6 +176,28 @@ namespace STDEXEC
template <class _Sender, class... _Env>
concept __with_co_await = __awaitable<_Sender, __detail::__promise<_Env>...>;

# if !STDEXEC_NO_STDCPP_REFLECTION()
template <class _Sender, class... _Env>
concept __has_get_completion_signatures_type = requires {
{
STDEXEC_REMOVE_REFERENCE(_Sender)
::template get_completion_signatures_type<_Sender, _Env...>()
} -> __std::same_as<std::meta::info>;
};

template <class _Sender, class... _Env>
consteval bool __nothrow_get_completion_signatures_type() noexcept
try
{
(void) STDEXEC::get_completion_signatures_type<_Sender, _Env...>();
return true;
}
catch (...)
{
return false;
}
# endif

template <class _Sender, class _Env>
concept __with = __with_legacy_static_member<_Sender, _Env> //
|| __with_legacy_member<_Sender, _Env> //
Expand All @@ -170,7 +206,11 @@ namespace STDEXEC
|| __with_consteval_static_member<_Sender> //
|| __with_legacy_tag_invoke<_Sender, _Env> //
|| __with_legacy_non_dependent_tag_invoke<_Sender, _Env> //
|| __with_co_await<_Sender, _Env>;
|| __with_co_await<_Sender, _Env>
# if !STDEXEC_NO_STDCPP_REFLECTION()
|| __has_get_completion_signatures_type<_Sender, _Env>
# endif
;
} // namespace __cmplsigs

template <class _Sender, class _Env>
Expand Down Expand Up @@ -354,7 +394,26 @@ namespace STDEXEC
template <class _Sender>
consteval auto get_completion_signatures()
{
return __cmplsigs::__get_completion_signatures_helper<_Sender>();
# if !STDEXEC_NO_STDCPP_REFLECTION()
if constexpr (__cmplsigs::__has_get_completion_signatures_type<_Sender>)
{
if constexpr (__cmplsigs::__nothrow_get_completion_signatures_type<_Sender>())
{
constexpr std::meta::info __completions =
STDEXEC::get_completion_signatures_type<_Sender>();
return typename[:__completions:]{};
}
else
{
(void) STDEXEC::get_completion_signatures_type<_Sender>();
return completion_signatures<>{};
}
}
else
# endif
{
return __cmplsigs::__get_completion_signatures_helper<_Sender>();
}
}

//! @brief Overload of @ref get_completion_signatures that takes an
Expand All @@ -377,9 +436,63 @@ namespace STDEXEC
{
using __new_sndr_t = transform_sender_result_t<_Sender, _Env>;
static_assert(!__merror<__new_sndr_t>);
return __cmplsigs::__get_completion_signatures_helper<__new_sndr_t, _Env>();
# if !STDEXEC_NO_STDCPP_REFLECTION()
if constexpr (__cmplsigs::__has_get_completion_signatures_type<__new_sndr_t, _Env>)
{
if constexpr (__cmplsigs::__nothrow_get_completion_signatures_type<_Sender, _Env>())
{
constexpr std::meta::info __completions =
STDEXEC::get_completion_signatures_type<_Sender, _Env>();
return typename[:__completions:]{};
}
else
{
(void) STDEXEC::get_completion_signatures_type<_Sender, _Env>();
return completion_signatures<>{};
}
}
else
# endif
{
return __cmplsigs::__get_completion_signatures_helper<__new_sndr_t, _Env>();
}
}

# if !STDEXEC_NO_STDCPP_REFLECTION()
STDEXEC_MODULE_EXPORT
template <class _Sender>
consteval std::meta::info get_completion_signatures_type()
{
if constexpr (__cmplsigs::__has_get_completion_signatures_type<_Sender>)
{
return STDEXEC_REMOVE_REFERENCE(_Sender)::template get_completion_signatures_type<_Sender>();
}
else
{
auto __completions = STDEXEC::get_completion_signatures<_Sender>();
return ^^decltype(__completions);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wonder if it would be possible to polyfill the reflection needed here with the friend-injection-based typeid facility in __typeinfo.hpp.

}
}

STDEXEC_MODULE_EXPORT
template <class _Sender, class _Env>
consteval std::meta::info get_completion_signatures_type()
{
using __new_sndr_t = transform_sender_result_t<_Sender, _Env>;
static_assert(!__merror<__new_sndr_t>);
if constexpr (__cmplsigs::__has_get_completion_signatures_type<__new_sndr_t, _Env>)
{
return STDEXEC_REMOVE_REFERENCE(
__new_sndr_t)::template get_completion_signatures_type<__new_sndr_t, _Env>();
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we should also look for __new_sndr_t::get_completion_signatures_type<__new_sndr_t>(). that is, a non-dependent sender may implement get_completion_signatures_type without an Env tparam.

else
{
auto __completions = STDEXEC::get_completion_signatures<_Sender, _Env>();
return ^^decltype(__completions);
}
}
# endif

// Legacy interface:
STDEXEC_MODULE_EXPORT_AUTHORING
template <class _Sender, class... _Env>
Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ set(stdexec_test_sources
stdexec/detail/test_common_domain.cpp
stdexec/detail/test_completion_signatures.cpp
stdexec/detail/test_demangle.cpp
stdexec/detail/test_get_completion_signatures.cpp
stdexec/detail/test_intrusive_mpsc_queue.cpp
stdexec/detail/test_utility.cpp
stdexec/queries/test_env.cpp
Expand Down
Loading