stdexec: update to latest commit
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I56cac3d5d7cc00d6efd7c9df62bc134e291a81a3
diff --git a/include/sdbusplus/async/stdexec/__detail/__basic_sender.hpp b/include/sdbusplus/async/stdexec/__detail/__basic_sender.hpp
index c71a879..5f02635 100644
--- a/include/sdbusplus/async/stdexec/__detail/__basic_sender.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__basic_sender.hpp
@@ -16,12 +16,16 @@
#pragma once
#include "../concepts.hpp"
+#include "__concepts.hpp"
+#include "__config.hpp"
#include "__env.hpp"
#include "__execution_fwd.hpp"
#include "__meta.hpp"
#include "__tuple.hpp"
#include "__type_traits.hpp"
+#include <cstddef>
+#include <type_traits>
#include <utility> // for tuple_size/tuple_element
namespace stdexec
@@ -761,13 +765,6 @@
template <__has_id _Sender>
requires(!same_as<__id<_Sender>, _Sender>)
extern __id_name __name_of_v<_Sender>;
-
-template <class _Ty>
-_Ty __remove_rvalue_reference_fn(_Ty&&);
-
-template <class _Ty>
-using __remove_rvalue_reference_t =
- decltype(__detail::__remove_rvalue_reference_fn(__declval<_Ty>()));
} // namespace __detail
} // namespace stdexec
@@ -782,8 +779,7 @@
template <size_t _Idx, class _Impl>
struct tuple_element<_Idx, stdexec::__sexpr<_Impl>>
{
- using type =
- stdexec::__detail::__remove_rvalue_reference_t<stdexec::__call_result_t<
- _Impl, stdexec::__cp, stdexec::__nth_pack_element_t<_Idx>>>;
+ using type = stdexec::__remove_rvalue_reference_t<stdexec::__call_result_t<
+ _Impl, stdexec::__cp, stdexec::__nth_pack_element_t<_Idx>>>;
};
} // namespace std
diff --git a/include/sdbusplus/async/stdexec/__detail/__cpo.hpp b/include/sdbusplus/async/stdexec/__detail/__cpo.hpp
new file mode 100644
index 0000000..7a5d680
--- /dev/null
+++ b/include/sdbusplus/async/stdexec/__detail/__cpo.hpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2024 NVIDIA Corporation
+ *
+ * Licensed under the Apache License Version 2.0 with LLVM Exceptions
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * https://llvm.org/LICENSE.txt
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "__config.hpp"
+#include "__execution_fwd.hpp"
+
+#define STDEXEC_EAT_THIS_this
+#define STDEXEC_EAT_AUTO_auto
+#define STDEXEC_EAT_VOID_void
+
+///////////////////////////////////////////////////////////////////////////////
+/// To hook a customization point like stdexec::get_env, first bring the names
+/// in stdexec::tags into scope:
+///
+/// @code
+/// using namespace stdexec::tags;
+/// @endcode
+///
+/// Then define a member function like this:
+///
+/// @code
+/// STDEXEC_MEMFN_DECL(auto get_env)(this const MySender& self) {
+/// return ...;
+/// }
+/// @endcode
+#define STDEXEC_MEMFN_DECL(...) \
+ friend STDEXEC_TAG_INVOKE(STDEXEC_IS_AUTO(__VA_ARGS__), __VA_ARGS__) \
+ STDEXEC_TAG_INVOKE_ARGS
+
+#define STDEXEC_TAG_INVOKE(_ISAUTO, ...) \
+ STDEXEC_IIF(_ISAUTO, STDEXEC_RETURN_AUTO, STDEXEC_RETURN_TYPE)(__VA_ARGS__) \
+ tag_invoke( \
+ STDEXEC_IIF(_ISAUTO, STDEXEC_TAG_AUTO, STDEXEC_TAG_WHAT)(__VA_ARGS__)
+
+#define STDEXEC_PROBE_AUTO_auto STDEXEC_PROBE(~)
+#define STDEXEC_IS_AUTO(_TY, ...) \
+ STDEXEC_CHECK(STDEXEC_CAT(STDEXEC_PROBE_AUTO_, _TY))
+
+#define STDEXEC_PROBE_VOID_void STDEXEC_PROBE(~)
+#define STDEXEC_IS_VOID(_TY, ...) \
+ STDEXEC_CHECK(STDEXEC_CAT(STDEXEC_PROBE_VOID_, _TY))
+
+#define STDEXEC_RETURN_AUTO(...) auto
+#define STDEXEC_RETURN_TYPE(...) ::stdexec::__arg_type_t<void(__VA_ARGS__())>
+
+#define STDEXEC_TAG_AUTO(...) \
+ STDEXEC_CAT(STDEXEC_CAT(STDEXEC_EAT_AUTO_, __VA_ARGS__), _t)
+#define STDEXEC_TAG_WHAT(...) \
+ STDEXEC_IIF(STDEXEC_IS_VOID(__VA_ARGS__), STDEXEC_TAG_VOID, \
+ STDEXEC_TAG_TYPE) \
+ (__VA_ARGS__)
+
+#define STDEXEC_TAG_VOID(...) \
+ STDEXEC_CAT(STDEXEC_CAT(STDEXEC_EAT_VOID_, __VA_ARGS__), _t)
+#define STDEXEC_TAG_TYPE(...) \
+ ::stdexec::__tag_type_t<STDEXEC_CAT(__VA_ARGS__, _t::*)>
+
+#define STDEXEC_TAG_INVOKE_ARGS(...) \
+ __VA_OPT__(,) STDEXEC_CAT(STDEXEC_EAT_THIS_, __VA_ARGS__))
+
+#if STDEXEC_MSVC()
+#pragma deprecated(STDEXEC_CUSTOM)
+#endif
+
+#if STDEXEC_GCC() || (STDEXEC_CLANG() && __clang_major__ < 14)
+#define STDEXEC_CUSTOM \
+ _Pragma( \
+ "GCC warning \"STDEXEC_CUSTOM is deprecated; use STDEXEC_MEMFN_DECL instead.\"") \
+ STDEXEC_MEMFN_DECL
+#else
+#define STDEXEC_CUSTOM STDEXEC_MEMFN_DECL
+#endif
+
+#if STDEXEC_CLANG() && __clang_major__ >= 14
+#pragma clang deprecated(STDEXEC_CUSTOM, "use STDEXEC_MEMFN_DECL instead.")
+#endif
+
+namespace stdexec
+{
+template <class>
+struct __arg_type;
+
+template <class _Arg>
+struct __arg_type<void(_Arg (*)())>
+{
+ using type = _Arg;
+};
+
+template <class _Fn>
+using __arg_type_t = typename __arg_type<_Fn>::type;
+
+template <class>
+struct __tag_type;
+
+template <class _Ret, class _Tag>
+struct __tag_type<_Ret _Tag::*>
+{
+ using type = _Tag;
+};
+
+template <class _Fn>
+using __tag_type_t = typename __tag_type<_Fn>::type;
+
+namespace tags
+{
+using stdexec::connect_t;
+using stdexec::get_completion_signatures_t;
+using stdexec::get_env_t;
+using stdexec::set_error_t;
+using stdexec::set_stopped_t;
+using stdexec::set_value_t;
+using stdexec::start_t;
+} // namespace tags
+} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__domain.hpp b/include/sdbusplus/async/stdexec/__detail/__domain.hpp
index 3b72e9e..0dcc3a8 100644
--- a/include/sdbusplus/async/stdexec/__detail/__domain.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__domain.hpp
@@ -17,6 +17,8 @@
#include "../functional.hpp"
#include "__basic_sender.hpp"
+#include "__concepts.hpp"
+#include "__config.hpp"
#include "__env.hpp"
#include "__execution_fwd.hpp"
#include "__meta.hpp"
diff --git a/include/sdbusplus/async/stdexec/__detail/__env.hpp b/include/sdbusplus/async/stdexec/__detail/__env.hpp
index 3c0ff09..d9f34b8 100644
--- a/include/sdbusplus/async/stdexec/__detail/__env.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__env.hpp
@@ -18,9 +18,13 @@
#include "../functional.hpp"
#include "../stop_token.hpp"
#include "__concepts.hpp"
+#include "__config.hpp"
#include "__execution_fwd.hpp"
+#include "__meta.hpp"
#include <concepts>
+#include <exception>
+#include <type_traits>
STDEXEC_PRAGMA_PUSH()
STDEXEC_PRAGMA_IGNORE_EDG(probable_guiding_friend)
@@ -382,9 +386,11 @@
{
using __t = __with;
using __id = __with;
- _Value __value_;
+ STDEXEC_ATTRIBUTE((no_unique_address)) _Value __value_;
- constexpr __with(_Value __value) noexcept(
+ __with() = default;
+
+ constexpr explicit __with(_Value __value) noexcept(
__nothrow_decay_copyable<_Value>) :
__value_((_Value&&)__value)
{}
@@ -405,17 +411,6 @@
template <class _Value, class _Tag, class... _Tags>
__with(_Value, _Tag, _Tags...) -> __with<_Value, _Tag, _Tags...>;
-template <class _Tag, class... _Tags>
-struct __without
-{
- using __t = __without;
- using __id = __without;
-
- __without() = default;
-
- constexpr explicit __without(_Tag, _Tags...) noexcept {}
-};
-
template <class _Env>
struct __fwd
{
@@ -437,6 +432,81 @@
template <class _Env>
__fwd(_Env&&) -> __fwd<_Env>;
+template <class _Env>
+struct __ref
+{
+ using __t = __ref;
+ using __id = __ref;
+ const _Env& __env_;
+
+ template <class _Tag>
+ requires tag_invocable<_Tag, const _Env&>
+ friend auto tag_invoke(_Tag, const __ref& __self) //
+ noexcept(nothrow_tag_invocable<_Tag, const _Env&>)
+ -> tag_invoke_result_t<_Tag, const _Env&>
+ {
+ return _Tag()(__self.__env_);
+ }
+};
+
+template <class _Env>
+__ref(_Env&) -> __ref<_Env>;
+
+struct __ref_fn
+{
+ template <class _Env>
+ constexpr auto operator()(_Env&& __env) const
+ {
+ if constexpr (same_as<_Env, _Env&>)
+ {
+ return __ref{(_Env&&)__env};
+ }
+ else
+ {
+ return (_Env&&)__env;
+ }
+ }
+};
+
+template <class _Env, class _Tag, class... _Tags>
+struct __without_ : _Env
+{
+ static_assert(__nothrow_move_constructible<_Env>);
+ using __t = __without_;
+ using __id = __without_;
+
+ constexpr explicit __without_(_Env&& __env, _Tag, _Tags...) noexcept :
+ _Env((_Env&&)__env)
+ {}
+
+ template <__one_of<_Tag, _Tags...> _Key, class _Self>
+ requires(std::is_base_of_v<__without_, __decay_t<_Self>>)
+ friend auto tag_invoke(_Key, _Self&&) noexcept = delete;
+};
+
+struct __without_fn
+{
+ template <class _Env, class _Tag, class... _Tags>
+ constexpr decltype(auto) operator()(_Env&& __env, _Tag,
+ _Tags...) const noexcept
+ {
+ if constexpr (tag_invocable<_Tag, _Env> ||
+ (tag_invocable<_Tags, _Env> || ...))
+ {
+ return __without_{__ref_fn()((_Env&&)__env), _Tag(), _Tags()...};
+ }
+ else
+ {
+ return static_cast<_Env>((_Env&&)__env);
+ }
+ }
+};
+
+inline constexpr __without_fn __without{};
+
+template <class _Env, class _Tag, class... _Tags>
+using __without_t = __result_of<__without, _Env, _Tag, _Tags...>;
+
template <class _Second, class _First>
struct __joined : _Second
{
@@ -457,19 +527,6 @@
}
};
-template <class _Second, class _Tag, class... _Tags>
-struct __joined<_Second, __without<_Tag, _Tags...>> :
- _Second,
- __without<_Tag, _Tags...>
-{
- using __t = __joined;
- using __id = __joined;
-
- template <__one_of<_Tag, _Tags...> _Key, class _Self>
- requires(std::is_base_of_v<__joined, __decay_t<_Self>>)
- friend auto tag_invoke(_Key, _Self&&) noexcept = delete;
-};
-
template <class _Second, class _First>
__joined(_Second&&, _First&&) -> __joined<_Second, _First>;
@@ -505,12 +562,6 @@
{
return {};
}
-
- template <class _Tag, class... _Tags>
- __without<_Tag, _Tags...> operator()(__without<_Tag, _Tags...>) const
- {
- return {};
- }
};
struct __join_fn
@@ -531,61 +582,23 @@
return {};
}
- template <class _Tag, class... _Tags>
- empty_env operator()(__without<_Tag, _Tags...>) const
- {
- return {};
- }
-
template <class _Env>
_Env operator()(_Env&& __env, empty_env) const
{
return (_Env&&)__env;
}
- template <class _Env, class _Tag, class... _Tags>
- _Env operator()(_Env&& __env, __without<_Tag, _Tags...>) const
- {
- return (_Env&&)__env;
- }
-
empty_env operator()(empty_env, empty_env) const
{
return {};
}
- template <class _Tag, class... _Tags>
- empty_env operator()(empty_env, __without<_Tag, _Tags...>) const
- {
- return {};
- }
-
- template <class _Tag, class... _Tags>
- empty_env operator()(__without<_Tag, _Tags...>, empty_env) const
- {
- return {};
- }
-
- template <class _Tag, class... _Tags, class _Tag2, class... _Tags2>
- empty_env operator()(__without<_Tag, _Tags...>,
- __without<_Tag2, _Tags2...>) const
- {
- return {};
- }
-
template <class... Rest>
decltype(auto) operator()(empty_env, Rest&&... rest) const
{
return __fwd_fn()(__join_fn()((Rest&&)rest...));
}
- template <class _Tag, class... _Tags, class... Rest>
- decltype(auto) operator()(__without<_Tag, _Tags...>, Rest&&... rest) const
- {
- return __joined{__fwd_fn()(__join_fn()((Rest&&)rest...)),
- __without<_Tag, _Tags...>()};
- }
-
template <class First, class... Rest>
decltype(auto) operator()(First&& first, Rest&&... rest) const
{
diff --git a/include/sdbusplus/async/stdexec/__detail/__execution_fwd.hpp b/include/sdbusplus/async/stdexec/__detail/__execution_fwd.hpp
index 70393e9..760ae84 100644
--- a/include/sdbusplus/async/stdexec/__detail/__execution_fwd.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__execution_fwd.hpp
@@ -18,6 +18,7 @@
#include "__concepts.hpp"
#include "__config.hpp"
#include "__meta.hpp"
+#include "__type_traits.hpp"
namespace stdexec
{
diff --git a/include/sdbusplus/async/stdexec/__detail/__intrusive_ptr.hpp b/include/sdbusplus/async/stdexec/__detail/__intrusive_ptr.hpp
index 74505f9..efb1399 100644
--- a/include/sdbusplus/async/stdexec/__detail/__intrusive_ptr.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__intrusive_ptr.hpp
@@ -16,11 +16,14 @@
#pragma once
#include "../concepts.hpp"
+#include "__config.hpp"
#include "__meta.hpp"
#include <atomic>
+#include <cstddef>
#include <memory>
#include <new>
+#include <type_traits>
#if STDEXEC_TSAN()
#include <sanitizer/tsan_interface.h>
diff --git a/include/sdbusplus/async/stdexec/__detail/__intrusive_queue.hpp b/include/sdbusplus/async/stdexec/__detail/__intrusive_queue.hpp
index 2ea46b4..ee577de 100644
--- a/include/sdbusplus/async/stdexec/__detail/__intrusive_queue.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__intrusive_queue.hpp
@@ -19,7 +19,7 @@
#include "__config.hpp"
#include <cassert>
-#include <tuple>
+#include <cstddef>
#include <utility>
namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__meta.hpp b/include/sdbusplus/async/stdexec/__detail/__meta.hpp
index 2a4c33b..b350b99 100644
--- a/include/sdbusplus/async/stdexec/__detail/__meta.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__meta.hpp
@@ -20,6 +20,7 @@
#include "__type_traits.hpp"
#include <cassert>
+#include <cstddef>
#include <exception>
#include <type_traits>
#include <utility>
@@ -170,6 +171,9 @@
const char __what_[_Len];
};
+template <std::size_t _Len>
+__mstring(const char (&__str)[_Len]) -> __mstring<_Len>;
+
STDEXEC_PRAGMA_PUSH()
STDEXEC_PRAGMA_IGNORE_GNU("-Wuser-defined-literals")
@@ -1060,21 +1064,6 @@
using __2 = __placeholder<2>;
using __3 = __placeholder<3>;
-template <class _Ty, class _Noexcept = __mbool<true>>
-struct __mconstruct
-{
- template <class... _As>
- auto operator()(_As&&... __as) const
- noexcept(__v<_Noexcept>&& noexcept(_Ty((_As&&)__as...)))
- -> decltype(_Ty((_As&&)__as...))
- {
- return _Ty((_As&&)__as...);
- }
-};
-
-template <template <class...> class _Cp, class _Noexcept = __mbool<true>>
-using __mconstructor_for = __mcompose<__q<__mconstruct>, __q<_Cp>>;
-
#if STDEXEC_MSVC()
// MSVCBUG
// https://developercommunity.visualstudio.com/t/Incorrect-function-template-argument-sub/10437827
diff --git a/include/sdbusplus/async/stdexec/__detail/__scope.hpp b/include/sdbusplus/async/stdexec/__detail/__scope.hpp
index ee1847d..1081269 100644
--- a/include/sdbusplus/async/stdexec/__detail/__scope.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__scope.hpp
@@ -15,6 +15,7 @@
*/
#pragma once
+#include "__config.hpp"
#include "__meta.hpp"
namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/__detail/__tuple.hpp b/include/sdbusplus/async/stdexec/__detail/__tuple.hpp
index cc91dd1..d5939f5 100644
--- a/include/sdbusplus/async/stdexec/__detail/__tuple.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__tuple.hpp
@@ -15,8 +15,12 @@
*/
#pragma once
+#include "__concepts.hpp"
#include "__config.hpp"
#include "__meta.hpp"
+#include "__type_traits.hpp"
+
+#include <cstddef>
namespace stdexec
{
diff --git a/include/sdbusplus/async/stdexec/__detail/__type_traits.hpp b/include/sdbusplus/async/stdexec/__detail/__type_traits.hpp
index 2ec69d6..0e8cae5 100644
--- a/include/sdbusplus/async/stdexec/__detail/__type_traits.hpp
+++ b/include/sdbusplus/async/stdexec/__detail/__type_traits.hpp
@@ -186,4 +186,14 @@
inline constexpr bool __is_const<const _Up> = true;
#endif
+namespace __tt
+{
+template <class _Ty>
+_Ty __remove_rvalue_reference_fn(_Ty&&);
+}
+
+template <class _Ty>
+using __remove_rvalue_reference_t =
+ decltype(__tt::__remove_rvalue_reference_fn(__declval<_Ty>()));
+
} // namespace stdexec
diff --git a/include/sdbusplus/async/stdexec/any_sender_of.hpp b/include/sdbusplus/async/stdexec/any_sender_of.hpp
index 42f5302..6805648 100644
--- a/include/sdbusplus/async/stdexec/any_sender_of.hpp
+++ b/include/sdbusplus/async/stdexec/any_sender_of.hpp
@@ -15,11 +15,14 @@
*/
#pragma once
+#include "../stdexec/concepts.hpp"
#include "../stdexec/execution.hpp"
+#include "../stdexec/functional.hpp"
#include <sdbusplus/async/stdexec/sequence_senders.hpp>
#include <cstddef>
+#include <utility>
namespace exec
{
diff --git a/include/sdbusplus/async/stdexec/async_scope.hpp b/include/sdbusplus/async/stdexec/async_scope.hpp
index 1669953..524f11c 100644
--- a/include/sdbusplus/async/stdexec/async_scope.hpp
+++ b/include/sdbusplus/async/stdexec/async_scope.hpp
@@ -17,8 +17,11 @@
#include "../stdexec/__detail/__intrusive_queue.hpp"
#include "../stdexec/execution.hpp"
+#include "../stdexec/stop_token.hpp"
#include "env.hpp"
+#include <mutex>
+
namespace exec
{
/////////////////////////////////////////////////////////////////////////////
diff --git a/include/sdbusplus/async/stdexec/commit.info b/include/sdbusplus/async/stdexec/commit.info
index 96d8212..0e54be9 100644
--- a/include/sdbusplus/async/stdexec/commit.info
+++ b/include/sdbusplus/async/stdexec/commit.info
@@ -1 +1 @@
-ad16d4a45053f7d16f037e08b51c11c0cb305ecc
+2c19548b9e38f54ef7b8d8d4e49920afe43b9ede
diff --git a/include/sdbusplus/async/stdexec/concepts.hpp b/include/sdbusplus/async/stdexec/concepts.hpp
index 17f5467..79a9740 100644
--- a/include/sdbusplus/async/stdexec/concepts.hpp
+++ b/include/sdbusplus/async/stdexec/concepts.hpp
@@ -19,6 +19,11 @@
#error This library requires support for C++20 concepts
#endif
+#include "__detail/__concepts.hpp"
+#include "__detail/__config.hpp"
+#include "__detail/__meta.hpp"
+#include "__detail/__type_traits.hpp"
+
#include <version>
// Perhaps the stdlib lacks support for concepts though:
@@ -34,9 +39,6 @@
#include <type_traits>
#endif
-#include "__detail/__concepts.hpp"
-#include "__detail/__meta.hpp"
-
namespace stdexec::__std_concepts
{
// Make sure we're using a same_as concept that doesn't instantiate std::is_same
diff --git a/include/sdbusplus/async/stdexec/coroutine.hpp b/include/sdbusplus/async/stdexec/coroutine.hpp
index 3391043..b5f9645 100644
--- a/include/sdbusplus/async/stdexec/coroutine.hpp
+++ b/include/sdbusplus/async/stdexec/coroutine.hpp
@@ -15,6 +15,8 @@
*/
#pragma once
+#include "__detail/__concepts.hpp"
+#include "__detail/__config.hpp"
#include "concepts.hpp"
#include <version>
diff --git a/include/sdbusplus/async/stdexec/env.hpp b/include/sdbusplus/async/stdexec/env.hpp
index 30f1a70..4df755c 100644
--- a/include/sdbusplus/async/stdexec/env.hpp
+++ b/include/sdbusplus/async/stdexec/env.hpp
@@ -22,12 +22,10 @@
namespace exec
{
-template <class _Tag, class _Value = void>
-using with_t = stdexec::__if_c<stdexec::same_as<_Value, void>,
- stdexec::__env::__without<_Tag>,
- stdexec::__env::__with<_Value, _Tag>>;
+template <class _Tag, class _Value>
+using with_t = stdexec::__env::__with<_Value, _Tag>;
-namespace __detail
+namespace __envs
{
struct __with_t
{
@@ -36,20 +34,14 @@
{
return stdexec::__env::__with((_Value&&)__val, _Tag());
}
-
- template <class _Tag>
- [[deprecated("use exec::without(Tag) instead")]] auto operator()(_Tag) const
- {
- return stdexec::__env::__without(_Tag());
- }
};
struct __without_t
{
- template <class _Tag>
- auto operator()(_Tag) const
+ template <class _Env, class _Tag>
+ decltype(auto) operator()(_Env&& __env, _Tag) const
{
- return stdexec::__env::__without(_Tag());
+ return stdexec::__env::__without((_Env&&)__env, _Tag());
}
};
@@ -71,12 +63,11 @@
return (_Env&&)__env;
}
};
-} // namespace __detail
+} // namespace __envs
-inline constexpr __detail::__with_t with{};
-inline constexpr __detail::__without_t without{};
-
-inline constexpr __detail::__make_env_t make_env{};
+inline constexpr __envs::__with_t with{};
+inline constexpr __envs::__without_t without{};
+inline constexpr __envs::__make_env_t make_env{};
template <class... _Ts>
using make_env_t = stdexec::__result_of<make_env, _Ts...>;
diff --git a/include/sdbusplus/async/stdexec/execution.hpp b/include/sdbusplus/async/stdexec/execution.hpp
index cceb182..36c5013 100644
--- a/include/sdbusplus/async/stdexec/execution.hpp
+++ b/include/sdbusplus/async/stdexec/execution.hpp
@@ -16,12 +16,15 @@
#pragma once
#include "__detail/__basic_sender.hpp"
+#include "__detail/__config.hpp"
+#include "__detail/__cpo.hpp"
#include "__detail/__domain.hpp"
#include "__detail/__env.hpp"
#include "__detail/__execution_fwd.hpp"
#include "__detail/__intrusive_ptr.hpp"
#include "__detail/__meta.hpp"
#include "__detail/__scope.hpp"
+#include "__detail/__type_traits.hpp"
#include "__detail/__utility.hpp"
#include "concepts.hpp"
#include "coroutine.hpp"
@@ -32,6 +35,8 @@
#include <cassert>
#include <concepts>
#include <condition_variable>
+#include <cstddef>
+#include <exception>
#include <memory>
#include <mutex>
#include <optional>
@@ -39,6 +44,7 @@
#include <system_error>
#include <tuple>
#include <type_traits>
+#include <utility>
#include <variant>
STDEXEC_PRAGMA_PUSH()
@@ -1842,10 +1848,26 @@
};
};
+// BUGBUG NOT TO SPEC: make senders of more-than-one-value awaitable
+// by packaging the values into a tuple.
+// See: https://github.com/cplusplus/sender-receiver/issues/182
+template <std::size_t _Count>
+extern const __q<std::tuple> __as_single;
+
+template <>
+inline const __q<__midentity> __as_single<1>;
+
+template <>
+inline const __mconst<void> __as_single<0>;
+
+template <class... _Values>
+using __single_value =
+ __minvoke<decltype(__as_single<sizeof...(_Values)>), _Values...>;
+
template <class _Sender, class _Promise>
using __value_t =
__decay_t<__value_types_of_t<_Sender, env_of_t<_Promise&>,
- __msingle_or<void>, __msingle_or<void>>>;
+ __q<__single_value>, __msingle_or<void>>>;
template <class _Sender, class _Promise>
using __receiver_t =
@@ -3832,7 +3854,7 @@
{
template <sender _Sender, class _Env = empty_env>
requires sender_in<_Sender, _Env> && __decay_copyable<env_of_t<_Sender>>
- auto operator()(_Sender&& __sndr, _Env&& __env = {}) const
+ [[nodiscard]] auto operator()(_Sender&& __sndr, _Env&& __env = {}) const
{
if constexpr (sender_expr_for<_Sender, __ensure_started_t>)
{
@@ -3975,9 +3997,9 @@
template <same_as<get_env_t> _Tag>
friend auto tag_invoke(_Tag, const __receiver_with_sched& __self) noexcept
{
- return __env::__join(__env::__with(__self.__sched_, get_scheduler),
- __env::__without(get_domain),
- get_env(__self.__rcvr_));
+ return __env::__join(
+ __env::__with(__self.__sched_, get_scheduler),
+ __env::__without(get_env(__self.__rcvr_), get_domain));
}
};
@@ -3991,7 +4013,7 @@
using __result_env_t =
__if_c<__unknown_context<_Scheduler>, _Env,
__env::__join_t<__env::__with<_Scheduler, get_scheduler_t>,
- __env::__without<get_domain_t>, _Env>>;
+ __env::__without_t<_Env, get_domain_t>>>;
template <class _Tp>
using __decay_ref = __decay_t<_Tp>&;
@@ -4024,7 +4046,7 @@
template <class _Sender, class _Env, class _Set>
using __ensure_sender = //
__minvoke_if_c<sender_in<_Sender, _Env>, __q<__midentity>,
- __mbind_back_q<__bad_result_sender, _Set, _Env>, _Sender>;
+ __mbind_back_q<__bad_result_sender, _Env, _Set>, _Sender>;
// A metafunction that computes the result sender type for a given set of
// argument types
@@ -4138,7 +4160,7 @@
__env::__with(get_completion_scheduler<_Set>(
stdexec::get_env(__child)),
get_scheduler),
- __env::__without(get_domain), __env);
+ __env::__without(__env, get_domain));
}
}
STDEXEC_UNREACHABLE();
@@ -4767,6 +4789,7 @@
template <class _SchedulerId>
struct __environ
{
+ using _Scheduler = stdexec::__t<_SchedulerId>;
struct __t :
__env::__with<stdexec::__t<_SchedulerId>,
get_completion_scheduler_t<set_value_t>,
@@ -4774,6 +4797,10 @@
{
using __id = __environ;
+ explicit __t(_Scheduler __sched) noexcept :
+ __t::__with{std::move(__sched)}
+ {}
+
template <same_as<get_domain_t> _Key>
friend auto tag_invoke(_Key, const __t& __self) noexcept
{
@@ -5163,17 +5190,18 @@
namespace __detail
{
-template <class _Scheduler>
+template <class _Env, class _Scheduler>
STDEXEC_ATTRIBUTE((always_inline))
-auto __mkenv_sched(_Scheduler __sched)
+auto __mkenv_sched(_Env&& __env, _Scheduler __sched)
{
- auto __env = __env::__join(__env::__with(__sched, get_scheduler),
- __env::__without(get_domain));
+ auto __env2 = __env::__join(__env::__with(__sched, get_scheduler),
+ __env::__without((_Env&&)__env, get_domain));
+ using _Env2 = decltype(__env2);
- struct __env_t : decltype(__env)
+ struct __env_t : _Env2
{};
- return __env_t{__env};
+ return __env_t{(_Env2&&)__env2};
}
template <class _Ty, class = __name_of<__decay_t<_Ty>>>
@@ -5216,8 +5244,7 @@
static auto __transform_env_fn(_Env&& __env) noexcept
{
return [&](__ignore, auto __sched, __ignore) noexcept {
- return __env::__join(__detail::__mkenv_sched(__sched),
- (_Env&&)__env);
+ return __detail::__mkenv_sched((_Env&&)__env, __sched);
};
}
@@ -5273,7 +5300,8 @@
{
auto __domain = __get_early_domain(__sndr);
return stdexec::transform_sender(
- __domain, __make_sexpr<into_variant_t>(__(), std::move(__sndr)));
+ __domain,
+ __make_sexpr<into_variant_t>(__(), std::forward<_Sender>(__sndr)));
}
STDEXEC_ATTRIBUTE((always_inline)) //
@@ -5803,9 +5831,8 @@
__t<__schedule_from::__environ<__id<__decay_t<_Scheduler>>>>;
auto __domain = query_or(get_domain, __sched, default_domain());
return stdexec::transform_sender(
- __domain,
- __make_sexpr<transfer_when_all_t>(_Env{{(_Scheduler&&)__sched}},
- (_Senders&&)__sndrs...));
+ __domain, __make_sexpr<transfer_when_all_t>(
+ _Env{(_Scheduler&&)__sched}, (_Senders&&)__sndrs...));
}
template <class _Sender, class _Env>
@@ -6144,8 +6171,7 @@
static auto __transform_env_fn(_Env&& __env) noexcept
{
return [&](__ignore, auto __sched, __ignore) noexcept {
- return __env::__join(__detail::__mkenv_sched(__sched),
- (_Env&&)__env);
+ return __detail::__mkenv_sched((_Env&&)__env, __sched);
};
}
@@ -6183,6 +6209,26 @@
__continue_on_data(_Scheduler, _Closure)
-> __continue_on_data<_Scheduler, _Closure>;
+template <class _Scheduler>
+struct __with_sched
+{
+ _Scheduler __sched_;
+
+ friend _Scheduler tag_invoke(get_scheduler_t,
+ const __with_sched& __self) noexcept
+ {
+ return __self.__sched_;
+ }
+
+ friend auto tag_invoke(get_domain_t, const __with_sched& __self) noexcept
+ {
+ return query_or(get_domain, __self.__sched_, default_domain());
+ }
+};
+
+template <class _Scheduler>
+__with_sched(_Scheduler) -> __with_sched<_Scheduler>;
+
struct continue_on_t : __no_scheduler_in_environment
{
template <sender _Sender, scheduler _Scheduler,
@@ -6219,12 +6265,12 @@
__ignore, _Data&& __data, _Child&& __child) {
auto&& [__sched, __clsur] = (_Data&&)__data;
using _Closure = decltype(__clsur);
- return __write(transfer(((_Closure&&)__clsur)(transfer(
- __write((_Child&&)__child,
- __detail::__mkenv_sched(__old)),
- __sched)),
- __old),
- __detail::__mkenv_sched(__sched));
+ return __write(
+ transfer(((_Closure&&)__clsur)(transfer(
+ __write((_Child&&)__child, __with_sched{__old}),
+ __sched)),
+ __old),
+ __with_sched{__sched});
});
}
};
diff --git a/include/sdbusplus/async/stdexec/functional.hpp b/include/sdbusplus/async/stdexec/functional.hpp
index b0bcc0f..a19719c 100644
--- a/include/sdbusplus/async/stdexec/functional.hpp
+++ b/include/sdbusplus/async/stdexec/functional.hpp
@@ -19,8 +19,10 @@
#include "__detail/__meta.hpp"
#include "concepts.hpp"
+#include <cstddef>
#include <functional>
#include <tuple>
+#include <type_traits>
namespace stdexec::__std_concepts
{
diff --git a/include/sdbusplus/async/stdexec/stop_token.hpp b/include/sdbusplus/async/stdexec/stop_token.hpp
index e23ee1f..9efd84e 100644
--- a/include/sdbusplus/async/stdexec/stop_token.hpp
+++ b/include/sdbusplus/async/stdexec/stop_token.hpp
@@ -16,7 +16,11 @@
*/
#pragma once
+#include "__detail/__config.hpp"
+#include "concepts.hpp"
+
#include <atomic>
+#include <concepts>
#include <cstdint>
#include <thread>
#include <type_traits>
@@ -27,9 +31,6 @@
#include <stop_token>
#endif
-#include "__detail/__config.hpp"
-#include "concepts.hpp"
-
namespace stdexec
{
// [stoptoken.inplace], class in_place_stop_token