diff options
| author | Brian Gesiak <modocache@gmail.com> | 2019-03-26 19:50:46 +0000 |
|---|---|---|
| committer | Brian Gesiak <modocache@gmail.com> | 2019-03-26 19:50:46 +0000 |
| commit | b66754a29ed7a479e36fed89e0b45d10d5e71e71 (patch) | |
| tree | 759fd580d95d431848d0c5f8176c77b7c5e6705d /libcxx/test | |
| parent | 492f752969ff3a37138372e8e973317dc63ef2d3 (diff) | |
| download | bcm5719-llvm-b66754a29ed7a479e36fed89e0b45d10d5e71e71.tar.gz bcm5719-llvm-b66754a29ed7a479e36fed89e0b45d10d5e71e71.zip | |
Revert "[coroutines] Add std::experimental::task<T> type"
This revision is causing build and test failures, such as
http://lab.llvm.org:8011/builders/libcxx-libcxxabi-libunwind-armv8-linux/builds/648/steps/test.libcxx/logs/stdio,
so I'll revert it.
llvm-svn: 357023
Diffstat (limited to 'libcxx/test')
10 files changed, 0 insertions, 1172 deletions
diff --git a/libcxx/test/std/experimental/task/awaitable_traits.hpp b/libcxx/test/std/experimental/task/awaitable_traits.hpp deleted file mode 100644 index 3d4ba16979a..00000000000 --- a/libcxx/test/std/experimental/task/awaitable_traits.hpp +++ /dev/null @@ -1,117 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP_TEST_EXPERIMENTAL_TASK_AWAITABLE_TRAITS -#define _LIBCPP_TEST_EXPERIMENTAL_TASK_AWAITABLE_TRAITS - -#include <type_traits> -#include <experimental/coroutine> - -_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_COROUTINES - -template<typename _Tp> -struct __is_coroutine_handle : std::false_type {}; - -template<typename _Tp> -struct __is_coroutine_handle<std::experimental::coroutine_handle<_Tp>> : - std::true_type -{}; - -template<typename _Tp> -struct __is_valid_await_suspend_result : - std::disjunction< - std::is_void<_Tp>, - std::is_same<_Tp, bool>, - __is_coroutine_handle<_Tp>> -{}; - -template<typename _Tp, typename = void> -struct is_awaiter : std::false_type {}; - -template<typename _Tp> -struct is_awaiter<_Tp, std::void_t< - decltype(std::declval<_Tp&>().await_ready()), - decltype(std::declval<_Tp&>().await_resume()), - decltype(std::declval<_Tp&>().await_suspend( - std::declval<std::experimental::coroutine_handle<void>>()))>> : - std::conjunction< - std::is_same<decltype(std::declval<_Tp&>().await_ready()), bool>, - __is_valid_await_suspend_result<decltype( - std::declval<_Tp&>().await_suspend( - std::declval<std::experimental::coroutine_handle<void>>()))>> -{}; - -template<typename _Tp> -constexpr bool is_awaiter_v = is_awaiter<_Tp>::value; - -template<typename _Tp, typename = void> -struct __has_member_operator_co_await : std::false_type {}; - -template<typename _Tp> -struct __has_member_operator_co_await<_Tp, std::void_t<decltype(std::declval<_Tp>().operator co_await())>> -: is_awaiter<decltype(std::declval<_Tp>().operator co_await())> -{}; - -template<typename _Tp, typename = void> -struct __has_non_member_operator_co_await : std::false_type {}; - -template<typename _Tp> -struct __has_non_member_operator_co_await<_Tp, std::void_t<decltype(operator co_await(std::declval<_Tp>()))>> -: is_awaiter<decltype(operator co_await(std::declval<_Tp>()))> -{}; - -template<typename _Tp> -struct is_awaitable : std::disjunction< - is_awaiter<_Tp>, - __has_member_operator_co_await<_Tp>, - __has_non_member_operator_co_await<_Tp>> -{}; - -template<typename _Tp> -constexpr bool is_awaitable_v = is_awaitable<_Tp>::value; - -template< - typename _Tp, - std::enable_if_t<is_awaitable_v<_Tp>, int> = 0> -decltype(auto) get_awaiter(_Tp&& __awaitable) -{ - if constexpr (__has_member_operator_co_await<_Tp>::value) - { - return static_cast<_Tp&&>(__awaitable).operator co_await(); - } - else if constexpr (__has_non_member_operator_co_await<_Tp>::value) - { - return operator co_await(static_cast<_Tp&&>(__awaitable)); - } - else - { - return static_cast<_Tp&&>(__awaitable); - } -} - -template<typename _Tp, typename = void> -struct await_result -{}; - -template<typename _Tp> -struct await_result<_Tp, std::enable_if_t<is_awaitable_v<_Tp>>> -{ -private: - using __awaiter = decltype(get_awaiter(std::declval<_Tp>())); -public: - using type = decltype(std::declval<__awaiter&>().await_resume()); -}; - -template<typename _Tp> -using await_result_t = typename await_result<_Tp>::type; - -_LIBCPP_END_NAMESPACE_EXPERIMENTAL_COROUTINES - -#endif diff --git a/libcxx/test/std/experimental/task/counted.hpp b/libcxx/test/std/experimental/task/counted.hpp deleted file mode 100644 index 50658d223cf..00000000000 --- a/libcxx/test/std/experimental/task/counted.hpp +++ /dev/null @@ -1,96 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP_TEST_EXPERIMENTAL_TASK_COUNTED -#define _LIBCPP_TEST_EXPERIMENTAL_TASK_COUNTED - -class counted -{ -public: - - counted() : id_(nextId_++) - { - ++defaultConstructedCount_; - } - - counted(const counted& other) : id_(other.id_) - { - ++copyConstructedCount_; - } - - counted(counted&& other) : id_(std::exchange(other.id_, 0)) - { - ++moveConstructedCount_; - } - - ~counted() - { - ++destructedCount_; - } - - static void reset() - { - nextId_ = 1; - defaultConstructedCount_ = 0; - copyConstructedCount_ = 0; - moveConstructedCount_ = 0; - destructedCount_ = 0; - } - - static std::size_t active_instance_count() - { - return - defaultConstructedCount_ + - copyConstructedCount_ + - moveConstructedCount_ - - destructedCount_; - } - - static std::size_t copy_constructor_count() - { - return copyConstructedCount_; - } - - static std::size_t move_constructor_count() - { - return moveConstructedCount_; - } - - static std::size_t default_constructor_count() - { - return defaultConstructedCount_; - } - - static std::size_t destructor_count() - { - return destructedCount_; - } - - std::size_t id() const { return id_; } - -private: - std::size_t id_; - - static std::size_t nextId_; - static std::size_t defaultConstructedCount_; - static std::size_t copyConstructedCount_; - static std::size_t moveConstructedCount_; - static std::size_t destructedCount_; - -}; - -#define DEFINE_COUNTED_VARIABLES() \ - std::size_t counted::nextId_; \ - std::size_t counted::defaultConstructedCount_; \ - std::size_t counted::copyConstructedCount_; \ - std::size_t counted::moveConstructedCount_; \ - std::size_t counted::destructedCount_ - -#endif diff --git a/libcxx/test/std/experimental/task/lit.local.cfg b/libcxx/test/std/experimental/task/lit.local.cfg deleted file mode 100644 index a0b3de8afaa..00000000000 --- a/libcxx/test/std/experimental/task/lit.local.cfg +++ /dev/null @@ -1,9 +0,0 @@ -# If the compiler doesn't support coroutines mark all of the tests under -# this directory as unsupported. Otherwise add the required `-fcoroutines-ts` -# flag. -if 'fcoroutines-ts' not in config.available_features: - config.unsupported = True -else: - import copy - config.test_format.cxx = copy.deepcopy(config.test_format.cxx) - config.test_format.cxx.compile_flags += ['-fcoroutines-ts'] diff --git a/libcxx/test/std/experimental/task/manual_reset_event.hpp b/libcxx/test/std/experimental/task/manual_reset_event.hpp deleted file mode 100644 index cfd53227495..00000000000 --- a/libcxx/test/std/experimental/task/manual_reset_event.hpp +++ /dev/null @@ -1,127 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP_TEST_EXPERIMENTAL_TASK_MANUAL_RESET_EVENT -#define _LIBCPP_TEST_EXPERIMENTAL_TASK_MANUAL_RESET_EVENT - -#include <experimental/coroutine> -#include <atomic> - -// manual_reset_event is a coroutine synchronisation tool that allows one -// coroutine to await the event object and if the event was not crrently -// in the 'set' state then will suspend the awaiting coroutine until some -// thread calls .set() on the event. -class manual_reset_event -{ - friend class _Awaiter; - - class _Awaiter - { - public: - - _Awaiter(const manual_reset_event* __event) noexcept - : __event_(__event) - {} - - bool await_ready() const noexcept - { - return __event_->is_set(); - } - - bool await_suspend(std::experimental::coroutine_handle<> __coro) noexcept - { - _LIBCPP_ASSERT( - __event_->__state_.load(std::memory_order_relaxed) != - __State::__not_set_waiting_coroutine, - "This manual_reset_event already has another coroutine awaiting it. " - "Only one awaiting coroutine is supported." - ); - - __event_->__awaitingCoroutine_ = __coro; - - // If the compare-exchange fails then this means that the event was - // already 'set' and so we should not suspend - this code path requires - // 'acquire' semantics so we have visibility of writes prior to the - // .set() operation that transitioned the event to the 'set' state. - // If the compare-exchange succeeds then this needs 'release' semantics - // so that a subsequent call to .set() has visibility of our writes - // to the coroutine frame and to __event_->__awaitingCoroutine_ after - // reading our write to __event_->__state_. - _State oldState = _State::__not_set; - return __event_->__state_.compare_exchange_strong( - oldState, - _State::__not_set_waiting_coroutine, - std::memory_order_release, - std::memory_order_acquire); - } - - void await_resume() const noexcept {} - - private: - const manual_reset_event* __event_; - }; - -public: - - manual_reset_event(bool __initiallySet = false) noexcept - : __state_(__initiallySet ? _State::__set : _State::__not_set) - {} - - bool is_set() const noexcept - { - return __state_.load(std::memory_order_acquire) == _State::__set; - } - - void set() noexcept - { - // Needs to be 'acquire' in case the old value was a waiting coroutine - // so that we have visibility of the writes to the coroutine frame in - // the current thrad before we resume it. - // Also needs to be 'release' in case the old value was 'not-set' so that - // another thread that subsequently awaits the - _State oldState = __state_.exchange(_State::__set, std::memory_order_acq_rel); - if (oldState == _State::__not_set_waiting_coroutine) - { - _VSTD::exchange(__awaitingCoroutine_, {}).resume(); - } - } - - void reset() noexcept - { - _LIBCPP_ASSERT( - __state_.load(std::memory_order_relaxed) != _State::__not_set_waiting_coroutine, - "Illegal to call reset() if a coroutine is currently awaiting the event."); - - // Note, we use 'relaxed' memory order here since it considered a - // data-race to call reset() concurrently either with operator co_await() - // or with set(). - __state_.store(_State::__not_set, std::memory_order_relaxed); - } - - auto operator co_await() const noexcept - { - return _Awaiter{ this }; - } - -private: - - enum class _State { - __not_set, - __not_set_waiting_coroutine, - __set - }; - - // TODO: Can we combine these two members into a single std::atomic<void*>? - mutable std::atomic<_State> __state_; - mutable std::experimental::coroutine_handle<> __awaitingCoroutine_; - -}; - -#endif diff --git a/libcxx/test/std/experimental/task/sync_wait.hpp b/libcxx/test/std/experimental/task/sync_wait.hpp deleted file mode 100644 index 42c629eb415..00000000000 --- a/libcxx/test/std/experimental/task/sync_wait.hpp +++ /dev/null @@ -1,284 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP_TEST_EXPERIMENTAL_TASK_SYNC_WAIT -#define _LIBCPP_TEST_EXPERIMENTAL_TASK_SYNC_WAIT - -#include <experimental/__config> -#include <experimental/coroutine> -#include <type_traits> -#include <mutex> -#include <condition_variable> - -#include "awaitable_traits.hpp" - -_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_COROUTINES - -// Thread-synchronisation helper that allows one thread to block in a call -// to .wait() until another thread signals the thread by calling .set(). -class __oneshot_event -{ -public: - __oneshot_event() : __isSet_(false) {} - - void set() noexcept - { - unique_lock<mutex> __lock{ __mutex_ }; - __isSet_ = true; - __cv_.notify_all(); - } - - void wait() noexcept - { - unique_lock<mutex> __lock{ __mutex_ }; - __cv_.wait(__lock, [this] { return __isSet_; }); - } - -private: - mutex __mutex_; - condition_variable __cv_; - bool __isSet_; -}; - -template<typename _Derived> -class __sync_wait_promise_base -{ -public: - - using __handle_t = coroutine_handle<_Derived>; - -private: - - struct _FinalAwaiter - { - bool await_ready() noexcept { return false; } - void await_suspend(__handle_t __coro) noexcept - { - __sync_wait_promise_base& __promise = __coro.promise(); - __promise.__event_.set(); - } - void await_resume() noexcept {} - }; - - friend struct _FinalAwaiter; - -public: - - __handle_t get_return_object() { return __handle(); } - suspend_always initial_suspend() { return {}; } - _FinalAwaiter final_suspend() { return {}; } - -private: - - __handle_t __handle() noexcept - { - return __handle_t::from_promise(static_cast<_Derived&>(*this)); - } - -protected: - - // Start the coroutine and then block waiting for it to finish. - void run() noexcept - { - __handle().resume(); - __event_.wait(); - } - -private: - - __oneshot_event __event_; - -}; - -template<typename _Tp> -class __sync_wait_promise final - : public __sync_wait_promise_base<__sync_wait_promise<_Tp>> -{ -public: - - __sync_wait_promise() : __state_(_State::__empty) {} - - ~__sync_wait_promise() - { - switch (__state_) - { - case _State::__empty: - case _State::__value: - break; -#ifndef _LIBCPP_NO_EXCEPTIONS - case _State::__exception: - __exception_.~exception_ptr(); - break; -#endif - } - } - - void return_void() noexcept - { - // Should be unreachable since coroutine should always - // suspend at `co_yield` point where it will be destroyed - // or will fail with an exception and bypass return_void() - // and call unhandled_exception() instead. - std::abort(); - } - - void unhandled_exception() noexcept - { -#ifndef _LIBCPP_NO_EXCEPTIONS - ::new (static_cast<void*>(&__exception_)) exception_ptr( - std::current_exception()); - __state_ = _State::__exception; -#else - _VSTD::abort(); -#endif - } - - auto yield_value(_Tp&& __value) noexcept - { - __valuePtr_ = std::addressof(__value); - __state_ = _State::__value; - return this->final_suspend(); - } - - _Tp&& get() - { - this->run(); - -#ifndef _LIBCPP_NO_EXCEPTIONS - if (__state_ == _State::__exception) - { - std::rethrow_exception(_VSTD::move(__exception_)); - } -#endif - - return static_cast<_Tp&&>(*__valuePtr_); - } - -private: - - enum class _State { - __empty, - __value, - __exception - }; - - _State __state_; - union { - std::add_pointer_t<_Tp> __valuePtr_; - std::exception_ptr __exception_; - }; - -}; - -template<> -struct __sync_wait_promise<void> final - : public __sync_wait_promise_base<__sync_wait_promise<void>> -{ -public: - - void unhandled_exception() noexcept - { -#ifndef _LIBCPP_NO_EXCEPTIONS - __exception_ = std::current_exception(); -#endif - } - - void return_void() noexcept {} - - void get() - { - this->run(); - -#ifndef _LIBCPP_NO_EXCEPTIONS - if (__exception_) - { - std::rethrow_exception(_VSTD::move(__exception_)); - } -#endif - } - -private: - - std::exception_ptr __exception_; - -}; - -template<typename _Tp> -class __sync_wait_task final -{ -public: - using promise_type = __sync_wait_promise<_Tp>; - -private: - using __handle_t = typename promise_type::__handle_t; - -public: - - __sync_wait_task(__handle_t __coro) noexcept : __coro_(__coro) {} - - ~__sync_wait_task() - { - _LIBCPP_ASSERT(__coro_, "Should always have a valid coroutine handle"); - __coro_.destroy(); - } - - decltype(auto) get() - { - return __coro_.promise().get(); - } -private: - __handle_t __coro_; -}; - -template<typename _Tp> -struct __remove_rvalue_reference -{ - using type = _Tp; -}; - -template<typename _Tp> -struct __remove_rvalue_reference<_Tp&&> -{ - using type = _Tp; -}; - -template<typename _Tp> -using __remove_rvalue_reference_t = - typename __remove_rvalue_reference<_Tp>::type; - -template< - typename _Awaitable, - typename _AwaitResult = await_result_t<_Awaitable>, - std::enable_if_t<std::is_void_v<_AwaitResult>, int> = 0> -__sync_wait_task<_AwaitResult> __make_sync_wait_task(_Awaitable&& __awaitable) -{ - co_await static_cast<_Awaitable&&>(__awaitable); -} - -template< - typename _Awaitable, - typename _AwaitResult = await_result_t<_Awaitable>, - std::enable_if_t<!std::is_void_v<_AwaitResult>, int> = 0> -__sync_wait_task<_AwaitResult> __make_sync_wait_task(_Awaitable&& __awaitable) -{ - co_yield co_await static_cast<_Awaitable&&>(__awaitable); -} - -template<typename _Awaitable> -auto sync_wait(_Awaitable&& __awaitable) - -> __remove_rvalue_reference_t<await_result_t<_Awaitable>> -{ - return _VSTD_CORO::__make_sync_wait_task( - static_cast<_Awaitable&&>(__awaitable)).get(); -} - -_LIBCPP_END_NAMESPACE_EXPERIMENTAL_COROUTINES - -#endif diff --git a/libcxx/test/std/experimental/task/task.basic/task_custom_allocator.pass.cpp b/libcxx/test/std/experimental/task/task.basic/task_custom_allocator.pass.cpp deleted file mode 100644 index bc7e5989861..00000000000 --- a/libcxx/test/std/experimental/task/task.basic/task_custom_allocator.pass.cpp +++ /dev/null @@ -1,230 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03, c++11, c++14 - -#include <experimental/task> -#include <cstdlib> -#include <cassert> -#include <vector> -#include <memory> -#include <experimental/memory_resource> - -#include "../sync_wait.hpp" - -namespace coro = std::experimental::coroutines_v1; - -namespace -{ - static size_t allocator_instance_count = 0; - - // A custom allocator that tracks the number of allocator instances that - // have been constructed/destructed as well as the number of bytes that - // have been allocated/deallocated using the allocator. - template<typename T> - class my_allocator { - public: - using value_type = T; - using size_type = std::size_t; - using difference_type = std::ptrdiff_t; - using is_always_equal = std::false_type; - - explicit my_allocator( - std::shared_ptr<size_type> totalAllocated) noexcept - : totalAllocated_(std::move(totalAllocated)) - { - ++allocator_instance_count; - assert(totalAllocated_); - } - - my_allocator(const my_allocator& other) - : totalAllocated_(other.totalAllocated_) - { - ++allocator_instance_count; - } - - my_allocator(my_allocator&& other) - : totalAllocated_(std::move(other.totalAllocated_)) - { - ++allocator_instance_count; - } - - template<typename U> - my_allocator(const my_allocator<U>& other) - : totalAllocated_(other.totalAllocated_) - { - ++allocator_instance_count; - } - - template<typename U> - my_allocator(my_allocator<U>&& other) - : totalAllocated_(std::move(other.totalAllocated_)) - { - ++allocator_instance_count; - } - - ~my_allocator() - { - --allocator_instance_count; - } - - char* allocate(size_t n) { - const auto byteCount = n * sizeof(T); - void* p = std::malloc(byteCount); - if (!p) { - throw std::bad_alloc{}; - } - *totalAllocated_ += byteCount; - return static_cast<char*>(p); - } - - void deallocate(char* p, size_t n) { - const auto byteCount = n * sizeof(T); - *totalAllocated_ -= byteCount; - std::free(p); - } - private: - template<typename U> - friend class my_allocator; - - std::shared_ptr<size_type> totalAllocated_; - }; -} - -template<typename Allocator> -coro::task<void> f(std::allocator_arg_t, [[maybe_unused]] Allocator alloc) -{ - co_return; -} - -void test_custom_allocator_is_destructed() -{ - auto totalAllocated = std::make_shared<size_t>(0); - - assert(allocator_instance_count == 0); - - { - std::vector<coro::task<>> tasks; - tasks.push_back( - f(std::allocator_arg, my_allocator<char>{ totalAllocated })); - tasks.push_back( - f(std::allocator_arg, my_allocator<char>{ totalAllocated })); - - assert(allocator_instance_count == 4); - assert(*totalAllocated > 0); - } - - assert(allocator_instance_count == 0); - assert(*totalAllocated == 0); -} - -void test_custom_allocator_type_rebinding() -{ - auto totalAllocated = std::make_shared<size_t>(0); - { - std::vector<coro::task<>> tasks; - tasks.emplace_back( - f(std::allocator_arg, my_allocator<int>{ totalAllocated })); - coro::sync_wait(tasks[0]); - } - assert(*totalAllocated == 0); - assert(allocator_instance_count == 0); -} - -void test_mixed_custom_allocator_type_erasure() -{ - assert(allocator_instance_count == 0); - - // Show that different allocators can be used within a vector of tasks - // of the same type. ie. that the allocator is type-erased inside the - // coroutine. - std::vector<coro::task<>> tasks; - tasks.push_back(f( - std::allocator_arg, std::allocator<char>{})); - tasks.push_back(f( - std::allocator_arg, - std::experimental::pmr::polymorphic_allocator<char>{ - std::experimental::pmr::new_delete_resource() })); - tasks.push_back(f( - std::allocator_arg, - my_allocator<char>{ std::make_shared<size_t>(0) })); - - assert(allocator_instance_count > 0); - - for (auto& t : tasks) - { - coro::sync_wait(t); - } - - tasks.clear(); - - assert(allocator_instance_count == 0); -} - -template<typename Allocator> -coro::task<int> add_async(std::allocator_arg_t, [[maybe_unused]] Allocator alloc, int a, int b) -{ - co_return a + b; -} - -void test_task_custom_allocator_with_extra_args() -{ - std::vector<coro::task<int>> tasks; - - for (int i = 0; i < 5; ++i) { - tasks.push_back(add_async( - std::allocator_arg, - std::allocator<char>{}, - i, 2 * i)); - } - - for (int i = 0; i < 5; ++i) - { - assert(sync_wait(std::move(tasks[i])) == 3 * i); - } -} - -struct some_type { - template<typename Allocator> - coro::task<int> get_async(std::allocator_arg_t, [[maybe_unused]] Allocator alloc) { - co_return 42; - } - - template<typename Allocator> - coro::task<int> add_async(std::allocator_arg_t, [[maybe_unused]] Allocator alloc, int a, int b) { - co_return a + b; - } -}; - -void test_task_custom_allocator_on_member_function() -{ - assert(allocator_instance_count == 0); - - auto totalAllocated = std::make_shared<size_t>(0); - some_type obj; - assert(sync_wait(obj.get_async(std::allocator_arg, std::allocator<char>{})) == 42); - assert(sync_wait(obj.get_async(std::allocator_arg, my_allocator<char>{totalAllocated})) == 42); - assert(sync_wait(obj.add_async(std::allocator_arg, std::allocator<char>{}, 2, 3)) == 5); - assert(sync_wait(obj.add_async(std::allocator_arg, my_allocator<char>{totalAllocated}, 2, 3)) == 5); - - assert(allocator_instance_count == 0); - assert(*totalAllocated == 0); -} - -int main() -{ - test_custom_allocator_is_destructed(); - test_custom_allocator_type_rebinding(); - test_mixed_custom_allocator_type_erasure(); - test_task_custom_allocator_with_extra_args(); - test_task_custom_allocator_on_member_function(); - - return 0; -} diff --git a/libcxx/test/std/experimental/task/task.basic/task_of_value.pass.cpp b/libcxx/test/std/experimental/task/task.basic/task_of_value.pass.cpp deleted file mode 100644 index 0d5a8c9f619..00000000000 --- a/libcxx/test/std/experimental/task/task.basic/task_of_value.pass.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03, c++11, c++14 - -#include <experimental/task> -#include <string> -#include <vector> -#include <memory> -#include "../sync_wait.hpp" - -void test_returning_move_only_type() -{ - auto move_only_async = - [](bool x) -> std::experimental::task<std::unique_ptr<int>> { - if (x) { - auto p = std::make_unique<int>(123); - co_return p; // Should be implicit std::move(p) here. - } - - co_return std::make_unique<int>(456); - }; - - assert(*sync_wait(move_only_async(true)) == 123); - assert(*sync_wait(move_only_async(false)) == 456); -} - -void test_co_return_with_curly_braces() -{ - auto t = []() -> std::experimental::task<std::tuple<int, std::string>> - { - co_return { 123, "test" }; - }(); - - auto result = sync_wait(std::move(t)); - - assert(std::get<0>(result) == 123); - assert(std::get<1>(result) == "test"); -} - -void test_co_return_by_initialiser_list() -{ - auto t = []() -> std::experimental::task<std::vector<int>> - { - co_return { 2, 10, -1 }; - }(); - - auto result = sync_wait(std::move(t)); - - assert(result.size() == 3); - assert(result[0] == 2); - assert(result[1] == 10); - assert(result[2] == -1); -} - -int main() -{ - test_returning_move_only_type(); - test_co_return_with_curly_braces(); - test_co_return_by_initialiser_list(); - - return 0; -} diff --git a/libcxx/test/std/experimental/task/task.basic/task_of_void.pass.cpp b/libcxx/test/std/experimental/task/task.basic/task_of_void.pass.cpp deleted file mode 100644 index de860b5db6a..00000000000 --- a/libcxx/test/std/experimental/task/task.basic/task_of_void.pass.cpp +++ /dev/null @@ -1,96 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03, c++11, c++14 - -#include <experimental/task> -#include "../manual_reset_event.hpp" -#include "../sync_wait.hpp" - -#include <optional> -#include <thread> - -namespace coro = std::experimental::coroutines_v1; - -static bool has_f_executed = false; - -static coro::task<void> f() -{ - has_f_executed = true; - co_return; -} - -static void test_coroutine_executes_lazily() -{ - coro::task<void> t = f(); - assert(!has_f_executed); - coro::sync_wait(t); - assert(has_f_executed); -} - -static std::optional<int> last_value_passed_to_g; - -static coro::task<void> g(int a) -{ - last_value_passed_to_g = a; - co_return; -} - -void test_coroutine_accepts_arguments() -{ - auto t = g(123); - assert(!last_value_passed_to_g); - coro::sync_wait(t); - assert(last_value_passed_to_g); - assert(*last_value_passed_to_g == 123); -} - -int shared_value = 0; -int read_value = 0; - -coro::task<void> consume_async(manual_reset_event& event) -{ - co_await event; - read_value = shared_value; -} - -void produce(manual_reset_event& event) -{ - shared_value = 101; - event.set(); -} - -void test_async_completion() -{ - manual_reset_event e; - std::thread t1{ [&e] - { - sync_wait(consume_async(e)); - }}; - - assert(read_value == 0); - - std::thread t2{ [&e] { produce(e); }}; - - t1.join(); - - assert(read_value == 101); - - t2.join(); -} - -int main() -{ - test_coroutine_executes_lazily(); - test_coroutine_accepts_arguments(); - test_async_completion(); - - return 0; -} diff --git a/libcxx/test/std/experimental/task/task.lifetime/task_parameter_lifetime.pass.cpp b/libcxx/test/std/experimental/task/task.lifetime/task_parameter_lifetime.pass.cpp deleted file mode 100644 index bc1bd432244..00000000000 --- a/libcxx/test/std/experimental/task/task.lifetime/task_parameter_lifetime.pass.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03, c++11, c++14 - -#include <experimental/task> -#include <cassert> - -#include "../counted.hpp" -#include "../sync_wait.hpp" - -DEFINE_COUNTED_VARIABLES(); - -void test_parameter_lifetime() -{ - counted::reset(); - - auto f = [](counted c) -> std::experimental::task<std::size_t> - { - co_return c.id(); - }; - - { - auto t = f({}); - - assert(counted::active_instance_count() == 1); - assert(counted::copy_constructor_count() == 0); - assert(counted::move_constructor_count() <= 2); // Ideally <= 1 - - auto id = sync_wait(t); - assert(id == 1); - - assert(counted::active_instance_count() == 1); - assert(counted::copy_constructor_count() == 0); - - // We are relying on C++17 copy-elision when passing the temporary counter - // into f(). Then f() must move the parameter into the coroutine frame by - // calling the move-constructor. This move could also potentially be - // elided by the - assert(counted::move_constructor_count() <= 1); - } - - assert(counted::active_instance_count() == 0); -} - -int main() -{ - test_parameter_lifetime(); - return 0; -} diff --git a/libcxx/test/std/experimental/task/task.lifetime/task_return_value_lifetime.pass.cpp b/libcxx/test/std/experimental/task/task.lifetime/task_return_value_lifetime.pass.cpp deleted file mode 100644 index cf528f50660..00000000000 --- a/libcxx/test/std/experimental/task/task.lifetime/task_return_value_lifetime.pass.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03, c++11, c++14 - -#include <experimental/task> -#include <cassert> -#include <iostream> - -#include "../counted.hpp" -#include "../sync_wait.hpp" - -DEFINE_COUNTED_VARIABLES(); - -void test_return_value_lifetime() -{ - counted::reset(); - - auto f = [](bool x) -> std::experimental::task<counted> - { - if (x) { - counted c; - co_return std::move(c); - } - co_return {}; - }; - - { - auto t = f(true); - - assert(counted::active_instance_count() == 0); - assert(counted::copy_constructor_count() == 0); - assert(counted::move_constructor_count() == 0); - - { - auto c = sync_wait(std::move(t)); - assert(c.id() == 1); - - assert(counted::active_instance_count() == 2); - assert(counted::copy_constructor_count() == 0); - assert(counted::move_constructor_count() > 0); - assert(counted::default_constructor_count() == 1); - } - - // The result value in 't' is still alive until 't' destructs. - assert(counted::active_instance_count() == 1); - } - - assert(counted::active_instance_count() == 0); - - counted::reset(); - - { - auto t = f(false); - - assert(counted::active_instance_count() == 0); - assert(counted::copy_constructor_count() == 0); - assert(counted::move_constructor_count() == 0); - - { - auto c = sync_wait(std::move(t)); - assert(c.id() == 1); - - assert(counted::active_instance_count() == 2); - assert(counted::copy_constructor_count() == 0); - assert(counted::move_constructor_count() > 0); - assert(counted::default_constructor_count() == 1); - } - - // The result value in 't' is still alive until 't' destructs. - assert(counted::active_instance_count() == 1); - } -} - -int main() -{ - test_return_value_lifetime(); - return 0; -} |

