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

STEllAR-GROUP / hpx / #853

19 Dec 2022 01:01AM UTC coverage: 86.287% (+0.4%) from 85.912%
#853

push

StellarBot
Merge #6109

6109: Modernize serialization module r=hkaiser a=hkaiser

- flyby separate serialization of Boost types

working towards https://github.com/STEllAR-GROUP/hpx/issues/5497

Co-authored-by: Hartmut Kaiser <hartmut.kaiser@gmail.com>

53 of 53 new or added lines in 6 files covered. (100.0%)

173939 of 201582 relevant lines covered (86.29%)

1931657.12 hits per line

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

95.24
/libs/core/algorithms/include/hpx/parallel/algorithms/destroy.hpp
1
//  Copyright (c) 2014-2022 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
/// \file parallel/algorithms/destroy.hpp
8

9
#pragma once
10

11
#if defined(DOXYGEN)
12
namespace hpx {
13
    // clang-format off
14

15
    /// Destroys objects of type typename iterator_traits<ForwardIt>::value_type
16
    /// in the range [first, last). Executed according to the policy.
17
    ///
18
    /// \note   Complexity: Performs exactly \a last - \a first operations.
19
    ///
20
    /// \tparam ExPolicy    The type of the execution policy to use (deduced).
21
    ///                     It describes the manner in which the execution
22
    ///                     of the algorithm may be parallelized and the manner
23
    ///                     in which it executes the assignments.
24
    /// \tparam FwdIter     The type of the source iterators used (deduced).
25
    ///                     This iterator type must meet the requirements of an
26
    ///                     forward iterator.
27
    ///
28
    /// \param policy       The execution policy to use for the scheduling of
29
    ///                     the iterations.
30
    /// \param first        Refers to the beginning of the sequence of elements
31
    ///                     the algorithm will be applied to.
32
    /// \param last         Refers to the end of the sequence of elements the
33
    ///                     algorithm will be applied to.
34
    ///
35
    /// The operations in the parallel \a destroy
36
    /// algorithm invoked with an execution policy object of type \a sequenced_policy
37
    /// execute in sequential order in the calling thread.
38
    ///
39
    /// The operations in the parallel \a destroy
40
    /// algorithm invoked with an execution policy object of type \a parallel_policy
41
    /// or \a parallel_task_policy are permitted to execute in an
42
    /// unordered fashion in unspecified threads, and indeterminately sequenced
43
    /// within each thread.
44
    ///
45
    /// \returns  The \a destroy algorithm returns a
46
    ///           \a hpx::future<void>, if the execution policy is of type
47
    ///           \a sequenced_task_policy or
48
    ///           \a parallel_task_policy and returns \a void otherwise.
49
    ///
50
    template <typename ExPolicy, typename FwdIter>
51
    typename util::detail::algorithm_result<ExPolicy>::type
52
    destroy(ExPolicy&& policy, FwdIter first, FwdIter last);
53

54
    /// Destroys objects of type typename iterator_traits<ForwardIt>::value_type
55
    /// in the range [first, last).
56
    ///
57
    /// \note   Complexity: Performs exactly \a last - \a first operations.
58
    ///
59
    /// \tparam FwdIter     The type of the source iterators used (deduced).
60
    ///                     This iterator type must meet the requirements of an
61
    ///                     forward iterator.
62
    ///
63
    /// \param first        Refers to the beginning of the sequence of elements
64
    ///                     the algorithm will be applied to.
65
    /// \param last         Refers to the end of the sequence of elements the
66
    ///                     algorithm will be applied to.
67
    ///
68
    /// \returns  The \a destroy algorithm returns a \a void
69
    template <typename FwdIter>
70
    void destroy(FwdIter first, FwdIter last);
71

72
    /// Destroys objects of type typename iterator_traits<ForwardIt>::value_type
73
    /// in the range [first, first + count). Executed according to the policy.
74
    ///
75
    /// \note   Complexity: Performs exactly \a count operations, if
76
    ///         count > 0, no assignments otherwise.
77
    ///
78
    /// \tparam ExPolicy    The type of the execution policy to use (deduced).
79
    ///                     It describes the manner in which the execution
80
    ///                     of the algorithm may be parallelized and the manner
81
    ///                     in which it executes the assignments.
82
    /// \tparam FwdIter     The type of the source iterators used (deduced).
83
    ///                     This iterator type must meet the requirements of an
84
    ///                     forward iterator.
85
    /// \tparam Size        The type of the argument specifying the number of
86
    ///                     elements to apply this algorithm to.
87
    ///
88
    /// \param policy       The execution policy to use for the scheduling of
89
    ///                     the iterations.
90
    /// \param first        Refers to the beginning of the sequence of elements
91
    ///                     the algorithm will be applied to.
92
    /// \param count        Refers to the number of elements starting at
93
    ///                     \a first the algorithm will be applied to.
94
    ///
95
    /// The operations in the parallel \a destroy_n
96
    /// algorithm invoked with an execution policy object of type
97
    /// \a sequenced_policy execute in sequential order in the
98
    /// calling thread.
99
    ///
100
    /// The operations in the parallel \a destroy_n
101
    /// algorithm invoked with an execution policy object of type
102
    /// \a parallel_policy or
103
    /// \a parallel_task_policy are permitted to execute in an
104
    /// unordered fashion in unspecified threads, and indeterminately sequenced
105
    /// within each thread.
106
    ///
107
    /// \returns  The \a destroy_n algorithm returns a
108
    ///           \a hpx::future<FwdIter> if the execution policy is of type
109
    ///           \a sequenced_task_policy or
110
    ///           \a parallel_task_policy and
111
    ///           returns \a FwdIter otherwise.
112
    ///           The \a destroy_n algorithm returns the
113
    ///           iterator to the element in the source range, one past
114
    ///           the last element constructed.
115
    ///
116
    template <typename ExPolicy, typename FwdIter, typename Size>
117
    typename util::detail::algorithm_result<ExPolicy, FwdIter>::type
118
    destroy_n(ExPolicy&& policy, FwdIter first, Size count);
119

120
    /// Destroys objects of type typename iterator_traits<ForwardIt>::value_type
121
    /// in the range [first, first + count).
122
    ///
123
    /// \note   Complexity: Performs exactly \a count operations, if
124
    ///         count > 0, no assignments otherwise.
125
    ///
126
    /// \tparam FwdIter     The type of the source iterators used (deduced).
127
    ///                     This iterator type must meet the requirements of an
128
    ///                     forward iterator.
129
    /// \tparam Size        The type of the argument specifying the number of
130
    ///                     elements to apply this algorithm to.
131
    ///
132
    /// \param first        Refers to the beginning of the sequence of elements
133
    ///                     the algorithm will be applied to.
134
    /// \param count        Refers to the number of elements starting at
135
    ///                     \a first the algorithm will be applied to.
136
    ///
137
    /// \returns  The \a destroy_n algorithm returns a \a FwdIter .
138
    ///           The \a destroy_n algorithm returns the
139
    ///           iterator to the element in the source range, one past
140
    ///           the last element constructed.
141
    ///
142
    template <typename FwdIter, typename Size>
143
    FwdIter destroy_n(FwdIter first, Size count);
144

145
    // clang-format on
146
}    // namespace hpx
147

