aboutsummaryrefslogtreecommitdiff
path: root/test/std/thread
diff options
context:
space:
mode:
Diffstat (limited to 'test/std/thread')
-rw-r--r--test/std/thread/futures/futures.async/async.pass.cpp198
-rw-r--r--test/std/thread/futures/futures.async/async_race.pass.cpp67
-rw-r--r--test/std/thread/futures/futures.errors/default_error_condition.pass.cpp27
-rw-r--r--test/std/thread/futures/futures.errors/equivalent_error_code_int.pass.cpp26
-rw-r--r--test/std/thread/futures/futures.errors/equivalent_int_error_condition.pass.cpp27
-rw-r--r--test/std/thread/futures/futures.errors/future_category.pass.cpp24
-rw-r--r--test/std/thread/futures/futures.errors/make_error_code.pass.cpp28
-rw-r--r--test/std/thread/futures/futures.errors/make_error_condition.pass.cpp30
-rw-r--r--test/std/thread/futures/futures.future_error/code.pass.cpp43
-rw-r--r--test/std/thread/futures/futures.future_error/types.pass.cpp23
-rw-r--r--test/std/thread/futures/futures.future_error/what.pass.cpp50
-rw-r--r--test/std/thread/futures/futures.overview/future_errc.pass.cpp30
-rw-r--r--test/std/thread/futures/futures.overview/future_status.pass.cpp28
-rw-r--r--test/std/thread/futures/futures.overview/is_error_code_enum_future_errc.pass.cpp21
-rw-r--r--test/std/thread/futures/futures.overview/launch.pass.cpp45
-rw-r--r--test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp84
-rw-r--r--test/std/thread/futures/futures.promise/copy_assign.fail.cpp87
-rw-r--r--test/std/thread/futures/futures.promise/copy_ctor.fail.cpp81
-rw-r--r--test/std/thread/futures/futures.promise/default.pass.cpp38
-rw-r--r--test/std/thread/futures/futures.promise/dtor.pass.cpp116
-rw-r--r--test/std/thread/futures/futures.promise/get_future.pass.cpp55
-rw-r--r--test/std/thread/futures/futures.promise/move_assign.pass.cpp91
-rw-r--r--test/std/thread/futures/futures.promise/move_ctor.pass.cpp85
-rw-r--r--test/std/thread/futures/futures.promise/set_exception.pass.cpp47
-rw-r--r--test/std/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp44
-rw-r--r--test/std/thread/futures/futures.promise/set_lvalue.pass.cpp43
-rw-r--r--test/std/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp38
-rw-r--r--test/std/thread/futures/futures.promise/set_rvalue.pass.cpp69
-rw-r--r--test/std/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp41
-rw-r--r--test/std/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp35
-rw-r--r--test/std/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp39
-rw-r--r--test/std/thread/futures/futures.promise/set_value_const.pass.cpp63
-rw-r--r--test/std/thread/futures/futures.promise/set_value_void.pass.cpp39
-rw-r--r--test/std/thread/futures/futures.promise/swap.pass.cpp84
-rw-r--r--test/std/thread/futures/futures.promise/uses_allocator.pass.cpp28
-rw-r--r--test/std/thread/futures/futures.shared_future/copy_assign.pass.cpp76
-rw-r--r--test/std/thread/futures/futures.shared_future/copy_ctor.pass.cpp68
-rw-r--r--test/std/thread/futures/futures.shared_future/ctor_future.pass.cpp68
-rw-r--r--test/std/thread/futures/futures.shared_future/default.pass.cpp35
-rw-r--r--test/std/thread/futures/futures.shared_future/dtor.pass.cpp68
-rw-r--r--test/std/thread/futures/futures.shared_future/get.pass.cpp145
-rw-r--r--test/std/thread/futures/futures.shared_future/move_assign.pass.cpp76
-rw-r--r--test/std/thread/futures/futures.shared_future/move_ctor.pass.cpp68
-rw-r--r--test/std/thread/futures/futures.shared_future/wait.pass.cpp88
-rw-r--r--test/std/thread/futures/futures.shared_future/wait_for.pass.cpp97
-rw-r--r--test/std/thread/futures/futures.shared_future/wait_until.pass.cpp129
-rw-r--r--test/std/thread/futures/futures.state/nothing_to_do.pass.cpp13
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp48
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp50
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp29
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp30
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp46
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp27
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp79
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp124
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp48
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp62
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp64
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp106
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp107
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp60
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp50
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp52
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp26
-rw-r--r--test/std/thread/futures/futures.tas/types.pass.cpp28
-rw-r--r--test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp74
-rw-r--r--test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp66
-rw-r--r--test/std/thread/futures/futures.unique_future/default.pass.cpp35
-rw-r--r--test/std/thread/futures/futures.unique_future/dtor.pass.cpp68
-rw-r--r--test/std/thread/futures/futures.unique_future/get.pass.cpp145
-rw-r--r--test/std/thread/futures/futures.unique_future/move_assign.pass.cpp76
-rw-r--r--test/std/thread/futures/futures.unique_future/move_ctor.pass.cpp70
-rw-r--r--test/std/thread/futures/futures.unique_future/share.pass.cpp68
-rw-r--r--test/std/thread/futures/futures.unique_future/wait.pass.cpp88
-rw-r--r--test/std/thread/futures/futures.unique_future/wait_for.pass.cpp97
-rw-r--r--test/std/thread/futures/futures.unique_future/wait_until.pass.cpp129
-rw-r--r--test/std/thread/futures/test_allocator.h158
-rw-r--r--test/std/thread/futures/version.pass.cpp22
-rw-r--r--test/std/thread/macro.pass.cpp23
-rw-r--r--test/std/thread/thread.condition/cv_status.pass.cpp23
-rw-r--r--test/std/thread/thread.condition/notify_all_at_thread_exit.pass.cpp44
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvar/assign.fail.cpp24
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvar/copy.fail.cpp23
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvar/default.pass.cpp24
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvar/destructor.pass.cpp58
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp29
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp69
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp94
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvar/wait.pass.cpp52
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp87
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvar/wait_for_pred.pass.cpp95
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvar/wait_pred.pass.cpp62
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvar/wait_until.pass.cpp102
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvar/wait_until_pred.pass.cpp113
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvarany/assign.fail.cpp24
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvarany/copy.fail.cpp23
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvarany/default.pass.cpp24
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvarany/destructor.pass.cpp59
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvarany/notify_all.pass.cpp73
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp98
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvarany/wait.exception.pass.cpp63
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvarany/wait.pass.cpp57
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvarany/wait_for.exception.pass.cpp63
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvarany/wait_for.pass.cpp90
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvarany/wait_for_pred.pass.cpp98
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvarany/wait_pred.pass.cpp66
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvarany/wait_until.pass.cpp105
-rw-r--r--test/std/thread/thread.condition/thread.condition.condvarany/wait_until_pred.pass.cpp117
-rw-r--r--test/std/thread/thread.condition/version.pass.cpp22
-rw-r--r--test/std/thread/thread.general/nothing_to_do.pass.cpp12
-rw-r--r--test/std/thread/thread.mutex/thread.lock.algorithm/lock.pass.cpp507
-rw-r--r--test/std/thread/thread.mutex/thread.lock.algorithm/try_lock.pass.cpp516
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp51
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.fail.cpp25
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.fail.cpp23
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp48
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp50
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp29
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_assign.fail.cpp34
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_ctor.fail.cpp30
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/default.pass.cpp28
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp39
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp35
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp81
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp30
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp29
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_duration.pass.cpp81
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_time_point.pass.cpp81
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp74
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp79
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp70
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp75
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp75
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp62
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp45
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp46
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp53
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/mutex.pass.cpp38
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp38
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/owns_lock.pass.cpp38
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.shared/types.pass.cpp31
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp31
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp29
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/default.pass.cpp26
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp35
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp33
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp50
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp28
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp27
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_duration.pass.cpp68
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_time_point.pass.cpp68
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_try_to_lock.pass.cpp64
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp69
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp64
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp69
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp69
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/unlock.pass.cpp56
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/member_swap.pass.cpp38
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/nonmember_swap.pass.cpp39
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/release.pass.cpp46
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/mutex.pass.cpp31
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/op_bool.pass.cpp31
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/owns_lock.pass.cpp31
-rw-r--r--test/std/thread/thread.mutex/thread.lock/thread.lock.unique/types.pass.cpp29
-rw-r--r--test/std/thread/thread.mutex/thread.lock/types.pass.cpp34
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/nothing_to_do.pass.cpp12
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.general/nothing_to_do.pass.cpp12
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/nothing_to_do.pass.cpp12
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/assign.fail.cpp23
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/copy.fail.cpp22
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/default.pass.cpp23
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/lock.pass.cpp50
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp27
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/try_lock.pass.cpp52
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/assign.fail.cpp23
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/copy.fail.cpp22
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/default.pass.cpp23
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/lock.pass.cpp52
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp27
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/try_lock.pass.cpp54
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/nothing_to_do.pass.cpp12
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/assign.fail.cpp29
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp28
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/default.pass.cpp24
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock.pass.cpp50
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock_shared.pass.cpp73
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock.pass.cpp53
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock_shared.pass.cpp58
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/nothing_to_do.pass.cpp12
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/assign.fail.cpp27
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/copy.fail.cpp26
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/default.pass.cpp24
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock.pass.cpp49
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock_shared.pass.cpp73
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock.pass.cpp53
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp68
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared.pass.cpp57
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp75
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp75
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp70
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until_deadlock_bug.pass.cpp70
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/nothing_to_do.pass.cpp12
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/assign.fail.cpp23
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/copy.fail.cpp22
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/default.pass.cpp23
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/lock.pass.cpp50
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock.pass.cpp52
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_for.pass.cpp67
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_until.pass.cpp67
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/assign.fail.cpp23
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/copy.fail.cpp22
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/default.pass.cpp23
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/lock.pass.cpp52
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock.pass.cpp54
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_for.pass.cpp69
-rw-r--r--test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_until.pass.cpp69
-rw-r--r--test/std/thread/thread.mutex/thread.once/nothing_to_do.pass.cpp12
-rw-r--r--test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp254
-rw-r--r--test/std/thread/thread.mutex/thread.once/thread.once.onceflag/assign.fail.cpp23
-rw-r--r--test/std/thread/thread.mutex/thread.once/thread.once.onceflag/copy.fail.cpp22
-rw-r--r--test/std/thread/thread.mutex/thread.once/thread.once.onceflag/default.pass.cpp28
-rw-r--r--test/std/thread/thread.mutex/version.pass.cpp20
-rw-r--r--test/std/thread/thread.req/nothing_to_do.pass.cpp12
-rw-r--r--test/std/thread/thread.req/thread.req.exception/nothing_to_do.pass.cpp12
-rw-r--r--test/std/thread/thread.req/thread.req.lockable/nothing_to_do.pass.cpp12
-rw-r--r--test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.basic/nothing_to_do.pass.cpp12
-rw-r--r--test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.general/nothing_to_do.pass.cpp12
-rw-r--r--test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.req/nothing_to_do.pass.cpp12
-rw-r--r--test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.timed/nothing_to_do.pass.cpp12
-rw-r--r--test/std/thread/thread.req/thread.req.native/nothing_to_do.pass.cpp12
-rw-r--r--test/std/thread/thread.req/thread.req.paramname/nothing_to_do.pass.cpp12
-rw-r--r--test/std/thread/thread.req/thread.req.timing/nothing_to_do.pass.cpp12
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.algorithm/swap.pass.cpp58
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/copy.fail.cpp51
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move.pass.cpp65
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp77
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp154
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/constr.fail.cpp26
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/copy.fail.cpp66
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/default.pass.cpp25
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/move.pass.cpp72
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.pass.cpp66
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.id/assign.pass.cpp29
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.id/copy.pass.cpp26
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.id/default.pass.cpp25
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.id/eq.pass.cpp32
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.id/lt.pass.cpp43
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp29
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.id/thread_id.pass.cpp35
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.cpp73
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.member/get_id.pass.cpp57
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp54
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.member/joinable.pass.cpp54
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp54
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.member/swap.pass.cpp58
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/thread.thread.static/hardware_concurrency.pass.cpp24
-rw-r--r--test/std/thread/thread.threads/thread.thread.class/types.pass.cpp27
-rw-r--r--test/std/thread/thread.threads/thread.thread.this/get_id.pass.cpp23
-rw-r--r--test/std/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp57
-rw-r--r--test/std/thread/thread.threads/thread.thread.this/sleep_until.pass.cpp34
-rw-r--r--test/std/thread/thread.threads/thread.thread.this/yield.pass.cpp22
-rw-r--r--test/std/thread/thread.threads/version.pass.cpp22
262 files changed, 14344 insertions, 0 deletions
diff --git a/test/std/thread/futures/futures.async/async.pass.cpp b/test/std/thread/futures/futures.async/async.pass.cpp
new file mode 100644
index 000000000000..c8a742566d8f
--- /dev/null
+++ b/test/std/thread/futures/futures.async/async.pass.cpp
@@ -0,0 +1,198 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// template <class F, class... Args>
+// future<typename result_of<F(Args...)>::type>
+// async(F&& f, Args&&... args);
+
+// template <class F, class... Args>
+// future<typename result_of<F(Args...)>::type>
+// async(launch policy, F&& f, Args&&... args);
+
+#include <future>
+#include <memory>
+#include <cassert>
+
+typedef std::chrono::high_resolution_clock Clock;
+typedef std::chrono::milliseconds ms;
+
+int f0()
+{
+ std::this_thread::sleep_for(ms(200));
+ return 3;
+}
+
+int i = 0;
+
+int& f1()
+{
+ std::this_thread::sleep_for(ms(200));
+ return i;
+}
+
+void f2()
+{
+ std::this_thread::sleep_for(ms(200));
+}
+
+std::unique_ptr<int> f3(int i)
+{
+ std::this_thread::sleep_for(ms(200));
+ return std::unique_ptr<int>(new int(i));
+}
+
+std::unique_ptr<int> f4(std::unique_ptr<int>&& p)
+{
+ std::this_thread::sleep_for(ms(200));
+ return std::move(p);
+}
+
+void f5(int i)
+{
+ std::this_thread::sleep_for(ms(200));
+ throw i;
+}
+
+int main()
+{
+ {
+ std::future<int> f = std::async(f0);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+ {
+ std::future<int> f = std::async(std::launch::async, f0);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+ {
+ std::future<int> f = std::async(std::launch::any, f0);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+ {
+ std::future<int> f = std::async(std::launch::deferred, f0);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 > ms(100));
+ }
+
+ {
+ std::future<int&> f = std::async(f1);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(&f.get() == &i);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+ {
+ std::future<int&> f = std::async(std::launch::async, f1);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(&f.get() == &i);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+ {
+ std::future<int&> f = std::async(std::launch::any, f1);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(&f.get() == &i);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+ {
+ std::future<int&> f = std::async(std::launch::deferred, f1);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(&f.get() == &i);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 > ms(100));
+ }
+
+ {
+ std::future<void> f = std::async(f2);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ f.get();
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+ {
+ std::future<void> f = std::async(std::launch::async, f2);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ f.get();
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+ {
+ std::future<void> f = std::async(std::launch::any, f2);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ f.get();
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+ {
+ std::future<void> f = std::async(std::launch::deferred, f2);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ f.get();
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 > ms(100));
+ }
+
+ {
+ std::future<std::unique_ptr<int>> f = std::async(f3, 3);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(*f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+
+ {
+ std::future<std::unique_ptr<int>> f =
+ std::async(f4, std::unique_ptr<int>(new int(3)));
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(*f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+
+ {
+ std::future<void> f = std::async(f5, 3);
+ std::this_thread::sleep_for(ms(300));
+ try { f.get(); assert (false); } catch ( int ex ) {}
+ }
+
+ {
+ std::future<void> f = std::async(std::launch::deferred, f5, 3);
+ std::this_thread::sleep_for(ms(300));
+ try { f.get(); assert (false); } catch ( int ex ) {}
+ }
+
+}
diff --git a/test/std/thread/futures/futures.async/async_race.pass.cpp b/test/std/thread/futures/futures.async/async_race.pass.cpp
new file mode 100644
index 000000000000..325a027132de
--- /dev/null
+++ b/test/std/thread/futures/futures.async/async_race.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// template <class F, class... Args>
+// future<typename result_of<F(Args...)>::type>
+// async(F&& f, Args&&... args);
+
+// template <class F, class... Args>
+// future<typename result_of<F(Args...)>::type>
+// async(launch policy, F&& f, Args&&... args);
+
+// This test is designed to cause and allow TSAN to detect the race condition
+// reported in PR23293. (http://llvm.org/PR23293).
+
+#include <future>
+#include <chrono>
+#include <thread>
+#include <memory>
+#include <cassert>
+
+int f_async() {
+ typedef std::chrono::milliseconds ms;
+ std::this_thread::sleep_for(ms(200));
+ return 42;
+}
+
+bool ran = false;
+
+int f_deferred() {
+ ran = true;
+ return 42;
+}
+
+void test_each() {
+ {
+ std::future<int> f = std::async(f_async);
+ int const result = f.get();
+ assert(result == 42);
+ }
+ {
+ std::future<int> f = std::async(std::launch::async, f_async);
+ int const result = f.get();
+ assert(result == 42);
+ }
+ {
+ ran = false;
+ std::future<int> f = std::async(std::launch::deferred, f_deferred);
+ assert(ran == false);
+ int const result = f.get();
+ assert(ran == true);
+ assert(result == 42);
+ }
+}
+
+int main() {
+ for (int i=0; i < 25; ++i) test_each();
+}
diff --git a/test/std/thread/futures/futures.errors/default_error_condition.pass.cpp b/test/std/thread/futures/futures.errors/default_error_condition.pass.cpp
new file mode 100644
index 000000000000..7f28b8a23b81
--- /dev/null
+++ b/test/std/thread/futures/futures.errors/default_error_condition.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// const error_category& future_category();
+
+// virtual error_condition default_error_condition(int ev) const;
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ const std::error_category& e_cat = std::future_category();
+ std::error_condition e_cond = e_cat.default_error_condition(static_cast<int>(std::errc::not_a_directory));
+ assert(e_cond.category() == e_cat);
+ assert(e_cond.value() == static_cast<int>(std::errc::not_a_directory));
+}
diff --git a/test/std/thread/futures/futures.errors/equivalent_error_code_int.pass.cpp b/test/std/thread/futures/futures.errors/equivalent_error_code_int.pass.cpp
new file mode 100644
index 000000000000..cd0017657740
--- /dev/null
+++ b/test/std/thread/futures/futures.errors/equivalent_error_code_int.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// const error_category& future_category();
+
+// virtual bool equivalent(const error_code& code, int condition) const;
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ const std::error_category& e_cat = std::future_category();
+ assert(e_cat.equivalent(std::error_code(5, e_cat), 5));
+ assert(!e_cat.equivalent(std::error_code(5, e_cat), 6));
+}
diff --git a/test/std/thread/futures/futures.errors/equivalent_int_error_condition.pass.cpp b/test/std/thread/futures/futures.errors/equivalent_int_error_condition.pass.cpp
new file mode 100644
index 000000000000..05ad1ec9c6f5
--- /dev/null
+++ b/test/std/thread/futures/futures.errors/equivalent_int_error_condition.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// const error_category& future_category();
+
+// virtual bool equivalent(int code, const error_condition& condition) const;
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ const std::error_category& e_cat = std::future_category();
+ std::error_condition e_cond = e_cat.default_error_condition(5);
+ assert(e_cat.equivalent(5, e_cond));
+ assert(!e_cat.equivalent(6, e_cond));
+}
diff --git a/test/std/thread/futures/futures.errors/future_category.pass.cpp b/test/std/thread/futures/futures.errors/future_category.pass.cpp
new file mode 100644
index 000000000000..7f407a061d95
--- /dev/null
+++ b/test/std/thread/futures/futures.errors/future_category.pass.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// const error_category& future_category();
+
+#include <future>
+#include <cstring>
+#include <cassert>
+
+int main()
+{
+ const std::error_category& ec = std::future_category();
+ assert(std::strcmp(ec.name(), "future") == 0);
+}
diff --git a/test/std/thread/futures/futures.errors/make_error_code.pass.cpp b/test/std/thread/futures/futures.errors/make_error_code.pass.cpp
new file mode 100644
index 000000000000..3c14addf309f
--- /dev/null
+++ b/test/std/thread/futures/futures.errors/make_error_code.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class error_code
+
+// error_code make_error_code(future_errc e);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ std::error_code ec = make_error_code(std::future_errc::broken_promise);
+ assert(ec.value() == static_cast<int>(std::future_errc::broken_promise));
+ assert(ec.category() == std::future_category());
+ }
+}
diff --git a/test/std/thread/futures/futures.errors/make_error_condition.pass.cpp b/test/std/thread/futures/futures.errors/make_error_condition.pass.cpp
new file mode 100644
index 000000000000..52972aa373f5
--- /dev/null
+++ b/test/std/thread/futures/futures.errors/make_error_condition.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class error_condition
+
+// error_condition make_error_condition(future_errc e);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ const std::error_condition ec1 =
+ std::make_error_condition(std::future_errc::future_already_retrieved);
+ assert(ec1.value() ==
+ static_cast<int>(std::future_errc::future_already_retrieved));
+ assert(ec1.category() == std::future_category());
+ }
+}
diff --git a/test/std/thread/futures/futures.future_error/code.pass.cpp b/test/std/thread/futures/futures.future_error/code.pass.cpp
new file mode 100644
index 000000000000..e02af486fc39
--- /dev/null
+++ b/test/std/thread/futures/futures.future_error/code.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class future_error
+
+// const error_code& code() const throw();
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ std::error_code ec = std::make_error_code(std::future_errc::broken_promise);
+ std::future_error f(ec);
+ assert(f.code() == ec);
+ }
+ {
+ std::error_code ec = std::make_error_code(std::future_errc::future_already_retrieved);
+ std::future_error f(ec);
+ assert(f.code() == ec);
+ }
+ {
+ std::error_code ec = std::make_error_code(std::future_errc::promise_already_satisfied);
+ std::future_error f(ec);
+ assert(f.code() == ec);
+ }
+ {
+ std::error_code ec = std::make_error_code(std::future_errc::no_state);
+ std::future_error f(ec);
+ assert(f.code() == ec);
+ }
+}
diff --git a/test/std/thread/futures/futures.future_error/types.pass.cpp b/test/std/thread/futures/futures.future_error/types.pass.cpp
new file mode 100644
index 000000000000..e741dd06e4b9
--- /dev/null
+++ b/test/std/thread/futures/futures.future_error/types.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class future_error : public logic_error {...};
+
+#include <future>
+#include <type_traits>
+
+int main()
+{
+ static_assert((std::is_convertible<std::future_error*,
+ std::logic_error*>::value), "");
+}
diff --git a/test/std/thread/futures/futures.future_error/what.pass.cpp b/test/std/thread/futures/futures.future_error/what.pass.cpp
new file mode 100644
index 000000000000..52d2e944a684
--- /dev/null
+++ b/test/std/thread/futures/futures.future_error/what.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// LWG 2056 changed the values of future_errc, so if we're using new headers
+// with an old library we'll get incorrect messages.
+//
+// XFAIL: with_system_cxx_lib=x86_64-apple-darwin11
+// XFAIL: with_system_cxx_lib=x86_64-apple-darwin12
+// XFAIL: with_system_cxx_lib=x86_64-apple-darwin13
+
+// <future>
+
+// class future_error
+
+// const char* what() const throw();
+
+#include <future>
+#include <cstring>
+#include <cassert>
+
+int main()
+{
+ {
+ std::future_error f(std::make_error_code(std::future_errc::broken_promise));
+ assert(std::strcmp(f.what(), "The associated promise has been destructed prior "
+ "to the associated state becoming ready.") == 0);
+ }
+ {
+ std::future_error f(std::make_error_code(std::future_errc::future_already_retrieved));
+ assert(std::strcmp(f.what(), "The future has already been retrieved from "
+ "the promise or packaged_task.") == 0);
+ }
+ {
+ std::future_error f(std::make_error_code(std::future_errc::promise_already_satisfied));
+ assert(std::strcmp(f.what(), "The state of the promise has already been set.") == 0);
+ }
+ {
+ std::future_error f(std::make_error_code(std::future_errc::no_state));
+ assert(std::strcmp(f.what(), "Operation not permitted on an object without "
+ "an associated state.") == 0);
+ }
+}
diff --git a/test/std/thread/futures/futures.overview/future_errc.pass.cpp b/test/std/thread/futures/futures.overview/future_errc.pass.cpp
new file mode 100644
index 000000000000..1e6fcb76a0e7
--- /dev/null
+++ b/test/std/thread/futures/futures.overview/future_errc.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// enum class future_errc
+// {
+// future_already_retrieved = 1,
+// promise_already_satisfied,
+// no_state
+// broken_promise,
+// };
+
+#include <future>
+
+int main()
+{
+ static_assert(static_cast<int>(std::future_errc::future_already_retrieved) == 1, "");
+ static_assert(static_cast<int>(std::future_errc::promise_already_satisfied) == 2, "");
+ static_assert(static_cast<int>(std::future_errc::no_state) == 3, "");
+ static_assert(static_cast<int>(std::future_errc::broken_promise) == 4, "");
+}
diff --git a/test/std/thread/futures/futures.overview/future_status.pass.cpp b/test/std/thread/futures/futures.overview/future_status.pass.cpp
new file mode 100644
index 000000000000..2c196aaac56d
--- /dev/null
+++ b/test/std/thread/futures/futures.overview/future_status.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// enum class future_status
+// {
+// ready,
+// timeout,
+// deferred
+// };
+
+#include <future>
+
+int main()
+{
+ static_assert(static_cast<int>(std::future_status::ready) == 0, "");
+ static_assert(static_cast<int>(std::future_status::timeout) == 1, "");
+ static_assert(static_cast<int>(std::future_status::deferred) == 2, "");
+}
diff --git a/test/std/thread/futures/futures.overview/is_error_code_enum_future_errc.pass.cpp b/test/std/thread/futures/futures.overview/is_error_code_enum_future_errc.pass.cpp
new file mode 100644
index 000000000000..499de52598b6
--- /dev/null
+++ b/test/std/thread/futures/futures.overview/is_error_code_enum_future_errc.pass.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// template <> struct is_error_code_enum<future_errc> : public true_type {};
+
+#include <future>
+
+int main()
+{
+ static_assert(std::is_error_code_enum<std::future_errc>::value, "");
+}
diff --git a/test/std/thread/futures/futures.overview/launch.pass.cpp b/test/std/thread/futures/futures.overview/launch.pass.cpp
new file mode 100644
index 000000000000..da54f7ee6732
--- /dev/null
+++ b/test/std/thread/futures/futures.overview/launch.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// enum class launch
+// {
+// async = 1,
+// deferred = 2,
+// any = async | deferred
+// };
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
+ static_assert(static_cast<int>(std::launch::any) ==
+ (static_cast<int>(std::launch::async) | static_cast<int>(std::launch::deferred)), "");
+#else
+ static_assert(std::launch::any == (std::launch::async | std::launch::deferred), "");
+ static_assert(std::launch(0) == (std::launch::async & std::launch::deferred), "");
+ static_assert(std::launch::any == (std::launch::async ^ std::launch::deferred), "");
+ static_assert(std::launch::deferred == ~std::launch::async, "");
+ std::launch x = std::launch::async;
+ x &= std::launch::deferred;
+ assert(x == std::launch(0));
+ x = std::launch::async;
+ x |= std::launch::deferred;
+ assert(x == std::launch::any);
+ x ^= std::launch::deferred;
+ assert(x == std::launch::async);
+#endif
+ static_assert(static_cast<int>(std::launch::async) == 1, "");
+ static_assert(static_cast<int>(std::launch::deferred) == 2, "");
+}
diff --git a/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp b/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp
new file mode 100644
index 000000000000..70a4e00b0d6a
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// template <class Allocator>
+// promise(allocator_arg_t, const Allocator& a);
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+#include "min_allocator.h"
+
+int main()
+{
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 1);
+ std::future<int> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int&> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 1);
+ std::future<int&> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<void> p(std::allocator_arg, test_allocator<void>());
+ assert(test_alloc_base::count == 1);
+ std::future<void> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 0);
+ // Test with a minimal allocator
+ {
+ std::promise<int> p(std::allocator_arg, bare_allocator<void>());
+ std::future<int> f = p.get_future();
+ assert(f.valid());
+ }
+ {
+ std::promise<int&> p(std::allocator_arg, bare_allocator<void>());
+ std::future<int&> f = p.get_future();
+ assert(f.valid());
+ }
+ {
+ std::promise<void> p(std::allocator_arg, bare_allocator<void>());
+ std::future<void> f = p.get_future();
+ assert(f.valid());
+ }
+ // Test with a minimal allocator that returns class-type pointers
+ {
+ std::promise<int> p(std::allocator_arg, min_allocator<void>());
+ std::future<int> f = p.get_future();
+ assert(f.valid());
+ }
+ {
+ std::promise<int&> p(std::allocator_arg, min_allocator<void>());
+ std::future<int&> f = p.get_future();
+ assert(f.valid());
+ }
+ {
+ std::promise<void> p(std::allocator_arg, min_allocator<void>());
+ std::future<void> f = p.get_future();
+ assert(f.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/copy_assign.fail.cpp b/test/std/thread/futures/futures.promise/copy_assign.fail.cpp
new file mode 100644
index 000000000000..c08278122225
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/copy_assign.fail.cpp
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// promise& operator=(const promise& rhs) = delete;
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 2);
+ p = p0;
+ assert(test_alloc_base::count == 1);
+ std::future<int> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int&> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int&> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 2);
+ p = p0;
+ assert(test_alloc_base::count == 1);
+ std::future<int&> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<void> p0(std::allocator_arg, test_allocator<void>());
+ std::promise<void> p(std::allocator_arg, test_allocator<void>());
+ assert(test_alloc_base::count == 2);
+ p = p0;
+ assert(test_alloc_base::count == 1);
+ std::future<void> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+}
diff --git a/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp b/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp
new file mode 100644
index 000000000000..36a3555aed46
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// promise(const promise&) = delete;
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int> p(p0);
+ assert(test_alloc_base::count == 1);
+ std::future<int> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int&> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int&> p(p0);
+ assert(test_alloc_base::count == 1);
+ std::future<int&> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<void> p0(std::allocator_arg, test_allocator<void>());
+ std::promise<void> p(p0);
+ assert(test_alloc_base::count == 1);
+ std::future<void> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+}
diff --git a/test/std/thread/futures/futures.promise/default.pass.cpp b/test/std/thread/futures/futures.promise/default.pass.cpp
new file mode 100644
index 000000000000..95c9657c633e
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/default.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// promise();
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ std::promise<int> p;
+ std::future<int> f = p.get_future();
+ assert(f.valid());
+ }
+ {
+ std::promise<int&> p;
+ std::future<int&> f = p.get_future();
+ assert(f.valid());
+ }
+ {
+ std::promise<void> p;
+ std::future<void> f = p.get_future();
+ assert(f.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/dtor.pass.cpp b/test/std/thread/futures/futures.promise/dtor.pass.cpp
new file mode 100644
index 000000000000..78912f12adb9
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/dtor.pass.cpp
@@ -0,0 +1,116 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// ~promise();
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef int T;
+ std::future<T> f;
+ {
+ std::promise<T> p;
+ f = p.get_future();
+ p.set_value(3);
+ }
+ assert(f.get() == 3);
+ }
+ {
+ typedef int T;
+ std::future<T> f;
+ {
+ std::promise<T> p;
+ f = p.get_future();
+ }
+ try
+ {
+ T i = f.get();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::broken_promise));
+ }
+ }
+
+ {
+ typedef int& T;
+ int i = 4;
+ std::future<T> f;
+ {
+ std::promise<T> p;
+ f = p.get_future();
+ p.set_value(i);
+ }
+ assert(&f.get() == &i);
+ }
+ {
+ typedef int& T;
+ std::future<T> f;
+ {
+ std::promise<T> p;
+ f = p.get_future();
+ }
+ try
+ {
+ T i = f.get();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::broken_promise));
+ }
+ }
+
+ {
+ typedef void T;
+ std::future<T> f;
+ {
+ std::promise<T> p;
+ f = p.get_future();
+ p.set_value();
+ }
+ f.get();
+ assert(true);
+ }
+ {
+ typedef void T;
+ std::future<T> f;
+ {
+ std::promise<T> p;
+ f = p.get_future();
+ }
+ try
+ {
+ f.get();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ // LWG 2056 changed the values of future_errc, so if we're using new
+ // headers with an old library the error codes won't line up.
+ //
+ // Note that this particular check only applies to promise<void>
+ // since the other specializations happen to be implemented in the
+ // header rather than the library.
+ assert(
+ e.code() == make_error_code(std::future_errc::broken_promise) ||
+ e.code() == std::error_code(0, std::future_category()));
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/get_future.pass.cpp b/test/std/thread/futures/futures.promise/get_future.pass.cpp
new file mode 100644
index 000000000000..a7d084ee7873
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/get_future.pass.cpp
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// future<R> get_future();
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ std::promise<double> p;
+ std::future<double> f = p.get_future();
+ p.set_value(105.5);
+ assert(f.get() == 105.5);
+ }
+ {
+ std::promise<double> p;
+ std::future<double> f = p.get_future();
+ try
+ {
+ f = p.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::future_already_retrieved));
+ }
+ }
+ {
+ std::promise<double> p;
+ std::promise<double> p0 = std::move(p);
+ try
+ {
+ std::future<double> f = p.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/move_assign.pass.cpp b/test/std/thread/futures/futures.promise/move_assign.pass.cpp
new file mode 100644
index 000000000000..c3097df74990
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/move_assign.pass.cpp
@@ -0,0 +1,91 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// promise& operator=(promise&& rhs);
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 2);
+ p = std::move(p0);
+ assert(test_alloc_base::count == 1);
+ std::future<int> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int&> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int&> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 2);
+ p = std::move(p0);
+ assert(test_alloc_base::count == 1);
+ std::future<int&> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<void> p0(std::allocator_arg, test_allocator<void>());
+ std::promise<void> p(std::allocator_arg, test_allocator<void>());
+ assert(test_alloc_base::count == 2);
+ p = std::move(p0);
+ assert(test_alloc_base::count == 1);
+ std::future<void> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/futures/futures.promise/move_ctor.pass.cpp b/test/std/thread/futures/futures.promise/move_ctor.pass.cpp
new file mode 100644
index 000000000000..eeec4fb15b95
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/move_ctor.pass.cpp
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// promise(promise&& rhs);
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int> p(std::move(p0));
+ assert(test_alloc_base::count == 1);
+ std::future<int> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int&> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int&> p(std::move(p0));
+ assert(test_alloc_base::count == 1);
+ std::future<int&> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<void> p0(std::allocator_arg, test_allocator<void>());
+ std::promise<void> p(std::move(p0));
+ assert(test_alloc_base::count == 1);
+ std::future<void> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/futures/futures.promise/set_exception.pass.cpp b/test/std/thread/futures/futures.promise/set_exception.pass.cpp
new file mode 100644
index 000000000000..51c05eb803cb
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_exception.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void set_exception(exception_ptr p);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ p.set_exception(std::make_exception_ptr(3));
+ try
+ {
+ f.get();
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 3);
+ }
+ try
+ {
+ p.set_exception(std::make_exception_ptr(3));
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp
new file mode 100644
index 000000000000..5e57692563d8
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void promise::set_exception_at_thread_exit(exception_ptr p);
+
+#include <future>
+#include <cassert>
+
+void func(std::promise<int> p)
+{
+ const int i = 5;
+ p.set_exception_at_thread_exit(std::make_exception_ptr(3));
+}
+
+int main()
+{
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func, std::move(p)).detach();
+ try
+ {
+ f.get();
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 3);
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/set_lvalue.pass.cpp b/test/std/thread/futures/futures.promise/set_lvalue.pass.cpp
new file mode 100644
index 000000000000..cdc37775012c
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_lvalue.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void promise<R&>::set_value(R& r);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef int& T;
+ int i = 3;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ p.set_value(i);
+ int& j = f.get();
+ assert(j == 3);
+ ++i;
+ assert(j == 4);
+ try
+ {
+ p.set_value(i);
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp
new file mode 100644
index 000000000000..18f87c596a00
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void promise<R&>::set_value_at_thread_exit(R& r);
+
+#include <future>
+#include <memory>
+#include <cassert>
+
+int i = 0;
+
+void func(std::promise<int&> p)
+{
+ p.set_value_at_thread_exit(i);
+ i = 4;
+}
+
+int main()
+{
+ {
+ std::promise<int&> p;
+ std::future<int&> f = p.get_future();
+ std::thread(func, std::move(p)).detach();
+ assert(f.get() == 4);
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp b/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp
new file mode 100644
index 000000000000..dab4bf7e9c83
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void promise::set_value(R&& r);
+
+#include <future>
+#include <memory>
+#include <cassert>
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+struct A
+{
+ A() {}
+ A(const A&) = delete;
+ A(A&&) {throw 9;}
+};
+
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ typedef std::unique_ptr<int> T;
+ T i(new int(3));
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ p.set_value(std::move(i));
+ assert(*f.get() == 3);
+ try
+ {
+ p.set_value(std::move(i));
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
+ }
+ }
+ {
+ typedef A T;
+ T i;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ try
+ {
+ p.set_value(std::move(i));
+ assert(false);
+ }
+ catch (int j)
+ {
+ assert(j == 9);
+ }
+ }
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp
new file mode 100644
index 000000000000..8f3b76865e2a
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void promise::set_value_at_thread_exit(R&& r);
+
+#include <future>
+#include <memory>
+#include <cassert>
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+void func(std::promise<std::unique_ptr<int>> p)
+{
+ p.set_value_at_thread_exit(std::unique_ptr<int>(new int(5)));
+}
+
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ std::promise<std::unique_ptr<int>> p;
+ std::future<std::unique_ptr<int>> f = p.get_future();
+ std::thread(func, std::move(p)).detach();
+ assert(*f.get() == 5);
+ }
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp
new file mode 100644
index 000000000000..ec50cc310298
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void promise::set_value_at_thread_exit(const R& r);
+
+#include <future>
+#include <cassert>
+
+void func(std::promise<int> p)
+{
+ const int i = 5;
+ p.set_value_at_thread_exit(i);
+}
+
+int main()
+{
+ {
+ std::promise<int> p;
+ std::future<int> f = p.get_future();
+ std::thread(func, std::move(p)).detach();
+ assert(f.get() == 5);
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp
new file mode 100644
index 000000000000..8c092084668d
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void promise<void>::set_value_at_thread_exit();
+
+#include <future>
+#include <memory>
+#include <cassert>
+
+int i = 0;
+
+void func(std::promise<void> p)
+{
+ p.set_value_at_thread_exit();
+ i = 1;
+}
+
+int main()
+{
+ {
+ std::promise<void> p;
+ std::future<void> f = p.get_future();
+ std::thread(func, std::move(p)).detach();
+ f.get();
+ assert(i == 1);
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/set_value_const.pass.cpp b/test/std/thread/futures/futures.promise/set_value_const.pass.cpp
new file mode 100644
index 000000000000..6673f6307579
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_value_const.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void promise::set_value(const R& r);
+
+#include <future>
+#include <cassert>
+
+struct A
+{
+ A() {}
+ A(const A&) {throw 10;}
+};
+
+int main()
+{
+ {
+ typedef int T;
+ T i = 3;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ p.set_value(i);
+ ++i;
+ assert(f.get() == 3);
+ --i;
+ try
+ {
+ p.set_value(i);
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
+ }
+ }
+ {
+ typedef A T;
+ T i;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ try
+ {
+ p.set_value(i);
+ assert(false);
+ }
+ catch (int j)
+ {
+ assert(j == 10);
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/set_value_void.pass.cpp b/test/std/thread/futures/futures.promise/set_value_void.pass.cpp
new file mode 100644
index 000000000000..5012e0bfe5fd
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_value_void.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void promise<void>::set_value();
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ p.set_value();
+ f.get();
+ try
+ {
+ p.set_value();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/swap.pass.cpp b/test/std/thread/futures/futures.promise/swap.pass.cpp
new file mode 100644
index 000000000000..1ed3e646813c
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/swap.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void swap(promise& other);
+
+// template <class R> void swap(promise<R>& x, promise<R>& y);
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 2);
+ p.swap(p0);
+ assert(test_alloc_base::count == 2);
+ std::future<int> f = p.get_future();
+ assert(test_alloc_base::count == 2);
+ assert(f.valid());
+ f = p0.get_future();
+ assert(f.valid());
+ assert(test_alloc_base::count == 2);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 2);
+ swap(p, p0);
+ assert(test_alloc_base::count == 2);
+ std::future<int> f = p.get_future();
+ assert(test_alloc_base::count == 2);
+ assert(f.valid());
+ f = p0.get_future();
+ assert(f.valid());
+ assert(test_alloc_base::count == 2);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int> p;
+ assert(test_alloc_base::count == 1);
+ p.swap(p0);
+ assert(test_alloc_base::count == 1);
+ std::future<int> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ f = p0.get_future();
+ assert(f.valid());
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int> p;
+ assert(test_alloc_base::count == 1);
+ swap(p, p0);
+ assert(test_alloc_base::count == 1);
+ std::future<int> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ f = p0.get_future();
+ assert(f.valid());
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+}
diff --git a/test/std/thread/futures/futures.promise/uses_allocator.pass.cpp b/test/std/thread/futures/futures.promise/uses_allocator.pass.cpp
new file mode 100644
index 000000000000..458826e956e1
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/uses_allocator.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// template <class R, class Alloc>
+// struct uses_allocator<promise<R>, Alloc>
+// : true_type { };
+
+#include <future>
+#include "../test_allocator.h"
+
+int main()
+{
+ static_assert((std::uses_allocator<std::promise<int>, test_allocator<int> >::value), "");
+ static_assert((std::uses_allocator<std::promise<int&>, test_allocator<int> >::value), "");
+ static_assert((std::uses_allocator<std::promise<void>, test_allocator<void> >::value), "");
+}
diff --git a/test/std/thread/futures/futures.shared_future/copy_assign.pass.cpp b/test/std/thread/futures/futures.shared_future/copy_assign.pass.cpp
new file mode 100644
index 000000000000..b23ba196ec30
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/copy_assign.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// shared_future& operator=(const shared_future& rhs);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f;
+ f = f0;
+ assert(f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f;
+ f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f;
+ f = f0;
+ assert(f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f;
+ f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f;
+ f = f0;
+ assert(f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f;
+ f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/futures/futures.shared_future/copy_ctor.pass.cpp b/test/std/thread/futures/futures.shared_future/copy_ctor.pass.cpp
new file mode 100644
index 000000000000..425d1f9be96f
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/copy_ctor.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// shared_future(const shared_future& rhs);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f = f0;
+ assert(f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f = f0;
+ assert(f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f = f0;
+ assert(f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.shared_future/ctor_future.pass.cpp b/test/std/thread/futures/futures.shared_future/ctor_future.pass.cpp
new file mode 100644
index 000000000000..3a78b80f0634
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/ctor_future.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// shared_future(future<R>&& rhs);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::future<T> f0;
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::future<T> f0;
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::future<T> f0;
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.shared_future/default.pass.cpp b/test/std/thread/futures/futures.shared_future/default.pass.cpp
new file mode 100644
index 000000000000..92927f5f6933
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/default.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// shared_future();
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ std::shared_future<int> f;
+ assert(!f.valid());
+ }
+ {
+ std::shared_future<int&> f;
+ assert(!f.valid());
+ }
+ {
+ std::shared_future<void> f;
+ assert(!f.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.shared_future/dtor.pass.cpp b/test/std/thread/futures/futures.shared_future/dtor.pass.cpp
new file mode 100644
index 000000000000..baa89cb12b1c
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/dtor.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// ~shared_future();
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+ assert(test_alloc_base::count == 0);
+ {
+ typedef int T;
+ std::shared_future<T> f;
+ {
+ std::promise<T> p(std::allocator_arg, test_allocator<T>());
+ assert(test_alloc_base::count == 1);
+ f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ typedef int& T;
+ std::shared_future<T> f;
+ {
+ std::promise<T> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 1);
+ f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ typedef void T;
+ std::shared_future<T> f;
+ {
+ std::promise<T> p(std::allocator_arg, test_allocator<T>());
+ assert(test_alloc_base::count == 1);
+ f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 0);
+}
diff --git a/test/std/thread/futures/futures.shared_future/get.pass.cpp b/test/std/thread/futures/futures.shared_future/get.pass.cpp
new file mode 100644
index 000000000000..c5ee234b127f
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/get.pass.cpp
@@ -0,0 +1,145 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// const R& shared_future::get();
+// R& shared_future<R&>::get();
+// void shared_future<void>::get();
+
+#include <future>
+#include <cassert>
+
+void func1(std::promise<int> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_value(3);
+}
+
+void func2(std::promise<int> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_exception(std::make_exception_ptr(3));
+}
+
+int j = 0;
+
+void func3(std::promise<int&> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func4(std::promise<int&> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_exception(std::make_exception_ptr(3.5));
+}
+
+void func5(std::promise<void> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_value();
+}
+
+void func6(std::promise<void> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_exception(std::make_exception_ptr('c'));
+}
+
+int main()
+{
+ {
+ typedef int T;
+ {
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.get() == 3);
+ assert(f.valid());
+ }
+ {
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func2, std::move(p)).detach();
+ try
+ {
+ assert(f.valid());
+ assert(f.get() == 3);
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 3);
+ }
+ assert(f.valid());
+ }
+ }
+ {
+ typedef int& T;
+ {
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func3, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.get() == 5);
+ assert(f.valid());
+ }
+ {
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func4, std::move(p)).detach();
+ try
+ {
+ assert(f.valid());
+ assert(f.get() == 3);
+ assert(false);
+ }
+ catch (double i)
+ {
+ assert(i == 3.5);
+ }
+ assert(f.valid());
+ }
+ }
+ {
+ typedef void T;
+ {
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func5, std::move(p)).detach();
+ assert(f.valid());
+ f.get();
+ assert(f.valid());
+ }
+ {
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func6, std::move(p)).detach();
+ try
+ {
+ assert(f.valid());
+ f.get();
+ assert(false);
+ }
+ catch (char i)
+ {
+ assert(i == 'c');
+ }
+ assert(f.valid());
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.shared_future/move_assign.pass.cpp b/test/std/thread/futures/futures.shared_future/move_assign.pass.cpp
new file mode 100644
index 000000000000..6b58f41c9085
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/move_assign.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// shared_future& operator=(shared_future&& rhs);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/futures/futures.shared_future/move_ctor.pass.cpp b/test/std/thread/futures/futures.shared_future/move_ctor.pass.cpp
new file mode 100644
index 000000000000..32b8fd77c672
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/move_ctor.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// shared_future(shared_future&& rhs);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.shared_future/wait.pass.cpp b/test/std/thread/futures/futures.shared_future/wait.pass.cpp
new file mode 100644
index 000000000000..4293fcab3564
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/wait.pass.cpp
@@ -0,0 +1,88 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// void wait() const;
+
+#include <future>
+#include <cassert>
+
+void func1(std::promise<int> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_value(3);
+}
+
+int j = 0;
+
+void func3(std::promise<int&> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func5(std::promise<void> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_value();
+}
+
+int main()
+{
+ typedef std::chrono::high_resolution_clock Clock;
+ typedef std::chrono::duration<double, std::milli> ms;
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ assert(f.valid());
+ f.wait();
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func3, std::move(p)).detach();
+ assert(f.valid());
+ f.wait();
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func5, std::move(p)).detach();
+ assert(f.valid());
+ f.wait();
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+}
diff --git a/test/std/thread/futures/futures.shared_future/wait_for.pass.cpp b/test/std/thread/futures/futures.shared_future/wait_for.pass.cpp
new file mode 100644
index 000000000000..e5a4754e38ad
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/wait_for.pass.cpp
@@ -0,0 +1,97 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// template <class Rep, class Period>
+// future_status
+// wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+
+#include <future>
+#include <cassert>
+
+typedef std::chrono::milliseconds ms;
+
+void func1(std::promise<int> p)
+{
+ std::this_thread::sleep_for(ms(500));
+ p.set_value(3);
+}
+
+int j = 0;
+
+void func3(std::promise<int&> p)
+{
+ std::this_thread::sleep_for(ms(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func5(std::promise<void> p)
+{
+ std::this_thread::sleep_for(ms(500));
+ p.set_value();
+}
+
+int main()
+{
+ typedef std::chrono::high_resolution_clock Clock;
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::timeout);
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func3, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::timeout);
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func5, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::timeout);
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+}
diff --git a/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp b/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp
new file mode 100644
index 000000000000..6a6aeba7759e
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp
@@ -0,0 +1,129 @@
+ //===----------------------------------------------------------------------===//
+ //
+ // 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: libcpp-has-no-threads
+
+ // <future>
+
+ // class shared_future<R>
+
+ // template <class Clock, class Duration>
+ // future_status
+ // wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+
+ #include <future>
+ #include <atomic>
+ #include <cassert>
+
+ enum class WorkerThreadState { Uninitialized, AllowedToRun, Exiting };
+ typedef std::chrono::milliseconds ms;
+
+ std::atomic<WorkerThreadState> thread_state(WorkerThreadState::Uninitialized);
+
+ void set_worker_thread_state(WorkerThreadState state)
+ {
+ thread_state.store(state, std::memory_order_relaxed);
+ }
+
+ void wait_for_worker_thread_state(WorkerThreadState state)
+ {
+ while (thread_state.load(std::memory_order_relaxed) != state);
+ }
+
+ void func1(std::promise<int> p)
+ {
+ wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+ p.set_value(3);
+ set_worker_thread_state(WorkerThreadState::Exiting);
+ }
+
+ int j = 0;
+
+ void func3(std::promise<int&> p)
+ {
+ wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+ j = 5;
+ p.set_value(j);
+ set_worker_thread_state(WorkerThreadState::Exiting);
+ }
+
+ void func5(std::promise<void> p)
+ {
+ wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+ p.set_value();
+ set_worker_thread_state(WorkerThreadState::Exiting);
+ }
+
+ int main()
+ {
+ typedef std::chrono::high_resolution_clock Clock;
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+ assert(f.valid());
+
+ // allow the worker thread to produce the result and wait until the worker is done
+ set_worker_thread_state(WorkerThreadState::AllowedToRun);
+ wait_for_worker_thread_state(WorkerThreadState::Exiting);
+
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func3, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+ assert(f.valid());
+
+ // allow the worker thread to produce the result and wait until the worker is done
+ set_worker_thread_state(WorkerThreadState::AllowedToRun);
+ wait_for_worker_thread_state(WorkerThreadState::Exiting);
+
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func5, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+ assert(f.valid());
+
+ // allow the worker thread to produce the result and wait until the worker is done
+ set_worker_thread_state(WorkerThreadState::AllowedToRun);
+ wait_for_worker_thread_state(WorkerThreadState::Exiting);
+
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ }
diff --git a/test/std/thread/futures/futures.state/nothing_to_do.pass.cpp b/test/std/thread/futures/futures.state/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..9a59227abdd9
--- /dev/null
+++ b/test/std/thread/futures/futures.state/nothing_to_do.pass.cpp
@@ -0,0 +1,13 @@
+// -*- 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp
new file mode 100644
index 000000000000..70ea0ad31fed
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// packaged_task& operator=(packaged_task&) = delete;
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p0(A(5));
+ std::packaged_task<double(int, char)> p;
+ p = p0;
+ assert(!p0.valid());
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p0;
+ std::packaged_task<double(int, char)> p;
+ p = p0;
+ assert(!p0.valid());
+ assert(!p.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp
new file mode 100644
index 000000000000..18786f4eb7a2
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// packaged_task& operator=(packaged_task&& other);
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p0(A(5));
+ std::packaged_task<double(int, char)> p;
+ p = std::move(p0);
+ assert(!p0.valid());
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p0;
+ std::packaged_task<double(int, char)> p;
+ p = std::move(p0);
+ assert(!p0.valid());
+ assert(!p.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp
new file mode 100644
index 000000000000..45048b747f7a
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+// template <class F>
+// packaged_task(F&& f);
+// These constructors shall not participate in overload resolution if
+// decay<F>::type is the same type as std::packaged_task<R(ArgTypes...)>.
+
+#include <future>
+#include <cassert>
+
+struct A {};
+typedef std::packaged_task<A(int, char)> PT;
+typedef volatile std::packaged_task<A(int, char)> VPT;
+
+
+int main()
+{
+ PT p { VPT{} };
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp
new file mode 100644
index 000000000000..e4df4ec225e7
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+// template <class F, class Allocator>
+// packaged_task(allocator_arg_t, const Allocator& a, F&& f);
+// These constructors shall not participate in overload resolution if
+// decay<F>::type is the same type as std::packaged_task<R(ArgTypes...)>.
+
+#include <future>
+#include <cassert>
+
+#include "../../test_allocator.h"
+
+struct A {};
+typedef std::packaged_task<A(int, char)> PT;
+typedef volatile std::packaged_task<A(int, char)> VPT;
+
+int main()
+{
+ PT p { std::allocator_arg_t{}, test_allocator<A>{}, VPT {}};
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp
new file mode 100644
index 000000000000..9884c49a6dc7
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// packaged_task(packaged_task&) = delete;
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p0(A(5));
+ std::packaged_task<double(int, char)> p(p0);
+ assert(!p0.valid());
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p0;
+ std::packaged_task<double(int, char)> p(p0);
+ assert(!p0.valid());
+ assert(!p.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp
new file mode 100644
index 000000000000..76904962a778
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// packaged_task();
+
+#include <future>
+#include <cassert>
+
+struct A {};
+
+int main()
+{
+ std::packaged_task<A(int, char)> p;
+ assert(!p.valid());
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp
new file mode 100644
index 000000000000..2eee2cbc2d50
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// template <class F>
+// explicit packaged_task(F&& f);
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ static int n_moves;
+ static int n_copies;
+
+ explicit A(long i) : data_(i) {}
+ A(A&& a) : data_(a.data_) {++n_moves; a.data_ = -1;}
+ A(const A& a) : data_(a.data_) {++n_copies;}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int A::n_moves = 0;
+int A::n_copies = 0;
+
+int func(int i) { return i; }
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ assert(A::n_copies == 0);
+ assert(A::n_moves > 0);
+ }
+ A::n_copies = 0;
+ A::n_copies = 0;
+ {
+ A a(5);
+ std::packaged_task<double(int, char)> p(a);
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ assert(A::n_copies > 0);
+ assert(A::n_moves > 0);
+ }
+ {
+ std::packaged_task<int(int)> p(&func);
+ assert(p.valid());
+ std::future<int> f = p.get_future();
+ p(4);
+ assert(f.get() == 4);
+ }
+ {
+ std::packaged_task<int(int)> p(func);
+ assert(p.valid());
+ std::future<int> f = p.get_future();
+ p(4);
+ assert(f.get() == 4);
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp
new file mode 100644
index 000000000000..3aac2b26bfc1
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp
@@ -0,0 +1,124 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// template <class F, class Allocator>
+// explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
+
+#include <future>
+#include <cassert>
+
+#include "../../test_allocator.h"
+#include "min_allocator.h"
+
+class A
+{
+ long data_;
+
+public:
+ static int n_moves;
+ static int n_copies;
+
+ explicit A(long i) : data_(i) {}
+ A(A&& a) : data_(a.data_) {++n_moves; a.data_ = -1;}
+ A(const A& a) : data_(a.data_) {++n_copies;}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int A::n_moves = 0;
+int A::n_copies = 0;
+
+int func(int i) { return i; }
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p(std::allocator_arg,
+ test_allocator<A>(), A(5));
+ assert(test_alloc_base::count > 0);
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ assert(A::n_copies == 0);
+ assert(A::n_moves > 0);
+ }
+ assert(test_alloc_base::count == 0);
+ A::n_copies = 0;
+ A::n_moves = 0;
+ {
+ A a(5);
+ std::packaged_task<double(int, char)> p(std::allocator_arg,
+ test_allocator<A>(), a);
+ assert(test_alloc_base::count > 0);
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ assert(A::n_copies > 0);
+ assert(A::n_moves > 0);
+ }
+ assert(test_alloc_base::count == 0);
+ A::n_copies = 0;
+ A::n_moves = 0;
+ {
+ A a(5);
+ std::packaged_task<int(int)> p(std::allocator_arg, test_allocator<A>(), &func);
+ assert(test_alloc_base::count > 0);
+ assert(p.valid());
+ std::future<int> f = p.get_future();
+ p(4);
+ assert(f.get() == 4);
+ }
+ assert(test_alloc_base::count == 0);
+ A::n_copies = 0;
+ A::n_moves = 0;
+ {
+ A a(5);
+ std::packaged_task<int(int)> p(std::allocator_arg, test_allocator<A>(), func);
+ assert(test_alloc_base::count > 0);
+ assert(p.valid());
+ std::future<int> f = p.get_future();
+ p(4);
+ assert(f.get() == 4);
+ }
+ assert(test_alloc_base::count == 0);
+ A::n_copies = 0;
+ A::n_moves = 0;
+ {
+ std::packaged_task<double(int, char)> p(std::allocator_arg,
+ bare_allocator<void>(), A(5));
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ assert(A::n_copies == 0);
+ assert(A::n_moves > 0);
+ }
+ A::n_copies = 0;
+ A::n_moves = 0;
+ {
+ std::packaged_task<double(int, char)> p(std::allocator_arg,
+ min_allocator<void>(), A(5));
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ assert(A::n_copies == 0);
+ assert(A::n_moves > 0);
+ }
+ A::n_copies = 0;
+ A::n_moves = 0;
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp
new file mode 100644
index 000000000000..88f072281750
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// packaged_task(packaged_task&& other);
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p0(A(5));
+ std::packaged_task<double(int, char)> p = std::move(p0);
+ assert(!p0.valid());
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p0;
+ std::packaged_task<double(int, char)> p = std::move(p0);
+ assert(!p0.valid());
+ assert(!p.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp
new file mode 100644
index 000000000000..e24232d1b227
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// ~packaged_task();
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+void func(std::packaged_task<double(int, char)> p)
+{
+}
+
+void func2(std::packaged_task<double(int, char)> p)
+{
+ p(3, 'a');
+}
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ std::thread(func, std::move(p)).detach();
+ try
+ {
+ double i = f.get();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::broken_promise));
+ }
+ }
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ std::thread(func2, std::move(p)).detach();
+ assert(f.get() == 105.0);
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp
new file mode 100644
index 000000000000..13b5db110668
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// future<R> get_future();
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ try
+ {
+ f = p.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::future_already_retrieved));
+ }
+ }
+ {
+ std::packaged_task<double(int, char)> p;
+ try
+ {
+ std::future<double> f = p.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp
new file mode 100644
index 000000000000..61a6a4f87965
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp
@@ -0,0 +1,106 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// void make_ready_at_thread_exit(ArgTypes... args);
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const
+ {
+ if (j == 'z')
+ throw A(6);
+ return data_ + i + j;
+ }
+};
+
+void func0(std::packaged_task<double(int, char)> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.make_ready_at_thread_exit(3, 'a');
+}
+
+void func1(std::packaged_task<double(int, char)> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.make_ready_at_thread_exit(3, 'z');
+}
+
+void func2(std::packaged_task<double(int, char)> p)
+{
+ p.make_ready_at_thread_exit(3, 'a');
+ try
+ {
+ p.make_ready_at_thread_exit(3, 'c');
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
+ }
+}
+
+void func3(std::packaged_task<double(int, char)> p)
+{
+ try
+ {
+ p.make_ready_at_thread_exit(3, 'a');
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+}
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ std::thread(func0, std::move(p)).detach();
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ try
+ {
+ f.get();
+ assert(false);
+ }
+ catch (const A& e)
+ {
+ assert(e(3, 'a') == 106);
+ }
+ }
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ std::thread(func2, std::move(p)).detach();
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p;
+ std::thread t(func3, std::move(p));
+ t.join();
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp
new file mode 100644
index 000000000000..2a09353b1e63
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp
@@ -0,0 +1,107 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// void operator()(ArgTypes... args);
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const
+ {
+ if (j == 'z')
+ throw A(6);
+ return data_ + i + j;
+ }
+};
+
+void func0(std::packaged_task<double(int, char)> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p(3, 'a');
+}
+
+void func1(std::packaged_task<double(int, char)> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p(3, 'z');
+}
+
+void func2(std::packaged_task<double(int, char)> p)
+{
+ p(3, 'a');
+ try
+ {
+ p(3, 'c');
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
+ }
+}
+
+void func3(std::packaged_task<double(int, char)> p)
+{
+ try
+ {
+ p(3, 'a');
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+}
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ std::thread(func0, std::move(p)).detach();
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ try
+ {
+ f.get();
+ assert(false);
+ }
+ catch (const A& e)
+ {
+ assert(e(3, 'a') == 106);
+ }
+ }
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ std::thread t(func2, std::move(p));
+ assert(f.get() == 105.0);
+ t.join();
+ }
+ {
+ std::packaged_task<double(int, char)> p;
+ std::thread t(func3, std::move(p));
+ t.join();
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp
new file mode 100644
index 000000000000..9d38d9b409c0
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// void reset();
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const
+ {
+ if (j == 'z')
+ throw A(6);
+ return data_ + i + j;
+ }
+};
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ p.reset();
+ p(4, 'a');
+ f = p.get_future();
+ assert(f.get() == 106.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p;
+ try
+ {
+ p.reset();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp
new file mode 100644
index 000000000000..33763bef0d0f
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// void swap(packaged_task& other);
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p0(A(5));
+ std::packaged_task<double(int, char)> p;
+ p.swap(p0);
+ assert(!p0.valid());
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p0;
+ std::packaged_task<double(int, char)> p;
+ p.swap(p0);
+ assert(!p0.valid());
+ assert(!p.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp
new file mode 100644
index 000000000000..668732b9b24a
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// template <class R, class... ArgTypes>
+// void
+// swap(packaged_task<R(ArgTypes...)>& x, packaged_task<R(ArgTypes...)>& y);
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p0(A(5));
+ std::packaged_task<double(int, char)> p;
+ swap(p, p0);
+ assert(!p0.valid());
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p0;
+ std::packaged_task<double(int, char)> p;
+ swap(p, p0);
+ assert(!p0.valid());
+ assert(!p.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp
new file mode 100644
index 000000000000..986f71e29a46
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// template <class Callable, class Alloc>
+// struct uses_allocator<packaged_task<Callable>, Alloc>
+// : true_type { };
+
+#include <future>
+#include "../../test_allocator.h"
+
+int main()
+{
+ static_assert((std::uses_allocator<std::packaged_task<double(int, char)>, test_allocator<int> >::value), "");
+}
diff --git a/test/std/thread/futures/futures.tas/types.pass.cpp b/test/std/thread/futures/futures.tas/types.pass.cpp
new file mode 100644
index 000000000000..dd1724ddbda5
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/types.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// template<class R, class... ArgTypes>
+// class packaged_task<R(ArgTypes...)>
+// {
+// public:
+// typedef R result_type;
+
+#include <future>
+#include <type_traits>
+
+struct A {};
+
+int main()
+{
+ static_assert((std::is_same<std::packaged_task<A(int, char)>::result_type, A>::value), "");
+}
diff --git a/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp b/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp
new file mode 100644
index 000000000000..ebdcbf98d996
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class future<R>
+
+// future& operator=(const future&) = delete;
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f;
+ f = f0;
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::future<T> f0;
+ std::future<T> f;
+ f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f;
+ f = f0;
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::future<T> f0;
+ std::future<T> f;
+ f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f;
+ f = f0;
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::future<T> f0;
+ std::future<T> f;
+ f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp b/test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp
new file mode 100644
index 000000000000..8d43294edc26
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class future<R>
+
+// future(const future&) = delete;
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f = f0;
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::future<T> f0;
+ std::future<T> f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f = f0;
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::future<T> f0;
+ std::future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f = f0;
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::future<T> f0;
+ std::future<T> f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.unique_future/default.pass.cpp b/test/std/thread/futures/futures.unique_future/default.pass.cpp
new file mode 100644
index 000000000000..84cb84650dcd
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/default.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class future<R>
+
+// future();
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ std::future<int> f;
+ assert(!f.valid());
+ }
+ {
+ std::future<int&> f;
+ assert(!f.valid());
+ }
+ {
+ std::future<void> f;
+ assert(!f.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.unique_future/dtor.pass.cpp b/test/std/thread/futures/futures.unique_future/dtor.pass.cpp
new file mode 100644
index 000000000000..5e9697bb939b
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/dtor.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class future<R>
+
+// ~future();
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+ assert(test_alloc_base::count == 0);
+ {
+ typedef int T;
+ std::future<T> f;
+ {
+ std::promise<T> p(std::allocator_arg, test_allocator<T>());
+ assert(test_alloc_base::count == 1);
+ f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ typedef int& T;
+ std::future<T> f;
+ {
+ std::promise<T> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 1);
+ f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ typedef void T;
+ std::future<T> f;
+ {
+ std::promise<T> p(std::allocator_arg, test_allocator<T>());
+ assert(test_alloc_base::count == 1);
+ f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 0);
+}
diff --git a/test/std/thread/futures/futures.unique_future/get.pass.cpp b/test/std/thread/futures/futures.unique_future/get.pass.cpp
new file mode 100644
index 000000000000..758e38a7dae9
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/get.pass.cpp
@@ -0,0 +1,145 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class future<R>
+
+// R future::get();
+// R& future<R&>::get();
+// void future<void>::get();
+
+#include <future>
+#include <cassert>
+
+void func1(std::promise<int> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_value(3);
+}
+
+void func2(std::promise<int> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_exception(std::make_exception_ptr(3));
+}
+
+int j = 0;
+
+void func3(std::promise<int&> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func4(std::promise<int&> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_exception(std::make_exception_ptr(3.5));
+}
+
+void func5(std::promise<void> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_value();
+}
+
+void func6(std::promise<void> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_exception(std::make_exception_ptr('c'));
+}
+
+int main()
+{
+ {
+ typedef int T;
+ {
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.get() == 3);
+ assert(!f.valid());
+ }
+ {
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func2, std::move(p)).detach();
+ try
+ {
+ assert(f.valid());
+ assert(f.get() == 3);
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 3);
+ }
+ assert(!f.valid());
+ }
+ }
+ {
+ typedef int& T;
+ {
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func3, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.get() == 5);
+ assert(!f.valid());
+ }
+ {
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func4, std::move(p)).detach();
+ try
+ {
+ assert(f.valid());
+ assert(f.get() == 3);
+ assert(false);
+ }
+ catch (double i)
+ {
+ assert(i == 3.5);
+ }
+ assert(!f.valid());
+ }
+ }
+ {
+ typedef void T;
+ {
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func5, std::move(p)).detach();
+ assert(f.valid());
+ f.get();
+ assert(!f.valid());
+ }
+ {
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func6, std::move(p)).detach();
+ try
+ {
+ assert(f.valid());
+ f.get();
+ assert(false);
+ }
+ catch (char i)
+ {
+ assert(i == 'c');
+ }
+ assert(!f.valid());
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.unique_future/move_assign.pass.cpp b/test/std/thread/futures/futures.unique_future/move_assign.pass.cpp
new file mode 100644
index 000000000000..8d38b81f0cda
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/move_assign.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class future<R>
+
+// future& operator=(future&& rhs);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::future<T> f0;
+ std::future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::future<T> f0;
+ std::future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::future<T> f0;
+ std::future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/futures/futures.unique_future/move_ctor.pass.cpp b/test/std/thread/futures/futures.unique_future/move_ctor.pass.cpp
new file mode 100644
index 000000000000..e12c920886fa
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/move_ctor.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class future<R>
+
+// future(future&& rhs);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::future<T> f0;
+ std::future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::future<T> f0;
+ std::future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::future<T> f0;
+ std::future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/futures/futures.unique_future/share.pass.cpp b/test/std/thread/futures/futures.unique_future/share.pass.cpp
new file mode 100644
index 000000000000..794b5ce38feb
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/share.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class future<R>
+
+// shared_future<R> share() &&;
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::shared_future<T> f = std::move(f0.share());
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::future<T> f0;
+ std::shared_future<T> f = std::move(f0.share());
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::shared_future<T> f = std::move(f0.share());
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::future<T> f0;
+ std::shared_future<T> f = std::move(f0.share());
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::shared_future<T> f = std::move(f0.share());
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::future<T> f0;
+ std::shared_future<T> f = std::move(f0.share());
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.unique_future/wait.pass.cpp b/test/std/thread/futures/futures.unique_future/wait.pass.cpp
new file mode 100644
index 000000000000..e10d37cf8064
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/wait.pass.cpp
@@ -0,0 +1,88 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class future<R>
+
+// void wait() const;
+
+#include <future>
+#include <cassert>
+
+void func1(std::promise<int> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_value(3);
+}
+
+int j = 0;
+
+void func3(std::promise<int&> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func5(std::promise<void> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_value();
+}
+
+int main()
+{
+ typedef std::chrono::high_resolution_clock Clock;
+ typedef std::chrono::duration<double, std::milli> ms;
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ assert(f.valid());
+ f.wait();
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func3, std::move(p)).detach();
+ assert(f.valid());
+ f.wait();
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func5, std::move(p)).detach();
+ assert(f.valid());
+ f.wait();
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+}
diff --git a/test/std/thread/futures/futures.unique_future/wait_for.pass.cpp b/test/std/thread/futures/futures.unique_future/wait_for.pass.cpp
new file mode 100644
index 000000000000..0a381d9ca2f0
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/wait_for.pass.cpp
@@ -0,0 +1,97 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+// class future<R>
+
+// template <class Rep, class Period>
+// future_status
+// wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+
+#include <future>
+#include <cassert>
+
+typedef std::chrono::milliseconds ms;
+
+void func1(std::promise<int> p)
+{
+ std::this_thread::sleep_for(ms(500));
+ p.set_value(3);
+}
+
+int j = 0;
+
+void func3(std::promise<int&> p)
+{
+ std::this_thread::sleep_for(ms(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func5(std::promise<void> p)
+{
+ std::this_thread::sleep_for(ms(500));
+ p.set_value();
+}
+
+int main()
+{
+ typedef std::chrono::high_resolution_clock Clock;
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::timeout);
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(50));
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func3, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::timeout);
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(50));
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func5, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::timeout);
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(50));
+ }
+}
diff --git a/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp b/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp
new file mode 100644
index 000000000000..d5865b9b9dcf
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp
@@ -0,0 +1,129 @@
+ //===----------------------------------------------------------------------===//
+ //
+ // 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: libcpp-has-no-threads
+
+ // <future>
+
+ // class future<R>
+
+ // template <class Clock, class Duration>
+ // future_status
+ // wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+
+ #include <future>
+ #include <atomic>
+ #include <cassert>
+
+ enum class WorkerThreadState { Uninitialized, AllowedToRun, Exiting };
+ typedef std::chrono::milliseconds ms;
+
+ std::atomic<WorkerThreadState> thread_state(WorkerThreadState::Uninitialized);
+
+ void set_worker_thread_state(WorkerThreadState state)
+ {
+ thread_state.store(state, std::memory_order_relaxed);
+ }
+
+ void wait_for_worker_thread_state(WorkerThreadState state)
+ {
+ while (thread_state.load(std::memory_order_relaxed) != state);
+ }
+
+ void func1(std::promise<int> p)
+ {
+ wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+ p.set_value(3);
+ set_worker_thread_state(WorkerThreadState::Exiting);
+ }
+
+ int j = 0;
+
+ void func3(std::promise<int&> p)
+ {
+ wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+ j = 5;
+ p.set_value(j);
+ set_worker_thread_state(WorkerThreadState::Exiting);
+ }
+
+ void func5(std::promise<void> p)
+ {
+ wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+ p.set_value();
+ set_worker_thread_state(WorkerThreadState::Exiting);
+ }
+
+ int main()
+ {
+ typedef std::chrono::high_resolution_clock Clock;
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+ assert(f.valid());
+
+ // allow the worker thread to produce the result and wait until the worker is done
+ set_worker_thread_state(WorkerThreadState::AllowedToRun);
+ wait_for_worker_thread_state(WorkerThreadState::Exiting);
+
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func3, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+ assert(f.valid());
+
+ // allow the worker thread to produce the result and wait until the worker is done
+ set_worker_thread_state(WorkerThreadState::AllowedToRun);
+ wait_for_worker_thread_state(WorkerThreadState::Exiting);
+
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func5, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+ assert(f.valid());
+
+ // allow the worker thread to produce the result and wait until the worker is done
+ set_worker_thread_state(WorkerThreadState::AllowedToRun);
+ wait_for_worker_thread_state(WorkerThreadState::Exiting);
+
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ }
diff --git a/test/std/thread/futures/test_allocator.h b/test/std/thread/futures/test_allocator.h
new file mode 100644
index 000000000000..50072909fa4e
--- /dev/null
+++ b/test/std/thread/futures/test_allocator.h
@@ -0,0 +1,158 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TEST_ALLOCATOR_H
+#define TEST_ALLOCATOR_H
+
+#include <cstddef>
+#include <type_traits>
+#include <utility>
+#include <cstdlib>
+#include <new>
+#include <climits>
+
+class test_alloc_base
+{
+public:
+ static int count;
+public:
+ static int throw_after;
+};
+
+int test_alloc_base::count = 0;
+int test_alloc_base::throw_after = INT_MAX;
+
+template <class T>
+class test_allocator
+ : public test_alloc_base
+{
+ int data_;
+
+ template <class U> friend class test_allocator;
+public:
+
+ typedef unsigned size_type;
+ typedef int difference_type;
+ typedef T value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef typename std::add_lvalue_reference<value_type>::type reference;
+ typedef typename std::add_lvalue_reference<const value_type>::type const_reference;
+
+ template <class U> struct rebind {typedef test_allocator<U> other;};
+
+ test_allocator() throw() : data_(-1) {}
+ explicit test_allocator(int i) throw() : data_(i) {}
+ test_allocator(const test_allocator& a) throw()
+ : data_(a.data_) {}
+ template <class U> test_allocator(const test_allocator<U>& a) throw()
+ : data_(a.data_) {}
+ ~test_allocator() throw() {data_ = 0;}
+ pointer address(reference x) const {return &x;}
+ const_pointer address(const_reference x) const {return &x;}
+ pointer allocate(size_type n, const void* = 0)
+ {
+ if (count >= throw_after) {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ throw std::bad_alloc();
+#else
+ std::terminate();
+#endif
+ }
+ ++count;
+ return (pointer)std::malloc(n * sizeof(T));
+ }
+ void deallocate(pointer p, size_type n)
+ {--count; std::free(p);}
+ size_type max_size() const throw()
+ {return UINT_MAX / sizeof(T);}
+ void construct(pointer p, const T& val)
+ {::new(p) T(val);}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ void construct(pointer p, T&& val)
+ {::new(p) T(std::move(val));}
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ void destroy(pointer p) {p->~T();}
+
+ friend bool operator==(const test_allocator& x, const test_allocator& y)
+ {return x.data_ == y.data_;}
+ friend bool operator!=(const test_allocator& x, const test_allocator& y)
+ {return !(x == y);}
+};
+
+template <>
+class test_allocator<void>
+ : public test_alloc_base
+{
+ int data_;
+
+ template <class U> friend class test_allocator;
+public:
+
+ typedef unsigned size_type;
+ typedef int difference_type;
+ typedef void value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+
+ template <class U> struct rebind {typedef test_allocator<U> other;};
+
+ test_allocator() throw() : data_(-1) {}
+ explicit test_allocator(int i) throw() : data_(i) {}
+ test_allocator(const test_allocator& a) throw()
+ : data_(a.data_) {}
+ template <class U> test_allocator(const test_allocator<U>& a) throw()
+ : data_(a.data_) {}
+ ~test_allocator() throw() {data_ = 0;}
+
+ friend bool operator==(const test_allocator& x, const test_allocator& y)
+ {return x.data_ == y.data_;}
+ friend bool operator!=(const test_allocator& x, const test_allocator& y)
+ {return !(x == y);}
+};
+
+template <class T>
+class other_allocator
+{
+ int data_;
+
+ template <class U> friend class other_allocator;
+
+public:
+ typedef T value_type;
+
+ other_allocator() : data_(-1) {}
+ explicit other_allocator(int i) : data_(i) {}
+ template <class U> other_allocator(const other_allocator<U>& a)
+ : data_(a.data_) {}
+ T* allocate(std::size_t n)
+ {return (T*)std::malloc(n * sizeof(T));}
+ void deallocate(T* p, std::size_t n)
+ {std::free(p);}
+
+ other_allocator select_on_container_copy_construction() const
+ {return other_allocator(-2);}
+
+ friend bool operator==(const other_allocator& x, const other_allocator& y)
+ {return x.data_ == y.data_;}
+ friend bool operator!=(const other_allocator& x, const other_allocator& y)
+ {return !(x == y);}
+
+ typedef std::true_type propagate_on_container_copy_assignment;
+ typedef std::true_type propagate_on_container_move_assignment;
+ typedef std::true_type propagate_on_container_swap;
+
+#ifdef _LIBCPP_HAS_NO_ADVANCED_SFINAE
+ std::size_t max_size() const
+ {return UINT_MAX / sizeof(T);}
+#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+
+};
+
+#endif // TEST_ALLOCATOR_H
diff --git a/test/std/thread/futures/version.pass.cpp b/test/std/thread/futures/version.pass.cpp
new file mode 100644
index 000000000000..6730a1477db7
--- /dev/null
+++ b/test/std/thread/futures/version.pass.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <future>
+
+#include <future>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main()
+{
+}
diff --git a/test/std/thread/macro.pass.cpp b/test/std/thread/macro.pass.cpp
new file mode 100644
index 000000000000..c1b1377d6cc3
--- /dev/null
+++ b/test/std/thread/macro.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// #define __STDCPP_THREADS__ __cplusplus
+
+#include <thread>
+
+int main()
+{
+#ifndef __STDCPP_THREADS__
+#error __STDCPP_THREADS__ is not defined
+#endif
+}
diff --git a/test/std/thread/thread.condition/cv_status.pass.cpp b/test/std/thread/thread.condition/cv_status.pass.cpp
new file mode 100644
index 000000000000..fe5fa05ad247
--- /dev/null
+++ b/test/std/thread/thread.condition/cv_status.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// enum class cv_status { no_timeout, timeout };
+
+#include <condition_variable>
+#include <cassert>
+
+int main()
+{
+ assert(static_cast<int>(std::cv_status::no_timeout) == 0);
+ assert(static_cast<int>(std::cv_status::timeout) == 1);
+}
diff --git a/test/std/thread/thread.condition/notify_all_at_thread_exit.pass.cpp b/test/std/thread/thread.condition/notify_all_at_thread_exit.pass.cpp
new file mode 100644
index 000000000000..2b8772f92ed2
--- /dev/null
+++ b/test/std/thread/thread.condition/notify_all_at_thread_exit.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// void
+// notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <chrono>
+#include <cassert>
+
+std::condition_variable cv;
+std::mutex mut;
+
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::high_resolution_clock Clock;
+
+void func()
+{
+ std::unique_lock<std::mutex> lk(mut);
+ std::notify_all_at_thread_exit(cv, std::move(lk));
+ std::this_thread::sleep_for(ms(300));
+}
+
+int main()
+{
+ std::unique_lock<std::mutex> lk(mut);
+ std::thread(func).detach();
+ Clock::time_point t0 = Clock::now();
+ cv.wait(lk);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 > ms(250));
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvar/assign.fail.cpp b/test/std/thread/thread.condition/thread.condition.condvar/assign.fail.cpp
new file mode 100644
index 000000000000..e88550c5b8ad
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvar/assign.fail.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <condition_variable>
+
+// class condition_variable;
+
+// condition_variable& operator=(const condition_variable&) = delete;
+
+#include <condition_variable>
+#include <cassert>
+
+int main()
+{
+ std::condition_variable cv0;
+ std::condition_variable cv1;
+ cv1 = cv0;
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvar/copy.fail.cpp b/test/std/thread/thread.condition/thread.condition.condvar/copy.fail.cpp
new file mode 100644
index 000000000000..24d6ee0e71d2
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvar/copy.fail.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <condition_variable>
+
+// class condition_variable;
+
+// condition_variable(const condition_variable&) = delete;
+
+#include <condition_variable>
+#include <cassert>
+
+int main()
+{
+ std::condition_variable cv0;
+ std::condition_variable cv1(cv0);
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvar/default.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/default.pass.cpp
new file mode 100644
index 000000000000..6f43564c3b3d
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvar/default.pass.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable;
+
+// condition_variable();
+
+#include <condition_variable>
+#include <cassert>
+
+int main()
+{
+ std::condition_variable cv;
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvar/destructor.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/destructor.pass.cpp
new file mode 100644
index 000000000000..437ed965b191
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvar/destructor.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable;
+
+// ~condition_variable();
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <cassert>
+
+std::condition_variable* cv;
+std::mutex m;
+typedef std::unique_lock<std::mutex> Lock;
+
+bool f_ready = false;
+bool g_ready = false;
+
+void f()
+{
+ Lock lk(m);
+ f_ready = true;
+ cv->notify_one();
+ delete cv;
+}
+
+void g()
+{
+ Lock lk(m);
+ g_ready = true;
+ cv->notify_one();
+ while (!f_ready)
+ cv->wait(lk);
+}
+
+int main()
+{
+ cv = new std::condition_variable;
+ std::thread th2(g);
+ Lock lk(m);
+ while (!g_ready)
+ cv->wait(lk);
+ lk.unlock();
+ std::thread th1(f);
+ th1.join();
+ th2.join();
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp
new file mode 100644
index 000000000000..bf28e01a0e86
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvar/native_handle.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable;
+
+// typedef pthread_cond_t* native_handle_type;
+// native_handle_type native_handle();
+
+#include <condition_variable>
+#include <cassert>
+
+int main()
+{
+ static_assert((std::is_same<std::condition_variable::native_handle_type,
+ pthread_cond_t*>::value), "");
+ std::condition_variable cv;
+ std::condition_variable::native_handle_type h = cv.native_handle();
+ assert(h != nullptr);
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp
new file mode 100644
index 000000000000..fd80ee99c968
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvar/notify_all.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable;
+
+// void notify_all();
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <cassert>
+
+std::condition_variable cv;
+std::mutex mut;
+
+int test0 = 0;
+int test1 = 0;
+int test2 = 0;
+
+void f1()
+{
+ std::unique_lock<std::mutex> lk(mut);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 == 1);
+ test1 = 2;
+}
+
+void f2()
+{
+ std::unique_lock<std::mutex> lk(mut);
+ assert(test2 == 0);
+ while (test2 == 0)
+ cv.wait(lk);
+ assert(test2 == 1);
+ test2 = 2;
+}
+
+int main()
+{
+ std::thread t1(f1);
+ std::thread t2(f2);
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ {
+ std::unique_lock<std::mutex>lk(mut);
+ test1 = 1;
+ test2 = 1;
+ }
+ cv.notify_all();
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ std::unique_lock<std::mutex>lk(mut);
+ }
+ t1.join();
+ t2.join();
+ assert(test1 == 2);
+ assert(test2 == 2);
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp
new file mode 100644
index 000000000000..6236a13df80e
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvar/notify_one.pass.cpp
@@ -0,0 +1,94 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable;
+
+// void notify_one();
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <cassert>
+
+std::condition_variable cv;
+std::mutex mut;
+
+int test0 = 0;
+int test1 = 0;
+int test2 = 0;
+
+void f1()
+{
+ std::unique_lock<std::mutex> lk(mut);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 == 1);
+ test1 = 2;
+}
+
+void f2()
+{
+ std::unique_lock<std::mutex> lk(mut);
+ assert(test2 == 0);
+ while (test2 == 0)
+ cv.wait(lk);
+ assert(test2 == 1);
+ test2 = 2;
+}
+
+int main()
+{
+ std::thread t1(f1);
+ std::thread t2(f2);
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ {
+ std::unique_lock<std::mutex>lk(mut);
+ test1 = 1;
+ test2 = 1;
+ }
+ cv.notify_one();
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ std::unique_lock<std::mutex>lk(mut);
+ }
+ if (test1 == 2)
+ {
+ t1.join();
+ test1 = 0;
+ }
+ else if (test2 == 2)
+ {
+ t2.join();
+ test2 = 0;
+ }
+ else
+ assert(false);
+ cv.notify_one();
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ std::unique_lock<std::mutex>lk(mut);
+ }
+ if (test1 == 2)
+ {
+ t1.join();
+ test1 = 0;
+ }
+ else if (test2 == 2)
+ {
+ t2.join();
+ test2 = 0;
+ }
+ else
+ assert(false);
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvar/wait.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/wait.pass.cpp
new file mode 100644
index 000000000000..236eecc919ad
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvar/wait.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable;
+
+// void wait(unique_lock<mutex>& lock);
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <cassert>
+
+std::condition_variable cv;
+std::mutex mut;
+
+int test1 = 0;
+int test2 = 0;
+
+void f()
+{
+ std::unique_lock<std::mutex> lk(mut);
+ assert(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ while (test2 == 0)
+ cv.wait(lk);
+ assert(test2 != 0);
+}
+
+int main()
+{
+ std::unique_lock<std::mutex>lk(mut);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp
new file mode 100644
index 000000000000..ca48eee19d27
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvar/wait_for.pass.cpp
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable;
+
+// template <class Rep, class Period>
+// cv_status
+// wait_for(unique_lock<mutex>& lock,
+// const chrono::duration<Rep, Period>& rel_time);
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <chrono>
+#include <cassert>
+
+std::condition_variable cv;
+std::mutex mut;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+void f()
+{
+ typedef std::chrono::system_clock Clock;
+ typedef std::chrono::milliseconds milliseconds;
+ std::unique_lock<std::mutex> lk(mut);
+ assert(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ Clock::time_point t0 = Clock::now();
+ while (test2 == 0 &&
+ cv.wait_for(lk, milliseconds(250)) == std::cv_status::no_timeout)
+ ;
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ assert(t1 - t0 < milliseconds(250));
+ assert(test2 != 0);
+ }
+ else
+ {
+ assert(t1 - t0 - milliseconds(250) < milliseconds(50));
+ assert(test2 == 0);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ std::unique_lock<std::mutex>lk(mut);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ std::unique_lock<std::mutex>lk(mut);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvar/wait_for_pred.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/wait_for_pred.pass.cpp
new file mode 100644
index 000000000000..0ee40d161b7b
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvar/wait_for_pred.pass.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable;
+
+// template <class Rep, class Period, class Predicate>
+// bool
+// wait_for(unique_lock<mutex>& lock,
+// const chrono::duration<Rep, Period>& rel_time,
+// Predicate pred);
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <chrono>
+#include <cassert>
+
+class Pred
+{
+ int& i_;
+public:
+ explicit Pred(int& i) : i_(i) {}
+
+ bool operator()() {return i_ != 0;}
+};
+
+std::condition_variable cv;
+std::mutex mut;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+void f()
+{
+ typedef std::chrono::system_clock Clock;
+ typedef std::chrono::milliseconds milliseconds;
+ std::unique_lock<std::mutex> lk(mut);
+ assert(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ Clock::time_point t0 = Clock::now();
+ bool r = cv.wait_for(lk, milliseconds(250), Pred(test2));
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ assert(t1 - t0 < milliseconds(250));
+ assert(test2 != 0);
+ }
+ else
+ {
+ assert(t1 - t0 - milliseconds(250) < milliseconds(50));
+ assert(test2 == 0);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ std::unique_lock<std::mutex>lk(mut);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ std::unique_lock<std::mutex>lk(mut);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvar/wait_pred.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/wait_pred.pass.cpp
new file mode 100644
index 000000000000..45e0b8124165
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvar/wait_pred.pass.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable;
+
+// template <class Predicate>
+// void wait(unique_lock<mutex>& lock, Predicate pred);
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <functional>
+#include <cassert>
+
+std::condition_variable cv;
+std::mutex mut;
+
+int test1 = 0;
+int test2 = 0;
+
+class Pred
+{
+ int& i_;
+public:
+ explicit Pred(int& i) : i_(i) {}
+
+ bool operator()() {return i_ != 0;}
+};
+
+void f()
+{
+ std::unique_lock<std::mutex> lk(mut);
+ assert(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ cv.wait(lk, Pred(test2));
+ assert(test2 != 0);
+}
+
+int main()
+{
+ std::unique_lock<std::mutex>lk(mut);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvar/wait_until.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/wait_until.pass.cpp
new file mode 100644
index 000000000000..d87a188e93d7
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvar/wait_until.pass.cpp
@@ -0,0 +1,102 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable;
+
+// template <class Clock, class Duration>
+// cv_status
+// wait_until(unique_lock<mutex>& lock,
+// const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <chrono>
+#include <cassert>
+
+struct Clock
+{
+ typedef std::chrono::milliseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef std::chrono::time_point<Clock> time_point;
+ static const bool is_steady = true;
+
+ static time_point now()
+ {
+ using namespace std::chrono;
+ return time_point(duration_cast<duration>(
+ steady_clock::now().time_since_epoch()
+ ));
+ }
+};
+
+std::condition_variable cv;
+std::mutex mut;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+void f()
+{
+ std::unique_lock<std::mutex> lk(mut);
+ assert(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ Clock::time_point t0 = Clock::now();
+ Clock::time_point t = t0 + Clock::duration(250);
+ while (test2 == 0 && cv.wait_until(lk, t) == std::cv_status::no_timeout)
+ ;
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ assert(t1 - t0 < Clock::duration(250));
+ assert(test2 != 0);
+ }
+ else
+ {
+ assert(t1 - t0 - Clock::duration(250) < Clock::duration(50));
+ assert(test2 == 0);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ std::unique_lock<std::mutex>lk(mut);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ std::unique_lock<std::mutex>lk(mut);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvar/wait_until_pred.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvar/wait_until_pred.pass.cpp
new file mode 100644
index 000000000000..90ffb1d0b29d
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvar/wait_until_pred.pass.cpp
@@ -0,0 +1,113 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable;
+
+// template <class Clock, class Duration, class Predicate>
+// bool
+// wait_until(unique_lock<mutex>& lock,
+// const chrono::time_point<Clock, Duration>& abs_time,
+// Predicate pred);
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <chrono>
+#include <cassert>
+
+struct Clock
+{
+ typedef std::chrono::milliseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef std::chrono::time_point<Clock> time_point;
+ static const bool is_steady = true;
+
+ static time_point now()
+ {
+ using namespace std::chrono;
+ return time_point(duration_cast<duration>(
+ steady_clock::now().time_since_epoch()
+ ));
+ }
+};
+
+class Pred
+{
+ int& i_;
+public:
+ explicit Pred(int& i) : i_(i) {}
+
+ bool operator()() {return i_ != 0;}
+};
+
+std::condition_variable cv;
+std::mutex mut;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+void f()
+{
+ std::unique_lock<std::mutex> lk(mut);
+ assert(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ Clock::time_point t0 = Clock::now();
+ Clock::time_point t = t0 + Clock::duration(250);
+ bool r = cv.wait_until(lk, t, Pred(test2));
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ assert(t1 - t0 < Clock::duration(250));
+ assert(test2 != 0);
+ assert(r);
+ }
+ else
+ {
+ assert(t1 - t0 - Clock::duration(250) < Clock::duration(50));
+ assert(test2 == 0);
+ assert(!r);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ std::unique_lock<std::mutex>lk(mut);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ std::unique_lock<std::mutex>lk(mut);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvarany/assign.fail.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/assign.fail.cpp
new file mode 100644
index 000000000000..0b8d8e965e63
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvarany/assign.fail.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <condition_variable>
+
+// class condition_variable_any;
+
+// condition_variable_any& operator=(const condition_variable_any&) = delete;
+
+#include <condition_variable>
+#include <cassert>
+
+int main()
+{
+ std::condition_variable_any cv0;
+ std::condition_variable_any cv1;
+ cv1 = cv0;
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvarany/copy.fail.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/copy.fail.cpp
new file mode 100644
index 000000000000..84902546d07d
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvarany/copy.fail.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <condition_variable>
+
+// class condition_variable_any;
+
+// condition_variable_any(const condition_variable_any&) = delete;
+
+#include <condition_variable>
+#include <cassert>
+
+int main()
+{
+ std::condition_variable_any cv0;
+ std::condition_variable_any cv1(cv0);
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvarany/default.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/default.pass.cpp
new file mode 100644
index 000000000000..210060a7461b
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvarany/default.pass.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable_any;
+
+// condition_variable_any();
+
+#include <condition_variable>
+#include <cassert>
+
+int main()
+{
+ std::condition_variable_any cv;
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvarany/destructor.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/destructor.pass.cpp
new file mode 100644
index 000000000000..6bdca7b010c2
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvarany/destructor.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable_any;
+
+// ~condition_variable_any();
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <cassert>
+
+std::condition_variable_any* cv;
+std::mutex m;
+
+bool f_ready = false;
+bool g_ready = false;
+
+void f()
+{
+ m.lock();
+ f_ready = true;
+ cv->notify_one();
+ delete cv;
+ m.unlock();
+}
+
+void g()
+{
+ m.lock();
+ g_ready = true;
+ cv->notify_one();
+ while (!f_ready)
+ cv->wait(m);
+ m.unlock();
+}
+
+int main()
+{
+ cv = new std::condition_variable_any;
+ std::thread th2(g);
+ m.lock();
+ while (!g_ready)
+ cv->wait(m);
+ m.unlock();
+ std::thread th1(f);
+ th1.join();
+ th2.join();
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvarany/notify_all.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/notify_all.pass.cpp
new file mode 100644
index 000000000000..27ead95682a4
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvarany/notify_all.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable_any;
+
+// void notify_all();
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <cassert>
+
+std::condition_variable_any cv;
+
+typedef std::timed_mutex L0;
+typedef std::unique_lock<L0> L1;
+
+L0 m0;
+
+int test0 = 0;
+int test1 = 0;
+int test2 = 0;
+
+void f1()
+{
+ L1 lk(m0);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 == 1);
+ test1 = 2;
+}
+
+void f2()
+{
+ L1 lk(m0);
+ assert(test2 == 0);
+ while (test2 == 0)
+ cv.wait(lk);
+ assert(test2 == 1);
+ test2 = 2;
+}
+
+int main()
+{
+ std::thread t1(f1);
+ std::thread t2(f2);
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ {
+ L1 lk(m0);
+ test1 = 1;
+ test2 = 1;
+ }
+ cv.notify_all();
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ L1 lk(m0);
+ }
+ t1.join();
+ t2.join();
+ assert(test1 == 2);
+ assert(test2 == 2);
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp
new file mode 100644
index 000000000000..98f6c432c977
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvarany/notify_one.pass.cpp
@@ -0,0 +1,98 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable_any;
+
+// void notify_one();
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <cassert>
+
+std::condition_variable_any cv;
+
+typedef std::timed_mutex L0;
+typedef std::unique_lock<L0> L1;
+
+L0 m0;
+
+int test0 = 0;
+int test1 = 0;
+int test2 = 0;
+
+void f1()
+{
+ L1 lk(m0);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 == 1);
+ test1 = 2;
+}
+
+void f2()
+{
+ L1 lk(m0);
+ assert(test2 == 0);
+ while (test2 == 0)
+ cv.wait(lk);
+ assert(test2 == 1);
+ test2 = 2;
+}
+
+int main()
+{
+ std::thread t1(f1);
+ std::thread t2(f2);
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ {
+ L1 lk(m0);
+ test1 = 1;
+ test2 = 1;
+ }
+ cv.notify_one();
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ L1 lk(m0);
+ }
+ if (test1 == 2)
+ {
+ t1.join();
+ test1 = 0;
+ }
+ else if (test2 == 2)
+ {
+ t2.join();
+ test2 = 0;
+ }
+ else
+ assert(false);
+ cv.notify_one();
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ L1 lk(m0);
+ }
+ if (test1 == 2)
+ {
+ t1.join();
+ test1 = 0;
+ }
+ else if (test2 == 2)
+ {
+ t2.join();
+ test2 = 0;
+ }
+ else
+ assert(false);
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvarany/wait.exception.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/wait.exception.pass.cpp
new file mode 100644
index 000000000000..522c61b02d17
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvarany/wait.exception.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+#include <thread>
+#include <condition_variable>
+#include <mutex>
+#include <chrono>
+#include <iostream>
+#include <cassert>
+
+void f1()
+{
+ std::exit(0);
+}
+
+struct Mutex
+{
+ unsigned state = 0;
+ Mutex() = default;
+ ~Mutex() = default;
+ Mutex(const Mutex&) = delete;
+ Mutex& operator=(const Mutex&) = delete;
+
+ void lock()
+ {
+ if (++state == 2)
+ throw 1; // this throw should end up calling terminate()
+ }
+
+ void unlock() {}
+};
+
+Mutex mut;
+std::condition_variable_any cv;
+
+void
+signal_me()
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ cv.notify_one();
+}
+
+int
+main()
+{
+ std::set_terminate(f1);
+ try
+ {
+ std::thread(signal_me).detach();
+ mut.lock();
+ cv.wait(mut);
+ }
+ catch (...) {}
+ assert(false);
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvarany/wait.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/wait.pass.cpp
new file mode 100644
index 000000000000..f5c8926e34b3
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvarany/wait.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable_any;
+
+// template <class Lock>
+// void wait(Lock& lock);
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <cassert>
+
+std::condition_variable_any cv;
+
+typedef std::timed_mutex L0;
+typedef std::unique_lock<L0> L1;
+
+L0 m0;
+
+int test1 = 0;
+int test2 = 0;
+
+void f()
+{
+ L1 lk(m0);
+ assert(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ while (test2 == 0)
+ cv.wait(lk);
+ assert(test2 != 0);
+}
+
+int main()
+{
+ L1 lk(m0);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.exception.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.exception.pass.cpp
new file mode 100644
index 000000000000..1906b5892506
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.exception.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+#include <thread>
+#include <condition_variable>
+#include <mutex>
+#include <chrono>
+#include <iostream>
+#include <cassert>
+
+void f1()
+{
+ std::exit(0);
+}
+
+struct Mutex
+{
+ unsigned state = 0;
+ Mutex() = default;
+ ~Mutex() = default;
+ Mutex(const Mutex&) = delete;
+ Mutex& operator=(const Mutex&) = delete;
+
+ void lock()
+ {
+ if (++state == 2)
+ throw 1; // this throw should end up calling terminate()
+ }
+
+ void unlock() {}
+};
+
+Mutex mut;
+std::condition_variable_any cv;
+
+void
+signal_me()
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ cv.notify_one();
+}
+
+int
+main()
+{
+ std::set_terminate(f1);
+ try
+ {
+ std::thread(signal_me).detach();
+ mut.lock();
+ cv.wait_for(mut, std::chrono::milliseconds(250));
+ }
+ catch (...) {}
+ assert(false);
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.pass.cpp
new file mode 100644
index 000000000000..a4b4ed991f29
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvarany/wait_for.pass.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable_any;
+
+// template <class Lock, class Rep, class Period>
+// cv_status
+// wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <chrono>
+#include <cassert>
+
+std::condition_variable_any cv;
+
+typedef std::timed_mutex L0;
+typedef std::unique_lock<L0> L1;
+
+L0 m0;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+void f()
+{
+ typedef std::chrono::system_clock Clock;
+ typedef std::chrono::milliseconds milliseconds;
+ L1 lk(m0);
+ assert(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ Clock::time_point t0 = Clock::now();
+ while (test2 == 0 &&
+ cv.wait_for(lk, milliseconds(250)) == std::cv_status::no_timeout)
+ ;
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ assert(t1 - t0 < milliseconds(250));
+ assert(test2 != 0);
+ }
+ else
+ {
+ assert(t1 - t0 - milliseconds(250) < milliseconds(50));
+ assert(test2 == 0);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ L1 lk(m0);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ L1 lk(m0);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvarany/wait_for_pred.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/wait_for_pred.pass.cpp
new file mode 100644
index 000000000000..b2403079275d
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvarany/wait_for_pred.pass.cpp
@@ -0,0 +1,98 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable_any;
+
+// template <class Lock, class Rep, class Period, class Predicate>
+// bool
+// wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time,
+// Predicate pred);
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <chrono>
+#include <cassert>
+
+class Pred
+{
+ int& i_;
+public:
+ explicit Pred(int& i) : i_(i) {}
+
+ bool operator()() {return i_ != 0;}
+};
+
+std::condition_variable_any cv;
+
+typedef std::timed_mutex L0;
+typedef std::unique_lock<L0> L1;
+
+L0 m0;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+void f()
+{
+ typedef std::chrono::system_clock Clock;
+ typedef std::chrono::milliseconds milliseconds;
+ L1 lk(m0);
+ assert(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ Clock::time_point t0 = Clock::now();
+ bool r = cv.wait_for(lk, milliseconds(250), Pred(test2));
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ assert(t1 - t0 < milliseconds(250));
+ assert(test2 != 0);
+ }
+ else
+ {
+ assert(t1 - t0 - milliseconds(250) < milliseconds(50));
+ assert(test2 == 0);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ L1 lk(m0);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ L1 lk(m0);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvarany/wait_pred.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/wait_pred.pass.cpp
new file mode 100644
index 000000000000..921ad69f145e
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvarany/wait_pred.pass.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable_any;
+
+// template <class Lock, class Predicate>
+// void wait(Lock& lock, Predicate pred);
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <functional>
+#include <cassert>
+
+std::condition_variable_any cv;
+
+typedef std::timed_mutex L0;
+typedef std::unique_lock<L0> L1;
+
+L0 m0;
+
+int test1 = 0;
+int test2 = 0;
+
+class Pred
+{
+ int& i_;
+public:
+ explicit Pred(int& i) : i_(i) {}
+
+ bool operator()() {return i_ != 0;}
+};
+
+void f()
+{
+ L1 lk(m0);
+ assert(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ cv.wait(lk, Pred(test2));
+ assert(test2 != 0);
+}
+
+int main()
+{
+ L1 lk(m0);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvarany/wait_until.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/wait_until.pass.cpp
new file mode 100644
index 000000000000..1994ebdfe609
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvarany/wait_until.pass.cpp
@@ -0,0 +1,105 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable_any;
+
+// template <class Lock, class Clock, class Duration>
+// cv_status
+// wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <chrono>
+#include <cassert>
+
+struct Clock
+{
+ typedef std::chrono::milliseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef std::chrono::time_point<Clock> time_point;
+ static const bool is_steady = true;
+
+ static time_point now()
+ {
+ using namespace std::chrono;
+ return time_point(duration_cast<duration>(
+ steady_clock::now().time_since_epoch()
+ ));
+ }
+};
+
+std::condition_variable_any cv;
+
+typedef std::timed_mutex L0;
+typedef std::unique_lock<L0> L1;
+
+L0 m0;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+void f()
+{
+ L1 lk(m0);
+ assert(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ Clock::time_point t0 = Clock::now();
+ Clock::time_point t = t0 + Clock::duration(250);
+ while (test2 == 0 && cv.wait_until(lk, t) == std::cv_status::no_timeout)
+ ;
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ assert(t1 - t0 < Clock::duration(250));
+ assert(test2 != 0);
+ }
+ else
+ {
+ assert(t1 - t0 - Clock::duration(250) < Clock::duration(50));
+ assert(test2 == 0);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ L1 lk(m0);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ L1 lk(m0);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+}
diff --git a/test/std/thread/thread.condition/thread.condition.condvarany/wait_until_pred.pass.cpp b/test/std/thread/thread.condition/thread.condition.condvarany/wait_until_pred.pass.cpp
new file mode 100644
index 000000000000..c0fea0355b9c
--- /dev/null
+++ b/test/std/thread/thread.condition/thread.condition.condvarany/wait_until_pred.pass.cpp
@@ -0,0 +1,117 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+// class condition_variable_any;
+
+// template <class Lock, class Duration, class Predicate>
+// bool
+// wait_until(Lock& lock,
+// const chrono::time_point<Clock, Duration>& abs_time,
+// Predicate pred);
+
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+#include <chrono>
+#include <cassert>
+
+struct Clock
+{
+ typedef std::chrono::milliseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef std::chrono::time_point<Clock> time_point;
+ static const bool is_steady = true;
+
+ static time_point now()
+ {
+ using namespace std::chrono;
+ return time_point(duration_cast<duration>(
+ steady_clock::now().time_since_epoch()
+ ));
+ }
+};
+
+class Pred
+{
+ int& i_;
+public:
+ explicit Pred(int& i) : i_(i) {}
+
+ bool operator()() {return i_ != 0;}
+};
+
+std::condition_variable_any cv;
+
+typedef std::timed_mutex L0;
+typedef std::unique_lock<L0> L1;
+
+L0 m0;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+void f()
+{
+ L1 lk(m0);
+ assert(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ Clock::time_point t0 = Clock::now();
+ Clock::time_point t = t0 + Clock::duration(250);
+ bool r = cv.wait_until(lk, t, Pred(test2));
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ assert(t1 - t0 < Clock::duration(250));
+ assert(test2 != 0);
+ assert(r);
+ }
+ else
+ {
+ assert(t1 - t0 - Clock::duration(250) < Clock::duration(50));
+ assert(test2 == 0);
+ assert(!r);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ L1 lk(m0);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ L1 lk(m0);
+ std::thread t(f);
+ assert(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ assert(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+}
diff --git a/test/std/thread/thread.condition/version.pass.cpp b/test/std/thread/thread.condition/version.pass.cpp
new file mode 100644
index 000000000000..12a775e83398
--- /dev/null
+++ b/test/std/thread/thread.condition/version.pass.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <condition_variable>
+
+#include <condition_variable>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.general/nothing_to_do.pass.cpp b/test/std/thread/thread.general/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..b58f5c55b643
--- /dev/null
+++ b/test/std/thread/thread.general/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.mutex/thread.lock.algorithm/lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock.algorithm/lock.pass.cpp
new file mode 100644
index 000000000000..f67ca2169825
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock.algorithm/lock.pass.cpp
@@ -0,0 +1,507 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class L1, class L2, class... L3>
+// void lock(L1&, L2&, L3&...);
+
+#include <mutex>
+#include <cassert>
+
+class L0
+{
+ bool locked_;
+
+public:
+ L0() : locked_(false) {}
+
+ void lock()
+ {
+ locked_ = true;
+ }
+
+ bool try_lock()
+ {
+ locked_ = true;
+ return locked_;
+ }
+
+ void unlock() {locked_ = false;}
+
+ bool locked() const {return locked_;}
+};
+
+class L1
+{
+ bool locked_;
+
+public:
+ L1() : locked_(false) {}
+
+ void lock()
+ {
+ locked_ = true;
+ }
+
+ bool try_lock()
+ {
+ locked_ = false;
+ return locked_;
+ }
+
+ void unlock() {locked_ = false;}
+
+ bool locked() const {return locked_;}
+};
+
+class L2
+{
+ bool locked_;
+
+public:
+ L2() : locked_(false) {}
+
+ void lock()
+ {
+ throw 1;
+ }
+
+ bool try_lock()
+ {
+ throw 1;
+ return locked_;
+ }
+
+ void unlock() {locked_ = false;}
+
+ bool locked() const {return locked_;}
+};
+
+int main()
+{
+ {
+ L0 l0;
+ L0 l1;
+ std::lock(l0, l1);
+ assert(l0.locked());
+ assert(l1.locked());
+ }
+ {
+ L0 l0;
+ L1 l1;
+ std::lock(l0, l1);
+ assert(l0.locked());
+ assert(l1.locked());
+ }
+ {
+ L1 l0;
+ L0 l1;
+ std::lock(l0, l1);
+ assert(l0.locked());
+ assert(l1.locked());
+ }
+ {
+ L0 l0;
+ L2 l1;
+ try
+ {
+ std::lock(l0, l1);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ }
+ }
+ {
+ L2 l0;
+ L0 l1;
+ try
+ {
+ std::lock(l0, l1);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ }
+ }
+ {
+ L1 l0;
+ L2 l1;
+ try
+ {
+ std::lock(l0, l1);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ }
+ }
+ {
+ L2 l0;
+ L1 l1;
+ try
+ {
+ std::lock(l0, l1);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ }
+ }
+ {
+ L2 l0;
+ L2 l1;
+ try
+ {
+ std::lock(l0, l1);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ }
+ }
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+ {
+ L0 l0;
+ L0 l1;
+ L0 l2;
+ std::lock(l0, l1, l2);
+ assert(l0.locked());
+ assert(l1.locked());
+ assert(l2.locked());
+ }
+ {
+ L2 l0;
+ L2 l1;
+ L2 l2;
+ try
+ {
+ std::lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L0 l0;
+ L0 l1;
+ L1 l2;
+ std::lock(l0, l1, l2);
+ assert(l0.locked());
+ assert(l1.locked());
+ assert(l2.locked());
+ }
+ {
+ L0 l0;
+ L1 l1;
+ L0 l2;
+ std::lock(l0, l1, l2);
+ assert(l0.locked());
+ assert(l1.locked());
+ assert(l2.locked());
+ }
+ {
+ L1 l0;
+ L0 l1;
+ L0 l2;
+ std::lock(l0, l1, l2);
+ assert(l0.locked());
+ assert(l1.locked());
+ assert(l2.locked());
+ }
+ {
+ L0 l0;
+ L0 l1;
+ L2 l2;
+ try
+ {
+ std::lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L0 l0;
+ L2 l1;
+ L0 l2;
+ try
+ {
+ std::lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L2 l0;
+ L0 l1;
+ L0 l2;
+ try
+ {
+ std::lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L2 l0;
+ L2 l1;
+ L0 l2;
+ try
+ {
+ std::lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L2 l0;
+ L0 l1;
+ L2 l2;
+ try
+ {
+ std::lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L0 l0;
+ L2 l1;
+ L2 l2;
+ try
+ {
+ std::lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L2 l0;
+ L2 l1;
+ L1 l2;
+ try
+ {
+ std::lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L2 l0;
+ L1 l1;
+ L2 l2;
+ try
+ {
+ std::lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L1 l0;
+ L2 l1;
+ L2 l2;
+ try
+ {
+ std::lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L0 l0;
+ L0 l1;
+ L0 l2;
+ L0 l3;
+ std::lock(l0, l1, l2, l3);
+ assert(l0.locked());
+ assert(l1.locked());
+ assert(l2.locked());
+ assert(l3.locked());
+ }
+ {
+ L0 l0;
+ L0 l1;
+ L0 l2;
+ L1 l3;
+ std::lock(l0, l1, l2, l3);
+ assert(l0.locked());
+ assert(l1.locked());
+ assert(l2.locked());
+ assert(l3.locked());
+ }
+ {
+ L0 l0;
+ L0 l1;
+ L1 l2;
+ L0 l3;
+ std::lock(l0, l1, l2, l3);
+ assert(l0.locked());
+ assert(l1.locked());
+ assert(l2.locked());
+ assert(l3.locked());
+ }
+ {
+ L0 l0;
+ L1 l1;
+ L0 l2;
+ L0 l3;
+ std::lock(l0, l1, l2, l3);
+ assert(l0.locked());
+ assert(l1.locked());
+ assert(l2.locked());
+ assert(l3.locked());
+ }
+ {
+ L1 l0;
+ L0 l1;
+ L0 l2;
+ L0 l3;
+ std::lock(l0, l1, l2, l3);
+ assert(l0.locked());
+ assert(l1.locked());
+ assert(l2.locked());
+ assert(l3.locked());
+ }
+ {
+ L0 l0;
+ L0 l1;
+ L0 l2;
+ L2 l3;
+ try
+ {
+ std::lock(l0, l1, l2, l3);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ assert(!l3.locked());
+ }
+ }
+ {
+ L0 l0;
+ L0 l1;
+ L2 l2;
+ L0 l3;
+ try
+ {
+ std::lock(l0, l1, l2, l3);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ assert(!l3.locked());
+ }
+ }
+ {
+ L0 l0;
+ L2 l1;
+ L0 l2;
+ L0 l3;
+ try
+ {
+ std::lock(l0, l1, l2, l3);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ assert(!l3.locked());
+ }
+ }
+ {
+ L2 l0;
+ L0 l1;
+ L0 l2;
+ L0 l3;
+ try
+ {
+ std::lock(l0, l1, l2, l3);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ assert(!l3.locked());
+ }
+ }
+#endif // _LIBCPP_HAS_NO_VARIADICS
+}
diff --git a/test/std/thread/thread.mutex/thread.lock.algorithm/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock.algorithm/try_lock.pass.cpp
new file mode 100644
index 000000000000..f0c54b71883f
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock.algorithm/try_lock.pass.cpp
@@ -0,0 +1,516 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class L1, class L2, class... L3>
+// int try_lock(L1&, L2&, L3&...);
+
+#include <mutex>
+#include <cassert>
+
+class L0
+{
+ bool locked_;
+
+public:
+ L0() : locked_(false) {}
+
+ bool try_lock()
+ {
+ locked_ = true;
+ return locked_;
+ }
+
+ void unlock() {locked_ = false;}
+
+ bool locked() const {return locked_;}
+};
+
+class L1
+{
+ bool locked_;
+
+public:
+ L1() : locked_(false) {}
+
+ bool try_lock()
+ {
+ locked_ = false;
+ return locked_;
+ }
+
+ void unlock() {locked_ = false;}
+
+ bool locked() const {return locked_;}
+};
+
+class L2
+{
+ bool locked_;
+
+public:
+ L2() : locked_(false) {}
+
+ bool try_lock()
+ {
+ throw 1;
+ return locked_;
+ }
+
+ void unlock() {locked_ = false;}
+
+ bool locked() const {return locked_;}
+};
+
+int main()
+{
+ {
+ L0 l0;
+ L0 l1;
+ assert(std::try_lock(l0, l1) == -1);
+ assert(l0.locked());
+ assert(l1.locked());
+ }
+ {
+ L0 l0;
+ L1 l1;
+ assert(std::try_lock(l0, l1) == 1);
+ assert(!l0.locked());
+ assert(!l1.locked());
+ }
+ {
+ L1 l0;
+ L0 l1;
+ assert(std::try_lock(l0, l1) == 0);
+ assert(!l0.locked());
+ assert(!l1.locked());
+ }
+ {
+ L0 l0;
+ L2 l1;
+ try
+ {
+ std::try_lock(l0, l1);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ }
+ }
+ {
+ L2 l0;
+ L0 l1;
+ try
+ {
+ std::try_lock(l0, l1);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ }
+ }
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+ {
+ L0 l0;
+ L0 l1;
+ L0 l2;
+ assert(std::try_lock(l0, l1, l2) == -1);
+ assert(l0.locked());
+ assert(l1.locked());
+ assert(l2.locked());
+ }
+ {
+ L1 l0;
+ L1 l1;
+ L1 l2;
+ assert(std::try_lock(l0, l1, l2) == 0);
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ {
+ L2 l0;
+ L2 l1;
+ L2 l2;
+ try
+ {
+ std::try_lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L0 l0;
+ L1 l1;
+ L2 l2;
+ assert(std::try_lock(l0, l1, l2) == 1);
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ {
+ L0 l0;
+ L0 l1;
+ L1 l2;
+ assert(std::try_lock(l0, l1, l2) == 2);
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ {
+ L0 l0;
+ L1 l1;
+ L0 l2;
+ assert(std::try_lock(l0, l1, l2) == 1);
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ {
+ L1 l0;
+ L0 l1;
+ L0 l2;
+ assert(std::try_lock(l0, l1, l2) == 0);
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ {
+ L0 l0;
+ L0 l1;
+ L2 l2;
+ try
+ {
+ std::try_lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L0 l0;
+ L2 l1;
+ L0 l2;
+ try
+ {
+ std::try_lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L2 l0;
+ L0 l1;
+ L0 l2;
+ try
+ {
+ std::try_lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L1 l0;
+ L1 l1;
+ L0 l2;
+ assert(std::try_lock(l0, l1, l2) == 0);
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ {
+ L1 l0;
+ L0 l1;
+ L1 l2;
+ assert(std::try_lock(l0, l1, l2) == 0);
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ {
+ L0 l0;
+ L1 l1;
+ L1 l2;
+ assert(std::try_lock(l0, l1, l2) == 1);
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ {
+ L1 l0;
+ L1 l1;
+ L2 l2;
+ assert(std::try_lock(l0, l1, l2) == 0);
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ {
+ L1 l0;
+ L2 l1;
+ L1 l2;
+ assert(std::try_lock(l0, l1, l2) == 0);
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ {
+ L2 l0;
+ L1 l1;
+ L1 l2;
+ try
+ {
+ std::try_lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L2 l0;
+ L2 l1;
+ L0 l2;
+ try
+ {
+ std::try_lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L2 l0;
+ L0 l1;
+ L2 l2;
+ try
+ {
+ std::try_lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L0 l0;
+ L2 l1;
+ L2 l2;
+ try
+ {
+ std::try_lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L2 l0;
+ L2 l1;
+ L1 l2;
+ try
+ {
+ std::try_lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L2 l0;
+ L1 l1;
+ L2 l2;
+ try
+ {
+ std::try_lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L1 l0;
+ L2 l1;
+ L2 l2;
+ assert(std::try_lock(l0, l1, l2) == 0);
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ {
+ L0 l0;
+ L2 l1;
+ L1 l2;
+ try
+ {
+ std::try_lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L1 l0;
+ L0 l1;
+ L2 l2;
+ assert(std::try_lock(l0, l1, l2) == 0);
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ {
+ L1 l0;
+ L2 l1;
+ L0 l2;
+ assert(std::try_lock(l0, l1, l2) == 0);
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ {
+ L2 l0;
+ L0 l1;
+ L1 l2;
+ try
+ {
+ std::try_lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L2 l0;
+ L1 l1;
+ L0 l2;
+ try
+ {
+ std::try_lock(l0, l1, l2);
+ assert(false);
+ }
+ catch (int)
+ {
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ }
+ }
+ {
+ L0 l0;
+ L0 l1;
+ L0 l2;
+ L0 l3;
+ assert(std::try_lock(l0, l1, l2, l3) == -1);
+ assert(l0.locked());
+ assert(l1.locked());
+ assert(l2.locked());
+ assert(l3.locked());
+ }
+ {
+ L1 l0;
+ L0 l1;
+ L0 l2;
+ L0 l3;
+ assert(std::try_lock(l0, l1, l2, l3) == 0);
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ assert(!l3.locked());
+ }
+ {
+ L0 l0;
+ L1 l1;
+ L0 l2;
+ L0 l3;
+ assert(std::try_lock(l0, l1, l2, l3) == 1);
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ assert(!l3.locked());
+ }
+ {
+ L0 l0;
+ L0 l1;
+ L1 l2;
+ L0 l3;
+ assert(std::try_lock(l0, l1, l2, l3) == 2);
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ assert(!l3.locked());
+ }
+ {
+ L0 l0;
+ L0 l1;
+ L0 l2;
+ L1 l3;
+ assert(std::try_lock(l0, l1, l2, l3) == 3);
+ assert(!l0.locked());
+ assert(!l1.locked());
+ assert(!l2.locked());
+ assert(!l3.locked());
+ }
+#endif // _LIBCPP_HAS_NO_VARIADICS
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp
new file mode 100644
index 000000000000..83271009a67e
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class lock_guard;
+
+// lock_guard(mutex_type& m, adopt_lock_t);
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ time_point t1;
+ {
+ m.lock();
+ std::lock_guard<std::mutex> lg(m, std::adopt_lock);
+ t1 = Clock::now();
+ }
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.fail.cpp
new file mode 100644
index 000000000000..53abb42c0e38
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.fail.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <mutex>
+
+// template <class Mutex> class lock_guard;
+
+// lock_guard& operator=(lock_guard const&) = delete;
+
+#include <mutex>
+
+int main()
+{
+ std::mutex m0;
+ std::mutex m1;
+ std::lock_guard<std::mutex> lg0(m0);
+ std::lock_guard<std::mutex> lg(m1);
+ lg = lg0;
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.fail.cpp
new file mode 100644
index 000000000000..296ccdaee67a
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.fail.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <mutex>
+
+// template <class Mutex> class lock_guard;
+
+// lock_guard(lock_guard const&) = delete;
+
+#include <mutex>
+
+int main()
+{
+ std::mutex m;
+ std::lock_guard<std::mutex> lg0(m);
+ std::lock_guard<std::mutex> lg(lg0);
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp
new file mode 100644
index 000000000000..246eb935c995
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.fail.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <mutex>
+
+// template <class Mutex> class lock_guard;
+
+// explicit lock_guard(mutex_type& m);
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ time_point t1;
+ {
+ std::lock_guard<std::mutex> lg = m;
+ t1 = Clock::now();
+ }
+ ns d = t1 - t0 - ms(250);
+ assert(d < ns(2500000)); // within 2.5ms
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
new file mode 100644
index 000000000000..a15405fcd98b
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class lock_guard;
+
+// explicit lock_guard(mutex_type& m);
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ time_point t1;
+ {
+ std::lock_guard<std::mutex> lg(m);
+ t1 = Clock::now();
+ }
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(200)); // within 200ms
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp
new file mode 100644
index 000000000000..5238ed67064f
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex>
+// class lock_guard
+// {
+// public:
+// typedef Mutex mutex_type;
+// ...
+// };
+
+#include <mutex>
+#include <type_traits>
+
+int main()
+{
+ static_assert((std::is_same<std::lock_guard<std::mutex>::mutex_type,
+ std::mutex>::value), "");
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_assign.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_assign.fail.cpp
new file mode 100644
index 000000000000..446807f3f333
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_assign.fail.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock& operator=(shared_lock const&) = delete;
+
+#include <shared_mutex>
+
+#if _LIBCPP_STD_VER > 11
+
+std::shared_timed_mutex m0;
+std::shared_timed_mutex m1;
+
+#endif // _LIBCPP_STD_VER > 11
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ std::shared_lock<std::shared_timed_mutex> lk0(m0);
+ std::shared_lock<std::shared_timed_mutex> lk1(m1);
+ lk1 = lk0;
+#else
+# error
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_ctor.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_ctor.fail.cpp
new file mode 100644
index 000000000000..370c1fa4e336
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/copy_ctor.fail.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock(shared_lock const&) = delete;
+
+#include <shared_mutex>
+
+#if _LIBCPP_STD_VER > 11
+std::shared_timed_mutex m;
+#endif // _LIBCPP_STD_VER > 11
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ std::shared_lock<std::shared_timed_mutex> lk0(m);
+ std::shared_lock<std::shared_timed_mutex> lk = lk0;
+#else
+# error
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/default.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/default.pass.cpp
new file mode 100644
index 000000000000..2c1c665fdeda
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/default.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock();
+
+#include <shared_mutex>
+#include <cassert>
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ std::shared_lock<std::shared_timed_mutex> ul;
+ assert(!ul.owns_lock());
+ assert(ul.mutex() == nullptr);
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp
new file mode 100644
index 000000000000..8676f2ca0472
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_assign.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock& operator=(shared_lock&& u);
+
+#include <shared_mutex>
+#include <cassert>
+
+#if _LIBCPP_STD_VER > 11
+
+std::shared_timed_mutex m0;
+std::shared_timed_mutex m1;
+
+#endif // _LIBCPP_STD_VER > 11
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ std::shared_lock<std::shared_timed_mutex> lk0(m0);
+ std::shared_lock<std::shared_timed_mutex> lk1(m1);
+ lk1 = std::move(lk0);
+ assert(lk1.mutex() == &m0);
+ assert(lk1.owns_lock() == true);
+ assert(lk0.mutex() == nullptr);
+ assert(lk0.owns_lock() == false);
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp
new file mode 100644
index 000000000000..f59d2e826980
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/move_ctor.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock(shared_lock&& u);
+
+#include <shared_mutex>
+#include <cassert>
+
+#if _LIBCPP_STD_VER > 11
+std::shared_timed_mutex m;
+#endif // _LIBCPP_STD_VER > 11
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ std::shared_lock<std::shared_timed_mutex> lk0(m);
+ std::shared_lock<std::shared_timed_mutex> lk = std::move(lk0);
+ assert(lk.mutex() == &m);
+ assert(lk.owns_lock() == true);
+ assert(lk0.mutex() == nullptr);
+ assert(lk0.owns_lock() == false);
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp
new file mode 100644
index 000000000000..c8a0287314bf
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex.pass.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// explicit shared_lock(mutex_type& m);
+
+#include <shared_mutex>
+#include <thread>
+#include <vector>
+#include <cstdlib>
+#include <cassert>
+
+#if _LIBCPP_STD_VER > 11
+
+std::shared_timed_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ time_point t1;
+ {
+ std::shared_lock<std::shared_timed_mutex> ul(m);
+ t1 = Clock::now();
+ }
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+void g()
+{
+ time_point t0 = Clock::now();
+ time_point t1;
+ {
+ std::shared_lock<std::shared_timed_mutex> ul(m);
+ t1 = Clock::now();
+ }
+ ns d = t1 - t0;
+ assert(d < ms(50)); // within 50ms
+}
+
+#endif // _LIBCPP_STD_VER > 11
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ m.lock();
+ std::vector<std::thread> v;
+ for (int i = 0; i < 5; ++i)
+ v.push_back(std::thread(f));
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ for (auto& t : v)
+ t.join();
+ m.lock_shared();
+ for (auto& t : v)
+ t = std::thread(g);
+ std::thread q(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock_shared();
+ for (auto& t : v)
+ t.join();
+ q.join();
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp
new file mode 100644
index 000000000000..3b49b3029052
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_adopt_lock.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock(mutex_type& m, adopt_lock_t);
+
+#include <shared_mutex>
+#include <cassert>
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ std::shared_timed_mutex m;
+ m.lock_shared();
+ std::shared_lock<std::shared_timed_mutex> lk(m, std::adopt_lock);
+ assert(lk.mutex() == &m);
+ assert(lk.owns_lock() == true);
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp
new file mode 100644
index 000000000000..bbc38fcadb10
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_defer_lock.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock(mutex_type& m, defer_lock_t);
+
+#include <shared_mutex>
+#include <cassert>
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ std::shared_timed_mutex m;
+ std::shared_lock<std::shared_timed_mutex> lk(m, std::defer_lock);
+ assert(lk.mutex() == &m);
+ assert(lk.owns_lock() == false);
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_duration.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_duration.pass.cpp
new file mode 100644
index 000000000000..9816e57f692a
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_duration.pass.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// class timed_mutex;
+
+// template <class Rep, class Period>
+// shared_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
+
+#include <shared_mutex>
+#include <thread>
+#include <vector>
+#include <cstdlib>
+#include <cassert>
+
+#if _LIBCPP_STD_VER > 11
+
+std::shared_timed_mutex m;
+
+typedef std::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ std::shared_lock<std::shared_timed_mutex> lk(m, ms(300));
+ assert(lk.owns_lock() == true);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ std::shared_lock<std::shared_timed_mutex> lk(m, ms(250));
+ assert(lk.owns_lock() == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+#endif // _LIBCPP_STD_VER > 11
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ {
+ m.lock();
+ std::vector<std::thread> v;
+ for (int i = 0; i < 5; ++i)
+ v.push_back(std::thread(f1));
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ for (auto& t : v)
+ t.join();
+ }
+ {
+ m.lock();
+ std::vector<std::thread> v;
+ for (int i = 0; i < 5; ++i)
+ v.push_back(std::thread(f2));
+ std::this_thread::sleep_for(ms(300));
+ m.unlock();
+ for (auto& t : v)
+ t.join();
+ }
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_time_point.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_time_point.pass.cpp
new file mode 100644
index 000000000000..5d188ab06737
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_time_point.pass.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// class shared_timed_mutex;
+
+// template <class Clock, class Duration>
+// shared_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <shared_mutex>
+#include <thread>
+#include <vector>
+#include <cstdlib>
+#include <cassert>
+
+#if _LIBCPP_STD_VER > 11
+
+std::shared_timed_mutex m;
+
+typedef std::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ std::shared_lock<std::shared_timed_mutex> lk(m, Clock::now() + ms(300));
+ assert(lk.owns_lock() == true);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ns(50000000)); // within 50ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ std::shared_lock<std::shared_timed_mutex> lk(m, Clock::now() + ms(250));
+ assert(lk.owns_lock() == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+#endif // _LIBCPP_STD_VER > 11
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ {
+ m.lock();
+ std::vector<std::thread> v;
+ for (int i = 0; i < 5; ++i)
+ v.push_back(std::thread(f1));
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ for (auto& t : v)
+ t.join();
+ }
+ {
+ m.lock();
+ std::vector<std::thread> v;
+ for (int i = 0; i < 5; ++i)
+ v.push_back(std::thread(f2));
+ std::this_thread::sleep_for(ms(300));
+ m.unlock();
+ for (auto& t : v)
+ t.join();
+ }
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp
new file mode 100644
index 000000000000..f2d4e0deb73f
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.cons/mutex_try_to_lock.pass.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock(mutex_type& m, try_to_lock_t);
+
+#include <shared_mutex>
+#include <thread>
+#include <vector>
+#include <cstdlib>
+#include <cassert>
+
+#if _LIBCPP_STD_VER > 11
+
+std::shared_timed_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ {
+ std::shared_lock<std::shared_timed_mutex> lk(m, std::try_to_lock);
+ assert(lk.owns_lock() == false);
+ }
+ {
+ std::shared_lock<std::shared_timed_mutex> lk(m, std::try_to_lock);
+ assert(lk.owns_lock() == false);
+ }
+ {
+ std::shared_lock<std::shared_timed_mutex> lk(m, std::try_to_lock);
+ assert(lk.owns_lock() == false);
+ }
+ while (true)
+ {
+ std::shared_lock<std::shared_timed_mutex> lk(m, std::try_to_lock);
+ if (lk.owns_lock())
+ break;
+ }
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(200)); // within 200ms
+}
+
+#endif // _LIBCPP_STD_VER > 11
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ m.lock();
+ std::vector<std::thread> v;
+ for (int i = 0; i < 5; ++i)
+ v.push_back(std::thread(f));
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ for (auto& t : v)
+ t.join();
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp
new file mode 100644
index 000000000000..f1500652badd
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/lock.pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// void lock();
+
+#include <shared_mutex>
+#include <thread>
+#include <vector>
+#include <cstdlib>
+#include <cassert>
+
+#if _LIBCPP_STD_VER > 11
+
+std::shared_timed_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ std::shared_lock<std::shared_timed_mutex> lk(m, std::defer_lock);
+ time_point t0 = Clock::now();
+ lk.lock();
+ time_point t1 = Clock::now();
+ assert(lk.owns_lock() == true);
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(25)); // within 25ms
+ try
+ {
+ lk.lock();
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EDEADLK);
+ }
+ lk.unlock();
+ lk.release();
+ try
+ {
+ lk.lock();
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EPERM);
+ }
+}
+
+#endif // _LIBCPP_STD_VER > 11
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ m.lock();
+ std::vector<std::thread> v;
+ for (int i = 0; i < 5; ++i)
+ v.push_back(std::thread(f));
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ for (auto& t : v)
+ t.join();
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp
new file mode 100644
index 000000000000..82b1ff865053
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// bool try_lock();
+
+#include <shared_mutex>
+#include <cassert>
+
+#if _LIBCPP_STD_VER > 11
+
+bool try_lock_called = false;
+
+struct mutex
+{
+ bool try_lock_shared()
+ {
+ try_lock_called = !try_lock_called;
+ return try_lock_called;
+ }
+ void unlock_shared() {}
+};
+
+mutex m;
+
+#endif // _LIBCPP_STD_VER > 11
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ std::shared_lock<mutex> lk(m, std::defer_lock);
+ assert(lk.try_lock() == true);
+ assert(try_lock_called == true);
+ assert(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock();
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EDEADLK);
+ }
+ lk.unlock();
+ assert(lk.try_lock() == false);
+ assert(try_lock_called == false);
+ assert(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock();
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EPERM);
+ }
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp
new file mode 100644
index 000000000000..5867465a6626
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_for.pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <shared_mutex>
+#include <cassert>
+
+#if _LIBCPP_STD_VER > 11
+
+bool try_lock_for_called = false;
+
+typedef std::chrono::milliseconds ms;
+
+struct mutex
+{
+ template <class Rep, class Period>
+ bool try_lock_shared_for(const std::chrono::duration<Rep, Period>& rel_time)
+ {
+ assert(rel_time == ms(5));
+ try_lock_for_called = !try_lock_for_called;
+ return try_lock_for_called;
+ }
+ void unlock_shared() {}
+};
+
+mutex m;
+
+#endif // _LIBCPP_STD_VER > 11
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ std::shared_lock<mutex> lk(m, std::defer_lock);
+ assert(lk.try_lock_for(ms(5)) == true);
+ assert(try_lock_for_called == true);
+ assert(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock_for(ms(5));
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EDEADLK);
+ }
+ lk.unlock();
+ assert(lk.try_lock_for(ms(5)) == false);
+ assert(try_lock_for_called == false);
+ assert(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock_for(ms(5));
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EPERM);
+ }
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp
new file mode 100644
index 000000000000..9d38983be724
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/try_lock_until.pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// template <class Clock, class Duration>
+// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <shared_mutex>
+#include <cassert>
+
+#if _LIBCPP_STD_VER > 11
+
+bool try_lock_until_called = false;
+
+struct mutex
+{
+ template <class Clock, class Duration>
+ bool try_lock_shared_until(const std::chrono::time_point<Clock, Duration>& abs_time)
+ {
+ typedef std::chrono::milliseconds ms;
+ assert(Clock::now() - abs_time < ms(5));
+ try_lock_until_called = !try_lock_until_called;
+ return try_lock_until_called;
+ }
+ void unlock_shared() {}
+};
+
+mutex m;
+
+#endif // _LIBCPP_STD_VER > 11
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ typedef std::chrono::steady_clock Clock;
+ std::shared_lock<mutex> lk(m, std::defer_lock);
+ assert(lk.try_lock_until(Clock::now()) == true);
+ assert(try_lock_until_called == true);
+ assert(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock_until(Clock::now());
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EDEADLK);
+ }
+ lk.unlock();
+ assert(lk.try_lock_until(Clock::now()) == false);
+ assert(try_lock_until_called == false);
+ assert(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock_until(Clock::now());
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EPERM);
+ }
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp
new file mode 100644
index 000000000000..eb08a45cde6e
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.locking/unlock.pass.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// void unlock();
+
+#include <shared_mutex>
+#include <cassert>
+
+#if _LIBCPP_STD_VER > 11
+
+bool unlock_called = false;
+
+struct mutex
+{
+ void lock_shared() {}
+ void unlock_shared() {unlock_called = true;}
+};
+
+mutex m;
+
+#endif // _LIBCPP_STD_VER > 11
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ std::shared_lock<mutex> lk(m);
+ lk.unlock();
+ assert(unlock_called == true);
+ assert(lk.owns_lock() == false);
+ try
+ {
+ lk.unlock();
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EPERM);
+ }
+ lk.release();
+ try
+ {
+ lk.unlock();
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EPERM);
+ }
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp
new file mode 100644
index 000000000000..8505763e44bc
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/member_swap.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// void swap(shared_lock& u) noexcept;
+
+#include <shared_mutex>
+#include <cassert>
+
+#if _LIBCPP_STD_VER > 11
+
+struct mutex
+{
+ void lock_shared() {}
+ void unlock_shared() {}
+};
+
+mutex m;
+
+#endif // _LIBCPP_STD_VER > 11
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ std::shared_lock<mutex> lk1(m);
+ std::shared_lock<mutex> lk2;
+ lk1.swap(lk2);
+ assert(lk1.mutex() == nullptr);
+ assert(lk1.owns_lock() == false);
+ assert(lk2.mutex() == &m);
+ assert(lk2.owns_lock() == true);
+ static_assert(noexcept(lk1.swap(lk2)), "member swap must be noexcept");
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp
new file mode 100644
index 000000000000..057dbc4cd3b7
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/nonmember_swap.pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// template <class Mutex>
+// void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
+
+#include <shared_mutex>
+#include <cassert>
+
+#if _LIBCPP_STD_VER > 11
+
+struct mutex
+{
+ void lock_shared() {}
+ void unlock_shared() {}
+};
+
+mutex m;
+
+#endif // _LIBCPP_STD_VER > 11
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ std::shared_lock<mutex> lk1(m);
+ std::shared_lock<mutex> lk2;
+ swap(lk1, lk2);
+ assert(lk1.mutex() == nullptr);
+ assert(lk1.owns_lock() == false);
+ assert(lk2.mutex() == &m);
+ assert(lk2.owns_lock() == true);
+ static_assert(noexcept(swap(lk1, lk2)), "non-member swap must be noexcept");
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp
new file mode 100644
index 000000000000..65ddca624725
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.mod/release.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// mutex_type* release() noexcept;
+
+#include <shared_mutex>
+#include <cassert>
+
+#if _LIBCPP_STD_VER > 11
+
+struct mutex
+{
+ static int lock_count;
+ static int unlock_count;
+ void lock_shared() {++lock_count;}
+ void unlock_shared() {++unlock_count;}
+};
+
+int mutex::lock_count = 0;
+int mutex::unlock_count = 0;
+
+mutex m;
+
+#endif // _LIBCPP_STD_VER > 11
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ std::shared_lock<mutex> lk(m);
+ assert(lk.mutex() == &m);
+ assert(lk.owns_lock() == true);
+ assert(mutex::lock_count == 1);
+ assert(mutex::unlock_count == 0);
+ assert(lk.release() == &m);
+ assert(lk.mutex() == nullptr);
+ assert(lk.owns_lock() == false);
+ assert(mutex::lock_count == 1);
+ assert(mutex::unlock_count == 0);
+ static_assert(noexcept(lk.release()), "release must be noexcept");
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/mutex.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/mutex.pass.cpp
new file mode 100644
index 000000000000..4eb75d8f050e
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/mutex.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// mutex_type *mutex() const noexcept;
+
+#include <shared_mutex>
+#include <cassert>
+
+#if _LIBCPP_STD_VER > 11
+
+std::shared_timed_mutex m;
+
+#endif // _LIBCPP_STD_VER > 11
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ std::shared_lock<std::shared_timed_mutex> lk0;
+ assert(lk0.mutex() == nullptr);
+ std::shared_lock<std::shared_timed_mutex> lk1(m);
+ assert(lk1.mutex() == &m);
+ lk1.unlock();
+ assert(lk1.mutex() == &m);
+ static_assert(noexcept(lk0.mutex()), "mutex() must be noexcept");
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp
new file mode 100644
index 000000000000..d079d2d8b03a
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/op_bool.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// explicit operator bool() const noexcept;
+
+#include <shared_mutex>
+#include <cassert>
+
+#if _LIBCPP_STD_VER > 11
+
+std::shared_timed_mutex m;
+
+#endif // _LIBCPP_STD_VER > 11
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ std::shared_lock<std::shared_timed_mutex> lk0;
+ assert(static_cast<bool>(lk0) == false);
+ std::shared_lock<std::shared_timed_mutex> lk1(m);
+ assert(static_cast<bool>(lk1) == true);
+ lk1.unlock();
+ assert(static_cast<bool>(lk1) == false);
+ static_assert(noexcept(static_cast<bool>(lk0)), "explicit operator bool() must be noexcept");
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/owns_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/owns_lock.pass.cpp
new file mode 100644
index 000000000000..d64b0aa6a736
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/thread.lock.shared.obs/owns_lock.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// template <class Mutex> class shared_lock;
+
+// bool owns_lock() const noexcept;
+
+#include <shared_mutex>
+#include <cassert>
+
+#if _LIBCPP_STD_VER > 11
+
+std::shared_timed_mutex m;
+
+#endif // _LIBCPP_STD_VER > 11
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ std::shared_lock<std::shared_timed_mutex> lk0;
+ assert(lk0.owns_lock() == false);
+ std::shared_lock<std::shared_timed_mutex> lk1(m);
+ assert(lk1.owns_lock() == true);
+ lk1.unlock();
+ assert(lk1.owns_lock() == false);
+ static_assert(noexcept(lk0.owns_lock()), "owns_lock must be noexcept");
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/types.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/types.pass.cpp
new file mode 100644
index 000000000000..c153b455f404
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.shared/types.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <shared_mutex>
+
+// template <class Mutex>
+// class shared_lock
+// {
+// public:
+// typedef Mutex mutex_type;
+// ...
+// };
+
+#include <shared_mutex>
+#include <type_traits>
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ static_assert((std::is_same<std::shared_lock<std::mutex>::mutex_type,
+ std::mutex>::value), "");
+#endif // _LIBCPP_STD_VER > 11
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp
new file mode 100644
index 000000000000..4f477449d6a2
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_assign.fail.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock& operator=(unique_lock const&) = delete;
+
+#include <mutex>
+#include <cassert>
+
+std::mutex m0;
+std::mutex m1;
+
+int main()
+{
+ std::unique_lock<std::mutex> lk0(m0);
+ std::unique_lock<std::mutex> lk1(m1);
+ lk1 = lk0;
+ assert(lk1.mutex() == &m0);
+ assert(lk1.owns_lock() == true);
+ assert(lk0.mutex() == nullptr);
+ assert(lk0.owns_lock() == false);
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp
new file mode 100644
index 000000000000..4888fe90d92c
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/copy_ctor.fail.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(unique_lock const&) = delete;
+
+#include <mutex>
+#include <cassert>
+
+std::mutex m;
+
+int main()
+{
+ std::unique_lock<std::mutex> lk0(m);
+ std::unique_lock<std::mutex> lk = lk0;
+ assert(lk.mutex() == &m);
+ assert(lk.owns_lock() == true);
+ assert(lk0.mutex() == nullptr);
+ assert(lk0.owns_lock() == false);
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/default.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/default.pass.cpp
new file mode 100644
index 000000000000..a49bc507171c
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/default.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock();
+
+#include <mutex>
+#include <cassert>
+
+int main()
+{
+ std::unique_lock<std::mutex> ul;
+ assert(!ul.owns_lock());
+ assert(ul.mutex() == nullptr);
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp
new file mode 100644
index 000000000000..4dff853088ac
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_assign.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock& operator=(unique_lock&& u);
+
+#include <mutex>
+#include <cassert>
+
+std::mutex m0;
+std::mutex m1;
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ std::unique_lock<std::mutex> lk0(m0);
+ std::unique_lock<std::mutex> lk1(m1);
+ lk1 = std::move(lk0);
+ assert(lk1.mutex() == &m0);
+ assert(lk1.owns_lock() == true);
+ assert(lk0.mutex() == nullptr);
+ assert(lk0.owns_lock() == false);
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp
new file mode 100644
index 000000000000..aa640ee6d746
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/move_ctor.pass.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(unique_lock&& u);
+
+#include <mutex>
+#include <cassert>
+
+std::mutex m;
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ std::unique_lock<std::mutex> lk0(m);
+ std::unique_lock<std::mutex> lk = std::move(lk0);
+ assert(lk.mutex() == &m);
+ assert(lk.owns_lock() == true);
+ assert(lk0.mutex() == nullptr);
+ assert(lk0.owns_lock() == false);
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp
new file mode 100644
index 000000000000..1f7217a8300e
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// explicit unique_lock(mutex_type& m);
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ time_point t1;
+ {
+ std::unique_lock<std::mutex> ul(m);
+ t1 = Clock::now();
+ }
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp
new file mode 100644
index 000000000000..9c3a7b6505a4
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_adopt_lock.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(mutex_type& m, adopt_lock_t);
+
+#include <mutex>
+#include <cassert>
+
+int main()
+{
+ std::mutex m;
+ m.lock();
+ std::unique_lock<std::mutex> lk(m, std::adopt_lock);
+ assert(lk.mutex() == &m);
+ assert(lk.owns_lock() == true);
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp
new file mode 100644
index 000000000000..bf622311f013
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_defer_lock.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(mutex_type& m, defer_lock_t);
+
+#include <mutex>
+#include <cassert>
+
+int main()
+{
+ std::mutex m;
+ std::unique_lock<std::mutex> lk(m, std::defer_lock);
+ assert(lk.mutex() == &m);
+ assert(lk.owns_lock() == false);
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_duration.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_duration.pass.cpp
new file mode 100644
index 000000000000..33e400b0da80
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_duration.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class timed_mutex;
+
+// template <class Rep, class Period>
+// unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::timed_mutex m;
+
+typedef std::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ std::unique_lock<std::timed_mutex> lk(m, ms(300));
+ assert(lk.owns_lock() == true);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ std::unique_lock<std::timed_mutex> lk(m, ms(250));
+ assert(lk.owns_lock() == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ std::thread t(f1);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ std::thread t(f2);
+ std::this_thread::sleep_for(ms(300));
+ m.unlock();
+ t.join();
+ }
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_time_point.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_time_point.pass.cpp
new file mode 100644
index 000000000000..2ead67097730
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_time_point.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class timed_mutex;
+
+// template <class Clock, class Duration>
+// unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::timed_mutex m;
+
+typedef std::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ std::unique_lock<std::timed_mutex> lk(m, Clock::now() + ms(300));
+ assert(lk.owns_lock() == true);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ns(50000000)); // within 50ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ std::unique_lock<std::timed_mutex> lk(m, Clock::now() + ms(250));
+ assert(lk.owns_lock() == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ std::thread t(f1);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ std::thread t(f2);
+ std::this_thread::sleep_for(ms(300));
+ m.unlock();
+ t.join();
+ }
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_try_to_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_try_to_lock.pass.cpp
new file mode 100644
index 000000000000..cea58c554a9b
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.cons/mutex_try_to_lock.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(mutex_type& m, try_to_lock_t);
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ {
+ std::unique_lock<std::mutex> lk(m, std::try_to_lock);
+ assert(lk.owns_lock() == false);
+ }
+ {
+ std::unique_lock<std::mutex> lk(m, std::try_to_lock);
+ assert(lk.owns_lock() == false);
+ }
+ {
+ std::unique_lock<std::mutex> lk(m, std::try_to_lock);
+ assert(lk.owns_lock() == false);
+ }
+ while (true)
+ {
+ std::unique_lock<std::mutex> lk(m, std::try_to_lock);
+ if (lk.owns_lock())
+ break;
+ }
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(200)); // within 200ms
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp
new file mode 100644
index 000000000000..f5408df98199
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/lock.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// void lock();
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ std::unique_lock<std::mutex> lk(m, std::defer_lock);
+ time_point t0 = Clock::now();
+ lk.lock();
+ time_point t1 = Clock::now();
+ assert(lk.owns_lock() == true);
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(25)); // within 25ms
+ try
+ {
+ lk.lock();
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EDEADLK);
+ }
+ lk.unlock();
+ lk.release();
+ try
+ {
+ lk.lock();
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EPERM);
+ }
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp
new file mode 100644
index 000000000000..bd88577f0a22
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// bool try_lock();
+
+#include <mutex>
+#include <cassert>
+
+bool try_lock_called = false;
+
+struct mutex
+{
+ bool try_lock()
+ {
+ try_lock_called = !try_lock_called;
+ return try_lock_called;
+ }
+ void unlock() {}
+};
+
+mutex m;
+
+int main()
+{
+ std::unique_lock<mutex> lk(m, std::defer_lock);
+ assert(lk.try_lock() == true);
+ assert(try_lock_called == true);
+ assert(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock();
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EDEADLK);
+ }
+ lk.unlock();
+ assert(lk.try_lock() == false);
+ assert(try_lock_called == false);
+ assert(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock();
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EPERM);
+ }
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp
new file mode 100644
index 000000000000..558f079463a4
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_for.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <mutex>
+#include <cassert>
+
+bool try_lock_for_called = false;
+
+typedef std::chrono::milliseconds ms;
+
+struct mutex
+{
+ template <class Rep, class Period>
+ bool try_lock_for(const std::chrono::duration<Rep, Period>& rel_time)
+ {
+ assert(rel_time == ms(5));
+ try_lock_for_called = !try_lock_for_called;
+ return try_lock_for_called;
+ }
+ void unlock() {}
+};
+
+mutex m;
+
+int main()
+{
+ std::unique_lock<mutex> lk(m, std::defer_lock);
+ assert(lk.try_lock_for(ms(5)) == true);
+ assert(try_lock_for_called == true);
+ assert(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock_for(ms(5));
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EDEADLK);
+ }
+ lk.unlock();
+ assert(lk.try_lock_for(ms(5)) == false);
+ assert(try_lock_for_called == false);
+ assert(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock_for(ms(5));
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EPERM);
+ }
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp
new file mode 100644
index 000000000000..24e4d109a097
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/try_lock_until.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Clock, class Duration>
+// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <mutex>
+#include <cassert>
+
+bool try_lock_until_called = false;
+
+struct mutex
+{
+ template <class Clock, class Duration>
+ bool try_lock_until(const std::chrono::time_point<Clock, Duration>& abs_time)
+ {
+ typedef std::chrono::milliseconds ms;
+ assert(Clock::now() - abs_time < ms(5));
+ try_lock_until_called = !try_lock_until_called;
+ return try_lock_until_called;
+ }
+ void unlock() {}
+};
+
+mutex m;
+
+int main()
+{
+ typedef std::chrono::steady_clock Clock;
+ std::unique_lock<mutex> lk(m, std::defer_lock);
+ assert(lk.try_lock_until(Clock::now()) == true);
+ assert(try_lock_until_called == true);
+ assert(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock_until(Clock::now());
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EDEADLK);
+ }
+ lk.unlock();
+ assert(lk.try_lock_until(Clock::now()) == false);
+ assert(try_lock_until_called == false);
+ assert(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock_until(Clock::now());
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EPERM);
+ }
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/unlock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/unlock.pass.cpp
new file mode 100644
index 000000000000..bbabfc41df11
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.locking/unlock.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// void unlock();
+
+#include <mutex>
+#include <cassert>
+
+bool unlock_called = false;
+
+struct mutex
+{
+ void lock() {}
+ void unlock() {unlock_called = true;}
+};
+
+mutex m;
+
+int main()
+{
+ std::unique_lock<mutex> lk(m);
+ lk.unlock();
+ assert(unlock_called == true);
+ assert(lk.owns_lock() == false);
+ try
+ {
+ lk.unlock();
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EPERM);
+ }
+ lk.release();
+ try
+ {
+ lk.unlock();
+ assert(false);
+ }
+ catch (std::system_error& e)
+ {
+ assert(e.code().value() == EPERM);
+ }
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/member_swap.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/member_swap.pass.cpp
new file mode 100644
index 000000000000..598d53a65c85
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/member_swap.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// void swap(unique_lock& u);
+
+#include <mutex>
+#include <cassert>
+
+struct mutex
+{
+ void lock() {}
+ void unlock() {}
+};
+
+mutex m;
+
+int main()
+{
+ std::unique_lock<mutex> lk1(m);
+ std::unique_lock<mutex> lk2;
+ lk1.swap(lk2);
+ assert(lk1.mutex() == nullptr);
+ assert(lk1.owns_lock() == false);
+ assert(lk2.mutex() == &m);
+ assert(lk2.owns_lock() == true);
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/nonmember_swap.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/nonmember_swap.pass.cpp
new file mode 100644
index 000000000000..3fc8c28f5071
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/nonmember_swap.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Mutex>
+// void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y);
+
+#include <mutex>
+#include <cassert>
+
+struct mutex
+{
+ void lock() {}
+ void unlock() {}
+};
+
+mutex m;
+
+int main()
+{
+ std::unique_lock<mutex> lk1(m);
+ std::unique_lock<mutex> lk2;
+ swap(lk1, lk2);
+ assert(lk1.mutex() == nullptr);
+ assert(lk1.owns_lock() == false);
+ assert(lk2.mutex() == &m);
+ assert(lk2.owns_lock() == true);
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/release.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/release.pass.cpp
new file mode 100644
index 000000000000..89c28e6be73c
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.mod/release.pass.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// mutex_type* release() noexcept;
+
+#include <mutex>
+#include <cassert>
+
+struct mutex
+{
+ static int lock_count;
+ static int unlock_count;
+ void lock() {++lock_count;}
+ void unlock() {++unlock_count;}
+};
+
+int mutex::lock_count = 0;
+int mutex::unlock_count = 0;
+
+mutex m;
+
+int main()
+{
+ std::unique_lock<mutex> lk(m);
+ assert(lk.mutex() == &m);
+ assert(lk.owns_lock() == true);
+ assert(mutex::lock_count == 1);
+ assert(mutex::unlock_count == 0);
+ assert(lk.release() == &m);
+ assert(lk.mutex() == nullptr);
+ assert(lk.owns_lock() == false);
+ assert(mutex::lock_count == 1);
+ assert(mutex::unlock_count == 0);
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/mutex.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/mutex.pass.cpp
new file mode 100644
index 000000000000..bc1e3e5eb774
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/mutex.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// mutex_type *mutex() const;
+
+#include <mutex>
+#include <cassert>
+
+std::mutex m;
+
+int main()
+{
+ std::unique_lock<std::mutex> lk0;
+ assert(lk0.mutex() == nullptr);
+ std::unique_lock<std::mutex> lk1(m);
+ assert(lk1.mutex() == &m);
+ lk1.unlock();
+ assert(lk1.mutex() == &m);
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/op_bool.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/op_bool.pass.cpp
new file mode 100644
index 000000000000..7004ac0092e1
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/op_bool.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// explicit operator bool() const;
+
+#include <mutex>
+#include <cassert>
+
+std::mutex m;
+
+int main()
+{
+ std::unique_lock<std::mutex> lk0;
+ assert(static_cast<bool>(lk0) == false);
+ std::unique_lock<std::mutex> lk1(m);
+ assert(static_cast<bool>(lk1) == true);
+ lk1.unlock();
+ assert(static_cast<bool>(lk1) == false);
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/owns_lock.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/owns_lock.pass.cpp
new file mode 100644
index 000000000000..f53af35ff284
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/thread.lock.unique.obs/owns_lock.pass.cpp
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex> class unique_lock;
+
+// bool owns_lock() const;
+
+#include <mutex>
+#include <cassert>
+
+std::mutex m;
+
+int main()
+{
+ std::unique_lock<std::mutex> lk0;
+ assert(lk0.owns_lock() == false);
+ std::unique_lock<std::mutex> lk1(m);
+ assert(lk1.owns_lock() == true);
+ lk1.unlock();
+ assert(lk1.owns_lock() == false);
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/types.pass.cpp b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/types.pass.cpp
new file mode 100644
index 000000000000..f8bcb6d0d22f
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/thread.lock.unique/types.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// template <class Mutex>
+// class unique_lock
+// {
+// public:
+// typedef Mutex mutex_type;
+// ...
+// };
+
+#include <mutex>
+#include <type_traits>
+
+int main()
+{
+ static_assert((std::is_same<std::unique_lock<std::mutex>::mutex_type,
+ std::mutex>::value), "");
+}
diff --git a/test/std/thread/thread.mutex/thread.lock/types.pass.cpp b/test/std/thread/thread.mutex/thread.lock/types.pass.cpp
new file mode 100644
index 000000000000..64df0680b0b9
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.lock/types.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// struct defer_lock_t {};
+// struct try_to_lock_t {};
+// struct adopt_lock_t {};
+//
+// constexpr defer_lock_t defer_lock{};
+// constexpr try_to_lock_t try_to_lock{};
+// constexpr adopt_lock_t adopt_lock{};
+
+#include <mutex>
+#include <type_traits>
+
+int main()
+{
+ typedef std::defer_lock_t T1;
+ typedef std::try_to_lock_t T2;
+ typedef std::adopt_lock_t T3;
+
+ T1 t1 = std::defer_lock;
+ T2 t2 = std::try_to_lock;
+ T3 t3 = std::adopt_lock;
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/nothing_to_do.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..b58f5c55b643
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.general/nothing_to_do.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.general/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..b58f5c55b643
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.general/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/nothing_to_do.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..b58f5c55b643
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/assign.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/assign.fail.cpp
new file mode 100644
index 000000000000..7f6333af9e29
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/assign.fail.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <mutex>
+
+// class mutex;
+
+// mutex& operator=(const mutex&) = delete;
+
+#include <mutex>
+
+int main()
+{
+ std::mutex m0;
+ std::mutex m1;
+ m1 = m0;
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/copy.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/copy.fail.cpp
new file mode 100644
index 000000000000..7e1a07ac8c1a
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/copy.fail.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <mutex>
+
+// class mutex;
+
+// mutex(const mutex&) = delete;
+
+#include <mutex>
+
+int main()
+{
+ std::mutex m0;
+ std::mutex m1(m0);
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/default.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/default.pass.cpp
new file mode 100644
index 000000000000..4de42fbd0243
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/default.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class mutex;
+
+// mutex();
+
+#include <mutex>
+
+int main()
+{
+ std::mutex m;
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/lock.pass.cpp
new file mode 100644
index 000000000000..ba2d54d58663
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/lock.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class mutex;
+
+// void lock();
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+#include <iostream>
+
+std::mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ m.lock();
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp
new file mode 100644
index 000000000000..12c80f02c340
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/native_handle.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class mutex;
+
+// typedef pthread_mutex_t* native_handle_type;
+// native_handle_type native_handle();
+
+#include <mutex>
+#include <cassert>
+
+int main()
+{
+ std::mutex m;
+ pthread_mutex_t* h = m.native_handle();
+ assert(h);
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/try_lock.pass.cpp
new file mode 100644
index 000000000000..fe8f351d7db7
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.class/try_lock.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class mutex;
+
+// bool try_lock();
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ assert(!m.try_lock());
+ assert(!m.try_lock());
+ assert(!m.try_lock());
+ while(!m.try_lock())
+ ;
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(200)); // within 200ms
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/assign.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/assign.fail.cpp
new file mode 100644
index 000000000000..61b56216e8fb
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/assign.fail.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <mutex>
+
+// class recursive_mutex;
+
+// recursive_mutex& operator=(const recursive_mutex&) = delete;
+
+#include <mutex>
+
+int main()
+{
+ std::recursive_mutex m0;
+ std::recursive_mutex m1;
+ m1 = m0;
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/copy.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/copy.fail.cpp
new file mode 100644
index 000000000000..0239c0475ac2
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/copy.fail.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <mutex>
+
+// class recursive_mutex;
+
+// recursive_mutex(const recursive_mutex&) = delete;
+
+#include <mutex>
+
+int main()
+{
+ std::recursive_mutex m0;
+ std::recursive_mutex m1(m0);
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/default.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/default.pass.cpp
new file mode 100644
index 000000000000..8c5d26675d3f
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/default.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class recursive_mutex;
+
+// recursive_mutex();
+
+#include <mutex>
+
+int main()
+{
+ std::recursive_mutex m;
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/lock.pass.cpp
new file mode 100644
index 000000000000..abebe906378c
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/lock.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class recursive_mutex;
+
+// void lock();
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+#include <iostream>
+
+std::recursive_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ m.lock();
+ time_point t1 = Clock::now();
+ m.lock();
+ m.unlock();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(200)); // within 200ms
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp
new file mode 100644
index 000000000000..10626bc4072e
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/native_handle.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class recursive_mutex;
+
+// typedef pthread_mutex_t* native_handle_type;
+// native_handle_type native_handle();
+
+#include <mutex>
+#include <cassert>
+
+int main()
+{
+ std::recursive_mutex m;
+ pthread_mutex_t* h = m.native_handle();
+ assert(h);
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/try_lock.pass.cpp
new file mode 100644
index 000000000000..ff546d4ad66d
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.mutex.requirements.mutex/thread.mutex.recursive/try_lock.pass.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class recursive_mutex;
+
+// bool try_lock();
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::recursive_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ assert(!m.try_lock());
+ assert(!m.try_lock());
+ assert(!m.try_lock());
+ while(!m.try_lock())
+ ;
+ time_point t1 = Clock::now();
+ assert(m.try_lock());
+ m.unlock();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(200)); // within 200ms
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/nothing_to_do.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..b58f5c55b643
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/assign.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/assign.fail.cpp
new file mode 100644
index 000000000000..7bcb2d61379a
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/assign.fail.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// shared_mutex& operator=(const shared_mutex&) = delete;
+
+#include <shared_mutex>
+
+#include "test_macros.h"
+
+int main()
+{
+#if TEST_STD_VER > 14
+ std::shared_mutex m0;
+ std::shared_mutex m1;
+ m1 = m0;
+#else
+# error
+#endif
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp
new file mode 100644
index 000000000000..af064aeee26c
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/copy.fail.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// shared_mutex(const shared_mutex&) = delete;
+
+#include <shared_mutex>
+
+#include "test_macros.h"
+
+int main()
+{
+#if TEST_STD_VER > 14
+ std::shared_mutex m0;
+ std::shared_mutex m1(m0);
+#else
+# error
+#endif
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/default.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/default.pass.cpp
new file mode 100644
index 000000000000..c61a93aa0c7f
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/default.pass.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11, c++14
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// shared_mutex();
+
+#include <shared_mutex>
+
+int main()
+{
+ std::shared_mutex m;
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock.pass.cpp
new file mode 100644
index 000000000000..9bf7a79e3400
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11, c++14
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// void lock();
+
+#include <shared_mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+
+std::shared_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ m.lock();
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock_shared.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock_shared.pass.cpp
new file mode 100644
index 000000000000..3ffa9e2d0065
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/lock_shared.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11, c++14
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// void lock_shared();
+
+#include <shared_mutex>
+#include <thread>
+#include <vector>
+#include <cstdlib>
+#include <cassert>
+
+std::shared_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ m.lock_shared();
+ time_point t1 = Clock::now();
+ m.unlock_shared();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+void g()
+{
+ time_point t0 = Clock::now();
+ m.lock_shared();
+ time_point t1 = Clock::now();
+ m.unlock_shared();
+ ns d = t1 - t0;
+ assert(d < ms(50)); // within 50ms
+}
+
+
+int main()
+{
+ m.lock();
+ std::vector<std::thread> v;
+ for (int i = 0; i < 5; ++i)
+ v.push_back(std::thread(f));
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ for (auto& t : v)
+ t.join();
+ m.lock_shared();
+ for (auto& t : v)
+ t = std::thread(g);
+ std::thread q(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock_shared();
+ for (auto& t : v)
+ t.join();
+ q.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock.pass.cpp
new file mode 100644
index 000000000000..6f3ca24a4558
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11, c++14
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// bool try_lock();
+
+#include <shared_mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::shared_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ assert(!m.try_lock());
+ assert(!m.try_lock());
+ assert(!m.try_lock());
+ while(!m.try_lock())
+ ;
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(200)); // within 200ms
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock_shared.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock_shared.pass.cpp
new file mode 100644
index 000000000000..52007155ba5f
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.shared_mutex.requirements/thread.shared_mutex.class/try_lock_shared.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11, c++14
+
+// <shared_mutex>
+
+// class shared_mutex;
+
+// bool try_lock_shared();
+
+#include <shared_mutex>
+#include <thread>
+#include <vector>
+#include <cstdlib>
+#include <cassert>
+
+std::shared_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ assert(!m.try_lock_shared());
+ assert(!m.try_lock_shared());
+ assert(!m.try_lock_shared());
+ while(!m.try_lock_shared())
+ ;
+ time_point t1 = Clock::now();
+ m.unlock_shared();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(200)); // within 200ms
+}
+
+
+int main()
+{
+ m.lock();
+ std::vector<std::thread> v;
+ for (int i = 0; i < 5; ++i)
+ v.push_back(std::thread(f));
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ for (auto& t : v)
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/nothing_to_do.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..b58f5c55b643
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/assign.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/assign.fail.cpp
new file mode 100644
index 000000000000..528aaca6d9e1
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/assign.fail.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <shared_mutex>
+
+// class shared_timed_mutex;
+
+// shared_timed_mutex& operator=(const shared_timed_mutex&) = delete;
+
+#include <shared_mutex>
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ std::shared_timed_mutex m0;
+ std::shared_timed_mutex m1;
+ m1 = m0;
+#else
+# error
+#endif
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/copy.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/copy.fail.cpp
new file mode 100644
index 000000000000..dbf01002e691
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/copy.fail.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <shared_mutex>
+
+// class shared_timed_mutex;
+
+// shared_timed_mutex(const shared_timed_mutex&) = delete;
+
+#include <shared_mutex>
+
+int main()
+{
+#if _LIBCPP_STD_VER > 11
+ std::shared_timed_mutex m0;
+ std::shared_timed_mutex m1(m0);
+#else
+# error
+#endif
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/default.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/default.pass.cpp
new file mode 100644
index 000000000000..45cd563f9407
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/default.pass.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
+
+// <shared_mutex>
+
+// class shared_timed_mutex;
+
+// shared_timed_mutex();
+
+#include <shared_mutex>
+
+int main()
+{
+ std::shared_timed_mutex m;
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock.pass.cpp
new file mode 100644
index 000000000000..62bb736837ea
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
+
+// <shared_mutex>
+
+// class shared_timed_mutex;
+
+// void lock();
+
+#include <shared_mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::shared_timed_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ m.lock();
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock_shared.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock_shared.pass.cpp
new file mode 100644
index 000000000000..8fc6299f1b8f
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/lock_shared.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
+
+// <shared_mutex>
+
+// class shared_timed_mutex;
+
+// void lock_shared();
+
+#include <shared_mutex>
+#include <thread>
+#include <vector>
+#include <cstdlib>
+#include <cassert>
+
+std::shared_timed_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ m.lock_shared();
+ time_point t1 = Clock::now();
+ m.unlock_shared();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+void g()
+{
+ time_point t0 = Clock::now();
+ m.lock_shared();
+ time_point t1 = Clock::now();
+ m.unlock_shared();
+ ns d = t1 - t0;
+ assert(d < ms(50)); // within 50ms
+}
+
+
+int main()
+{
+ m.lock();
+ std::vector<std::thread> v;
+ for (int i = 0; i < 5; ++i)
+ v.push_back(std::thread(f));
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ for (auto& t : v)
+ t.join();
+ m.lock_shared();
+ for (auto& t : v)
+ t = std::thread(g);
+ std::thread q(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock_shared();
+ for (auto& t : v)
+ t.join();
+ q.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock.pass.cpp
new file mode 100644
index 000000000000..61900ba83342
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
+
+// <shared_mutex>
+
+// class shared_timed_mutex;
+
+// bool try_lock();
+
+#include <shared_mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::shared_timed_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ assert(!m.try_lock());
+ assert(!m.try_lock());
+ assert(!m.try_lock());
+ while(!m.try_lock())
+ ;
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(200)); // within 200ms
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp
new file mode 100644
index 000000000000..ab20241895ba
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_for.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
+
+// <shared_mutex>
+
+// class shared_timed_mutex;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <shared_mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::shared_timed_mutex m;
+
+typedef std::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ assert(m.try_lock_for(ms(300)) == true);
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ assert(m.try_lock_for(ms(250)) == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ std::thread t(f1);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ std::thread t(f2);
+ std::this_thread::sleep_for(ms(300));
+ m.unlock();
+ t.join();
+ }
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared.pass.cpp
new file mode 100644
index 000000000000..9c2d8c9c8e5c
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
+
+// <shared_mutex>
+
+// class shared_timed_mutex;
+
+// bool try_lock_shared();
+
+#include <shared_mutex>
+#include <thread>
+#include <vector>
+#include <cstdlib>
+#include <cassert>
+
+std::shared_timed_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ assert(!m.try_lock_shared());
+ assert(!m.try_lock_shared());
+ assert(!m.try_lock_shared());
+ while(!m.try_lock_shared())
+ ;
+ time_point t1 = Clock::now();
+ m.unlock_shared();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(200)); // within 200ms
+}
+
+int main()
+{
+ m.lock();
+ std::vector<std::thread> v;
+ for (int i = 0; i < 5; ++i)
+ v.push_back(std::thread(f));
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ for (auto& t : v)
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp
new file mode 100644
index 000000000000..35444112a5da
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_for.pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
+
+// <shared_mutex>
+
+// class shared_timed_mutex;
+
+// template <class Rep, class Period>
+// bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <shared_mutex>
+#include <thread>
+#include <vector>
+#include <cstdlib>
+#include <cassert>
+
+std::shared_timed_mutex m;
+
+typedef std::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ assert(m.try_lock_shared_for(ms(300)) == true);
+ time_point t1 = Clock::now();
+ m.unlock_shared();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ assert(m.try_lock_shared_for(ms(250)) == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ std::vector<std::thread> v;
+ for (int i = 0; i < 5; ++i)
+ v.push_back(std::thread(f1));
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ for (auto& t : v)
+ t.join();
+ }
+ {
+ m.lock();
+ std::vector<std::thread> v;
+ for (int i = 0; i < 5; ++i)
+ v.push_back(std::thread(f2));
+ std::this_thread::sleep_for(ms(300));
+ m.unlock();
+ for (auto& t : v)
+ t.join();
+ }
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp
new file mode 100644
index 000000000000..4e0f19de07ce
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_shared_until.pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
+
+// <shared_mutex>
+
+// class shared_timed_mutex;
+
+// template <class Clock, class Duration>
+// bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <shared_mutex>
+#include <thread>
+#include <vector>
+#include <cstdlib>
+#include <cassert>
+
+std::shared_timed_mutex m;
+
+typedef std::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ assert(m.try_lock_shared_until(Clock::now() + ms(300)) == true);
+ time_point t1 = Clock::now();
+ m.unlock_shared();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ assert(m.try_lock_shared_until(Clock::now() + ms(250)) == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ std::vector<std::thread> v;
+ for (int i = 0; i < 5; ++i)
+ v.push_back(std::thread(f1));
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ for (auto& t : v)
+ t.join();
+ }
+ {
+ m.lock();
+ std::vector<std::thread> v;
+ for (int i = 0; i < 5; ++i)
+ v.push_back(std::thread(f2));
+ std::this_thread::sleep_for(ms(300));
+ m.unlock();
+ for (auto& t : v)
+ t.join();
+ }
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp
new file mode 100644
index 000000000000..aa90cf71502f
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
+
+// <shared_mutex>
+
+// class shared_timed_mutex;
+
+// template <class Clock, class Duration>
+// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <shared_mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+#include "test_macros.h"
+
+std::shared_timed_mutex m;
+
+typedef std::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ assert(m.try_lock_until(Clock::now() + ms(300)) == true);
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ assert(m.try_lock_until(Clock::now() + ms(250)) == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ std::thread t(f1);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ std::thread t(f2);
+ std::this_thread::sleep_for(ms(300));
+ m.unlock();
+ t.join();
+ }
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until_deadlock_bug.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until_deadlock_bug.pass.cpp
new file mode 100644
index 000000000000..ed288099c979
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until_deadlock_bug.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+// UNSUPPORTED: c++03, c++98, c++11
+
+// <shared_mutex>
+
+// class shared_timed_mutex;
+
+#include <shared_mutex>
+
+#include <atomic>
+#include <chrono>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::shared_timed_mutex m;
+
+const int total_readers = 2;
+std::atomic<int> readers_started(0);
+std::atomic<int> readers_finished(0);
+
+// Wait for the readers to start then try and acquire the write lock.
+void writer_one() {
+ while (readers_started != total_readers) {}
+ bool b = m.try_lock_for(std::chrono::milliseconds(500));
+ assert(b == false);
+}
+
+void blocked_reader() {
+ ++readers_started;
+ // Wait until writer_one is waiting for the write lock.
+ while (m.try_lock_shared()) {
+ m.unlock_shared();
+ }
+ // Attempt to get the read lock. writer_one should be blocking us because
+ // writer_one is blocked by main.
+ m.lock_shared();
+ ++readers_finished;
+ m.unlock_shared();
+}
+
+int main()
+{
+ typedef std::chrono::steady_clock Clock;
+
+ m.lock_shared();
+ std::thread t1(writer_one);
+ // create some readers
+ std::thread t2(blocked_reader);
+ std::thread t3(blocked_reader);
+ // Kill the test after 10 seconds if it hasn't completed.
+ auto end_point = Clock::now() + std::chrono::seconds(10);
+ while (readers_finished != total_readers && Clock::now() < end_point) {
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+ }
+ assert(readers_finished == total_readers);
+ m.unlock_shared();
+ t1.join();
+ t2.join();
+ t3.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/nothing_to_do.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..b58f5c55b643
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/assign.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/assign.fail.cpp
new file mode 100644
index 000000000000..58006833ecac
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/assign.fail.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <mutex>
+
+// class timed_mutex;
+
+// timed_mutex& operator=(const timed_mutex&) = delete;
+
+#include <mutex>
+
+int main()
+{
+ std::timed_mutex m0;
+ std::timed_mutex m1;
+ m1 = m0;
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/copy.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/copy.fail.cpp
new file mode 100644
index 000000000000..61ba31d8648e
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/copy.fail.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <mutex>
+
+// class timed_mutex;
+
+// timed_mutex(const timed_mutex&) = delete;
+
+#include <mutex>
+
+int main()
+{
+ std::timed_mutex m0;
+ std::timed_mutex m1(m0);
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/default.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/default.pass.cpp
new file mode 100644
index 000000000000..33320a7e260a
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/default.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class timed_mutex;
+
+// timed_mutex();
+
+#include <mutex>
+
+int main()
+{
+ std::timed_mutex m;
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/lock.pass.cpp
new file mode 100644
index 000000000000..fe2dd825c207
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/lock.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class timed_mutex;
+
+// void lock();
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+#include <iostream>
+
+std::timed_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ m.lock();
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock.pass.cpp
new file mode 100644
index 000000000000..b32a2664551a
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class timed_mutex;
+
+// bool try_lock();
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::timed_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ assert(!m.try_lock());
+ assert(!m.try_lock());
+ assert(!m.try_lock());
+ while(!m.try_lock())
+ ;
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(200)); // within 200ms
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_for.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_for.pass.cpp
new file mode 100644
index 000000000000..46222a70c8d9
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_for.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class timed_mutex;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::timed_mutex m;
+
+typedef std::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ assert(m.try_lock_for(ms(300)) == true);
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ assert(m.try_lock_for(ms(250)) == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ std::thread t(f1);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ std::thread t(f2);
+ std::this_thread::sleep_for(ms(300));
+ m.unlock();
+ t.join();
+ }
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_until.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_until.pass.cpp
new file mode 100644
index 000000000000..6c9c442ab124
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.class/try_lock_until.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class timed_mutex;
+
+// template <class Clock, class Duration>
+// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::timed_mutex m;
+
+typedef std::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ assert(m.try_lock_until(Clock::now() + ms(300)) == true);
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ assert(m.try_lock_until(Clock::now() + ms(250)) == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ std::thread t(f1);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ std::thread t(f2);
+ std::this_thread::sleep_for(ms(300));
+ m.unlock();
+ t.join();
+ }
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/assign.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/assign.fail.cpp
new file mode 100644
index 000000000000..ae84be838d66
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/assign.fail.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <mutex>
+
+// class recursive_timed_mutex;
+
+// recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
+
+#include <mutex>
+
+int main()
+{
+ std::recursive_timed_mutex m0;
+ std::recursive_timed_mutex m1;
+ m1 = m0;
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/copy.fail.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/copy.fail.cpp
new file mode 100644
index 000000000000..487d6a8c269c
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/copy.fail.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <mutex>
+
+// class recursive_timed_mutex;
+
+// recursive_timed_mutex(const recursive_timed_mutex&) = delete;
+
+#include <mutex>
+
+int main()
+{
+ std::recursive_timed_mutex m0;
+ std::recursive_timed_mutex m1(m0);
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/default.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/default.pass.cpp
new file mode 100644
index 000000000000..56e1874dc126
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/default.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class recursive_timed_mutex;
+
+// recursive_timed_mutex();
+
+#include <mutex>
+
+int main()
+{
+ std::recursive_timed_mutex m;
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/lock.pass.cpp
new file mode 100644
index 000000000000..91f747bc1ab0
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/lock.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class recursive_timed_mutex;
+
+// void lock();
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+#include <iostream>
+
+std::recursive_timed_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ m.lock();
+ time_point t1 = Clock::now();
+ m.lock();
+ m.unlock();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock.pass.cpp
new file mode 100644
index 000000000000..63c3cfee38a3
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock.pass.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class recursive_timed_mutex;
+
+// bool try_lock();
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::recursive_timed_mutex m;
+
+typedef std::chrono::system_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f()
+{
+ time_point t0 = Clock::now();
+ assert(!m.try_lock());
+ assert(!m.try_lock());
+ assert(!m.try_lock());
+ while(!m.try_lock())
+ ;
+ time_point t1 = Clock::now();
+ assert(m.try_lock());
+ m.unlock();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(200)); // within 200ms
+}
+
+int main()
+{
+ m.lock();
+ std::thread t(f);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_for.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_for.pass.cpp
new file mode 100644
index 000000000000..3c1d6ddc6f40
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_for.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class recursive_timed_mutex;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::recursive_timed_mutex m;
+
+typedef std::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ assert(m.try_lock_for(ms(300)) == true);
+ time_point t1 = Clock::now();
+ assert(m.try_lock());
+ m.unlock();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ns(50000000)); // within 50ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ assert(m.try_lock_for(ms(250)) == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ns(50000000)); // within 50ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ std::thread t(f1);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ std::thread t(f2);
+ std::this_thread::sleep_for(ms(300));
+ m.unlock();
+ t.join();
+ }
+}
diff --git a/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_until.pass.cpp b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_until.pass.cpp
new file mode 100644
index 000000000000..066eb7b3064c
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.mutex.requirements/thread.timedmutex.requirements/thread.timedmutex.recursive/try_lock_until.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// class recursive_timed_mutex;
+
+// template <class Clock, class Duration>
+// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <mutex>
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+std::recursive_timed_mutex m;
+
+typedef std::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef std::chrono::milliseconds ms;
+typedef std::chrono::nanoseconds ns;
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ assert(m.try_lock_until(Clock::now() + ms(300)) == true);
+ time_point t1 = Clock::now();
+ assert(m.try_lock());
+ m.unlock();
+ m.unlock();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ assert(m.try_lock_until(Clock::now() + ms(250)) == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ assert(d < ms(50)); // within 50ms
+}
+
+int main()
+{
+ {
+ m.lock();
+ std::thread t(f1);
+ std::this_thread::sleep_for(ms(250));
+ m.unlock();
+ t.join();
+ }
+ {
+ m.lock();
+ std::thread t(f2);
+ std::this_thread::sleep_for(ms(300));
+ m.unlock();
+ t.join();
+ }
+}
diff --git a/test/std/thread/thread.mutex/thread.once/nothing_to_do.pass.cpp b/test/std/thread/thread.mutex/thread.once/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..b58f5c55b643
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.once/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp b/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp
new file mode 100644
index 000000000000..89b99348459b
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.once/thread.once.callonce/call_once.pass.cpp
@@ -0,0 +1,254 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <mutex>
+
+// struct once_flag;
+
+// template<class Callable, class ...Args>
+// void call_once(once_flag& flag, Callable&& func, Args&&... args);
+
+#include <mutex>
+#include <thread>
+#include <cassert>
+
+typedef std::chrono::milliseconds ms;
+
+std::once_flag flg0;
+
+int init0_called = 0;
+
+void init0()
+{
+ std::this_thread::sleep_for(ms(250));
+ ++init0_called;
+}
+
+void f0()
+{
+ std::call_once(flg0, init0);
+}
+
+std::once_flag flg3;
+
+int init3_called = 0;
+int init3_completed = 0;
+
+void init3()
+{
+ ++init3_called;
+ std::this_thread::sleep_for(ms(250));
+ if (init3_called == 1)
+ throw 1;
+ ++init3_completed;
+}
+
+void f3()
+{
+ try
+ {
+ std::call_once(flg3, init3);
+ }
+ catch (...)
+ {
+ }
+}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+struct init1
+{
+ static int called;
+
+ void operator()(int i) {called += i;}
+};
+
+int init1::called = 0;
+
+std::once_flag flg1;
+
+void f1()
+{
+ std::call_once(flg1, init1(), 1);
+}
+
+struct init2
+{
+ static int called;
+
+ void operator()(int i, int j) const {called += i + j;}
+};
+
+int init2::called = 0;
+
+std::once_flag flg2;
+
+void f2()
+{
+ std::call_once(flg2, init2(), 2, 3);
+ std::call_once(flg2, init2(), 4, 5);
+}
+
+#endif // _LIBCPP_HAS_NO_VARIADICS
+
+std::once_flag flg41;
+std::once_flag flg42;
+
+int init41_called = 0;
+int init42_called = 0;
+
+void init42();
+
+void init41()
+{
+ std::this_thread::sleep_for(ms(250));
+ ++init41_called;
+}
+
+void init42()
+{
+ std::this_thread::sleep_for(ms(250));
+ ++init42_called;
+}
+
+void f41()
+{
+ std::call_once(flg41, init41);
+ std::call_once(flg42, init42);
+}
+
+void f42()
+{
+ std::call_once(flg42, init42);
+ std::call_once(flg41, init41);
+}
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+class MoveOnly
+{
+#if !defined(__clang__)
+ // GCC 4.8 complains about the following being private
+public:
+ MoveOnly(const MoveOnly&)
+ {
+ }
+#else
+ MoveOnly(const MoveOnly&);
+#endif
+public:
+ MoveOnly() {}
+ MoveOnly(MoveOnly&&) {}
+
+ void operator()(MoveOnly&&)
+ {
+ }
+};
+
+class NonCopyable
+{
+#if !defined(__clang__)
+ // GCC 4.8 complains about the following being private
+public:
+ NonCopyable(const NonCopyable&)
+ {
+ }
+#else
+ NonCopyable(const NonCopyable&);
+#endif
+public:
+ NonCopyable() {}
+
+ void operator()(int&) {}
+};
+
+#if __cplusplus >= 201103L
+// reference qualifiers on functions are a C++11 extension
+struct RefQual
+{
+ int lv_called, rv_called;
+
+ RefQual() : lv_called(0), rv_called(0) {}
+
+ void operator()() & { ++lv_called; }
+ void operator()() && { ++rv_called; }
+};
+#endif
+#endif
+
+int main()
+{
+ // check basic functionality
+ {
+ std::thread t0(f0);
+ std::thread t1(f0);
+ t0.join();
+ t1.join();
+ assert(init0_called == 1);
+ }
+ // check basic exception safety
+ {
+ std::thread t0(f3);
+ std::thread t1(f3);
+ t0.join();
+ t1.join();
+ assert(init3_called == 2);
+ assert(init3_completed == 1);
+ }
+ // check deadlock avoidance
+ {
+ std::thread t0(f41);
+ std::thread t1(f42);
+ t0.join();
+ t1.join();
+ assert(init41_called == 1);
+ assert(init42_called == 1);
+ }
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+ // check functors with 1 arg
+ {
+ std::thread t0(f1);
+ std::thread t1(f1);
+ t0.join();
+ t1.join();
+ assert(init1::called == 1);
+ }
+ // check functors with 2 args
+ {
+ std::thread t0(f2);
+ std::thread t1(f2);
+ t0.join();
+ t1.join();
+ assert(init2::called == 5);
+ }
+ {
+ std::once_flag f;
+ std::call_once(f, MoveOnly(), MoveOnly());
+ }
+ // check LWG2442: call_once() shouldn't DECAY_COPY()
+ {
+ std::once_flag f;
+ int i = 0;
+ std::call_once(f, NonCopyable(), i);
+ }
+#if __cplusplus >= 201103L
+// reference qualifiers on functions are a C++11 extension
+ {
+ std::once_flag f1, f2;
+ RefQual rq;
+ std::call_once(f1, rq);
+ assert(rq.lv_called == 1);
+ std::call_once(f2, std::move(rq));
+ assert(rq.rv_called == 1);
+ }
+#endif
+#endif // _LIBCPP_HAS_NO_VARIADICS
+}
diff --git a/test/std/thread/thread.mutex/thread.once/thread.once.onceflag/assign.fail.cpp b/test/std/thread/thread.mutex/thread.once/thread.once.onceflag/assign.fail.cpp
new file mode 100644
index 000000000000..c4714276432c
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.once/thread.once.onceflag/assign.fail.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <mutex>
+
+// struct once_flag;
+
+// once_flag& operator=(const once_flag&) = delete;
+
+#include <mutex>
+
+int main()
+{
+ std::once_flag f;
+ std::once_flag f2;
+ f2 = f;
+}
diff --git a/test/std/thread/thread.mutex/thread.once/thread.once.onceflag/copy.fail.cpp b/test/std/thread/thread.mutex/thread.once/thread.once.onceflag/copy.fail.cpp
new file mode 100644
index 000000000000..450ba8361391
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.once/thread.once.onceflag/copy.fail.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <mutex>
+
+// struct once_flag;
+
+// once_flag(const once_flag&) = delete;
+
+#include <mutex>
+
+int main()
+{
+ std::once_flag f;
+ std::once_flag f2(f);
+}
diff --git a/test/std/thread/thread.mutex/thread.once/thread.once.onceflag/default.pass.cpp b/test/std/thread/thread.mutex/thread.once/thread.once.onceflag/default.pass.cpp
new file mode 100644
index 000000000000..6995f0648335
--- /dev/null
+++ b/test/std/thread/thread.mutex/thread.once/thread.once.onceflag/default.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <mutex>
+
+// struct once_flag;
+
+// constexpr once_flag() noexcept;
+
+#include <mutex>
+
+int main()
+{
+ {
+ std::once_flag f;
+ }
+#ifndef _LIBCPP_HAS_NO_CONSTEXPR
+ {
+ constexpr std::once_flag f;
+ }
+#endif
+}
diff --git a/test/std/thread/thread.mutex/version.pass.cpp b/test/std/thread/thread.mutex/version.pass.cpp
new file mode 100644
index 000000000000..81b52c79204b
--- /dev/null
+++ b/test/std/thread/thread.mutex/version.pass.cpp
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <mutex>
+
+#include <mutex>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.req/nothing_to_do.pass.cpp b/test/std/thread/thread.req/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..b58f5c55b643
--- /dev/null
+++ b/test/std/thread/thread.req/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.req/thread.req.exception/nothing_to_do.pass.cpp b/test/std/thread/thread.req/thread.req.exception/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..b58f5c55b643
--- /dev/null
+++ b/test/std/thread/thread.req/thread.req.exception/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.req/thread.req.lockable/nothing_to_do.pass.cpp b/test/std/thread/thread.req/thread.req.lockable/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..b58f5c55b643
--- /dev/null
+++ b/test/std/thread/thread.req/thread.req.lockable/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.basic/nothing_to_do.pass.cpp b/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.basic/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..b58f5c55b643
--- /dev/null
+++ b/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.basic/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.general/nothing_to_do.pass.cpp b/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.general/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..b58f5c55b643
--- /dev/null
+++ b/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.general/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.req/nothing_to_do.pass.cpp b/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.req/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..b58f5c55b643
--- /dev/null
+++ b/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.req/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.timed/nothing_to_do.pass.cpp b/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.timed/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..b58f5c55b643
--- /dev/null
+++ b/test/std/thread/thread.req/thread.req.lockable/thread.req.lockable.timed/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.req/thread.req.native/nothing_to_do.pass.cpp b/test/std/thread/thread.req/thread.req.native/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..b58f5c55b643
--- /dev/null
+++ b/test/std/thread/thread.req/thread.req.native/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.req/thread.req.paramname/nothing_to_do.pass.cpp b/test/std/thread/thread.req/thread.req.paramname/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..b58f5c55b643
--- /dev/null
+++ b/test/std/thread/thread.req/thread.req.paramname/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.req/thread.req.timing/nothing_to_do.pass.cpp b/test/std/thread/thread.req/thread.req.timing/nothing_to_do.pass.cpp
new file mode 100644
index 000000000000..b58f5c55b643
--- /dev/null
+++ b/test/std/thread/thread.req/thread.req.timing/nothing_to_do.pass.cpp
@@ -0,0 +1,12 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.algorithm/swap.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.algorithm/swap.pass.cpp
new file mode 100644
index 000000000000..4d3a742dd168
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.algorithm/swap.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// class thread
+
+// void swap(thread& x, thread& y);
+
+#include <thread>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() : alive_(1) {++n_alive;}
+ G(const G& g) : alive_(g.alive_) {++n_alive;}
+ ~G() {alive_ = 0; --n_alive;}
+
+ void operator()()
+ {
+ assert(alive_ == 1);
+ assert(n_alive >= 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ G g;
+ std::thread t0(g);
+ std::thread::id id0 = t0.get_id();
+ std::thread t1;
+ std::thread::id id1 = t1.get_id();
+ swap(t0, t1);
+ assert(t0.get_id() == id1);
+ assert(t1.get_id() == id0);
+ t1.join();
+ }
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/copy.fail.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/copy.fail.cpp
new file mode 100644
index 000000000000..7373886f6173
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/copy.fail.cpp
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <thread>
+
+// class thread
+
+// thread& operator=(thread&& t);
+
+#include <thread>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() : alive_(1) {++n_alive;}
+ G(const G& g) : alive_(g.alive_) {++n_alive;}
+ ~G() {alive_ = 0; --n_alive;}
+
+ void operator()()
+ {
+ assert(alive_ == 1);
+ assert(n_alive >= 1);
+ op_run = true;
+ }
+
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ std::thread t0(G());
+ std::thread t1;
+ t1 = t0;
+ }
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move.pass.cpp
new file mode 100644
index 000000000000..2db9430a698d
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move.pass.cpp
@@ -0,0 +1,65 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// class thread
+
+// thread& operator=(thread&& t);
+
+#include <thread>
+#include <cassert>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() : alive_(1) {++n_alive;}
+ G(const G& g) : alive_(g.alive_) {++n_alive;}
+ ~G() {alive_ = 0; --n_alive;}
+
+ void operator()(int i, double j)
+ {
+ assert(alive_ == 1);
+ assert(n_alive >= 1);
+ assert(i == 5);
+ assert(j == 5.5);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ assert(G::n_alive == 0);
+ assert(!G::op_run);
+ {
+ G g;
+ std::thread t0(g, 5, 5.5);
+ std::thread::id id = t0.get_id();
+ std::thread t1;
+ t1 = std::move(t0);
+ assert(t1.get_id() == id);
+ assert(t0.get_id() == std::thread::id());
+ t1.join();
+ }
+ assert(G::n_alive == 0);
+ assert(G::op_run);
+ }
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp
new file mode 100644
index 000000000000..7198d226960a
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.assign/move2.pass.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// NOTE: std::terminate is called so the destructors are not invoked and the
+// memory is not freed. This will cause ASAN to fail.
+// XFAIL: asan
+
+// NOTE: TSAN will report this test as leaking a thread.
+// XFAIL: tsan
+
+// <thread>
+
+// class thread
+
+// thread& operator=(thread&& t);
+
+#include <thread>
+#include <exception>
+#include <cstdlib>
+#include <cassert>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() : alive_(1) {++n_alive;}
+ G(const G& g) : alive_(g.alive_) {++n_alive;}
+ ~G() {alive_ = 0; --n_alive;}
+
+ void operator()()
+ {
+ assert(alive_ == 1);
+ assert(n_alive >= 1);
+ op_run = true;
+ }
+
+ void operator()(int i, double j)
+ {
+ assert(alive_ == 1);
+ assert(n_alive >= 1);
+ assert(i == 5);
+ assert(j == 5.5);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+void f1()
+{
+ std::exit(0);
+}
+
+int main()
+{
+ std::set_terminate(f1);
+ {
+ G g;
+ std::thread t0(g, 5, 5.5);
+ std::thread::id id = t0.get_id();
+ std::thread t1;
+ t0 = std::move(t1);
+ assert(false);
+ }
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp
new file mode 100644
index 000000000000..a8b4be16e631
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp
@@ -0,0 +1,154 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// class thread
+
+// template <class F, class ...Args> thread(F&& f, Args&&... args);
+
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <thread>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+
+unsigned throw_one = 0xFFFF;
+
+void* operator new(std::size_t s) throw(std::bad_alloc)
+{
+ if (throw_one == 0)
+ throw std::bad_alloc();
+ --throw_one;
+ return std::malloc(s);
+}
+
+void operator delete(void* p) throw()
+{
+ std::free(p);
+}
+
+bool f_run = false;
+
+void f()
+{
+ f_run = true;
+}
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() : alive_(1) {++n_alive;}
+ G(const G& g) : alive_(g.alive_) {++n_alive;}
+ ~G() {alive_ = 0; --n_alive;}
+
+ void operator()()
+ {
+ assert(alive_ == 1);
+ assert(n_alive >= 1);
+ op_run = true;
+ }
+
+ void operator()(int i, double j)
+ {
+ assert(alive_ == 1);
+ assert(n_alive >= 1);
+ assert(i == 5);
+ assert(j == 5.5);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+
+class MoveOnly
+{
+ MoveOnly(const MoveOnly&);
+public:
+ MoveOnly() {}
+ MoveOnly(MoveOnly&&) {}
+
+ void operator()(MoveOnly&&)
+ {
+ }
+};
+
+#endif
+
+int main()
+{
+ {
+ std::thread t(f);
+ t.join();
+ assert(f_run == true);
+ }
+ f_run = false;
+ {
+ try
+ {
+ throw_one = 0;
+ std::thread t(f);
+ assert(false);
+ }
+ catch (...)
+ {
+ throw_one = 0xFFFF;
+ assert(!f_run);
+ }
+ }
+ {
+ assert(G::n_alive == 0);
+ assert(!G::op_run);
+ std::thread t((G()));
+ t.join();
+ assert(G::n_alive == 0);
+ assert(G::op_run);
+ }
+ G::op_run = false;
+ {
+ try
+ {
+ throw_one = 0;
+ assert(G::n_alive == 0);
+ assert(!G::op_run);
+ std::thread t((G()));
+ assert(false);
+ }
+ catch (...)
+ {
+ throw_one = 0xFFFF;
+ assert(G::n_alive == 0);
+ assert(!G::op_run);
+ }
+ }
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+ {
+ assert(G::n_alive == 0);
+ assert(!G::op_run);
+ std::thread t(G(), 5, 5.5);
+ t.join();
+ assert(G::n_alive == 0);
+ assert(G::op_run);
+ }
+ {
+ std::thread t = std::thread(MoveOnly(), MoveOnly());
+ t.join();
+ }
+#endif // _LIBCPP_HAS_NO_VARIADICS
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/constr.fail.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/constr.fail.cpp
new file mode 100644
index 000000000000..a331add96263
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/constr.fail.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <thread>
+
+// class thread
+// template <class _Fp, class ..._Args,
+// explicit thread(_Fp&& __f, _Args&&... __args);
+// This constructor shall not participate in overload resolution
+// if decay<F>::type is the same type as std::thread.
+
+
+#include <thread>
+#include <cassert>
+
+int main()
+{
+ volatile std::thread t1;
+ std::thread t2 ( t1, 1, 2.0 );
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/copy.fail.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/copy.fail.cpp
new file mode 100644
index 000000000000..f66474c93b42
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/copy.fail.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+
+// <thread>
+
+// class thread
+
+// thread(const thread&) = delete;
+
+#include <thread>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() : alive_(1) {++n_alive;}
+ G(const G& g) : alive_(g.alive_) {++n_alive;}
+ ~G() {alive_ = 0; --n_alive;}
+
+ void operator()()
+ {
+ assert(alive_ == 1);
+ assert(n_alive >= 1);
+ op_run = true;
+ }
+
+ void operator()(int i, double j)
+ {
+ assert(alive_ == 1);
+ assert(n_alive >= 1);
+ assert(i == 5);
+ assert(j == 5.5);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ assert(G::n_alive == 0);
+ assert(!G::op_run);
+ std::thread t0(G(), 5, 5.5);
+ std::thread::id id = t0.get_id();
+ std::thread t1 = t0;
+ assert(t1.get_id() == id);
+ assert(t0.get_id() == std::thread::id());
+ t1.join();
+ assert(G::n_alive == 0);
+ assert(G::op_run);
+ }
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/default.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/default.pass.cpp
new file mode 100644
index 000000000000..64d5a935ba55
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/default.pass.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// class thread
+
+// thread();
+
+#include <thread>
+#include <cassert>
+
+int main()
+{
+ std::thread t;
+ assert(t.get_id() == std::thread::id());
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/move.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/move.pass.cpp
new file mode 100644
index 000000000000..e88304ec8da9
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/move.pass.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// class thread
+
+// thread(thread&& t);
+
+#include <thread>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() : alive_(1) {++n_alive;}
+ G(const G& g) : alive_(g.alive_) {++n_alive;}
+ ~G() {alive_ = 0; --n_alive;}
+
+ void operator()()
+ {
+ assert(alive_ == 1);
+ assert(n_alive >= 1);
+ op_run = true;
+ }
+
+ void operator()(int i, double j)
+ {
+ assert(alive_ == 1);
+ assert(n_alive >= 1);
+ assert(i == 5);
+ assert(j == 5.5);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ G g;
+ assert(G::n_alive == 1);
+ assert(!G::op_run);
+ std::thread t0(g, 5, 5.5);
+ std::thread::id id = t0.get_id();
+ std::thread t1 = std::move(t0);
+ assert(t1.get_id() == id);
+ assert(t0.get_id() == std::thread::id());
+ t1.join();
+ assert(G::n_alive == 1);
+ assert(G::op_run);
+ }
+ assert(G::n_alive == 0);
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.pass.cpp
new file mode 100644
index 000000000000..ddf96d095730
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.pass.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// NOTE: TSAN will report this test as leaking a thread.
+// XFAIL: tsan
+
+// <thread>
+
+// class thread
+
+// ~thread();
+
+#include <thread>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() : alive_(1) {++n_alive;}
+ G(const G& g) : alive_(g.alive_) {++n_alive;}
+ ~G() {alive_ = 0; --n_alive;}
+
+ void operator()()
+ {
+ assert(alive_ == 1);
+ assert(n_alive >= 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+void f1()
+{
+ std::exit(0);
+}
+
+int main()
+{
+ std::set_terminate(f1);
+ {
+ assert(G::n_alive == 0);
+ assert(!G::op_run);
+ G g;
+ {
+ std::thread t(g);
+ std::this_thread::sleep_for(std::chrono::milliseconds(250));
+ }
+ }
+ assert(false);
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/assign.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/assign.pass.cpp
new file mode 100644
index 000000000000..585f7ea98a03
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/assign.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// class thread::id
+
+// id& operator=(const id&) = default;
+
+#include <thread>
+#include <cassert>
+
+int main()
+{
+ std::thread::id id0;
+ std::thread::id id1;
+ id1 = id0;
+ assert(id1 == id0);
+ id1 = std::this_thread::get_id();
+ assert(id1 != id0);
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/copy.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/copy.pass.cpp
new file mode 100644
index 000000000000..e8c38016b288
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/copy.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// class thread::id
+
+// id(const id&) = default;
+
+#include <thread>
+#include <cassert>
+
+int main()
+{
+ std::thread::id id0;
+ std::thread::id id1 = id0;
+ assert(id1 == id0);
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/default.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/default.pass.cpp
new file mode 100644
index 000000000000..0037deb1dd65
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/default.pass.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// class thread::id
+
+// id();
+
+#include <thread>
+#include <cassert>
+
+int main()
+{
+ std::thread::id id;
+ assert(id == std::thread::id());
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/eq.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/eq.pass.cpp
new file mode 100644
index 000000000000..6dd4c3ec4f57
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/eq.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// class thread::id
+
+// bool operator==(thread::id x, thread::id y);
+// bool operator!=(thread::id x, thread::id y);
+
+#include <thread>
+#include <cassert>
+
+int main()
+{
+ std::thread::id id0;
+ std::thread::id id1;
+ id1 = id0;
+ assert( (id1 == id0));
+ assert(!(id1 != id0));
+ id1 = std::this_thread::get_id();
+ assert(!(id1 == id0));
+ assert( (id1 != id0));
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/lt.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/lt.pass.cpp
new file mode 100644
index 000000000000..de52b1d00cdf
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/lt.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// class thread::id
+
+// bool operator< (thread::id x, thread::id y);
+// bool operator<=(thread::id x, thread::id y);
+// bool operator> (thread::id x, thread::id y);
+// bool operator>=(thread::id x, thread::id y);
+
+#include <thread>
+#include <cassert>
+
+int main()
+{
+ std::thread::id id0;
+ std::thread::id id1;
+ std::thread::id id2 = std::this_thread::get_id();
+ assert(!(id0 < id1));
+ assert( (id0 <= id1));
+ assert(!(id0 > id1));
+ assert( (id0 >= id1));
+ assert(!(id0 == id2));
+ if (id0 < id2) {
+ assert( (id0 <= id2));
+ assert(!(id0 > id2));
+ assert(!(id0 >= id2));
+ } else {
+ assert(!(id0 <= id2));
+ assert( (id0 > id2));
+ assert( (id0 >= id2));
+ }
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
new file mode 100644
index 000000000000..126965fe3fc3
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// class thread::id
+
+// template<class charT, class traits>
+// basic_ostream<charT, traits>&
+// operator<<(basic_ostream<charT, traits>& out, thread::id id);
+
+#include <thread>
+#include <sstream>
+#include <cassert>
+
+int main()
+{
+ std::thread::id id0 = std::this_thread::get_id();
+ std::ostringstream os;
+ os << id0;
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/thread_id.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/thread_id.pass.cpp
new file mode 100644
index 000000000000..106c69e2e4a1
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.id/thread_id.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <functional>
+
+// template <class T>
+// struct hash
+// : public unary_function<T, size_t>
+// {
+// size_t operator()(T val) const;
+// };
+
+// Not very portable
+
+#include <thread>
+#include <cassert>
+
+int main()
+{
+ std::thread::id id1;
+ std::thread::id id2 = std::this_thread::get_id();
+ typedef std::hash<std::thread::id> H;
+ static_assert((std::is_same<typename H::argument_type, std::thread::id>::value), "" );
+ static_assert((std::is_same<typename H::result_type, std::size_t>::value), "" );
+ H h;
+ assert(h(id1) != h(id2));
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.cpp
new file mode 100644
index 000000000000..f4a4d1f777f1
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// class thread
+
+// void detach();
+
+#include <thread>
+#include <atomic>
+#include <cassert>
+
+std::atomic_bool done = ATOMIC_VAR_INIT(false);
+
+class G
+{
+ int alive_;
+ bool done_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() : alive_(1), done_(false)
+ {
+ ++n_alive;
+ }
+
+ G(const G& g) : alive_(g.alive_), done_(false)
+ {
+ ++n_alive;
+ }
+ ~G()
+ {
+ alive_ = 0;
+ --n_alive;
+ if (done_) done = true;
+ }
+
+ void operator()()
+ {
+ assert(alive_ == 1);
+ assert(n_alive >= 1);
+ op_run = true;
+ done_ = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ G g;
+ std::thread t0(g);
+ assert(t0.joinable());
+ t0.detach();
+ assert(!t0.joinable());
+ while (!done) {}
+ assert(G::op_run);
+ assert(G::n_alive == 1);
+ }
+ assert(G::n_alive == 0);
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/get_id.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/get_id.pass.cpp
new file mode 100644
index 000000000000..5cca7b0b66b8
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/get_id.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// class thread
+
+// id get_id() const;
+
+#include <thread>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() : alive_(1) {++n_alive;}
+ G(const G& g) : alive_(g.alive_) {++n_alive;}
+ ~G() {alive_ = 0; --n_alive;}
+
+ void operator()()
+ {
+ assert(alive_ == 1);
+ assert(n_alive >= 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ G g;
+ std::thread t0(g);
+ std::thread::id id0 = t0.get_id();
+ std::thread t1;
+ std::thread::id id1 = t1.get_id();
+ assert(t0.get_id() != id1);
+ assert(t1.get_id() == std::thread::id());
+ t0.join();
+ }
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp
new file mode 100644
index 000000000000..0512e49dcb33
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// class thread
+
+// void join();
+
+#include <thread>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() : alive_(1) {++n_alive;}
+ G(const G& g) : alive_(g.alive_) {++n_alive;}
+ ~G() {alive_ = 0; --n_alive;}
+
+ void operator()()
+ {
+ assert(alive_ == 1);
+ assert(n_alive >= 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ G g;
+ std::thread t0(g);
+ assert(t0.joinable());
+ t0.join();
+ assert(!t0.joinable());
+ }
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/joinable.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/joinable.pass.cpp
new file mode 100644
index 000000000000..b97839c32184
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/joinable.pass.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// class thread
+
+// bool joinable() const;
+
+#include <thread>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() : alive_(1) {++n_alive;}
+ G(const G& g) : alive_(g.alive_) {++n_alive;}
+ ~G() {alive_ = 0; --n_alive;}
+
+ void operator()()
+ {
+ assert(alive_ == 1);
+ assert(n_alive >= 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ G g;
+ std::thread t0(g);
+ assert(t0.joinable());
+ t0.join();
+ assert(!t0.joinable());
+ }
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp
new file mode 100644
index 000000000000..c8807a965c44
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// class thread
+
+// native_handle_type native_handle();
+
+#include <thread>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() : alive_(1) {++n_alive;}
+ G(const G& g) : alive_(g.alive_) {++n_alive;}
+ ~G() {alive_ = 0; --n_alive;}
+
+ void operator()()
+ {
+ assert(alive_ == 1);
+ assert(n_alive >= 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ G g;
+ std::thread t0(g);
+ pthread_t pid = t0.native_handle();
+ assert(pid != 0);
+ t0.join();
+ }
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/swap.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/swap.pass.cpp
new file mode 100644
index 000000000000..49d4618e86ad
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.member/swap.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// class thread
+
+// void swap(thread& t);
+
+#include <thread>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+
+class G
+{
+ int alive_;
+public:
+ static int n_alive;
+ static bool op_run;
+
+ G() : alive_(1) {++n_alive;}
+ G(const G& g) : alive_(g.alive_) {++n_alive;}
+ ~G() {alive_ = 0; --n_alive;}
+
+ void operator()()
+ {
+ assert(alive_ == 1);
+ assert(n_alive >= 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ G g;
+ std::thread t0(g);
+ std::thread::id id0 = t0.get_id();
+ std::thread t1;
+ std::thread::id id1 = t1.get_id();
+ t0.swap(t1);
+ assert(t0.get_id() == id1);
+ assert(t1.get_id() == id0);
+ t1.join();
+ }
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/thread.thread.static/hardware_concurrency.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/thread.thread.static/hardware_concurrency.pass.cpp
new file mode 100644
index 000000000000..4d1ffad45937
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/thread.thread.static/hardware_concurrency.pass.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// class thread
+
+// unsigned hardware_concurrency();
+
+#include <thread>
+#include <cassert>
+
+int main()
+{
+ assert(std::thread::hardware_concurrency() > 0);
+}
diff --git a/test/std/thread/thread.threads/thread.thread.class/types.pass.cpp b/test/std/thread/thread.threads/thread.thread.class/types.pass.cpp
new file mode 100644
index 000000000000..a5bf77031cca
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.class/types.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// class thread
+// {
+// public:
+// typedef pthread_t native_handle_type;
+// ...
+// };
+
+#include <thread>
+#include <type_traits>
+
+int main()
+{
+ static_assert((std::is_same<std::thread::native_handle_type, pthread_t>::value), "");
+}
diff --git a/test/std/thread/thread.threads/thread.thread.this/get_id.pass.cpp b/test/std/thread/thread.threads/thread.thread.this/get_id.pass.cpp
new file mode 100644
index 000000000000..3b4b7823a831
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.this/get_id.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// thread::id this_thread::get_id();
+
+#include <thread>
+#include <cassert>
+
+int main()
+{
+ std::thread::id id = std::this_thread::get_id();
+ assert(id != std::thread::id());
+}
diff --git a/test/std/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp b/test/std/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp
new file mode 100644
index 000000000000..27e1d2a1d42f
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp
@@ -0,0 +1,57 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// template <class Rep, class Period>
+// void sleep_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+#include <cstring>
+#include <signal.h>
+#include <sys/time.h>
+
+void sig_action(int) {}
+
+int main()
+{
+ int ec;
+ struct sigaction action;
+ action.sa_handler = &sig_action;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+
+ ec = sigaction(SIGALRM, &action, nullptr);
+ assert(!ec);
+
+ struct itimerval it;
+ std::memset(&it, 0, sizeof(itimerval));
+ it.it_value.tv_sec = 0;
+ it.it_value.tv_usec = 250000;
+ // This will result in a SIGALRM getting fired resulting in the nanosleep
+ // inside sleep_for getting EINTR.
+ ec = setitimer(ITIMER_REAL, &it, nullptr);
+ assert(!ec);
+
+ typedef std::chrono::system_clock Clock;
+ typedef Clock::time_point time_point;
+ typedef Clock::duration duration;
+ std::chrono::milliseconds ms(500);
+ time_point t0 = Clock::now();
+ std::this_thread::sleep_for(ms);
+ time_point t1 = Clock::now();
+ std::chrono::nanoseconds ns = (t1 - t0) - ms;
+ std::chrono::nanoseconds err = 5 * ms / 100;
+ // The time slept is within 5% of 500ms
+ assert(std::abs(ns.count()) < err.count());
+}
diff --git a/test/std/thread/thread.threads/thread.thread.this/sleep_until.pass.cpp b/test/std/thread/thread.threads/thread.thread.this/sleep_until.pass.cpp
new file mode 100644
index 000000000000..9f3941b93adf
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.this/sleep_until.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// template <class Clock, class Duration>
+// void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <thread>
+#include <cstdlib>
+#include <cassert>
+
+int main()
+{
+ typedef std::chrono::system_clock Clock;
+ typedef Clock::time_point time_point;
+ typedef Clock::duration duration;
+ std::chrono::milliseconds ms(500);
+ time_point t0 = Clock::now();
+ std::this_thread::sleep_until(t0 + ms);
+ time_point t1 = Clock::now();
+ std::chrono::nanoseconds ns = (t1 - t0) - ms;
+ std::chrono::nanoseconds err = 5 * ms / 100;
+ // The time slept is within 5% of 500ms
+ assert(std::abs(ns.count()) < err.count());
+}
diff --git a/test/std/thread/thread.threads/thread.thread.this/yield.pass.cpp b/test/std/thread/thread.threads/thread.thread.this/yield.pass.cpp
new file mode 100644
index 000000000000..daf5b0cf7abf
--- /dev/null
+++ b/test/std/thread/thread.threads/thread.thread.this/yield.pass.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+// void this_thread::yield();
+
+#include <thread>
+#include <cassert>
+
+int main()
+{
+ std::this_thread::yield();
+}
diff --git a/test/std/thread/thread.threads/version.pass.cpp b/test/std/thread/thread.threads/version.pass.cpp
new file mode 100644
index 000000000000..d16b0eb06842
--- /dev/null
+++ b/test/std/thread/thread.threads/version.pass.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-threads
+
+// <thread>
+
+#include <thread>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main()
+{
+}