Iros
 
Loading...
Searching...
No Matches
start_detached.h
Go to the documentation of this file.
1#pragma once
2
21#include "di/meta/core.h"
23#include "di/util/addressof.h"
25#include "di/util/destroy_at.h"
26#include "di/util/immovable.h"
29
30namespace di::execution {
32 template<typename Alloc>
33 struct DataT {
34 struct Type {
36 [[no_unique_address]] Alloc allocator;
37 };
38 };
39
40 template<typename Alloc>
42
43 template<typename Alloc>
44 struct ReceiverT {
45 struct Type {
46 using is_receiver = void;
47
49
50 friend void tag_invoke(Tag<set_value>, Type&& self) { self.data->did_complete(); }
51 friend void tag_invoke(Tag<set_stopped>, Type&& self) { self.data->did_complete(); }
52
53 friend auto tag_invoke(Tag<get_env>, Type const& self) {
54 return make_env(empty_env, with(get_allocator, self.data->allocator));
55 }
56 };
57 };
58
59 template<typename Alloc>
61
62 template<typename Send, typename Alloc>
63 struct StorageT {
67
68 explicit Type(Alloc&& allocator, Send&& sender)
69 : data(
70 [this] {
71 // Destroy the operation state when the sender completes. Since we store the allocator
72 // ourselves, we must first move it out of the operation state before destroying ourselves.
73 auto allocator = util::move(data.allocator);
74 auto* pointer = this;
75 util::destroy_at(pointer);
76 container::deallocate_one<Type>(allocator, pointer);
77 },
78 util::forward<Alloc>(allocator))
79 , op(connect(util::forward<Send>(sender), Rec(util::addressof(data)))) {}
80
81 [[no_unique_address]] Data<Alloc> data;
83 };
84 };
85
86 template<typename Send, typename Alloc>
88
89 struct Function {
90 template<concepts::NextSender Send, concepts::Allocator Alloc = platform::DefaultAllocator>
91 auto operator()(Send&& sender, Alloc&& allocator = {}) const {
92 if constexpr (requires {
94 util::forward<Send>(sender), util::forward<Alloc>(allocator));
95 }) {
97 util::forward<Send>(sender), util::forward<Alloc>(allocator));
98 } else if constexpr (requires {
99 tag_invoke(*this, util::forward<Send>(sender), util::forward<Alloc>(allocator));
100 }) {
101 return tag_invoke(*this, util::forward<Send>(sender), util::forward<Alloc>(allocator));
102 } else {
103 using Store = Storage<Send, Alloc>;
104
105 return vocab::as_fallible(container::allocate_one<Store>(allocator)) % [&](Store* storage) {
106 util::construct_at(storage, util::forward<Alloc>(allocator), util::forward<Send>(sender));
107 start(storage->op);
109 }
110 }
111 };
112}
113
135}
#define DI_IMMOVABLE_NO_UNIQUE_ADDRESS
Definition compiler.h:15
constexpr auto allocate_one
Definition allocate_one.h:29
constexpr auto deallocate_one
Definition deallocate_one.h:27
Definition start_detached.h:31
meta::Type< StorageT< Send, Alloc > > Storage
Definition start_detached.h:87
meta::Type< ReceiverT< Alloc > > Receiver
Definition start_detached.h:60
meta::Type< DataT< Alloc > > Data
Definition start_detached.h:41
Definition bulk.h:30
constexpr auto start_detached
Start a sender without waiting for it to complete.
Definition start_detached.h:134
constexpr auto start
Definition start.h:20
constexpr auto make_env
Create an environment with overrides for queries.
Definition make_env.h:147
constexpr auto with
Specify an override for an environment query.
Definition make_env.h:112
constexpr auto get_completion_scheduler
Definition get_completion_scheduler.h:19
constexpr auto get_env
Definition get_env.h:27
constexpr auto get_allocator
Definition get_allocator.h:27
constexpr auto connect
Definition connect.h:42
T::Type Type
Definition core.h:26
decltype(execution::connect(util::declval< Send >(), util::declval< Rec >())) ConnectResult
Definition connect_result.h:7
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
constexpr auto destroy_at
Definition destroy_at.h:24
constexpr auto construct_at
Definition construct_at.h:27
constexpr auto as_fallible
Definition as_fallible.h:26
constexpr auto try_infallible
Definition try_infallible.h:31
constexpr tag_invoke_detail::TagInvokeFn tag_invoke
Definition tag_invoke.h:22
constexpr auto data
Definition data.h:51
constexpr auto empty_env
Definition empty_env.h:6
Defines the sequence sender concepts and related CPOs.
Definition start_detached.h:34
Alloc allocator
Definition start_detached.h:36
Function< void()> did_complete
Definition start_detached.h:35
Definition start_detached.h:33
Definition start_detached.h:89
auto operator()(Send &&sender, Alloc &&allocator={}) const
Definition start_detached.h:91
void is_receiver
Definition start_detached.h:46
friend void tag_invoke(Tag< set_stopped >, Type &&self)
Definition start_detached.h:51
friend void tag_invoke(Tag< set_value >, Type &&self)
Definition start_detached.h:50
Data< Alloc > * data
Definition start_detached.h:48
friend auto tag_invoke(Tag< get_env >, Type const &self)
Definition start_detached.h:53
Definition start_detached.h:44
meta::ConnectResult< Send, Rec > Op
Definition start_detached.h:66
Type(Alloc &&allocator, Send &&sender)
Definition start_detached.h:68
DI_IMMOVABLE_NO_UNIQUE_ADDRESS Op op
Definition start_detached.h:82
Data< Alloc > data
Definition start_detached.h:81
Receiver< Alloc > Rec
Definition start_detached.h:65
Definition start_detached.h:63
Definition immovable.h:4