From 154f1cb86795b685aab655d62a3965b4ae944f91 Mon Sep 17 00:00:00 2001 From: targetakhil Date: Sun, 20 Jun 2021 19:13:42 +0530 Subject: [PATCH 1/5] updated base imlementations and added tag_fallback_dispatch overloads for parallel overloads --- .../uninitialized_default_construct.hpp | 362 ++++++++++++++++-- .../uninitialized_default_construct_tests.hpp | 16 +- .../uninitialized_default_constructn.cpp | 16 +- 3 files changed, 348 insertions(+), 46 deletions(-) diff --git a/libs/parallelism/algorithms/include/hpx/parallel/algorithms/uninitialized_default_construct.hpp b/libs/parallelism/algorithms/include/hpx/parallel/algorithms/uninitialized_default_construct.hpp index 5a506cae3fd2..e5cb867bf964 100644 --- a/libs/parallelism/algorithms/include/hpx/parallel/algorithms/uninitialized_default_construct.hpp +++ b/libs/parallelism/algorithms/include/hpx/parallel/algorithms/uninitialized_default_construct.hpp @@ -8,6 +8,169 @@ #pragma once +#if defined(DOXYGEN) +namespace hpx { + + /// Copies the given \a value to an uninitialized memory area, defined by + /// the range [first, last). If an exception is thrown during the + /// initialization, the function has no effects. + /// + /// \note Complexity: Linear in the distance between \a first and \a last + /// + /// \tparam FwdIter The type of the source iterators used (deduced). + /// This iterator type must meet the requirements of an + /// forward iterator. + /// \tparam T The type of the value to be assigned (deduced). + /// + /// \param first Refers to the beginning of the sequence of elements + /// the algorithm will be applied to. + /// \param last Refers to the end of the sequence of elements the + /// algorithm will be applied to. + /// \param value The value to be assigned. + /// + /// The assignments in the parallel \a uninitialized_default_construct algorithm invoked + /// without an execution policy object will execute in sequential order in + /// the calling thread. + /// + /// \returns The \a uninitialized_default_construct algorithm returns nothing + /// + template + void uninitialized_default_construct( + FwdIter first, FwdIter last, T const& value); + + /// Copies the given \a value to an uninitialized memory area, defined by + /// the range [first, last). If an exception is thrown during the + /// initialization, the function has no effects. + /// + /// \note Complexity: Linear in the distance between \a first and \a last + /// + /// \tparam ExPolicy The type of the execution policy to use (deduced). + /// It describes the manner in which the execution + /// of the algorithm may be parallelized and the manner + /// in which it executes the assignments. + /// \tparam FwdIter The type of the source iterators used (deduced). + /// This iterator type must meet the requirements of an + /// forward iterator. + /// \tparam T The type of the value to be assigned (deduced). + /// + /// \param policy The execution policy to use for the scheduling of + /// the iterations. + /// \param first Refers to the beginning of the sequence of elements + /// the algorithm will be applied to. + /// \param last Refers to the end of the sequence of elements the + /// algorithm will be applied to. + /// \param value The value to be assigned. + /// + /// The initializations in the parallel \a uninitialized_default_construct algorithm + /// invoked with an execution policy object of type + /// \a sequenced_policy execute in sequential order in the + /// calling thread. + /// + /// The initializations in the parallel \a uninitialized_default_construct algorithm + /// invoked with an execution policy object of type + /// \a parallel_policy or \a parallel_task_policy are + /// permitted to execute in an unordered fashion in unspecified threads, + /// and indeterminately sequenced within each thread. + /// + /// \returns The \a uninitialized_default_construct algorithm returns a + /// \a hpx::future, if the execution policy is of type + /// \a sequenced_task_policy or + /// \a parallel_task_policy and returns nothing + /// otherwise. + /// + template + typename parallel::util::detail::algorithm_result::type + uninitialized_default_construct( + ExPolicy&& policy, FwdIter first, FwdIter last, T const& value); + + /// Copies the given \a value value to the first count elements in an + /// uninitialized memory area beginning at first. If an exception is thrown + /// during the initialization, the function has no effects. + /// + /// \note Complexity: Performs exactly \a count assignments, if + /// count > 0, no assignments otherwise. + /// + /// \tparam FwdIter The type of the source iterators used (deduced). + /// This iterator type must meet the requirements of a + /// forward iterator. + /// \tparam Size The type of the argument specifying the number of + /// elements to apply \a f to. + /// \tparam T The type of the value to be assigned (deduced). + /// + /// \param first Refers to the beginning of the sequence of elements + /// the algorithm will be applied to. + /// \param count Refers to the number of elements starting at + /// \a first the algorithm will be applied to. + /// \param value The value to be assigned. + /// + /// The assignments in the parallel \a uninitialized_default_construct_n algorithm + /// invoked without an execution policy object execute in sequential order + /// in the calling thread. + /// + /// \returns The \a uninitialized_default_construct_n algorithm returns a + /// returns \a FwdIter. + /// The \a uninitialized_default_construct_n algorithm returns the output + /// iterator to the element in the range, one past + /// the last element copied. + /// + template + FwdIter uninitialized_default_construct_n( + FwdIter first, Size count, T const& value); + + /// Copies the given \a value value to the first count elements in an + /// uninitialized memory area beginning at first. If an exception is thrown + /// during the initialization, the function has no effects. + /// + /// \note Complexity: Performs exactly \a count assignments, if + /// count > 0, no assignments otherwise. + /// + /// \tparam ExPolicy The type of the execution policy to use (deduced). + /// It describes the manner in which the execution + /// of the algorithm may be parallelized and the manner + /// in which it executes the assignments. + /// \tparam FwdIter The type of the source iterators used (deduced). + /// This iterator type must meet the requirements of a + /// forward iterator. + /// \tparam Size The type of the argument specifying the number of + /// elements to apply \a f to. + /// \tparam T The type of the value to be assigned (deduced). + /// + /// \param policy The execution policy to use for the scheduling of + /// the iterations. + /// \param first Refers to the beginning of the sequence of elements + /// the algorithm will be applied to. + /// \param count Refers to the number of elements starting at + /// \a first the algorithm will be applied to. + /// \param value The value to be assigned. + /// + /// The initializations in the parallel \a uninitialized_default_construct_n algorithm + /// invoked with an execution policy object of type + /// \a sequenced_policy execute in sequential order in the + /// calling thread. + /// + /// The initializations in the parallel \a uninitialized_default_construct_n algorithm + /// invoked with an execution policy object of type + /// \a parallel_policy or \a parallel_task_policy are + /// permitted to execute in an unordered fashion in unspecified threads, + /// and indeterminately sequenced within each thread. + /// + /// \returns The \a uninitialized_default_construct_n algorithm returns a + /// \a hpx::future, if the execution policy is of type + /// \a sequenced_task_policy or + /// \a parallel_task_policy and returns FwdIter + /// otherwise. + /// The \a uninitialized_default_construct_n algorithm returns the output + /// iterator to the element in the range, one past + /// the last element copied. + /// + template + typename parallel::util::detail::algorithm_result::type + uninitialized_default_construct_n( + ExPolicy&& policy, FwdIter first, Size count, T const& value); +} // namespace hpx + +#else // DOXYGEN + #include #include #include @@ -15,6 +178,7 @@ #include #include #include +#include #include #include #include @@ -36,19 +200,19 @@ namespace hpx { namespace parallel { inline namespace v1 { // provide our own implementation of std::uninitialized_default_construct as some // versions of MSVC horribly fail at compiling it for some types T - template - void std_uninitialized_default_construct(InIter first, InIter last) + template + Iter std_uninitialized_default_construct(Iter first, Sent last) { - typedef - typename std::iterator_traits::value_type value_type; + using value_type = typename std::iterator_traits::value_type; - InIter s_first = first; + Iter s_first = first; try { for (/* */; first != last; ++first) { ::new (std::addressof(*first)) value_type; } + return first; } catch (...) { @@ -66,8 +230,8 @@ namespace hpx { namespace parallel { inline namespace v1 { std::size_t count, util::cancellation_token& tok) { - typedef - typename std::iterator_traits::value_type value_type; + using value_type = + typename std::iterator_traits::value_type; return util::loop_with_cleanup_n_with_token( first, count, tok, @@ -121,11 +285,11 @@ namespace hpx { namespace parallel { inline namespace v1 { } }); } - /////////////////////////////////////////////////////////////////////// template struct uninitialized_default_construct - : public detail::algorithm> + : public detail::algorithm, + FwdIter> { uninitialized_default_construct() : uninitialized_default_construct::algorithm( @@ -133,22 +297,20 @@ namespace hpx { namespace parallel { inline namespace v1 { { } - template - static hpx::util::unused_type sequential( - ExPolicy, InIter first, InIter last) + template + static FwdIter sequential(ExPolicy, FwdIter first, Sent last) { - std_uninitialized_default_construct(first, last); - return hpx::util::unused; + return std_uninitialized_default_construct(first, last); } - template - static typename util::detail::algorithm_result::type - parallel(ExPolicy&& policy, FwdIter first, FwdIter last) + template + static + typename util::detail::algorithm_result::type + parallel(ExPolicy&& policy, FwdIter first, Sent last) { - return util::detail::algorithm_result::get( - parallel_sequential_uninitialized_default_construct_n( - std::forward(policy), first, - std::distance(first, last))); + return parallel_sequential_uninitialized_default_construct_n( + std::forward(policy), first, + detail::distance(first, last)); } }; /// \endcond @@ -194,15 +356,32 @@ namespace hpx { namespace parallel { inline namespace v1 { template ::value&& hpx::traits::is_iterator::value)> + HPX_DEPRECATED_V(1, 7, + "hpx::parallel::uninitialized_default_construct is deprecated, use " + "hpx::uninitialized_default_construct " + "instead") typename util::detail::algorithm_result::type - uninitialized_default_construct( - ExPolicy&& policy, FwdIter first, FwdIter last) + uninitialized_default_construct( + ExPolicy&& policy, FwdIter first, FwdIter last) { static_assert((hpx::traits::is_forward_iterator::value), "Required at least forward iterator."); - return detail::uninitialized_default_construct().call( - std::forward(policy), first, last); +#if defined(HPX_GCC_VERSION) && HPX_GCC_VERSION >= 100000 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + using result_type = + typename hpx::parallel::util::detail::algorithm_result< + ExPolicy>::type; + + return hpx::util::void_guard(), + hpx::parallel::v1::detail::uninitialized_default_construct< + FwdIter>() + .call(std::forward(policy), first, last); +#if defined(HPX_GCC_VERSION) && HPX_GCC_VERSION >= 100000 +#pragma GCC diagnostic pop +#endif } /////////////////////////////////////////////////////////////////////////// @@ -249,8 +428,9 @@ namespace hpx { namespace parallel { inline namespace v1 { { } - template - static InIter sequential(ExPolicy, InIter first, std::size_t count) + template + static FwdIter sequential( + ExPolicy, FwdIter first, std::size_t count) { return std_uninitialized_default_construct_n(first, count); } @@ -316,11 +496,15 @@ namespace hpx { namespace parallel { inline namespace v1 { template ::value&& hpx::traits::is_iterator::value)> + HPX_DEPRECATED_V(1, 7, + "hpx::parallel::uninitialized_default_construct_n is deprecated, use " + "hpx::uninitialized_default_construct_n " + "instead") typename util::detail::algorithm_result::type - uninitialized_default_construct_n( - ExPolicy&& policy, FwdIter first, Size count) + uninitialized_default_construct_n( + ExPolicy&& policy, FwdIter first, Size count) { - static_assert((hpx::traits::is_forward_iterator::value), + static_assert(hpx::traits::is_forward_iterator::value, "Requires at least forward iterator."); // if count is representing a negative value, we do nothing @@ -330,7 +514,125 @@ namespace hpx { namespace parallel { inline namespace v1 { std::move(first)); } +#if defined(HPX_GCC_VERSION) && HPX_GCC_VERSION >= 100000 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif return detail::uninitialized_default_construct_n().call( std::forward(policy), first, std::size_t(count)); } +#if defined(HPX_GCC_VERSION) && HPX_GCC_VERSION >= 100000 +#pragma GCC diagnostic pop +#endif }}} // namespace hpx::parallel::v1 + +namespace hpx { + /////////////////////////////////////////////////////////////////////////// + // DPO for hpx::uninitialized_default_construct + HPX_INLINE_CONSTEXPR_VARIABLE struct uninitialized_default_construct_t final + : hpx::functional::tag_fallback + { + // clang-format off + template ::value + )> + // clang-format on + friend void tag_fallback_dispatch( + hpx::uninitialized_default_construct_t, FwdIter first, FwdIter last) + { + static_assert(hpx::traits::is_forward_iterator::value, + "Requires at least forward iterator."); + + hpx::parallel::v1::detail::uninitialized_default_construct< + FwdIter>() + .call(hpx::execution::seq, first, last); + } + + // clang-format off + template ::value && + hpx::traits::is_forward_iterator::value + )> + // clang-format on + friend typename parallel::util::detail::algorithm_result::type + tag_fallback_dispatch(hpx::uninitialized_default_construct_t, + ExPolicy&& policy, FwdIter first, FwdIter last) + { + static_assert(hpx::traits::is_forward_iterator::value, + "Requires at least forward iterator."); + + using result_type = + typename hpx::parallel::util::detail::algorithm_result< + ExPolicy>::type; + + return hpx::util::void_guard(), + hpx::parallel::v1::detail::uninitialized_default_construct< + FwdIter>() + .call(std::forward(policy), first, last); + } + + } uninitialized_default_construct{}; + + /////////////////////////////////////////////////////////////////////////// + // DPO for hpx::uninitialized_default_construct_n + HPX_INLINE_CONSTEXPR_VARIABLE struct uninitialized_default_construct_n_t + final + : hpx::functional::tag_fallback + { + // clang-format off + template ::value + )> + // clang-format on + friend FwdIter tag_fallback_dispatch( + hpx::uninitialized_default_construct_n_t, FwdIter first, Size count) + { + static_assert(hpx::traits::is_forward_iterator::value, + "Requires at least forward iterator."); + + // if count is representing a negative value, we do nothing + if (hpx::parallel::v1::detail::is_negative(count)) + { + return first; + } + + return hpx::parallel::v1::detail::uninitialized_default_construct_n< + FwdIter>() + .call(hpx::execution::seq, first, std::size_t(count)); + } + + // clang-format off + template ::value && + hpx::traits::is_forward_iterator::value + )> + // clang-format on + friend typename parallel::util::detail::algorithm_result::type + tag_fallback_dispatch(hpx::uninitialized_default_construct_n_t, + ExPolicy&& policy, FwdIter first, Size count) + { + static_assert(hpx::traits::is_forward_iterator::value, + "Requires at least forward iterator."); + + // if count is representing a negative value, we do nothing + if (hpx::parallel::v1::detail::is_negative(count)) + { + return parallel::util::detail::algorithm_result::get(std::move(first)); + } + + return hpx::parallel::v1::detail::uninitialized_default_construct_n< + FwdIter>() + .call( + std::forward(policy), first, std::size_t(count)); + } + + } uninitialized_default_construct_n{}; +} // namespace hpx + +#endif // DOXYGEN diff --git a/libs/parallelism/algorithms/tests/unit/algorithms/uninitialized_default_construct_tests.hpp b/libs/parallelism/algorithms/tests/unit/algorithms/uninitialized_default_construct_tests.hpp index 645b43c301d5..4a22e3e4670a 100644 --- a/libs/parallelism/algorithms/tests/unit/algorithms/uninitialized_default_construct_tests.hpp +++ b/libs/parallelism/algorithms/tests/unit/algorithms/uninitialized_default_construct_tests.hpp @@ -52,7 +52,7 @@ void test_uninitialized_default_construct(ExPolicy&& policy, IteratorTag) std::memset( static_cast(p), 0xcd, data_size * sizeof(default_constructable)); - hpx::parallel::uninitialized_default_construct( + hpx::uninitialized_default_construct( std::forward(policy), iterator(p), iterator(p + data_size)); std::size_t count = 0; @@ -76,7 +76,7 @@ void test_uninitialized_default_construct_async(ExPolicy&& policy, IteratorTag) std::memset( static_cast(p), 0xcd, data_size * sizeof(default_constructable)); - auto f = hpx::parallel::uninitialized_default_construct( + auto f = hpx::uninitialized_default_construct( std::forward(policy), iterator(p), iterator(p + data_size)); f.wait(); @@ -104,7 +104,7 @@ void test_uninitialized_default_construct2(ExPolicy&& policy, IteratorTag) std::memset( static_cast(p), 0xcd, data_size * sizeof(value_constructable)); - hpx::parallel::uninitialized_default_construct( + hpx::uninitialized_default_construct( std::forward(policy), iterator(p), iterator(p + data_size)); std::size_t count = 0; @@ -128,7 +128,7 @@ void test_uninitialized_default_construct_async2(ExPolicy&& policy, IteratorTag) std::memset( static_cast(p), 0xcd, data_size * sizeof(value_constructable)); - auto f = hpx::parallel::uninitialized_default_construct( + auto f = hpx::uninitialized_default_construct( std::forward(policy), iterator(p), iterator(p + data_size)); f.wait(); @@ -167,7 +167,7 @@ void test_uninitialized_default_construct_exception( bool caught_exception = false; try { - hpx::parallel::uninitialized_default_construct(policy, + hpx::uninitialized_default_construct(policy, decorated_iterator(p, [&throw_after]() { if (throw_after-- == 0) @@ -215,7 +215,7 @@ void test_uninitialized_default_construct_exception_async( bool returned_from_algorithm = false; try { - auto f = hpx::parallel::uninitialized_default_construct(policy, + auto f = hpx::uninitialized_default_construct(policy, decorated_iterator(p, [&throw_after]() { if (throw_after-- == 0) @@ -271,7 +271,7 @@ void test_uninitialized_default_construct_bad_alloc( bool caught_bad_alloc = false; try { - hpx::parallel::uninitialized_default_construct(policy, + hpx::uninitialized_default_construct(policy, decorated_iterator(p, [&throw_after]() { if (throw_after-- == 0) @@ -319,7 +319,7 @@ void test_uninitialized_default_construct_bad_alloc_async( bool returned_from_algorithm = false; try { - auto f = hpx::parallel::uninitialized_default_construct(policy, + auto f = hpx::uninitialized_default_construct(policy, decorated_iterator(p, [&throw_after]() { if (throw_after-- == 0) diff --git a/libs/parallelism/algorithms/tests/unit/algorithms/uninitialized_default_constructn.cpp b/libs/parallelism/algorithms/tests/unit/algorithms/uninitialized_default_constructn.cpp index c2aeee0e07e5..1bb0c059e5e9 100644 --- a/libs/parallelism/algorithms/tests/unit/algorithms/uninitialized_default_constructn.cpp +++ b/libs/parallelism/algorithms/tests/unit/algorithms/uninitialized_default_constructn.cpp @@ -50,7 +50,7 @@ void test_uninitialized_default_construct_n(ExPolicy policy, IteratorTag) std::memset( static_cast(p), 0xcd, data_size * sizeof(default_constructable)); - hpx::parallel::uninitialized_default_construct_n( + hpx::uninitialized_default_construct_n( policy, iterator(p), data_size); std::size_t count = 0; @@ -74,7 +74,7 @@ void test_uninitialized_default_construct_n_async(ExPolicy policy, IteratorTag) std::memset( static_cast(p), 0xcd, data_size * sizeof(default_constructable)); - auto f = hpx::parallel::uninitialized_default_construct_n( + auto f = hpx::uninitialized_default_construct_n( policy, iterator(p), data_size); f.wait(); @@ -102,7 +102,7 @@ void test_uninitialized_default_construct_n2(ExPolicy policy, IteratorTag) std::memset( static_cast(p), 0xcd, data_size * sizeof(value_constructable)); - hpx::parallel::uninitialized_default_construct_n( + hpx::uninitialized_default_construct_n( policy, iterator(p), data_size); std::size_t count = 0; @@ -126,7 +126,7 @@ void test_uninitialized_default_construct_n_async2(ExPolicy policy, IteratorTag) std::memset( static_cast(p), 0xcd, data_size * sizeof(value_constructable)); - auto f = hpx::parallel::uninitialized_default_construct_n( + auto f = hpx::uninitialized_default_construct_n( policy, iterator(p), data_size); f.wait(); @@ -191,7 +191,7 @@ void test_uninitialized_default_construct_n_exception( bool caught_exception = false; try { - hpx::parallel::uninitialized_default_construct_n(policy, + hpx::uninitialized_default_construct_n(policy, decorated_iterator(p, [&throw_after]() { if (throw_after-- == 0) @@ -239,7 +239,7 @@ void test_uninitialized_default_construct_n_exception_async( bool returned_from_algorithm = false; try { - auto f = hpx::parallel::uninitialized_default_construct_n(policy, + auto f = hpx::uninitialized_default_construct_n(policy, decorated_iterator(p, [&throw_after]() { if (throw_after-- == 0) @@ -320,7 +320,7 @@ void test_uninitialized_default_construct_n_bad_alloc( bool caught_bad_alloc = false; try { - hpx::parallel::uninitialized_default_construct_n(policy, + hpx::uninitialized_default_construct_n(policy, decorated_iterator(p, [&throw_after]() { if (throw_after-- == 0) @@ -368,7 +368,7 @@ void test_uninitialized_default_construct_n_bad_alloc_async( bool returned_from_algorithm = false; try { - auto f = hpx::parallel::uninitialized_default_construct_n(policy, + auto f = hpx::uninitialized_default_construct_n(policy, decorated_iterator(p, [&throw_after]() { if (throw_after-- == 0) From 86ab9ec3374fe313acdc07771a56e33762eeff1d Mon Sep 17 00:00:00 2001 From: targetakhil Date: Mon, 21 Jun 2021 09:11:03 +0530 Subject: [PATCH 2/5] add container overloads --- libs/parallelism/algorithms/CMakeLists.txt | 1 + .../uninitialized_default_construct.hpp | 415 ++++++++++++++++++ .../unit/container_algorithms/CMakeLists.txt | 2 + .../uninitialized_default_construct_range.cpp | 185 ++++++++ ...uninitialized_default_constructn_range.cpp | 134 ++++++ 5 files changed, 737 insertions(+) create mode 100644 libs/parallelism/algorithms/include/hpx/parallel/container_algorithms/uninitialized_default_construct.hpp create mode 100644 libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_construct_range.cpp create mode 100644 libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_constructn_range.cpp diff --git a/libs/parallelism/algorithms/CMakeLists.txt b/libs/parallelism/algorithms/CMakeLists.txt index 8cb2dc63226c..91039de9bdc3 100644 --- a/libs/parallelism/algorithms/CMakeLists.txt +++ b/libs/parallelism/algorithms/CMakeLists.txt @@ -121,6 +121,7 @@ set(algorithms_headers hpx/parallel/container_algorithms/stable_sort.hpp hpx/parallel/container_algorithms/transform.hpp hpx/parallel/container_algorithms/transform_reduce.hpp + hpx/parallel/container_algorithms/uninitialized_default_construct.hpp hpx/parallel/container_algorithms/uninitialized_move.hpp hpx/parallel/container_algorithms/unique.hpp hpx/parallel/container_memory.hpp diff --git a/libs/parallelism/algorithms/include/hpx/parallel/container_algorithms/uninitialized_default_construct.hpp b/libs/parallelism/algorithms/include/hpx/parallel/container_algorithms/uninitialized_default_construct.hpp new file mode 100644 index 000000000000..14e3a46f41b7 --- /dev/null +++ b/libs/parallelism/algorithms/include/hpx/parallel/container_algorithms/uninitialized_default_construct.hpp @@ -0,0 +1,415 @@ +// Copyright (c) 2020 ETH Zurich +// Copyright (c) 2014 Grant Mercer +// +// SPDX-License-Identifier: BSL-1.0 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +/// \file parallel/container_algorithms/uninitialized_default_construct.hpp + +#pragma once + +#if defined(DOXYGEN) + +namespace hpx { namespace ranges { + + /// Copies the given \a value to an uninitialized memory area, defined by + /// the range [first, last). If an exception is thrown during the + /// initialization, the function has no effects. + /// + /// \note Complexity: Linear in the distance between \a first and \a last + /// + /// \tparam FwdIter The type of the source iterators used (deduced). + /// This iterator type must meet the requirements of an + /// forward iterator. + /// \tparam Sent The type of the source sentinel (deduced). This + /// sentinel type must be a sentinel for FwdIter. + /// \tparam T The type of the value to be assigned (deduced). + /// + /// \param first Refers to the beginning of the sequence of elements + /// the algorithm will be applied to. + /// \param last Refers to sentinel value denoting the end of the + /// sequence of elements the algorithm will be applied. + /// \param value The value to be assigned. + /// + /// The assignments in the ranges \a uninitialized_default_construct algorithm invoked + /// without an execution policy object will execute in sequential order in + /// the calling thread. + /// + /// \returns The \a uninitialized_default_construct algorithm returns a + /// returns \a FwdIter. + /// The \a uninitialized_default_construct algorithm returns the output + /// iterator to the element in the range, one past + /// the last element copied. + /// + template + FwdIter uninitialized_default_construct( + FwdIter first, Sent last, T const& value); + + /// Copies the given \a value to an uninitialized memory area, defined by + /// the range [first, last). If an exception is thrown during the + /// initialization, the function has no effects. + /// + /// \note Complexity: Linear in the distance between \a first and \a last + /// + /// \tparam ExPolicy The type of the execution policy to use (deduced). + /// It describes the manner in which the execution + /// of the algorithm may be parallelized and the manner + /// in which it executes the assignments. + /// \tparam FwdIter The type of the source iterators used (deduced). + /// This iterator type must meet the requirements of an + /// forward iterator. + /// \tparam Sent The type of the source sentinel (deduced). This + /// sentinel type must be a sentinel for FwdIter. + /// \tparam T The type of the value to be assigned (deduced). + /// + /// \param policy The execution policy to use for the scheduling of + /// the iterations. + /// \param first Refers to the beginning of the sequence of elements + /// the algorithm will be applied to. + /// \param last Refers to sentinel value denoting the end of the + /// sequence of elements the algorithm will be applied. + /// \param value The value to be assigned. + /// + /// The assignments in the parallel \a uninitialized_default_construct algorithm invoked + /// with an execution policy object of type \a sequenced_policy + /// execute in sequential order in the calling thread. + /// + /// The assignments in the parallel \a uninitialized_default_construct algorithm invoked + /// with an execution policy object of type \a parallel_policy or + /// \a parallel_task_policy are permitted to execute in an + /// unordered fashion in unspecified threads, and indeterminately sequenced + /// within each thread. + /// + /// \returns The \a uninitialized_default_construct algorithm returns a + /// returns \a FwdIter. + /// The \a uninitialized_default_construct algorithm returns the output + /// iterator to the element in the range, one past + /// the last element copied. + /// + template + typename parallel::util::detail::algorithm_result::type + uninitialized_default_construct( + ExPolicy&& policy, FwdIter first, Sent last, T const& value); + + /// Copies the given \a value to an uninitialized memory area, defined by + /// the range [first, last). If an exception is thrown during the + /// initialization, the function has no effects. + /// + /// \note Complexity: Linear in the distance between \a first and \a last + /// + /// \tparam Rng The type of the source range used (deduced). + /// The iterators extracted from this range type must + /// meet the requirements of an input iterator. + /// \tparam T The type of the value to be assigned (deduced). + /// + /// \param rng Refers to the range to which the value + /// will be filled + /// \param value The value to be assigned. + /// + /// The assignments in the parallel \a uninitialized_default_construct algorithm invoked + /// without an execution policy object will execute in sequential order in + /// the calling thread. + /// + /// \returns The \a uninitialized_default_construct algorithm returns a + /// returns \a hpx::traits::range_traits + /// ::iterator_type. + /// The \a uninitialized_default_construct algorithm returns the output + /// iterator to the element in the range, one past + /// the last element copied. + /// + template + typename hpx::traits::range_traits::iterator_type + uninitialized_default_construct(Rng&& rng, T const& value); + + /// Copies the given \a value to an uninitialized memory area, defined by + /// the range [first, last). If an exception is thrown during the + /// initialization, the function has no effects. + /// + /// \note Complexity: Linear in the distance between \a first and \a last + /// + /// \tparam ExPolicy The type of the execution policy to use (deduced). + /// It describes the manner in which the execution + /// of the algorithm may be parallelized and the manner + /// in which it executes the assignments. + /// \tparam Rng The type of the source range used (deduced). + /// The iterators extracted from this range type must + /// meet the requirements of an input iterator. + /// \tparam T The type of the value to be assigned (deduced). + /// + /// \param policy The execution policy to use for the scheduling of + /// the iterations. + /// \param rng Refers to the range to which the value + /// will be filled + /// \param value The value to be assigned. + /// + /// The assignments in the parallel \a uninitialized_default_construct algorithm invoked + /// with an execution policy object of type \a sequenced_policy + /// execute in sequential order in the calling thread. + /// + /// The assignments in the parallel \a uninitialized_default_construct algorithm invoked + /// with an execution policy object of type \a parallel_policy or + /// \a parallel_task_policy are permitted to execute in an + /// unordered fashion in unspecified threads, and indeterminately sequenced + /// within each thread. + /// + /// \returns The \a uninitialized_default_construct algorithm returns a + /// \a hpx::future + /// ::iterator_type>, if the + /// execution policy is of type \a sequenced_task_policy + /// or \a parallel_task_policy and returns \a typename + /// hpx::traits::range_traits::iterator_type otherwise. + /// The \a uninitialized_default_construct algorithm returns the + /// iterator to one past the last element filled in the range. + /// + template + typename parallel::util::detail::algorithm_result::iterator_type>::type + uninitialized_default_construct( + ExPolicy&& policy, Rng&& rng, T const& value); + + /// Copies the given \a value value to the first count elements in an + /// uninitialized memory area beginning at first. If an exception is thrown + /// during the initialization, the function has no effects. + /// + /// \note Complexity: Performs exactly \a count assignments, if + /// count > 0, no assignments otherwise. + /// + /// \tparam FwdIter The type of the source iterators used (deduced). + /// This iterator type must meet the requirements of a + /// forward iterator. + /// \tparam Size The type of the argument specifying the number of + /// elements to apply \a f to. + /// \tparam T The type of the value to be assigned (deduced). + /// + /// \param first Refers to the beginning of the sequence of elements + /// the algorithm will be applied to. + /// \param count Refers to the number of elements starting at + /// \a first the algorithm will be applied to. + /// \param value The value to be assigned. + /// + /// The assignments in the parallel \a uninitialized_default_construct_n algorithm + /// invoked with an execution policy object of type + /// \a sequenced_policy execute in sequential order in the + /// calling thread. + /// + /// \returns The \a uninitialized_default_construct_n algorithm returns a + /// returns \a FwdIter. + /// The \a uninitialized_default_construct_n algorithm returns the output + /// iterator to the element in the range, one past + /// the last element copied. + /// + template + FwdIter uninitialized_default_construct_n( + FwdIter first, Size count, T const& value); + + /// Copies the given \a value value to the first count elements in an + /// uninitialized memory area beginning at first. If an exception is thrown + /// during the initialization, the function has no effects. + /// + /// \note Complexity: Performs exactly \a count assignments, if + /// count > 0, no assignments otherwise. + /// + /// \tparam ExPolicy The type of the execution policy to use (deduced). + /// It describes the manner in which the execution + /// of the algorithm may be parallelized and the manner + /// in which it executes the assignments. + /// \tparam FwdIter The type of the source iterators used (deduced). + /// This iterator type must meet the requirements of a + /// forward iterator. + /// \tparam Size The type of the argument specifying the number of + /// elements to apply \a f to. + /// \tparam T The type of the value to be assigned (deduced). + /// + /// \param policy The execution policy to use for the scheduling of + /// the iterations. + /// \param first Refers to the beginning of the sequence of elements + /// the algorithm will be applied to. + /// \param count Refers to the number of elements starting at + /// \a first the algorithm will be applied to. + /// \param value The value to be assigned. + /// + /// The assignments in the parallel \a uninitialized_default_construct_n algorithm + /// invoked with an execution policy object of type + /// \a sequenced_policy execute in sequential order in the + /// calling thread. + /// + /// The assignments in the parallel \a uninitialized_default_construct_n algorithm + /// invoked with an execution policy object of type + /// \a parallel_policy or + /// \a parallel_task_policy are permitted to execute in an + /// unordered fashion in unspecified threads, and indeterminately sequenced + /// within each thread. + /// + /// \returns The \a uninitialized_default_construct_n algorithm returns a + /// \a hpx::future, if the execution policy is of type + /// \a sequenced_task_policy or + /// \a parallel_task_policy and returns FwdIter + /// otherwise. + /// The \a uninitialized_default_construct_n algorithm returns the output + /// iterator to the element in the range, one past + /// the last element copied. + /// + template + typename typename parallel::util::detail::algorithm_result::type + uninitialized_default_construct_n( + ExPolicy&& policy, FwdIter first, Size count, T const& value); +}} // namespace hpx::ranges +#else + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace hpx { namespace ranges { + HPX_INLINE_CONSTEXPR_VARIABLE struct uninitialized_default_construct_t final + : hpx::functional::tag_fallback + { + private: + // clang-format off + template ::value && + hpx::traits::is_sentinel_for::value + )> + // clang-format on + friend FwdIter tag_fallback_dispatch( + hpx::ranges::uninitialized_default_construct_t, FwdIter first, + Sent last) + { + static_assert(hpx::traits::is_forward_iterator::value, + "Requires at least forward iterator."); + + return hpx::parallel::v1::detail::uninitialized_default_construct< + FwdIter>() + .call(hpx::execution::seq, first, last); + } + + // clang-format off + template ::value && + hpx::traits::is_forward_iterator::value && + hpx::traits::is_sentinel_for::value + )> + // clang-format on + friend typename parallel::util::detail::algorithm_result::type + tag_fallback_dispatch(hpx::ranges::uninitialized_default_construct_t, + ExPolicy&& policy, FwdIter first, Sent last) + { + static_assert(hpx::traits::is_forward_iterator::value, + "Requires at least forward iterator."); + + return hpx::parallel::v1::detail::uninitialized_default_construct< + FwdIter>() + .call(std::forward(policy), first, last); + } + + // clang-format off + template ::value + )> + // clang-format on + friend typename hpx::traits::range_traits::iterator_type + tag_fallback_dispatch( + hpx::ranges::uninitialized_default_construct_t, Rng&& rng) + { + using iterator_type = + typename hpx::traits::range_traits::iterator_type; + + static_assert( + hpx::traits::is_forward_iterator::value, + "Requires at least forward iterator."); + + return hpx::parallel::v1::detail::uninitialized_default_construct< + iterator_type>() + .call(hpx::execution::seq, std::begin(rng), std::end(rng)); + } + + // clang-format off + template ::value && + hpx::traits::is_range::value + )> + // clang-format on + friend typename parallel::util::detail::algorithm_result::iterator_type>::type + tag_fallback_dispatch(hpx::ranges::uninitialized_default_construct_t, + ExPolicy&& policy, Rng&& rng) + { + using iterator_type = + typename hpx::traits::range_traits::iterator_type; + + static_assert( + hpx::traits::is_forward_iterator::value, + "Requires at least forward iterator."); + + return hpx::parallel::v1::detail::uninitialized_default_construct< + iterator_type>() + .call(std::forward(policy), std::begin(rng), + std::end(rng)); + } + } uninitialized_default_construct{}; + + HPX_INLINE_CONSTEXPR_VARIABLE struct uninitialized_default_construct_n_t + final + : hpx::functional::tag_fallback + { + private: + // clang-format off + template ::value + )> + // clang-format on + friend FwdIter tag_fallback_dispatch( + hpx::ranges::uninitialized_default_construct_n_t, FwdIter first, + Size count) + { + static_assert(hpx::traits::is_forward_iterator::value, + "Requires at least forward iterator."); + + return hpx::parallel::v1::detail::uninitialized_default_construct_n< + FwdIter>() + .call(hpx::execution::seq, first, count); + } + + // clang-format off + template ::value && + hpx::traits::is_forward_iterator::value + )> + // clang-format on + friend typename parallel::util::detail::algorithm_result::type + tag_fallback_dispatch(hpx::ranges::uninitialized_default_construct_n_t, + ExPolicy&& policy, FwdIter first, Size count) + { + static_assert(hpx::traits::is_forward_iterator::value, + "Requires at least forward iterator."); + + return hpx::parallel::v1::detail::uninitialized_default_construct_n< + FwdIter>() + .call(std::forward(policy), first, count); + } + } uninitialized_default_construct_n{}; +}} // namespace hpx::ranges + +#endif diff --git a/libs/parallelism/algorithms/tests/unit/container_algorithms/CMakeLists.txt b/libs/parallelism/algorithms/tests/unit/container_algorithms/CMakeLists.txt index a588b0a59fe8..a1c7057fd28e 100644 --- a/libs/parallelism/algorithms/tests/unit/container_algorithms/CMakeLists.txt +++ b/libs/parallelism/algorithms/tests/unit/container_algorithms/CMakeLists.txt @@ -94,6 +94,8 @@ set(tests transform_reduce_binary_exception_range transform_reduce_binary_range transform_reduce_range + uninitialized_default_construct_range + uninitialized_default_constructn_range uninitialized_move_range uninitialized_move_n_range unique_range diff --git a/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_construct_range.cpp b/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_construct_range.cpp new file mode 100644 index 000000000000..da5a7528990e --- /dev/null +++ b/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_construct_range.cpp @@ -0,0 +1,185 @@ +// Copyright (c) 2018 Christopher Ogle +// Copyright (c) 2020 Hartmut Kaiser +// +// SPDX-License-Identifier: BSL-1.0 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include "test_utils.hpp" + +//////////////////////////////////////////////////////////////////////////// +void test_uninitialized_fill_sent() +{ + std::vector c(200); + std::iota(std::begin(c), std::end(c), std::rand()); + + hpx::ranges::uninitialized_fill( + std::begin(c), sentinel{*(std::begin(c) + 100)}, 10); + + // verify values + std::size_t count = 0; + std::for_each( + std::begin(c), std::begin(c) + 100, [&count](std::size_t v) -> void { + HPX_TEST_EQ(v, std::size_t(10)); + ++count; + }); + + HPX_TEST_EQ(count, (size_t) 100); +} + +template +void test_uninitialized_fill_sent(ExPolicy policy) +{ + static_assert(hpx::is_execution_policy::value, + "hpx::is_execution_policy::value"); + + std::vector c(200); + std::iota(std::begin(c), std::end(c), std::rand()); + + hpx::ranges::uninitialized_fill(policy, std::begin(c), + sentinel{*(std::begin(c) + 100)}, 10); + + // verify values + std::size_t count = 0; + std::for_each( + std::begin(c), std::begin(c) + 100, [&count](std::size_t v) -> void { + HPX_TEST_EQ(v, std::size_t(10)); + ++count; + }); + + HPX_TEST_EQ(count, (size_t) 100); +} + +template +void test_uninitialized_fill(IteratorTag) +{ + std::vector c(10007); + std::iota(std::begin(c), std::end(c), std::rand()); + + hpx::ranges::uninitialized_fill(c, 10); + + // verify values + std::size_t count = 0; + std::for_each(std::begin(c), std::end(c), [&count](std::size_t v) -> void { + HPX_TEST_EQ(v, std::size_t(10)); + ++count; + }); + + HPX_TEST_EQ(count, c.size()); +} + +template +void test_uninitialized_fill(ExPolicy policy, IteratorTag) +{ + static_assert(hpx::is_execution_policy::value, + "hpx::is_execution_policy::value"); + + std::vector c(10007); + std::iota(std::begin(c), std::end(c), std::rand()); + + hpx::ranges::uninitialized_fill(policy, c, 10); + + // verify values + std::size_t count = 0; + std::for_each(std::begin(c), std::end(c), [&count](std::size_t v) -> void { + HPX_TEST_EQ(v, std::size_t(10)); + ++count; + }); + + HPX_TEST_EQ(count, c.size()); +} + +template +void test_uninitialized_fill_async(ExPolicy p, IteratorTag) +{ + std::vector c(10007); + std::iota(std::begin(c), std::end(c), std::rand()); + + hpx::future f = hpx::ranges::uninitialized_fill(p, c, 10); + f.wait(); + + std::size_t count = 0; + std::for_each(std::begin(c), std::end(c), [&count](std::size_t v) -> void { + HPX_TEST_EQ(v, std::size_t(10)); + ++count; + }); + + HPX_TEST_EQ(count, c.size()); +} + +template +void test_uninitialized_fill() +{ + using namespace hpx::execution; + + test_uninitialized_fill(IteratorTag()); + + test_uninitialized_fill(seq, IteratorTag()); + test_uninitialized_fill(par, IteratorTag()); + test_uninitialized_fill(par_unseq, IteratorTag()); + + test_uninitialized_fill_async(seq(task), IteratorTag()); + test_uninitialized_fill_async(par(task), IteratorTag()); + + test_uninitialized_fill_sent(); + test_uninitialized_fill_sent(seq); + test_uninitialized_fill_sent(par); + test_uninitialized_fill_sent(par_unseq); +} + +void uninitialized_fill_test() +{ + test_uninitialized_fill(); + test_uninitialized_fill(); +} + +//////////////////////////////////////////////////////////////////////////// +int hpx_main(hpx::program_options::variables_map& vm) +{ + unsigned int seed = (unsigned int) std::time(nullptr); + if (vm.count("seed")) + seed = vm["seed"].as(); + + std::cout << "using seed: " << seed << std::endl; + std::srand(seed); + + uninitialized_fill_test(); + return hpx::local::finalize(); +} + +int main(int argc, char* argv[]) +{ + // add command line option which controls the random number generator seed + using namespace hpx::program_options; + options_description desc_commandline( + "Usage: " HPX_APPLICATION_STRING " [options]"); + + desc_commandline.add_options()("seed,s", value(), + "the random number generator seed to use for this run"); + + // By default this test should run on all available cores + std::vector const cfg = {"hpx.os_threads=all"}; + + // Initialize and run HPX + hpx::local::init_params init_args; + init_args.desc_cmdline = desc_commandline; + init_args.cfg = cfg; + + HPX_TEST_EQ_MSG(hpx::local::init(hpx_main, argc, argv, init_args), 0, + "HPX main exited with non-zero status"); + + return hpx::util::report_errors(); +} diff --git a/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_constructn_range.cpp b/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_constructn_range.cpp new file mode 100644 index 000000000000..455298ab0b3e --- /dev/null +++ b/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_constructn_range.cpp @@ -0,0 +1,134 @@ +// Copyright (c) 2014 Grant Mercer +// Copyright (c) 2015 Hartmut Kaiser +// +// SPDX-License-Identifier: BSL-1.0 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "test_utils.hpp" + +//////////////////////////////////////////////////////////////////////////// +template +void test_uninitialized_fill_n_sent(IteratorTag) +{ + std::vector c(10007); + std::size_t sent_len = (std::rand() % 10007) + 1; + hpx::ranges::uninitialized_fill_n(std::begin(c), sent_len, 10); + + std::size_t count = 0; + std::for_each(std::begin(c), std::begin(c) + sent_len, + [&count](std::size_t v) -> void { + HPX_TEST_EQ(v, std::size_t(10)); + ++count; + }); + + HPX_TEST_EQ(count, sent_len); +} + +template +void test_uninitialized_fill_n_sent(ExPolicy&& policy, IteratorTag) +{ + static_assert(hpx::is_execution_policy::value, + "hpx::is_execution_policy::value"); + + std::vector c(10007); + std::size_t sent_len = (std::rand() % 10007) + 1; + hpx::ranges::uninitialized_fill_n(policy, std::begin(c), sent_len, 10); + + std::size_t count = 0; + std::for_each(std::begin(c), std::begin(c) + sent_len, + [&count](std::size_t v) -> void { + HPX_TEST_EQ(v, std::size_t(10)); + ++count; + }); + + HPX_TEST_EQ(count, sent_len); +} + +template +void test_uninitialized_fill_n_sent_async(ExPolicy&& p, IteratorTag) +{ + std::vector c(10007); + std::size_t sent_len = (std::rand() % 10007) + 1; + auto f = hpx::ranges::uninitialized_fill_n(p, std::begin(c), sent_len, 10); + f.wait(); + + std::size_t count = 0; + std::for_each(std::begin(c), std::begin(c) + sent_len, + [&count](std::size_t v) -> void { + HPX_TEST_EQ(v, std::size_t(10)); + ++count; + }); + + HPX_TEST_EQ(count, sent_len); +} + +template +void test_uninitialized_fill_n_sent() +{ + using namespace hpx::execution; + + test_uninitialized_fill_n_sent(IteratorTag()); + + test_uninitialized_fill_n_sent(seq, IteratorTag()); + test_uninitialized_fill_n_sent(par, IteratorTag()); + test_uninitialized_fill_n_sent(par_unseq, IteratorTag()); + + test_uninitialized_fill_n_sent_async(seq(task), IteratorTag()); + test_uninitialized_fill_n_sent_async(par(task), IteratorTag()); +} + +void uninitialized_fill_n_sent_test() +{ + test_uninitialized_fill_n_sent(); + test_uninitialized_fill_n_sent(); +} + +int hpx_main(hpx::program_options::variables_map& vm) +{ + unsigned int seed = (unsigned int) std::time(nullptr); + if (vm.count("seed")) + seed = vm["seed"].as(); + + std::cout << "using seed: " << seed << std::endl; + std::srand(seed); + + uninitialized_fill_n_sent_test(); + return hpx::local::finalize(); +} + +int main(int argc, char* argv[]) +{ + // add command line option which controls the random number generator seed + using namespace hpx::program_options; + options_description desc_commandline( + "Usage: " HPX_APPLICATION_STRING " [options]"); + + desc_commandline.add_options()("seed,s", value(), + "the random number generator seed to use for this run"); + + // By default this test should run on all available cores + std::vector const cfg = {"hpx.os_threads=all"}; + + // Initialize and run HPX + hpx::local::init_params init_args; + init_args.desc_cmdline = desc_commandline; + init_args.cfg = cfg; + + HPX_TEST_EQ_MSG(hpx::local::init(hpx_main, argc, argv, init_args), 0, + "HPX main exited with non-zero status"); + + return hpx::util::report_errors(); +} From b5ada04cc1a123ebcb058e4c418b01ff03be11c8 Mon Sep 17 00:00:00 2001 From: targetakhil Date: Sun, 27 Jun 2021 11:08:34 +0530 Subject: [PATCH 3/5] added container tests for uninitialized_default_construct and uninitialized_default_construct_n --- .../include/hpx/local/memory.hpp | 2 - .../uninitialized_default_construct_range.cpp | 247 ++++++++++++------ ...uninitialized_default_constructn_range.cpp | 141 ++++++---- 3 files changed, 271 insertions(+), 119 deletions(-) diff --git a/libs/full/include_local/include/hpx/local/memory.hpp b/libs/full/include_local/include/hpx/local/memory.hpp index 582f73d749a0..0d1cbec9d942 100644 --- a/libs/full/include_local/include/hpx/local/memory.hpp +++ b/libs/full/include_local/include/hpx/local/memory.hpp @@ -12,8 +12,6 @@ namespace hpx { using hpx::parallel::uninitialized_copy; using hpx::parallel::uninitialized_copy_n; - using hpx::parallel::uninitialized_default_construct; - using hpx::parallel::uninitialized_default_construct_n; using hpx::parallel::uninitialized_fill; using hpx::parallel::uninitialized_fill_n; using hpx::parallel::uninitialized_value_construct; diff --git a/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_construct_range.cpp b/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_construct_range.cpp index da5a7528990e..07652c2b7c82 100644 --- a/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_construct_range.cpp +++ b/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_construct_range.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include @@ -17,133 +17,234 @@ #include #include -#include #include "test_utils.hpp" //////////////////////////////////////////////////////////////////////////// -void test_uninitialized_fill_sent() +struct default_constructable +{ + default_constructable() + : value_(42) + { + } + + default_constructable(std::int32_t val) + { + value_ = val; + } + + bool operator!=(default_constructable const& lhs) const + { + return lhs.value_ != value_; + } + + std::int32_t value_; +}; + +struct value_constructable +{ + std::int32_t value_; +}; + +std::size_t const data_size = 10; + +//////////////////////////////////////////////////////////////////////////// +template +void test_uninitialized_default_construct_range_sent(IteratorTag) +{ + typedef std::vector base_iterator; + + base_iterator c(data_size, default_constructable(10)); + auto end_size = rand() % data_size; + c[end_size] = default_constructable(20); + + hpx::ranges::uninitialized_default_construct( + std::begin(c), sentinel{20}); + + std::size_t count42 = 0; + std::size_t count10 = 0; + std::for_each(std::begin(c), std::begin(c) + data_size, + [&count42, &count10](default_constructable v1) { + if (v1.value_ == 42) + { + count42++; + } + else if (v1.value_ == 10) + { + count10++; + } + }); + + HPX_TEST_EQ(count42, end_size); + HPX_TEST_EQ(count10, data_size - end_size - 1); +} + +template +void test_uninitialized_default_construct_range_sent( + ExPolicy&& policy, IteratorTag) +{ + typedef std::vector base_iterator; + + base_iterator c(data_size, default_constructable(10)); + auto end_size = rand() % data_size; + c[end_size] = default_constructable(20); + + hpx::ranges::uninitialized_default_construct( + policy, std::begin(c), sentinel{20}); + + std::size_t count42 = 0; + std::size_t count10 = 0; + std::for_each(std::begin(c), std::begin(c) + data_size, + [&count42, &count10](default_constructable v1) { + if (v1.value_ == 42) + { + count42++; + } + else if (v1.value_ == 10) + { + count10++; + } + }); + + HPX_TEST_EQ(count42, end_size); + HPX_TEST_EQ(count10, data_size - end_size - 1); +} + +template +void test_uninitialized_default_construct_range(IteratorTag) { - std::vector c(200); - std::iota(std::begin(c), std::end(c), std::rand()); + typedef std::vector base_iterator; - hpx::ranges::uninitialized_fill( - std::begin(c), sentinel{*(std::begin(c) + 100)}, 10); + base_iterator c(data_size, default_constructable(10)); + hpx::ranges::uninitialized_default_construct(c); - // verify values std::size_t count = 0; - std::for_each( - std::begin(c), std::begin(c) + 100, [&count](std::size_t v) -> void { - HPX_TEST_EQ(v, std::size_t(10)); + std::for_each(std::begin(c), std::begin(c) + data_size, + [&count](default_constructable v1) { + HPX_TEST_EQ(v1.value_, 42); ++count; }); - - HPX_TEST_EQ(count, (size_t) 100); + HPX_TEST_EQ(count, data_size); } -template -void test_uninitialized_fill_sent(ExPolicy policy) +template +void test_uninitialized_default_construct_range(ExPolicy&& policy, IteratorTag) { static_assert(hpx::is_execution_policy::value, "hpx::is_execution_policy::value"); - std::vector c(200); - std::iota(std::begin(c), std::end(c), std::rand()); + typedef std::vector base_iterator; - hpx::ranges::uninitialized_fill(policy, std::begin(c), - sentinel{*(std::begin(c) + 100)}, 10); + base_iterator c(data_size, default_constructable(10)); + hpx::ranges::uninitialized_default_construct( + std::forward(policy), c); - // verify values std::size_t count = 0; - std::for_each( - std::begin(c), std::begin(c) + 100, [&count](std::size_t v) -> void { - HPX_TEST_EQ(v, std::size_t(10)); + std::for_each(std::begin(c), std::begin(c) + data_size, + [&count](default_constructable v1) { + HPX_TEST_EQ(v1.value_, 42); ++count; }); - - HPX_TEST_EQ(count, (size_t) 100); + HPX_TEST_EQ(count, data_size); } -template -void test_uninitialized_fill(IteratorTag) +template +void test_uninitialized_default_construct_range_async( + ExPolicy&& policy, IteratorTag) { - std::vector c(10007); - std::iota(std::begin(c), std::end(c), std::rand()); + static_assert(hpx::is_execution_policy::value, + "hpx::is_execution_policy::value"); - hpx::ranges::uninitialized_fill(c, 10); + typedef std::vector base_iterator; - // verify values - std::size_t count = 0; - std::for_each(std::begin(c), std::end(c), [&count](std::size_t v) -> void { - HPX_TEST_EQ(v, std::size_t(10)); - ++count; - }); + base_iterator c(data_size, default_constructable(10)); + auto f = hpx::ranges::uninitialized_default_construct( + std::forward(policy), c); + f.wait(); - HPX_TEST_EQ(count, c.size()); + std::size_t count = 0; + std::for_each(std::begin(c), std::begin(c) + data_size, + [&count](default_constructable v1) { + HPX_TEST_EQ(v1.value_, 42); + ++count; + }); + HPX_TEST_EQ(count, data_size); } template -void test_uninitialized_fill(ExPolicy policy, IteratorTag) +void test_uninitialized_default_construct_range2(ExPolicy&& policy, IteratorTag) { static_assert(hpx::is_execution_policy::value, "hpx::is_execution_policy::value"); - std::vector c(10007); - std::iota(std::begin(c), std::end(c), std::rand()); + typedef std::vector base_iterator; + base_iterator c(data_size, value_constructable{10}); - hpx::ranges::uninitialized_fill(policy, c, 10); + hpx::ranges::uninitialized_default_construct( + std::forward(policy), c); - // verify values std::size_t count = 0; - std::for_each(std::begin(c), std::end(c), [&count](std::size_t v) -> void { - HPX_TEST_EQ(v, std::size_t(10)); - ++count; - }); - - HPX_TEST_EQ(count, c.size()); + std::for_each(std::begin(c), std::begin(c) + data_size, + [&count](value_constructable v1) { + HPX_TEST_EQ(v1.value_, (std::int32_t) 10); + ++count; + }); + HPX_TEST_EQ(count, data_size); } template -void test_uninitialized_fill_async(ExPolicy p, IteratorTag) +void test_uninitialized_default_construct_range_async2( + ExPolicy&& policy, IteratorTag) { - std::vector c(10007); - std::iota(std::begin(c), std::end(c), std::rand()); + static_assert(hpx::is_execution_policy::value, + "hpx::is_execution_policy::value"); - hpx::future f = hpx::ranges::uninitialized_fill(p, c, 10); + typedef std::vector base_iterator; + base_iterator c(data_size, value_constructable{10}); + + auto f = hpx::ranges::uninitialized_default_construct( + std::forward(policy), c); f.wait(); std::size_t count = 0; - std::for_each(std::begin(c), std::end(c), [&count](std::size_t v) -> void { - HPX_TEST_EQ(v, std::size_t(10)); - ++count; - }); - - HPX_TEST_EQ(count, c.size()); + std::for_each(std::begin(c), std::begin(c) + data_size, + [&count](value_constructable v1) { + HPX_TEST_EQ(v1.value_, (std::int32_t) 10); + ++count; + }); + HPX_TEST_EQ(count, data_size); } template -void test_uninitialized_fill() +void test_uninitialized_default_construct_range() { using namespace hpx::execution; - test_uninitialized_fill(IteratorTag()); + test_uninitialized_default_construct_range(IteratorTag()); + test_uninitialized_default_construct_range(seq, IteratorTag()); + test_uninitialized_default_construct_range(par, IteratorTag()); + test_uninitialized_default_construct_range(par_unseq, IteratorTag()); + + test_uninitialized_default_construct_range_async(seq(task), IteratorTag()); + test_uninitialized_default_construct_range_async(par(task), IteratorTag()); - test_uninitialized_fill(seq, IteratorTag()); - test_uninitialized_fill(par, IteratorTag()); - test_uninitialized_fill(par_unseq, IteratorTag()); + test_uninitialized_default_construct_range2(seq, IteratorTag()); + test_uninitialized_default_construct_range2(par, IteratorTag()); + test_uninitialized_default_construct_range2(par_unseq, IteratorTag()); - test_uninitialized_fill_async(seq(task), IteratorTag()); - test_uninitialized_fill_async(par(task), IteratorTag()); + test_uninitialized_default_construct_range_async2(seq(task), IteratorTag()); + test_uninitialized_default_construct_range_async2(par(task), IteratorTag()); - test_uninitialized_fill_sent(); - test_uninitialized_fill_sent(seq); - test_uninitialized_fill_sent(par); - test_uninitialized_fill_sent(par_unseq); + test_uninitialized_default_construct_range_sent(IteratorTag()); + test_uninitialized_default_construct_range_sent(seq, IteratorTag()); + test_uninitialized_default_construct_range_sent(par, IteratorTag()); + test_uninitialized_default_construct_range_sent(par_unseq, IteratorTag()); } -void uninitialized_fill_test() +void uninitialized_default_construct_range_test() { - test_uninitialized_fill(); - test_uninitialized_fill(); + test_uninitialized_default_construct_range< + std::random_access_iterator_tag>(); + test_uninitialized_default_construct_range(); } //////////////////////////////////////////////////////////////////////////// @@ -156,7 +257,7 @@ int hpx_main(hpx::program_options::variables_map& vm) std::cout << "using seed: " << seed << std::endl; std::srand(seed); - uninitialized_fill_test(); + uninitialized_default_construct_range_test(); return hpx::local::finalize(); } diff --git a/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_constructn_range.cpp b/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_constructn_range.cpp index 455298ab0b3e..cfefe0aa7697 100644 --- a/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_constructn_range.cpp +++ b/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_constructn_range.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include @@ -19,81 +19,134 @@ #include "test_utils.hpp" +//////////////////////////////////////////////////////////////////////////// +struct default_constructable +{ + default_constructable() + : value_(42) + { + } + + default_constructable(std::int32_t val) + { + value_ = val; + } + + std::int32_t value_; +}; + +std::size_t const data_size = 10007; + //////////////////////////////////////////////////////////////////////////// template -void test_uninitialized_fill_n_sent(IteratorTag) +void test_uninitialized_default_construct_n(IteratorTag) { - std::vector c(10007); - std::size_t sent_len = (std::rand() % 10007) + 1; - hpx::ranges::uninitialized_fill_n(std::begin(c), sent_len, 10); - - std::size_t count = 0; - std::for_each(std::begin(c), std::begin(c) + sent_len, - [&count](std::size_t v) -> void { - HPX_TEST_EQ(v, std::size_t(10)); - ++count; + using base_iterator = std::vector; + + base_iterator c(data_size, default_constructable(10)); + auto end_size = rand() % data_size; + hpx::ranges::uninitialized_default_construct_n(std::begin(c), end_size); + + std::size_t count42 = 0; + std::size_t count10 = 0; + std::for_each(std::begin(c), std::begin(c) + data_size, + [&count42, &count10](default_constructable v1) { + if (v1.value_ == 42) + { + count42++; + } + else if (v1.value_ == 10) + { + count10++; + } }); - HPX_TEST_EQ(count, sent_len); + HPX_TEST_EQ(count42, end_size); + HPX_TEST_EQ(count10, data_size - end_size); } template -void test_uninitialized_fill_n_sent(ExPolicy&& policy, IteratorTag) +void test_uninitialized_default_construct_n(ExPolicy&& policy, IteratorTag) { static_assert(hpx::is_execution_policy::value, "hpx::is_execution_policy::value"); - std::vector c(10007); - std::size_t sent_len = (std::rand() % 10007) + 1; - hpx::ranges::uninitialized_fill_n(policy, std::begin(c), sent_len, 10); - - std::size_t count = 0; - std::for_each(std::begin(c), std::begin(c) + sent_len, - [&count](std::size_t v) -> void { - HPX_TEST_EQ(v, std::size_t(10)); - ++count; + using base_iterator = std::vector; + + base_iterator c(data_size, default_constructable(10)); + auto end_size = rand() % data_size; + hpx::ranges::uninitialized_default_construct_n( + policy, std::begin(c), end_size); + + std::size_t count42 = 0; + std::size_t count10 = 0; + std::for_each(std::begin(c), std::begin(c) + data_size, + [&count42, &count10](default_constructable v1) { + if (v1.value_ == 42) + { + count42++; + } + else if (v1.value_ == 10) + { + count10++; + } }); - HPX_TEST_EQ(count, sent_len); + HPX_TEST_EQ(count42, end_size); + HPX_TEST_EQ(count10, data_size - end_size); } template -void test_uninitialized_fill_n_sent_async(ExPolicy&& p, IteratorTag) +void test_uninitialized_default_construct_n_async(ExPolicy&& p, IteratorTag) { - std::vector c(10007); - std::size_t sent_len = (std::rand() % 10007) + 1; - auto f = hpx::ranges::uninitialized_fill_n(p, std::begin(c), sent_len, 10); + static_assert(hpx::is_execution_policy::value, + "hpx::is_execution_policy::value"); + + using base_iterator = std::vector; + + base_iterator c(data_size, default_constructable(10)); + auto end_size = rand() % data_size; + auto f = hpx::ranges::uninitialized_default_construct_n( + p, std::begin(c), end_size); f.wait(); - std::size_t count = 0; - std::for_each(std::begin(c), std::begin(c) + sent_len, - [&count](std::size_t v) -> void { - HPX_TEST_EQ(v, std::size_t(10)); - ++count; + std::size_t count42 = 0; + std::size_t count10 = 0; + std::for_each(std::begin(c), std::begin(c) + data_size, + [&count42, &count10](default_constructable v1) { + if (v1.value_ == 42) + { + count42++; + } + else if (v1.value_ == 10) + { + count10++; + } }); - HPX_TEST_EQ(count, sent_len); + HPX_TEST_EQ(count42, end_size); + HPX_TEST_EQ(count10, data_size - end_size); } template -void test_uninitialized_fill_n_sent() +void test_uninitialized_default_construct_n() { using namespace hpx::execution; - test_uninitialized_fill_n_sent(IteratorTag()); + test_uninitialized_default_construct_n(IteratorTag()); - test_uninitialized_fill_n_sent(seq, IteratorTag()); - test_uninitialized_fill_n_sent(par, IteratorTag()); - test_uninitialized_fill_n_sent(par_unseq, IteratorTag()); + test_uninitialized_default_construct_n(seq, IteratorTag()); + test_uninitialized_default_construct_n(par, IteratorTag()); + test_uninitialized_default_construct_n(par_unseq, IteratorTag()); - test_uninitialized_fill_n_sent_async(seq(task), IteratorTag()); - test_uninitialized_fill_n_sent_async(par(task), IteratorTag()); + test_uninitialized_default_construct_n_async(seq(task), IteratorTag()); + test_uninitialized_default_construct_n_async(par(task), IteratorTag()); } -void uninitialized_fill_n_sent_test() +void uninitialized_default_construct_n_test() { - test_uninitialized_fill_n_sent(); - test_uninitialized_fill_n_sent(); + test_uninitialized_default_construct_n(); + test_uninitialized_default_construct_n(); } int hpx_main(hpx::program_options::variables_map& vm) @@ -105,7 +158,7 @@ int hpx_main(hpx::program_options::variables_map& vm) std::cout << "using seed: " << seed << std::endl; std::srand(seed); - uninitialized_fill_n_sent_test(); + uninitialized_default_construct_n_test(); return hpx::local::finalize(); } From 7831f0274eaf092606acc32bf6b1cdcdf3a77bb0 Mon Sep 17 00:00:00 2001 From: targetakhil Date: Sun, 27 Jun 2021 22:36:13 +0530 Subject: [PATCH 4/5] updated documentation for uninitialized_default_construct --- docs/sphinx/api/public_api.rst | 6 +- .../writing_single_node_hpx_applications.rst | 4 +- .../uninitialized_default_construct.hpp | 206 +++++------------- .../uninitialized_default_construct.hpp | 198 +++++++++-------- .../uninitialized_default_construct_range.cpp | 2 +- 5 files changed, 164 insertions(+), 252 deletions(-) diff --git a/docs/sphinx/api/public_api.rst b/docs/sphinx/api/public_api.rst index 75b6fecbd002..1006fdf28542 100644 --- a/docs/sphinx/api/public_api.rst +++ b/docs/sphinx/api/public_api.rst @@ -567,8 +567,8 @@ Functions - :cpp:func:`hpx::parallel::v1::uninitialized_copy` - :cpp:func:`hpx::parallel::v1::uninitialized_copy_n` -- :cpp:func:`hpx::parallel::v1::uninitialized_default_construct` -- :cpp:func:`hpx::parallel::v1::uninitialized_default_construct_n` +- :cpp:func:`hpx::uninitialized_default_construct` +- :cpp:func:`hpx::uninitialized_default_construct_n` - :cpp:func:`hpx::parallel::v1::uninitialized_fill` - :cpp:func:`hpx::parallel::v1::uninitialized_fill_n` - :cpp:func:`hpx::uninitialized_move` @@ -576,6 +576,8 @@ Functions - :cpp:func:`hpx::parallel::v1::uninitialized_value_construct` - :cpp:func:`hpx::parallel::v1::uninitialized_value_construct_n` +- :cpp:func:`hpx::ranges::uninitialized_default_construct` +- :cpp:func:`hpx::ranges::uninitialized_default_construct_n` - :cpp:func:`hpx::ranges::uninitialized_move` - :cpp:func:`hpx::ranges::uninitialized_move_n` diff --git a/docs/sphinx/manual/writing_single_node_hpx_applications.rst b/docs/sphinx/manual/writing_single_node_hpx_applications.rst index 17d696916004..66064220a525 100644 --- a/docs/sphinx/manual/writing_single_node_hpx_applications.rst +++ b/docs/sphinx/manual/writing_single_node_hpx_applications.rst @@ -724,11 +724,11 @@ Parallel algorithms * Copies a number of objects to an uninitialized area of memory. * ```` * :cppreference-memory:`uninitialized_copy_n` - * * :cpp:func:`hpx::parallel::v1::uninitialized_default_construct` + * * :cpp:func:`hpx::uninitialized_default_construct` * Copies a range of objects to an uninitialized area of memory. * ```` * :cppreference-memory:`uninitialized_default_construct` - * * :cpp:func:`hpx::parallel::v1::uninitialized_default_construct_n` + * * :cpp:func:`hpx::uninitialized_default_construct_n` * Copies a number of objects to an uninitialized area of memory. * ```` * :cppreference-memory:`uninitialized_default_construct_n` diff --git a/libs/parallelism/algorithms/include/hpx/parallel/algorithms/uninitialized_default_construct.hpp b/libs/parallelism/algorithms/include/hpx/parallel/algorithms/uninitialized_default_construct.hpp index e5cb867bf964..9672105bc506 100644 --- a/libs/parallelism/algorithms/include/hpx/parallel/algorithms/uninitialized_default_construct.hpp +++ b/libs/parallelism/algorithms/include/hpx/parallel/algorithms/uninitialized_default_construct.hpp @@ -11,38 +11,38 @@ #if defined(DOXYGEN) namespace hpx { - /// Copies the given \a value to an uninitialized memory area, defined by - /// the range [first, last). If an exception is thrown during the + /// Constructs objects of type typename iterator_traits + /// ::value_type in the uninitialized storage designated by the range + /// by default-initialization. If an exception is thrown during the /// initialization, the function has no effects. /// - /// \note Complexity: Linear in the distance between \a first and \a last + /// \note Complexity: Performs exactly \a last - \a first assignments. /// /// \tparam FwdIter The type of the source iterators used (deduced). /// This iterator type must meet the requirements of an /// forward iterator. - /// \tparam T The type of the value to be assigned (deduced). /// /// \param first Refers to the beginning of the sequence of elements /// the algorithm will be applied to. /// \param last Refers to the end of the sequence of elements the /// algorithm will be applied to. - /// \param value The value to be assigned. /// - /// The assignments in the parallel \a uninitialized_default_construct algorithm invoked - /// without an execution policy object will execute in sequential order in - /// the calling thread. + /// The assignments in the parallel \a uninitialized_default_construct + /// algorithm invoked without an execution policy object will execute in + /// sequential order in the calling thread. /// - /// \returns The \a uninitialized_default_construct algorithm returns nothing + /// \returns The \a uninitialized_default_construct algorithm + /// returns nothing /// - template - void uninitialized_default_construct( - FwdIter first, FwdIter last, T const& value); + template + void uninitialized_default_construct(FwdIter first, FwdIter last); - /// Copies the given \a value to an uninitialized memory area, defined by - /// the range [first, last). If an exception is thrown during the + /// Constructs objects of type typename iterator_traits + /// ::value_type in the uninitialized storage designated by the range + /// by default-initialization. If an exception is thrown during the /// initialization, the function has no effects. /// - /// \note Complexity: Linear in the distance between \a first and \a last + /// \note Complexity: Performs exactly \a last - \a first assignments. /// /// \tparam ExPolicy The type of the execution policy to use (deduced). /// It describes the manner in which the execution @@ -51,7 +51,6 @@ namespace hpx { /// \tparam FwdIter The type of the source iterators used (deduced). /// This iterator type must meet the requirements of an /// forward iterator. - /// \tparam T The type of the value to be assigned (deduced). /// /// \param policy The execution policy to use for the scheduling of /// the iterations. @@ -59,18 +58,16 @@ namespace hpx { /// the algorithm will be applied to. /// \param last Refers to the end of the sequence of elements the /// algorithm will be applied to. - /// \param value The value to be assigned. /// - /// The initializations in the parallel \a uninitialized_default_construct algorithm - /// invoked with an execution policy object of type - /// \a sequenced_policy execute in sequential order in the - /// calling thread. + /// The assignments in the parallel \a uninitialized_default_construct + /// algorithm invoked with an execution policy object of type \a + /// sequenced_policy execute in sequential order in the calling thread. /// - /// The initializations in the parallel \a uninitialized_default_construct algorithm - /// invoked with an execution policy object of type - /// \a parallel_policy or \a parallel_task_policy are - /// permitted to execute in an unordered fashion in unspecified threads, - /// and indeterminately sequenced within each thread. + /// The assignments in the parallel \a uninitialized_default_construct + /// algorithm invoked with an execution policy object of type \a + /// parallel_policy or \a parallel_task_policy are permitted to execute + /// in an unordered fashion in unspecified threads, and indeterminately + /// sequenced within each thread. /// /// \returns The \a uninitialized_default_construct algorithm returns a /// \a hpx::future, if the execution policy is of type @@ -78,48 +75,47 @@ namespace hpx { /// \a parallel_task_policy and returns nothing /// otherwise. /// - template + template typename parallel::util::detail::algorithm_result::type uninitialized_default_construct( - ExPolicy&& policy, FwdIter first, FwdIter last, T const& value); + ExPolicy&& policy, FwdIter first, FwdIter last); - /// Copies the given \a value value to the first count elements in an - /// uninitialized memory area beginning at first. If an exception is thrown - /// during the initialization, the function has no effects. + /// Constructs objects of type typename iterator_traits + /// ::value_type in the uninitialized storage designated by the range + /// [first, first + count) by default-initialization. If an exception + /// is thrown during the initialization, the function has no effects. /// /// \note Complexity: Performs exactly \a count assignments, if /// count > 0, no assignments otherwise. /// /// \tparam FwdIter The type of the source iterators used (deduced). - /// This iterator type must meet the requirements of a + /// This iterator type must meet the requirements of an /// forward iterator. /// \tparam Size The type of the argument specifying the number of /// elements to apply \a f to. - /// \tparam T The type of the value to be assigned (deduced). /// /// \param first Refers to the beginning of the sequence of elements /// the algorithm will be applied to. /// \param count Refers to the number of elements starting at /// \a first the algorithm will be applied to. - /// \param value The value to be assigned. /// - /// The assignments in the parallel \a uninitialized_default_construct_n algorithm - /// invoked without an execution policy object execute in sequential order - /// in the calling thread. + /// The assignments in the parallel \a uninitialized_default_construct_n + /// algorithm invoked without an execution policy object execute in + /// sequential order in the calling thread. /// /// \returns The \a uninitialized_default_construct_n algorithm returns a /// returns \a FwdIter. - /// The \a uninitialized_default_construct_n algorithm returns the output - /// iterator to the element in the range, one past - /// the last element copied. + /// The \a uninitialized_default_construct_n algorithm returns + /// the iterator to the element in the source range, one past + /// the last element constructed. /// - template - FwdIter uninitialized_default_construct_n( - FwdIter first, Size count, T const& value); + template + FwdIter uninitialized_default_construct_n(FwdIter first, Size count); - /// Copies the given \a value value to the first count elements in an - /// uninitialized memory area beginning at first. If an exception is thrown - /// during the initialization, the function has no effects. + /// Constructs objects of type typename iterator_traits + /// ::value_type in the uninitialized storage designated by the range + /// [first, first + count) by default-initialization. If an exception + /// is thrown during the initialization, the function has no effects. /// /// \note Complexity: Performs exactly \a count assignments, if /// count > 0, no assignments otherwise. @@ -129,11 +125,10 @@ namespace hpx { /// of the algorithm may be parallelized and the manner /// in which it executes the assignments. /// \tparam FwdIter The type of the source iterators used (deduced). - /// This iterator type must meet the requirements of a + /// This iterator type must meet the requirements of an /// forward iterator. /// \tparam Size The type of the argument specifying the number of /// elements to apply \a f to. - /// \tparam T The type of the value to be assigned (deduced). /// /// \param policy The execution policy to use for the scheduling of /// the iterations. @@ -141,32 +136,32 @@ namespace hpx { /// the algorithm will be applied to. /// \param count Refers to the number of elements starting at /// \a first the algorithm will be applied to. - /// \param value The value to be assigned. /// - /// The initializations in the parallel \a uninitialized_default_construct_n algorithm - /// invoked with an execution policy object of type + /// The assignments in the parallel \a uninitialized_default_construct_n + /// algorithm invoked with an execution policy object of type /// \a sequenced_policy execute in sequential order in the /// calling thread. /// - /// The initializations in the parallel \a uninitialized_default_construct_n algorithm - /// invoked with an execution policy object of type - /// \a parallel_policy or \a parallel_task_policy are - /// permitted to execute in an unordered fashion in unspecified threads, - /// and indeterminately sequenced within each thread. + /// The assignments in the parallel \a uninitialized_default_construct_n + /// algorithm invoked with an execution policy object of type + /// \a parallel_policy or + /// \a parallel_task_policy are permitted to execute in an + /// unordered fashion in unspecified threads, and indeterminately sequenced + /// within each thread. /// /// \returns The \a uninitialized_default_construct_n algorithm returns a - /// \a hpx::future, if the execution policy is of type + /// \a hpx::future if the execution policy is of type /// \a sequenced_task_policy or - /// \a parallel_task_policy and returns FwdIter - /// otherwise. - /// The \a uninitialized_default_construct_n algorithm returns the output - /// iterator to the element in the range, one past - /// the last element copied. + /// \a parallel_task_policy and + /// returns \a FwdIter otherwise. + /// The \a uninitialized_default_construct_n algorithm returns + /// the iterator to the element in the source range, one past + /// the last element constructed. /// - template + template typename parallel::util::detail::algorithm_result::type uninitialized_default_construct_n( - ExPolicy&& policy, FwdIter first, Size count, T const& value); + ExPolicy&& policy, FwdIter first, Size count); } // namespace hpx #else // DOXYGEN @@ -316,43 +311,6 @@ namespace hpx { namespace parallel { inline namespace v1 { /// \endcond } // namespace detail - /// Constructs objects of type typename iterator_traits::value_type - /// in the uninitialized storage designated by the range [first, last) by - /// default-initialization. If an exception is thrown during the - /// initialization, the function has no effects. - /// - /// \note Complexity: Performs exactly \a last - \a first assignments. - /// - /// \tparam ExPolicy The type of the execution policy to use (deduced). - /// It describes the manner in which the execution - /// of the algorithm may be parallelized and the manner - /// in which it executes the assignments. - /// \tparam FwdIter The type of the source iterators used (deduced). - /// This iterator type must meet the requirements of an - /// forward iterator. - /// - /// \param policy The execution policy to use for the scheduling of - /// the iterations. - /// \param first Refers to the beginning of the sequence of elements - /// the algorithm will be applied to. - /// \param last Refers to the end of the sequence of elements the - /// algorithm will be applied to. - /// - /// The assignments in the parallel \a uninitialized_default_construct - /// algorithm invoked with an execution policy object of type \a sequenced_policy - /// execute in sequential order in the calling thread. - /// - /// The assignments in the parallel \a uninitialized_default_construct - /// algorithm invoked with an execution policy object of type \a parallel_policy - /// or \a parallel_task_policy are permitted to execute in an - /// unordered fashion in unspecified threads, and indeterminately sequenced - /// within each thread. - /// - /// \returns The \a uninitialized_default_construct algorithm returns a - /// \a hpx::future, if the execution policy is of type - /// \a sequenced_task_policy or - /// \a parallel_task_policy and returns \a void otherwise. - /// template ::value&& hpx::traits::is_iterator::value)> @@ -447,52 +405,6 @@ namespace hpx { namespace parallel { inline namespace v1 { /// \endcond } // namespace detail - /// Constructs objects of type typename iterator_traits::value_type - /// in the uninitialized storage designated by the range [first, first + count) by - /// default-initialization. If an exception is thrown during the - /// initialization, the function has no effects. - /// - /// \note Complexity: Performs exactly \a count assignments, if - /// count > 0, no assignments otherwise. - /// - /// \tparam ExPolicy The type of the execution policy to use (deduced). - /// It describes the manner in which the execution - /// of the algorithm may be parallelized and the manner - /// in which it executes the assignments. - /// \tparam FwdIter The type of the source iterators used (deduced). - /// This iterator type must meet the requirements of an - /// forward iterator. - /// \tparam Size The type of the argument specifying the number of - /// elements to apply \a f to. - /// - /// \param policy The execution policy to use for the scheduling of - /// the iterations. - /// \param first Refers to the beginning of the sequence of elements - /// the algorithm will be applied to. - /// \param count Refers to the number of elements starting at - /// \a first the algorithm will be applied to. - /// - /// The assignments in the parallel \a uninitialized_default_construct_n - /// algorithm invoked with an execution policy object of type - /// \a sequenced_policy execute in sequential order in the - /// calling thread. - /// - /// The assignments in the parallel \a uninitialized_default_construct_n - /// algorithm invoked with an execution policy object of type - /// \a parallel_policy or - /// \a parallel_task_policy are permitted to execute in an - /// unordered fashion in unspecified threads, and indeterminately sequenced - /// within each thread. - /// - /// \returns The \a uninitialized_default_construct_n algorithm returns a - /// \a hpx::future if the execution policy is of type - /// \a sequenced_task_policy or - /// \a parallel_task_policy and - /// returns \a FwdIter otherwise. - /// The \a uninitialized_default_construct_n algorithm returns the - /// iterator to the element in the source range, one past - /// the last element constructed. - /// template ::value&& hpx::traits::is_iterator::value)> diff --git a/libs/parallelism/algorithms/include/hpx/parallel/container_algorithms/uninitialized_default_construct.hpp b/libs/parallelism/algorithms/include/hpx/parallel/container_algorithms/uninitialized_default_construct.hpp index 14e3a46f41b7..3cec8ee70bf5 100644 --- a/libs/parallelism/algorithms/include/hpx/parallel/container_algorithms/uninitialized_default_construct.hpp +++ b/libs/parallelism/algorithms/include/hpx/parallel/container_algorithms/uninitialized_default_construct.hpp @@ -12,45 +12,46 @@ #if defined(DOXYGEN) namespace hpx { namespace ranges { + // clang-format off - /// Copies the given \a value to an uninitialized memory area, defined by - /// the range [first, last). If an exception is thrown during the + /// Constructs objects of type typename iterator_traits + /// ::value_type in the uninitialized storage designated by the range + /// by default-initialization. If an exception is thrown during the /// initialization, the function has no effects. /// - /// \note Complexity: Linear in the distance between \a first and \a last + /// \note Complexity: Performs exactly \a last - \a first assignments. /// /// \tparam FwdIter The type of the source iterators used (deduced). /// This iterator type must meet the requirements of an /// forward iterator. /// \tparam Sent The type of the source sentinel (deduced). This /// sentinel type must be a sentinel for FwdIter. - /// \tparam T The type of the value to be assigned (deduced). /// /// \param first Refers to the beginning of the sequence of elements /// the algorithm will be applied to. /// \param last Refers to sentinel value denoting the end of the /// sequence of elements the algorithm will be applied. - /// \param value The value to be assigned. /// - /// The assignments in the ranges \a uninitialized_default_construct algorithm invoked - /// without an execution policy object will execute in sequential order in - /// the calling thread. + /// The assignments in the parallel \a uninitialized_default_construct + /// algorithm invoked without an execution policy object will execute in + /// sequential order in the calling thread. /// /// \returns The \a uninitialized_default_construct algorithm returns a /// returns \a FwdIter. - /// The \a uninitialized_default_construct algorithm returns the output - /// iterator to the element in the range, one past - /// the last element copied. + /// The \a uninitialized_default_construct algorithm returns the + /// output iterator to the element in the range, one past + /// the last element constructed. /// - template + template FwdIter uninitialized_default_construct( - FwdIter first, Sent last, T const& value); + FwdIter first, Sent last); - /// Copies the given \a value to an uninitialized memory area, defined by - /// the range [first, last). If an exception is thrown during the + /// Constructs objects of type typename iterator_traits + /// ::value_type in the uninitialized storage designated by the range + /// by default-initialization. If an exception is thrown during the /// initialization, the function has no effects. /// - /// \note Complexity: Linear in the distance between \a first and \a last + /// \note Complexity: Performs exactly \a last - \a first assignments. /// /// \tparam ExPolicy The type of the execution policy to use (deduced). /// It describes the manner in which the execution @@ -61,7 +62,6 @@ namespace hpx { namespace ranges { /// forward iterator. /// \tparam Sent The type of the source sentinel (deduced). This /// sentinel type must be a sentinel for FwdIter. - /// \tparam T The type of the value to be assigned (deduced). /// /// \param policy The execution policy to use for the scheduling of /// the iterations. @@ -69,64 +69,66 @@ namespace hpx { namespace ranges { /// the algorithm will be applied to. /// \param last Refers to sentinel value denoting the end of the /// sequence of elements the algorithm will be applied. - /// \param value The value to be assigned. /// - /// The assignments in the parallel \a uninitialized_default_construct algorithm invoked - /// with an execution policy object of type \a sequenced_policy - /// execute in sequential order in the calling thread. + /// The assignments in the parallel \a uninitialized_default_construct + /// algorithm invoked with an execution policy object of type \a + /// sequenced_policy execute in sequential order in the calling thread. /// - /// The assignments in the parallel \a uninitialized_default_construct algorithm invoked - /// with an execution policy object of type \a parallel_policy or - /// \a parallel_task_policy are permitted to execute in an - /// unordered fashion in unspecified threads, and indeterminately sequenced - /// within each thread. + /// The assignments in the parallel \a uninitialized_default_construct + /// algorithm invoked with an execution policy object of type \a + /// parallel_policy or \a parallel_task_policy are permitted to execute + /// in an unordered fashion in unspecified threads, and indeterminately + /// sequenced within each thread. /// /// \returns The \a uninitialized_default_construct algorithm returns a - /// returns \a FwdIter. - /// The \a uninitialized_default_construct algorithm returns the output - /// iterator to the element in the range, one past - /// the last element copied. + /// \a hpx::future if the execution policy is of type + /// \a sequenced_task_policy or + /// \a parallel_task_policy and + /// returns \a FwdIter otherwise. + /// The \a uninitialized_default_construct algorithm returns + /// the iterator to the element in the source range, one past + /// the last element constructed. /// template typename parallel::util::detail::algorithm_result::type uninitialized_default_construct( - ExPolicy&& policy, FwdIter first, Sent last, T const& value); + ExPolicy&& policy, FwdIter first, Sent last); - /// Copies the given \a value to an uninitialized memory area, defined by - /// the range [first, last). If an exception is thrown during the + /// Constructs objects of type typename iterator_traits + /// ::value_type in the uninitialized storage designated by the range + /// by default-initialization. If an exception is thrown during the /// initialization, the function has no effects. /// - /// \note Complexity: Linear in the distance between \a first and \a last + /// \note Complexity: Performs exactly \a last - \a first assignments. /// /// \tparam Rng The type of the source range used (deduced). /// The iterators extracted from this range type must /// meet the requirements of an input iterator. - /// \tparam T The type of the value to be assigned (deduced). /// - /// \param rng Refers to the range to which the value - /// will be filled - /// \param value The value to be assigned. + /// \param rng Refers to the range to which will be default + /// constructed. /// - /// The assignments in the parallel \a uninitialized_default_construct algorithm invoked - /// without an execution policy object will execute in sequential order in - /// the calling thread. + /// The assignments in the parallel \a uninitialized_default_construct + /// algorithm invoked without an execution policy object will execute in + /// sequential order in the calling thread. /// /// \returns The \a uninitialized_default_construct algorithm returns a /// returns \a hpx::traits::range_traits /// ::iterator_type. - /// The \a uninitialized_default_construct algorithm returns the output - /// iterator to the element in the range, one past - /// the last element copied. + /// The \a uninitialized_default_construct algorithm returns + /// the output iterator to the element in the range, one past + /// the last element constructed. /// - template + template typename hpx::traits::range_traits::iterator_type - uninitialized_default_construct(Rng&& rng, T const& value); + uninitialized_default_construct(Rng&& rng); - /// Copies the given \a value to an uninitialized memory area, defined by - /// the range [first, last). If an exception is thrown during the + /// Constructs objects of type typename iterator_traits + /// ::value_type in the uninitialized storage designated by the range + /// by default-initialization. If an exception is thrown during the /// initialization, the function has no effects. /// - /// \note Complexity: Linear in the distance between \a first and \a last + /// \note Complexity: Performs exactly \a last - \a first assignments. /// /// \tparam ExPolicy The type of the execution policy to use (deduced). /// It describes the manner in which the execution @@ -135,23 +137,21 @@ namespace hpx { namespace ranges { /// \tparam Rng The type of the source range used (deduced). /// The iterators extracted from this range type must /// meet the requirements of an input iterator. - /// \tparam T The type of the value to be assigned (deduced). /// /// \param policy The execution policy to use for the scheduling of /// the iterations. /// \param rng Refers to the range to which the value - /// will be filled - /// \param value The value to be assigned. + /// will be default consutrcted /// - /// The assignments in the parallel \a uninitialized_default_construct algorithm invoked - /// with an execution policy object of type \a sequenced_policy - /// execute in sequential order in the calling thread. + /// The assignments in the parallel \a uninitialized_default_construct + /// algorithm invoked with an execution policy object of type \a + /// sequenced_policy execute in sequential order in the calling thread. /// - /// The assignments in the parallel \a uninitialized_default_construct algorithm invoked - /// with an execution policy object of type \a parallel_policy or - /// \a parallel_task_policy are permitted to execute in an - /// unordered fashion in unspecified threads, and indeterminately sequenced - /// within each thread. + /// The assignments in the parallel \a uninitialized_default_construct + /// algorithm invoked with an execution policy object of type \a + /// parallel_policy or \a parallel_task_policy are permitted to execute + /// in an unordered fashion in unspecified threads, and indeterminately + /// sequenced within each thread. /// /// \returns The \a uninitialized_default_construct algorithm returns a /// \a hpx::future @@ -159,53 +159,51 @@ namespace hpx { namespace ranges { /// execution policy is of type \a sequenced_task_policy /// or \a parallel_task_policy and returns \a typename /// hpx::traits::range_traits::iterator_type otherwise. - /// The \a uninitialized_default_construct algorithm returns the - /// iterator to one past the last element filled in the range. + /// The \a uninitialized_default_construct algorithm returns + /// the output iterator to the element in the range, one past + /// the last element constructed. /// - template + template typename parallel::util::detail::algorithm_result::iterator_type>::type - uninitialized_default_construct( - ExPolicy&& policy, Rng&& rng, T const& value); + typename hpx::traits::range_traits::iterator_type>::type + uninitialized_default_construct(ExPolicy&& policy, Rng&& rng); - /// Copies the given \a value value to the first count elements in an - /// uninitialized memory area beginning at first. If an exception is thrown - /// during the initialization, the function has no effects. + /// Constructs objects of type typename iterator_traits + /// ::value_type in the uninitialized storage designated by the range + /// [first, first + count) by default-initialization. If an exception + /// is thrown during the initialization, the function has no effects. /// /// \note Complexity: Performs exactly \a count assignments, if /// count > 0, no assignments otherwise. /// /// \tparam FwdIter The type of the source iterators used (deduced). - /// This iterator type must meet the requirements of a + /// This iterator type must meet the requirements of an /// forward iterator. /// \tparam Size The type of the argument specifying the number of /// elements to apply \a f to. - /// \tparam T The type of the value to be assigned (deduced). /// /// \param first Refers to the beginning of the sequence of elements /// the algorithm will be applied to. /// \param count Refers to the number of elements starting at /// \a first the algorithm will be applied to. - /// \param value The value to be assigned. /// - /// The assignments in the parallel \a uninitialized_default_construct_n algorithm - /// invoked with an execution policy object of type - /// \a sequenced_policy execute in sequential order in the - /// calling thread. + /// The assignments in the parallel \a uninitialized_default_construct_n + /// algorithm invoked without an execution policy object execute in + /// sequential order in the calling thread. /// /// \returns The \a uninitialized_default_construct_n algorithm returns a /// returns \a FwdIter. - /// The \a uninitialized_default_construct_n algorithm returns the output - /// iterator to the element in the range, one past - /// the last element copied. + /// The \a uninitialized_default_construct_n algorithm returns + /// the iterator to the element in the source range, one past + /// the last element constructed. /// - template - FwdIter uninitialized_default_construct_n( - FwdIter first, Size count, T const& value); + template + FwdIter uninitialized_default_construct_n(FwdIter first, Size count); - /// Copies the given \a value value to the first count elements in an - /// uninitialized memory area beginning at first. If an exception is thrown - /// during the initialization, the function has no effects. + /// Constructs objects of type typename iterator_traits + /// ::value_type in the uninitialized storage designated by the range + /// [first, first + count) by default-initialization. If an exception + /// is thrown during the initialization, the function has no effects. /// /// \note Complexity: Performs exactly \a count assignments, if /// count > 0, no assignments otherwise. @@ -215,11 +213,10 @@ namespace hpx { namespace ranges { /// of the algorithm may be parallelized and the manner /// in which it executes the assignments. /// \tparam FwdIter The type of the source iterators used (deduced). - /// This iterator type must meet the requirements of a + /// This iterator type must meet the requirements of an /// forward iterator. /// \tparam Size The type of the argument specifying the number of /// elements to apply \a f to. - /// \tparam T The type of the value to be assigned (deduced). /// /// \param policy The execution policy to use for the scheduling of /// the iterations. @@ -227,34 +224,35 @@ namespace hpx { namespace ranges { /// the algorithm will be applied to. /// \param count Refers to the number of elements starting at /// \a first the algorithm will be applied to. - /// \param value The value to be assigned. /// - /// The assignments in the parallel \a uninitialized_default_construct_n algorithm - /// invoked with an execution policy object of type + /// The assignments in the parallel \a uninitialized_default_construct_n + /// algorithm invoked with an execution policy object of type /// \a sequenced_policy execute in sequential order in the /// calling thread. /// - /// The assignments in the parallel \a uninitialized_default_construct_n algorithm - /// invoked with an execution policy object of type + /// The assignments in the parallel \a uninitialized_default_construct_n + /// algorithm invoked with an execution policy object of type /// \a parallel_policy or /// \a parallel_task_policy are permitted to execute in an /// unordered fashion in unspecified threads, and indeterminately sequenced /// within each thread. /// /// \returns The \a uninitialized_default_construct_n algorithm returns a - /// \a hpx::future, if the execution policy is of type + /// \a hpx::future if the execution policy is of type /// \a sequenced_task_policy or - /// \a parallel_task_policy and returns FwdIter - /// otherwise. - /// The \a uninitialized_default_construct_n algorithm returns the output - /// iterator to the element in the range, one past - /// the last element copied. + /// \a parallel_task_policy and + /// returns \a FwdIter otherwise. + /// The \a uninitialized_default_construct_n algorithm returns + /// the iterator to the element in the source range, one past + /// the last element constructed. /// - template + template typename typename parallel::util::detail::algorithm_result::type uninitialized_default_construct_n( - ExPolicy&& policy, FwdIter first, Size count, T const& value); + ExPolicy&& policy, FwdIter first, Size count); + + // clang-format on }} // namespace hpx::ranges #else diff --git a/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_construct_range.cpp b/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_construct_range.cpp index 07652c2b7c82..d00defb5812f 100644 --- a/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_construct_range.cpp +++ b/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_construct_range.cpp @@ -45,7 +45,7 @@ struct value_constructable std::int32_t value_; }; -std::size_t const data_size = 10; +std::size_t const data_size = 10007; //////////////////////////////////////////////////////////////////////////// template From d6248e7912d34d890354e43fb5a99c9675f6227e Mon Sep 17 00:00:00 2001 From: targetakhil Date: Mon, 28 Jun 2021 10:04:49 +0530 Subject: [PATCH 5/5] fixed clang and inspect errors --- .../uninitialized_default_constructn.cpp | 14 ++++++-------- .../uninitialized_default_construct_range.cpp | 8 +++++--- .../uninitialized_default_constructn_range.cpp | 3 ++- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/libs/parallelism/algorithms/tests/unit/algorithms/uninitialized_default_constructn.cpp b/libs/parallelism/algorithms/tests/unit/algorithms/uninitialized_default_constructn.cpp index 1bb0c059e5e9..8238b5ceb069 100644 --- a/libs/parallelism/algorithms/tests/unit/algorithms/uninitialized_default_constructn.cpp +++ b/libs/parallelism/algorithms/tests/unit/algorithms/uninitialized_default_constructn.cpp @@ -50,8 +50,7 @@ void test_uninitialized_default_construct_n(ExPolicy policy, IteratorTag) std::memset( static_cast(p), 0xcd, data_size * sizeof(default_constructable)); - hpx::uninitialized_default_construct_n( - policy, iterator(p), data_size); + hpx::uninitialized_default_construct_n(policy, iterator(p), data_size); std::size_t count = 0; std::for_each(p, p + data_size, [&count](default_constructable v1) { @@ -74,8 +73,8 @@ void test_uninitialized_default_construct_n_async(ExPolicy policy, IteratorTag) std::memset( static_cast(p), 0xcd, data_size * sizeof(default_constructable)); - auto f = hpx::uninitialized_default_construct_n( - policy, iterator(p), data_size); + auto f = + hpx::uninitialized_default_construct_n(policy, iterator(p), data_size); f.wait(); std::size_t count = 0; @@ -102,8 +101,7 @@ void test_uninitialized_default_construct_n2(ExPolicy policy, IteratorTag) std::memset( static_cast(p), 0xcd, data_size * sizeof(value_constructable)); - hpx::uninitialized_default_construct_n( - policy, iterator(p), data_size); + hpx::uninitialized_default_construct_n(policy, iterator(p), data_size); std::size_t count = 0; std::for_each(p, p + data_size, [&count](value_constructable v1) { @@ -126,8 +124,8 @@ void test_uninitialized_default_construct_n_async2(ExPolicy policy, IteratorTag) std::memset( static_cast(p), 0xcd, data_size * sizeof(value_constructable)); - auto f = hpx::uninitialized_default_construct_n( - policy, iterator(p), data_size); + auto f = + hpx::uninitialized_default_construct_n(policy, iterator(p), data_size); f.wait(); std::size_t count = 0; diff --git a/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_construct_range.cpp b/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_construct_range.cpp index d00defb5812f..eeae277a9ace 100644 --- a/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_construct_range.cpp +++ b/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_construct_range.cpp @@ -11,10 +11,12 @@ #include #include +#include #include #include #include #include +#include #include #include "test_utils.hpp" @@ -27,14 +29,14 @@ struct default_constructable { } - default_constructable(std::int32_t val) + explicit default_constructable(std::int32_t val) { value_ = val; } - bool operator!=(default_constructable const& lhs) const + bool operator!=(std::int32_t const& lhs) const { - return lhs.value_ != value_; + return lhs != value_; } std::int32_t value_; diff --git a/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_constructn_range.cpp b/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_constructn_range.cpp index cfefe0aa7697..02d60512d3c6 100644 --- a/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_constructn_range.cpp +++ b/libs/parallelism/algorithms/tests/unit/container_algorithms/uninitialized_default_constructn_range.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -27,7 +28,7 @@ struct default_constructable { } - default_constructable(std::int32_t val) + explicit default_constructable(std::int32_t val) { value_ = val; }