forked from llvm/llvm-project
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reviewed By: #libc, ldionne Spies: ldionne, libcxx-commits Differential Revision: https://reviews.llvm.org/D155330
- Loading branch information
1 parent
3d40411
commit d2a46e6
Showing
8 changed files
with
234 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef _LIBCPP___ALGORITHM_PSTL_MOVE_H | ||
#define _LIBCPP___ALGORITHM_PSTL_MOVE_H | ||
|
||
#include <__algorithm/copy_n.h> | ||
#include <__algorithm/pstl_frontend_dispatch.h> | ||
#include <__algorithm/pstl_transform.h> | ||
#include <__config> | ||
#include <__functional/identity.h> | ||
#include <__iterator/iterator_traits.h> | ||
#include <__type_traits/enable_if.h> | ||
#include <__type_traits/is_constant_evaluated.h> | ||
#include <__type_traits/is_execution_policy.h> | ||
#include <__type_traits/is_trivially_copyable.h> | ||
#include <__type_traits/remove_cvref.h> | ||
#include <optional> | ||
|
||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | ||
# pragma GCC system_header | ||
#endif | ||
|
||
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | ||
|
||
_LIBCPP_BEGIN_NAMESPACE_STD | ||
|
||
// TODO: Use the std::copy/move shenanigans to forward to std::memmove | ||
// Investigate whether we want to still forward to std::transform(policy) | ||
// in that case for the execution::par part, or whether we actually want | ||
// to run everything serially in that case. | ||
|
||
template <class> | ||
void __pstl_move(); | ||
|
||
template <class _ExecutionPolicy, | ||
class _ForwardIterator, | ||
class _ForwardOutIterator, | ||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | ||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | ||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<_ForwardOutIterator> | ||
__move(_ExecutionPolicy&& __policy, | ||
_ForwardIterator&& __first, | ||
_ForwardIterator&& __last, | ||
_ForwardOutIterator&& __result) noexcept { | ||
return std::__pstl_frontend_dispatch( | ||
_LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_move, _RawPolicy), | ||
[&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _ForwardOutIterator __g_result) { | ||
return std::__transform(__policy, __g_first, __g_last, __g_result, [](auto&& __v) { return std::move(__v); }); | ||
}, | ||
std::move(__first), | ||
std::move(__last), | ||
std::move(__result)); | ||
} | ||
|
||
template <class _ExecutionPolicy, | ||
class _ForwardIterator, | ||
class _ForwardOutIterator, | ||
class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | ||
enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | ||
_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator | ||
move(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __result) { | ||
auto __res = std::__move(__policy, std::move(__first), std::move(__last), std::move(__result)); | ||
if (!__res) | ||
std::__throw_bad_alloc(); | ||
return *__res; | ||
} | ||
|
||
_LIBCPP_END_NAMESPACE_STD | ||
|
||
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | ||
|
||
#endif // _LIBCPP___ALGORITHM_PSTL_MOVE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
...xx/test/std/algorithms/alg.modifying.operations/alg.move/pstl.exception_handling.pass.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
// UNSUPPORTED: c++03, c++11, c++14 | ||
// UNSUPPORTED: no-exceptions | ||
// REQUIRES: has-unix-headers | ||
|
||
// UNSUPPORTED: libcpp-has-no-incomplete-pstl | ||
|
||
// check that std::move(ExecutionPolicy) terminates on user-thrown exceptions | ||
|
||
#include <algorithm> | ||
|
||
#include "check_assertion.h" | ||
#include "test_execution_policies.h" | ||
#include "test_iterators.h" | ||
|
||
int main(int, char**) { | ||
test_execution_policies([](auto&& policy) { | ||
EXPECT_STD_TERMINATE([&] { | ||
try { | ||
int a[] = {1, 2}; | ||
int b[] = {1, 2}; | ||
(void)std::move(policy, | ||
util::throw_on_move_iterator(std::begin(a), 1), | ||
util::throw_on_move_iterator(std::end(a), 1), | ||
util::throw_on_move_iterator(std::begin(b), 1)); | ||
} catch (const util::iterator_error&) { | ||
assert(false); | ||
} | ||
std::terminate(); // make the test pass in case the algorithm didn't move the iterator | ||
}); | ||
}); | ||
} |
99 changes: 99 additions & 0 deletions
99
libcxx/test/std/algorithms/alg.modifying.operations/alg.move/pstl.move.pass.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
// UNSUPPORTED: c++03, c++11, c++14 | ||
|
||
// UNSUPPORTED: libcpp-has-no-incomplete-pstl | ||
|
||
// <algorithm> | ||
|
||
// template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> | ||
// ForwardIterator2 move(ExecutionPolicy&& policy, | ||
// ForwardIterator1 first, ForwardIterator1 last, | ||
// ForwardIterator2 result); | ||
|
||
#include <algorithm> | ||
#include <vector> | ||
|
||
#include "test_macros.h" | ||
#include "test_execution_policies.h" | ||
#include "test_iterators.h" | ||
|
||
EXECUTION_POLICY_SFINAE_TEST(move); | ||
|
||
static_assert(sfinae_test_move<int, int*, int*, int*>); | ||
static_assert(!sfinae_test_move<std::execution::parallel_policy, int*, int*, int*>); | ||
|
||
template <class Iter1, class Iter2> | ||
struct TestInt { | ||
template <class Policy> | ||
void operator()(Policy&& policy) { | ||
// simple test | ||
for (const int size : {0, 1, 2, 100, 350}) { | ||
std::vector<int> a(size); | ||
for (int i = 0; i != size; ++i) | ||
a[i] = i + 1; | ||
|
||
std::vector<int> out(std::size(a)); | ||
decltype(auto) ret = | ||
std::move(policy, Iter1(std::data(a)), Iter1(std::data(a) + std::size(a)), Iter2(std::data(out))); | ||
static_assert(std::is_same_v<decltype(ret), Iter2>); | ||
assert(base(ret) == std::data(out) + std::size(out)); | ||
for (int i = 0; i != size; ++i) | ||
assert(out[i] == i + 1); | ||
} | ||
} | ||
}; | ||
|
||
struct MovedToTester { | ||
bool moved_to = false; | ||
MovedToTester() = default; | ||
MovedToTester(MovedToTester&&) {} | ||
MovedToTester& operator=(MovedToTester&&) { | ||
assert(!moved_to); | ||
moved_to = true; | ||
return *this; | ||
} | ||
~MovedToTester() = default; | ||
}; | ||
|
||
template <class Iter1, class Iter2> | ||
struct TestNonTrivial { | ||
template <class Policy> | ||
void operator()(Policy&& policy) { | ||
// simple test | ||
for (const int size : {0, 1, 2, 100, 350}) { | ||
std::vector<MovedToTester> a(size); | ||
|
||
std::vector<MovedToTester> out(std::size(a)); | ||
auto ret = std::move(policy, Iter1(std::data(a)), Iter1(std::data(a) + std::size(a)), Iter2(std::data(out))); | ||
assert(base(ret) == std::data(out) + std::size(out)); | ||
assert(std::all_of(std::begin(out), std::end(out), [](MovedToTester& t) { return t.moved_to; })); | ||
assert(std::none_of(std::begin(a), std::end(a), [](MovedToTester& t) { return t.moved_to; })); | ||
} | ||
} | ||
}; | ||
|
||
int main(int, char**) { | ||
types::for_each(types::forward_iterator_list<int*>{}, types::apply_type_identity{[](auto v) { | ||
using Iter = typename decltype(v)::type; | ||
types::for_each( | ||
types::forward_iterator_list<int*>{}, | ||
TestIteratorWithPolicies< types::partial_instantiation<TestInt, Iter>::template apply>{}); | ||
}}); | ||
|
||
types::for_each( | ||
types::forward_iterator_list<MovedToTester*>{}, types::apply_type_identity{[](auto v) { | ||
using Iter = typename decltype(v)::type; | ||
types::for_each( | ||
types::forward_iterator_list<MovedToTester*>{}, | ||
TestIteratorWithPolicies< types::partial_instantiation<TestNonTrivial, Iter>::template apply>{}); | ||
}}); | ||
|
||
return 0; | ||
} |