148
#else    // DOXYGEN
149

150
#include <hpx/config.hpp>
151
#include <hpx/concepts/concepts.hpp>
152
#include <hpx/iterator_support/traits/is_iterator.hpp>
153
#include <hpx/parallel/util/detail/sender_util.hpp>
154

155
#include <hpx/execution/algorithms/detail/is_negative.hpp>
156
#include <hpx/executors/execution_policy.hpp>
157
#include <hpx/parallel/algorithms/detail/dispatch.hpp>
158
#include <hpx/parallel/algorithms/detail/distance.hpp>
159
#include <hpx/parallel/util/detail/algorithm_result.hpp>
160
#include <hpx/parallel/util/foreach_partitioner.hpp>
161
#include <hpx/parallel/util/loop.hpp>
162
#include <hpx/parallel/util/projection_identity.hpp>
163

164
#include <algorithm>
165
#include <cstddef>
166
#include <iterator>
167
#include <memory>
168
#include <type_traits>
169
#include <utility>
170
#include <vector>
171

172
namespace hpx { namespace parallel { inline namespace v1 {
173
    ///////////////////////////////////////////////////////////////////////////
174
    // destroy
175
    namespace detail {
176
        /// \cond NOINTERNAL
177

178
        // provide our own implementation of std::destroy
179
        // as some versions of MSVC horribly fail at compiling it for some types
180
        // T
181
        template <typename Iter, typename Sent>
182
        Iter sequential_destroy(Iter first, Sent last)
32✔
183
        {
184
            for (/* */; first != last; ++first)
230,556✔
185
            {
186
                std::destroy_at(std::addressof(*first));
230,524✔
187
            }
230,524✔
188
            return first;
12✔
189
        }
190

191
        ///////////////////////////////////////////////////////////////////////
192
        template <typename ExPolicy, typename Iter>
193
        typename util::detail::algorithm_result<ExPolicy, Iter>::type
194
        parallel_sequential_destroy_n(
56✔
195
            ExPolicy&& policy, Iter first, std::size_t count)
196
        {
197
            if (count == 0)
56✔
198
            {
199
                return util::detail::algorithm_result<ExPolicy, Iter>::get(
×
200
                    HPX_MOVE(first));
201
            }
202

203
            return util::foreach_partitioner<ExPolicy>::call(
56✔
204
                HPX_FORWARD(ExPolicy, policy), first, count,
56✔
205
                [](Iter first, std::size_t count, std::size_t) {
560✔
206
                    return util::loop_n<std::decay_t<ExPolicy>>(
560✔
207
                        first, count, [](Iter it) -> void {
448,478✔
208
                            std::destroy_at(std::addressof(*it));
448,612✔
209
                        });
448,612✔
210
                },
211
                util::projection_identity());
212
        }
56✔
213

214
        ///////////////////////////////////////////////////////////////////////
215
        template <typename FwdIter>
216
        struct destroy : public detail::algorithm<destroy<FwdIter>, FwdIter>
217
        {
218
            destroy()
60✔
219
              : destroy::algorithm("destroy")
60✔
220
            {
60✔
221
            }
60✔
222

223
            template <typename ExPolicy, typename Iter, typename Sent>
224
            static Iter sequential(ExPolicy, Iter first, Sent last)
32✔
225
            {
226
                return sequential_destroy(first, last);
32✔
227
            }
20✔
228

229
            template <typename ExPolicy, typename Iter, typename Sent>
230
            static typename util::detail::algorithm_result<ExPolicy, Iter>::type
231
            parallel(ExPolicy&& policy, Iter first, Sent last)
28✔
232
            {
233
                return parallel_sequential_destroy_n(
28✔
234
                    HPX_FORWARD(ExPolicy, policy), first,
28✔
235
                    detail::distance(first, last));
28✔
236
            }
8✔
237
        };
238
        /// \endcond
239
    }    // namespace detail
240

241
    ///////////////////////////////////////////////////////////////////////////
242
    // destroy_n
243
    namespace detail {
244
        /// \cond NOINTERNAL
245

246
        // provide our own implementation of std::destroy
247
        // as some versions of MSVC horribly fail at compiling it for some
248
        // types T
249
        template <typename Iter>
250
        Iter sequential_destroy_n(Iter first, std::size_t count)
32✔
251
        {
252
            for (/* */; count != 0; (void) ++first, --count)
217,545✔
253
            {
254
                std::destroy_at(std::addressof(*first));
217,513✔
255
            }
217,513✔
256
            return first;
12✔
257
        }
258

259
        template <typename FwdIter>
260
        struct destroy_n : public detail::algorithm<destroy_n<FwdIter>, FwdIter>
261
        {
262
            destroy_n()
60✔
263
              : destroy_n::algorithm("destroy_n")
60✔
264
            {
60✔
265
            }
60✔
266

267
            template <typename ExPolicy, typename Iter>
268
            static Iter sequential(ExPolicy, Iter first, std::size_t count)
32✔
269
            {
270
                return sequential_destroy_n(first, count);
32✔
271
            }
20✔
272

273
            template <typename ExPolicy, typename Iter>
274
            static typename util::detail::algorithm_result<ExPolicy, Iter>::type
275
            parallel(ExPolicy&& policy, Iter first, std::size_t count)
28✔
276
            {
277
                return parallel_sequential_destroy_n(
28✔
278
                    HPX_FORWARD(ExPolicy, policy), first, count);
28✔
279
            }
8✔
280
        };
281
        /// \endcond
282
    }    // namespace detail
283
}}}      // namespace hpx::parallel::v1
284

