• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

STEllAR-GROUP / hpx / #882

31 Aug 2023 07:44PM UTC coverage: 41.798% (-44.7%) from 86.546%
#882

push

19442 of 46514 relevant lines covered (41.8%)

126375.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.14
/libs/core/algorithms/include/hpx/parallel/util/detail/algorithm_result.hpp
1
//  Copyright (c) 2007-2025 Hartmut Kaiser
2
//
3
//  SPDX-License-Identifier: BSL-1.0
4
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
5
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6

7
#pragma once
8

9
#include <hpx/config.hpp>
10
#include <hpx/modules/concepts.hpp>
11
#include <hpx/modules/datastructures.hpp>
12
#include <hpx/modules/execution.hpp>
13
#include <hpx/modules/executors.hpp>
14
#include <hpx/modules/futures.hpp>
15
#include <hpx/modules/tag_invoke.hpp>
16
#include <hpx/modules/type_support.hpp>
17

18
#if defined(HPX_HAVE_STDEXEC)
19
// for is_sender
20
#include <hpx/modules/execution_base.hpp>
21
#endif
22

23
#include <type_traits>
24
#include <utility>
25

26
namespace hpx::parallel::util::detail {
27

28
    ///////////////////////////////////////////////////////////////////////////
29
    HPX_CXX_EXPORT template <typename ExPolicy, typename T,
30
        typename Enable = void>
31
    struct algorithm_result_impl;
32

33
    HPX_CXX_EXPORT template <typename ExPolicy, typename T>
34
    struct algorithm_result_impl<ExPolicy, T,
35
        std::enable_if_t<!hpx::is_async_execution_policy_v<ExPolicy> &&
36
            !hpx::execution_policy_has_scheduler_executor_v<ExPolicy>>>
37
    {
38
        // The return type of the initiating function.
39
        using type = T;
40

41
        // Obtain initiating function's return type.
42
        static constexpr type get() noexcept(
43
            std::is_nothrow_default_constructible_v<T>)
44
        {
45
            return T();
46
        }
1✔
47

48
        template <typename T_>
3✔
49
        static constexpr auto get(T_&& t)
50
        {
51
            return HPX_FORWARD(T_, t);
52
        }
53

54
        template <typename T_>
1✔
55
        static auto get(hpx::future<T_>&& t)
56
        {
57
            return t.get();
58
        }
59
    };
60

61
    HPX_CXX_EXPORT template <typename ExPolicy>
62
    struct algorithm_result_impl<ExPolicy, void,
63
        std::enable_if_t<!hpx::is_async_execution_policy_v<ExPolicy> &&
64
            !hpx::execution_policy_has_scheduler_executor_v<ExPolicy>>>
65
    {
66
        // The return type of the initiating function.
67
        using type = void;
1✔
68

69
        // Obtain initiating function's return type.
70
        static constexpr void get() noexcept {}
71

72
        static constexpr void get(hpx::util::unused_type) noexcept {}
73

74
        static void get(hpx::future<void>&& t)
75
        {
76
            t.get();
77
        }
78

79
        template <typename T>
80
        static void get(hpx::future<T>&& t)
81
        {
82
            t.get();
83
        }
84
    };
85

86
    HPX_CXX_EXPORT template <typename ExPolicy, typename T>
87
    struct algorithm_result_impl<ExPolicy, T,
88
        std::enable_if_t<hpx::is_async_execution_policy_v<ExPolicy> &&
89
            !hpx::execution_policy_has_scheduler_executor_v<ExPolicy>>>
90
    {
91
        // The return type of the initiating function.
92
        using type = hpx::future<T>;
93

94
        // Obtain initiating function's return type.
×
95
        static type get(T&& t)
96
        {
97
            return hpx::make_ready_future(HPX_MOVE(t));
×
98
        }
99

×
100
        static type get(hpx::future<T>&& t)
101
        {
102
            return HPX_MOVE(t);
103
        }
104
    };
105

106
    HPX_CXX_EXPORT template <typename ExPolicy>
107
    struct algorithm_result_impl<ExPolicy, void,
108
        std::enable_if_t<hpx::is_async_execution_policy_v<ExPolicy> &&
109
            !hpx::execution_policy_has_scheduler_executor_v<ExPolicy>>>
110
    {
111
        // The return type of the initiating function.
112
        using type = hpx::future<void>;
113

114
        // Obtain initiating function's return type.
115
        static type get()
116
        {
117
            return hpx::make_ready_future();
118
        }
119

120
        static type get(hpx::util::unused_type)
121
        {
122
            return hpx::make_ready_future();
123
        }
124

125
        static type get(hpx::future<void>&& t) noexcept
126
        {
127
            return HPX_MOVE(t);
128
        }
129

130
        template <typename T>
131
        static type get(hpx::future<T>&& t) noexcept
132
        {
133
            return hpx::future<void>(HPX_MOVE(t));
134
        }
135
    };
136

137
    HPX_CXX_EXPORT template <typename ExPolicy, typename T>
138
    struct algorithm_result_impl<ExPolicy, T,
139
        std::enable_if_t<!hpx::is_async_execution_policy_v<ExPolicy> &&
140
            hpx::execution_policy_has_scheduler_executor_v<ExPolicy>>>
141
    {
142
        // The return type of the initiating function.
143
        using type = T;
144

145
        static constexpr type get() noexcept(
146
            std::is_nothrow_default_constructible_v<T>)
147
        {
148
            return T();
149
        }
150

151
        template <typename T_>
152
        static constexpr auto get(T_&& t)
153
        {
154
            namespace ex = hpx::execution::experimental;
155
            if constexpr (ex::is_sender_v<T_>)
156
            {
157
                namespace tt = hpx::this_thread::experimental;
158
                auto result = tt::sync_wait(HPX_FORWARD(T_, t));
159
                if constexpr (hpx::tuple_size_v<
160
                                  std::decay_t<decltype(*result)>> == 0)
161
                {
162
                    return;
163
                }
164
                else
165
                {
166
                    // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
167
                    return hpx::get<0>(*result);
168
                }
169
            }
170
            else
171
            {
172
                return HPX_FORWARD(T_, t);
173
            }
174
        }
175
    };
176

177
    HPX_CXX_EXPORT template <typename ExPolicy>
178
    struct algorithm_result_impl<ExPolicy, void,
179
        std::enable_if_t<!hpx::is_async_execution_policy_v<ExPolicy> &&
180
            hpx::execution_policy_has_scheduler_executor_v<ExPolicy>>>
181
    {
182
        // The return type of the initiating function.
183
        using type = void;
184

185
        static constexpr type get() noexcept {}
186

187
        template <typename T>
188
        static constexpr auto get(T&& t)
189
        {
190
            namespace ex = hpx::execution::experimental;
191
            if constexpr (ex::is_sender_v<T>)
192
            {
193
                namespace tt = hpx::this_thread::experimental;
194
                tt::sync_wait(HPX_FORWARD(T, t));
195
            }
196
        }
197
    };
198

199
    HPX_CXX_EXPORT template <typename ExPolicy, typename T>
200
    struct algorithm_result_impl<ExPolicy, T,
201
        std::enable_if_t<hpx::is_async_execution_policy_v<ExPolicy> &&
202
            hpx::execution_policy_has_scheduler_executor_v<ExPolicy>>>
203
    {
204
        // Due to the nature of senders, this only serves as a dummy.
205
        using type =
206
            decltype(hpx::execution::experimental::just(std::declval<T>()));
207

208
        template <typename T_>
209
        static constexpr auto get(T_&& t)
210
        {
211
            namespace ex = hpx::execution::experimental;
212
            if constexpr (ex::is_sender_v<T_>)
213
            {
214
                return HPX_FORWARD(T_, t);
215
            }
216
            else
217
            {
218
                return ex::just(HPX_FORWARD(T_, t));
219
            }
220
        }
221
    };
222

223
    HPX_CXX_EXPORT template <typename ExPolicy>
224
    struct algorithm_result_impl<ExPolicy, void,
225
        std::enable_if_t<hpx::is_async_execution_policy_v<ExPolicy> &&
226
            hpx::execution_policy_has_scheduler_executor_v<ExPolicy>>>
227
    {
228
        // Due to the nature of senders, this only serves as a dummy.
229
        using type = decltype(hpx::execution::experimental::just());
230

231
        template <typename T_>
232
        static constexpr auto get(T_&& t)
233
        {
234
            namespace ex = hpx::execution::experimental;
235
            if constexpr (ex::is_sender_v<T_>)
236
            {
237
                return HPX_FORWARD(T_, t);
238
            }
239
            else
240
            {
241
                return ex::just(HPX_FORWARD(T_, t));
242
            }
243
        }
244
    };
245

246
    ///////////////////////////////////////////////////////////////////////////
247
    HPX_CXX_EXPORT template <typename ExPolicy, typename T = void>
248
    struct algorithm_result : algorithm_result_impl<std::decay_t<ExPolicy>, T>
249
    {
250
        static_assert(!std::is_lvalue_reference_v<T>,
251
            "T shouldn't be a lvalue reference");
252
    };
253

254
    HPX_CXX_EXPORT template <typename ExPolicy, typename T = void>
255
    using algorithm_result_t = typename algorithm_result<ExPolicy, T>::type;
256

257
    ///////////////////////////////////////////////////////////////////////////
258

259
    HPX_CXX_EXPORT template <typename U, typename Conv>
260
    // clang-format off
261
        requires (
262
           !hpx::execution::experimental::is_sender_v<U> &&
263
            hpx::is_invocable_v<Conv, U>
264
        )
265
    // clang-format on
266
    constexpr hpx::util::invoke_result_t<Conv, U> convert_to_result(
267
        U&& val, Conv&& conv)
268
    {
269
        return HPX_INVOKE(conv, val);
270
    }
271

272
    HPX_CXX_EXPORT template <typename Sender, typename Conv>
273
        requires(hpx::execution::experimental::is_sender_v<Sender>)
274
    constexpr decltype(auto) convert_to_result(Sender&& sender, Conv&& conv)
275
    {
276
        return hpx::execution::experimental::then(HPX_FORWARD(Sender, sender),
277
            [conv = HPX_FORWARD(Conv, conv)](auto&& value) mutable {
278
                return HPX_INVOKE(conv, HPX_FORWARD(decltype(value), value));
279
            });
280
    }
281

282
    HPX_CXX_EXPORT template <typename U, typename Conv>
283
        requires(hpx::is_invocable_v<Conv, U>)
284
    hpx::future<hpx::util::invoke_result_t<Conv, U>> convert_to_result(
285
        hpx::future<U>&& f, Conv&& conv)
286
    {
287
        using result_type = hpx::util::invoke_result_t<Conv, U>;
288

289
        return hpx::make_future<result_type>(
290
            HPX_MOVE(f), HPX_FORWARD(Conv, conv));
291
    }
292
}    // namespace hpx::parallel::util::detail
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc