kokkos-execution
0.0.1
Toggle main menu visibility
Loading...
Searching...
No Matches
lifetime.hpp
Go to the documentation of this file.
1
// NOLINTBEGIN
2
/*
3
* SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
4
* Copyright (c) 2025 Robert Leahy. All rights reserved.
5
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
*
7
* Licensed under the Apache License, Version 2.0 with LLVM Exceptions (the "License");
8
* you may not use this file except in compliance with the License.
9
* You may obtain a copy of the License at
10
*
11
* https://llvm.org/LICENSE.txt
12
*
13
* Unless required by applicable law or agreed to in writing, software
14
* distributed under the License is distributed on an "AS IS" BASIS,
15
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
* See the License for the specific language governing permissions and
17
* limitations under the License.
18
*/
19
20
#pragma once
21
22
#include <cstddef>
23
#include <functional>
24
#include <memory>
25
#include <tuple>
26
#include <type_traits>
27
#include <utility>
28
29
#include "
enter_scope_sender.hpp
"
30
#include "
enter_scopes.hpp
"
31
#include "
invoke.hpp
"
32
#include "
object.hpp
"
33
#include "stdexec/execution.hpp"
34
#include "
within.hpp
"
35
36
namespace
experimental::execution
{
37
38
namespace
detail::lifetime
{
39
40
template
<
typename
F,
typename
... Objects>
41
concept
function
= ::STDEXEC::sender<std::invoke_result_t<F, ::exec::type_of_object_t<Objects>&...>>;
42
43
template
<
typename
SenderFactory,
typename
... Objects>
44
concept
sender_factory
=
45
::exec::enter_scope_sender<std::invoke_result_t<SenderFactory, ::exec::enter_scope_sender_of_object_t<Objects>...>>;
46
47
struct
t
{
48
template
<
typename
F, ::exec::object... Objects>
49
requires
function
<F, Objects...>
50
constexpr ::STDEXEC::sender
auto
operator()
(F&& f, Objects&&... objects)
const
noexcept
(
51
std::is_nothrow_constructible_v<std::remove_cvref_t<F>, F>
52
&& (std::is_nothrow_constructible_v<std::remove_cvref_t<Objects>, Objects> && ...)) {
53
return
(*
this
)(::exec::enter_scopes, (F&&) f, (Objects&&) objects...);
54
}
55
56
template
<
typename
SenderFactory,
typename
F, ::exec::object... Objects>
57
requires
sender_factory
<SenderFactory, Objects...> &&
function
<F, Objects...>
58
constexpr ::STDEXEC::sender
auto
59
operator()
(SenderFactory&&
sender_factory
, F&& f, Objects&&... objects)
const
noexcept
(
60
std::is_nothrow_constructible_v<std::remove_cvref_t<SenderFactory>, SenderFactory>
61
&& std::is_nothrow_constructible_v<std::remove_cvref_t<F>, F>
62
&& (std::is_nothrow_constructible_v<std::remove_cvref_t<Objects>, Objects> && ...)) {
63
return ::STDEXEC::__sexpr{
t
(), std::tuple((SenderFactory&&)
sender_factory
, (F&&) f, (Objects&&) objects...)};
64
}
65
};
66
67
template
<
typename
T>
68
class
storage_for_object
{
69
union
type_
{
70
char
c
;
71
T
t
;
72
73
constexpr
type_
() noexcept
74
:
c
() {
75
}
76
77
constexpr
~type_
() noexcept {
78
}
79
};
80
81
type_
storage_
;
82
public
:
83
constexpr
T*
get_storage
() noexcept {
84
return
std::addressof(
storage_
.t);
85
}
86
87
constexpr
T&
get_object
() noexcept {
88
return
*std::launder(
get_storage
());
89
}
90
};
91
92
template
<
typename
Object>
93
using
storage_for_object_t
=
storage_for_object<::exec::type_of_object_t<Object>
>;
94
95
template
<
typename
... Objects>
96
using
storage_for_objects_t
= std::tuple<storage_for_object_t<Objects>...>;
97
98
template
<
typename
Tuple,
typename
= std::remove_cvref_t<Tuple>>
99
class
make_sender
;
100
101
template
<
typename
Tuple,
typename
SenderFactory,
typename
F,
typename
... Objects>
102
class
make_sender
<Tuple, std::tuple<SenderFactory, F, Objects...>> {
103
static
constexpr
auto
impl_
(::STDEXEC::__copy_cvref_t<Tuple, F>&& f,
storage_for_object_t<Objects>
&... storage)
104
noexcept
(std::is_nothrow_constructible_v<F, ::STDEXEC::__copy_cvref_t<Tuple, F>>) {
105
return
[f = (::STDEXEC::__copy_cvref_t<Tuple, F>&&) f,
106
&storage...]()
mutable
noexcept
(std::is_nothrow_invocable_v<F, ::exec::type_of_object_t<Objects>&...>) {
107
return
std::invoke(std::move(f), storage.get_object()...);
108
};
109
}
110
public
:
111
static
constexpr
bool
nothrow
=
noexcept
(::exec::within(
112
std::invoke(
113
std::declval<::STDEXEC::__copy_cvref_t<Tuple, SenderFactory>>(),
114
std::invoke(
115
std::declval<::STDEXEC::__copy_cvref_t<Tuple, Objects>>(),
116
std::declval<::exec::type_of_object_t<Objects>*>())...),
117
::STDEXEC::just()
118
| ::exec::invoke(
impl_
(
119
std::declval<::STDEXEC::__copy_cvref_t<Tuple, F>>(),
120
std::declval<
storage_for_object_t<Objects>
&>()...))));
121
using
storage_type
=
storage_for_objects_t
<Objects...>;
122
123
static
constexpr ::STDEXEC::sender
auto
impl
(Tuple&&
t
,
storage_type
& storage)
noexcept
(
nothrow
) {
124
return
std::apply(
125
[&](
auto
&&
sender_factory
,
auto
&& f,
auto
&&... objects)
noexcept
(
nothrow
) {
126
return
std::apply(
127
[&](
auto
&...
storage_for_object
)
noexcept
(
nothrow
) {
128
return ::exec::within(
129
std::invoke(
130
(
decltype
(
sender_factory
)&&)
sender_factory
,
131
std::invoke((
decltype
(objects)&&) objects,
storage_for_object
.
get_storage
())...),
132
::STDEXEC::just() | ::exec::invoke(
impl_
((
decltype
(f)&&) f,
storage_for_object
...)));
133
},
134
storage);
135
},
136
(Tuple&&)
t
);
137
}
138
139
using
sender_type
=
decltype
(
impl
(std::declval<Tuple>(), std::declval<
storage_for_objects_t<Objects...>
&>()));
140
};
141
142
template
<
typename
Tuple,
typename
Receiver>
143
class
state
{
144
using
impl_
=
make_sender<Tuple>
;
145
typename
impl_::storage_type
storage_
;
146
::STDEXEC::connect_result_t<typename impl_::sender_type, Receiver>
op_
;
147
public
:
148
explicit
constexpr
state
(Tuple&&
t
, Receiver r)
noexcept
(impl_::nothrow)
149
:
op_
(::STDEXEC::connect(
impl_
::
impl
((Tuple&&)
t
,
storage_
), (Receiver&&) r)) {
150
}
151
152
constexpr
void
start
() &
noexcept
{
153
::STDEXEC::start(
op_
);
154
}
155
};
156
157
// TODO: We should be able to get a better "message" than this
158
struct
FAILED_TO_FORM_COMPLETION_SIGNATURES
{ };
159
160
class
impl
:
public
::STDEXEC::__sexpr_defaults {
161
template
<
typename
Self,
typename
... Env>
162
using
completions_
=
163
::STDEXEC::completion_signatures_of_t<typename make_sender<::STDEXEC::__data_of<Self>>::sender_type, Env...>;
164
public
:
165
template
<
typename
Self,
typename
... Env>
166
static
consteval
auto
__get_completion_signatures
() {
167
if
constexpr
(::STDEXEC::__minvocable_q<
completions_
, Self, Env...>) {
168
return
completions_
<Self, Env...>{};
169
}
else
if
constexpr
(
sizeof
...(Env) == 0) {
170
return
STDEXEC::__throw_dependent_sender_error<Self>();
171
}
else
{
172
return ::STDEXEC::__throw_compile_time_error<
173
FAILED_TO_FORM_COMPLETION_SIGNATURES
,
174
::STDEXEC::_WITH_SENDER_<Self>
175
>();
176
}
177
}
178
179
static
constexpr
auto
__get_state
= []<
typename
Sender,
typename
Receiver>(Sender&& sender, Receiver r)
noexcept
(
180
std::is_nothrow_constructible_v<
181
state
<::STDEXEC::__data_of<Sender>, Receiver>,
182
::STDEXEC::__data_of<Sender>,
183
Receiver
184
>) ->
state<::STDEXEC::__data_of<Sender>
, Receiver> {
185
auto
&& [_, tuple] = (Sender&&) sender;
186
return
state<decltype(tuple), Receiver>
((
decltype
(tuple)&&) tuple, (Receiver&&) r);
187
};
188
static
constexpr
auto
__start
= [](
auto
&
state
)
noexcept
{
189
state
.
start
();
190
};
191
};
192
193
}
// namespace detail::lifetime
194
195
using
lifetime_t
=
detail::lifetime::t
;
196
inline
constexpr
lifetime_t
lifetime
;
197
198
}
// namespace experimental::execution
199
200
namespace
STDEXEC {
201
202
template
<>
203
struct
__sexpr_impl<::exec::lifetime_t> : ::exec::detail::lifetime::impl { };
204
205
}
// namespace STDEXEC
206
207
// NOLINTEND
experimental::execution::detail::lifetime::impl
Definition
lifetime.hpp:160
experimental::execution::detail::lifetime::impl::__start
static constexpr auto __start
Definition
lifetime.hpp:188
experimental::execution::detail::lifetime::impl::completions_
::stdexec::completion_signatures_of_t< typename make_sender<::stdexec::__data_of< Self > >::sender_type, Env... > completions_
Definition
lifetime.hpp:162
experimental::execution::detail::lifetime::impl::__get_state
static constexpr auto __get_state
Definition
lifetime.hpp:179
experimental::execution::detail::lifetime::impl::__get_completion_signatures
static consteval auto __get_completion_signatures()
Definition
lifetime.hpp:166
experimental::execution::detail::lifetime::make_sender< Tuple, std::tuple< SenderFactory, F, Objects... > >::storage_type
storage_for_objects_t< Objects... > storage_type
Definition
lifetime.hpp:121
experimental::execution::detail::lifetime::make_sender< Tuple, std::tuple< SenderFactory, F, Objects... > >::sender_type
decltype(impl(std::declval< Tuple >(), std::declval< storage_for_objects_t< Objects... > & >())) sender_type
Definition
lifetime.hpp:139
experimental::execution::detail::lifetime::make_sender< Tuple, std::tuple< SenderFactory, F, Objects... > >::impl_
static constexpr auto impl_(::stdexec::__copy_cvref_t< Tuple, F > &&f, storage_for_object_t< Objects > &... storage) noexcept(std::is_nothrow_constructible_v< F, ::stdexec::__copy_cvref_t< Tuple, F > >)
Definition
lifetime.hpp:103
experimental::execution::detail::lifetime::make_sender< Tuple, std::tuple< SenderFactory, F, Objects... > >::nothrow
static constexpr bool nothrow
Definition
lifetime.hpp:111
experimental::execution::detail::lifetime::make_sender< Tuple, std::tuple< SenderFactory, F, Objects... > >::impl
static constexpr ::stdexec::sender auto impl(Tuple &&t, storage_type &storage) noexcept(nothrow)
Definition
lifetime.hpp:123
experimental::execution::detail::lifetime::make_sender
Definition
lifetime.hpp:99
experimental::execution::detail::lifetime::state
Definition
lifetime.hpp:143
experimental::execution::detail::lifetime::state::storage_
impl_::storage_type storage_
Definition
lifetime.hpp:145
experimental::execution::detail::lifetime::state::state
constexpr state(Tuple &&t, Receiver r) noexcept(impl_::nothrow)
Definition
lifetime.hpp:148
experimental::execution::detail::lifetime::state::start
constexpr void start() &noexcept
Definition
lifetime.hpp:152
experimental::execution::detail::lifetime::state::impl_
make_sender< Tuple > impl_
Definition
lifetime.hpp:144
experimental::execution::detail::lifetime::state::op_
::stdexec::connect_result_t< typename impl_::sender_type, Receiver > op_
Definition
lifetime.hpp:146
experimental::execution::detail::lifetime::storage_for_object
Definition
lifetime.hpp:68
experimental::execution::detail::lifetime::storage_for_object::get_storage
constexpr T * get_storage() noexcept
Definition
lifetime.hpp:83
experimental::execution::detail::lifetime::storage_for_object::get_object
constexpr T & get_object() noexcept
Definition
lifetime.hpp:87
experimental::execution::detail::lifetime::storage_for_object<::exec::type_of_object_t< Object > >::storage_
type_ storage_
Definition
lifetime.hpp:81
experimental::execution::detail::lifetime::function
Definition
lifetime.hpp:41
experimental::execution::detail::lifetime::sender_factory
Definition
lifetime.hpp:44
enter_scope_sender.hpp
enter_scopes.hpp
invoke.hpp
experimental::execution::detail::lifetime
Definition
lifetime.hpp:38
experimental::execution::detail::lifetime::storage_for_objects_t
std::tuple< storage_for_object_t< Objects >... > storage_for_objects_t
Definition
lifetime.hpp:96
experimental::execution::detail::lifetime::storage_for_object_t
storage_for_object<::exec::type_of_object_t< Object > > storage_for_object_t
Definition
lifetime.hpp:93
experimental::execution
Definition
elide.hpp:28
experimental::execution::lifetime
constexpr lifetime_t lifetime
Definition
lifetime.hpp:196
experimental::execution::lifetime_t
detail::lifetime::t lifetime_t
Definition
lifetime.hpp:195
object.hpp
experimental::execution::detail::lifetime::FAILED_TO_FORM_COMPLETION_SIGNATURES
Definition
lifetime.hpp:158
experimental::execution::detail::lifetime::t
Definition
lifetime.hpp:47
experimental::execution::detail::lifetime::t::operator()
constexpr ::stdexec::sender auto operator()(SenderFactory &&sender_factory, F &&f, Objects &&... objects) const noexcept(std::is_nothrow_constructible_v< std::remove_cvref_t< SenderFactory >, SenderFactory > &&std::is_nothrow_constructible_v< std::remove_cvref_t< F >, F > &&(std::is_nothrow_constructible_v< std::remove_cvref_t< Objects >, Objects > &&...))
Definition
lifetime.hpp:59
experimental::execution::detail::lifetime::t::operator()
constexpr ::stdexec::sender auto operator()(F &&f, Objects &&... objects) const noexcept(std::is_nothrow_constructible_v< std::remove_cvref_t< F >, F > &&(std::is_nothrow_constructible_v< std::remove_cvref_t< Objects >, Objects > &&...))
Definition
lifetime.hpp:50
experimental::execution::detail::lifetime::storage_for_object::type_::type_
constexpr type_() noexcept
Definition
lifetime.hpp:73
experimental::execution::detail::lifetime::storage_for_object::type_::t
T t
Definition
lifetime.hpp:71
experimental::execution::detail::lifetime::storage_for_object::type_::c
char c
Definition
lifetime.hpp:70
experimental::execution::detail::lifetime::storage_for_object::type_::~type_
constexpr ~type_() noexcept
Definition
lifetime.hpp:77
within.hpp
kokkos-execution
stdexec
P3955
lifetime.hpp
Generated on
for kokkos-execution by
1.18.0