285
namespace hpx {
286

287
    ///////////////////////////////////////////////////////////////////////////
288
    // CPO for hpx::destroy
289
    inline constexpr struct destroy_t final
290
      : hpx::detail::tag_parallel_algorithm<destroy_t>
291
    {
292
    private:
293
        // clang-format off
294
        template <typename ExPolicy, typename FwdIter,
295
            HPX_CONCEPT_REQUIRES_(
296
                hpx::is_execution_policy<ExPolicy>::value &&
297
                hpx::traits::is_iterator<FwdIter>::value
298
            )>
299
        // clang-format on
300
        friend typename hpx::parallel::util::detail::algorithm_result<
301
            ExPolicy>::type
302
        tag_fallback_invoke(
26✔
303
            destroy_t, ExPolicy&& policy, FwdIter first, FwdIter last)
304
        {
305
            static_assert((hpx::traits::is_forward_iterator<FwdIter>::value),
306
                "Required at least forward iterator.");
307

308
            return hpx::parallel::util::detail::algorithm_result<ExPolicy>::get(
26✔
309
                hpx::parallel::v1::detail::destroy<FwdIter>().call(
52✔
310
                    HPX_FORWARD(ExPolicy, policy), first, last));
26✔
311
        }
312

313
        // clang-format off
314
        template <typename FwdIter,
315
            HPX_CONCEPT_REQUIRES_(
316
                hpx::traits::is_iterator<FwdIter>::value
317
            )>
318
        // clang-format on
319
        friend void tag_fallback_invoke(destroy_t, FwdIter first, FwdIter last)
4✔
320
        {
321
            static_assert((hpx::traits::is_forward_iterator<FwdIter>::value),
322
                "Required at least forward iterator.");
323

324
            hpx::parallel::v1::detail::destroy<FwdIter>().call(
4✔
325
                hpx::execution::seq, first, last);
326
        }
4✔
327
    } destroy{};
328

329
    ///////////////////////////////////////////////////////////////////////////
330
    // CPO for hpx::destroy_n
331
    inline constexpr struct destroy_n_t final
332
      : hpx::detail::tag_parallel_algorithm<destroy_n_t>
333
    {
334
    private:
335
        // clang-format off
336
        template <typename ExPolicy, typename FwdIter, typename Size,
337
            HPX_CONCEPT_REQUIRES_(
338
                hpx::is_execution_policy<ExPolicy>::value &&
339
                hpx::traits::is_iterator<FwdIter>::value
340
            )>
341
        // clang-format on
342
        friend typename hpx::parallel::util::detail::algorithm_result<ExPolicy,
343
            FwdIter>::type
344
        tag_fallback_invoke(
26✔
345
            destroy_n_t, ExPolicy&& policy, FwdIter first, Size count)
346
        {
347
            static_assert((hpx::traits::is_forward_iterator<FwdIter>::value),
348
                "Requires at least forward iterator.");
349

350
            // if count is representing a negative value, we do nothing
351
            if (hpx::parallel::v1::detail::is_negative(count))
26✔
352
            {
353
                return hpx::parallel::util::detail::algorithm_result<ExPolicy,
×
354
                    FwdIter>::get(HPX_MOVE(first));
355
            }
356

357
            return hpx::parallel::v1::detail::destroy_n<FwdIter>().call(
52✔
358
                HPX_FORWARD(ExPolicy, policy), first, std::size_t(count));
18✔
359
        }
18✔
360

361
        // clang-format off
362
        template <typename FwdIter, typename Size,
363
            HPX_CONCEPT_REQUIRES_(
364
                hpx::traits::is_iterator<FwdIter>::value
365
            )>
366
        // clang-format on
367
        friend FwdIter tag_fallback_invoke(
4✔
368
            destroy_n_t, FwdIter first, Size count)
369
        {
370
            static_assert((hpx::traits::is_forward_iterator<FwdIter>::value),
371
                "Requires at least forward iterator.");
372

373
            // if count is representing a negative value, we do nothing
374
            if (hpx::parallel::v1::detail::is_negative(count))
4✔
375
            {
376
                return first;
×
377
            }
378

379
            return hpx::parallel::v1::detail::destroy_n<FwdIter>().call(
8✔
380
                hpx::execution::seq, first, std::size_t(count));
2✔
381
        }
2✔
382
    } destroy_n{};
383
}    // namespace hpx
384

385
#endif    // DOXYGEN
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