Skip to content

Commit 165e725

Browse files
authored
Merge pull request #1826 from ericniebler/std-this_thread-sync_wait
define types directly in namespaces specified by the standard
2 parents b62ecdf + 9d55687 commit 165e725

File tree

81 files changed

+2702
-2742
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+2702
-2742
lines changed

examples/nvexec/launch.cu

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323

2424
#include <thrust/device_vector.h>
2525

26-
constexpr std::size_t N = 2 * 1024;
27-
constexpr std::size_t THREAD_BLOCK_SIZE = 128u;
26+
constexpr std::size_t N = 2ul * 1024ul;
27+
constexpr std::size_t THREAD_BLOCK_SIZE = 128ul;
2828
constexpr std::size_t NUM_BLOCKS = (N + THREAD_BLOCK_SIZE - 1) / THREAD_BLOCK_SIZE;
2929

3030
enum {
@@ -46,12 +46,13 @@ auto main() -> int {
4646

4747
nvexec::stream_context stream{};
4848

49-
auto snd = stdexec::transfer_just(stream.get_scheduler(), first, last)
49+
auto snd = stdexec::just(first, last) //
50+
| stdexec::continues_on(stream.get_scheduler())
5051
| nvexec::launch(
5152
{.grid_size = NUM_BLOCKS, .block_size = THREAD_BLOCK_SIZE},
5253
[](cudaStream_t, int* first, int* last) {
5354
assert(nvexec::is_on_gpu());
54-
int32_t idx = blockIdx.x * blockDim.x + threadIdx.x;
55+
ptrdiff_t idx = blockIdx.x * blockDim.x + threadIdx.x;
5556
if (idx < (last - first)) {
5657
first[idx] *= scaling;
5758
}

examples/nvexec/reduce.cu

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
#include <thrust/device_vector.h>
2121

22-
#include <cstdio>
22+
#include <iostream>
2323
#include <span>
2424

2525
namespace ex = stdexec;
@@ -32,7 +32,8 @@ auto main() -> int {
3232

3333
nvexec::stream_context stream_ctx{};
3434

35-
auto snd = ex::transfer_just(stream_ctx.get_scheduler(), std::span{first, last})
35+
auto snd = ex::just(std::span{first, last}) //
36+
| ex::continues_on(stream_ctx.get_scheduler()) //
3637
| nvexec::reduce(42.0f);
3738

3839
auto [result] = stdexec::sync_wait(std::move(snd)).value();

examples/server_theme/let_value.cpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,20 @@
2424
* - optional GPU context that may be used on some types of servers
2525
*
2626
* Specific problem description:
27-
* - we are looking at the flow of processing an HTTP request and sending back
28-
* the response
29-
* - show how one can break the (slightly complex) flow into steps with let_*
30-
* functions
31-
* - different phases of processing HTTP requests are broken down into separate
32-
* concerns
33-
* - each part of the processing might use different execution contexts (details
34-
* not shown in this example)
35-
* - error handling is generic, regardless which component fails; we always send
36-
* the right response to the clients
27+
*
28+
* - we are looking at the flow of processing an HTTP request and sending back the
29+
* response
30+
* - show how one can break the (slightly complex) flow into steps with let_* functions
31+
* - different phases of processing HTTP requests are broken down into separate concerns
32+
* - each part of the processing might use different execution contexts (details not shown
33+
* in this example)
34+
* - error handling is generic, regardless which component fails; we always send the right
35+
* response to the clients
3736
*
3837
* Example goals:
3938
* - show how one can break more complex flows into steps with let_* functions
40-
* - exemplify the use of let_value, let_error, let_stopped, transfer_just and just
41-
* algorithms
39+
* - exemplify the use of let_value, let_error, let_stopped, continues_on and just
40+
* algorithms
4241
*/
4342

4443
#include <iostream>
@@ -77,7 +76,7 @@ auto schedule_request_start(S sched, int idx) -> ex::sender auto {
7776
std::cout << "HTTP request " << idx << " arrived\n";
7877

7978
// Return a sender for the incoming http_request
80-
return ex::transfer_just(std::forward<S>(sched), std::move(req));
79+
return ex::just(std::move(req)) | ex::continues_on(std::forward<S>(sched));
8180
}
8281

8382
// Sends a response back to the client; yields a void signal on success

include/exec/any_sender_of.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -855,7 +855,7 @@ namespace exec {
855855
STDEXEC::inplace_stop_source __stop_source_{};
856856
using __stop_callback = typename STDEXEC::stop_token_of_t<
857857
STDEXEC::env_of_t<_Receiver>
858-
>::template callback_type<__forward_stop_request>;
858+
>::template callback_type<STDEXEC::__forward_stop_request>;
859859
std::optional<__stop_callback> __on_stop_{};
860860
};
861861

include/exec/env.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ namespace exec {
3333
};
3434

3535
template <class _Env, class _Query>
36-
struct __without : STDEXEC::__env::__env_base_t<_Env> {
36+
struct __without : STDEXEC::__env_base_t<_Env> {
3737
static_assert(STDEXEC::__nothrow_move_constructible<_Env>);
3838

39-
using STDEXEC::__env::__env_base_t<_Env>::query;
39+
using STDEXEC::__env_base_t<_Env>::query;
4040

4141
STDEXEC_ATTRIBUTE(nodiscard, host, device)
4242
auto query(_Query) const noexcept = delete;
@@ -168,9 +168,9 @@ namespace exec {
168168
inline constexpr __read_with_default::__read_with_default_t read_with_default{};
169169

170170
[[deprecated("exec::write has been renamed to STDEXEC::write_env")]]
171-
inline constexpr STDEXEC::__write::write_env_t write{};
172-
[[deprecated("write_env has been moved to the STDEXEC:: namespace")]]
173-
inline constexpr STDEXEC::__write::write_env_t write_env{};
171+
inline constexpr STDEXEC::__write_env_t write{};
172+
[[deprecated("exec::write_env has been moved to the STDEXEC:: namespace")]]
173+
inline constexpr STDEXEC::__write_env_t write_env{};
174174

175175
namespace __write_attrs {
176176
using namespace STDEXEC;

include/exec/start_now.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ namespace exec {
188188

189189
struct start_now_t {
190190
template <
191-
STDEXEC::queryable _Env,
191+
STDEXEC::__queryable _Env,
192192
exec::__scope::__async_scope _AsyncScope,
193193
STDEXEC::sender... _Sender
194194
>

include/exec/task.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ namespace exec {
334334

335335
private:
336336
using __scheduler_t =
337-
__query_result_or_t<get_scheduler_t, _Context, STDEXEC::inline_scheduler>;
337+
__call_result_or_t<get_scheduler_t, STDEXEC::inline_scheduler, _Context>;
338338

339339
struct __final_awaitable {
340340
static constexpr auto await_ready() noexcept -> bool {

include/stdexec/__detail/__as_awaitable.hpp

Lines changed: 51 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ namespace STDEXEC {
4747
template <class _Sender, class _Promise>
4848
using __value_t = __decay_t<
4949
__value_types_of_t<_Sender, env_of_t<_Promise&>, __q<__single_value>, __msingle_or<void>>
50-
>;
50+
>;
5151
} // namespace __detail
5252

5353
/////////////////////////////////////////////////////////////////////////////
@@ -185,61 +185,62 @@ namespace STDEXEC {
185185
constexpr void return_void() noexcept;
186186
constexpr auto unhandled_stopped() noexcept -> __std::coroutine_handle<>;
187187
};
188+
} // namespace __as_awaitable
188189

189-
struct as_awaitable_t {
190-
template <class _Tp, class _Promise>
191-
static consteval auto __get_declfn() noexcept {
192-
if constexpr (__connect_await::__has_as_awaitable_member<_Tp, _Promise>) {
193-
using __result_t = decltype(__declval<_Tp>().as_awaitable(__declval<_Promise&>()));
194-
constexpr bool __is_nothrow = noexcept(__declval<_Tp>()
195-
.as_awaitable(__declval<_Promise&>()));
196-
return __declfn<__result_t, __is_nothrow>();
197-
// NOLINTNEXTLINE(bugprone-branch-clone)
198-
} else if constexpr (__awaitable<_Tp, __unspecified>) { // NOT __awaitable<_Tp, _Promise> !!
199-
return __declfn<_Tp&&>();
200-
} else if constexpr (__awaitable_sender<_Tp, _Promise>) {
201-
using __result_t = __sender_awaitable<_Promise, _Tp>;
202-
constexpr bool __is_nothrow =
203-
__nothrow_constructible_from<__result_t, _Tp, __std::coroutine_handle<_Promise>>;
204-
return __declfn<__result_t, __is_nothrow>();
205-
} else {
206-
return __declfn<_Tp&&>();
207-
}
208-
}
209-
210-
template <class _Tp, class _Promise, auto _DeclFn = __get_declfn<_Tp, _Promise>()>
211-
requires __callable<__mtypeof<_DeclFn>>
212-
auto operator()(_Tp&& __t, _Promise& __promise) const noexcept(noexcept(_DeclFn()))
213-
-> decltype(_DeclFn()) {
214-
if constexpr (__connect_await::__has_as_awaitable_member<_Tp, _Promise>) {
215-
using __result_t = decltype(static_cast<_Tp&&>(__t).as_awaitable(__promise));
216-
static_assert(__awaitable<__result_t, _Promise>);
217-
return static_cast<_Tp&&>(__t).as_awaitable(__promise);
218-
// NOLINTNEXTLINE(bugprone-branch-clone)
219-
} else if constexpr (__awaitable<_Tp, __unspecified>) { // NOT __awaitable<_Tp, _Promise> !!
220-
return static_cast<_Tp&&>(__t);
221-
} else if constexpr (__awaitable_sender<_Tp, _Promise>) {
222-
auto __hcoro = __std::coroutine_handle<_Promise>::from_promise(__promise);
223-
return __sender_awaitable<_Promise, _Tp>{static_cast<_Tp&&>(__t), __hcoro};
224-
} else {
225-
return static_cast<_Tp&&>(__t);
226-
}
190+
struct as_awaitable_t {
191+
template <class _Tp, class _Promise>
192+
static consteval auto __get_declfn() noexcept {
193+
using __as_awaitable::__unspecified;
194+
if constexpr (__connect_await::__has_as_awaitable_member<_Tp, _Promise>) {
195+
using __result_t = decltype(__declval<_Tp>().as_awaitable(__declval<_Promise&>()));
196+
constexpr bool __is_nothrow = noexcept(__declval<_Tp>()
197+
.as_awaitable(__declval<_Promise&>()));
198+
return __declfn<__result_t, __is_nothrow>();
199+
// NOLINTNEXTLINE(bugprone-branch-clone)
200+
} else if constexpr (__awaitable<_Tp, __unspecified>) { // NOT __awaitable<_Tp, _Promise> !!
201+
return __declfn<_Tp&&>();
202+
} else if constexpr (__as_awaitable::__awaitable_sender<_Tp, _Promise>) {
203+
using __result_t = __as_awaitable::__sender_awaitable<_Promise, _Tp>;
204+
constexpr bool __is_nothrow =
205+
__nothrow_constructible_from<__result_t, _Tp, __std::coroutine_handle<_Promise>>;
206+
return __declfn<__result_t, __is_nothrow>();
207+
} else {
208+
return __declfn<_Tp&&>();
227209
}
210+
}
228211

229-
template <class _Tp, class _Promise, auto _DeclFn = __get_declfn<_Tp, _Promise>()>
230-
requires __callable<__mtypeof<_DeclFn>> || __tag_invocable<as_awaitable_t, _Tp, _Promise&>
231-
[[deprecated("the use of tag_invoke for as_awaitable is deprecated")]]
232-
auto operator()(_Tp&& __t, _Promise& __promise) const
233-
noexcept(__nothrow_tag_invocable<as_awaitable_t, _Tp, _Promise&>)
234-
-> __tag_invoke_result_t<as_awaitable_t, _Tp, _Promise&> {
235-
using __result_t = __tag_invoke_result_t<as_awaitable_t, _Tp, _Promise&>;
212+
template <class _Tp, class _Promise, auto _DeclFn = __get_declfn<_Tp, _Promise>()>
213+
requires __callable<__mtypeof<_DeclFn>>
214+
auto operator()(_Tp&& __t, _Promise& __promise) const noexcept(noexcept(_DeclFn()))
215+
-> decltype(_DeclFn()) {
216+
using __as_awaitable::__unspecified;
217+
if constexpr (__connect_await::__has_as_awaitable_member<_Tp, _Promise>) {
218+
using __result_t = decltype(static_cast<_Tp&&>(__t).as_awaitable(__promise));
236219
static_assert(__awaitable<__result_t, _Promise>);
237-
return __tag_invoke(*this, static_cast<_Tp&&>(__t), __promise);
220+
return static_cast<_Tp&&>(__t).as_awaitable(__promise);
221+
// NOLINTNEXTLINE(bugprone-branch-clone)
222+
} else if constexpr (__awaitable<_Tp, __unspecified>) { // NOT __awaitable<_Tp, _Promise> !!
223+
return static_cast<_Tp&&>(__t);
224+
} else if constexpr (__as_awaitable::__awaitable_sender<_Tp, _Promise>) {
225+
auto __hcoro = __std::coroutine_handle<_Promise>::from_promise(__promise);
226+
return __as_awaitable::__sender_awaitable<_Promise, _Tp>{static_cast<_Tp&&>(__t), __hcoro};
227+
} else {
228+
return static_cast<_Tp&&>(__t);
238229
}
239-
};
240-
} // namespace __as_awaitable
230+
}
231+
232+
template <class _Tp, class _Promise, auto _DeclFn = __get_declfn<_Tp, _Promise>()>
233+
requires __callable<__mtypeof<_DeclFn>> || __tag_invocable<as_awaitable_t, _Tp, _Promise&>
234+
[[deprecated("the use of tag_invoke for as_awaitable is deprecated")]]
235+
auto operator()(_Tp&& __t, _Promise& __promise) const
236+
noexcept(__nothrow_tag_invocable<as_awaitable_t, _Tp, _Promise&>)
237+
-> __tag_invoke_result_t<as_awaitable_t, _Tp, _Promise&> {
238+
using __result_t = __tag_invoke_result_t<as_awaitable_t, _Tp, _Promise&>;
239+
static_assert(__awaitable<__result_t, _Promise>);
240+
return __tag_invoke(*this, static_cast<_Tp&&>(__t), __promise);
241+
}
242+
};
241243

242-
using __as_awaitable::as_awaitable_t;
243244
inline constexpr as_awaitable_t as_awaitable{};
244245
#endif
245246
} // namespace STDEXEC

include/stdexec/__detail/__basic_sender.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ namespace STDEXEC {
4646
#else // ^^^ EDG ^^^ / vvv !EDG vvv
4747
# define STDEXEC_SEXPR_DESCRIPTOR_FN(_Descriptor) ([] { return _Descriptor(); })
4848
# define STDEXEC_SEXPR_DESCRIPTOR(_Tag, _Data, _Child) \
49-
STDEXEC::__descriptor_fn_v<STDEXEC::__detail::__desc<_Tag, _Data, _Child>>
49+
STDEXEC::__descriptor_fn_v<STDEXEC::__desc<_Tag, _Data, _Child>>
5050
#endif
5151

5252
#if defined(STDEXEC_DEMANGLE_SENDER_NAMES)
@@ -59,7 +59,7 @@ namespace STDEXEC {
5959

6060
template <class _Tag, class _Data, class... _Child>
6161
consteval auto __descriptor_fn() noexcept {
62-
return __descriptor_fn_v<__detail::__desc<_Tag, _Data, _Child...>>;
62+
return __descriptor_fn_v<__desc<_Tag, _Data, _Child...>>;
6363
}
6464

6565
template <class _Tag>

include/stdexec/__detail/__bulk.hpp

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ namespace STDEXEC {
3434
/////////////////////////////////////////////////////////////////////////////
3535
// [execution.senders.adaptors.bulk]
3636
namespace __bulk {
37-
struct bulk_t;
38-
struct bulk_chunked_t;
39-
struct bulk_unchunked_t;
40-
4137
//! Wrapper for a policy object.
4238
//!
4339
//! If we wrap a standard execution policy, we don't store anything, as we know the type.
@@ -240,29 +236,6 @@ namespace STDEXEC {
240236
template <class _Fun>
241237
STDEXEC_HOST_DEVICE_DEDUCTION_GUIDE __as_bulk_chunked_fn(_Fun) -> __as_bulk_chunked_fn<_Fun>;
242238

243-
struct bulk_t : __generic_bulk_t<bulk_t> {
244-
struct __transform_sender_fn {
245-
template <class _Data, class _Child>
246-
constexpr auto operator()(__ignore, _Data&& __data, _Child&& __child) const {
247-
// Lower `bulk` to `bulk_chunked`. If `bulk_chunked` is customized, we will see the customization.
248-
return bulk_chunked(
249-
static_cast<_Child&&>(__child),
250-
__data.__pol_.__get(),
251-
__data.__shape_,
252-
__as_bulk_chunked_fn(std::move(__data.__fun_)));
253-
}
254-
};
255-
256-
template <class _Sender>
257-
static constexpr auto transform_sender(set_value_t, _Sender&& __sndr, __ignore) {
258-
return __apply(__transform_sender_fn(), static_cast<_Sender&&>(__sndr));
259-
}
260-
};
261-
262-
struct bulk_chunked_t : __generic_bulk_t<bulk_chunked_t> { };
263-
264-
struct bulk_unchunked_t : __generic_bulk_t<bulk_unchunked_t> { };
265-
266239
template <class _AlgoTag>
267240
struct __impl_base : __sexpr_defaults {
268241
template <class _Sender>
@@ -356,9 +329,23 @@ namespace STDEXEC {
356329
};
357330
} // namespace __bulk
358331

359-
using __bulk::bulk_t;
360-
using __bulk::bulk_chunked_t;
361-
using __bulk::bulk_unchunked_t;
332+
struct bulk_t : __bulk::__generic_bulk_t<bulk_t> {
333+
template <class _Sender>
334+
static constexpr auto transform_sender(set_value_t, _Sender&& __sndr, __ignore) {
335+
auto& [__tag, __data, __child] = __sndr;
336+
// Lower `bulk` to `bulk_chunked`. If `bulk_chunked` is customized, we will see the customization.
337+
return bulk_chunked(
338+
STDEXEC::__forward_like<_Sender>(__child),
339+
__data.__pol_.__get(),
340+
__data.__shape_,
341+
__bulk::__as_bulk_chunked_fn(STDEXEC::__forward_like<_Sender>(__data).__fun_));
342+
}
343+
};
344+
345+
struct bulk_chunked_t : __bulk::__generic_bulk_t<bulk_chunked_t> { };
346+
347+
struct bulk_unchunked_t : __bulk::__generic_bulk_t<bulk_unchunked_t> { };
348+
362349
inline constexpr bulk_t bulk{};
363350
inline constexpr bulk_chunked_t bulk_chunked{};
364351
inline constexpr bulk_unchunked_t bulk_unchunked{};

0 commit comments

Comments
 (0)