summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/thread/test
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:45:59 +0000
commit19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch)
tree42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/thread/test
parentInitial commit. (diff)
downloadceph-6d07fdb6bb33b1af39833b850bb6cf8af79fe293.tar.xz
ceph-6d07fdb6bb33b1af39833b850bb6cf8af79fe293.zip
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/thread/test')
-rw-r--r--src/boost/libs/thread/test/Carbon.r18
-rw-r--r--src/boost/libs/thread/test/Jamfile.v21098
-rw-r--r--src/boost/libs/thread/test/condition_test_common.hpp97
-rw-r--r--src/boost/libs/thread/test/experimental/parallel/v1/exception_list_pass.cpp23
-rw-r--r--src/boost/libs/thread/test/experimental/parallel/v2/task_region_pass.cpp295
-rw-r--r--src/boost/libs/thread/test/functional/invoke/invoke_int_0_pass.cpp68
-rw-r--r--src/boost/libs/thread/test/functional/invoke/invoke_lvalue_pass.cpp336
-rw-r--r--src/boost/libs/thread/test/functional/invoke/invoke_rvalue_pass.cpp227
-rw-r--r--src/boost/libs/thread/test/functional/invoker/invoker_int_0_pass.cpp68
-rw-r--r--src/boost/libs/thread/test/functional/invoker/invoker_lvalue_pass.cpp342
-rw-r--r--src/boost/libs/thread/test/functional/invoker/invoker_rvalue_pass.cpp230
-rw-r--r--src/boost/libs/thread/test/no_implicit_assign_from_lvalue_thread.cpp17
-rw-r--r--src/boost/libs/thread/test/no_implicit_move_from_lvalue_thread.cpp16
-rw-r--r--src/boost/libs/thread/test/remove_error_code_unused_warning.hpp17
-rw-r--r--src/boost/libs/thread/test/self_contained_header.cpp26
-rw-r--r--src/boost/libs/thread/test/shared_mutex_locking_thread.hpp145
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable/assign_fail.cpp31
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable/copy_fail.cpp30
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable/default_pass.cpp27
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable/dtor_pass.cpp69
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable/lost_notif_pass.cpp241
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable/native_handle_pass.cpp37
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable/wait_for_pass.cpp116
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable/wait_for_pred_pass.cpp127
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable/wait_pass.cpp79
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable/wait_until_pass.cpp128
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable/wait_until_pred_pass.cpp146
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable_any/assign_fail.cpp30
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable_any/copy_fail.cpp30
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable_any/default_pass.cpp28
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable_any/dtor_pass.cpp69
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable_any/lost_notif_pass.cpp241
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pass.cpp104
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pred_pass.cpp118
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pass.cpp115
-rw-r--r--src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pred_pass.cpp134
-rw-r--r--src/boost/libs/thread/test/sync/conditions/cv_status/cv_status_pass.cpp60
-rw-r--r--src/boost/libs/thread/test/sync/conditions/notify_all_at_thread_exit_pass.cpp51
-rw-r--r--src/boost/libs/thread/test/sync/futures/async/async_executor_pass.cpp250
-rw-r--r--src/boost/libs/thread/test/sync/futures/async/async_pass.cpp903
-rw-r--r--src/boost/libs/thread/test/sync/futures/future/async_deferred_then_pass.cpp153
-rw-r--r--src/boost/libs/thread/test/sync/futures/future/copy_assign_fail.cpp40
-rw-r--r--src/boost/libs/thread/test/sync/futures/future/copy_ctor_fail.cpp38
-rw-r--r--src/boost/libs/thread/test/sync/futures/future/default_pass.cpp45
-rw-r--r--src/boost/libs/thread/test/sync/futures/future/dtor_pass.cpp109
-rw-r--r--src/boost/libs/thread/test/sync/futures/future/get_or_pass.cpp187
-rw-r--r--src/boost/libs/thread/test/sync/futures/future/get_pass.cpp268
-rw-r--r--src/boost/libs/thread/test/sync/futures/future/move_assign_pass.cpp87
-rw-r--r--src/boost/libs/thread/test/sync/futures/future/move_ctor_pass.cpp78
-rw-r--r--src/boost/libs/thread/test/sync/futures/future/share_pass.cpp84
-rw-r--r--src/boost/libs/thread/test/sync/futures/future/then_deferred_pass.cpp137
-rw-r--r--src/boost/libs/thread/test/sync/futures/future/then_executor_pass.cpp152
-rw-r--r--src/boost/libs/thread/test/sync/futures/future/then_pass.cpp133
-rw-r--r--src/boost/libs/thread/test/sync/futures/future/wait_for_pass.cpp174
-rw-r--r--src/boost/libs/thread/test/sync/futures/future/wait_pass.cpp155
-rw-r--r--src/boost/libs/thread/test/sync/futures/future/wait_until_pass.cpp175
-rw-r--r--src/boost/libs/thread/test/sync/futures/make_ready_future_pass.cpp157
-rw-r--r--src/boost/libs/thread/test/sync/futures/packaged_task/alloc_ctor_pass.cpp181
-rw-r--r--src/boost/libs/thread/test/sync/futures/packaged_task/copy_assign_fail.cpp55
-rw-r--r--src/boost/libs/thread/test/sync/futures/packaged_task/copy_ctor_fail.cpp55
-rw-r--r--src/boost/libs/thread/test/sync/futures/packaged_task/default_ctor_pass.cpp42
-rw-r--r--src/boost/libs/thread/test/sync/futures/packaged_task/dtor_pass.cpp108
-rw-r--r--src/boost/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp378
-rw-r--r--src/boost/libs/thread/test/sync/futures/packaged_task/get_future_pass.cpp80
-rw-r--r--src/boost/libs/thread/test/sync/futures/packaged_task/make_ready_at_thread_exit_pass.cpp189
-rw-r--r--src/boost/libs/thread/test/sync/futures/packaged_task/member_swap_pass.cpp74
-rw-r--r--src/boost/libs/thread/test/sync/futures/packaged_task/move_assign_pass.cpp68
-rw-r--r--src/boost/libs/thread/test/sync/futures/packaged_task/move_ctor_pass.cpp64
-rw-r--r--src/boost/libs/thread/test/sync/futures/packaged_task/non_member_swap_pass.cpp65
-rw-r--r--src/boost/libs/thread/test/sync/futures/packaged_task/operator_pass.cpp218
-rw-r--r--src/boost/libs/thread/test/sync/futures/packaged_task/reset_pass.cpp81
-rw-r--r--src/boost/libs/thread/test/sync/futures/packaged_task/types_pass.cpp36
-rw-r--r--src/boost/libs/thread/test/sync/futures/packaged_task/use_allocator_pass.cpp53
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/alloc_ctor_pass.cpp67
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/copy_assign_fail.cpp35
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/copy_ctor_fail.cpp34
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/default_pass.cpp47
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/dtor_pass.cpp116
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/emplace_pass.cpp207
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/get_future_pass.cpp64
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/move_assign_pass.cpp155
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/move_ctor_pass.cpp151
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/set_exception_at_thread_exit_pass.cpp110
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/set_exception_pass.cpp110
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/set_lvalue_at_thread_exit_pass.cpp49
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/set_lvalue_pass.cpp132
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/set_rvalue_at_thread_exit_pass.cpp55
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/set_rvalue_pass.cpp297
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_const_pass.cpp69
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp110
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/set_value_const_pass.cpp118
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/set_value_void_pass.cpp84
-rw-r--r--src/boost/libs/thread/test/sync/futures/promise/use_allocator_pass.cpp47
-rw-r--r--src/boost/libs/thread/test/sync/futures/shared_future/copy_assign_pass.cpp85
-rw-r--r--src/boost/libs/thread/test/sync/futures/shared_future/copy_ctor_pass.cpp77
-rw-r--r--src/boost/libs/thread/test/sync/futures/shared_future/default_pass.cpp45
-rw-r--r--src/boost/libs/thread/test/sync/futures/shared_future/dtor_pass.cpp109
-rw-r--r--src/boost/libs/thread/test/sync/futures/shared_future/get_pass.cpp208
-rw-r--r--src/boost/libs/thread/test/sync/futures/shared_future/move_assign_pass.cpp87
-rw-r--r--src/boost/libs/thread/test/sync/futures/shared_future/move_ctor_pass.cpp78
-rw-r--r--src/boost/libs/thread/test/sync/futures/shared_future/then_executor_pass.cpp149
-rw-r--r--src/boost/libs/thread/test/sync/futures/shared_future/then_pass.cpp156
-rw-r--r--src/boost/libs/thread/test/sync/futures/shared_future/wait_for_pass.cpp174
-rw-r--r--src/boost/libs/thread/test/sync/futures/shared_future/wait_pass.cpp155
-rw-r--r--src/boost/libs/thread/test/sync/futures/shared_future/wait_until_pass.cpp175
-rw-r--r--src/boost/libs/thread/test/sync/futures/test_allocator.hpp158
-rw-r--r--src/boost/libs/thread/test/sync/futures/when_all/iterators_pass.cpp362
-rw-r--r--src/boost/libs/thread/test/sync/futures/when_all/none_pass.cpp44
-rw-r--r--src/boost/libs/thread/test/sync/futures/when_all/one_pass.cpp186
-rw-r--r--src/boost/libs/thread/test/sync/futures/when_all/variadic_pass.cpp300
-rw-r--r--src/boost/libs/thread/test/sync/futures/when_any/iterators_pass.cpp363
-rw-r--r--src/boost/libs/thread/test/sync/futures/when_any/none_pass.cpp44
-rw-r--r--src/boost/libs/thread/test/sync/futures/when_any/one_pass.cpp159
-rw-r--r--src/boost/libs/thread/test/sync/futures/when_any/variadic_pass.cpp323
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/deque_views/single_thread_pass.cpp468
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/adopt_lock_pass.cpp85
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_assign_fail.cpp37
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_ctor_fail.cpp36
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/default_pass.cpp83
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_adopt_lock_compile_fail.cpp21
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_adopt_lock_compile_pass.cpp22
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_compile_fail.cpp22
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_compile_pass.cpp24
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/make_lock_guard_adopt_lock_pass.cpp93
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/make_lock_guard_pass.cpp77
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/types_pass.cpp41
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_assign_fail.cpp31
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_ctor_fail.cpp28
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/default_pass.cpp79
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp70
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/owns_lock_pass.cpp60
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/types_pass.cpp35
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_assign_fail.cpp33
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_ctor_fail.cpp32
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/types_pass.cpp34
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/unique_lock_ctor_pass.cpp52
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/adopt_lock_pass.cpp37
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_assign_fail.cpp41
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_ctor_fail.cpp40
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/default_pass.cpp33
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/defer_lock_pass.cpp35
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/duration_pass.cpp87
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_assign_pass.cpp82
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_pass.cpp47
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_unique_lock_pass.cpp65
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_upgrade_lock_pass.cpp64
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/mutex_pass.cpp86
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/time_point_pass.cpp86
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/try_to_lock_pass.cpp115
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/lock_pass.cpp126
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_for_pass.cpp78
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_pass.cpp74
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_until_pass.cpp76
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/unlock_pass.cpp69
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/member_swap_pass.cpp48
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/non_member_swap_pass.cpp47
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/release_pass.cpp58
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/mutex_pass.cpp38
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/op_bool_pass.cpp38
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/owns_lock_pass.cpp39
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/types_pass.cpp40
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/adopt_lock_pass.cpp88
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_assign_fail.cpp37
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_ctor_fail.cpp36
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/default_pass.cpp86
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/types_pass.cpp41
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/copy_assign_fail.cpp28
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/copy_ctor_fail.cpp27
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/default_pass.cpp74
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp70
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/owns_lock_pass.cpp34
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/types_pass.cpp34
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/adopt_lock_pass.cpp36
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_assign_fail.cpp41
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_ctor_fail.cpp40
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/default_pass.cpp33
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/defer_lock_pass.cpp34
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/duration_pass.cpp94
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_adopt_lock_pass.cpp31
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_defer_lock_pass.cpp32
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_mutex_pass.cpp100
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_try_to_lock_pass.cpp146
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_locks_mutex_pass.cpp94
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_assign_pass.cpp52
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_pass.cpp63
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp69
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp66
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp69
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_for_pass.cpp67
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_pass.cpp63
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_try_pass.cpp64
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_until_pass.cpp67
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/mutex_pass.cpp90
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/time_point_pass.cpp93
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/try_to_lock_pass.cpp120
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/lock_pass.cpp127
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_for_pass.cpp85
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_pass.cpp73
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_until_pass.cpp84
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/unlock_pass.cpp69
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/member_swap_pass.cpp48
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/non_member_swap_pass.cpp47
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/release_pass.cpp58
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/mutex_pass.cpp38
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_bool_pass.cpp48
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_int_fail.cpp39
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/owns_lock_pass.cpp40
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/types_pass.cpp40
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/adopt_lock_pass.cpp37
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_assign_fail.cpp41
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_ctor_fail.cpp40
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/default_pass.cpp33
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/defer_lock_pass.cpp35
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/duration_pass.cpp89
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_assign_pass.cpp66
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_pass.cpp46
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp69
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp66
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp69
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_unique_lock_pass.cpp46
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/mutex_pass.cpp88
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/time_point_pass.cpp88
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/try_to_lock_pass.cpp117
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/lock_pass.cpp126
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_for_pass.cpp78
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_pass.cpp74
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_until_pass.cpp76
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/unlock_pass.cpp69
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/member_swap_pass.cpp48
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/non_member_swap_pass.cpp47
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/release_pass.cpp58
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/mutex_pass.cpp38
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/op_bool_pass.cpp38
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/owns_lock_pass.cpp39
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/types_pass.cpp40
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/mutex/assign_fail.cpp31
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/mutex/copy_fail.cpp31
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/mutex/default_pass.cpp29
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_compile_fail.cpp19
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_compile_pass.cpp18
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_pass.cpp82
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/mutex/native_handle_pass.cpp36
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_compile_fail.cpp19
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_compile_pass.cpp19
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_pass.cpp91
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/assign_fail.cpp30
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/copy_fail.cpp31
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/default_pass.cpp29
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/lock_pass.cpp72
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_for_pass.cpp67
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_pass.cpp70
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_until_pass.cpp65
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp297
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/queue_views/single_thread_pass.cpp468
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/assign_fail.cpp31
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/copy_fail.cpp31
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/default_pass.cpp29
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/lock_pass.cpp88
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp37
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/try_lock_pass.cpp96
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/assign_fail.cpp30
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/copy_fail.cpp31
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/default_pass.cpp29
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/lock_pass.cpp88
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/native_handle_pass.cpp36
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_for_pass.cpp92
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_pass.cpp95
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_until_pass.cpp92
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/assign_fail.cpp31
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/copy_fail.cpp32
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/default_pass.cpp29
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/lock_pass.cpp82
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_for_pass.cpp86
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_pass.cpp90
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_until_pass.cpp84
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/multi_thread_pass.cpp252
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp600
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/sync_deque/multi_thread_pass.cpp256
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/sync_deque/single_thread_pass.cpp403
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_multi_thread_pass.cpp219
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_single_thread_pass.cpp429
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/tq_multi_thread_pass.cpp124
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/tq_single_thread_pass.cpp155
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp256
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/sync_queue/single_thread_pass.cpp374
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/call_pass.cpp144
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_T_assign_pass.cpp30
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_T_ctor_pass.cpp29
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_assign_pass.cpp31
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_ctor_pass.cpp30
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/default_ctor_pass.cpp30
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/indirect_pass.cpp38
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_T_assign_pass.cpp29
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_T_ctor_pass.cpp28
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_assign_pass.cpp30
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_ctor_pass.cpp29
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/swap_T_pass.cpp38
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/swap_pass.cpp31
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/synchronize_pass.cpp41
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/assign_fail.cpp31
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/copy_fail.cpp30
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/default_pass.cpp29
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/lock_pass.cpp83
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/native_handle_pass.cpp37
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_for_pass.cpp90
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_pass.cpp92
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_until_pass.cpp90
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_bind.cpp145
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_lambda.cpp59
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_move.cpp110
-rw-r--r--src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_simple.cpp139
-rw-r--r--src/boost/libs/thread/test/test.mcpbin0 -> 3675 bytes
-rw-r--r--src/boost/libs/thread/test/test_10340.cpp28
-rw-r--r--src/boost/libs/thread/test/test_10963.cpp61
-rw-r--r--src/boost/libs/thread/test/test_10964.cpp191
-rw-r--r--src/boost/libs/thread/test/test_11053.cpp70
-rw-r--r--src/boost/libs/thread/test/test_11256.cpp42
-rw-r--r--src/boost/libs/thread/test/test_11266.cpp29
-rw-r--r--src/boost/libs/thread/test/test_11499.cpp56
-rw-r--r--src/boost/libs/thread/test/test_11611.cpp66
-rw-r--r--src/boost/libs/thread/test/test_11796.cpp33
-rw-r--r--src/boost/libs/thread/test/test_11818.cpp64
-rw-r--r--src/boost/libs/thread/test/test_12293.cpp64
-rw-r--r--src/boost/libs/thread/test/test_12949.cpp20
-rw-r--r--src/boost/libs/thread/test/test_13480b.cpp77
-rw-r--r--src/boost/libs/thread/test/test_13561.cpp17
-rw-r--r--src/boost/libs/thread/test/test_2309.cpp70
-rw-r--r--src/boost/libs/thread/test/test_2501.cpp16
-rw-r--r--src/boost/libs/thread/test/test_2741.cpp79
-rw-r--r--src/boost/libs/thread/test/test_3628.cpp97
-rw-r--r--src/boost/libs/thread/test/test_3837.cpp73
-rw-r--r--src/boost/libs/thread/test/test_4521.cpp31
-rw-r--r--src/boost/libs/thread/test/test_4648.cpp47
-rw-r--r--src/boost/libs/thread/test/test_4882.cpp78
-rw-r--r--src/boost/libs/thread/test/test_5351.cpp52
-rw-r--r--src/boost/libs/thread/test/test_5502.cpp93
-rw-r--r--src/boost/libs/thread/test/test_5542_1.cpp69
-rw-r--r--src/boost/libs/thread/test/test_5542_2.cpp18
-rw-r--r--src/boost/libs/thread/test/test_5542_3.cpp37
-rw-r--r--src/boost/libs/thread/test/test_5891.cpp35
-rw-r--r--src/boost/libs/thread/test/test_6130.cpp49
-rw-r--r--src/boost/libs/thread/test/test_6170.cpp31
-rw-r--r--src/boost/libs/thread/test/test_6174.cpp48
-rw-r--r--src/boost/libs/thread/test/test_7160.cpp36
-rw-r--r--src/boost/libs/thread/test/test_7328.cpp47
-rw-r--r--src/boost/libs/thread/test/test_7571.cpp93
-rw-r--r--src/boost/libs/thread/test/test_7665.cpp39
-rw-r--r--src/boost/libs/thread/test/test_7666.cpp23
-rw-r--r--src/boost/libs/thread/test/test_7720.cpp56
-rw-r--r--src/boost/libs/thread/test/test_7755.cpp94
-rw-r--r--src/boost/libs/thread/test/test_8455.cpp23
-rw-r--r--src/boost/libs/thread/test/test_8508.cpp20
-rw-r--r--src/boost/libs/thread/test/test_8557.cpp140
-rw-r--r--src/boost/libs/thread/test/test_8586.cpp18
-rw-r--r--src/boost/libs/thread/test/test_8596.cpp61
-rw-r--r--src/boost/libs/thread/test/test_8600.cpp140
-rw-r--r--src/boost/libs/thread/test/test_8674.cpp43
-rw-r--r--src/boost/libs/thread/test/test_8943.cpp47
-rw-r--r--src/boost/libs/thread/test/test_8960.cpp53
-rw-r--r--src/boost/libs/thread/test/test_9079_a.cpp57
-rw-r--r--src/boost/libs/thread/test/test_9079_b.cpp86
-rw-r--r--src/boost/libs/thread/test/test_9192.cpp145
-rw-r--r--src/boost/libs/thread/test/test_9303.cpp177
-rw-r--r--src/boost/libs/thread/test/test_9319.cpp60
-rw-r--r--src/boost/libs/thread/test/test_9711.cpp44
-rw-r--r--src/boost/libs/thread/test/test_9856.cpp29
-rw-r--r--src/boost/libs/thread/test/test_barrier.cpp69
-rw-r--r--src/boost/libs/thread/test/test_barrier_size_fct.cpp69
-rw-r--r--src/boost/libs/thread/test/test_barrier_void_fct.cpp68
-rw-r--r--src/boost/libs/thread/test/test_completion_latch.cpp108
-rw-r--r--src/boost/libs/thread/test/test_condition.cpp187
-rw-r--r--src/boost/libs/thread/test/test_condition_notify_all.cpp216
-rw-r--r--src/boost/libs/thread/test/test_condition_notify_one.cpp148
-rw-r--r--src/boost/libs/thread/test/test_condition_timed_wait_times_out.cpp169
-rw-r--r--src/boost/libs/thread/test/test_futures.cpp1236
-rw-r--r--src/boost/libs/thread/test/test_generic_locks.cpp578
-rw-r--r--src/boost/libs/thread/test/test_hardware_concurrency.cpp17
-rw-r--r--src/boost/libs/thread/test/test_latch.cpp70
-rw-r--r--src/boost/libs/thread/test/test_lock_concept.cpp600
-rw-r--r--src/boost/libs/thread/test/test_ml.cpp201
-rw-r--r--src/boost/libs/thread/test/test_ml2.cpp60
-rw-r--r--src/boost/libs/thread/test/test_move_function.cpp134
-rw-r--r--src/boost/libs/thread/test/test_mutex.cpp341
-rw-r--r--src/boost/libs/thread/test/test_once.cpp192
-rw-r--r--src/boost/libs/thread/test/test_physical_concurrency.cpp25
-rw-r--r--src/boost/libs/thread/test/test_scheduled_tp.cpp97
-rw-r--r--src/boost/libs/thread/test/test_scheduler.cpp81
-rw-r--r--src/boost/libs/thread/test/test_scheduling_adaptor.cpp54
-rw-r--r--src/boost/libs/thread/test/test_shared_mutex.cpp281
-rw-r--r--src/boost/libs/thread/test/test_shared_mutex_part_2.cpp294
-rw-r--r--src/boost/libs/thread/test/test_shared_mutex_timed_locks.cpp255
-rw-r--r--src/boost/libs/thread/test/test_shared_mutex_timed_locks_chrono.cpp259
-rw-r--r--src/boost/libs/thread/test/test_thread.cpp222
-rw-r--r--src/boost/libs/thread/test/test_thread_exit.cpp63
-rw-r--r--src/boost/libs/thread/test/test_thread_id.cpp139
-rw-r--r--src/boost/libs/thread/test/test_thread_launching.cpp216
-rw-r--r--src/boost/libs/thread/test/test_thread_mf.cpp135
-rw-r--r--src/boost/libs/thread/test/test_thread_move.cpp50
-rw-r--r--src/boost/libs/thread/test/test_thread_move_return.cpp31
-rw-r--r--src/boost/libs/thread/test/test_thread_return_local.cpp31
-rw-r--r--src/boost/libs/thread/test/test_time_jumps.cpp2398
-rw-r--r--src/boost/libs/thread/test/test_tss.cpp511
-rw-r--r--src/boost/libs/thread/test/test_xtime.cpp97
-rw-r--r--src/boost/libs/thread/test/threads/container/thread_ptr_list_pass.cpp101
-rw-r--r--src/boost/libs/thread/test/threads/container/thread_vector_pass.cpp97
-rw-r--r--src/boost/libs/thread/test/threads/this_thread/get_id/get_id_pass.cpp28
-rw-r--r--src/boost/libs/thread/test/threads/this_thread/sleep_for/sleep_for_pass.cpp63
-rw-r--r--src/boost/libs/thread/test/threads/this_thread/sleep_until/sleep_until_pass.cpp95
-rw-r--r--src/boost/libs/thread/test/threads/thread/assign/copy_fail.cpp70
-rw-r--r--src/boost/libs/thread/test/threads/thread/assign/move_pass.cpp101
-rw-r--r--src/boost/libs/thread/test/threads/thread/constr/FArgs_pass.cpp145
-rw-r--r--src/boost/libs/thread/test/threads/thread/constr/F_pass.cpp150
-rw-r--r--src/boost/libs/thread/test/threads/thread/constr/FrvalueArgs_pass.cpp103
-rw-r--r--src/boost/libs/thread/test/threads/thread/constr/Frvalue_pass.cpp59
-rw-r--r--src/boost/libs/thread/test/threads/thread/constr/copy_fail.cpp86
-rw-r--r--src/boost/libs/thread/test/threads/thread/constr/default_pass.cpp30
-rw-r--r--src/boost/libs/thread/test/threads/thread/constr/lambda_pass.cpp89
-rw-r--r--src/boost/libs/thread/test/threads/thread/constr/move_pass.cpp94
-rw-r--r--src/boost/libs/thread/test/threads/thread/destr/dtor_pass.cpp81
-rw-r--r--src/boost/libs/thread/test/threads/thread/id/hash_pass.cpp40
-rw-r--r--src/boost/libs/thread/test/threads/thread/members/detach_pass.cpp75
-rw-r--r--src/boost/libs/thread/test/threads/thread/members/get_id_pass.cpp73
-rw-r--r--src/boost/libs/thread/test/threads/thread/members/join_pass.cpp135
-rw-r--r--src/boost/libs/thread/test/threads/thread/members/joinable_pass.cpp71
-rw-r--r--src/boost/libs/thread/test/threads/thread/members/native_handle_pass.cpp71
-rw-r--r--src/boost/libs/thread/test/threads/thread/members/swap_pass.cpp73
-rw-r--r--src/boost/libs/thread/test/threads/thread/members/try_join_for_pass.cpp161
-rw-r--r--src/boost/libs/thread/test/threads/thread/members/try_join_until_pass.cpp162
-rw-r--r--src/boost/libs/thread/test/threads/thread/non_members/swap_pass.cpp72
-rw-r--r--src/boost/libs/thread/test/threads/thread/static/hardware_concurrency_pass.cpp28
-rw-r--r--src/boost/libs/thread/test/timming.hpp27
-rw-r--r--src/boost/libs/thread/test/util.inl243
-rw-r--r--src/boost/libs/thread/test/winrt_init.cpp19
433 files changed, 46108 insertions, 0 deletions
diff --git a/src/boost/libs/thread/test/Carbon.r b/src/boost/libs/thread/test/Carbon.r
new file mode 100644
index 000000000..e0ac5b449
--- /dev/null
+++ b/src/boost/libs/thread/test/Carbon.r
@@ -0,0 +1,18 @@
+/*
+ * Permit this Carbon application to launch on OS X
+ *
+ * © 1997-2000 Metrowerks Corp.
+ *
+ * Questions and comments to:
+ * <mailto:support@metrowerks.com>
+ * <http://www.metrowerks.com/>
+ */
+
+
+/*----------------------------carb ¥ Carbon on OS X launch information --------------------------*/
+type 'carb' {
+};
+
+
+resource 'carb'(0) {
+};
diff --git a/src/boost/libs/thread/test/Jamfile.v2 b/src/boost/libs/thread/test/Jamfile.v2
new file mode 100644
index 000000000..5788c83d8
--- /dev/null
+++ b/src/boost/libs/thread/test/Jamfile.v2
@@ -0,0 +1,1098 @@
+# (C) Copyright William E. Kempf 2001.
+# (C) Copyright 2007 Anthony Williams.
+# (C) Copyright 2011-2012 Vicente J.Botet Escriba.
+# Distributed under the Boost Software License, Version 1.0. (See accompanying
+# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#
+# Boost.Threads test Jamfile
+#
+# Additional configuration variables used:
+# 1. PTW32 may be used on Win32 platforms to specify that the pthreads-win32
+# library should be used instead of "native" threads. This feature is
+# mostly used for testing and it's generally recommended you use the
+# native threading libraries instead. PTW32 should be set to be a list
+# of two strings, the first specifying the installation path of the
+# pthreads-win32 library and the second specifying which library
+# variant to link against (see the pthreads-win32 documentation).
+# Example: jam -sPTW32="c:\pthreads-win32 pthreadVCE.lib"
+
+# bring in rules for testing
+import testing ;
+import regex ;
+import path ;
+import os ;
+
+project
+ : requirements
+ <threading>multi
+
+ <define>BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
+
+ <warnings>all
+ <toolset>gcc:<cxxflags>-Wextra
+ <toolset>gcc:<cxxflags>-pedantic
+ <toolset>gcc:<cxxflags>-Wno-long-long
+ #<toolset>gcc:<cxxflags>-ansi
+ #<toolset>gcc:<cxxflags>-fpermissive
+ <toolset>gcc-4:<cxxflags>-Wno-variadic-macros
+ <toolset>gcc-5:<cxxflags>-Wno-variadic-macros
+ #<toolset>gcc:<cxxflags>-Wunused-local-typedefs
+ <toolset>gcc:<cxxflags>-Wunused-function
+ <toolset>gcc:<cxxflags>-Wno-unused-parameter
+
+ <toolset>darwin:<cxxflags>-Wextra
+ <toolset>darwin:<cxxflags>-pedantic
+ <toolset>darwin:<cxxflags>-Wno-long-long
+ #<toolset>darwin:<cxxflags>-ansi # doesn't work for 4.1.2
+ <toolset>darwin:<cxxflags>-fpermissive
+ <toolset>darwin:<cxxflags>-Wno-variadic-macros
+ #<toolset>darwin:<cxxflags>-Wunused-local-typedefs
+ <toolset>darwin:<cxxflags>-Wunused-function
+ <toolset>darwin:<cxxflags>-Wno-unused-parameter
+
+ #<toolset>pathscale:<cxxflags>-Wextra
+ <toolset>pathscale:<cxxflags>-Wno-long-long
+ <toolset>pathscale:<cxxflags>-pedantic
+
+ <toolset>clang:<warnings>on
+ <toolset>clang:<cxxflags>-Wextra
+ #<toolset>clang:<cxxflags>-pedantic
+ <toolset>clang:<cxxflags>-Wno-long-long
+ #<toolset>clang:<cxxflags>-ansi
+ #<toolset>clang:<cxxflags>-fpermissive # doesn't work
+ <toolset>clang:<cxxflags>-Wunused-function
+ <toolset>clang:<cxxflags>-Wno-unused-parameter
+
+ #<toolset>gcc-mingw-4.4.0:<cxxflags>-fdiagnostics-show-option
+ #<toolset>gcc-mingw-4.5.0:<cxxflags>-fdiagnostics-show-option
+ #<toolset>gcc-mingw-4.6.0:<cxxflags>-fdiagnostics-show-option
+ #<toolset>gcc-mingw-4.6.3:<cxxflags>-fdiagnostics-show-option
+ #<toolset>gcc-mingw-4.7.0:<cxxflags>-fdiagnostics-show-option
+ #<toolset>gcc-mingw-4.8.0:<cxxflags>-fdiagnostics-show-option
+
+ <toolset>darwin-4.6.2:<cxxflags>-ansi
+ #<toolset>darwin-4.6.2:<cxxflags>-Wno-delete-non-virtual-dtor # doesn't work
+ <toolset>darwin-4.7.0:<cxxflags>-ansi
+ <toolset>darwin-4.7.0:<cxxflags>-Wno-delete-non-virtual-dtor
+ #<toolset>darwin-4.6.2:<cxxflags>-Wno-unused-local-typedefs
+ #<toolset>darwin-4.7.1:<cxxflags>-Wno-unused-local-typedefs
+ #<toolset>darwin-4.7.2:<cxxflags>-Wno-unused-local-typedefs
+ #<toolset>darwin-4.8.0:<cxxflags>-Wno-unused-local-typedefs
+ #<toolset>darwin-4.6.2x:<cxxflags>-Wno-unused-local-typedefs
+ #<toolset>darwin-4.7.1x:<cxxflags>-Wno-unused-local-typedefs
+ #<toolset>darwin-4.7.2x:<cxxflags>-Wno-unused-local-typedefs
+ #<toolset>darwin-4.8.0x:<cxxflags>-Wno-unused-local-typedefs
+
+ #<toolset>clang-2.8:<cxxflags>-Wno-delete-non-virtual-dtor
+ #<toolset>clang-2.8:<cxxflags>-Wno-unused-function
+ #<toolset>clang-2.9:<cxxflags>-Wno-delete-non-virtual-dtor
+ #<toolset>clang-2.9:<cxxflags>-Wno-unused-function
+ <toolset>clang-3.0:<cxxflags>-Wno-delete-non-virtual-dtor
+ #<toolset>clang-3.0:<cxxflags>-Wno-unused-function
+ #<toolset>clang-3.0:<cxxflags>-Wno-unused-variable
+ #<toolset>clang-3.1:<cxxflags>-Wno-bind-to-temporary-copy
+ #<toolset>clang-3.2:<cxxflags>-Wno-bind-to-temporary-copy
+
+# Note: Some of the remarks from the Intel compiler are disabled
+# remark #193: zero used for undefined preprocessing identifier "XXX"
+# remark #304: access control not specified ("public" by default)
+# remark #593: variable "XXX" was set but never used
+# remark #1418: external function definition with no prior declaration
+# remark #2415: variable "XXX" of static storage duration was declared but never referenced
+
+ <toolset>intel:<cxxflags>-wd193,304,383,444
+ <toolset>intel:<cxxflags>-wd593,981
+ <toolset>intel:<cxxflags>-wd1418
+ <toolset>intel:<cxxflags>-wd2415
+
+ <toolset>msvc:<cxxflags>/wd4100
+ <toolset>msvc:<cxxflags>/wd4512
+ <toolset>msvc:<cxxflags>/wd6246
+ ;
+
+rule thread-run ( sources )
+{
+ sources = $(sources) winrt_init.cpp ;
+ return
+ [ run $(sources) ../build//boost_thread ]
+ [ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
+ : : : : $(sources[1]:B)_lib ]
+ ;
+}
+
+
+rule thread-test ( sources )
+{
+ sources = $(sources) winrt_init.cpp ;
+ return
+ [ run $(sources) ../build//boost_thread : : :
+ <library>/boost/test//boost_unit_test_framework
+ ]
+ [ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
+ : : :
+ <library>/boost/test//boost_unit_test_framework/<link>static
+ : $(sources[1]:B)_lib
+ ]
+ ;
+}
+
+rule thread-run2 ( sources : name )
+{
+ sources = $(sources) winrt_init.cpp ;
+ return
+ [ run $(sources) ../build//boost_thread : : :
+ : $(name) ]
+ [ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
+ : : :
+ : $(name)_lib ]
+ ;
+}
+
+rule thread-run2-noit ( sources : name : reqs * )
+{
+ sources = $(sources) winrt_init.cpp ;
+ return
+ [ run $(sources) ../build//boost_thread : : : $(reqs)
+ : $(name) ]
+ [ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
+ : : : $(reqs)
+ : $(name)_lib ]
+ #[ run $(sources) ../build//boost_thread : : :
+ # <define>BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
+ # : $(name)_noit ]
+ ;
+}
+
+rule thread-run2-noit-pthread ( sources : name )
+{
+ sources = $(sources) winrt_init.cpp ;
+ return
+ [ run $(sources) ../build//boost_thread : : : <threadapi>win32:<build>no
+ : $(name) ]
+ [ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
+ : : : <threadapi>win32:<build>no
+ : $(name)_lib ]
+ #[ run $(sources) ../build//boost_thread : : :
+ # <define>BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
+ # : $(name)_noit ]
+ ;
+}
+
+rule thread-run2-h ( sources : name )
+{
+ sources = $(sources) winrt_init.cpp ;
+ return
+ [ run $(sources) : : :
+ <define>BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
+ <define>BOOST_THREAD_VERSION=3
+ : $(name)_h ]
+ ;
+}
+
+
+rule thread-run-lib2 ( sources : name )
+{
+ sources = $(sources) winrt_init.cpp ;
+ return
+ [ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
+ : : :
+ : $(name)_lib ]
+ ;
+}
+
+
+rule thread-compile-fail ( sources : reqs * : name )
+{
+ return
+ [ compile-fail $(sources)
+ : $(reqs)
+ : $(name) ]
+ ;
+}
+
+rule clang-thread-safety ( properties * )
+{
+ if <toolset>clang in $(properties)
+ {
+ return <cxxflags>-Werror=thread-safety <define>BOOST_THREAD_ENABLE_THREAD_SAFETY_ANALYSIS ;
+ }
+ else
+ {
+ return <build>no ;
+ }
+}
+
+rule thread-safety-compile ( sources : reqs * : name )
+{
+ return
+ [ compile $(sources)
+ : $(reqs) <conditional>@clang-thread-safety
+ : $(name) ]
+ ;
+}
+
+rule thread-safety-compile-fail ( sources : reqs * : name )
+{
+ return
+ [ compile-fail $(sources)
+ : $(reqs) <conditional>@clang-thread-safety
+ : $(name) ]
+ ;
+}
+
+rule thread-compile ( sources : reqs * : name )
+{
+ return
+ [ compile $(sources)
+ : $(reqs)
+ : $(name) ]
+ ;
+}
+
+rule windows-cygwin-specific ( properties * )
+{
+ if <target-os>windows in $(properties) || <target-os>cygwin in $(properties)
+ {
+ return <build>yes ;
+ }
+ else
+ {
+ return <build>no ;
+ }
+}
+
+rule generate_self_contained_header_tests
+{
+ local all_rules ;
+ local file ;
+
+ if ! [ os.environ BOOST_THREAD_TEST_WITHOUT_SELF_CONTAINED_HEADER_TESTS ]
+ {
+ local headers_path = [ path.make $(BOOST_ROOT)/libs/thread/include/boost/thread ] ;
+ for file in [ path.glob-tree $(headers_path) : *.hpp : detail pthread win32 ]
+ {
+ local rel_file = [ path.relative-to $(headers_path) $(file) ] ;
+ # Note: The test name starts with '~' in order to group these tests in the test report table, preferably at the end.
+ # All '/' are replaced with '-' because apparently test scripts have a problem with test names containing slashes.
+ local test_name = [ regex.replace ~hdr/$(rel_file) "/" "-" ] ;
+ #ECHO $(rel_file) ;
+ all_rules += [ compile self_contained_header.cpp : <define>"BOOST_THREAD_TEST_HEADER=$(rel_file)" <dependency>$(file) : $(test_name) ] ;
+ all_rules += [ compile self_contained_header.cpp : <define>"BOOST_THREAD_TEST_HEADER=$(rel_file)" <define>"BOOST_THREAD_TEST_POST_WINDOWS_H" <dependency>$(file) <conditional>@windows-cygwin-specific : $(test_name)-post_winh ] ;
+ }
+ }
+
+ #ECHO All rules: $(all_rules) ;
+ return $(all_rules) ;
+}
+
+{
+ test-suite t_threads
+ :
+ [ thread-test test_thread.cpp ]
+ [ thread-test test_thread_id.cpp ]
+ [ thread-test test_hardware_concurrency.cpp ]
+ [ thread-test test_physical_concurrency.cpp ]
+ [ thread-test test_thread_move.cpp ]
+ [ thread-test test_thread_return_local.cpp ]
+ [ thread-test test_thread_move_return.cpp ]
+ [ thread-test test_thread_launching.cpp ]
+ [ thread-test test_thread_mf.cpp ]
+ [ thread-test test_thread_exit.cpp ]
+ [ thread-test test_move_function.cpp ]
+ [ compile-fail no_implicit_move_from_lvalue_thread.cpp ]
+ [ compile-fail no_implicit_assign_from_lvalue_thread.cpp ]
+ [ thread-test test_tss.cpp ]
+ [ thread-test test_xtime.cpp ]
+ ;
+
+ test-suite t_sync
+ :
+ [ thread-test test_mutex.cpp ]
+ [ thread-test test_condition_notify_one.cpp ]
+ [ thread-test test_condition_timed_wait_times_out.cpp ]
+ [ thread-test test_condition_notify_all.cpp ]
+ [ thread-test test_condition.cpp ]
+ [ thread-test test_once.cpp ]
+ [ thread-run test_barrier.cpp ]
+ [ thread-run test_barrier_void_fct.cpp ]
+ [ thread-run test_barrier_size_fct.cpp ]
+ [ thread-test test_lock_concept.cpp ]
+ [ thread-test test_generic_locks.cpp ]
+ [ thread-run test_latch.cpp ]
+ [ thread-run test_completion_latch.cpp ]
+ ;
+
+ test-suite t_shared
+ :
+ [ thread-test test_shared_mutex.cpp ]
+ [ thread-test test_shared_mutex_part_2.cpp ]
+ [ thread-test test_shared_mutex_timed_locks.cpp ]
+ [ thread-test test_shared_mutex_timed_locks_chrono.cpp ]
+ #uncomment the following once these works on windows
+ #[ thread-test test_vhh_shared_mutex.cpp ]
+ #[ thread-test test_vhh_shared_mutex_part_2.cpp ]
+ #[ thread-test test_vhh_shared_mutex_timed_locks.cpp ]
+ ;
+
+ explicit t_futures_too_long ;
+ test-suite t_futures_too_long
+ :
+ [ thread-test test_futures.cpp ]
+ ;
+
+
+ #explicit tickets ;
+ test-suite tickets
+ :
+ [ thread-test test_2309.cpp ]
+ [ thread-run test_2501.cpp ]
+ [ thread-test test_2741.cpp ]
+ [ thread-run test_3628.cpp ]
+ [ thread-run test_4521.cpp ]
+ [ thread-run test_4648.cpp ]
+ [ thread-run test_4882.cpp ]
+ [ thread-run test_5542_1.cpp ]
+ [ thread-run test_5542_2.cpp ]
+ [ thread-run test_5542_3.cpp ]
+ [ thread-run test_5891.cpp ]
+ #[ thread-run test_6130.cpp ]
+ #[ thread-run test_6170.cpp ]
+ [ thread-run test_6174.cpp ]
+ #[ thread-run test_7160.cpp ]
+ [ thread-run test_7328.cpp ]
+ [ thread-run test_7571.cpp ]
+ [ thread-run test_9319.cpp ]
+ #[ thread-run test_9711.cpp ] This is an invalid use of ::then deferred.
+ [ thread-run test_9856.cpp ]
+ [ thread-compile test_10963.cpp : : test_10963_c ]
+ [ thread-run test_10964.cpp ]
+ [ thread-test test_11053.cpp ]
+ [ thread-run test_11266.cpp ]
+ ;
+
+
+ explicit oth_tickets ;
+ test-suite oth_tickets
+ :
+ [ thread-run test_5351.cpp ]
+ [ thread-run test_5502.cpp ]
+ ;
+
+
+
+ #explicit ts_conditions ;
+ test-suite ts_conditions
+ :
+ [ thread-compile-fail ./sync/conditions/condition_variable/assign_fail.cpp : : condition_variable__assign_f ]
+ [ thread-compile-fail ./sync/conditions/condition_variable/copy_fail.cpp : : condition_variable__copy_f ]
+ [ thread-run2-noit ./sync/conditions/condition_variable/default_pass.cpp : condition_variable__default_p ]
+ [ thread-run2-noit ./sync/conditions/condition_variable/dtor_pass.cpp : condition_variable__dtor_p ]
+ [ thread-run2-noit-pthread ./sync/conditions/condition_variable/native_handle_pass.cpp : condition_variable__native_handle_p ]
+ [ thread-run2-noit ./sync/conditions/condition_variable/wait_pass.cpp : condition_variable__wait_p ]
+ [ thread-run2-noit ./sync/conditions/condition_variable/wait_for_pass.cpp : condition_variable__wait_for_p ]
+ [ thread-run2-noit ./sync/conditions/condition_variable/wait_for_pred_pass.cpp : condition_variable__wait_for_pred_p ]
+ [ thread-run2-noit ./sync/conditions/condition_variable/wait_until_pass.cpp : condition_variable__wait_until_p ]
+ [ thread-run2-noit ./sync/conditions/condition_variable/wait_until_pred_pass.cpp : condition_variable__wait_until_pred_p ]
+ [ thread-run2-noit ./sync/conditions/condition_variable/lost_notif_pass.cpp : condition_variable__lost_notif_p ]
+
+ [ thread-compile-fail ./sync/conditions/condition_variable_any/assign_fail.cpp : : condition_variable_any__assign_f ]
+ [ thread-compile-fail ./sync/conditions/condition_variable_any/copy_fail.cpp : : condition_variable_any__copy_f ]
+ [ thread-run2-noit ./sync/conditions/condition_variable_any/default_pass.cpp : condition_variable_any__default_p ]
+ [ thread-run2-noit ./sync/conditions/condition_variable_any/dtor_pass.cpp : condition_variable_any__dtor_p ]
+ [ thread-run2-noit ./sync/conditions/condition_variable_any/wait_for_pass.cpp : condition_variable_any__wait_for_p ]
+ [ thread-run2-noit ./sync/conditions/condition_variable_any/wait_for_pred_pass.cpp : condition_variable_any__wait_for_pred_p ]
+ [ thread-run2-noit ./sync/conditions/condition_variable_any/wait_until_pass.cpp : condition_variable_any__wait_until_p ]
+ [ thread-run2-noit ./sync/conditions/condition_variable_any/wait_until_pred_pass.cpp : condition_variable_any__wait_until_pred_p ]
+ [ thread-run2-noit ./sync/conditions/condition_variable_any/lost_notif_pass.cpp : condition_variable_any__lost_notif_p ]
+ [ thread-run2-noit ./sync/conditions/cv_status/cv_status_pass.cpp : cv_status__cv_status_p ]
+ [ thread-run2-noit ./sync/conditions/notify_all_at_thread_exit_pass.cpp : notify_all_at_thread_exit_p ]
+ ;
+
+ #explicit ts_async ;
+ test-suite ts_async
+ :
+ [ thread-run2-noit ./sync/futures/async/async_pass.cpp : async__async_p ]
+ [ thread-run2-noit ./sync/futures/async/async_executor_pass.cpp : async__async_executor_p ]
+ ;
+
+ #explicit ts_promise ;
+ test-suite ts_promise
+ :
+ [ thread-compile-fail ./sync/futures/promise/copy_assign_fail.cpp : : promise__copy_assign_f ]
+ [ thread-compile-fail ./sync/futures/promise/copy_ctor_fail.cpp : : promise__copy_ctor_f ]
+ [ thread-run2-noit ./sync/futures/promise/alloc_ctor_pass.cpp : promise__alloc_ctor_p ]
+ [ thread-run2-noit ./sync/futures/promise/default_pass.cpp : promise__default_p ]
+ [ thread-run2-noit ./sync/futures/promise/dtor_pass.cpp : promise__dtor_p ]
+ [ thread-run2-noit ./sync/futures/promise/get_future_pass.cpp : promise__get_future_p ]
+ [ thread-run2-noit ./sync/futures/promise/move_ctor_pass.cpp : promise__move_ctor_p ]
+ [ thread-run2-noit ./sync/futures/promise/move_assign_pass.cpp : promise__move_asign_p ]
+ [ thread-run2-noit ./sync/futures/promise/set_exception_pass.cpp : promise__set_exception_p ]
+ [ thread-run2-noit ./sync/futures/promise/set_lvalue_pass.cpp : promise__set_lvalue_p ]
+ [ thread-run2-noit ./sync/futures/promise/set_rvalue_pass.cpp : promise__set_rvalue_p ]
+ [ thread-run2-noit ./sync/futures/promise/set_value_const_pass.cpp : promise__set_value_const_p ]
+ [ thread-run2-noit ./sync/futures/promise/set_value_void_pass.cpp : promise__set_value_void_p ]
+ [ thread-run2-noit ./sync/futures/promise/emplace_pass.cpp : promise__emplace_p ]
+ [ thread-run2-noit ./sync/futures/promise/use_allocator_pass.cpp : promise__use_allocator_p ]
+ [ thread-run2-noit ./sync/futures/promise/set_exception_at_thread_exit_pass.cpp : promise__set_exception_at_thread_exit_p ]
+ [ thread-run2-noit ./sync/futures/promise/set_lvalue_at_thread_exit_pass.cpp : promise__set_lvalue_at_thread_exit_p ]
+ [ thread-run2-noit ./sync/futures/promise/set_rvalue_at_thread_exit_pass.cpp : promise__set_rvalue_at_thread_exit_p ]
+ [ thread-run2-noit ./sync/futures/promise/set_value_at_thread_exit_const_pass.cpp : promise__set_value_at_thread_exit_const_p ]
+ [ thread-run2-noit ./sync/futures/promise/set_value_at_thread_exit_void_pass.cpp : promise__set_value_at_thread_exit_void_p ]
+ ;
+
+ #explicit ts_make_ready_future ;
+ test-suite ts_make_ready_future
+ :
+ [ thread-run2-noit ./sync/futures/make_ready_future_pass.cpp : make_ready_future_p ]
+ ;
+
+ #explicit ts_future ;
+ test-suite ts_future
+ :
+ [ thread-compile-fail ./sync/futures/future/copy_assign_fail.cpp : : future__copy_assign_f ]
+ [ thread-compile-fail ./sync/futures/future/copy_ctor_fail.cpp : : future__copy_ctor_f ]
+ [ thread-run2-noit ./sync/futures/future/default_pass.cpp : future__default_p ]
+ [ thread-run2-noit ./sync/futures/future/dtor_pass.cpp : future__dtor_p ]
+ [ thread-run2-noit ./sync/futures/future/get_pass.cpp : future__get_p ]
+ [ thread-run2-noit ./sync/futures/future/get_or_pass.cpp : future__get_or_p ]
+ [ thread-run2-noit ./sync/futures/future/move_ctor_pass.cpp : future__move_ctor_p ]
+ [ thread-run2-noit ./sync/futures/future/move_assign_pass.cpp : future__move_asign_p ]
+ [ thread-run2-noit ./sync/futures/future/share_pass.cpp : future__share_p ]
+ [ thread-run2-noit ./sync/futures/future/wait_pass.cpp : future__wait_p ]
+ [ thread-run2-noit ./sync/futures/future/wait_for_pass.cpp : future__wait_for_p ]
+ [ thread-run2-noit ./sync/futures/future/wait_until_pass.cpp : future__wait_until_p ]
+ [ thread-run2-noit ./sync/futures/future/then_pass.cpp : future__then_p ]
+ [ thread-run2-noit ./sync/futures/future/then_executor_pass.cpp : future__then_executor_p ]
+ [ thread-run2-noit ./sync/futures/future/async_deferred_then_pass.cpp : future__async_def_then_p ]
+ [ thread-run2-noit ./sync/futures/future/then_deferred_pass.cpp : future__then_def_p ]
+ ;
+
+ #explicit ts_shared_future ;
+ test-suite ts_shared_future
+ :
+ [ thread-run2-noit ./sync/futures/shared_future/copy_assign_pass.cpp : shared_future__copy_assign_p ]
+ [ thread-run2-noit ./sync/futures/shared_future/copy_ctor_pass.cpp : shared_future__copy_ctor_p ]
+ [ thread-run2-noit ./sync/futures/shared_future/default_pass.cpp : shared_future__default_p ]
+ [ thread-run2-noit ./sync/futures/shared_future/dtor_pass.cpp : shared_future__dtor_p ]
+ [ thread-run2-noit ./sync/futures/shared_future/get_pass.cpp : shared_future__get_p ]
+ [ thread-run2-noit ./sync/futures/shared_future/move_ctor_pass.cpp : shared_future__move_ctor_p ]
+ [ thread-run2-noit ./sync/futures/shared_future/move_assign_pass.cpp : shared_future__move_asign_p ]
+ [ thread-run2-noit ./sync/futures/shared_future/wait_pass.cpp : shared_future__wait_p ]
+ [ thread-run2-noit ./sync/futures/shared_future/wait_for_pass.cpp : shared_future__wait_for_p ]
+ [ thread-run2-noit ./sync/futures/shared_future/wait_until_pass.cpp : shared_future__wait_until_p ]
+ [ thread-run2-noit ./sync/futures/shared_future/then_pass.cpp : shared_future__then_p ]
+ [ thread-run2-noit ./sync/futures/shared_future/then_executor_pass.cpp : shared_future__then_executor_p ]
+ ;
+
+ #explicit ts_packaged_task ;
+ test-suite ts_packaged_task
+ :
+ [ thread-run2-noit ./sync/futures/packaged_task/alloc_ctor_pass.cpp : packaged_task__alloc_ctor_p ]
+ [ thread-compile-fail ./sync/futures/packaged_task/copy_assign_fail.cpp : : packaged_task__copy_assign_f ]
+ [ thread-compile-fail ./sync/futures/packaged_task/copy_ctor_fail.cpp : : packaged_task__copy_ctor_f ]
+ [ thread-run2-noit ./sync/futures/packaged_task/default_ctor_pass.cpp : packaged_task__default_ctor_p ]
+ [ thread-run2-noit ./sync/futures/packaged_task/func_ctor_pass.cpp : packaged_task__func_ctor_p ]
+ [ thread-run2-noit ./sync/futures/packaged_task/dtor_pass.cpp : packaged_task__dtor_p ]
+ [ thread-run2-noit ./sync/futures/packaged_task/get_future_pass.cpp : packaged_task__get_future_p ]
+ [ thread-run2-noit ./sync/futures/packaged_task/move_ctor_pass.cpp : packaged_task__move_ctor_p ]
+ [ thread-run2-noit ./sync/futures/packaged_task/move_assign_pass.cpp : packaged_task__move_asign_p ]
+ [ thread-run2-noit ./sync/futures/packaged_task/operator_pass.cpp : packaged_task__operator_p ]
+ [ thread-run2-noit ./sync/futures/packaged_task/reset_pass.cpp : packaged_task__reset_p ]
+ [ thread-run2-noit ./sync/futures/packaged_task/use_allocator_pass.cpp : packaged_task__use_allocator_p ]
+ [ thread-run2-noit ./sync/futures/packaged_task/types_pass.cpp : packaged_task__types_p ]
+ [ thread-run2-noit ./sync/futures/packaged_task/member_swap_pass.cpp : packaged_task__member_swap_p ]
+ [ thread-run2-noit ./sync/futures/packaged_task/non_member_swap_pass.cpp : packaged_task__non_member_swap_p ]
+ [ thread-run2-noit ./sync/futures/packaged_task/make_ready_at_thread_exit_pass.cpp : packaged_task__make_ready_at_thread_exit_p ]
+ ;
+
+
+ #explicit ts_when_all ;
+ test-suite ts_when_all
+ :
+ [ thread-run2-noit ./sync/futures/when_all/none_pass.cpp : when_all__none_p ]
+ [ thread-run2-noit ./sync/futures/when_all/one_pass.cpp : when_all__one_p ]
+ [ thread-run2-noit ./sync/futures/when_all/iterators_pass.cpp : when_all__iterators_p ]
+ [ thread-run2-noit ./sync/futures/when_all/variadic_pass.cpp : when_all__variadic_p ]
+ ;
+
+ #explicit ts_when_any ;
+ test-suite ts_when_any
+ :
+ [ thread-run2-noit ./sync/futures/when_any/none_pass.cpp : when_any__none_p ]
+ [ thread-run2-noit ./sync/futures/when_any/one_pass.cpp : when_any__one_p ]
+ [ thread-run2-noit ./sync/futures/when_any/iterators_pass.cpp : when_any__iterators_p ]
+ [ thread-run2-noit ./sync/futures/when_any/variadic_pass.cpp : when_any__variadic_p ]
+ ;
+
+ #explicit ts_lock_guard ;
+ test-suite ts_lock_guard
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/lock_guard/copy_assign_fail.cpp : : lock_guard__cons__copy_assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/lock_guard/copy_ctor_fail.cpp : : lock_guard__cons__copy_ctor_f ]
+ [ thread-safety-compile ./sync/mutual_exclusion/locks/lock_guard/lock_guard_compile_pass.cpp : : lock_guard__lock_compile_p ]
+ [ thread-safety-compile-fail ./sync/mutual_exclusion/locks/lock_guard/lock_guard_compile_fail.cpp : : lock_guard__lock_compile_f ]
+ [ thread-safety-compile ./sync/mutual_exclusion/locks/lock_guard/lock_guard_adopt_lock_compile_pass.cpp : : lock_guard__adopt_lock_compile_p ]
+ [ thread-safety-compile-fail ./sync/mutual_exclusion/locks/lock_guard/lock_guard_adopt_lock_compile_fail.cpp : : lock_guard__adopt_lock_compile_f ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/lock_guard/adopt_lock_pass.cpp : lock_guard__cons__adopt_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/lock_guard/default_pass.cpp : lock_guard__cons__default_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/lock_guard/types_pass.cpp : lock_guard__types_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/lock_guard/make_lock_guard_pass.cpp : make_lock_guard_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/lock_guard/make_lock_guard_adopt_lock_pass.cpp : make_lock_guard__adopt_lock_p ]
+ ;
+
+ #explicit ts_unique_lock ;
+ test-suite ts_unique_lock
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/unique_lock/cons/copy_assign_fail.cpp : : unique_lock__cons__copy_assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/unique_lock/cons/copy_ctor_fail.cpp : : unique_lock__cons__copy_ctor_f ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/adopt_lock_pass.cpp : unique_lock__cons__adopt_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/default_pass.cpp : unique_lock__cons__default_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/defer_lock_pass.cpp : unique_lock__cons__defer_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/duration_pass.cpp : unique_lock__cons__duration_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/move_assign_pass.cpp : unique_lock__cons__move_assign_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_pass.cpp : unique_lock__cons__move_ctor_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_pass.cpp : uq_lk_cons_mv_c_upg_lk_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_try_pass.cpp : uq_lk_cons_mv_c_upg_lk_t_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_for_pass.cpp : uq_lk_cons_mv_c_upg_lk_f_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_until_pass.cpp : uq_lk_cons_mv_c_upg_lk_u_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/mutex_pass.cpp : unique_lock__cons__mutex_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/time_point_pass.cpp : unique_lock__cons__time_point_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/try_to_lock_pass.cpp : unique_lock__cons__try_to_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/locking/lock_pass.cpp : unique_lock__lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/locking/try_lock_for_pass.cpp : unique_lock__try_lock_for_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/locking/try_lock_pass.cpp : unique_lock__try_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/locking/try_lock_until_pass.cpp : unique_lock__try_lock_until_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/locking/unlock_pass.cpp : unique_lock__unlock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/mod/member_swap_pass.cpp : unique_lock__member_swap_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/mod/non_member_swap_pass.cpp : unique_lock__non_member_swap_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/mod/release_pass.cpp : unique_lock__release_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/obs/mutex_pass.cpp : unique_lock__mutex_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/obs/op_bool_pass.cpp : unique_lock__op_bool_p ]
+ #[ thread-compile-fail ./sync/mutual_exclusion/locks/unique_lock/obs/op_int_fail.cpp : : unique_lock__op_int_f ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/obs/owns_lock_pass.cpp : unique_lock__owns_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/types_pass.cpp : unique_lock__types_p ]
+
+
+ ;
+
+ #explicit ts_make_unique_lock ;
+ test-suite ts_make_unique_lock
+ :
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_mutex_pass.cpp : make_unique_lock__mutex_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_adopt_lock_pass.cpp : make_unique_lock__adopt_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_defer_lock_pass.cpp : make_unique_lock__defer_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_try_to_lock_pass.cpp : make_unique_lock__try_to_lock_p ]
+
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/make_unique_locks_mutex_pass.cpp : make_unique_locks__mutex_p ]
+
+ ;
+
+ #explicit ts_shared_lock ;
+ test-suite ts_shared_lock
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/shared_lock/cons/copy_assign_fail.cpp : : shared_lock__cons__copy_assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/shared_lock/cons/copy_ctor_fail.cpp : : shared_lock__cons__copy_ctor_f ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/cons/adopt_lock_pass.cpp : shared_lock__cons__adopt_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/cons/default_pass.cpp : shared_lock__cons__default_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/cons/defer_lock_pass.cpp : shared_lock__cons__defer_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/cons/duration_pass.cpp : shared_lock__cons__duration_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/cons/move_assign_pass.cpp : shared_lock__cons__move_assign_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_pass.cpp : shared_lock__cons__move_ctor_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_unique_lock_pass.cpp : sh_lock_cons_move_ctor_unq_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_upgrade_lock_pass.cpp : sh_lock_cons_move_ctor_upg_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/cons/mutex_pass.cpp : shared_lock__cons__mutex_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/cons/time_point_pass.cpp : shared_lock__cons__time_point_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/cons/try_to_lock_pass.cpp : shared_lock__cons__try_to_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/locking/lock_pass.cpp : shared_lock__lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/locking/try_lock_for_pass.cpp : shared_lock__try_lock_for_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/locking/try_lock_pass.cpp : shared_lock__try_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/locking/try_lock_until_pass.cpp : shared_lock__try_lock_until_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/locking/unlock_pass.cpp : shared_lock__unlock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/mod/member_swap_pass.cpp : shared_lock__member_swap_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/mod/non_member_swap_pass.cpp : shared_lock__non_member_swap_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/mod/release_pass.cpp : shared_lock__release_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/obs/mutex_pass.cpp : shared_lock__mutex_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/obs/op_bool_pass.cpp : shared_lock__op_bool_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/obs/owns_lock_pass.cpp : shared_lock__owns_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock/types_pass.cpp : shared_lock__types_p ]
+
+ #[ thread-run2-h ./sync/mutual_exclusion/locks/shared_lock/cons/default_pass.cpp : shared_lock__cons__default_p ]
+ #[ thread-run2-h ./sync/mutual_exclusion/locks/shared_lock/cons/defer_lock_pass.cpp : shared_lock__cons__defer_lock_p ]
+
+ ;
+
+ #explicit ts_upgrade_lock ;
+ test-suite ts_upgrade_lock
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/upgrade_lock/cons/copy_assign_fail.cpp : : upgrade_lock__cons__copy_assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/upgrade_lock/cons/copy_ctor_fail.cpp : : upgrade_lock__cons__copy_ctor_f ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/cons/adopt_lock_pass.cpp : upgrade_lock__cons__adopt_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/cons/default_pass.cpp : upgrade_lock__cons__default_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/cons/defer_lock_pass.cpp : upgrade_lock__cons__defer_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/cons/duration_pass.cpp : upgrade_lock__cons__duration_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_assign_pass.cpp : upgrade_lock__cons__move_assign_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_pass.cpp : upgrade_lock__cons__move_ctor_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_unique_lock_pass.cpp : upg_lock_cons_mv_ctor_uq_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/cons/mutex_pass.cpp : upgrade_lock__cons__mutex_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/cons/time_point_pass.cpp : upgrade_lock__cons__time_point_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/cons/try_to_lock_pass.cpp : upgrade_lock__cons__try_to_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/locking/lock_pass.cpp : upgrade_lock__lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_for_pass.cpp : upgrade_lock__try_lock_for_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_pass.cpp : upgrade_lock__try_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_until_pass.cpp : upgrade_lock__try_lock_until_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/locking/unlock_pass.cpp : upgrade_lock__unlock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/mod/member_swap_pass.cpp : upgrade_lock__member_swap_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/mod/non_member_swap_pass.cpp : upgrade_lock__non_member_swap_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/mod/release_pass.cpp : upgrade_lock__release_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/obs/mutex_pass.cpp : upgrade_lock__mutex_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/obs/op_bool_pass.cpp : upgrade_lock__op_bool_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/obs/owns_lock_pass.cpp : upgrade_lock__owns_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/types_pass.cpp : upgrade_lock__types_p ]
+ ;
+
+ #explicit ts_strict_lock ;
+ test-suite ts_strict_lock
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/strict_lock/copy_assign_fail.cpp : : strict_lock__cons__copy_assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/strict_lock/copy_ctor_fail.cpp : : strict_lock__cons__copy_ctor_f ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/strict_lock/default_pass.cpp : strict_lock__cons__default_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/strict_lock/owns_lock_pass.cpp : strict_lock__owns_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/strict_lock/types_pass.cpp : strict_lock__types_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp : make_strict_lock_p ]
+ ;
+
+ #explicit ts_nested_strict_lock ;
+ test-suite ts_nested_strict_lock
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/nested_strict_lock/copy_assign_fail.cpp : : nested_strict_lock_cons_copy_assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/nested_strict_lock/copy_ctor_fail.cpp : : nested_strict_lock_cons_copy_ctor_f ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/nested_strict_lock/default_pass.cpp : nested_strict_lock__cons__default_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/nested_strict_lock/owns_lock_pass.cpp : nested_strict_lock__owns_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/nested_strict_lock/types_pass.cpp : nested_strict_lock__types_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp : make_nested_strict_lock_p ]
+ ;
+
+
+ #explicit ts_once ;
+ test-suite ts_once
+ :
+ #[ thread-compile-fail ./sync/mutual_exclusion/once/once_flag/assign_fail.cpp : : once_flag__assign_f ]
+ #[ thread-compile-fail ./sync/mutual_exclusion/once/once_flag/copy_fail.cpp : : once_flag__copy_f ]
+ #[ thread-run2-noit ./sync/mutual_exclusion/once/once_flag/default_pass.cpp : once_flag__default_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/once/call_once/call_once_pass.cpp : call_once_p ]
+ ;
+
+ #explicit ts_mutex ;
+ test-suite ts_mutex
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/mutex/assign_fail.cpp : : mutex__assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/mutex/copy_fail.cpp : : mutex__copy_f ]
+ [ thread-safety-compile ./sync/mutual_exclusion/mutex/lock_compile_pass.cpp : : mutex__lock_compile_p ]
+ [ thread-safety-compile-fail ./sync/mutual_exclusion/mutex/lock_compile_fail.cpp : : mutex__lock_compile_f ]
+ # https://bugs.llvm.org/show_bug.cgi?id=32954
+ # http://clang-developers.42468.n3.nabble.com/thread-safety-warnings-specifically-try-acquire-capability-td4059337.html
+ #[ thread-safety-compile ./sync/mutual_exclusion/mutex/try_lock_compile_pass.cpp : : mutex__try_lock_compile_p ]
+ [ thread-safety-compile-fail ./sync/mutual_exclusion/mutex/try_lock_compile_fail.cpp : : mutex__try_lock_compile_f ]
+ [ thread-run2-noit ./sync/mutual_exclusion/mutex/default_pass.cpp : mutex__default_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/mutex/lock_pass.cpp : mutex__lock_p ]
+ [ thread-run2-noit-pthread ./sync/mutual_exclusion/mutex/native_handle_pass.cpp : mutex__native_handle_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/mutex/try_lock_pass.cpp : mutex__try_lock_p ]
+ ;
+
+ #explicit ts_recursive_mutex ;
+ test-suite ts_recursive_mutex
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/recursive_mutex/assign_fail.cpp : : recursive_mutex__assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/recursive_mutex/copy_fail.cpp : : recursive_mutex__copy_f ]
+ [ thread-run2-noit ./sync/mutual_exclusion/recursive_mutex/default_pass.cpp : recursive_mutex__default_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/recursive_mutex/lock_pass.cpp : recursive_mutex__lock_p ]
+ [ thread-run2-noit-pthread ./sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp : recursive_mutex__native_handle_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/recursive_mutex/try_lock_pass.cpp : recursive_mutex__try_lock_p ]
+ ;
+
+ #explicit ts_recursive_timed_mutex ;
+ test-suite ts_recursive_timed_mutex
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/recursive_timed_mutex/assign_fail.cpp : : recursive_timed_mutex__assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/recursive_timed_mutex/copy_fail.cpp : : recursive_timed_mutex__copy_f ]
+ [ thread-run2-noit ./sync/mutual_exclusion/recursive_timed_mutex/default_pass.cpp : recursive_timed_mutex__default_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/recursive_timed_mutex/lock_pass.cpp : recursive_timed_mutex__lock_p ]
+ [ thread-run2-noit-pthread ./sync/mutual_exclusion/recursive_timed_mutex/native_handle_pass.cpp : rec_timed_mutex_native_handle_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/recursive_timed_mutex/try_lock_for_pass.cpp : rec_timed_mutex_try_lock_for_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/recursive_timed_mutex/try_lock_pass.cpp : recursive_timed_mutex__try_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/recursive_timed_mutex/try_lock_until_pass.cpp : rec_timed_mutex_try_lock_until_p ]
+ ;
+
+ #explicit ts_timed_mutex ;
+ test-suite ts_timed_mutex
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/timed_mutex/assign_fail.cpp : : timed_mutex__assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/timed_mutex/copy_fail.cpp : : timed_mutex__copy_f ]
+ [ thread-run2-noit ./sync/mutual_exclusion/timed_mutex/default_pass.cpp : timed_mutex__default_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/timed_mutex/lock_pass.cpp : timed_mutex__lock_p ]
+ [ thread-run2-noit-pthread ./sync/mutual_exclusion/timed_mutex/native_handle_pass.cpp : timed_mutex__native_handle_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/timed_mutex/try_lock_for_pass.cpp : timed_mutex__try_lock_for_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/timed_mutex/try_lock_pass.cpp : timed_mutex__try_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/timed_mutex/try_lock_until_pass.cpp : timed_mutex__try_lock_until_p ]
+ ;
+
+ #explicit ts_shared_mutex ;
+ test-suite ts_shared_mutex
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/shared_mutex/assign_fail.cpp : : shared_mutex__assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/shared_mutex/copy_fail.cpp : : shared_mutex__copy_f ]
+ [ thread-run2-noit ./sync/mutual_exclusion/shared_mutex/default_pass.cpp : shared_mutex__default_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/shared_mutex/lock_pass.cpp : shared_mutex__lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/shared_mutex/try_lock_for_pass.cpp : shared_mutex__try_lock_for_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/shared_mutex/try_lock_pass.cpp : shared_mutex__try_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/shared_mutex/try_lock_until_pass.cpp : shared_mutex__try_lock_until_p ]
+
+ #[ thread-run2-h ./sync/mutual_exclusion/shared_mutex/default_pass.cpp : shared_mutex__default_p ]
+ ;
+
+ #explicit ts_null_mutex ;
+ test-suite ts_null_mutex
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/null_mutex/assign_fail.cpp : : null_mutex__assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/null_mutex/copy_fail.cpp : : null_mutex__copy_f ]
+ [ thread-run2-noit ./sync/mutual_exclusion/null_mutex/default_pass.cpp : null_mutex__default_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/null_mutex/lock_pass.cpp : null_mutex__lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/null_mutex/try_lock_for_pass.cpp : null_mutex__try_lock_for_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/null_mutex/try_lock_pass.cpp : null_mutex__try_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/null_mutex/try_lock_until_pass.cpp : null_mutex__try_lock_until_p ]
+ ;
+
+ test-suite ts_sync_queue
+ :
+ [ thread-run2-noit ./sync/mutual_exclusion/sync_queue/single_thread_pass.cpp : sync_queue__single_thread_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp : sync_queue__multi_thread_p ]
+ ;
+
+ test-suite ts_sync_deque
+ :
+ [ thread-run2-noit ./sync/mutual_exclusion/sync_deque/single_thread_pass.cpp : sync_deque__single_thread_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/sync_deque/multi_thread_pass.cpp : sync_deque__multi_thread_p ]
+ ;
+
+ test-suite ts_sync_bounded_queue
+ :
+ [ thread-run2-noit ./sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp : sync_bounded_q_single_thread_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/sync_bounded_queue/multi_thread_pass.cpp : sync_bounded_q_multi_thread_p ]
+ ;
+
+ test-suite ts_sync_pq
+ :
+ [ thread-run2-noit ./sync/mutual_exclusion/sync_pq/pq_single_thread_pass.cpp : sync_pq_single_thread_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/sync_pq/pq_multi_thread_pass.cpp : sync_pq_multi_thread_p ]
+ ;
+
+ test-suite ts_sync_tq
+ :
+ [ thread-run2-noit ./sync/mutual_exclusion/sync_pq/tq_single_thread_pass.cpp : sync_tq_single_thread_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/sync_pq/tq_multi_thread_pass.cpp : sync_tq_multi_thread_p ]
+ ;
+
+ test-suite ts_scheduler
+ :
+ [ thread-run2-noit ./test_scheduled_tp.cpp : test_scheduled_tp_p ]
+ [ thread-run2-noit ./test_scheduling_adaptor.cpp : test_scheduling_adaptor_p ]
+ [ thread-run2-noit ./test_scheduler.cpp : test_scheduler_p ]
+ ;
+
+ test-suite ts_queue_views
+ :
+ [ thread-run2-noit ./sync/mutual_exclusion/queue_views/single_thread_pass.cpp : queue_views__single_thread_p ]
+ #[ thread-run2-noit ./sync/mutual_exclusion/queue_views/multi_thread_pass.cpp : queue_views__multi_thread_p ]
+ ;
+
+ test-suite ts_deque_views
+ :
+ [ thread-run2-noit ./sync/mutual_exclusion/deque_views/single_thread_pass.cpp : deque_views__single_thread_p ]
+ #[ thread-run2-noit ./sync/mutual_exclusion/deque_views/multi_thread_pass.cpp : deque_views__multi_thread_p ]
+ ;
+
+ #explicit ts_this_thread ;
+ test-suite ts_this_thread
+ :
+ [ thread-run2-noit ./threads/this_thread/get_id/get_id_pass.cpp : this_thread__get_id_p ]
+ [ thread-run2-noit ./threads/this_thread/sleep_for/sleep_for_pass.cpp : this_thread__sleep_for_p ]
+ [ thread-run2-noit ./threads/this_thread/sleep_until/sleep_until_pass.cpp : this_thread__sleep_until_p ]
+ ;
+
+ #explicit ts_thread ;
+ test-suite ts_thread
+ :
+ [ thread-compile-fail ./threads/thread/assign/copy_fail.cpp : : thread__assign__copy_f ]
+ [ thread-run2-noit ./threads/thread/assign/move_pass.cpp : thread__assign__move_p ]
+ [ thread-compile-fail ./threads/thread/constr/copy_fail.cpp : : thread__constr__copy_f ]
+ [ thread-run2-noit ./threads/thread/constr/default_pass.cpp : thread__constr__default_p ]
+ [ thread-run-lib2 ./threads/thread/constr/lambda_pass.cpp : thread__constr__lambda_p ]
+ [ thread-run-lib2 ./threads/thread/constr/F_pass.cpp : thread__constr__F_p ]
+ [ thread-run-lib2 ./threads/thread/constr/FArgs_pass.cpp : thread__constr__FArgs_p ]
+ [ thread-run2-noit ./threads/thread/constr/Frvalue_pass.cpp : thread__constr__Frvalue_p ]
+ [ thread-run2-noit ./threads/thread/constr/FrvalueArgs_pass.cpp : thread__constr__FrvalueArgs_p ]
+ [ thread-run2-noit ./threads/thread/constr/move_pass.cpp : thread__constr__move_p ]
+ [ thread-run2-noit ./threads/thread/destr/dtor_pass.cpp : thread__destr__dtor_p ]
+ [ thread-run2-noit ./threads/thread/id/hash_pass.cpp : thread__id__hash_p ]
+ [ thread-run2-noit ./threads/thread/members/detach_pass.cpp : thread__detach_p ]
+ [ thread-run2-noit ./threads/thread/members/get_id_pass.cpp : thread__get_id_p ]
+ [ thread-run2-noit ./threads/thread/members/join_pass.cpp : thread__join_p ]
+ [ thread-run2-noit ./threads/thread/members/try_join_until_pass.cpp : thread__join_until_p ]
+ [ thread-run2-noit ./threads/thread/members/try_join_for_pass.cpp : thread__join_for_p ]
+ [ thread-run2-noit ./threads/thread/members/joinable_pass.cpp : thread__joinable_p ]
+ [ thread-run2-noit ./threads/thread/members/native_handle_pass.cpp : thread__native_handle_p ]
+ [ thread-run2-noit ./threads/thread/members/swap_pass.cpp : thread__swap_p ]
+ [ thread-run2-noit ./threads/thread/non_members/swap_pass.cpp : swap_threads_p ]
+ [ thread-run2-noit ./threads/thread/static/hardware_concurrency_pass.cpp : thread__hardware_concurrency_p ]
+ ;
+
+ #explicit ts_container ;
+ test-suite ts_container
+ :
+ [ thread-run2-noit ./threads/container/thread_vector_pass.cpp : container__thread_vector_p ]
+ [ thread-run2-noit ./threads/container/thread_ptr_list_pass.cpp : container__thread_ptr_list_p ]
+ ;
+
+ explicit ts_examples_too_long ;
+ test-suite ts_examples_too_long
+ :
+ [ thread-run2 ../example/shared_mutex.cpp : ex_shared_mutex ]
+ ;
+
+ #explicit ts_examples ;
+ test-suite ts_examples
+ :
+ [ thread-run2-noit ../example/monitor.cpp : ex_monitor ]
+ [ thread-compile ../example/starvephil.cpp : : ex_starvephil ]
+ [ thread-run2 ../example/tennis.cpp : ex_tennis ]
+ [ thread-compile ../example/condition.cpp : : ex_condition ]
+ [ thread-run2-noit ../example/mutex.cpp : ex_mutex ]
+ [ thread-run2-noit ../example/once.cpp : ex_once ]
+ [ thread-run2-noit ../example/recursive_mutex.cpp : ex_recursive_mutex ]
+ [ thread-run2-noit ../example/thread.cpp : ex_thread ]
+ [ thread-run2-noit ../example/thread_group.cpp : ex_thread_group ]
+ [ thread-run2-noit ../example/tss.cpp : ex_tss ]
+ [ thread-run2 ../example/xtime.cpp : ex_xtime ]
+ [ thread-run2 ../example/shared_monitor.cpp : ex_shared_monitor ]
+ #[ thread-run ../example/vhh_shared_monitor.cpp ]
+ #[ thread-run ../example/vhh_shared_mutex.cpp ]
+ [ thread-run2 ../example/make_future.cpp : ex_make_future ]
+ [ thread-run2 ../example/future_then.cpp : ex_future_then ]
+ [ thread-run2 ../example/future_fallback_to.cpp : ex_future_fallback_to ]
+ [ thread-run2 ../example/future_unwrap.cpp : ex_future_unwrap ]
+ [ thread-run2-noit ../example/synchronized_value.cpp : ex_synchronized_value ]
+ [ thread-run2-noit ../example/synchronized_person.cpp : ex_synchronized_person ]
+ [ thread-run2-noit ../example/thread_guard.cpp : ex_thread_guard ]
+ [ thread-run2-noit ../example/std_thread_guard.cpp : ex_std_thread_guard : <toolset>gcc-4.8:<build>no ]
+ [ thread-run2-noit ../example/scoped_thread.cpp : ex_scoped_thread ]
+ [ thread-run2-noit ../example/std_scoped_thread.cpp : ex_std_scoped_thread : <toolset>gcc-4.8:<build>no ]
+ [ thread-run2-noit ../example/strict_lock.cpp : ex_strict_lock ]
+ [ thread-run2-noit ../example/ba_externallly_locked.cpp : ex_ba_externallly_locked ]
+ [ thread-run2 ../example/producer_consumer_bounded.cpp : ex_producer_consumer_bounded ]
+ [ thread-run2 ../example/producer_consumer.cpp : ex_producer_consumer ]
+ [ thread-run2 ../example/producer_consumer2.cpp : ex_producer_consumer2 ]
+ [ thread-run2 ../example/not_interleaved.cpp : ex_not_interleaved ]
+ [ thread-run2 ../example/lambda_future.cpp : ex_lambda_future ]
+ [ thread-run2 ../example/not_interleaved2.cpp : ex_not_interleaved2 ]
+ [ thread-run2 ../example/thread_pool.cpp : ex_thread_pool ]
+ [ thread-run2 ../example/user_scheduler.cpp : ex_user_scheduler ]
+ [ thread-run2 ../example/executor.cpp : ex_executor ]
+ [ thread-run2 ../example/generic_executor_ref.cpp : ex_generic_executor_ref ]
+ [ thread-run2 ../example/serial_executor.cpp : ex_serial_executor ]
+ #[ thread-run2 ../example/serial_executor_cont.cpp : ex_serial_executor_cont ]
+ [ thread-run2 ../example/future_when_all.cpp : ex_future_when_all ]
+ [ thread-run2 ../example/parallel_accumulate.cpp : ex_parallel_accumulate ]
+ [ thread-run2 ../example/parallel_quick_sort.cpp : ex_parallel_quick_sort ]
+ [ thread-run2 ../example/with_lock_guard.cpp : ex_with_lock_guard ]
+ [ thread-run2 ../example/fib_task_region.cpp : ex_fib_task_region ]
+ ;
+
+ #explicit ts_shared_upwards ;
+ test-suite ts_shared_upwards
+ :
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp : uq_lock_cons_mv_ctor_sh_lock_try_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp : uq_lock_cons_mv_ctor_sh_lock_for_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp : uq_lock_cons_mv_ctor_sh_lock_until_p ]
+
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp : upg_lock_cons_move_ctor_sh_lock_try_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp : upg_lock_cons_move_ctor_sh_lock_for_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp : upg_lock_cons_move_ctor_sh_lock_untl_p ]
+ ;
+
+
+ #explicit ts_shared_lock_guard ;
+ test-suite ts_shared_lock_guard
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/shared_lock_guard/copy_assign_fail.cpp : : shared_lock_guard__cons__copy_assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/shared_lock_guard/copy_ctor_fail.cpp : : shared_lock_guard__cons__copy_ctor_f ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock_guard/adopt_lock_pass.cpp : shared_lock_guard__cons__adopt_lock_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock_guard/default_pass.cpp : shared_lock_guard__cons__default_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/shared_lock_guard/types_pass.cpp : shared_lock_guard__types_p ]
+ ;
+
+ #explicit ts_reverse_lock ;
+ test-suite ts_reverse_lock
+ :
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/reverse_lock/copy_assign_fail.cpp : : reverse_lock__copy_assign_f ]
+ [ thread-compile-fail ./sync/mutual_exclusion/locks/reverse_lock/copy_ctor_fail.cpp : : reverse_lock__copy_ctor_f ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/reverse_lock/unique_lock_ctor_pass.cpp : reverse_lock__unique_lock_ctor_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/locks/reverse_lock/types_pass.cpp : reverse_lock__types_p ]
+ ;
+
+
+ #explicit ts_synchronized_value ;
+ test-suite ts_synchronized_value
+ :
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/copy_assign_pass.cpp : synchronized_value__copy_assign_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/copy_ctor_pass.cpp : synchronized_value__copy_ctor_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/copy_T_assign_pass.cpp : synchronized_value__copy_T_assign_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/copy_T_ctor_pass.cpp : synchronized_value__copy_T_ctor_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/default_ctor_pass.cpp : synchronized_value__default_ctor_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/indirect_pass.cpp : synchronized_value__indirect_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/move_assign_pass.cpp : synchronized_value__move_assign_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/move_ctor_pass.cpp : synchronized_value__move_ctor_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/move_T_assign_pass.cpp : synchronized_value__move_T_assign_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/move_T_ctor_pass.cpp : synchronized_value__move_T_ctor_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/swap_pass.cpp : synchronized_value__swap_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/swap_T_pass.cpp : synchronized_value__swap_T_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/synchronize_pass.cpp : synchronized_value__synchronize_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/call_pass.cpp : synchronized_value__call_p ]
+
+ ;
+
+
+ test-suite ts_with_lock_guard
+ :
+ [ thread-run2-noit ./sync/mutual_exclusion/with_lock_guard/with_lock_guard_simple.cpp : with_lock_guard_simple_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/with_lock_guard/with_lock_guard_bind.cpp : with_lock_guard_bind_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/with_lock_guard/with_lock_guard_move.cpp : with_lock_guard_move_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/with_lock_guard/with_lock_guard_lambda.cpp : with_lock_guard_lambda_p ]
+ ;
+
+ explicit ts_invoke ;
+ test-suite ts_invoke
+ :
+ [ thread-run2-noit ./functional/invoke/invoke_int_0_pass.cpp : invoke_int_0_p ]
+ [ thread-run2-noit ./functional/invoke/invoke_lvalue_pass.cpp : invoke_lvalue_p ]
+ [ thread-run2-noit ./functional/invoke/invoke_rvalue_pass.cpp : invoke_rvalue_p ]
+ ;
+
+ explicit ts_invoker ;
+ test-suite ts_invoker
+ :
+ [ thread-run2-noit ./functional/invoker/invoker_int_0_pass.cpp : invoker_int_0_p ]
+ [ thread-run2-noit ./functional/invoker/invoker_lvalue_pass.cpp : invoker_lvalue_p ]
+ [ thread-run2-noit ./functional/invoker/invoker_rvalue_pass.cpp : invoker_rvalue_p ]
+ ;
+
+
+
+ explicit ts_more ;
+ test-suite ts_more
+ :
+ [ thread-run test_7666.cpp ]
+ [ thread-run test_7720.cpp ]
+ [ thread-run test_7755.cpp ]
+ [ thread-run test_8455.cpp ]
+ [ thread-run test_8508.cpp ]
+ #[ thread-run test_8557.cpp ]
+ [ thread-run test_8586.cpp ]
+ [ thread-run test_8943.cpp ]
+ [ thread-run test_8960.cpp ]
+ [ thread-run test_9079_a.cpp ]
+ [ thread-run test_9079_b.cpp ]
+ [ thread-run test_9192.cpp ]
+ #[ thread-run test_9303.cpp ]
+ #[ thread-run test_9720.cpp ]
+ #[ thread-run test_10125.cpp ]
+ #[ thread-run test_10128.cpp ]
+ #[ thread-run test_10340.cpp ]
+ ;
+
+ explicit ts_more_cpp11 ;
+ test-suite ts_more_cpp11
+ :
+ [ thread-run test_8596.cpp ]
+ [ thread-run test_8600.cpp ]
+ ;
+
+ explicit perf ;
+ test-suite perf
+ :
+ #[ thread-run ../example/perf_condition_variable.cpp ]
+ #[ thread-run ../example/perf_shared_mutex.cpp ]
+ ;
+
+
+ #explicit ts_exception_list ;
+ test-suite ts_exception_list
+ :
+ [ thread-run2-noit ./experimental/parallel/v1/exception_list_pass.cpp : exception_list_p ]
+ ;
+
+ #explicit ts_task_region ;
+ test-suite ts_task_region
+ :
+ [ thread-run2-noit ./experimental/parallel/v2/task_region_pass.cpp : task_region_p ]
+ ;
+
+ explicit ts_other ;
+ test-suite ts_other
+ :
+ [ thread-run2 ../example/this_executor.cpp : ex_this_executor ]
+ [ thread-run2 ../example/default_executor.cpp : ex_default_executor ]
+ ;
+
+ explicit ts_ ;
+ test-suite ts_
+ :
+ #[ thread-run test_11256.cpp ]
+ #[ thread-run test_11256.cpp ]
+ #[ thread-run test_11499.cpp ]
+ #[ thread-run test_11611.cpp ]
+ #[ thread-run test_11818.cpp ]
+ #[ thread-run test_11796.cpp ]
+ #[ thread-run test_12293.cpp ]
+ #[ thread-run test_12949.cpp ]
+ #[ thread-run test_13480b.cpp ]
+ [ thread-run test_13561.cpp ]
+
+ ;
+
+ explicit test_time_jumps_1_obj ;
+ obj test_time_jumps_1_obj : test_time_jumps.cpp :
+ # BOOST_THREAD_USES_MOVE is required to prevent ambiguity between the two definitions
+ # of boost::move when using sync_priority_queue/sync_timed_queue with POD data types.
+ <define>BOOST_THREAD_USES_MOVE
+ <define>BOOST_THREAD_PROVIDES_FUTURE
+ ;
+
+ explicit test_time_jumps_2_obj ;
+ obj test_time_jumps_2_obj : test_time_jumps.cpp :
+ # BOOST_THREAD_USES_MOVE is required to prevent ambiguity between the two definitions
+ # of boost::move when using sync_priority_queue/sync_timed_queue with POD data types.
+ <define>BOOST_THREAD_USES_MOVE
+ <define>BOOST_THREAD_PROVIDES_FUTURE
+ <define>BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+ ;
+
+ explicit test_time_jumps_3_obj ;
+ obj test_time_jumps_3_obj : test_time_jumps.cpp :
+ # BOOST_THREAD_USES_MOVE is required to prevent ambiguity between the two definitions
+ # of boost::move when using sync_priority_queue/sync_timed_queue with POD data types.
+ <define>BOOST_THREAD_USES_MOVE
+ <define>BOOST_THREAD_PROVIDES_FUTURE
+ <define>BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+ <define>BOOST_THREAD_V2_SHARED_MUTEX
+ ;
+
+ explicit test_time_jumps ;
+ test-suite test_time_jumps
+ :
+ [ exe test_time_jumps_1 : test_time_jumps_1_obj ../build//boost_thread ]
+ [ exe test_time_jumps_2 : test_time_jumps_2_obj ../build//boost_thread ]
+ [ exe test_time_jumps_3 : test_time_jumps_3_obj ../build//boost_thread ]
+ ;
+
+ test-suite test_self_contained_headers : [ generate_self_contained_header_tests ] ;
+}
diff --git a/src/boost/libs/thread/test/condition_test_common.hpp b/src/boost/libs/thread/test/condition_test_common.hpp
new file mode 100644
index 000000000..4aa114e05
--- /dev/null
+++ b/src/boost/libs/thread/test/condition_test_common.hpp
@@ -0,0 +1,97 @@
+#ifndef CONDITION_TEST_COMMON_HPP
+#define CONDITION_TEST_COMMON_HPP
+// Copyright (C) 2007 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread_time.hpp>
+
+unsigned const timeout_seconds=5;
+
+struct wait_for_flag
+{
+ boost::mutex mutex;
+ boost::condition_variable cond_var;
+ bool flag;
+ unsigned woken;
+
+ wait_for_flag():
+ flag(false),woken(0)
+ {}
+
+ struct check_flag
+ {
+ bool const& flag;
+
+ check_flag(bool const& flag_):
+ flag(flag_)
+ {}
+
+ bool operator()() const
+ {
+ return flag;
+ }
+ private:
+ void operator=(check_flag&);
+ };
+
+
+ void wait_without_predicate()
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ while(!flag)
+ {
+ cond_var.wait(lock);
+ }
+ ++woken;
+ }
+
+ void wait_with_predicate()
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ cond_var.wait(lock,check_flag(flag));
+ if(flag)
+ {
+ ++woken;
+ }
+ }
+
+ void timed_wait_without_predicate()
+ {
+ boost::system_time const timeout=boost::get_system_time()+boost::posix_time::seconds(timeout_seconds);
+
+ boost::unique_lock<boost::mutex> lock(mutex);
+ while(!flag)
+ {
+ if(!cond_var.timed_wait(lock,timeout))
+ {
+ return;
+ }
+ }
+ ++woken;
+ }
+
+ void timed_wait_with_predicate()
+ {
+ boost::system_time const timeout=boost::get_system_time()+boost::posix_time::seconds(timeout_seconds);
+ boost::unique_lock<boost::mutex> lock(mutex);
+ if(cond_var.timed_wait(lock,timeout,check_flag(flag)) && flag)
+ {
+ ++woken;
+ }
+ }
+ void relative_timed_wait_with_predicate()
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ if(cond_var.timed_wait(lock,boost::posix_time::seconds(timeout_seconds),check_flag(flag)) && flag)
+ {
+ ++woken;
+ }
+ }
+};
+
+
+#endif
diff --git a/src/boost/libs/thread/test/experimental/parallel/v1/exception_list_pass.cpp b/src/boost/libs/thread/test/experimental/parallel/v1/exception_list_pass.cpp
new file mode 100644
index 000000000..de79412ae
--- /dev/null
+++ b/src/boost/libs/thread/test/experimental/parallel/v1/exception_list_pass.cpp
@@ -0,0 +1,23 @@
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/experimental/parallel/v1/exception_list.hpp>
+
+
+#define BOOST_THREAD_VERSION 4
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#include <boost/thread/experimental/parallel/v1/exception_list.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+
+int main()
+{
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/experimental/parallel/v2/task_region_pass.cpp b/src/boost/libs/thread/test/experimental/parallel/v2/task_region_pass.cpp
new file mode 100644
index 000000000..814ef28e5
--- /dev/null
+++ b/src/boost/libs/thread/test/experimental/parallel/v2/task_region_pass.cpp
@@ -0,0 +1,295 @@
+// Copyright (C) 2014-2015 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/experimental/parallel/v1/exception_list.hpp>
+
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#include <boost/thread/experimental/parallel/v2/task_region.hpp>
+#include <string>
+
+#include <boost/detail/lightweight_test.hpp>
+
+#if ! defined BOOST_NO_CXX11_LAMBDAS && defined(BOOST_THREAD_PROVIDES_INVOKE)
+using boost::experimental::parallel::v2::task_region;
+using boost::experimental::parallel::v2::task_region_handle;
+using boost::experimental::parallel::v1::exception_list;
+
+void run_no_exception()
+{
+ std::string s("test");
+ bool parent_flag = false;
+ bool task1_flag = false;
+ bool task2_flag = false;
+ bool task21_flag = false;
+ bool task3_flag = false;
+ task_region([&](task_region_handle& trh)
+ {
+ parent_flag = true;
+ trh.run([&]()
+ {
+ task1_flag = true;
+ std::cout << "task1: " << s << std::endl;
+ });
+ trh.run([&]()
+ {
+ task2_flag = true;
+ std::cout << "task2" << std::endl;
+ task_region([&](task_region_handle& trh)
+ {
+ trh.run([&]()
+ {
+ task21_flag = true;
+ std::cout << "task2.1" << std::endl;
+ });
+ });
+ });
+ int i = 0, j = 10, k = 20;
+ trh.run([=, &task3_flag]()
+ {
+ task3_flag = true;
+ std::cout << "task3: " << i << " " << j << " " << k << std::endl;
+ });
+ std::cout << "parent" << std::endl;
+ });
+ BOOST_TEST(parent_flag);
+ BOOST_TEST(task1_flag);
+ BOOST_TEST(task2_flag);
+ BOOST_TEST(task21_flag);
+ BOOST_TEST(task3_flag);
+}
+
+void run_no_exception_wait()
+{
+ std::string s("test");
+ bool parent_flag = false;
+ bool wait_flag = false;
+ bool task1_flag = false;
+ bool task2_flag = false;
+ bool task21_flag = false;
+ bool task3_flag = false;
+ task_region([&](task_region_handle& trh)
+ {
+ parent_flag = true;
+ trh.run([&]()
+ {
+ task1_flag = true;
+ std::cout << "task1: " << s << std::endl;
+ });
+ trh.run([&]()
+ {
+ task2_flag = true;
+ std::cout << "task2" << std::endl;
+ task_region([&](task_region_handle& trh)
+ {
+ trh.run([&]()
+ {
+ task21_flag = true;
+ std::cout << "task2.1" << std::endl;
+ });
+ });
+ });
+ int i = 0, j = 10, k = 20;
+ trh.run([=, &task3_flag]()
+ {
+ task3_flag = true;
+ std::cout << "task3: " << i << " " << j << " " << k << std::endl;
+ });
+ std::cout << "before" << std::endl;
+ trh.wait();
+ wait_flag = true;
+ std::cout << "parent" << std::endl;
+ });
+ BOOST_TEST(parent_flag);
+ BOOST_TEST(wait_flag);
+ BOOST_TEST(task1_flag);
+ BOOST_TEST(task2_flag);
+ BOOST_TEST(task21_flag);
+ BOOST_TEST(task3_flag);
+}
+
+void run_exception_1()
+{
+ try
+ {
+ task_region([](task_region_handle& trh)
+ {
+ trh.run([]()
+ {
+ std::cout << "task1" << std::endl;
+ throw 1;
+ });
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ trh.run([]()
+ {
+ std::cout << "task3" << std::endl;
+ });
+#if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
+ BOOST_TEST(false);
+#endif
+ });
+ BOOST_TEST(false);
+ }
+ catch (exception_list const& e)
+ {
+ BOOST_TEST_EQ(e.size(), 1u);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+}
+
+void run_exception()
+{
+ try
+ {
+ task_region([](task_region_handle& trh)
+ {
+ trh.run([]()
+ {
+ std::cout << "task1" << std::endl;
+ throw 1;
+ });
+ trh.run([]()
+ {
+ std::cout << "task2" << std::endl;
+ throw 2;
+ });
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ trh.run([]()
+ {
+ std::cout << "task3" << std::endl;
+ throw 3;
+ });
+ std::cout << "parent" << std::endl;
+ throw 100;
+ });
+ BOOST_TEST(false);
+ }
+ catch (exception_list const& el)
+ {
+ BOOST_TEST(el.size() >= 1u);
+ for (boost::exception_ptr const& e: el)
+ {
+ try {
+ boost::rethrow_exception(e);
+ }
+ catch (boost::exception&)
+ {
+ BOOST_TEST(true);
+ }
+ catch (int i) // this doesn't works yet
+ {
+ BOOST_TEST((i == 1) || (i == 2) || (i == 3));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+}
+
+
+void run_nested_exception()
+{
+ std::string s("test");
+ bool parent_flag = false;
+ bool task1_flag = false;
+ bool task2_flag = false;
+ bool task21_flag = false;
+ bool task3_flag = false;
+ try
+ {
+ task_region([&](task_region_handle& trh)
+ {
+ parent_flag = true;
+ trh.run([&]()
+ {
+ task1_flag = true;
+ std::cout << "task1: " << s << std::endl;
+ });
+ trh.run([&]()
+ {
+ task2_flag = true;
+ std::cout << "task2" << std::endl;
+ task_region([&](task_region_handle& trh)
+ {
+ trh.run([&]()
+ {
+ task21_flag = true;
+ std::cout << "task2.1" << std::endl;
+ throw 21;
+ });
+ });
+ });
+ int i = 0, j = 10, k = 20;
+ trh.run([=, &task3_flag]()
+ {
+ task3_flag = true;
+ std::cout << "task3: " << i << " " << j << " " << k << std::endl;
+ });
+ std::cout << "parent" << std::endl;
+ });
+ }
+ catch (exception_list const& el)
+ {
+ BOOST_TEST(el.size() == 1u);
+ for (boost::exception_ptr const& e: el)
+ {
+ try {
+ boost::rethrow_exception(e);
+ }
+ catch (int i) // this doesn't works yet
+ {
+ BOOST_TEST_EQ(i, 21);
+ }
+ catch (boost::exception&)
+ {
+ BOOST_TEST(true);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ BOOST_TEST(parent_flag);
+ BOOST_TEST(task1_flag);
+ BOOST_TEST(task2_flag);
+ BOOST_TEST(task21_flag);
+}
+
+
+int main()
+{
+ run_no_exception();
+ run_no_exception_wait();
+ run_exception();
+ run_exception_1();
+ run_nested_exception();
+ return boost::report_errors();
+}
+#else
+int main()
+{
+ return boost::report_errors();
+}
+#endif
diff --git a/src/boost/libs/thread/test/functional/invoke/invoke_int_0_pass.cpp b/src/boost/libs/thread/test/functional/invoke/invoke_int_0_pass.cpp
new file mode 100644
index 000000000..fa1f67543
--- /dev/null
+++ b/src/boost/libs/thread/test/functional/invoke/invoke_int_0_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/detail/invoke.hpp>
+
+#include <boost/thread/detail/invoke.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int f()
+{
+ return 1;
+}
+
+struct A_int_0
+{
+ A_int_0()
+ {
+ }
+ int operator()()
+ {
+ return 4;
+ }
+ int operator()() const
+ {
+ return 5;
+ }
+};
+
+
+int main()
+{
+ const A_int_0 ca;
+ A_int_0 a;
+
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST_EQ(boost::detail::invoke(f), 1);
+ BOOST_TEST_EQ(boost::detail::invoke(&f), 1);
+ BOOST_TEST_EQ(boost::detail::invoke(A_int_0()), 4);
+ BOOST_TEST_EQ(boost::detail::invoke(a), 4);
+ BOOST_TEST_EQ(boost::detail::invoke(ca), 5);
+#endif
+
+ BOOST_TEST_EQ(boost::detail::invoke<int>(f), 1);
+ BOOST_TEST_EQ(boost::detail::invoke<int>(&f), 1);
+ BOOST_TEST_EQ(A_int_0()(), 4);
+#if defined BOOST_THREAD_PROVIDES_INVOKE || ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ BOOST_TEST_EQ(boost::detail::invoke<int>(A_int_0()), 4);
+#else
+ //BOOST_TEST_EQ(boost::detail::invoke<int>(A_int_0()), 5);
+#endif
+ BOOST_TEST_EQ(a(), 4);
+ BOOST_TEST_EQ(boost::detail::invoke<int>(a), 4);
+ BOOST_TEST_EQ(ca(), 5);
+ BOOST_TEST_EQ(boost::detail::invoke<int>(ca), 5);
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/functional/invoke/invoke_lvalue_pass.cpp b/src/boost/libs/thread/test/functional/invoke/invoke_lvalue_pass.cpp
new file mode 100644
index 000000000..154953d89
--- /dev/null
+++ b/src/boost/libs/thread/test/functional/invoke/invoke_lvalue_pass.cpp
@@ -0,0 +1,336 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+// <boost/thread/detail/invoke.hpp>
+
+#include <boost/thread/detail/invoke.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int count = 0;
+
+// 1 arg, return void
+
+void f_void_1(int i)
+{
+ count += i;
+}
+
+struct A_void_1
+{
+ void operator()(int i)
+ {
+ count += i;
+ }
+
+ void mem1() {++count;}
+ void mem2() const {count += 2;}
+};
+
+void
+test_void_1()
+{
+ int save_count = count;
+ // function
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ {
+ int i = 2;
+ boost::detail::invoke(f_void_1, i);
+ BOOST_TEST(count == save_count + 2);
+ save_count = count;
+ }
+#endif
+ {
+ int i = 2;
+ boost::detail::invoke<void>(f_void_1, i);
+ BOOST_TEST(count == save_count + 2);
+ save_count = count;
+ }
+ // function pointer
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ {
+ void (*fp)(int) = f_void_1;
+ int i = 3;
+ boost::detail::invoke(fp, i);
+ BOOST_TEST(count == save_count+3);
+ save_count = count;
+ }
+#endif
+ {
+ void (*fp)(int) = f_void_1;
+ int i = 3;
+ boost::detail::invoke<void>(fp, i);
+ BOOST_TEST(count == save_count+3);
+ save_count = count;
+ }
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ {
+ void (*fp)(int) = f_void_1;
+ int i = 3;
+ boost::detail::invoke(fp, i);
+ BOOST_TEST(count == save_count+3);
+ save_count = count;
+ }
+#endif
+ {
+ void (*fp)(int) = f_void_1;
+ int i = 3;
+ boost::detail::invoke<void>(fp, i);
+ BOOST_TEST(count == save_count+3);
+ save_count = count;
+ }
+ // functor
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ {
+ A_void_1 a0;
+ int i = 4;
+ boost::detail::invoke(a0, i);
+ BOOST_TEST(count == save_count+4);
+ save_count = count;
+ }
+#endif
+ {
+ A_void_1 a0;
+ int i = 4;
+ boost::detail::invoke<void>(a0, i);
+ BOOST_TEST(count == save_count+4);
+ save_count = count;
+ }
+ // member function pointer
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ {
+ void (A_void_1::*fp)() = &A_void_1::mem1;
+ A_void_1 a;
+ boost::detail::invoke(fp, a);
+ BOOST_TEST(count == save_count+1);
+ save_count = count;
+ A_void_1* ap = &a;
+ boost::detail::invoke(fp, ap);
+ BOOST_TEST(count == save_count+1);
+ save_count = count;
+ }
+#endif
+ {
+ void (A_void_1::*fp)() = &A_void_1::mem1;
+ A_void_1 a;
+ boost::detail::invoke<void>(fp, a);
+ BOOST_TEST(count == save_count+1);
+ save_count = count;
+ A_void_1* ap = &a;
+ boost::detail::invoke<void>(fp, ap);
+ BOOST_TEST(count == save_count+1);
+ save_count = count;
+ }
+ // const member function pointer
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ {
+ void (A_void_1::*fp)() const = &A_void_1::mem2;
+ A_void_1 a;
+ boost::detail::invoke(fp, a);
+ BOOST_TEST(count == save_count+2);
+ save_count = count;
+ A_void_1* ap = &a;
+ boost::detail::invoke(fp, ap);
+ BOOST_TEST(count == save_count+2);
+ save_count = count;
+ }
+#endif
+ {
+ void (A_void_1::*fp)() const = &A_void_1::mem2;
+ A_void_1 a;
+ boost::detail::invoke<void>(fp, a);
+ BOOST_TEST(count == save_count+2);
+ save_count = count;
+ A_void_1* ap = &a;
+ boost::detail::invoke<void>(fp, ap);
+ BOOST_TEST(count == save_count+2);
+ save_count = count;
+ }
+}
+
+// 1 arg, return int
+
+int f_int_1(int i)
+{
+ return i + 1;
+}
+
+struct A_int_1
+{
+ A_int_1() : data_(5) {}
+ int operator()(int i)
+ {
+ return i - 1;
+ }
+
+ int mem1() {return 3;}
+ int mem2() const {return 4;}
+ int data_;
+};
+
+void
+test_int_1()
+{
+ // function
+ {
+ int i = 2;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST(boost::detail::invoke(f_int_1, i) == 3);
+#endif
+ BOOST_TEST(boost::detail::invoke<int>(f_int_1, i) == 3);
+ }
+ // function pointer
+ {
+ int (*fp)(int) = f_int_1;
+ int i = 3;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST(boost::detail::invoke(fp, i) == 4);
+#endif
+ BOOST_TEST(boost::detail::invoke<int>(fp, i) == 4);
+ }
+ // functor
+ {
+ int i = 4;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST(boost::detail::invoke(A_int_1(), i) == 3);
+#endif
+ const A_int_1 ca;
+ A_int_1 a;
+ BOOST_TEST(boost::detail::invoke<int>(a, i) == 3);
+ //BOOST_TEST(boost::detail::invoke<int>(ca, i) == 3);
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST(boost::detail::invoke<int>(A_int_1(), i) == 3);
+#endif
+ }
+ // member function pointer
+ {
+ A_int_1 a;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST(boost::detail::invoke(&A_int_1::mem1, a) == 3);
+#endif
+ BOOST_TEST(boost::detail::invoke<int>(&A_int_1::mem1, a) == 3);
+ A_int_1* ap = &a;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST(boost::detail::invoke(&A_int_1::mem1, ap) == 3);
+#endif
+ BOOST_TEST(boost::detail::invoke<int>(&A_int_1::mem1, ap) == 3);
+ }
+ // const member function pointer
+ {
+ A_int_1 a;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST(boost::detail::invoke(&A_int_1::mem2, A_int_1()) == 4);
+#endif
+ BOOST_TEST(boost::detail::invoke<int>(&A_int_1::mem2, A_int_1()) == 4);
+ A_int_1* ap = &a;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST(boost::detail::invoke(&A_int_1::mem2, ap) == 4);
+#endif
+ BOOST_TEST(boost::detail::invoke<int>(&A_int_1::mem2, ap) == 4);
+ }
+ // member data pointer
+ {
+ A_int_1 a;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST(boost::detail::invoke(&A_int_1::data_, a) == 5);
+
+ BOOST_TEST(boost::detail::invoke<int>(&A_int_1::data_, a) == 5);
+
+#endif
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ A_int_1* ap = &a;
+
+ boost::detail::invoke(&A_int_1::data_, a) = 6;
+ BOOST_TEST(boost::detail::invoke(&A_int_1::data_, a) == 6);
+
+ boost::detail::invoke<int>(&A_int_1::data_, a) = 6;
+ BOOST_TEST(boost::detail::invoke<int>(&A_int_1::data_, a) == 6);
+
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST(boost::detail::invoke(&A_int_1::data_, ap) == 6);
+ boost::detail::invoke(&A_int_1::data_, ap) = 7;
+ BOOST_TEST(boost::detail::invoke(&A_int_1::data_, ap) == 7);
+
+ BOOST_TEST(boost::detail::invoke<int>(&A_int_1::data_, ap) == 7);
+ boost::detail::invoke<int>(&A_int_1::data_, ap) = 8;
+ BOOST_TEST(boost::detail::invoke<int>(&A_int_1::data_, ap) == 8);
+#endif
+
+ }
+}
+
+// 2 arg, return void
+
+void f_void_2(int i, int j)
+{
+ count += i+j;
+}
+
+struct A_void_2
+{
+ void operator()(int i, int j)
+ {
+ count += i+j;
+ }
+
+ void mem1(int i) {count += i;}
+ void mem2(int i) const {count += i;}
+};
+
+void
+test_void_2()
+{
+ int save_count = count;
+ // function
+ {
+ int i = 2;
+ int j = 3;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ boost::detail::invoke(f_void_2, i, j);
+ BOOST_TEST(count == save_count+5);
+ save_count = count;
+#endif
+ boost::detail::invoke<void>(f_void_2, i, j);
+ BOOST_TEST(count == save_count+5);
+ save_count = count;
+ }
+ // member function pointer
+ {
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ int j = 3;
+ boost::detail::invoke(&A_void_2::mem1, A_void_2(), j);
+ BOOST_TEST(count == save_count+3);
+ save_count = count;
+
+ boost::detail::invoke<void>(&A_void_2::mem1, A_void_2(), j);
+ BOOST_TEST(count == save_count+3);
+ save_count = count;
+#endif
+// A_void_2 a2;
+// boost::detail::invoke<void>(&A_void_2::mem1, a2, j);
+// BOOST_TEST(count == save_count+3);
+// save_count = count;
+ }
+}
+
+int main()
+{
+ test_void_1();
+ test_int_1();
+ test_void_2();
+ return boost::report_errors();
+
+}
diff --git a/src/boost/libs/thread/test/functional/invoke/invoke_rvalue_pass.cpp b/src/boost/libs/thread/test/functional/invoke/invoke_rvalue_pass.cpp
new file mode 100644
index 000000000..82ea09432
--- /dev/null
+++ b/src/boost/libs/thread/test/functional/invoke/invoke_rvalue_pass.cpp
@@ -0,0 +1,227 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/detail/invoke.hpp>
+
+#include <boost/thread/detail/invoke.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int count = 0;
+
+// 1 arg, return void
+
+void f_void_1(int i)
+{
+ count += i;
+}
+
+struct A_void_1
+{
+ void operator()(int i)
+ {
+ count += i;
+ }
+
+ void mem1() {++count;}
+ void mem2() const {count += 2;}
+};
+
+void
+test_void_1()
+{
+ int save_count = count;
+ // function
+ {
+ boost::detail::invoke(f_void_1, 2);
+ BOOST_TEST(count == save_count + 2);
+ save_count = count;
+ }
+ // function pointer
+ {
+ void (*fp)(int) = f_void_1;
+ boost::detail::invoke(fp, 3);
+ BOOST_TEST(count == save_count+3);
+ save_count = count;
+ }
+ // functor
+ {
+ A_void_1 a0;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ boost::detail::invoke(a0, 4);
+ BOOST_TEST(count == save_count+4);
+ save_count = count;
+#endif
+ boost::detail::invoke<void>(a0, 4);
+ BOOST_TEST(count == save_count+4);
+ save_count = count;
+ }
+ // member function pointer
+ {
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ void (A_void_1::*fp)() = &A_void_1::mem1;
+ boost::detail::invoke(fp, A_void_1());
+ BOOST_TEST(count == save_count+1);
+ save_count = count;
+ //BUG
+ boost::detail::invoke<void>(fp, A_void_1());
+ BOOST_TEST(count == save_count+1);
+ save_count = count;
+
+#endif
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ A_void_1 a;
+ boost::detail::invoke(fp, &a);
+ BOOST_TEST(count == save_count+1);
+ save_count = count;
+ //BUG
+ boost::detail::invoke<int>(fp, &a);
+ BOOST_TEST(count == save_count+1);
+ save_count = count;
+
+#endif
+ }
+ // const member function pointer
+ {
+ void (A_void_1::*fp)() const = &A_void_1::mem2;
+ boost::detail::invoke(fp, A_void_1());
+ BOOST_TEST(count == save_count+2);
+ save_count = count;
+ A_void_1 a;
+ boost::detail::invoke(fp, &a);
+ BOOST_TEST(count == save_count+2);
+ save_count = count;
+ }
+}
+
+// 1 arg, return int
+
+int f_int_1(int i)
+{
+ return i + 1;
+}
+
+struct A_int_1
+{
+ A_int_1() : data_(5) {}
+ int operator()(int i)
+ {
+ return i - 1;
+ }
+
+ int mem1() {return 3;}
+ int mem2() const {return 4;}
+ int data_;
+};
+
+void
+test_int_1()
+{
+ // function
+ {
+ BOOST_TEST(boost::detail::invoke(f_int_1, 2) == 3);
+ }
+ // function pointer
+ {
+ int (*fp)(int) = f_int_1;
+ BOOST_TEST(boost::detail::invoke(fp, 3) == 4);
+ }
+ // functor
+ {
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST(boost::detail::invoke(A_int_1(), 4) == 3);
+ BOOST_TEST(boost::detail::invoke<int>(A_int_1(), 4) == 3);
+#endif
+ }
+ // member function pointer
+ {
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST(boost::detail::invoke(&A_int_1::mem1, A_int_1()) == 3);
+ BOOST_TEST(boost::detail::invoke<int>(&A_int_1::mem1, A_int_1()) == 3);
+#endif
+
+ A_int_1 a;
+ BOOST_TEST(boost::detail::invoke(&A_int_1::mem1, &a) == 3);
+ }
+ // const member function pointer
+ {
+ BOOST_TEST(boost::detail::invoke(&A_int_1::mem2, A_int_1()) == 4);
+ A_int_1 a;
+ BOOST_TEST(boost::detail::invoke(&A_int_1::mem2, &a) == 4);
+ }
+ // member data pointer
+ {
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST(boost::detail::invoke(&A_int_1::data_, A_int_1()) == 5);
+ BOOST_TEST(boost::detail::invoke<int>(&A_int_1::data_, A_int_1()) == 5);
+ A_int_1 a;
+ BOOST_TEST(boost::detail::invoke(&A_int_1::data_, a) == 5);
+ boost::detail::invoke(&A_int_1::data_, a) = 6;
+ BOOST_TEST(boost::detail::invoke(&A_int_1::data_, a) == 6);
+ BOOST_TEST(boost::detail::invoke(&A_int_1::data_, &a) == 6);
+ boost::detail::invoke(&A_int_1::data_, &a) = 7;
+ BOOST_TEST(boost::detail::invoke(&A_int_1::data_, &a) == 7);
+#endif
+ }
+}
+
+// 2 arg, return void
+
+void f_void_2(int i, int j)
+{
+ count += i+j;
+}
+
+struct A_void_2
+{
+ void operator()(int i, int j)
+ {
+ count += i+j;
+ }
+
+ void mem1(int i) {count += i;}
+ void mem2(int i) const {count += i;}
+};
+
+void
+test_void_2()
+{
+ int save_count = count;
+ // function
+ {
+ boost::detail::invoke(f_void_2, 2, 3);
+ BOOST_TEST(count == save_count+5);
+ save_count = count;
+ }
+ // member function pointer
+ {
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ boost::detail::invoke(&A_void_2::mem1, A_void_2(), 3);
+ BOOST_TEST(count == save_count+3);
+ save_count = count;
+
+ boost::detail::invoke<void>(&A_void_2::mem1, A_void_2(), 3);
+ BOOST_TEST(count == save_count+3);
+ save_count = count;
+#endif
+
+ }
+}
+
+int main()
+{
+ test_void_1();
+ test_int_1();
+ test_void_2();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/functional/invoker/invoker_int_0_pass.cpp b/src/boost/libs/thread/test/functional/invoker/invoker_int_0_pass.cpp
new file mode 100644
index 000000000..123bde2e6
--- /dev/null
+++ b/src/boost/libs/thread/test/functional/invoker/invoker_int_0_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/detail/invoker.hpp>
+
+#include <boost/thread/detail/invoker.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int f()
+{
+ return 1;
+}
+
+struct A_int_0
+{
+ A_int_0()
+ {
+ }
+ int operator()()
+ {
+ return 4;
+ }
+ int operator()() const
+ {
+ return 5;
+ }
+};
+
+
+int main()
+{
+ const A_int_0 ca;
+ A_int_0 a;
+
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST_EQ(boost::detail::invoker<int(*)()>(f)(), 1);
+ BOOST_TEST_EQ(boost::detail::invoker<int(*)()>(&f)(), 1);
+ BOOST_TEST_EQ(boost::detail::invoker<A_int_0>(A_int_0())(), 4);
+ BOOST_TEST_EQ(boost::detail::invoker<A_int_0>(a)(), 4);
+ BOOST_TEST_EQ(boost::detail::invoker<const A_int_0>(ca)(), 5);
+#endif
+
+ //BOOST_TEST_EQ(boost::detail::invoker<int>(f), 1);
+ //BOOST_TEST_EQ(boost::detail::invoker<int>(&f), 1);
+ BOOST_TEST_EQ(A_int_0()(), 4);
+#if defined BOOST_THREAD_PROVIDES_INVOKE || ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ //BOOST_TEST_EQ(boost::detail::invoker<int>(A_int_0()), 4);
+#else
+ //BOOST_TEST_EQ(boost::detail::invoke<int>(A_int_0()), 5);
+#endif
+ //BOOST_TEST_EQ(a(), 4);
+ //BOOST_TEST_EQ(boost::detail::invoke<int>(a), 4);
+ //BOOST_TEST_EQ(ca(), 5);
+ //BOOST_TEST_EQ(boost::detail::invoke<int>(ca), 5);
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/functional/invoker/invoker_lvalue_pass.cpp b/src/boost/libs/thread/test/functional/invoker/invoker_lvalue_pass.cpp
new file mode 100644
index 000000000..42a98d45a
--- /dev/null
+++ b/src/boost/libs/thread/test/functional/invoker/invoker_lvalue_pass.cpp
@@ -0,0 +1,342 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/detail/invoker.hpp>
+
+#include <boost/thread/detail/invoker.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int count = 0;
+
+// 1 arg, return void
+
+void f_void_1(int i)
+{
+ count += i;
+}
+
+struct A_void_1
+{
+ typedef void result_type;
+ void operator()(int i)
+ {
+ count += i;
+ }
+
+ void mem1() {
+ std::cout << "mem1 " << count << std::endl;
+ ++count;
+ std::cout << "mem1 " << count << std::endl;
+ }
+ void mem2() const {count += 2;}
+};
+
+void
+test_void_1()
+{
+ int save_count = count;
+ // function
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ {
+ int i = 2;
+ boost::detail::invoker<void(*)(int), int>(f_void_1, i)();
+ BOOST_TEST(count == save_count + 2);
+ save_count = count;
+ }
+#endif
+// {
+// int i = 2;
+// boost::detail::invoke<void>(f_void_1, i);
+// BOOST_TEST(count == save_count + 2);
+// save_count = count;
+// }
+ // function pointer
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ {
+ void (*fp)(int) = f_void_1;
+ int i = 3;
+ boost::detail::invoker<void(*)(int), int>(fp, i)();
+ BOOST_TEST(count == save_count+3);
+ save_count = count;
+ }
+#endif
+// {
+// void (*fp)(int) = f_void_1;
+// int i = 3;
+// boost::detail::invoke<void>(fp, i);
+// BOOST_TEST(count == save_count+3);
+// save_count = count;
+// }
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ {
+ void (*fp)(int) = f_void_1;
+ int i = 3;
+ boost::detail::invoker<void(*)(int), int>(fp, i)();
+ BOOST_TEST(count == save_count+3);
+ save_count = count;
+ }
+#endif
+// {
+// void (*fp)(int) = f_void_1;
+// int i = 3;
+// boost::detail::invoke<void>(fp, i);
+// BOOST_TEST(count == save_count+3);
+// save_count = count;
+// }
+ // functor
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ {
+ A_void_1 a0;
+ int i = 4;
+ boost::detail::invoker<A_void_1, int>(a0, i)();
+ BOOST_TEST(count == save_count+4);
+ save_count = count;
+ }
+#endif
+// {
+// A_void_1 a0;
+// int i = 4;
+// boost::detail::invoke<void>(a0, i);
+// BOOST_TEST(count == save_count+4);
+// save_count = count;
+// }
+ // member function pointer
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ {
+ void (A_void_1::*fp)() = &A_void_1::mem1;
+ A_void_1 a;
+ //BUG
+ boost::detail::invoker<void (A_void_1::*)(), A_void_1>(fp, a)();
+ BOOST_TEST_EQ(count, save_count+1);
+ save_count = count;
+ A_void_1* ap = &a;
+ boost::detail::invoker<void (A_void_1::*)(), A_void_1*>(fp, ap)();
+ BOOST_TEST_EQ(count, save_count+1);
+ save_count = count;
+ }
+#endif
+// {
+// void (A_void_1::*fp)() = &A_void_1::mem1;
+// A_void_1 a;
+// boost::detail::invoke<void>(fp, a);
+// BOOST_TEST(count == save_count+1);
+// save_count = count;
+// A_void_1* ap = &a;
+// boost::detail::invoke<void>(fp, ap);
+// BOOST_TEST(count == save_count+1);
+// save_count = count;
+// }
+ // const member function pointer
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ {
+ void (A_void_1::*fp)() const = &A_void_1::mem2;
+ A_void_1 a;
+ boost::detail::invoker<void (A_void_1::*)() const, A_void_1>(fp, a)();
+ BOOST_TEST(count == save_count+2);
+ save_count = count;
+ A_void_1* ap = &a;
+ boost::detail::invoker<void (A_void_1::*)() const, A_void_1*>(fp, ap)();
+ BOOST_TEST_EQ(count, save_count+2);
+ save_count = count;
+ }
+#endif
+// {
+// void (A_void_1::*fp)() const = &A_void_1::mem2;
+// A_void_1 a;
+// boost::detail::invoke<void>(fp, a);
+// BOOST_TEST(count == save_count+2);
+// save_count = count;
+// A_void_1* ap = &a;
+// boost::detail::invoke<void>(fp, ap);
+// BOOST_TEST(count == save_count+2);
+// save_count = count;
+// }
+}
+
+// 1 arg, return int
+
+int f_int_1(int i)
+{
+ return i + 1;
+}
+
+struct A_int_1
+{
+ A_int_1() : data_(5) {}
+ int operator()(int i)
+ {
+ return i - 1;
+ }
+
+ int mem1() {return 3;}
+ int mem2() const {return 4;}
+ int data_;
+};
+
+void
+test_int_1()
+{
+ // function
+ {
+ int i = 2;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST((boost::detail::invoker<int(*)(int), int>(f_int_1, i)() == 3));
+#endif
+// BOOST_TEST(boost::detail::invoke<int>(f_int_1, i) == 3);
+ }
+ // function pointer
+ {
+ int (*fp)(int) = f_int_1;
+ int i = 3;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST((boost::detail::invoker<int (*)(int), int>(fp, i)() == 4));
+#endif
+// BOOST_TEST(boost::detail::invoke<int>(fp, i) == 4);
+ }
+ // functor
+ {
+ int i = 4;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST((boost::detail::invoker<A_int_1, int>(A_int_1(), i)() == 3));
+#endif
+// const A_int_1 ca;
+// A_int_1 a;
+// BOOST_TEST(boost::detail::invoke<int>(a, i) == 3);
+// //BOOST_TEST(boost::detail::invoke<int>(ca, i) == 3);
+//#if defined BOOST_THREAD_PROVIDES_INVOKE
+// BOOST_TEST(boost::detail::invoke<int>(A_int_1(), i) == 3);
+//#endif
+ }
+ // member function pointer
+ {
+ A_int_1 a;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST((boost::detail::invoker<int (A_int_1::*)(), A_int_1>(&A_int_1::mem1, a)() == 3));
+#endif
+// BOOST_TEST(boost::detail::invoke<int>(&A_int_1::mem1, a) == 3);
+ A_int_1* ap = &a;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST((boost::detail::invoker<int (A_int_1::*)(), A_int_1*>(&A_int_1::mem1, ap)() == 3));
+#endif
+// BOOST_TEST(boost::detail::invoke<int>(&A_int_1::mem1, ap) == 3);
+ }
+ // const member function pointer
+ {
+ A_int_1 a;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST((boost::detail::invoker<int (A_int_1::*)() const, A_int_1>(&A_int_1::mem2, A_int_1())() == 4));
+#endif
+// BOOST_TEST(boost::detail::invoke<int>(&A_int_1::mem2, A_int_1()) == 4);
+ A_int_1* ap = &a;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST((boost::detail::invoker<int (A_int_1::*)() const, A_int_1*>(&A_int_1::mem2, ap)() == 4));
+#endif
+// BOOST_TEST(boost::detail::invoke<int>(&A_int_1::mem2, ap) == 4);
+ }
+ // member data pointer
+ {
+ A_int_1 a;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ // BUG
+ //BOOST_TEST(boost::detail::invoker<int A_int_1::*>(&A_int_1::data_, a) == 5);
+
+// BOOST_TEST(boost::detail::invoke<int>(&A_int_1::data_, a) == 5);
+
+#endif
+//#if defined BOOST_THREAD_PROVIDES_INVOKE
+// A_int_1* ap = &a;
+//
+// boost::detail::invoker<int A_int_1::*>(&A_int_1::data_, a) = 6;
+// BOOST_TEST(boost::detail::invoker<int A_int_1::*>(&A_int_1::data_, a) == 6);
+//
+//// boost::detail::invoke<int>(&A_int_1::data_, a) = 6;
+//// BOOST_TEST(boost::detail::invoke<int>(&A_int_1::data_, a) == 6);
+//
+//#endif
+//
+//#if defined BOOST_THREAD_PROVIDES_INVOKE
+// BOOST_TEST(boost::detail::invoker<int A_int_1::*>(&A_int_1::data_, ap) == 6);
+// boost::detail::invoker<int A_int_1::*>(&A_int_1::data_, ap) = 7;
+// BOOST_TEST(boost::detail::invoker<int A_int_1::*>(&A_int_1::data_, ap) == 7);
+//
+//// BOOST_TEST(boost::detail::invoke<int>(&A_int_1::data_, ap) == 7);
+//// boost::detail::invoke<int>(&A_int_1::data_, ap) = 8;
+//// BOOST_TEST(boost::detail::invoke<int>(&A_int_1::data_, ap) == 8);
+//#endif
+
+ }
+}
+
+// 2 arg, return void
+
+void f_void_2(int i, int j)
+{
+ count += i+j;
+}
+
+struct A_void_2
+{
+ void operator()(int i, int j)
+ {
+ count += i+j;
+ }
+
+ void mem1(int i) {count += i;}
+ void mem2(int i) const {count += i;}
+};
+
+void
+test_void_2()
+{
+ int save_count = count;
+ // function
+ {
+ int i = 2;
+ int j = 3;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ boost::detail::invoke(f_void_2, i, j);
+ BOOST_TEST(count == save_count+5);
+ save_count = count;
+#endif
+// boost::detail::invoke<void>(f_void_2, i, j);
+// BOOST_TEST(count == save_count+5);
+// save_count = count;
+ }
+ // member function pointer
+ {
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ int j = 3;
+ boost::detail::invoke(&A_void_2::mem1, A_void_2(), j);
+ BOOST_TEST(count == save_count+3);
+ save_count = count;
+
+// boost::detail::invoke<void>(&A_void_2::mem1, A_void_2(), j);
+// BOOST_TEST(count == save_count+3);
+// save_count = count;
+#endif
+// A_void_2 a2;
+// boost::detail::invoke<void>(&A_void_2::mem1, a2, j);
+// BOOST_TEST(count == save_count+3);
+// save_count = count;
+ }
+}
+
+int main()
+{
+ test_void_1();
+ test_int_1();
+ test_void_2();
+ return boost::report_errors();
+
+}
diff --git a/src/boost/libs/thread/test/functional/invoker/invoker_rvalue_pass.cpp b/src/boost/libs/thread/test/functional/invoker/invoker_rvalue_pass.cpp
new file mode 100644
index 000000000..ae06e16b6
--- /dev/null
+++ b/src/boost/libs/thread/test/functional/invoker/invoker_rvalue_pass.cpp
@@ -0,0 +1,230 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/detail/invoker.hpp>
+
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+//#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#include <boost/thread/detail/invoker.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int count = 0;
+
+// 1 arg, return void
+
+void f_void_1(int i)
+{
+ count += i;
+}
+
+struct A_void_1
+{
+ typedef void result_type;
+ void operator()(int i)
+ {
+ count += i;
+ }
+
+ void mem1() {++count;}
+ void mem2() const {count += 2;}
+};
+
+void
+test_void_1()
+{
+ int save_count = count;
+ // function
+ {
+ boost::detail::invoker<void(*)(int), int>(f_void_1, 2)();
+ BOOST_TEST(count == save_count + 2);
+ save_count = count;
+ }
+ // function pointer
+ {
+ void (*fp)(int) = f_void_1;
+ boost::detail::invoker<void(*)(int), int>(fp, 3)();
+ BOOST_TEST(count == save_count+3);
+ save_count = count;
+ }
+ // functor
+ {
+ A_void_1 a0;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ boost::detail::invoker<A_void_1, int>(a0, 4)();
+ BOOST_TEST(count == save_count+4);
+ save_count = count;
+#endif
+// boost::detail::invoke<void>(a0, 4);
+// BOOST_TEST(count == save_count+4);
+// save_count = count;
+ }
+ // member function pointer
+ {
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ void (A_void_1::*fp)() = &A_void_1::mem1;
+ boost::detail::invoker<void (A_void_1::*)(), A_void_1>(fp, A_void_1())();
+ BOOST_TEST(count == save_count+1);
+ save_count = count;
+
+#endif
+ // boost::detail::invoke<void>(fp, A_void_1());
+ // BOOST_TEST(count == save_count+1);
+ // save_count = count;
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ A_void_1 a;
+ boost::detail::invoker<void (A_void_1::*)(), A_void_1*>(fp, &a)();
+ BOOST_TEST(count == save_count+1);
+ save_count = count;
+
+#endif
+ // boost::detail::invoke<int>(fp, &a);
+ // BOOST_TEST(count == save_count+1);
+ // save_count = count;
+ }
+ // const member function pointer
+ {
+ void (A_void_1::*fp)() const = &A_void_1::mem2;
+ boost::detail::invoker<void (A_void_1::*)() const, A_void_1>(fp, A_void_1())();
+ BOOST_TEST(count == save_count+2);
+ save_count = count;
+ A_void_1 a;
+ boost::detail::invoker<void (A_void_1::*)() const, A_void_1*>(fp, &a)();
+ BOOST_TEST(count == save_count+2);
+ save_count = count;
+ }
+}
+
+// 1 arg, return int
+
+int f_int_1(int i)
+{
+ return i + 1;
+}
+
+struct A_int_1
+{
+ A_int_1() : data_(5) {}
+ int operator()(int i)
+ {
+ return i - 1;
+ }
+
+ int mem1() {return 3;}
+ int mem2() const {return 4;}
+ int data_;
+};
+
+void
+test_int_1()
+{
+ // function
+ {
+ BOOST_TEST((boost::detail::invoker<int (*)(int), int>(f_int_1, 2)() == 3));
+ }
+ // function pointer
+ {
+ int (*fp)(int) = f_int_1;
+ BOOST_TEST((boost::detail::invoker<int (*)(int), int>(fp, 3)() == 4));
+ }
+ // functor
+ {
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST((boost::detail::invoker<A_int_1, int>(A_int_1(), 4)() == 3));
+// BOOST_TEST(boost::detail::invoke<int>(A_int_1(), 4) == 3);
+#endif
+ }
+ // member function pointer
+ {
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ BOOST_TEST((boost::detail::invoker<int (A_int_1::*)(),A_int_1>(&A_int_1::mem1, A_int_1())() == 3));
+// BOOST_TEST(boost::detail::invoke<int>(&A_int_1::mem1, A_int_1()) == 3);
+#endif
+
+ A_int_1 a;
+ BOOST_TEST((boost::detail::invoker<int (A_int_1::*)(), A_int_1*>(&A_int_1::mem1, &a)() == 3));
+ }
+ // const member function pointer
+ {
+ BOOST_TEST((boost::detail::invoker<int (A_int_1::*)() const, A_int_1>(&A_int_1::mem2, A_int_1())() == 4));
+ A_int_1 a;
+ BOOST_TEST((boost::detail::invoker<int (A_int_1::*)() const, A_int_1*>(&A_int_1::mem2, &a)() == 4));
+ }
+ // member data pointer
+ {
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+// BOOST_TEST((boost::detail::invoker<int A_int_1::*>(&A_int_1::data_, A_int_1())() == 5));
+//// BOOST_TEST(boost::detail::invoke<int>(&A_int_1::data_, A_int_1()) == 5);
+// A_int_1 a;
+// BOOST_TEST((boost::detail::invoker<int A_int_1::*>(&A_int_1::data_, a)() == 5));
+// boost::detail::invoker<int A_int_1::*>(&A_int_1::data_, a)() = 6;
+// BOOST_TEST((boost::detail::invoker<int A_int_1::*>(&A_int_1::data_, a)() == 6));
+// BOOST_TEST((boost::detail::invoker<int A_int_1::*>(&A_int_1::data_, &a)() == 6));
+// boost::detail::invoker<int A_int_1::*>(&A_int_1::data_, &a)() = 7;
+// BOOST_TEST((boost::detail::invoker<int A_int_1::*>(&A_int_1::data_, &a)() == 7));
+#endif
+ }
+}
+
+// 2 arg, return void
+
+void f_void_2(int i, int j)
+{
+ count += i+j;
+}
+
+struct A_void_2
+{
+ void operator()(int i, int j)
+ {
+ count += i+j;
+ }
+
+ void mem1(int i) {count += i;}
+ void mem2(int i) const {count += i;}
+};
+
+void
+test_void_2()
+{
+ int save_count = count;
+ // function
+ {
+ boost::detail::invoke(f_void_2, 2, 3);
+ BOOST_TEST(count == save_count+5);
+ save_count = count;
+ }
+ // member function pointer
+ {
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ boost::detail::invoke(&A_void_2::mem1, A_void_2(), 3);
+ BOOST_TEST(count == save_count+3);
+ save_count = count;
+
+ boost::detail::invoke<void>(&A_void_2::mem1, A_void_2(), 3);
+ BOOST_TEST(count == save_count+3);
+ save_count = count;
+#endif
+
+ }
+}
+
+int main()
+{
+ test_void_1();
+ test_int_1();
+ test_void_2();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/no_implicit_assign_from_lvalue_thread.cpp b/src/boost/libs/thread/test/no_implicit_assign_from_lvalue_thread.cpp
new file mode 100644
index 000000000..1922bb7dc
--- /dev/null
+++ b/src/boost/libs/thread/test/no_implicit_assign_from_lvalue_thread.cpp
@@ -0,0 +1,17 @@
+// Copyright (C) 2008 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/thread/thread.hpp>
+
+void do_nothing()
+{}
+
+void test()
+{
+ boost::thread t1(do_nothing);
+ boost::thread t2;
+ t2=t1;
+}
+
+#include "./remove_error_code_unused_warning.hpp"
diff --git a/src/boost/libs/thread/test/no_implicit_move_from_lvalue_thread.cpp b/src/boost/libs/thread/test/no_implicit_move_from_lvalue_thread.cpp
new file mode 100644
index 000000000..63522f0f0
--- /dev/null
+++ b/src/boost/libs/thread/test/no_implicit_move_from_lvalue_thread.cpp
@@ -0,0 +1,16 @@
+// Copyright (C) 2008 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/thread/thread.hpp>
+
+void do_nothing()
+{}
+
+void test()
+{
+ boost::thread t1(do_nothing);
+ boost::thread t2(t1);
+}
+
+#include "./remove_error_code_unused_warning.hpp"
diff --git a/src/boost/libs/thread/test/remove_error_code_unused_warning.hpp b/src/boost/libs/thread/test/remove_error_code_unused_warning.hpp
new file mode 100644
index 000000000..1f43f2a2e
--- /dev/null
+++ b/src/boost/libs/thread/test/remove_error_code_unused_warning.hpp
@@ -0,0 +1,17 @@
+// Copyright (C) 2008 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#include <boost/thread/thread.hpp>
+
+void remove_unused_warning()
+{
+ //../../../boost/system/error_code.hpp:214:36: warning: 'boost::system::posix_category' defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:215:36: warning: 'boost::system::errno_ecat' defined but not used [-Wunused-variable]
+ //../../../boost/system/error_code.hpp:216:36: warning: 'boost::system::native_ecat' defined but not used [-Wunused-variable]
+
+ //(void)boost::system::posix_category;
+ //(void)boost::system::errno_ecat;
+ //(void)boost::system::native_ecat;
+
+}
diff --git a/src/boost/libs/thread/test/self_contained_header.cpp b/src/boost/libs/thread/test/self_contained_header.cpp
new file mode 100644
index 000000000..ef4117a13
--- /dev/null
+++ b/src/boost/libs/thread/test/self_contained_header.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright Andrey Semashev 2019.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file self_contained_header.cpp
+ * \author Andrey Semashev
+ * \date 2019-01-19
+ *
+ * \brief This file contains a test boilerplate for checking that every public header is self-contained and does not have any missing #includes.
+ */
+
+#if defined(BOOST_THREAD_TEST_POST_WINDOWS_H)
+#include <windows.h>
+#endif
+
+#define BOOST_THREAD_TEST_INCLUDE_HEADER() <boost/thread/BOOST_THREAD_TEST_HEADER>
+
+#include BOOST_THREAD_TEST_INCLUDE_HEADER()
+
+int main(int, char*[])
+{
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/shared_mutex_locking_thread.hpp b/src/boost/libs/thread/test/shared_mutex_locking_thread.hpp
new file mode 100644
index 000000000..4d9a31ca5
--- /dev/null
+++ b/src/boost/libs/thread/test/shared_mutex_locking_thread.hpp
@@ -0,0 +1,145 @@
+#ifndef SHARED_MUTEX_LOCKING_THREAD_HPP
+#define SHARED_MUTEX_LOCKING_THREAD_HPP
+
+// (C) Copyright 2008 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/config.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/shared_mutex.hpp>
+
+template<typename lock_type>
+class locking_thread
+{
+ boost::shared_mutex& rw_mutex;
+ unsigned& unblocked_count;
+ boost::condition_variable& unblocked_condition;
+ unsigned& simultaneous_running_count;
+ unsigned& max_simultaneous_running;
+ boost::mutex& unblocked_count_mutex;
+ boost::mutex& finish_mutex;
+public:
+ locking_thread(boost::shared_mutex& rw_mutex_,
+ unsigned& unblocked_count_,
+ boost::mutex& unblocked_count_mutex_,
+ boost::condition_variable& unblocked_condition_,
+ boost::mutex& finish_mutex_,
+ unsigned& simultaneous_running_count_,
+ unsigned& max_simultaneous_running_):
+ rw_mutex(rw_mutex_),
+ unblocked_count(unblocked_count_),
+ unblocked_condition(unblocked_condition_),
+ simultaneous_running_count(simultaneous_running_count_),
+ max_simultaneous_running(max_simultaneous_running_),
+ unblocked_count_mutex(unblocked_count_mutex_),
+ finish_mutex(finish_mutex_)
+ {}
+
+#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
+ locking_thread(locking_thread const&) = default;
+#endif
+
+ void operator()()
+ {
+ // acquire lock
+ lock_type lock(rw_mutex);
+
+ // increment count to show we're unblocked
+ {
+ boost::unique_lock<boost::mutex> ublock(unblocked_count_mutex);
+ ++unblocked_count;
+ unblocked_condition.notify_one();
+ ++simultaneous_running_count;
+ if(simultaneous_running_count>max_simultaneous_running)
+ {
+ max_simultaneous_running=simultaneous_running_count;
+ }
+ }
+
+ // wait to finish
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+ {
+ boost::unique_lock<boost::mutex> ublock(unblocked_count_mutex);
+ --simultaneous_running_count;
+ }
+ }
+private:
+ void operator=(locking_thread&);
+};
+
+class simple_writing_thread
+{
+ boost::shared_mutex& rwm;
+ boost::mutex& finish_mutex;
+ boost::mutex& unblocked_mutex;
+ unsigned& unblocked_count;
+
+ void operator=(simple_writing_thread&);
+
+public:
+ simple_writing_thread(boost::shared_mutex& rwm_,
+ boost::mutex& finish_mutex_,
+ boost::mutex& unblocked_mutex_,
+ unsigned& unblocked_count_):
+ rwm(rwm_),finish_mutex(finish_mutex_),
+ unblocked_mutex(unblocked_mutex_),unblocked_count(unblocked_count_)
+ {}
+
+#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
+ simple_writing_thread(simple_writing_thread const&) = default;
+#endif
+
+ void operator()()
+ {
+ boost::unique_lock<boost::shared_mutex> lk(rwm);
+
+ {
+ boost::unique_lock<boost::mutex> ulk(unblocked_mutex);
+ ++unblocked_count;
+ }
+
+ boost::unique_lock<boost::mutex> flk(finish_mutex);
+ }
+};
+
+class simple_reading_thread
+{
+ boost::shared_mutex& rwm;
+ boost::mutex& finish_mutex;
+ boost::mutex& unblocked_mutex;
+ unsigned& unblocked_count;
+
+ void operator=(simple_reading_thread&);
+
+public:
+ simple_reading_thread(boost::shared_mutex& rwm_,
+ boost::mutex& finish_mutex_,
+ boost::mutex& unblocked_mutex_,
+ unsigned& unblocked_count_):
+ rwm(rwm_),finish_mutex(finish_mutex_),
+ unblocked_mutex(unblocked_mutex_),unblocked_count(unblocked_count_)
+ {}
+
+#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
+ simple_reading_thread(simple_reading_thread const&) = default;
+#endif
+
+ void operator()()
+ {
+ boost::shared_lock<boost::shared_mutex> lk(rwm);
+
+ {
+ boost::unique_lock<boost::mutex> ulk(unblocked_mutex);
+ ++unblocked_count;
+ }
+
+ boost::unique_lock<boost::mutex> flk(finish_mutex);
+ }
+};
+
+
+#endif
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/assign_fail.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/assign_fail.cpp
new file mode 100644
index 000000000..703616ff1
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable& operator=(const condition_variable&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+
+void fail()
+{
+ boost::condition_variable cv0;
+ boost::condition_variable cv1;
+ cv1 = cv0;
+
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/copy_fail.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/copy_fail.cpp
new file mode 100644
index 000000000..374ce3165
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/copy_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable(const condition_variable&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+void fail()
+{
+ boost::condition_variable cv0;
+ boost::condition_variable cv1(cv0);
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/default_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/default_pass.cpp
new file mode 100644
index 000000000..465a12de8
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable(const condition_variable&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::condition_variable cv0;
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/dtor_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/dtor_pass.cpp
new file mode 100644
index 000000000..533898ed4
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/dtor_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable(const condition_variable&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::condition_variable* cv;
+boost::mutex m;
+typedef boost::unique_lock<boost::mutex> Lock;
+
+bool f_ready = false;
+bool g_ready = false;
+
+void f()
+{
+ Lock lk(m);
+ f_ready = true;
+ cv->notify_one();
+ cv->wait(lk);
+ delete cv;
+}
+
+void g()
+{
+ Lock lk(m);
+ g_ready = true;
+ cv->notify_one();
+ while (!f_ready)
+ {
+ cv->wait(lk);
+ }
+ cv->notify_one();
+}
+
+int main()
+{
+ cv = new boost::condition_variable;
+ boost::thread th2(g);
+ Lock lk(m);
+ while (!g_ready)
+ {
+ cv->wait(lk);
+ }
+ lk.unlock();
+ boost::thread th1(f);
+ th1.join();
+ th2.join();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/lost_notif_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/lost_notif_pass.cpp
new file mode 100644
index 000000000..79dbcd295
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/lost_notif_pass.cpp
@@ -0,0 +1,241 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2017 Austin J. Beer
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable(const condition_variable&) = delete;
+
+#include <iostream>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <cassert>
+
+// Summary of each test:
+// 1. Start the test thread and wait for it to start up.
+// The test thread waits for the flag to be set using a large timeout.
+// 2. The main thread takes the lock and then sleeps for a long time while holding
+// the lock before setting the flag and calling notify_one(). If the wait
+// function being tested is polling pthread_cond_timedwait() internally, any
+// notifications sent after pthread_cond_timedwait() times out but before it can
+// reacquire the lock may be "lost". pthread_cond_timedwait() will report that
+// it timed out and the wait function may incorrectly assume that no
+// notification was received. This test ensures that that doesn't happen.
+// 3. Measure how it takes the test thread to return. If it received the
+// notification, it will return fairly quickly. If it missed the notification,
+// the test thread won't return until the wait function being tested times out.
+
+//------------------------------------------------------------------------------
+
+boost::condition_variable cv;
+boost::mutex mut;
+
+bool flag;
+bool waiting;
+
+bool flagIsSet()
+{
+ return flag;
+}
+
+bool threadIsWaiting()
+{
+ return waiting;
+}
+
+//------------------------------------------------------------------------------
+
+#ifdef BOOST_THREAD_USES_DATETIME
+
+boost::posix_time::milliseconds posix_wait_time(1000);
+
+template <typename F>
+void test_posix_wait_function(F f)
+{
+ flag = false;
+ waiting = false;
+ boost::thread t(f);
+ while (!threadIsWaiting())
+ {
+ boost::this_thread::sleep(boost::posix_time::milliseconds(1));
+ }
+
+ boost::unique_lock<boost::mutex> lk(mut);
+ boost::this_thread::sleep(boost::posix_time::milliseconds(500));
+ boost::posix_time::ptime t0 = boost::posix_time::microsec_clock::universal_time();
+ flag = true;
+ cv.notify_one();
+ lk.unlock();
+ t.join();
+ boost::posix_time::ptime t1 = boost::posix_time::microsec_clock::universal_time();
+
+ BOOST_TEST(t1 - t0 < boost::posix_time::milliseconds(250));
+}
+
+//------------------------------------------------------------------------------
+
+void timed_wait_absolute_without_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ while (!flagIsSet())
+ {
+ cv.timed_wait(lk, boost::posix_time::microsec_clock::universal_time() + posix_wait_time);
+ }
+}
+
+void timed_wait_absolute_with_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ cv.timed_wait(lk, boost::posix_time::microsec_clock::universal_time() + posix_wait_time, flagIsSet);
+}
+
+//------------------------------------------------------------------------------
+
+void timed_wait_relative_without_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ while (!flagIsSet())
+ {
+ cv.timed_wait(lk, posix_wait_time);
+ }
+}
+
+void timed_wait_relative_with_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ cv.timed_wait(lk, posix_wait_time, flagIsSet);
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_DATETIME not defined for this platform as not supported"
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifdef BOOST_THREAD_USES_CHRONO
+
+boost::chrono::milliseconds chrono_wait_time(1000);
+
+template <typename F>
+void test_chrono_wait_function(F f)
+{
+ flag = false;
+ waiting = false;
+ boost::thread t(f);
+ while (!threadIsWaiting())
+ {
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(1));
+ }
+
+ boost::unique_lock<boost::mutex> lk(mut);
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ boost::chrono::steady_clock::time_point t0 = boost::chrono::steady_clock::now();
+ flag = true;
+ cv.notify_one();
+ lk.unlock();
+ t.join();
+ boost::chrono::steady_clock::time_point t1 = boost::chrono::steady_clock::now();
+
+ BOOST_TEST(t1 - t0 < boost::chrono::milliseconds(250));
+}
+
+//------------------------------------------------------------------------------
+
+void wait_until_system_without_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ while (!flagIsSet())
+ {
+ cv.wait_until(lk, boost::chrono::system_clock::now() + chrono_wait_time);
+ }
+}
+
+void wait_until_system_with_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ cv.wait_until(lk, boost::chrono::system_clock::now() + chrono_wait_time, flagIsSet);
+}
+
+//------------------------------------------------------------------------------
+
+void wait_until_steady_without_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ while (!flagIsSet())
+ {
+ cv.wait_until(lk, boost::chrono::steady_clock::now() + chrono_wait_time);
+ }
+}
+
+void wait_until_steady_with_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ cv.wait_until(lk, boost::chrono::steady_clock::now() + chrono_wait_time, flagIsSet);
+}
+
+//------------------------------------------------------------------------------
+
+void wait_for_without_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ while (!flagIsSet())
+ {
+ cv.wait_for(lk, chrono_wait_time);
+ }
+}
+
+void wait_for_with_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ cv.wait_for(lk, chrono_wait_time, flagIsSet);
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
+//------------------------------------------------------------------------------
+
+int main()
+{
+#ifdef BOOST_THREAD_USES_DATETIME
+ test_posix_wait_function(timed_wait_absolute_without_pred);
+ test_posix_wait_function(timed_wait_absolute_with_pred);
+ test_posix_wait_function(timed_wait_relative_without_pred);
+ test_posix_wait_function(timed_wait_relative_with_pred);
+#endif
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ test_chrono_wait_function(wait_until_system_without_pred);
+ test_chrono_wait_function(wait_until_system_with_pred);
+ test_chrono_wait_function(wait_until_steady_without_pred);
+ test_chrono_wait_function(wait_until_steady_with_pred);
+ test_chrono_wait_function(wait_for_without_pred);
+ test_chrono_wait_function(wait_for_with_pred);
+#endif
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/native_handle_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/native_handle_pass.cpp
new file mode 100644
index 000000000..9835f5920
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/native_handle_pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable(const condition_variable&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+
+#include <boost/static_assert.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+#if defined BOOST_THREAD_DEFINES_CONDITION_VARIABLE_NATIVE_HANDLE
+ //BOOST_STATIC_ASSERT((boost::is_same<boost::condition_variable::native_handle_type, pthread_cond_t*>::value));
+ boost::condition_variable cv;
+ boost::condition_variable::native_handle_type h = cv.native_handle();
+ BOOST_TEST(h != 0);
+#else
+#error "Test not applicable: BOOST_THREAD_DEFINES_CONDITION_VARIABLE_NATIVE_HANDLE not defined for this platform as not supported"
+#endif
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_for_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_for_pass.cpp
new file mode 100644
index 000000000..4c6a0af3e
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_for_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable(const condition_variable&) = delete;
+
+#include <iostream>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <cassert>
+#include "../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+boost::condition_variable cv;
+boost::mutex mut;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+typedef boost::chrono::steady_clock Clock;
+typedef boost::chrono::milliseconds milliseconds;
+typedef boost::chrono::nanoseconds nanoseconds;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+ try {
+ boost::unique_lock<boost::mutex> lk(mut);
+ assert(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ Clock::time_point t0 = Clock::now();
+ Clock::time_point t = t0 + milliseconds(250);
+ while (test2 == 0 && cv.wait_for(lk, t - Clock::now()) == boost::cv_status::no_timeout) {}
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ assert(t1 - t0 < max_diff);
+ assert(test2 != 0);
+ }
+ else
+ {
+ nanoseconds d = t1 - t0 - milliseconds(250);
+ std::cout << "diff= " << d.count() << std::endl;
+ std::cout << "max_diff= " << max_diff.count() << std::endl;
+ assert( d < max_diff);
+ assert(test2 == 0);
+ }
+ ++runs;
+ } catch(...) {
+ std::cout << "ERROR exception" << __LINE__ << std::endl;
+ assert(false);
+ }
+}
+
+int main()
+{
+ try
+ {
+ boost::unique_lock<boost::mutex> lk(mut);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ } catch(...) {
+ std::cout << "ERROR exception" << __LINE__ << std::endl;
+ BOOST_TEST(false);
+ }
+ test1 = 0;
+ test2 = 0;
+ try
+ {
+ boost::unique_lock<boost::mutex> lk(mut);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ lk.unlock();
+ t.join();
+ } catch(...) {
+ BOOST_TEST(false);
+ std::cout << "ERROR exception" << __LINE__ << std::endl;
+ }
+ return boost::report_errors();
+}
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_for_pred_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_for_pred_pass.cpp
new file mode 100644
index 000000000..92ba82f1e
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_for_pred_pass.cpp
@@ -0,0 +1,127 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable(const condition_variable&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <cassert>
+#include <iostream>
+#include "../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+class Pred
+{
+ int& i_;
+public:
+ explicit Pred(int& i) :
+ i_(i)
+ {
+ }
+
+ bool operator()()
+ {
+ return i_ != 0;
+ }
+};
+
+boost::condition_variable cv;
+boost::mutex mut;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+typedef boost::chrono::system_clock Clock;
+typedef boost::chrono::milliseconds milliseconds;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+ try {
+ boost::unique_lock < boost::mutex > lk(mut);
+ assert(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ Clock::time_point t0 = Clock::now();
+ cv.wait_for(lk, milliseconds(250), Pred(test2));
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ assert(t1 - t0 < max_diff);
+ assert(test2 != 0);
+ }
+ else
+ {
+ assert(t1 - t0 - milliseconds(250) < max_diff);
+ assert(test2 == 0);
+ }
+ ++runs;
+ } catch(...) {
+ std::cout << "ERROR exception" << __LINE__ << std::endl;
+ assert(false);
+ }
+}
+
+int main()
+{
+ try
+ {
+ boost::unique_lock < boost::mutex > lk(mut);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ } catch(...) {
+ BOOST_TEST(false);
+ std::cout << "ERROR exception" << __LINE__ << std::endl;
+ }
+ test1 = 0;
+ test2 = 0;
+ try
+ {
+ boost::unique_lock < boost::mutex > lk(mut);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ lk.unlock();
+ t.join();
+ } catch(...) {
+ BOOST_TEST(false);
+ std::cout << "ERROR exception" << __LINE__ << std::endl;
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_pass.cpp
new file mode 100644
index 000000000..612724b85
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// void wait(unique_lock<mutex>& lock);
+
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <cassert>
+#include <iostream>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+boost::condition_variable cv;
+boost::mutex mut;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+void f()
+{
+ try {
+ boost::unique_lock<boost::mutex> lk(mut);
+ assert(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ while (test2 == 0) {
+ cv.wait(lk);
+ }
+ assert(test2 != 0);
+ } catch(...) {
+ std::cout << "ERROR exception" << __LINE__ << std::endl;
+ assert(false);
+ }
+}
+
+int main()
+{
+ try {
+ boost::unique_lock<boost::mutex>lk(mut);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ {
+ cv.wait(lk);
+ }
+ BOOST_TEST(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ } catch(...) {
+ BOOST_TEST(false);
+ std::cout << "ERROR exception" << __LINE__ << std::endl;
+ }
+ return boost::report_errors();
+}
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_until_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_until_pass.cpp
new file mode 100644
index 000000000..34ef32268
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_until_pass.cpp
@@ -0,0 +1,128 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable(const condition_variable&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include <cassert>
+#include "../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+struct Clock
+{
+ typedef boost::chrono::milliseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef boost::chrono::time_point<Clock> time_point;
+ static const bool is_steady = true;
+
+ static time_point now()
+ {
+ using namespace boost::chrono;
+ return time_point(duration_cast<duration> (steady_clock::now().time_since_epoch()));
+ }
+};
+
+boost::condition_variable cv;
+boost::mutex mut;
+
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+ try {
+ boost::unique_lock < boost::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) == boost::cv_status::no_timeout) {}
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ assert(test2 != 0);
+ }
+ else
+ {
+ ns d = t1 - t0 - Clock::duration(250);
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ assert(test2 == 0);
+ }
+ ++runs;
+ } catch(...) {
+ assert(false);
+ std::cout << "ERROR exception" << __LINE__ << std::endl;
+ }
+}
+
+int main()
+{
+ try
+ {
+ boost::unique_lock < boost::mutex > lk(mut);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ } catch(...) {
+ BOOST_TEST(false);
+ std::cout << "ERROR exception" << __LINE__ << std::endl;
+ }
+
+ test1 = 0;
+ test2 = 0;
+ try
+ {
+ boost::unique_lock < boost::mutex > lk(mut);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ lk.unlock();
+ t.join();
+ } catch(...) {
+ BOOST_TEST(false);
+ std::cout << "ERROR exception" << __LINE__ << std::endl;
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_until_pred_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_until_pred_pass.cpp
new file mode 100644
index 000000000..120e49853
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_until_pred_pass.cpp
@@ -0,0 +1,146 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable(const condition_variable&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <cassert>
+#include <iostream>
+#include "../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::milliseconds milliseconds;
+typedef boost::chrono::nanoseconds nanoseconds;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+struct Clock
+{
+ typedef boost::chrono::milliseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef boost::chrono::time_point<Clock> time_point;
+ static const bool is_steady = true;
+
+ static time_point now()
+ {
+ using namespace boost::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;
+ }
+};
+
+boost::condition_variable cv;
+boost::mutex mut;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+ try {
+ boost::unique_lock<boost::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 < max_diff);
+ assert(test2 != 0);
+ assert(r);
+ }
+ else
+ {
+ const nanoseconds d = t1 - t0 - milliseconds(250);
+ std::cout << "diff= " << d.count() << std::endl;
+ std::cout << "max_diff= " << max_diff.count() << std::endl;
+ assert(d < max_diff);
+ assert(test2 == 0);
+ assert(!r);
+ }
+ ++runs;
+ } catch(...) {
+ std::cout << "ERROR exception" << __LINE__ << std::endl;
+ assert(false);
+ }
+}
+
+int main()
+{
+ try
+ {
+ boost::unique_lock<boost::mutex> lk(mut);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ } catch(...) {
+ BOOST_TEST(false);
+ std::cout << "ERROR exception" << __LINE__ << std::endl;
+ }
+ test1 = 0;
+ test2 = 0;
+ try
+ {
+ boost::unique_lock<boost::mutex> lk(mut);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ lk.unlock();
+ t.join();
+ } catch(...) {
+ BOOST_TEST(false);
+ std::cout << "ERROR exception" << __LINE__ << std::endl;
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable_any/assign_fail.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/assign_fail.cpp
new file mode 100644
index 000000000..6dba459cb
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/assign_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable_any>
+
+// class condition_variable_any;
+
+// condition_variable_any& operator=(const condition_variable_any&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+
+void fail()
+{
+ boost::condition_variable_any cv0;
+ boost::condition_variable_any cv1;
+ cv1 = cv0;
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable_any/copy_fail.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/copy_fail.cpp
new file mode 100644
index 000000000..71d3a3f06
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/copy_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable_any>
+
+// class condition_variable_any;
+
+// condition_variable_any(const condition_variable_any&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+void fail()
+{
+ boost::condition_variable_any cv0;
+ boost::condition_variable_any cv1(cv0);
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable_any/default_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/default_pass.cpp
new file mode 100644
index 000000000..21116ebc4
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable_any>
+
+// class condition_variable_any;
+
+// condition_variable_any(const condition_variable_any&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::condition_variable_any cv0;
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable_any/dtor_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/dtor_pass.cpp
new file mode 100644
index 000000000..7734d93b7
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/dtor_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable_any>
+
+// class condition_variable_any;
+
+// condition_variable_any(const condition_variable_any&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::condition_variable_any* cv;
+boost::timed_mutex m;
+typedef boost::unique_lock<boost::timed_mutex> Lock;
+
+bool f_ready = false;
+bool g_ready = false;
+
+void f()
+{
+ Lock lk(m);
+ f_ready = true;
+ cv->notify_one();
+ cv->wait(lk);
+ delete cv;
+}
+
+void g()
+{
+ Lock lk(m);
+ g_ready = true;
+ cv->notify_one();
+ while (!f_ready)
+ {
+ cv->wait(lk);
+ }
+ cv->notify_one();
+}
+
+int main()
+{
+ cv = new boost::condition_variable_any;
+ boost::thread th2(g);
+ Lock lk(m);
+ while (!g_ready)
+ {
+ cv->wait(lk);
+ }
+ lk.unlock();
+ boost::thread th1(f);
+ th1.join();
+ th2.join();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable_any/lost_notif_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/lost_notif_pass.cpp
new file mode 100644
index 000000000..c696da3c2
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/lost_notif_pass.cpp
@@ -0,0 +1,241 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2017 Austin J. Beer
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable>
+
+// class condition_variable;
+
+// condition_variable(const condition_variable&) = delete;
+
+#include <iostream>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <cassert>
+
+// Summary of each test:
+// 1. Start the test thread and wait for it to start up.
+// The test thread waits for the flag to be set using a large timeout.
+// 2. The main thread takes the lock and then sleeps for a long time while holding
+// the lock before setting the flag and calling notify_one(). If the wait
+// function being tested is polling pthread_cond_timedwait() internally, any
+// notifications sent after pthread_cond_timedwait() times out but before it can
+// reacquire the lock may be "lost". pthread_cond_timedwait() will report that
+// it timed out and the wait function may incorrectly assume that no
+// notification was received. This test ensures that that doesn't happen.
+// 3. Measure how it takes the test thread to return. If it received the
+// notification, it will return fairly quickly. If it missed the notification,
+// the test thread won't return until the wait function being tested times out.
+
+//------------------------------------------------------------------------------
+
+boost::condition_variable_any cv;
+boost::mutex mut;
+
+bool flag;
+bool waiting;
+
+bool flagIsSet()
+{
+ return flag;
+}
+
+bool threadIsWaiting()
+{
+ return waiting;
+}
+
+//------------------------------------------------------------------------------
+
+#ifdef BOOST_THREAD_USES_DATETIME
+
+boost::posix_time::milliseconds posix_wait_time(1000);
+
+template <typename F>
+void test_posix_wait_function(F f)
+{
+ flag = false;
+ waiting = false;
+ boost::thread t(f);
+ while (!threadIsWaiting())
+ {
+ boost::this_thread::sleep(boost::posix_time::milliseconds(1));
+ }
+
+ boost::unique_lock<boost::mutex> lk(mut);
+ boost::this_thread::sleep(boost::posix_time::milliseconds(500));
+ boost::posix_time::ptime t0 = boost::posix_time::microsec_clock::universal_time();
+ flag = true;
+ cv.notify_one();
+ lk.unlock();
+ t.join();
+ boost::posix_time::ptime t1 = boost::posix_time::microsec_clock::universal_time();
+
+ BOOST_TEST(t1 - t0 < boost::posix_time::milliseconds(250));
+}
+
+//------------------------------------------------------------------------------
+
+void timed_wait_absolute_without_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ while (!flagIsSet())
+ {
+ cv.timed_wait(lk, boost::posix_time::microsec_clock::universal_time() + posix_wait_time);
+ }
+}
+
+void timed_wait_absolute_with_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ cv.timed_wait(lk, boost::posix_time::microsec_clock::universal_time() + posix_wait_time, flagIsSet);
+}
+
+//------------------------------------------------------------------------------
+
+void timed_wait_relative_without_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ while (!flagIsSet())
+ {
+ cv.timed_wait(lk, posix_wait_time);
+ }
+}
+
+void timed_wait_relative_with_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ cv.timed_wait(lk, posix_wait_time, flagIsSet);
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_DATETIME not defined for this platform as not supported"
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifdef BOOST_THREAD_USES_CHRONO
+
+boost::chrono::milliseconds chrono_wait_time(1000);
+
+template <typename F>
+void test_chrono_wait_function(F f)
+{
+ flag = false;
+ waiting = false;
+ boost::thread t(f);
+ while (!threadIsWaiting())
+ {
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(1));
+ }
+
+ boost::unique_lock<boost::mutex> lk(mut);
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ boost::chrono::steady_clock::time_point t0 = boost::chrono::steady_clock::now();
+ flag = true;
+ cv.notify_one();
+ lk.unlock();
+ t.join();
+ boost::chrono::steady_clock::time_point t1 = boost::chrono::steady_clock::now();
+
+ BOOST_TEST(t1 - t0 < boost::chrono::milliseconds(250));
+}
+
+//------------------------------------------------------------------------------
+
+void wait_until_system_without_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ while (!flagIsSet())
+ {
+ cv.wait_until(lk, boost::chrono::system_clock::now() + chrono_wait_time);
+ }
+}
+
+void wait_until_system_with_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ cv.wait_until(lk, boost::chrono::system_clock::now() + chrono_wait_time, flagIsSet);
+}
+
+//------------------------------------------------------------------------------
+
+void wait_until_steady_without_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ while (!flagIsSet())
+ {
+ cv.wait_until(lk, boost::chrono::steady_clock::now() + chrono_wait_time);
+ }
+}
+
+void wait_until_steady_with_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ cv.wait_until(lk, boost::chrono::steady_clock::now() + chrono_wait_time, flagIsSet);
+}
+
+//------------------------------------------------------------------------------
+
+void wait_for_without_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ while (!flagIsSet())
+ {
+ cv.wait_for(lk, chrono_wait_time);
+ }
+}
+
+void wait_for_with_pred()
+{
+ boost::unique_lock<boost::mutex> lk(mut);
+ waiting = true;
+ cv.wait_for(lk, chrono_wait_time, flagIsSet);
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
+//------------------------------------------------------------------------------
+
+int main()
+{
+#ifdef BOOST_THREAD_USES_DATETIME
+ test_posix_wait_function(timed_wait_absolute_without_pred);
+ test_posix_wait_function(timed_wait_absolute_with_pred);
+ test_posix_wait_function(timed_wait_relative_without_pred);
+ test_posix_wait_function(timed_wait_relative_with_pred);
+#endif
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ test_chrono_wait_function(wait_until_system_without_pred);
+ test_chrono_wait_function(wait_until_system_with_pred);
+ test_chrono_wait_function(wait_until_steady_without_pred);
+ test_chrono_wait_function(wait_until_steady_with_pred);
+ test_chrono_wait_function(wait_for_without_pred);
+ test_chrono_wait_function(wait_for_with_pred);
+#endif
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pass.cpp
new file mode 100644
index 000000000..b1fca89f6
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pass.cpp
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable_any>
+
+// class condition_variable_any;
+
+// condition_variable_any(const condition_variable_any&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+boost::condition_variable_any cv;
+
+typedef boost::timed_mutex L0;
+typedef boost::unique_lock<L0> L1;
+
+L0 m0;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+typedef boost::chrono::system_clock Clock;
+typedef boost::chrono::milliseconds milliseconds;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+ L1 lk(m0);
+ BOOST_TEST(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ Clock::time_point t0 = Clock::now();
+ Clock::time_point t = t0 + milliseconds(250);
+ while (test2 == 0 && cv.wait_for(lk, t - Clock::now()) == boost::cv_status::no_timeout) {}
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ BOOST_TEST(test2 != 0);
+ }
+ else
+ {
+ ns d = t1 - t0 - ms(250);
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ BOOST_TEST(test2 == 0);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ L1 lk(m0);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ L1 lk(m0);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pred_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pred_pass.cpp
new file mode 100644
index 000000000..3885b23c1
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pred_pass.cpp
@@ -0,0 +1,118 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable_any>
+
+// class condition_variable_any;
+
+// condition_variable_any(const condition_variable_any&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+class Pred
+{
+ int& i_;
+public:
+ explicit Pred(int& i) :
+ i_(i)
+ {
+ }
+
+ bool operator()()
+ {
+ return i_ != 0;
+ }
+};
+
+boost::condition_variable_any cv;
+
+typedef boost::timed_mutex L0;
+typedef boost::unique_lock<L0> L1;
+
+L0 m0;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+typedef boost::chrono::system_clock Clock;
+typedef boost::chrono::milliseconds milliseconds;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+ L1 lk(m0);
+ BOOST_TEST(test2 == 0);
+ test1 = 1;
+ cv.notify_one();
+ Clock::time_point t0 = Clock::now();
+ cv.wait_for(lk, milliseconds(250), Pred(test2));
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ ns d = t1 - t0 ;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ BOOST_TEST(test2 != 0);
+ }
+ else
+ {
+ ns d = t1 - t0 - ms(250);
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ BOOST_TEST(test2 == 0);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ L1 lk(m0);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ L1 lk(m0);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pass.cpp
new file mode 100644
index 000000000..acf5fb1c4
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pass.cpp
@@ -0,0 +1,115 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable_any>
+
+// class condition_variable_any;
+
+// condition_variable_any(const condition_variable_any&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+struct Clock
+{
+ typedef boost::chrono::milliseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef boost::chrono::time_point<Clock> time_point;
+ static const bool is_steady = true;
+
+ static time_point now()
+ {
+ using namespace boost::chrono;
+ return time_point(duration_cast<duration> (steady_clock::now().time_since_epoch()));
+ }
+};
+
+boost::condition_variable_any cv;
+
+typedef boost::timed_mutex L0;
+typedef boost::unique_lock<L0> L1;
+
+L0 m0;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+ L1 lk(m0);
+ BOOST_TEST(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) == boost::cv_status::no_timeout) {}
+ Clock::time_point t1 = Clock::now();
+ if (runs == 0)
+ {
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ BOOST_TEST(test2 != 0);
+ }
+ else
+ {
+ ns d = t1 - t0 - ms(250);
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ BOOST_TEST(test2 == 0);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ L1 lk(m0);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ L1 lk(m0);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pred_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pred_pass.cpp
new file mode 100644
index 000000000..f6e9b7ee2
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pred_pass.cpp
@@ -0,0 +1,134 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable_any>
+
+// class condition_variable_any;
+
+// condition_variable_any(const condition_variable_any&) = delete;
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+struct Clock
+{
+ typedef boost::chrono::milliseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef boost::chrono::time_point<Clock> time_point;
+ static const bool is_steady = true;
+
+ static time_point now()
+ {
+ using namespace boost::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;
+ }
+};
+
+boost::condition_variable_any cv;
+
+typedef boost::timed_mutex L0;
+typedef boost::unique_lock<L0> L1;
+
+L0 m0;
+
+int test1 = 0;
+int test2 = 0;
+
+int runs = 0;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+ L1 lk(m0);
+ BOOST_TEST(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)
+ {
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ BOOST_TEST(test2 != 0);
+ BOOST_TEST(r);
+ }
+ else
+ {
+ ns d = t1 - t0 - ms(250);
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ BOOST_TEST(test2 == 0);
+ BOOST_TEST(!r);
+ }
+ ++runs;
+}
+
+int main()
+{
+ {
+ L1 lk(m0);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ test2 = 1;
+ lk.unlock();
+ cv.notify_one();
+ t.join();
+ }
+ test1 = 0;
+ test2 = 0;
+ {
+ L1 lk(m0);
+ boost::thread t(f);
+ BOOST_TEST(test1 == 0);
+ while (test1 == 0)
+ cv.wait(lk);
+ BOOST_TEST(test1 != 0);
+ lk.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/sync/conditions/cv_status/cv_status_pass.cpp b/src/boost/libs/thread/test/sync/conditions/cv_status/cv_status_pass.cpp
new file mode 100644
index 000000000..becac4da5
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/cv_status/cv_status_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// static unsigned hardware_concurrency();
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ BOOST_TEST(boost::cv_status::no_timeout != boost::cv_status::timeout);
+ }
+ {
+ boost::cv_status st = boost::cv_status::no_timeout;
+ BOOST_TEST(st == boost::cv_status::no_timeout);
+ BOOST_TEST(boost::cv_status::no_timeout==st);
+ BOOST_TEST(st != boost::cv_status::timeout);
+ BOOST_TEST(boost::cv_status::timeout!=st);
+ }
+ {
+ boost::cv_status st = boost::cv_status::timeout;
+ BOOST_TEST(st == boost::cv_status::timeout);
+ BOOST_TEST(boost::cv_status::timeout==st);
+ BOOST_TEST(st != boost::cv_status::no_timeout);
+ BOOST_TEST(boost::cv_status::no_timeout!=st);
+ }
+ {
+ boost::cv_status st;
+ st = boost::cv_status::no_timeout;
+ BOOST_TEST(st == boost::cv_status::no_timeout);
+ BOOST_TEST(boost::cv_status::no_timeout==st);
+ BOOST_TEST(st != boost::cv_status::timeout);
+ BOOST_TEST(boost::cv_status::timeout!=st);
+ }
+ {
+ boost::cv_status st;
+ st = boost::cv_status::timeout;
+ BOOST_TEST(st == boost::cv_status::timeout);
+ BOOST_TEST(boost::cv_status::timeout==st);
+ BOOST_TEST(st != boost::cv_status::no_timeout);
+ BOOST_TEST(boost::cv_status::no_timeout!=st);
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/conditions/notify_all_at_thread_exit_pass.cpp b/src/boost/libs/thread/test/sync/conditions/notify_all_at_thread_exit_pass.cpp
new file mode 100644
index 000000000..d6eecbd95
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/conditions/notify_all_at_thread_exit_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/condition_variable.hpp>
+
+// void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
+
+#define BOOST_THREAD_USES_MOVE
+#define BOOST_THREAD_VESRION 3
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/chrono/chrono.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::condition_variable cv;
+boost::mutex mut;
+
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::high_resolution_clock Clock;
+
+void func()
+{
+ boost::unique_lock < boost::mutex > lk(mut);
+ boost::notify_all_at_thread_exit(cv, boost::move(lk));
+ boost::this_thread::sleep_for(ms(300));
+}
+
+int main()
+{
+ boost::unique_lock < boost::mutex > lk(mut);
+ boost::thread(func).detach();
+ Clock::time_point t0 = Clock::now();
+ cv.wait(lk);
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(t1 - t0 > ms(250));
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/async/async_executor_pass.cpp b/src/boost/libs/thread/test/sync/futures/async/async_executor_pass.cpp
new file mode 100644
index 000000000..d5a0f4423
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/async/async_executor_pass.cpp
@@ -0,0 +1,250 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// template <class Executor, class F, class... Args>
+// future<typename result_of<F(Args...)>::type>
+// async(Executor& ex, F&& f, Args&&... args);
+
+#define BOOST_THREAD_VERSION 5
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+#include <iostream>
+#include <boost/thread/future.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/detail/memory.hpp>
+#include <boost/thread/csbl/memory/unique_ptr.hpp>
+#include <memory>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/thread/executors/basic_thread_pool.hpp>
+#include <boost/thread/executor.hpp>
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef boost::chrono::milliseconds ms;
+
+class A
+{
+ long data_;
+
+public:
+ typedef long result_type;
+
+ explicit A(long i) :
+ data_(i)
+ {
+ }
+
+ long doit() const
+ {
+ boost::this_thread::sleep_for(ms(200));
+ return data_;
+ }
+ long operator()() const
+ {
+ boost::this_thread::sleep_for(ms(200));
+ return data_;
+ }
+};
+
+class MoveOnly
+{
+public:
+ typedef int result_type;
+
+ int value;
+
+BOOST_THREAD_MOVABLE_ONLY(MoveOnly)
+ MoveOnly()
+ {
+ value = 0;
+ }
+ MoveOnly( BOOST_THREAD_RV_REF(MoveOnly))
+ {
+ value = 1;
+ }
+ MoveOnly& operator=(BOOST_THREAD_RV_REF(MoveOnly))
+ {
+ value = 2;
+ return *this;
+ }
+
+ int operator()()
+ {
+ boost::this_thread::sleep_for(ms(200));
+ return 3;
+ }
+ template <typename OS>
+ friend OS& operator<<(OS& os, MoveOnly const& v)
+ {
+ os << v.value;
+ return os;
+ }
+ };
+
+ namespace boost
+ {
+BOOST_THREAD_DCL_MOVABLE (MoveOnly)
+ }
+
+int f0()
+{
+ boost::this_thread::sleep_for(ms(200));
+ return 3;
+}
+
+int i = 0;
+
+int& f1()
+{
+ boost::this_thread::sleep_for(ms(200));
+ return i;
+}
+
+void f2()
+{
+ boost::this_thread::sleep_for(ms(200));
+}
+
+boost::csbl::unique_ptr<int> f3_0()
+{
+ boost::this_thread::sleep_for(ms(200));
+ boost::csbl::unique_ptr<int> r( (new int(3)));
+ return boost::move(r);
+}
+MoveOnly f3_1()
+{
+ boost::this_thread::sleep_for(ms(200));
+ MoveOnly r;
+ return boost::move(r);
+}
+
+boost::csbl::unique_ptr<int> f3(int i)
+{
+ boost::this_thread::sleep_for(ms(200));
+ return boost::csbl::unique_ptr<int>(new int(i));
+}
+
+boost::csbl::unique_ptr<int> f4(
+ BOOST_THREAD_RV_REF_BEG boost::csbl::unique_ptr<int> BOOST_THREAD_RV_REF_END p
+)
+{
+ boost::this_thread::sleep_for(ms(200));
+ return boost::move(p);
+}
+
+struct check_timer {
+ boost::chrono::nanoseconds delay;
+ Clock::time_point start;
+ check_timer(boost::chrono::nanoseconds delay)
+ : delay(delay)
+ , start(Clock::now())
+ {
+ }
+ ~check_timer() {
+ Clock::time_point now = Clock::now();
+ BOOST_TEST(now - start < delay);
+ std::cout << __FILE__ << "[" << __LINE__ << "] " << (now - start).count() << std::endl;
+ }
+
+};
+
+int main()
+{
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+#if defined BOOST_THREAD_PROVIDES_EXECUTORS
+ {
+ try
+ {
+ boost::executor_adaptor<boost::basic_thread_pool> ex(1);
+ boost::future<int> f = boost::async(ex, &f0);
+ boost::this_thread::sleep_for(ms(300));
+ int res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+#endif
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) && defined BOOST_THREAD_PROVIDES_EXECUTORS
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::executor_adaptor<boost::basic_thread_pool> ex(1);
+ boost::future<long> f = boost::async(ex, A(3));
+ boost::this_thread::sleep_for(ms(300));
+ int res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+
+ }
+#endif
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) && defined BOOST_THREAD_PROVIDES_EXECUTORS
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::executor_adaptor<boost::basic_thread_pool> ex(1);
+ MoveOnly mo;
+ boost::future<int> f = boost::async(ex, boost::move(mo));
+ //boost::future<int> f = boost::async(ex, MoveOnly());
+ boost::this_thread::sleep_for(ms(300));
+ int res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+#endif
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/futures/async/async_pass.cpp b/src/boost/libs/thread/test/sync/futures/async/async_pass.cpp
new file mode 100644
index 000000000..86fdfdbec
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/async/async_pass.cpp
@@ -0,0 +1,903 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// 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);
+
+//#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+#include <iostream>
+#include <boost/thread/future.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/detail/memory.hpp>
+#include <boost/thread/csbl/memory/unique_ptr.hpp>
+#include <memory>
+#include <boost/detail/lightweight_test.hpp>
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef boost::chrono::milliseconds ms;
+
+class A
+{
+ long data_;
+
+public:
+ typedef long result_type;
+
+ explicit A(long i) :
+ data_(i)
+ {
+ }
+
+ long doit() const
+ {
+ boost::this_thread::sleep_for(ms(200));
+ return data_;
+ }
+ long operator()() const
+ {
+ boost::this_thread::sleep_for(ms(200));
+ return data_;
+ }
+};
+
+class MoveOnly
+{
+public:
+ typedef int result_type;
+
+ int value;
+
+ BOOST_THREAD_MOVABLE_ONLY(MoveOnly)
+ MoveOnly()
+ {
+ value = 0;
+ }
+ MoveOnly( BOOST_THREAD_RV_REF(MoveOnly))
+ {
+ value = 1;
+ }
+ MoveOnly& operator=(BOOST_THREAD_RV_REF(MoveOnly))
+ {
+ value = 2;
+ return *this;
+ }
+
+ int operator()() const
+ {
+ boost::this_thread::sleep_for(ms(200));
+ return 3;
+ }
+ template <typename OS>
+ friend OS& operator<<(OS& os, MoveOnly const& v)
+ {
+ os << v.value;
+ return os;
+ }
+};
+
+namespace boost
+{
+ BOOST_THREAD_DCL_MOVABLE (MoveOnly)
+}
+
+int f0()
+{
+ boost::this_thread::sleep_for(ms(200));
+ return 3;
+}
+
+int i = 0;
+
+int& f1()
+{
+ boost::this_thread::sleep_for(ms(200));
+ return i;
+}
+
+void f2()
+{
+ boost::this_thread::sleep_for(ms(200));
+}
+
+boost::csbl::unique_ptr<int> f3_0()
+{
+ boost::this_thread::sleep_for(ms(200));
+ boost::csbl::unique_ptr<int> r( (new int(3)));
+ return boost::move(r);
+}
+MoveOnly f3_1()
+{
+ boost::this_thread::sleep_for(ms(200));
+ MoveOnly r;
+ return boost::move(r);
+}
+
+boost::csbl::unique_ptr<int> f3(int i)
+{
+ boost::this_thread::sleep_for(ms(200));
+ return boost::csbl::unique_ptr<int>(new int(i));
+}
+
+boost::csbl::unique_ptr<int> f4(
+ BOOST_THREAD_RV_REF_BEG boost::csbl::unique_ptr<int> BOOST_THREAD_RV_REF_END p
+)
+{
+ boost::this_thread::sleep_for(ms(200));
+ return boost::move(p);
+}
+
+struct check_timer {
+ boost::chrono::nanoseconds delay;
+ Clock::time_point start;
+ check_timer(boost::chrono::nanoseconds delay)
+ : delay(delay)
+ , start(Clock::now())
+ {
+ }
+ ~check_timer() {
+ Clock::time_point now = Clock::now();
+ BOOST_TEST(now - start < delay);
+ std::cout << __FILE__ << "[" << __LINE__ << "] " << (now - start).count() << std::endl;
+ }
+
+};
+
+int main()
+{
+ {
+ try {
+ boost::async(f0);
+ } catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+ {
+ try {
+ boost::async(boost::launch::async, f0);
+ } catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try {
+ boost::async(boost::launch::deferred, f0);
+ } catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+#endif
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::future<int> f = boost::async(f0);
+ boost::this_thread::sleep_for(ms(300));
+ int res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::shared_future<int> f = boost::async(f0).share();
+ boost::this_thread::sleep_for(ms(300));
+ int res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::future<int> f = boost::async(boost::launch::async, f0);
+ boost::this_thread::sleep_for(ms(300));
+ int res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::future<long> f = boost::async(boost::launch::async, A(3));
+ boost::this_thread::sleep_for(ms(300));
+ int res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+
+ }
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::future<long> f = boost::async(boost::launch::deferred, A(3));
+ //boost::this_thread::sleep_for(ms(300));
+ int res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+
+ }
+#endif
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ A a(3);
+ boost::future<long> f = boost::async(boost::launch::async, &A::doit, &a);
+ boost::this_thread::sleep_for(ms(300));
+ int res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ A a(3);
+ boost::future<long> f = boost::async(boost::launch::deferred, &A::doit, &a);
+ boost::this_thread::sleep_for(ms(300));
+ int res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+
+ }
+#endif
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::future<int> f = boost::async(boost::launch::async, BOOST_THREAD_MAKE_RV_REF(MoveOnly()));
+ boost::this_thread::sleep_for(ms(300));
+ int res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::future<int> f = boost::async(boost::launch::deferred, BOOST_THREAD_MAKE_RV_REF(MoveOnly()));
+ boost::this_thread::sleep_for(ms(300));
+ int res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+#endif
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::future<int> f = boost::async(boost::launch::any, f0);
+ boost::this_thread::sleep_for(ms(300));
+ int res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
+ {
+ try
+ {
+ boost::future<int> f = boost::async(boost::launch::deferred, f0);
+ //boost::this_thread::sleep_for(ms(300));
+ int res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+#endif
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::future<int&> f = boost::async(f1);
+ boost::this_thread::sleep_for(ms(300));
+ int* res;
+ {
+ check_timer timer(ms(500));
+ res = &f.get();
+ }
+ BOOST_TEST(res == &i);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::future<int&> f = boost::async(boost::launch::async, f1);
+ boost::this_thread::sleep_for(ms(300));
+ int* res;
+ {
+ check_timer timer(ms(500));
+ res = &f.get();
+ }
+ BOOST_TEST(res == &i);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::future<int&> f = boost::async(boost::launch::any, f1);
+ boost::this_thread::sleep_for(ms(300));
+ int* res;
+ {
+ check_timer timer(ms(500));
+ res = &f.get();
+ }
+ BOOST_TEST(res == &i);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
+ {
+ try
+ {
+ boost::future<int&> f = boost::async(boost::launch::deferred, f1);
+ //boost::this_thread::sleep_for(ms(300));
+ int* res;
+ {
+ check_timer timer(ms(500));
+ res = &f.get();
+ }
+ BOOST_TEST(res == &i);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+#endif
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::future<void> f = boost::async(f2);
+ boost::this_thread::sleep_for(ms(300));
+ {
+ check_timer timer(ms(500));
+ f.get();
+ }
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::future<void> f = boost::async(boost::launch::async, f2);
+ boost::this_thread::sleep_for(ms(300));
+ {
+ check_timer timer(ms(500));
+ f.get();
+ }
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::future<void> f = boost::async(boost::launch::any, f2);
+ boost::this_thread::sleep_for(ms(300));
+ {
+ check_timer timer(ms(500));
+ f.get();
+ }
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
+ {
+ try
+ {
+ boost::future<void> f = boost::async(boost::launch::deferred, f2);
+ //boost::this_thread::sleep_for(ms(300));
+ {
+ check_timer timer(ms(500));
+ f.get();
+ }
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+#endif
+
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::future<MoveOnly> f = boost::async(&f3_1);
+ boost::this_thread::sleep_for(ms(300));
+ MoveOnly res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST_EQ(res.value, 2);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::future<MoveOnly> f = boost::async(boost::launch::deferred, &f3_1);
+ //boost::this_thread::sleep_for(ms(300));
+ MoveOnly res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST_EQ(res.value, 2);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+#endif
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::future<MoveOnly> f;
+ f = boost::async(&f3_1);
+ boost::this_thread::sleep_for(ms(300));
+ MoveOnly res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(res.value == 2);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ try
+ {
+ boost::future<boost::csbl::unique_ptr<int> > f = boost::async(&f3_0);
+ boost::this_thread::sleep_for(ms(300));
+ boost::csbl::unique_ptr<int> res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(*res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
+ {
+ try
+ {
+ boost::future<boost::csbl::unique_ptr<int> > f = boost::async(boost::launch::async, &f3, 3);
+ boost::this_thread::sleep_for(ms(300));
+ boost::csbl::unique_ptr<int> res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(*res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
+ {
+ try
+ {
+ boost::future<boost::csbl::unique_ptr<int> > f = boost::async(boost::launch::deferred, &f3, 3);
+ //boost::this_thread::sleep_for(ms(300));
+ boost::csbl::unique_ptr<int> res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(*res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
+ {
+ try
+ {
+ boost::future<boost::csbl::unique_ptr<int> > f = boost::async(&f3, 3);
+ boost::this_thread::sleep_for(ms(300));
+ boost::csbl::unique_ptr<int> res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(*res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
+ {
+ try
+ {
+ boost::future<boost::csbl::unique_ptr<int> > f = boost::async(boost::launch::async, &f4, boost::csbl::unique_ptr<int>(new int(3)));
+ boost::this_thread::sleep_for(ms(300));
+ boost::csbl::unique_ptr<int> res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(*res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
+ {
+ try
+ {
+ boost::future<boost::csbl::unique_ptr<int> > f = boost::async(boost::launch::deferred, &f4, boost::csbl::unique_ptr<int>(new int(3)));
+ //boost::this_thread::sleep_for(ms(300));
+ boost::csbl::unique_ptr<int> res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(*res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
+ {
+ try
+ {
+ boost::future<boost::csbl::unique_ptr<int> > f = boost::async(&f4, boost::csbl::unique_ptr<int>(new int(3)));
+ boost::this_thread::sleep_for(ms(300));
+ boost::csbl::unique_ptr<int> res;
+ {
+ check_timer timer(ms(500));
+ res = f.get();
+ }
+ BOOST_TEST(*res == 3);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
+ BOOST_TEST(false && "exception thrown");
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception thrown");
+ }
+ }
+#endif
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/futures/future/async_deferred_then_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/async_deferred_then_pass.cpp
new file mode 100644
index 000000000..b400074cd
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/future/async_deferred_then_pass.cpp
@@ -0,0 +1,153 @@
+// Copyright (C) 2012-2013 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class future<R>
+
+// template<typename F>
+// auto then(F&& func) -> future<decltype(func(*this))>;
+
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#include <boost/thread/detail/log.hpp>
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+
+
+int p1()
+{
+ BOOST_THREAD_LOG << "p1 < " << BOOST_THREAD_END_LOG;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p1 >" << BOOST_THREAD_END_LOG;
+ return 1;
+}
+
+int p2(boost::future<int> f)
+{
+ BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
+ BOOST_TEST(f.valid());
+ int i = f.get();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
+ return 2 * i;
+}
+
+void p3(boost::future<int> f)
+{
+ BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG;
+ BOOST_TEST(f.valid());
+ int i = f.get();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p3 <" << &f << " " <<i << BOOST_THREAD_END_LOG;
+ return;
+}
+
+int main()
+{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ try
+ {
+ boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);
+ BOOST_TEST(f1.valid());
+ {
+ boost::future<int> f2 = f1.then(&p2);
+ BOOST_TEST(f2.valid());
+ }
+ BOOST_TEST(! f1.valid());
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<int> f2 = f1.then(&p2);
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(! f1.valid());
+ try
+ {
+ BOOST_TEST(f2.get()==2);
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<void> f2 = f1.then(&p3);
+ BOOST_TEST(f2.valid());
+ try
+ {
+ f2.wait();
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f2 = boost::async(boost::launch::deferred, p1).then(&p2);
+ BOOST_TEST(f2.get()==2);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f1 = boost::async(boost::launch::deferred, p1);
+ boost::future<int> f21 = f1.then(&p2);
+ boost::future<int> f2= f21.then(&p2);
+ BOOST_TEST(f2.get()==4);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f1 = boost::async(boost::launch::deferred, p1);
+ boost::future<int> f2= f1.then(&p2).then(&p2);
+ BOOST_TEST(f2.get()==4);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f2 = boost::async(boost::launch::deferred, p1).then(&p2).then(&p2);
+ BOOST_TEST(f2.get()==4);
+ }
+
+ return boost::report_errors();
+}
+
+#else
+
+int main()
+{
+ return 0;
+}
+#endif
diff --git a/src/boost/libs/thread/test/sync/futures/future/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/futures/future/copy_assign_fail.cpp
new file mode 100644
index 000000000..170f3a057
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/future/copy_assign_fail.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class future<R>
+
+// future& operator=(const future&) = delete;
+
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::future<T> f0 = p.get_future();
+ boost::future<T> f;
+ f = f0;
+ }
+
+ return boost::report_errors();
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/futures/future/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/futures/future/copy_ctor_fail.cpp
new file mode 100644
index 000000000..3a16afd50
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/future/copy_ctor_fail.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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class future<R>
+
+// future(const future&) = delete;
+
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::future<T> f0 = p.get_future();
+ boost::future<T> f = f0;
+ }
+
+ return boost::report_errors();
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/futures/future/default_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/default_pass.cpp
new file mode 100644
index 000000000..1b4cf392f
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/future/default_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class future<R>
+
+// future();
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ boost::future<int> f;
+ BOOST_TEST(!f.valid());
+ }
+ {
+ boost::future<int&> f;
+ BOOST_TEST(!f.valid());
+ }
+ {
+ boost::future<void> f;
+ BOOST_TEST(!f.valid());
+ }
+
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/future/dtor_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/dtor_pass.cpp
new file mode 100644
index 000000000..abfca7d8c
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/future/dtor_pass.cpp
@@ -0,0 +1,109 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class future<R>
+
+// ~future();
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/exception/exception.hpp>
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#include "../test_allocator.hpp"
+#endif
+
+int main()
+{
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ typedef int T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p(boost::allocator_arg, test_allocator<T>());
+ BOOST_TEST(test_alloc_base::count == 1);
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ typedef int& T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p(boost::allocator_arg, test_allocator<int>());
+ BOOST_TEST(test_alloc_base::count == 1);
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ typedef void T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p(boost::allocator_arg, test_allocator<T>());
+ BOOST_TEST(test_alloc_base::count == 1);
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+#endif
+ {
+ typedef int T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int& T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef void T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(f.valid());
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/future/get_or_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/get_or_pass.cpp
new file mode 100644
index 000000000..7db938d37
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/future/get_or_pass.cpp
@@ -0,0 +1,187 @@
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class future<R>
+
+// R future::get_or(R&&);
+// R& future<R&>::get_or(R&);
+
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#include <boost/thread/detail/log.hpp>
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/core/ref.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+namespace boost
+{
+template <typename T>
+struct wrap
+{
+ wrap(T const& v) : value(v){}
+ T value;
+
+};
+
+template <typename T>
+exception_ptr make_exception_ptr(T v) {
+ return copy_exception(wrap<T>(v));
+}
+}
+
+void func1(boost::promise<int> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_value(3);
+}
+
+void func2(boost::promise<int> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_exception(boost::make_exception_ptr(3));
+}
+
+int j = 0;
+
+void func3(boost::promise<int&> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func4(boost::promise<int&> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_exception(boost::make_exception_ptr(3.5));
+}
+
+void func5(boost::promise<void> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_value();
+}
+
+void func6(boost::promise<void> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_exception(boost::make_exception_ptr(4));
+}
+
+
+int main()
+{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ typedef int T;
+ {
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func1, boost::move(p)).detach();
+#else
+ p.set_value(3);
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST(f.get_or(4) == 3);
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ BOOST_TEST(!f.valid());
+#endif
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::promise<T> p;
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<T> f = p.get_future();
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func2, boost::move(p)).detach();
+#else
+ p.set_exception(boost::make_exception_ptr(3));
+#endif
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ try
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ BOOST_TEST(f.valid());
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ BOOST_TEST(f.get_or(4) == 4);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ BOOST_TEST(!f.valid());
+#endif
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ typedef int& T;
+ {
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func3, boost::move(p)).detach();
+#else
+ int j=5;
+ p.set_value(j);
+#endif
+ BOOST_TEST(f.valid());
+ int k=4;
+ BOOST_TEST(f.get_or(boost::ref(k)) == 5);
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ BOOST_TEST(!f.valid());
+#endif
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func4, boost::move(p)).detach();
+#else
+ p.set_exception(boost::make_exception_ptr(3.5));
+#endif
+ try
+ {
+ BOOST_TEST(f.valid());
+ int j=4;
+ BOOST_TEST(f.get_or(boost::ref(j)) == 4);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ BOOST_TEST(!f.valid());
+#endif
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/sync/futures/future/get_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/get_pass.cpp
new file mode 100644
index 000000000..ec2ccf8b0
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/future/get_pass.cpp
@@ -0,0 +1,268 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class future<R>
+
+// const R& future::get();
+// R& future<R&>::get();
+// void future<void>::get();
+
+//#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#include <boost/thread/detail/log.hpp>
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+namespace boost
+{
+template <typename T>
+struct wrap
+{
+ wrap(T const& v) : value(v){}
+ T value;
+
+};
+
+template <typename T>
+exception_ptr make_exception_ptr(T v) {
+ return copy_exception(wrap<T>(v));
+}
+}
+
+void func1(boost::promise<int> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_value(3);
+}
+
+void func2(boost::promise<int> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_exception(boost::make_exception_ptr(3));
+}
+
+int j = 0;
+
+void func3(boost::promise<int&> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func4(boost::promise<int&> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_exception(boost::make_exception_ptr(3.5));
+}
+
+void func5(boost::promise<void> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_value();
+}
+
+void func6(boost::promise<void> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_exception(boost::make_exception_ptr(4));
+}
+
+
+int main()
+{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ typedef int T;
+ {
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func1, boost::move(p)).detach();
+#else
+ p.set_value(3);
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST(f.get() == 3);
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ BOOST_TEST(!f.valid());
+#endif
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::promise<T> p;
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ boost::future<T> f = p.get_future();
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func2, boost::move(p)).detach();
+#else
+ p.set_exception(boost::make_exception_ptr(3));
+#endif
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ try
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ BOOST_TEST(f.valid());
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ BOOST_TEST(f.get() == 3);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ }
+ catch (boost::wrap<int> const& i)
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ BOOST_TEST(i.value == 3);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ }
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ BOOST_TEST(!f.valid());
+#endif
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ typedef int& T;
+ {
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func3, boost::move(p)).detach();
+#else
+ int j=5;
+ p.set_value(j);
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST(f.get() == 5);
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ BOOST_TEST(!f.valid());
+#endif
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func4, boost::move(p)).detach();
+#else
+ p.set_exception(boost::make_exception_ptr(3.5));
+#endif
+ try
+ {
+ BOOST_TEST(f.valid());
+ BOOST_TEST(f.get() == 3);
+ BOOST_TEST(false);
+ }
+ catch (boost::wrap<double> const& i)
+ {
+ BOOST_TEST(i.value == 3.5);
+ }
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ BOOST_TEST(!f.valid());
+#endif
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func4, boost::move(p)).detach();
+#else
+ p.set_exception(boost::make_exception_ptr(3.5));
+#endif
+ try
+ {
+ BOOST_TEST(f.valid());
+ boost::exception_ptr ptr = f.get_exception_ptr();
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ BOOST_TEST(f.valid());
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+
+ typedef void T;
+ {
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func5, boost::move(p)).detach();
+#else
+ p.set_value();
+#endif
+ BOOST_TEST(f.valid());
+ f.get();
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ BOOST_TEST(!f.valid());
+#endif
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func6, boost::move(p)).detach();
+#else
+ p.set_exception(boost::make_exception_ptr(4));
+#endif
+ try
+ {
+ BOOST_TEST(f.valid());
+ f.get();
+ BOOST_TEST(false);
+ }
+ catch (boost::wrap<int> const& i)
+ {
+ BOOST_TEST(i.value == 4);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
+ BOOST_TEST(!f.valid());
+#endif
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/sync/futures/future/move_assign_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/move_assign_pass.cpp
new file mode 100644
index 000000000..ebb13e5e0
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/future/move_assign_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <future>
+
+// class future<R>
+
+// future& operator=(future&& rhs);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int T;
+ boost::future<T> f0;
+ boost::future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int& T;
+ boost::future<T> f0;
+ boost::future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef void T;
+ boost::future<T> f0;
+ boost::future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+
+
+ return boost::report_errors();
+
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/future/move_ctor_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/move_ctor_pass.cpp
new file mode 100644
index 000000000..8da893a3c
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/future/move_ctor_pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <future>
+
+// class future<R>
+
+// future(future&& rhs);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m;
+
+int main()
+{
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int T;
+ boost::future<T> f0;
+ boost::future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int& T;
+ boost::future<T> f0;
+ boost::future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef void T;
+ boost::future<T> f0;
+ boost::future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/future/share_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/share_pass.cpp
new file mode 100644
index 000000000..91c07f5cd
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/future/share_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class future<R>
+
+// shared_future<R> share() &&;
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::shared_future<T> sf = f0.share();
+ boost::shared_future<T> f = sf;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int T;
+ boost::future<T> f0;
+ boost::shared_future<T> sf = f0.share();
+ boost::shared_future<T> f = sf;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::shared_future<T> sf = f0.share();
+ boost::shared_future<T> f = sf;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int& T;
+ boost::future<T> f0;
+ boost::shared_future<T> sf = f0.share();
+ boost::shared_future<T> f = sf;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::shared_future<T> sf = f0.share();
+ boost::shared_future<T> f = sf;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef void T;
+ boost::future<T> f0;
+ boost::shared_future<T> sf = f0.share();
+ boost::shared_future<T> f = sf;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/future/then_deferred_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/then_deferred_pass.cpp
new file mode 100644
index 000000000..0ea37bd7f
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/future/then_deferred_pass.cpp
@@ -0,0 +1,137 @@
+// Copyright (C) 2012-2013 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class future<R>
+
+// template<typename F>
+// auto then(F&& func) -> future<decltype(func(*this))>;
+
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#include <boost/thread/detail/log.hpp>
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <cassert>
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+int p1()
+{
+ BOOST_THREAD_LOG << "p1 < " << BOOST_THREAD_END_LOG;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p1 >" << BOOST_THREAD_END_LOG;
+ return 1;
+}
+
+int p2(boost::future<int> f)
+{
+ assert(f.is_ready());
+
+ BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
+ BOOST_TEST(f.valid());
+ int i = f.get();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
+ return 2 * i;
+}
+
+void p3(boost::future<int> f)
+{
+ assert(f.is_ready());
+ BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG;
+ BOOST_TEST(f.valid());
+ int i = f.get();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p3 <" << &f << " " <<i << BOOST_THREAD_END_LOG;
+ return;
+}
+
+int main()
+{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<int> f2 = f1.then(boost::launch::deferred, &p2);
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(! f1.valid());
+ try
+ {
+ BOOST_TEST(f2.get()==2);
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<void> f2 = f1.then(boost::launch::deferred, &p3);
+ BOOST_TEST(f2.valid());
+ try
+ {
+ f2.wait();
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f2 = boost::async(p1).then(boost::launch::deferred, &p2);
+ BOOST_TEST(f2.get()==2);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f1 = boost::async(p1);
+ boost::future<int> f21 = f1.then(boost::launch::deferred, &p2);
+ boost::future<int> f2= f21.then(boost::launch::deferred, &p2);
+ BOOST_TEST(f2.get()==4);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f1 = boost::async(p1);
+ boost::future<int> f2= f1.then(boost::launch::deferred, &p2).then(boost::launch::deferred, &p2);
+ BOOST_TEST(f2.get()==4);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f2 = boost::async(p1).then(boost::launch::deferred, &p2).then(boost::launch::deferred, &p2);
+ BOOST_TEST(f2.get()==4);
+ }
+
+ return boost::report_errors();
+}
+
+#else
+
+int main()
+{
+ return 0;
+}
+#endif
diff --git a/src/boost/libs/thread/test/sync/futures/future/then_executor_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/then_executor_pass.cpp
new file mode 100644
index 000000000..fcb062a0e
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/future/then_executor_pass.cpp
@@ -0,0 +1,152 @@
+// Copyright (C) 2014 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class future<R>
+
+// template<typename F>
+// auto then(F&& func) -> future<decltype(func(*this))>;
+
+#define BOOST_THREAD_VERSION 5
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#include <boost/thread/detail/log.hpp>
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/executors/basic_thread_pool.hpp>
+#include <boost/thread/executor.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <cassert>
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+int p1()
+{
+ BOOST_THREAD_LOG << "p1 < " << BOOST_THREAD_END_LOG;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p1 >" << BOOST_THREAD_END_LOG;
+ return 1;
+}
+
+int p2(boost::future<int> f)
+{
+ assert(f.is_ready());
+ BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
+ BOOST_TEST(f.valid());
+ int i = f.get();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
+ return 2 * i;
+}
+
+void p3(boost::future<int> f)
+{
+ assert(f.is_ready());
+ BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG;
+ BOOST_TEST(f.valid());
+ int i = f.get();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p3 <" << &f << " " <<i << BOOST_THREAD_END_LOG;
+ return;
+}
+
+int main()
+{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::basic_thread_pool ex(1);
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<int> f2 = f1.then(ex, &p2);
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(! f1.valid());
+ try
+ {
+ BOOST_TEST(f2.get()==2);
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::basic_thread_pool ex(1);
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<void> f2 = f1.then(ex, &p3);
+ BOOST_TEST(f2.valid());
+ try
+ {
+ f2.wait();
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::basic_thread_pool ex(1);
+ boost::future<int> f2 = boost::async(p1).then(ex, &p2);
+ BOOST_TEST(f2.get()==2);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::basic_thread_pool ex(1);
+ boost::future<int> f1 = boost::async(p1);
+ boost::future<int> f21 = f1.then(ex, &p2);
+ boost::future<int> f2= f21.then(ex, &p2);
+ BOOST_TEST(f2.get()==4);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::basic_thread_pool ex(1);
+ boost::future<int> f1 = boost::async(p1);
+ boost::future<int> f21 = f1.then(ex, &p2);
+ boost::future<int> f2= f21.then(&p2);
+ BOOST_TEST(f2.get()==4);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::basic_thread_pool ex(1);
+ boost::future<int> f1 = boost::async(p1);
+ boost::future<int> f2= f1.then(&p2).then(ex, &p2);
+ BOOST_TEST(f2.get()==4);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::basic_thread_pool ex(1);
+ boost::future<int> f2 = boost::async(p1).then(ex, &p2).then(ex, &p2);
+ BOOST_TEST(f2.get()==4);
+ }
+
+ return boost::report_errors();
+}
+
+#else
+
+int main()
+{
+ return 0;
+}
+#endif
diff --git a/src/boost/libs/thread/test/sync/futures/future/then_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/then_pass.cpp
new file mode 100644
index 000000000..12270679b
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/future/then_pass.cpp
@@ -0,0 +1,133 @@
+// Copyright (C) 2012-2013 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class future<R>
+
+// template<typename F>
+// auto then(F&& func) -> future<decltype(func(*this))>;
+
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#include <boost/thread/detail/log.hpp>
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+int p1()
+{
+ BOOST_THREAD_LOG << "p1 < " << BOOST_THREAD_END_LOG;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p1 >" << BOOST_THREAD_END_LOG;
+ return 1;
+}
+
+int p2(boost::future<int> f)
+{
+ BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
+ BOOST_TEST(f.valid());
+ int i = f.get();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
+ return 2 * i;
+}
+
+void p3(boost::future<int> f)
+{
+ BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG;
+ BOOST_TEST(f.valid());
+ int i = f.get();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p3 <" << &f << " " <<i << BOOST_THREAD_END_LOG;
+ return;
+}
+
+int main()
+{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<int> f2 = f1.then(&p2);
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(! f1.valid());
+ try
+ {
+ BOOST_TEST(f2.get()==2);
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<void> f2 = f1.then(&p3);
+ BOOST_TEST(f2.valid());
+ try
+ {
+ f2.wait();
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f2 = boost::async(p1).then(&p2);
+ BOOST_TEST(f2.get()==2);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f1 = boost::async(p1);
+ boost::future<int> f21 = f1.then(&p2);
+ boost::future<int> f2= f21.then(&p2);
+ BOOST_TEST(f2.get()==4);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f1 = boost::async(p1);
+ boost::future<int> f2= f1.then(&p2).then(&p2);
+ BOOST_TEST(f2.get()==4);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f2 = boost::async(p1).then(&p2).then(&p2);
+ BOOST_TEST(f2.get()==4);
+ }
+
+ return boost::report_errors();
+}
+
+#else
+
+int main()
+{
+ return 0;
+}
+#endif
diff --git a/src/boost/libs/thread/test/sync/futures/future/wait_for_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/wait_for_pass.cpp
new file mode 100644
index 000000000..71bca7abe
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/future/wait_for_pass.cpp
@@ -0,0 +1,174 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class future<R>
+
+// template <class Rep, class Period>
+// future_status
+// wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#include <boost/thread/detail/log.hpp>
+#include "../../../timming.hpp"
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/chrono/chrono_io.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+namespace boost
+{
+ template <typename OStream>
+ OStream& operator<<(OStream& os , boost::future_status st )
+ {
+ os << underlying_cast<int>(st) << " ";
+ return os;
+ }
+ template <typename T>
+ struct wrap
+ {
+ wrap(T const& v) :
+ value(v)
+ {
+ }
+ T value;
+
+ };
+
+ template <typename T>
+ exception_ptr make_exception_ptr(T v)
+ {
+ return copy_exception(wrap<T> (v));
+ }
+}
+
+void func1(boost::promise<int> p)
+{
+ boost::this_thread::sleep_for(ms(500));
+ p.set_value(3);
+}
+
+int j = 0;
+
+void func3(boost::promise<int&> p)
+{
+ boost::this_thread::sleep_for(ms(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func5(boost::promise<void> p)
+{
+ boost::this_thread::sleep_for(ms(500));
+ p.set_value();
+}
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+int main()
+{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ typedef boost::chrono::high_resolution_clock Clock;
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func1, boost::move(p)).detach();
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST_EQ(f.wait_for(ms(250)) , boost::future_status::timeout);
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#else
+ func1(boost::move(p));
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST_EQ(f.wait_for(ms(750)) , boost::future_status::ready);
+ BOOST_TEST(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(f.valid());
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func3, boost::move(p)).detach();
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST_EQ(f.wait_for(ms(250)) , boost::future_status::timeout);
+ BOOST_TEST(f.valid());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#else
+ func3(boost::move(p));
+#endif
+ BOOST_TEST_EQ(f.wait_for(ms(750)) , boost::future_status::ready);
+ BOOST_TEST(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(f.valid());
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func5, boost::move(p)).detach();
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST_EQ(f.wait_for(ms(250)) , boost::future_status::timeout);
+ BOOST_TEST(f.valid());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#else
+ func5(boost::move(p));
+#endif
+ BOOST_TEST_EQ(f.wait_for(ms(750)) , boost::future_status::ready);
+ BOOST_TEST(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(f.valid());
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/sync/futures/future/wait_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/wait_pass.cpp
new file mode 100644
index 000000000..daa9b376f
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/future/wait_pass.cpp
@@ -0,0 +1,155 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class future<R>
+
+// template <class Rep, class Period>
+// void wait() const;
+
+//#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#include <boost/thread/detail/log.hpp>
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/chrono/chrono_io.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+typedef boost::chrono::milliseconds ms;
+
+namespace boost
+{
+ template <typename OStream>
+ OStream& operator<<(OStream& os , boost::future_status st )
+ {
+ os << underlying_cast<int>(st) << " ";
+ return os;
+ }
+ template <typename T>
+ struct wrap
+ {
+ wrap(T const& v) :
+ value(v)
+ {
+ }
+ T value;
+
+ };
+
+ template <typename T>
+ exception_ptr make_exception_ptr(T v)
+ {
+ return copy_exception(wrap<T> (v));
+ }
+}
+
+void func1(boost::promise<int> p)
+{
+ boost::this_thread::sleep_for(ms(500));
+ p.set_value(3);
+}
+
+int j = 0;
+
+void func3(boost::promise<int&> p)
+{
+ boost::this_thread::sleep_for(ms(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func5(boost::promise<void> p)
+{
+ boost::this_thread::sleep_for(ms(500));
+ p.set_value();
+}
+
+int main()
+{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ typedef boost::chrono::high_resolution_clock Clock;
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func1, boost::move(p)).detach();
+#else
+ func1(boost::move(p));
+#endif
+ BOOST_TEST(f.valid());
+ f.wait();
+ BOOST_TEST(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(f.valid());
+ BOOST_TEST(t1 - t0 < ms(50));
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func3, boost::move(p)).detach();
+#else
+ func3(boost::move(p));
+#endif
+ BOOST_TEST(f.valid());
+ f.wait();
+ BOOST_TEST(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(f.valid());
+ BOOST_TEST(t1 - t0 < ms(50));
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func5, boost::move(p)).detach();
+#else
+ func5(boost::move(p));
+#endif
+ BOOST_TEST(f.valid());
+ f.wait();
+ BOOST_TEST(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(f.valid());
+ BOOST_TEST(t1 - t0 < ms(50));
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/sync/futures/future/wait_until_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/wait_until_pass.cpp
new file mode 100644
index 000000000..e9351671d
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/future/wait_until_pass.cpp
@@ -0,0 +1,175 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class future<R>
+
+// template <class Rep, class Period>
+// future_status
+// wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+
+//#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#include <boost/thread/detail/log.hpp>
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/chrono/chrono_io.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+namespace boost
+{
+ template <typename OStream>
+ OStream& operator<<(OStream& os , boost::future_status st )
+ {
+ os << underlying_cast<int>(st) << " ";
+ return os;
+ }
+ template <typename T>
+ struct wrap
+ {
+ wrap(T const& v) :
+ value(v)
+ {
+ }
+ T value;
+
+ };
+
+ template <typename T>
+ exception_ptr make_exception_ptr(T v)
+ {
+ return copy_exception(wrap<T> (v));
+ }
+}
+
+void func1(boost::promise<int> p)
+{
+ boost::this_thread::sleep_for(ms(500));
+ p.set_value(3);
+}
+
+int j = 0;
+
+void func3(boost::promise<int&> p)
+{
+ boost::this_thread::sleep_for(ms(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func5(boost::promise<void> p)
+{
+ boost::this_thread::sleep_for(ms(500));
+ p.set_value();
+}
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+int main()
+{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ typedef boost::chrono::high_resolution_clock Clock;
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func1, boost::move(p)).detach();
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(250)) , boost::future_status::timeout);
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#else
+ func1(boost::move(p));
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(750)) , boost::future_status::ready);
+ BOOST_TEST(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(f.valid());
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func3, boost::move(p)).detach();
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(250)) , boost::future_status::timeout);
+ BOOST_TEST(f.valid());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#else
+ func3(boost::move(p));
+#endif
+ BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(750)) , boost::future_status::ready);
+ BOOST_TEST(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(f.valid());
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func5, boost::move(p)).detach();
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(250)) , boost::future_status::timeout);
+ BOOST_TEST(f.valid());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#else
+ func5(boost::move(p));
+#endif
+ BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(750)) , boost::future_status::ready);
+ BOOST_TEST(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(f.valid());
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/sync/futures/make_ready_future_pass.cpp b/src/boost/libs/thread/test/sync/futures/make_ready_future_pass.cpp
new file mode 100644
index 000000000..dfce3cde7
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/make_ready_future_pass.cpp
@@ -0,0 +1,157 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011,2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// future<void> make_ready_future();
+// template <class T>
+// future<decay_t<T>> make_ready_future(T&&);
+// template <class T>
+// future<T> make_ready_future(remove_reference_t<T>&);
+// template <class T>
+// future<T> make_ready_future(remove_reference_t<T>&&);
+// template <class T, class ...Args>
+// future<T> make_ready_future(Args&& ... args);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+struct A
+{
+ A() :
+ value(0)
+ {
+ }
+ A(int i) :
+ value(i)
+ {
+ }
+ A(int i, int j) :
+ value(i+j)
+ {
+ }
+ int value;
+};
+
+A make(int i) {
+ return A(i);
+}
+A make(int i, int j) {
+ return A(i, j);
+}
+
+struct movable2
+{
+ int value_;
+ BOOST_THREAD_MOVABLE_ONLY(movable2)
+ movable2() : value_(1){}
+ movable2(int i) : value_(i){}
+ movable2(int i, int j) : value_(i+j){}
+
+ //Move constructor and assignment
+ movable2(BOOST_RV_REF(movable2) m)
+ { value_ = m.value_; m.value_ = 0; }
+
+ movable2 & operator=(BOOST_THREAD_RV_REF(movable2) m)
+ { value_ = m.value_; m.value_ = 0; return *this; }
+
+ bool moved() const //Observer
+ { return !value_; }
+
+ int value() const //Observer
+ { return value_; }
+};
+
+
+movable2 move_return_function2(int i) {
+ return movable2(i);
+}
+
+int main()
+{
+#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ BOOST_STATIC_ASSERT((boost::is_copy_constructible<movable2>::value == false));
+ BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<movable2>::value == true));
+ BOOST_STATIC_ASSERT((boost::is_copy_constructible<A>::value == true));
+ BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<A>::value == false));
+#endif
+
+ {
+ boost::future<void> f = boost::make_ready_future();
+ f.wait();
+ }
+ {
+ typedef A T;
+ T i;
+ boost::future<T> f = boost::make_ready_future(i);
+ BOOST_TEST(f.get().value==0);
+ }
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ {
+ typedef A T;
+ boost::future<T> f = boost::make_ready_future<T>();
+ BOOST_TEST(f.get().value==0);
+ }
+ {
+ typedef A T;
+ boost::future<T> f = boost::make_ready_future<T>(1);
+ BOOST_TEST(f.get().value==1);
+ }
+ {
+ typedef A T;
+ boost::future<T> f = boost::make_ready_future<T>(1,2);
+ BOOST_TEST(f.get().value==3);
+ }
+ {
+ typedef A T;
+ T i;
+ boost::future<T&> f = boost::make_ready_future<T&>(i);
+ BOOST_TEST(f.get().value==0);
+ }
+#endif
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+// sync/futures/make_ready_future_pass.cpp:125:65: erreur: conversion from Ôboost::future<boost::rv<movable2> >Õ to non-scalar type Ôboost::future<movable2>Õ requested
+ {
+ typedef movable2 T;
+ T i;
+ boost::future<T> f = boost::make_ready_future(boost::move(i));
+ BOOST_TEST_EQ(f.get().value(),1);
+ }
+#endif
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ {
+ typedef movable2 T;
+ boost::future<T> f = boost::make_ready_future<T>();
+ BOOST_TEST(f.get().value()==1);
+ }
+ {
+ typedef movable2 T;
+ boost::future<T> f = boost::make_ready_future<T>(1);
+ BOOST_TEST(f.get().value()==1);
+ }
+ {
+ typedef movable2 T;
+ boost::future<T> f = boost::make_ready_future<T>(1,2);
+ BOOST_TEST(f.get().value()==3);
+ }
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/alloc_ctor_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/alloc_ctor_pass.cpp
new file mode 100644
index 000000000..e83c06446
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/packaged_task/alloc_ctor_pass.cpp
@@ -0,0 +1,181 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class packaged_task<R>
+
+// template <class F, class Allocator>
+// explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
+
+
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#include "../test_allocator.hpp"
+
+double fct()
+{
+ return 5.0;
+}
+long lfct()
+{
+ return 5;
+}
+
+class A
+{
+ long data_;
+
+public:
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(A)
+ static int n_moves;
+ static int n_copies;
+ static int n_instances;
+ static int n_destroy;
+
+ explicit A(long i) : data_(i)
+ {
+ ++n_instances;
+ }
+ A(BOOST_THREAD_RV_REF(A) a) : data_(BOOST_THREAD_RV(a).data_)
+ {
+ ++n_instances;
+ ++n_moves; BOOST_THREAD_RV(a).data_ = -1;
+ }
+ A& operator=(BOOST_THREAD_RV_REF(A) a)
+ {
+ data_ = BOOST_THREAD_RV(a).data_;
+ BOOST_THREAD_RV(a).data_ = -1;
+ ++n_moves;
+ return *this;
+ }
+ A(const A& a) : data_(a.data_)
+ {
+ ++n_instances;
+ ++n_copies;
+ }
+ A& operator=(BOOST_THREAD_COPY_ASSIGN_REF(A) a)
+ {
+ data_ = a.data_;
+ ++n_copies;
+ return *this;
+ }
+ ~A()
+ {
+ --n_instances;
+ ++n_destroy;
+ }
+
+ long operator()() const
+ { return data_;}
+ long operator()(long i, long j) const
+ { return data_ + i + j;}
+};
+
+int A::n_moves = 0;
+int A::n_copies = 0;
+int A::n_instances = 0;
+int A::n_destroy = 0;
+
+int main()
+{
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(boost::allocator_arg,
+ test_allocator<A>(), BOOST_THREAD_MAKE_RV_REF(A(5)));
+ BOOST_TEST(test_alloc_base::count > 0);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ BOOST_TEST(A::n_copies == 0);
+ BOOST_TEST(A::n_moves > 0);
+ BOOST_TEST(A::n_instances == 0);
+ BOOST_TEST(A::n_destroy > 0);
+ BOOST_TEST(test_alloc_base::count == 0);
+ A::n_copies = 0;
+ A::n_moves = 0;
+ {
+ A a(5);
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(boost::allocator_arg,
+ test_allocator<A>(), a);
+ BOOST_TEST(test_alloc_base::count > 0);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ //BOOST_TEST(A::n_copies > 0);
+ //BOOST_TEST(A::n_moves > 0);
+ BOOST_TEST(test_alloc_base::count == 0);
+ A::n_copies = 0;
+ A::n_moves = 0;
+ {
+ const A a(5);
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(boost::allocator_arg,
+ test_allocator<A>(), a);
+ BOOST_TEST(test_alloc_base::count > 0);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ //BOOST_TEST(A::n_copies > 0);
+ //BOOST_TEST(A::n_moves > 0);
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(boost::allocator_arg,
+ test_allocator<A>(), fct);
+ BOOST_TEST(test_alloc_base::count > 0);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(boost::allocator_arg,
+ test_allocator<A>(), &lfct);
+ BOOST_TEST(test_alloc_base::count > 0);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+
+ return boost::report_errors();
+}
+
+#else
+int main()
+{
+ return boost::report_errors();
+}
+#endif
+
diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/copy_assign_fail.cpp
new file mode 100644
index 000000000..7f068eced
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/packaged_task/copy_assign_fail.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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class packaged_task<R>
+
+// packaged_task& operator=(packaged_task&) = delete;
+
+
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()() const {return data_;}
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+
+int main()
+{
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0(A(5));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
+ p = p0;
+ }
+
+ return boost::report_errors();
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/copy_ctor_fail.cpp
new file mode 100644
index 000000000..22a174961
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/packaged_task/copy_ctor_fail.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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class packaged_task<R>
+
+// packaged_task(packaged_task&) = delete;
+
+
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()() const {return data_;}
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+
+int main()
+{
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0(A(5));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(p0);
+
+ }
+
+ return boost::report_errors();
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/default_ctor_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/default_ctor_pass.cpp
new file mode 100644
index 000000000..7ab9f1e7c
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/packaged_task/default_ctor_pass.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class packaged_task<R>
+
+// packaged_task();
+
+
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE int()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE int
+#endif
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <string>
+
+int main()
+{
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
+ BOOST_TEST(!p.valid());
+
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/dtor_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/dtor_pass.cpp
new file mode 100644
index 000000000..89620ad05
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/packaged_task/dtor_pass.cpp
@@ -0,0 +1,108 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class packaged_task<R>
+
+// ~packaged_task();
+
+//#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#define BOOST_THREAD_DETAIL_SIGNATURE_2 double(int, char)
+#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5 + 3 +'a'
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE_2 double()
+#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5
+#endif
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE_2 double
+#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5
+#endif
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()() const {return data_;}
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+void func(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> )
+{
+}
+
+void func2(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p)
+{
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ p(3, 'a');
+#else
+ p();
+#endif
+}
+
+int main()
+{
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(A(5));
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func, boost::move(p)).detach();
+#else
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE>* p2=new boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE>(boost::move(p));
+ delete p2;
+#endif
+ try
+ {
+ f.get();
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::broken_promise));
+ }
+ }
+ {
+ std::cout << __LINE__ << std::endl;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(A(5));
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func2, boost::move(p)).detach();
+#else
+ p();
+#endif
+ std::cout << __LINE__ << std::endl;
+ BOOST_TEST(f.get() == BOOST_THREAD_DETAIL_SIGNATURE_2_RES);
+ std::cout << __LINE__ << std::endl;
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp
new file mode 100644
index 000000000..a4bd3105f
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp
@@ -0,0 +1,378 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class packaged_task<R>
+
+// template <class F>
+// explicit packaged_task(F&& f);
+
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#define BOOST_THREAD_DETAIL_VOID_SIGNATURE void()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#define BOOST_THREAD_DETAIL_VOID_SIGNATURE void
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#define BOOST_THREAD_DETAIL_SIGNATURE_2 double(int, char)
+#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5 + 3 +'a'
+#define BOOST_THREAD_DETAIL_VOID_SIGNATURE_2 void(int)
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE_2 double()
+#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5
+#define BOOST_THREAD_DETAIL_VOID_SIGNATURE_2 void()
+#endif
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE_2 double
+#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5
+#define BOOST_THREAD_DETAIL_VOID_SIGNATURE_2 void
+#endif
+
+void void_fct()
+{
+ return;
+}
+double fct()
+{
+ return 5.0;
+}
+long lfct()
+{
+ return 5;
+}
+
+class A
+{
+public:
+ long data_;
+
+ static int n_moves;
+ static int n_copies;
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(A)
+ static void reset()
+ {
+ n_moves=0;
+ n_copies=0;
+ }
+
+ explicit A(long i) : data_(i)
+ {
+ }
+ A(BOOST_THREAD_RV_REF(A) a) : data_(BOOST_THREAD_RV(a).data_)
+ {
+ BOOST_THREAD_RV(a).data_ = -1;
+ ++n_moves;
+ }
+ A& operator=(BOOST_THREAD_RV_REF(A) a)
+ {
+ data_ = BOOST_THREAD_RV(a).data_;
+ BOOST_THREAD_RV(a).data_ = -1;
+ ++n_moves;
+ return *this;
+ }
+ A(const A& a) : data_(a.data_)
+ {
+ ++n_copies;
+ }
+ A& operator=(BOOST_THREAD_COPY_ASSIGN_REF(A) a)
+ {
+ data_ = a.data_;
+ ++n_copies;
+ return *this;
+ }
+ ~A()
+ {
+ }
+
+ void operator()(int) const
+ { }
+ long operator()() const
+ { return data_;}
+ long operator()(long i, long j) const
+ { return data_ + i + j;}
+};
+
+int A::n_moves = 0;
+int A::n_copies = 0;
+
+class M
+{
+
+public:
+ long data_;
+ static int n_moves;
+
+ BOOST_THREAD_MOVABLE_ONLY(M)
+ static void reset() {
+ n_moves=0;
+ }
+ explicit M(long i) : data_(i)
+ {
+ }
+ M(BOOST_THREAD_RV_REF(M) a) : data_(BOOST_THREAD_RV(a).data_)
+ {
+ BOOST_THREAD_RV(a).data_ = -1;
+ ++n_moves;
+ }
+ M& operator=(BOOST_THREAD_RV_REF(M) a)
+ {
+ data_ = BOOST_THREAD_RV(a).data_;
+ BOOST_THREAD_RV(a).data_ = -1;
+ ++n_moves;
+ return *this;
+ }
+ ~M()
+ {
+ }
+
+ void operator()(int) const
+ { }
+ long operator()() const
+ { return data_;}
+ long operator()(long i, long j) const
+ { return data_ + i + j;}
+};
+
+int M::n_moves = 0;
+
+class C
+{
+public:
+ long data_;
+
+ static int n_copies;
+ static void reset()
+ {
+ n_copies=0;
+ }
+
+ explicit C(long i) : data_(i)
+ {
+ }
+ C(const C& a) : data_(a.data_)
+ {
+ ++n_copies;
+ }
+ C& operator=(C const& a)
+ {
+ data_ = a.data_;
+ ++n_copies;
+ return *this;
+ }
+ ~C()
+ {
+ }
+
+ void operator()(int) const
+ { }
+ long operator()() const
+ { return data_;}
+ long operator()(long i, long j) const
+ { return data_ + i + j;}
+};
+int C::n_copies = 0;
+
+int main()
+{
+ {
+ A::reset();
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(BOOST_THREAD_MAKE_RV_REF(A(5)));
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ p(3, 'a');
+#else
+ p();
+#endif
+ BOOST_TEST(f.get() == BOOST_THREAD_DETAIL_SIGNATURE_2_RES);
+ BOOST_TEST(A::n_copies == 0);
+ BOOST_TEST_EQ(A::n_moves, 1);
+ }
+ {
+ A::reset();
+ A a(5);
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(a);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ BOOST_TEST_EQ(A::n_copies, 1);
+ BOOST_TEST_EQ(A::n_moves, 0);
+ }
+ {
+ A::reset();
+ const A a(5);
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(a);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ BOOST_TEST_EQ(A::n_copies, 1);
+ BOOST_TEST_EQ(A::n_moves, 0);
+ }
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ {
+ A::reset();
+ boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(BOOST_THREAD_MAKE_RV_REF(A(5)));
+ BOOST_TEST(p.valid());
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ p(1);
+ BOOST_TEST(A::n_copies == 0);
+ BOOST_TEST_EQ(A::n_moves, 1);
+ }
+ {
+ A::reset();
+ A a(5);
+ boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(a);
+ BOOST_TEST(p.valid());
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ p(1);
+ BOOST_TEST_EQ(A::n_copies, 1);
+ BOOST_TEST_EQ(A::n_moves, 0);
+ }
+ {
+ A::reset();
+ const A a(5);
+ boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(a);
+ BOOST_TEST(p.valid());
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ p(1);
+ BOOST_TEST_EQ(A::n_copies, 1);
+ BOOST_TEST_EQ(A::n_moves, 0);
+ }
+#endif
+ {
+ M::reset();
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(BOOST_THREAD_MAKE_RV_REF(M(5)));
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ p(3, 'a');
+#else
+ p();
+#endif
+ BOOST_TEST(f.get() == BOOST_THREAD_DETAIL_SIGNATURE_2_RES);
+ BOOST_TEST_EQ(M::n_moves, 1);
+ }
+ {
+ M::reset();
+ M a(5);
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(boost::move(a));
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ BOOST_TEST_EQ(M::n_moves, 1);
+ }
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ {
+ M::reset();
+ boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(BOOST_THREAD_MAKE_RV_REF(M(5)));
+ BOOST_TEST(p.valid());
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ p(1);
+ BOOST_TEST_EQ(M::n_moves, 1);
+ }
+ {
+ M::reset();
+ M a(5);
+ boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(boost::move(a));
+ BOOST_TEST(p.valid());
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ p(1);
+ BOOST_TEST_EQ(M::n_moves, 1);
+ }
+#endif
+ {
+ C::reset();
+ C a(5);
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(a);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ BOOST_TEST_EQ(C::n_copies, 1);
+ }
+
+ {
+ C::reset();
+ const C a(5);
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(a);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ BOOST_TEST_EQ(C::n_copies, 1);
+ }
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ {
+ C::reset();
+ C a(5);
+ boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(a);
+ BOOST_TEST(p.valid());
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ p(1);
+ BOOST_TEST_EQ(C::n_copies, 1);
+ }
+
+ {
+ C::reset();
+ const C a(5);
+ boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(a);
+ BOOST_TEST(p.valid());
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ p(1);
+ BOOST_TEST_EQ(C::n_copies, 1);
+ }
+#endif
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE> p(void_fct);
+ BOOST_TEST(p.valid());
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ p();
+ }
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(fct);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(&lfct);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/get_future_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/get_future_pass.cpp
new file mode 100644
index 000000000..7b2985794
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/packaged_task/get_future_pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class packaged_task<R>
+
+// future<R> get_future();
+
+
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()() const {return data_;}
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int main()
+{
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(A(5));
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(A(5));
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::future_already_retrieved));
+ }
+ }
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
+ try
+ {
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/make_ready_at_thread_exit_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/make_ready_at_thread_exit_pass.cpp
new file mode 100644
index 000000000..08db7bbf2
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/packaged_task/make_ready_at_thread_exit_pass.cpp
@@ -0,0 +1,189 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class packaged_task<R>
+
+// packaged_task(packaged_task&& other);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO && \
+ defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && \
+ defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+
+class E : public std::exception
+{
+public:
+ long data;
+ explicit E(long i) :
+ data(i)
+ {
+ }
+
+ const char* what() const throw() { return ""; }
+
+ ~E() throw() {}
+};
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) :
+ data_(i)
+ {
+ }
+
+ long operator()(long i, long j) const
+ {
+ if (j == 'z') BOOST_THROW_EXCEPTION( E(6) );
+ return data_ + i + j;
+ }
+};
+
+void func0_mv(BOOST_THREAD_RV_REF(boost::packaged_task<double(int, char)>) p)
+//void func0(boost::packaged_task<double(int, char)> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.make_ready_at_thread_exit(3, 'a');
+}
+void func0(boost::packaged_task<double(int, char)> *p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p->make_ready_at_thread_exit(3, 'a');
+}
+void func1(boost::packaged_task<double(int, char)> *p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p->make_ready_at_thread_exit(3, 'z');
+}
+
+void func2(boost::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 boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+}
+
+void func3(boost::packaged_task<double(int, char)> *p)
+{
+ try
+ {
+ p->make_ready_at_thread_exit(3, 'a');
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+}
+
+int main()
+{
+ {
+ boost::packaged_task<double(int, char)> p(A(5));
+ boost::future<double> f = p.get_future();
+#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD
+ boost::thread(func0_mv, boost::move(p)).detach();
+#else
+ boost::thread(func0, &p).detach();
+#endif
+ BOOST_TEST(f.get() == 105.0);
+ }
+ {
+ boost::packaged_task<double(int, char)> p2(A(5));
+ boost::future<double> f = p2.get_future();
+ boost::packaged_task<double(int, char)> p = boost::move(p2);
+ boost::thread(func0, &p).detach();
+ BOOST_TEST(f.get() == 105.0);
+ }
+ {
+ boost::packaged_task<double(int, char)> p(A(5));
+ boost::future<double> f = p.get_future();
+ //boost::thread(func1, boost::move(p)).detach();
+ boost::thread(func1, &p).detach();
+ try
+ {
+ f.get();
+ BOOST_TEST(false);
+ }
+ catch (const E& e)
+ {
+ BOOST_TEST(e.data == 6);
+ }
+ }
+ {
+ boost::packaged_task<double(int, char)> p2(A(5));
+ boost::future<double> f = p2.get_future();
+ boost::packaged_task<double(int, char)> p = boost::move(p2);
+ boost::thread(func1, &p).detach();
+ try
+ {
+ f.get();
+ BOOST_TEST(false);
+ }
+ catch (const E& e)
+ {
+ BOOST_TEST(e.data == 6);
+ }
+ }
+ {
+ boost::packaged_task<double(int, char)> p(A(5));
+ boost::future<double> f = p.get_future();
+ //boost::thread(func2, boost::move(p)).detach();
+ boost::thread(func2, &p).detach();
+ BOOST_TEST(f.get() == 105.0);
+ }
+ {
+ boost::packaged_task<double(int, char)> p2(A(5));
+ boost::future<double> f = p2.get_future();
+ boost::packaged_task<double(int, char)> p = boost::move(p2);
+ boost::thread(func2, &p).detach();
+ BOOST_TEST(f.get() == 105.0);
+ }
+ {
+ boost::packaged_task<double(int, char)> p(A(5));
+ //boost::thread t(func3, boost::move(p));
+ boost::thread t(func3, &p);
+ t.join();
+ }
+ {
+ boost::packaged_task<double(int, char)> p2(A(5));
+ boost::packaged_task<double(int, char)> p = boost::move(p2);
+ boost::thread t(func3, &p);
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+int main()
+{
+ return boost::report_errors();
+}
+//#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
+
diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/member_swap_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/member_swap_pass.cpp
new file mode 100644
index 000000000..fe3c062f8
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/packaged_task/member_swap_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class packaged_task<R>
+
+// void swap(packaged_task& other);
+
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) :
+ data_(i)
+ {
+ }
+
+ long operator()() const
+ {
+ return data_;
+ }
+ long operator()(long i, long j) const
+ {
+ return data_ + i + j;
+ }
+};
+
+int main()
+{
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0(A(5));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
+ p.swap(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
+ p.swap(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(!p.valid());
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/move_assign_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/move_assign_pass.cpp
new file mode 100644
index 000000000..fe696c8fb
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/packaged_task/move_assign_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <future>
+
+// class promise<R>
+
+// promise& operator=(promise&& rhs);
+
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()() const {return data_;}
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+
+int main()
+{
+
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0(A(5));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
+ p = boost::move(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ // p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
+ p = boost::move(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(!p.valid());
+ }
+
+ return boost::report_errors();
+
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/move_ctor_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/move_ctor_pass.cpp
new file mode 100644
index 000000000..a5085b311
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/packaged_task/move_ctor_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class packaged_task<R>
+
+// packaged_task(packaged_task&& other);
+
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()() const {return data_;}
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+
+int main()
+{
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0(A(5));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p = boost::move(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p = boost::move(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(!p.valid());
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/non_member_swap_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/non_member_swap_pass.cpp
new file mode 100644
index 000000000..fb579094d
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/packaged_task/non_member_swap_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// template <class R>
+// void
+// swap(packaged_task<R>& x, packaged_task<R>& y);
+
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()() const {return data_;}
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int main()
+{
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0(A(5));
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
+ p.swap(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0;
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
+ p.swap(p0);
+ BOOST_TEST(!p0.valid());
+ BOOST_TEST(!p.valid());
+ }
+ return boost::report_errors();
+
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/operator_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/operator_pass.cpp
new file mode 100644
index 000000000..db932f72b
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/packaged_task/operator_pass.cpp
@@ -0,0 +1,218 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class packaged_task<R>
+
+// void operator()();
+
+
+//#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#define BOOST_THREAD_DETAIL_SIGNATURE_2 double(int, char)
+#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5 + 3 +'a'
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE_2 double()
+#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5
+#endif
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE_2 double
+#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5
+#endif
+class E : public std::exception
+{
+public:
+ long data;
+ explicit E(long i) :
+ data(i)
+ {
+ }
+
+ const char* what() const throw() { return ""; }
+
+ ~E() throw() {}
+};
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) :
+ data_(i)
+ {
+ }
+
+ long operator()() const
+ {
+ if (data_ == 0) BOOST_THROW_EXCEPTION(E(6));
+ return data_;
+ }
+ long operator()(long i, long j) const
+ {
+ if (j == 'z') BOOST_THROW_EXCEPTION(E(6));
+ return data_ + i + j;
+ }
+ ~A() {}
+};
+
+void func0(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ p(3, 'a');
+#else
+ p();
+#endif
+}
+
+void func1(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ p(3, 'z');
+#else
+ p();
+#endif
+}
+
+void func2(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p)
+{
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ p(3, 'a');
+#else
+ p();
+#endif
+ try
+ {
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ p(3, 'c');
+#else
+ p();
+#endif
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+}
+
+void func3(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p)
+{
+ try
+ {
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ p(3, 'a');
+#else
+ p();
+#endif
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+}
+
+int main()
+{
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(A(5));
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func0, boost::move(p)).detach();
+#else
+ //p();
+#endif
+ //BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(A(0));
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func1, boost::move(p)).detach();
+#endif
+ try
+ {
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#else
+ p();
+#endif
+ f.get();
+ BOOST_TEST(false);
+ }
+ catch (const E& e)
+ {
+ BOOST_TEST(e.data == 6);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(A(5));
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread t(func2, boost::move(p));
+#else
+ p();
+#endif
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ BOOST_TEST(f.get() == 105);
+ t.join();
+#else
+ BOOST_TEST(f.get() == 5.0);
+#endif
+ }
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p;
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread t(func3, boost::move(p));
+ t.join();
+#else
+ try
+ {
+ #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ p(3, 'a');
+ #else
+ p();
+ #endif
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+#endif
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/reset_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/reset_pass.cpp
new file mode 100644
index 000000000..711e7a57f
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/packaged_task/reset_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class packaged_task<R>
+
+// void operator()();
+
+
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) :
+ data_(i)
+ {
+ }
+
+ long operator()() const
+ {
+ return data_;
+ }
+ long operator()(long i, long j) const
+ {
+ if (j == 'z') throw A(6);
+ return data_ + i + j;
+ }
+};
+
+int main()
+{
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(A(5));
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ p.reset();
+ //p(4, 'a');
+ p();
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.get() == 5.0);
+ }
+ {
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p;
+ try
+ {
+ p.reset();
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/types_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/types_pass.cpp
new file mode 100644
index 000000000..a52fb0439
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/packaged_task/types_pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// template<class R, class... ArgTypes>
+// class packaged_task<R(ArgTypes...)>
+// {
+// public:
+// typedef R result_type;
+
+
+#include <boost/thread/future.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct A {};
+
+int main()
+{
+ //BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::packaged_task<A>::result_type, A>::value), "");
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/use_allocator_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/use_allocator_pass.cpp
new file mode 100644
index 000000000..ef75b7caa
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/packaged_task/use_allocator_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class packaged_task<R(ArgTypes...)>
+
+// template <class Callable, class Alloc>
+// struct uses_allocator<packaged_task<Callable>, Alloc>
+// : true_type { };
+
+
+#define BOOST_THREAD_VERSION 4
+#if BOOST_THREAD_VERSION == 4
+#define BOOST_THREAD_DETAIL_SIGNATURE double()
+#else
+#define BOOST_THREAD_DETAIL_SIGNATURE double
+#endif
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#include "../test_allocator.hpp"
+
+int main()
+{
+
+ BOOST_STATIC_ASSERT_MSG((boost::csbl::uses_allocator<boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE>, test_allocator<double> >::value), "");
+
+ return boost::report_errors();
+}
+
+#else
+int main()
+{
+ return boost::report_errors();
+}
+#endif
+
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/alloc_ctor_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/alloc_ctor_pass.cpp
new file mode 100644
index 000000000..0d0c3c0b9
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/promise/alloc_ctor_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// promise(allocator_arg_t, const Allocator& a);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#include "../test_allocator.hpp"
+
+int main()
+{
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ boost::promise<int> p(boost::allocator_arg, test_allocator<int>());
+ BOOST_TEST(test_alloc_base::count == 1);
+ boost::future<int> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ boost::promise<int&> p(boost::allocator_arg, test_allocator<int>());
+ BOOST_TEST(test_alloc_base::count == 1);
+ boost::future<int&> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ boost::promise<void> p(boost::allocator_arg, test_allocator<void>());
+ BOOST_TEST(test_alloc_base::count == 1);
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+
+
+ return boost::report_errors();
+}
+
+#else
+int main()
+{
+ return boost::report_errors();
+}
+#endif
+
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/futures/promise/copy_assign_fail.cpp
new file mode 100644
index 000000000..07895578f
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/promise/copy_assign_fail.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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class promise<R>
+// promise& operator=(const promise& rhs) = delete;
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ boost::promise<int> p0;
+ boost::promise<int> p;
+ p = p0;
+ }
+
+ return boost::report_errors();
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/futures/promise/copy_ctor_fail.cpp
new file mode 100644
index 000000000..cfd67a6d7
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/promise/copy_ctor_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class promise<R>
+// promise& operator=(const promise& rhs) = delete;
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ boost::promise<int> p0;
+ boost::promise<int> p(p0);
+ }
+
+ return boost::report_errors();
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/default_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/default_pass.cpp
new file mode 100644
index 000000000..00198a168
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/promise/default_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// promise();
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ boost::promise<int> p;
+ boost::future<int> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ }
+ {
+ boost::promise<int&> p;
+ boost::future<int&> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ }
+ {
+ boost::promise<void> p;
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/dtor_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/dtor_pass.cpp
new file mode 100644
index 000000000..e449c0378
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// ~promise();
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ typedef int T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ p.set_value(3);
+ }
+ BOOST_TEST(f.get() == 3);
+ }
+ {
+ typedef int T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ }
+ try
+ {
+ //T i =
+ (void)f.get();
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::broken_promise));
+ }
+ }
+ {
+ typedef int& T;
+ int i = 4;
+ boost::future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ p.set_value(i);
+ }
+ BOOST_TEST(&f.get() == &i);
+ }
+ {
+ typedef int& T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ }
+ try
+ {
+ //T i =
+ (void)f.get();
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::broken_promise));
+ }
+ }
+ {
+ typedef void T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ p.set_value();
+ }
+ f.get();
+ BOOST_TEST(true);
+ }
+ {
+ typedef void T;
+ boost::future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ }
+ try
+ {
+ f.get();
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::broken_promise));
+ }
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/emplace_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/emplace_pass.cpp
new file mode 100644
index 000000000..6a1a35292
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/promise/emplace_pass.cpp
@@ -0,0 +1,207 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011,2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// template <class ...Args>
+// void promise::emplace(Args&& ... args);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+struct A
+{
+ A() :
+ value(0)
+ {
+ }
+ A(int i) :
+ value(i)
+ {
+ }
+ A(int i, int j) :
+ value(i+j)
+ {
+ }
+ BOOST_THREAD_MOVABLE_ONLY(A)
+
+ A(BOOST_THREAD_RV_REF(A) rhs)
+ {
+ if(rhs.value==0)
+ throw 9;
+ else
+ {
+ value=rhs.value;
+ rhs.value=0;
+ }
+ }
+ A& operator=(BOOST_THREAD_RV_REF(A) rhs)
+ {
+ if(rhs.value==0)
+ throw 9;
+ else
+ {
+ value=rhs.value;
+ rhs.value=0;
+ }
+ return *this;
+ }
+ int value;
+};
+
+A make(int i) {
+ return A(i);
+}
+A make(int i, int j) {
+ return A(i, j);
+}
+
+struct movable2
+{
+ int value_;
+ BOOST_THREAD_MOVABLE_ONLY(movable2)
+ movable2() : value_(1){}
+ movable2(int i) : value_(i){}
+ movable2(int i, int j) : value_(i+j){}
+
+ //Move constructor and assignment
+ movable2(BOOST_RV_REF(movable2) m)
+ { value_ = m.value_; m.value_ = 0; }
+
+ movable2 & operator=(BOOST_THREAD_RV_REF(movable2) m)
+ { value_ = m.value_; m.value_ = 0; return *this; }
+
+ bool moved() const //Observer
+ { return !value_; }
+
+ int value() const //Observer
+ { return value_; }
+};
+
+
+movable2 move_return_function2(int i) {
+ return movable2(i);
+}
+
+int main()
+{
+#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ BOOST_STATIC_ASSERT((boost::is_copy_constructible<movable2>::value == false));
+ BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<movable2>::value == true));
+ BOOST_STATIC_ASSERT((boost::is_copy_constructible<A>::value == false));
+ BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<A>::value == true));
+#endif
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+ {
+ typedef A T;
+ T i;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.emplace();
+ try
+ {
+ T a = f.get(); (void)a;
+ BOOST_TEST(false);
+ }
+ catch (int j)
+ {
+ BOOST_TEST(j == 9);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ {
+ typedef A T;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.emplace(3);
+ BOOST_TEST(f.get().value == 3);
+ try
+ {
+ T j(3);
+ p.set_value(boost::move(j));
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+
+ }
+ {
+ boost::promise<movable2> p;
+ boost::future<movable2> f = p.get_future();
+ p.emplace(3);
+ BOOST_TEST(f.get().value_ == 3);
+ try
+ {
+ p.emplace(3);
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+
+ }
+ {
+ boost::promise<A> p;
+ boost::future<A> f = p.get_future();
+ p.emplace(1,2);
+ BOOST_TEST(f.get().value == 3);
+ try
+ {
+ p.emplace(1,2);
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+
+ }
+ {
+ typedef A T;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.emplace(3);
+ boost::promise<T> p2(boost::move(p));
+ BOOST_TEST(f.get().value == 3);
+
+ }
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/get_future_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/get_future_pass.cpp
new file mode 100644
index 000000000..13a63b13d
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/promise/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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// future<R> get_future();
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ boost::promise<double> p;
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ p.set_value(105.5);
+ BOOST_TEST(f.get() == 105.5);
+ }
+ {
+ boost::promise<double> p;
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::future_already_retrieved));
+ }
+ }
+ {
+ boost::promise<double> p;
+ boost::promise<double> p0 = boost::move(p);
+ try
+ {
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ }
+
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/move_assign_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/move_assign_pass.cpp
new file mode 100644
index 000000000..0190527c0
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/promise/move_assign_pass.cpp
@@ -0,0 +1,155 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <future>
+
+// class promise<R>
+
+// promise& operator=(promise&& rhs);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#include "../test_allocator.hpp"
+#endif
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ boost::promise<int> p0(boost::allocator_arg, test_allocator<int>());
+ boost::promise<int> p(boost::allocator_arg, test_allocator<int>());
+ BOOST_TEST(test_alloc_base::count == 2);
+ p = boost::move(p0);
+ BOOST_TEST(test_alloc_base::count == 1);
+ boost::future<int> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+
+ {
+ boost::promise<int&> p0(boost::allocator_arg, test_allocator<int>());
+ boost::promise<int&> p(boost::allocator_arg, test_allocator<int>());
+ BOOST_TEST(test_alloc_base::count == 2);
+ p = boost::move(p0);
+ BOOST_TEST(test_alloc_base::count == 1);
+ boost::future<int&> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ boost::promise<void> p0(boost::allocator_arg, test_allocator<void>());
+ boost::promise<void> p(boost::allocator_arg, test_allocator<void>());
+ BOOST_TEST(test_alloc_base::count == 2);
+ p = boost::move(p0);
+ BOOST_TEST(test_alloc_base::count == 1);
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+
+#endif
+ {
+ boost::promise<int> p0;
+ boost::promise<int> p;
+ p = boost::move(p0);
+ boost::future<int> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ }
+
+ {
+ boost::promise<int&> p0;
+ boost::promise<int&> p;
+ p = boost::move(p0);
+ boost::future<int&> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ }
+ {
+ boost::promise<void> p0;
+ boost::promise<void> p;
+ p = boost::move(p0);
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ }
+
+ return boost::report_errors();
+
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/move_ctor_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/move_ctor_pass.cpp
new file mode 100644
index 000000000..a72eb1829
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/promise/move_ctor_pass.cpp
@@ -0,0 +1,151 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <future>
+
+// class promise<R>
+
+// promise(promise&& rhs);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#include "../test_allocator.hpp"
+#endif
+
+boost::mutex m;
+
+int main()
+{
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ boost::promise<int> p0(boost::allocator_arg, test_allocator<int>());
+ boost::promise<int> p(boost::move(p0));
+ BOOST_TEST(test_alloc_base::count == 1);
+ std::cout << __LINE__ << std::endl;
+ boost::future<int> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ std::cout << __LINE__ << std::endl;
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ std::cout << __LINE__ << std::endl;
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ std::cout << __LINE__ << std::endl;
+ BOOST_TEST(test_alloc_base::count == 1);
+ }
+ std::cout << __LINE__ << std::endl;
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ boost::promise<int&> p0(boost::allocator_arg, test_allocator<int>());
+ boost::promise<int&> p(boost::move(p0));
+ BOOST_TEST(test_alloc_base::count == 1);
+ boost::future<int&> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ boost::promise<void> p0(boost::allocator_arg, test_allocator<void>());
+ boost::promise<void> p(boost::move(p0));
+ BOOST_TEST(test_alloc_base::count == 1);
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+#endif
+ {
+ boost::promise<int> p0;
+ boost::promise<int> p(boost::move(p0));
+ std::cout << __LINE__ << std::endl;
+ boost::future<int> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ std::cout << __LINE__ << std::endl;
+ BOOST_TEST(f.valid());
+ std::cout << __LINE__ << std::endl;
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ std::cout << __LINE__ << std::endl;
+ }
+ std::cout << __LINE__ << std::endl;
+ {
+ boost::promise<int&> p0;
+ boost::promise<int&> p(boost::move(p0));
+ boost::future<int&> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ }
+ {
+ boost::promise<void> p0;
+ boost::promise<void> p(boost::move(p0));
+ boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ try
+ {
+ f = BOOST_THREAD_MAKE_RV_REF(p0.get_future());
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
+ }
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_exception_at_thread_exit_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_exception_at_thread_exit_pass.cpp
new file mode 100644
index 000000000..d23d0befb
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/promise/set_exception_at_thread_exit_pass.cpp
@@ -0,0 +1,110 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// void promise::set_exception_at_thread_exit(exception_ptr p);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+namespace boost
+{
+ template <typename T>
+ struct wrap
+ {
+ wrap(T const& v) :
+ value(v)
+ {
+ }
+ T value;
+
+ };
+
+ template <typename T>
+ exception_ptr make_exception_ptr(T v)
+ {
+ return copy_exception(wrap<T> (v));
+ }
+}
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+void func(boost::promise<int> p)
+#else
+boost::promise<int> p;
+void func()
+#endif
+{
+ //p.set_exception(boost::make_exception_ptr(3));
+ p.set_exception_at_thread_exit(boost::make_exception_ptr(3));
+}
+
+int main()
+{
+ {
+ typedef int T;
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ boost::thread(func, boost::move(p)).detach();
+#else
+ boost::future<T> f = p.get_future();
+ boost::thread(func).detach();
+#endif
+ try
+ {
+ f.get();
+ BOOST_TEST(false);
+ }
+ catch (boost::wrap<int> i)
+ {
+ BOOST_TEST(i.value == 3);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ {
+ typedef int T;
+ boost::promise<T> p2;
+ boost::future<T> f = p2.get_future();
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func, boost::move(p2)).detach();
+#else
+ p = boost::move(p2);
+ boost::thread(func).detach();
+#endif
+ try
+ {
+ f.get();
+ BOOST_TEST(false);
+ }
+ catch (boost::wrap<int> i)
+ {
+ BOOST_TEST(i.value == 3);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_exception_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_exception_pass.cpp
new file mode 100644
index 000000000..c27aec293
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/promise/set_exception_pass.cpp
@@ -0,0 +1,110 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// void set_exception(exception_ptr p);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+namespace boost
+{
+ template <typename T>
+ struct wrap
+ {
+ wrap(T const& v) :
+ value(v)
+ {
+ }
+ T value;
+
+ };
+
+ template <typename T>
+ exception_ptr make_exception_ptr(T v)
+ {
+ return copy_exception(wrap<T> (v));
+ }
+}
+
+int main()
+{
+
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_exception(boost::make_exception_ptr(3));
+ try
+ {
+ f.get();
+ BOOST_TEST(false);
+ }
+ catch (boost::wrap<int> i)
+ {
+ BOOST_TEST(i.value == 3);
+ }
+ try
+ {
+ p.set_exception(boost::make_exception_ptr(3));
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_exception_deferred(boost::make_exception_ptr(3));
+ BOOST_TEST(!f.is_ready());
+ p.notify_deferred();
+ try
+ {
+ f.get();
+ BOOST_TEST(false);
+ }
+ catch (boost::wrap<int> i)
+ {
+ BOOST_TEST(i.value == 3);
+ }
+ try
+ {
+ p.set_exception(boost::make_exception_ptr(3));
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_lvalue_at_thread_exit_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_lvalue_at_thread_exit_pass.cpp
new file mode 100644
index 000000000..a143dc636
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/promise/set_lvalue_at_thread_exit_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// void promise<R&>::set_value_at_thread_exit(R& r);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <memory>
+
+int i = 0;
+
+//void func(boost::promise<int&> p)
+boost::promise<int&> p;
+void func()
+{
+ p.set_value_at_thread_exit(i);
+ i = 4;
+}
+
+int main()
+{
+ {
+ //boost::promise<int&> p;
+ boost::future<int&> f = p.get_future();
+ //boost::thread(func, boost::move(p)).detach();
+ boost::thread(func).detach();
+ int r = f.get();
+ BOOST_TEST(r == 4);
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_lvalue_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_lvalue_pass.cpp
new file mode 100644
index 000000000..6acfb62d1
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/promise/set_lvalue_pass.cpp
@@ -0,0 +1,132 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// void promise<R&>::set_value(R& r);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+int main()
+{
+
+ {
+ typedef int& T;
+ int i = 3;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_value(i);
+ int& j = f.get();
+ BOOST_TEST(j == 3);
+ ++i;
+ BOOST_TEST(j == 4);
+ try
+ {
+ p.set_value(i);
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ {
+ typedef int& T;
+ int i = 3;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_value(i);
+ int& j = f.get();
+ BOOST_TEST(j == 3);
+ ++i;
+ BOOST_TEST(j == 4);
+ try
+ {
+ p.set_value_deferred(i);
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ {
+ typedef int& T;
+ int i = 3;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_value_deferred(i);
+ BOOST_TEST(!f.is_ready());
+ p.notify_deferred();
+ int& j = f.get();
+ BOOST_TEST(j == 3);
+ ++i;
+ BOOST_TEST(j == 4);
+ try
+ {
+ p.set_value_deferred(i);
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ {
+ typedef int& T;
+ int i = 3;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_value_deferred(i);
+ BOOST_TEST(!f.is_ready());
+ p.notify_deferred();
+ int& j = f.get();
+ BOOST_TEST(j == 3);
+ ++i;
+ BOOST_TEST(j == 4);
+ try
+ {
+ p.set_value(i);
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_rvalue_at_thread_exit_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_rvalue_at_thread_exit_pass.cpp
new file mode 100644
index 000000000..0b23b4834
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/promise/set_rvalue_at_thread_exit_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011,2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// void promise::set_value_at_thread_exit(R&& p);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/thread/detail/memory.hpp>
+#include <boost/thread/csbl/memory/unique_ptr.hpp>
+
+boost::promise<boost::csbl::unique_ptr<int> > p;
+boost::promise<boost::csbl::unique_ptr<int> > p2;
+void func()
+{
+ boost::csbl::unique_ptr<int> uptr(new int(5));
+ p.set_value_at_thread_exit(boost::move(uptr));
+}
+void func2()
+{
+ p2.set_value_at_thread_exit(boost::csbl::make_unique<int>(5));
+}
+
+int main()
+{
+ {
+ boost::future<boost::csbl::unique_ptr<int> > f = p.get_future();
+ boost::thread(func).detach();
+ BOOST_TEST(*f.get() == 5);
+ }
+ {
+ boost::future<boost::csbl::unique_ptr<int> > f = p2.get_future();
+ boost::thread(func2).detach();
+ BOOST_TEST(*f.get() == 5);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_rvalue_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_rvalue_pass.cpp
new file mode 100644
index 000000000..63260d726
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/promise/set_rvalue_pass.cpp
@@ -0,0 +1,297 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011,2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// void promise::set_value(R&& r);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+struct A
+{
+ A() :
+ value(0)
+ {
+ }
+ A(int i) :
+ value(i)
+ {
+ }
+ BOOST_THREAD_MOVABLE_ONLY(A)
+
+ A(BOOST_THREAD_RV_REF(A) rhs)
+ {
+ if(rhs.value==0)
+ throw 9;
+ else
+ {
+ value=rhs.value;
+ rhs.value=0;
+ }
+ }
+ A& operator=(BOOST_THREAD_RV_REF(A) rhs)
+ {
+ if(rhs.value==0)
+ throw 9;
+ else
+ {
+ value=rhs.value;
+ rhs.value=0;
+ }
+ return *this;
+ }
+ int value;
+};
+
+A make(int i) {
+ return A(i);
+}
+
+struct movable2
+{
+ int value_;
+ BOOST_THREAD_MOVABLE_ONLY(movable2)
+ movable2() : value_(1){}
+ movable2(int i) : value_(i){}
+
+ //Move constructor and assignment
+ movable2(BOOST_RV_REF(movable2) m)
+ { value_ = m.value_; m.value_ = 0; }
+
+ movable2 & operator=(BOOST_THREAD_RV_REF(movable2) m)
+ { value_ = m.value_; m.value_ = 0; return *this; }
+
+ bool moved() const //Observer
+ { return !value_; }
+
+ int value() const //Observer
+ { return value_; }
+};
+
+
+movable2 move_return_function2(int i) {
+ return movable2(i);
+}
+
+int main()
+{
+#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ BOOST_STATIC_ASSERT((boost::is_copy_constructible<movable2>::value == false));
+ BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<movable2>::value == true));
+ BOOST_STATIC_ASSERT((boost::is_copy_constructible<A>::value == false));
+ BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<A>::value == true));
+#endif
+
+ {
+ typedef A T;
+ T i;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ try
+ {
+ p.set_value(boost::move(i));
+ BOOST_TEST(false);
+ }
+ catch (int j)
+ {
+ BOOST_TEST(j == 9);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ {
+ typedef A T;
+ T i;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ try
+ {
+ p.set_value_deferred(boost::move(i));
+ BOOST_TEST(!f.is_ready());
+ p.notify_deferred();
+
+ BOOST_TEST(false);
+ }
+ catch (int j)
+ {
+ BOOST_TEST(j == 9);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ {
+ typedef A T;
+ T i;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ try
+ {
+ p.set_value((T()));
+ BOOST_TEST(false);
+ }
+ catch (int j)
+ {
+ BOOST_TEST(j == 9);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ {
+ typedef A T;
+ T i;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ try
+ {
+ p.set_value_deferred((T()));
+ BOOST_TEST(false);
+ }
+ catch (int j)
+ {
+ BOOST_TEST(j == 9);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ {
+ typedef A T;
+ T i(3);
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_value(boost::move(i));
+ BOOST_TEST(f.get().value == 3);
+ try
+ {
+ T j(3);
+ p.set_value(boost::move(j));
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+
+ }
+ {
+ movable2 i(3);
+ boost::promise<movable2> p;
+ boost::future<movable2> f = p.get_future();
+ p.set_value(move_return_function2(3));
+ BOOST_TEST(f.get().value_ == 3);
+ try
+ {
+ movable2 j(3);
+ p.set_value(boost::move(j));
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+
+ }
+ {
+ boost::promise<A> p;
+ boost::future<A> f = p.get_future();
+ p.set_value(make(3));
+ BOOST_TEST(f.get().value == 3);
+ try
+ {
+ A j(3);
+ p.set_value(boost::move(j));
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+
+ }
+ {
+ typedef A T;
+ T i(3);
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_value(boost::move(i));
+ BOOST_TEST(i.value == 0);
+ boost::promise<T> p2(boost::move(p));
+ BOOST_TEST(f.get().value == 3);
+
+ }
+ {
+ typedef A T;
+ T i(3);
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_value(boost::move(i));
+ BOOST_TEST(i.value == 0);
+ boost::promise<T> p2(boost::move(p));
+ boost::future<T> f2(boost::move(f));
+ BOOST_TEST(f2.get().value == 3);
+
+ }
+ {
+ typedef A T;
+ T i(3);
+ boost::promise<T> p;
+ p.set_value(boost::move(i));
+ BOOST_TEST(i.value == 0);
+ boost::promise<T> p2(boost::move(p));
+ boost::future<T> f = p2.get_future();
+ BOOST_TEST(f.get().value == 3);
+
+ }
+
+ {
+ typedef boost::future<int> T;
+ boost::promise<int> pi;
+ T fi=pi.get_future();
+ pi.set_value(3);
+
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_value(boost::move(fi));
+ boost::future<T> f2(boost::move(f));
+ BOOST_TEST(f2.get().get() == 3);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_const_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_const_pass.cpp
new file mode 100644
index 000000000..4972cb7d8
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_const_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// void promise::set_value_at_thread_exit(const R& r);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+void func(boost::promise<int> p)
+#else
+boost::promise<int> p;
+void func()
+#endif
+{
+ const int i = 5;
+ p.set_value_at_thread_exit(i);
+}
+
+int main()
+{
+ {
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::promise<int> p;
+ boost::future<int> f = p.get_future();
+ boost::thread(func, boost::move(p)).detach();
+#else
+ boost::future<int> f = p.get_future();
+ boost::thread(func).detach();
+#endif
+ try
+ {
+ BOOST_TEST(f.get() == 5);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ {
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#else
+ boost::promise<int> p2;
+ boost::future<int> f = p2.get_future();
+ p = boost::move(p2);
+ boost::thread(func).detach();
+ BOOST_TEST(f.get() == 5);
+#endif
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp
new file mode 100644
index 000000000..c79f2a23e
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp
@@ -0,0 +1,110 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// void promise<void>::set_value_at_thread_exit();
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int i = 0;
+
+boost::promise<void> p;
+void func()
+{
+ p.set_value_at_thread_exit();
+ i = 1;
+}
+
+//void func2_mv(BOOST_THREAD_RV_REF(boost::promise<void>) p2)
+void func2_mv(boost::promise<void> p2)
+{
+ p2.set_value_at_thread_exit();
+ i = 2;
+}
+
+void func2(boost::promise<void> *p2)
+{
+ p2->set_value_at_thread_exit();
+ i = 2;
+}
+int main()
+{
+ try
+ {
+ boost::future<void> f = p.get_future();
+ boost::thread(func).detach();
+ f.get();
+ BOOST_TEST(i == 1);
+
+ }
+ catch(std::exception& )
+ {
+ BOOST_TEST(false);
+ }
+ catch(...)
+ {
+ BOOST_TEST(false);
+ }
+
+ try
+ {
+ boost::promise<void> p2;
+ boost::future<void> f = p2.get_future();
+ p = boost::move(p2);
+ boost::thread(func).detach();
+ f.get();
+ BOOST_TEST(i == 1);
+
+ }
+ catch(std::exception& ex)
+ {
+ std::cout << __FILE__ << ":" << __LINE__ << " " << ex.what() << std::endl;
+ BOOST_TEST(false);
+ }
+ catch(...)
+ {
+ BOOST_TEST(false);
+ }
+
+ try
+ {
+ boost::promise<void> p2;
+ boost::future<void> f = p2.get_future();
+#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD
+ boost::thread(func2_mv, boost::move(p2)).detach();
+#else
+ boost::thread(func2, &p2).detach();
+#endif
+ f.wait();
+ f.get();
+ BOOST_TEST(i == 2);
+ }
+ catch(std::exception& ex)
+ {
+ std::cout << __FILE__ << ":" << __LINE__ << " " << ex.what() << std::endl;
+ BOOST_TEST(false);
+ }
+ catch(...)
+ {
+ BOOST_TEST(false);
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_value_const_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_value_const_pass.cpp
new file mode 100644
index 000000000..84f2fb273
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/promise/set_value_const_pass.cpp
@@ -0,0 +1,118 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// void promise::set_value(const R& r);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/config.hpp>
+
+#ifdef BOOST_MSVC
+# pragma warning(disable: 4702) // unreachable code
+#endif
+
+struct A
+{
+ A()
+ {
+ }
+ A(const A&)
+ {
+ throw 10;
+ }
+#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
+ A& operator= (const A&) = default;
+#endif
+};
+
+int main()
+{
+
+ {
+ typedef int T;
+ T i = 3;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_value(i);
+ ++i;
+ BOOST_TEST(f.get() == 3);
+ --i;
+ try
+ {
+ p.set_value(i);
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ {
+ typedef int T;
+ T i = 3;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_value_deferred(i);
+ p.notify_deferred();
+ ++i;
+ BOOST_TEST(f.get() == 3);
+ --i;
+ try
+ {
+ p.set_value(i);
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ {
+ typedef A T;
+ T i;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ try
+ {
+ p.set_value(i);
+ BOOST_TEST(false);
+ }
+ catch (int j)
+ {
+ BOOST_TEST(j == 10);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_value_void_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_value_void_pass.cpp
new file mode 100644
index 000000000..7c11d5b66
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/promise/set_value_void_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// void promise<void>::set_value();
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+struct A
+{
+ A()
+ {
+ }
+ A(const A&)
+ {
+ throw 10;
+ }
+};
+
+int main()
+{
+
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_value();
+ f.get();
+ try
+ {
+ p.set_value();
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::future<T> f = p.get_future();
+ p.set_value_deferred();
+ p.notify_deferred();
+ f.get();
+ try
+ {
+ p.set_value();
+ BOOST_TEST(false);
+ }
+ catch (const boost::future_error& e)
+ {
+ BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/promise/use_allocator_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/use_allocator_pass.cpp
new file mode 100644
index 000000000..3b1e96c7e
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/promise/use_allocator_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class promise<R>
+
+// promise(allocator_arg_t, const Allocator& a);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#include "../test_allocator.hpp"
+
+int main()
+{
+
+ BOOST_STATIC_ASSERT_MSG((boost::csbl::uses_allocator<boost::promise<int>, test_allocator<int> >::value), "");
+ BOOST_STATIC_ASSERT_MSG((boost::csbl::uses_allocator<boost::promise<int&>, test_allocator<int&> >::value), "");
+ BOOST_STATIC_ASSERT_MSG((boost::csbl::uses_allocator<boost::promise<void>, test_allocator<void> >::value), "");
+
+ return boost::report_errors();
+}
+
+#else
+int main()
+{
+ return boost::report_errors();
+}
+#endif
+
+
diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/copy_assign_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/copy_assign_pass.cpp
new file mode 100644
index 000000000..1b23b2d16
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/shared_future/copy_assign_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class shared_future<R>
+
+// shared_future& operator=(const shared_future&);
+
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0((p.get_future()));
+ boost::shared_future<T> f;
+ f = f0;
+ BOOST_TEST(f0.valid());
+ BOOST_TEST(f.valid());
+
+ }
+ {
+ typedef int T;
+ boost::shared_future<T> f0;
+ boost::shared_future<T> f;
+ f = f0;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0((p.get_future()));
+ boost::shared_future<T> f;
+ f = f0;
+ BOOST_TEST(f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int& T;
+ boost::shared_future<T> f0;
+ boost::shared_future<T> f;
+ f = f0;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0((p.get_future()));
+ boost::shared_future<T> f;
+ f = f0;
+ BOOST_TEST(f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef void T;
+ boost::shared_future<T> f0;
+ boost::shared_future<T> f;
+ f = f0;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+
+ return boost::report_errors();
+}
+
+//#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/copy_ctor_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/copy_ctor_pass.cpp
new file mode 100644
index 000000000..fd29c0fe3
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/shared_future/copy_ctor_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+// class shared_future<R>
+
+// shared_future(const future&);
+
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0((p.get_future()));
+ boost::shared_future<T> f = f0;
+ BOOST_TEST(f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int T;
+ boost::shared_future < T > f0;
+ boost::shared_future<T> f = f0;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0((p.get_future()));
+ boost::shared_future<T> f = f0;
+ BOOST_TEST(f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int& T;
+ boost::shared_future < T > f0;
+ boost::shared_future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0((p.get_future()));
+ boost::shared_future<T> f = f0;
+ BOOST_TEST(f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef void T;
+ boost::shared_future < T > f0;
+ boost::shared_future<T> f = f0;
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+
+ return boost::report_errors();
+}
+
+//#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/default_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/default_pass.cpp
new file mode 100644
index 000000000..59ecea3a3
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/shared_future/default_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class shared_future<R>
+
+// shared_future();
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ boost::shared_future<int> f;
+ BOOST_TEST(!f.valid());
+ }
+ {
+ boost::shared_future<int&> f;
+ BOOST_TEST(!f.valid());
+ }
+ {
+ boost::shared_future<void> f;
+ BOOST_TEST(!f.valid());
+ }
+
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/dtor_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/dtor_pass.cpp
new file mode 100644
index 000000000..01fb591c0
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/shared_future/dtor_pass.cpp
@@ -0,0 +1,109 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class shared_future<R>
+
+// ~shared_future();
+
+#define BOOST_THREAD_VERSION 3
+#include <boost/exception/exception.hpp>
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+#include "../test_allocator.hpp"
+#endif
+
+int main()
+{
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ typedef int T;
+ boost::shared_future<T> f;
+ {
+ boost::promise<T> p(boost::allocator_arg, test_allocator<T>());
+ BOOST_TEST(test_alloc_base::count == 1);
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ typedef int& T;
+ boost::shared_future<T> f;
+ {
+ boost::promise<T> p(boost::allocator_arg, test_allocator<int>());
+ BOOST_TEST(test_alloc_base::count == 1);
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+ {
+ typedef void T;
+ boost::shared_future<T> f;
+ {
+ boost::promise<T> p(boost::allocator_arg, test_allocator<T>());
+ BOOST_TEST(test_alloc_base::count == 1);
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 1);
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(test_alloc_base::count == 0);
+#endif
+ {
+ typedef int T;
+ boost::shared_future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int& T;
+ boost::shared_future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef void T;
+ boost::shared_future<T> f;
+ {
+ boost::promise<T> p;
+ f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ BOOST_TEST(f.valid());
+ }
+ BOOST_TEST(f.valid());
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/get_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/get_pass.cpp
new file mode 100644
index 000000000..558fb024f
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/shared_future/get_pass.cpp
@@ -0,0 +1,208 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_future.hpp>
+
+// class shared_future<R>
+
+// const R& shared_future::get();
+// R& shared_future<R&>::get();
+// void shared_future<void>::get();
+//#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+namespace boost
+{
+template <typename T>
+struct wrap
+{
+ wrap(T const& v) : value(v){}
+ T value;
+
+};
+
+template <typename T>
+exception_ptr make_exception_ptr(T v) {
+ return copy_exception(wrap<T>(v));
+}
+}
+
+void func1(boost::promise<int> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_value(3);
+}
+
+void func2(boost::promise<int> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_exception(boost::make_exception_ptr(3));
+}
+
+int j = 0;
+
+void func3(boost::promise<int&> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func4(boost::promise<int&> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_exception(boost::make_exception_ptr(3.5));
+}
+
+void func5(boost::promise<void> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_value();
+}
+
+void func6(boost::promise<void> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.set_exception(boost::make_exception_ptr(4));
+}
+
+
+int main()
+{
+ {
+ typedef int T;
+ {
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func1, boost::move(p)).detach();
+#else
+ p.set_value(3);
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST(f.get() == 3);
+ BOOST_TEST(f.valid());
+ }
+ {
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func2, boost::move(p)).detach();
+#else
+ p.set_exception(boost::make_exception_ptr(3));
+#endif
+ try
+ {
+ BOOST_TEST(f.valid());
+ BOOST_TEST(f.get() == 3);
+ BOOST_TEST(false);
+ }
+ catch (boost::wrap<int> const& i)
+ {
+ BOOST_TEST(i.value == 3);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ BOOST_TEST(f.valid());
+ }
+ }
+ {
+ typedef int& T;
+ {
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func3, boost::move(p)).detach();
+#else
+ int j=5;
+ p.set_value(j);
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST(f.get() == 5);
+ BOOST_TEST(f.valid());
+ }
+ {
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func4, boost::move(p)).detach();
+#else
+ p.set_exception(boost::make_exception_ptr(3.5));
+#endif
+ try
+ {
+ BOOST_TEST(f.valid());
+ BOOST_TEST(f.get() == 3);
+ BOOST_TEST(false);
+ }
+ catch (boost::wrap<double> const& i)
+ {
+ BOOST_TEST(i.value == 3.5);
+ }
+ BOOST_TEST(f.valid());
+ }
+ }
+
+ typedef void T;
+ {
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func5, boost::move(p)).detach();
+#else
+ p.set_value();
+#endif
+ BOOST_TEST(f.valid());
+ f.get();
+ BOOST_TEST(f.valid());
+ }
+ {
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func6, boost::move(p)).detach();
+#else
+ p.set_exception(boost::make_exception_ptr(4));
+#endif
+ try
+ {
+ BOOST_TEST(f.valid());
+ f.get();
+ BOOST_TEST(false);
+ }
+ catch (boost::wrap<int> const& i)
+ {
+ BOOST_TEST(i.value == 4);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ BOOST_TEST(f.valid());
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/move_assign_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/move_assign_pass.cpp
new file mode 100644
index 000000000..40ff4992c
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/shared_future/move_assign_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <future>
+
+// class shared_future<R>
+
+// shared_future& shared_future=(shared_future&& rhs);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::shared_future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int T;
+ boost::shared_future<T> f0;
+ boost::shared_future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::shared_future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int& T;
+ boost::shared_future<T> f0;
+ boost::shared_future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::shared_future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef void T;
+ boost::shared_future<T> f0;
+ boost::shared_future<T> f;
+ f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+
+
+ return boost::report_errors();
+
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/move_ctor_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/move_ctor_pass.cpp
new file mode 100644
index 000000000..533f5ec90
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/shared_future/move_ctor_pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <future>
+
+// class shared_future<R>
+
+// shared_future(shared_future&& rhs);
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m;
+
+int main()
+{
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::shared_future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int T;
+ boost::shared_future<T> f0;
+ boost::shared_future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::shared_future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef int& T;
+ boost::shared_future<T> f0;
+ boost::shared_future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::shared_future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ boost::shared_future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(f.valid());
+ }
+ {
+ typedef void T;
+ boost::shared_future<T> f0;
+ boost::shared_future<T> f = boost::move(f0);
+ BOOST_TEST(!f0.valid());
+ BOOST_TEST(!f.valid());
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/then_executor_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/then_executor_pass.cpp
new file mode 100644
index 000000000..73b42fc8a
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/shared_future/then_executor_pass.cpp
@@ -0,0 +1,149 @@
+// Copyright (C) 2014 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class future<R>
+
+// template<typename F>
+// auto then(F&& func) -> future<decltype(func(*this))>;
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#include <boost/thread/detail/log.hpp>
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/executors/basic_thread_pool.hpp>
+#include <boost/thread/executor.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+int p1()
+{
+ BOOST_THREAD_LOG << "p1 < " << BOOST_THREAD_END_LOG;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p1 >" << BOOST_THREAD_END_LOG;
+ return 1;
+}
+
+int p2(boost::shared_future<int> f)
+{
+ BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
+ BOOST_TEST(f.valid());
+ int i = f.get();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
+ return 2 * i;
+}
+
+void p3(boost::shared_future<int> f)
+{
+ BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG;
+ BOOST_TEST(f.valid());
+ int i = f.get();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p3 <" << &f << " " << i << BOOST_THREAD_END_LOG;
+ return ;
+}
+
+int main()
+{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::basic_thread_pool ex(1);
+ boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
+ BOOST_TEST(f1.valid());
+ boost::future<int> f2 = f1.then(ex, &p2);
+ BOOST_TEST(f2.valid());
+ try
+ {
+ BOOST_TEST(f2.get()==2);
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::basic_thread_pool ex(1);
+ boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
+ BOOST_TEST(f1.valid());
+ boost::future<void> f2 = f1.then(ex, &p3);
+ BOOST_TEST(f2.valid());
+ try
+ {
+ f2.wait();
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::basic_thread_pool ex(1);
+ boost::future<int> f2 = boost::async(p1).share().then(ex, &p2);
+ BOOST_TEST(f2.get()==2);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::basic_thread_pool ex(1);
+ boost::shared_future<int> f1 = boost::async(p1).share();
+ boost::shared_future<int> f21 = f1.then(ex, &p2).share();
+ boost::future<int> f2= f21.then(ex, &p2);
+ BOOST_TEST(f2.get()==4);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::basic_thread_pool ex(1);
+ boost::shared_future<int> f1 = boost::async(p1).share();
+ boost::shared_future<int> f21 = f1.then(ex, &p2).share();
+ boost::future<int> f2= f21.then(&p2);
+ BOOST_TEST(f2.get()==4);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::basic_thread_pool ex(1);
+ boost::shared_future<int> f1 = boost::async(p1).share();
+ boost::future<int> f2= f1.then(ex, &p2).share().then(ex, &p2);
+ BOOST_TEST(f2.get()==4);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::basic_thread_pool ex(1);
+ boost::future<int> f2 = boost::async(p1).share().then(ex, &p2).share().then(ex, &p2);
+ BOOST_TEST(f2.get()==4);
+ }
+
+ return boost::report_errors();
+}
+
+#else
+
+int main()
+{
+ return 0;
+}
+#endif
diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/then_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/then_pass.cpp
new file mode 100644
index 000000000..e7cca062e
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/shared_future/then_pass.cpp
@@ -0,0 +1,156 @@
+// Copyright (C) 2012-2013 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class future<R>
+
+// template<typename F>
+// auto then(F&& func) -> future<decltype(func(*this))>;
+
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#include <boost/thread/detail/log.hpp>
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+int p1()
+{
+ BOOST_THREAD_LOG << "p1 < " << BOOST_THREAD_END_LOG;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p1 >" << BOOST_THREAD_END_LOG;
+ return 1;
+}
+
+int p2(boost::shared_future<int> f)
+{
+ BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
+ BOOST_TEST(f.valid());
+ int i = f.get();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
+ return 2 * i;
+}
+
+void p3(boost::shared_future<int> f)
+{
+ BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG;
+ BOOST_TEST(f.valid());
+ int i = f.get();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p3 <" << &f << " " << i << BOOST_THREAD_END_LOG;
+ return ;
+}
+
+int main()
+{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
+ BOOST_TEST(f1.valid());
+ boost::future<int> f2 = f1.then(&p2);
+ BOOST_TEST(f2.valid());
+ try
+ {
+ BOOST_TEST(f2.get()==2);
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
+ BOOST_TEST(f1.valid());
+ boost::future<int> f2 = f1.then(&p2);
+ boost::future<int> f3 = f1.then(&p2);
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(f3.valid());
+ try
+ {
+ BOOST_TEST(f2.get()==2);
+ BOOST_TEST(f3.get()==2);
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
+ BOOST_TEST(f1.valid());
+ boost::future<void> f2 = f1.then(&p3);
+ BOOST_TEST(f2.valid());
+ try
+ {
+ f2.wait();
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f2 = boost::async(p1).share().then(&p2);
+ BOOST_TEST(f2.get()==2);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::shared_future<int> f1 = boost::async(p1).share();
+ boost::shared_future<int> f21 = f1.then(&p2).share();
+ boost::future<int> f2= f21.then(&p2);
+ BOOST_TEST(f2.get()==4);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::shared_future<int> f1 = boost::async(p1).share();
+ boost::future<int> f2= f1.then(&p2).share().then(&p2);
+ BOOST_TEST(f2.get()==4);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::future<int> f2 = boost::async(p1).share().then(&p2).share().then(&p2);
+ BOOST_TEST(f2.get()==4);
+ }
+
+ return boost::report_errors();
+}
+
+#else
+
+int main()
+{
+ return 0;
+}
+#endif
diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/wait_for_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/wait_for_pass.cpp
new file mode 100644
index 000000000..e9d8ac684
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/shared_future/wait_for_pass.cpp
@@ -0,0 +1,174 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class shared_future<R>
+
+// template <class Rep, class Period>
+// future_status
+// wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#include <boost/thread/detail/log.hpp>
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/chrono/chrono_io.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+namespace boost
+{
+ template <typename OStream>
+ OStream& operator<<(OStream& os , boost::future_status st )
+ {
+ os << underlying_cast<int>(st) << " ";
+ return os;
+ }
+ template <typename T>
+ struct wrap
+ {
+ wrap(T const& v) :
+ value(v)
+ {
+ }
+ T value;
+
+ };
+
+ template <typename T>
+ exception_ptr make_exception_ptr(T v)
+ {
+ return copy_exception(wrap<T> (v));
+ }
+}
+
+void func1(boost::promise<int> p)
+{
+ boost::this_thread::sleep_for(ms(500));
+ p.set_value(3);
+}
+
+int j = 0;
+
+void func3(boost::promise<int&> p)
+{
+ boost::this_thread::sleep_for(ms(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func5(boost::promise<void> p)
+{
+ boost::this_thread::sleep_for(ms(500));
+ p.set_value();
+}
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+int main()
+{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ typedef boost::chrono::high_resolution_clock Clock;
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func1, boost::move(p)).detach();
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST_EQ(f.wait_for(ms(250)) , boost::future_status::timeout);
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#else
+ func1(boost::move(p));
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST_EQ(f.wait_for(ms(750)) , boost::future_status::ready);
+ BOOST_TEST(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(f.valid());
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func3, boost::move(p)).detach();
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST_EQ(f.wait_for(ms(250)) , boost::future_status::timeout);
+ BOOST_TEST(f.valid());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#else
+ func3(boost::move(p));
+#endif
+ BOOST_TEST_EQ(f.wait_for(ms(750)) , boost::future_status::ready);
+ BOOST_TEST(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(f.valid());
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func5, boost::move(p)).detach();
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST_EQ(f.wait_for(ms(250)) , boost::future_status::timeout);
+ BOOST_TEST(f.valid());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#else
+ func5(boost::move(p));
+#endif
+ BOOST_TEST_EQ(f.wait_for(ms(750)) , boost::future_status::ready);
+ BOOST_TEST(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(f.valid());
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/wait_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/wait_pass.cpp
new file mode 100644
index 000000000..d2d1b31f6
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/shared_future/wait_pass.cpp
@@ -0,0 +1,155 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class shared_future<R>
+
+// template <class Rep, class Period>
+// void wait() const;
+
+//#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#include <boost/thread/detail/log.hpp>
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/chrono/chrono_io.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+typedef boost::chrono::milliseconds ms;
+
+namespace boost
+{
+ template <typename OStream>
+ OStream& operator<<(OStream& os , boost::future_status st )
+ {
+ os << underlying_cast<int>(st) << " ";
+ return os;
+ }
+ template <typename T>
+ struct wrap
+ {
+ wrap(T const& v) :
+ value(v)
+ {
+ }
+ T value;
+
+ };
+
+ template <typename T>
+ exception_ptr make_exception_ptr(T v)
+ {
+ return copy_exception(wrap<T> (v));
+ }
+}
+
+void func1(boost::promise<int> p)
+{
+ boost::this_thread::sleep_for(ms(500));
+ p.set_value(3);
+}
+
+int j = 0;
+
+void func3(boost::promise<int&> p)
+{
+ boost::this_thread::sleep_for(ms(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func5(boost::promise<void> p)
+{
+ boost::this_thread::sleep_for(ms(500));
+ p.set_value();
+}
+
+int main()
+{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ typedef boost::chrono::high_resolution_clock Clock;
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func1, boost::move(p)).detach();
+#else
+ func1(boost::move(p));
+#endif
+ BOOST_TEST(f.valid());
+ f.wait();
+ BOOST_TEST(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(f.valid());
+ BOOST_TEST(t1 - t0 < ms(50));
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func3, boost::move(p)).detach();
+#else
+ func3(boost::move(p));
+#endif
+ BOOST_TEST(f.valid());
+ f.wait();
+ BOOST_TEST(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(f.valid());
+ BOOST_TEST(t1 - t0 < ms(50));
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func5, boost::move(p)).detach();
+#else
+ func5(boost::move(p));
+#endif
+ BOOST_TEST(f.valid());
+ f.wait();
+ BOOST_TEST(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(f.valid());
+ BOOST_TEST(t1 - t0 < ms(50));
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/wait_until_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/wait_until_pass.cpp
new file mode 100644
index 000000000..8b05725e7
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/shared_future/wait_until_pass.cpp
@@ -0,0 +1,175 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// class shared_future<R>
+
+// template <class Rep, class Period>
+// future_status
+// wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+
+//#define BOOST_THREAD_VERSION 3
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_USES_LOG
+#define BOOST_THREAD_USES_LOG_THREAD_ID
+#include <boost/thread/detail/log.hpp>
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/chrono/chrono_io.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+namespace boost
+{
+ template <typename OStream>
+ OStream& operator<<(OStream& os , boost::future_status st )
+ {
+ os << underlying_cast<int>(st) << " ";
+ return os;
+ }
+ template <typename T>
+ struct wrap
+ {
+ wrap(T const& v) :
+ value(v)
+ {
+ }
+ T value;
+
+ };
+
+ template <typename T>
+ exception_ptr make_exception_ptr(T v)
+ {
+ return copy_exception(wrap<T> (v));
+ }
+}
+
+void func1(boost::promise<int> p)
+{
+ boost::this_thread::sleep_for(ms(500));
+ p.set_value(3);
+}
+
+int j = 0;
+
+void func3(boost::promise<int&> p)
+{
+ boost::this_thread::sleep_for(ms(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func5(boost::promise<void> p)
+{
+ boost::this_thread::sleep_for(ms(500));
+ p.set_value();
+}
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+int main()
+{
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ typedef boost::chrono::high_resolution_clock Clock;
+ {
+ typedef int T;
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func1, boost::move(p)).detach();
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(250)) , boost::future_status::timeout);
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#else
+ func1(boost::move(p));
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(750)) , boost::future_status::ready);
+ BOOST_TEST(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(f.valid());
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ }
+ {
+ typedef int& T;
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func3, boost::move(p)).detach();
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(250)) , boost::future_status::timeout);
+ BOOST_TEST(f.valid());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#else
+ func3(boost::move(p));
+#endif
+ BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(750)) , boost::future_status::ready);
+ BOOST_TEST(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(f.valid());
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ }
+ {
+ typedef void T;
+ boost::promise<T> p;
+ boost::shared_future<T> f((p.get_future()));
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ boost::thread(func5, boost::move(p)).detach();
+#endif
+ BOOST_TEST(f.valid());
+ BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(250)) , boost::future_status::timeout);
+ BOOST_TEST(f.valid());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#else
+ func5(boost::move(p));
+#endif
+ BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(750)) , boost::future_status::ready);
+ BOOST_TEST(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ BOOST_TEST(f.valid());
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/sync/futures/test_allocator.hpp b/src/boost/libs/thread/test/sync/futures/test_allocator.hpp
new file mode 100644
index 000000000..a73d7d8e3
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/test_allocator.hpp
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_THREAD_TEST_ALLOCATOR_HPP
+#define BOOST_THREAD_TEST_ALLOCATOR_HPP
+
+#include <cstddef>
+#include <boost/type_traits.hpp>
+#include <boost/thread/detail/move.hpp>
+#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 boost::add_lvalue_reference<value_type>::type reference;
+ typedef typename boost::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)
+ throw std::bad_alloc();
+ ++count;
+ return (pointer)std::malloc(n * sizeof(T));
+ }
+ void deallocate(pointer p, size_type)
+ {--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);}
+
+ void construct(pointer p, BOOST_THREAD_RV_REF(T) val)
+ {::new(p) T(boost::move(val));}
+
+ 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)
+ {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 boost::true_type propagate_on_container_copy_assignment;
+ typedef boost::true_type propagate_on_container_move_assignment;
+ typedef boost::true_type propagate_on_container_swap;
+
+#ifdef BOOST_NO_SFINAE_EXPR
+ std::size_t max_size() const
+ {return UINT_MAX / sizeof(T);}
+#endif // BOOST_NO_SFINAE_EXPR
+
+};
+
+#endif // BOOST_THREAD_TEST_ALLOCATOR_HPP
diff --git a/src/boost/libs/thread/test/sync/futures/when_all/iterators_pass.cpp b/src/boost/libs/thread/test/sync/futures/when_all/iterators_pass.cpp
new file mode 100644
index 000000000..2646074f0
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/when_all/iterators_pass.cpp
@@ -0,0 +1,362 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// template< typename InputIterator>
+// future<vector<typename InputIterator::value_type> >
+// when_all(InputIterator first, InputIterator last)
+
+#include <boost/config.hpp>
+
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <stdexcept>
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+int p1()
+{
+ return 123;
+}
+
+int thr()
+{
+ throw std::logic_error("123");
+}
+int p2()
+{
+ return 321;
+}
+
+int main()
+{
+#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
+ if (0) // todo not yet implemented
+ { // invalid future copy-constructible
+ boost::csbl::vector<boost::future<int> > v;
+ boost::future<int> f1;
+ v.push_back(boost::move(f1));
+ v.push_back(boost::make_ready_future(321));
+ BOOST_TEST(! v[0].valid());
+ BOOST_TEST(v[1].valid());
+
+ boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(v.begin(), v.end());
+ BOOST_TEST(! v[0].valid());
+ BOOST_TEST(! v[1].valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::vector<boost::future<int> > res = all.get();
+ BOOST_TEST(res.size() == 2);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ // has exception
+ //BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+ { // is_ready future copy-constructible
+ boost::future<int> f1 = boost::make_ready_future(123);
+ boost::future<int> f2 = boost::make_ready_future(321);
+ boost::csbl::vector<boost::future<int> > v;
+ v.push_back(boost::move(f1));
+ v.push_back(boost::move(f2));
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[0].is_ready());
+ BOOST_TEST(v[1].valid());
+ BOOST_TEST(v[1].is_ready());
+ boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(v.begin(), v.end());
+ BOOST_TEST(! v[0].valid());
+ BOOST_TEST(! v[1].valid());
+ BOOST_TEST(all.valid());
+ if (0) // todo FAILS not yet implemented
+ BOOST_TEST(all.is_ready());
+ boost::csbl::vector<boost::future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ BOOST_TEST(res[0].is_ready());
+ BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+ { // is_ready shared_future copy-constructible
+ boost::shared_future<int> f1 = boost::make_ready_future(123).share();
+ boost::shared_future<int> f2 = boost::make_ready_future(321).share();
+ boost::csbl::vector<boost::shared_future<int> > v;
+ v.push_back(f1);
+ v.push_back(f2);
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[0].is_ready());
+ BOOST_TEST(v[1].valid());
+ BOOST_TEST(v[1].is_ready());
+ boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_all(v.begin(), v.end());
+ if (0) // fixme
+ BOOST_TEST(v[0].valid());
+ if (0) // fixme
+ BOOST_TEST(v[1].valid());
+ BOOST_TEST(all.valid());
+ if (0) // todo FAILS not yet implemented
+ BOOST_TEST(all.is_ready());
+ boost::csbl::vector<boost::shared_future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ BOOST_TEST(res[0].is_ready());
+ BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+ { // packaged_task future copy-constructible
+ boost::packaged_task<int()> pt1(&p1);
+ boost::future<int> f1 = pt1.get_future();
+ BOOST_TEST(f1.valid());
+ boost::packaged_task<int()> pt2(&p2);
+ boost::future<int> f2 = pt2.get_future();
+ BOOST_TEST(f2.valid());
+ boost::csbl::vector<boost::future<int> > v;
+ v.push_back(boost::move(f1));
+ v.push_back(boost::move(f2));
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[1].valid());
+ boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(v.begin(), v.end());
+ BOOST_TEST(! v[0].valid());
+ BOOST_TEST(! v[1].valid());
+ BOOST_TEST(all.valid());
+ pt1();
+ pt2();
+ boost::csbl::vector<boost::future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ BOOST_TEST(res[0].is_ready());
+ BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+ { // packaged_task future copy-constructible
+ boost::packaged_task<int()> pt1(&thr);
+ boost::future<int> f1 = pt1.get_future();
+ BOOST_TEST(f1.valid());
+ boost::packaged_task<int()> pt2(&p2);
+ boost::future<int> f2 = pt2.get_future();
+ BOOST_TEST(f2.valid());
+ boost::csbl::vector<boost::future<int> > v;
+ v.push_back(boost::move(f1));
+ v.push_back(boost::move(f2));
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[1].valid());
+ boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(v.begin(), v.end());
+ BOOST_TEST(! v[0].valid());
+ BOOST_TEST(! v[1].valid());
+ BOOST_TEST(all.valid());
+ pt1();
+ pt2();
+ boost::csbl::vector<boost::future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ BOOST_TEST(res[0].is_ready());
+ try {
+ res[0].get();
+ BOOST_TEST(false);
+ } catch (std::logic_error& ex) {
+ BOOST_TEST(ex.what() == std::string("123"));
+ } catch (...) {
+ BOOST_TEST(false);
+ }
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+ { // packaged_task shared_future copy-constructible
+ boost::packaged_task<int()> pt1(&p1);
+ boost::shared_future<int> f1 = pt1.get_future().share();
+ BOOST_TEST(f1.valid());
+ boost::packaged_task<int()> pt2(&p2);
+ boost::shared_future<int> f2 = pt2.get_future().share();
+ BOOST_TEST(f2.valid());
+ boost::csbl::vector<boost::shared_future<int> > v;
+ v.push_back(f1);
+ v.push_back(f2);
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[1].valid());
+ boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_all(v.begin(), v.end());
+ if (0) // fixme
+ BOOST_TEST(v[0].valid());
+ if (0) // fixme
+ BOOST_TEST(v[1].valid());
+ BOOST_TEST(all.valid());
+ BOOST_TEST(! all.is_ready());
+ pt1();
+ BOOST_TEST(! all.is_ready());
+ pt2();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(300));
+ BOOST_TEST(all.is_ready());
+ boost::csbl::vector<boost::shared_future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ BOOST_TEST(res[0].is_ready());
+ BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+ { // async future copy-constructible
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<int> f2 = boost::async(boost::launch::async, &p2);
+ BOOST_TEST(f2.valid());
+ boost::csbl::vector<boost::future<int> > v;
+ v.push_back(boost::move(f1));
+ v.push_back(boost::move(f2));
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[1].valid());
+ boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(v.begin(), v.end());
+ BOOST_TEST(! v[0].valid());
+ BOOST_TEST(! v[1].valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::vector<boost::future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ BOOST_TEST(res[0].is_ready());
+ BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+ { // async shared_future copy-constructible
+ boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
+ BOOST_TEST(f1.valid());
+ boost::shared_future<int> f2 = boost::async(boost::launch::async, &p2).share();
+ BOOST_TEST(f2.valid());
+ boost::csbl::vector<boost::shared_future<int> > v;
+ v.push_back(f1);
+ v.push_back(f2);
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[1].valid());
+ boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_all(v.begin(), v.end());
+ if (0) // fixme
+ BOOST_TEST(v[0].valid());
+ if (0) // fixme
+ BOOST_TEST(v[1].valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::vector<boost::shared_future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ BOOST_TEST(res[0].is_ready());
+ BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+ { // async future copy-constructible
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<int> f2 = boost::make_ready_future(321);
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(f2.is_ready());
+ boost::csbl::vector<boost::future<int> > v;
+ v.push_back(boost::move(f1));
+ v.push_back(boost::move(f2));
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[1].valid());
+ boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(v.begin(), v.end());
+ BOOST_TEST(! v[0].valid());
+ BOOST_TEST(! v[1].valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::vector<boost::future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ BOOST_TEST(res[0].is_ready());
+ BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD
+ // fixme darwin-4.8.0_11 terminate called without an active exception
+ { // deferred future copy-constructible
+ boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);
+ boost::future<int> f2 = boost::async(boost::launch::deferred, &p2);
+ boost::csbl::vector<boost::future<int> > v;
+ v.push_back(boost::move(f1));
+ v.push_back(boost::move(f2));
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[1].valid());
+ boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(v.begin(), v.end());
+ BOOST_TEST(! v[0].valid());
+ BOOST_TEST(! v[1].valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::vector<boost::future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ BOOST_TEST(res[0].is_ready());
+ BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+ // fixme darwin-4.8.0_11 terminate called without an active exception
+ { // deferred shared_future copy-constructible
+ boost::shared_future<int> f1 = boost::async(boost::launch::deferred, &p1).share();
+ boost::shared_future<int> f2 = boost::async(boost::launch::deferred, &p2).share();
+ boost::csbl::vector<boost::shared_future<int> > v;
+ v.push_back(f1);
+ v.push_back(f2);
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[1].valid());
+ boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_all(v.begin(), v.end());
+ if (0) // fixme
+ BOOST_TEST(v[0].valid());
+ if (0) // fixme
+ BOOST_TEST(v[1].valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::vector<boost::shared_future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ BOOST_TEST(res[0].is_ready());
+ BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+#endif
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+ { // async futures copy-constructible then()
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<int> f2 = boost::async(boost::launch::async, &p2);
+ BOOST_TEST(f2.valid());
+ boost::csbl::vector<boost::future<int> > v;
+ v.push_back(boost::move(f1));
+ v.push_back(boost::move(f2));
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[1].valid());
+ boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(v.begin(), v.end());
+ BOOST_TEST(! v[0].valid());
+ BOOST_TEST(! v[1].valid());
+ BOOST_TEST(all.valid());
+ boost::future<int> sum = all.then([](boost::future<boost::csbl::vector<boost::future<int> > > f)
+ {
+ boost::csbl::vector<boost::future<int> > v = f.get();
+ return v[0].get() + v[1].get();
+ });
+ BOOST_TEST(sum.valid());
+ BOOST_TEST(sum.get() == 444);
+ }
+#endif
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/when_all/none_pass.cpp b/src/boost/libs/thread/test/sync/futures/when_all/none_pass.cpp
new file mode 100644
index 000000000..613e2368d
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/when_all/none_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// future<tuple<>> when_all();
+
+#include <boost/config.hpp>
+
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
+
+ {
+ boost::future<boost::csbl::tuple<> > all = boost::when_all();
+ BOOST_TEST(all.valid());
+ BOOST_TEST(all.is_ready());
+ }
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/when_all/one_pass.cpp b/src/boost/libs/thread/test/sync/futures/when_all/one_pass.cpp
new file mode 100644
index 000000000..026abcf53
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/when_all/one_pass.cpp
@@ -0,0 +1,186 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// template <class T, class Ts>
+// future<tuple<T>> when_all(T&&);
+
+#include <boost/config.hpp>
+
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <stdexcept>
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+int p1()
+{
+ return 123;
+}
+
+int thr()
+{
+ throw std::logic_error("123");
+}
+
+int main()
+{
+#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
+ if (0) // todo not yet implemented
+ { // invalid future copy-constructible
+ boost::future<int> f1;
+ BOOST_TEST(! f1.valid());
+ boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ // has exception
+ //BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ }
+ { // is_ready future copy-constructible
+ boost::future<int> f1 = boost::make_ready_future(123);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(f1.is_ready());
+ boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(all.valid());
+ if (0) // todo FAILS not yet implemented
+ BOOST_TEST(all.is_ready());
+ boost::csbl::tuple<boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ }
+ { // is_ready shared_future copy-constructible
+ boost::shared_future<int> f1 = boost::make_ready_future(123).share();
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(f1.is_ready());
+ boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_all(f1);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(all.valid());
+ if (0) // todo FAILS not yet implemented
+ BOOST_TEST(all.is_ready());
+ boost::csbl::tuple<boost::shared_future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ }
+ { // packaged_task future copy-constructible
+ boost::packaged_task<int()> pt1(&p1);
+ boost::future<int> f1 = pt1.get_future();
+ BOOST_TEST(f1.valid());
+ boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(all.valid());
+ pt1();
+ boost::csbl::tuple<boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ }
+ { // packaged_task shared_future copy-constructible
+ boost::packaged_task<int()> pt1(&p1);
+ boost::shared_future<int> f1 = pt1.get_future().share();
+ BOOST_TEST(f1.valid());
+ boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_all(f1);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(all.valid());
+ pt1();
+ boost::csbl::tuple<boost::shared_future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ }
+ { // packaged_task future copy-constructible
+ boost::packaged_task<int()> pt1(&thr);
+ boost::future<int> f1 = pt1.get_future();
+ BOOST_TEST(f1.valid());
+ boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(all.valid());
+ pt1();
+ boost::csbl::tuple<boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ try {
+ boost::csbl::get<0>(res).get();
+ BOOST_TEST(false);
+ } catch (std::logic_error& ex) {
+ BOOST_TEST(ex.what() == std::string("123"));
+ } catch (...) {
+ BOOST_TEST(false);
+ }
+ }
+ { // async future copy-constructible
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ }
+ { // async shared_future copy-constructible
+ boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
+ BOOST_TEST(f1.valid());
+ boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_all(f1);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::shared_future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ }
+#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD
+ // fixme darwin-4.8.0_11 terminate called without an active exception
+ { // deferred future copy-constructible
+ boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);
+ boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ }
+ // fixme darwin-4.8.0_11 terminate called without an active exception
+ { // deferred shared_future copy-constructible
+ boost::shared_future<int> f1 = boost::async(boost::launch::deferred, &p1).share();
+ boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_all(f1);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::shared_future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ }
+#endif
+#endif
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/when_all/variadic_pass.cpp b/src/boost/libs/thread/test/sync/futures/when_all/variadic_pass.cpp
new file mode 100644
index 000000000..f3b93b8be
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/when_all/variadic_pass.cpp
@@ -0,0 +1,300 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// template <class T, class Ts>
+// future<tuple<T, Ts...>> when_all(T&&, Ts&& ...);
+
+#include <boost/config.hpp>
+
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <stdexcept>
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+int p1()
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
+ return 123;
+}
+
+int thr()
+{
+ throw std::logic_error("123");
+}
+int p2()
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
+ return 321;
+}
+
+int main()
+{
+#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
+ if (0) // todo not yet implemented
+ { // invalid future copy-constructible
+ boost::future<int> f1;
+ boost::future<int> f2 = boost::make_ready_future(321);
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(f2.valid());
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(! f2.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ // has exception
+ //BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ { // is_ready future copy-constructible
+ boost::future<int> f1 = boost::make_ready_future(123);
+ boost::future<int> f2 = boost::make_ready_future(321);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(f1.is_ready());
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(f2.is_ready());
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(! f2.valid());
+ BOOST_TEST(all.valid());
+ if (0) // todo FAILS not yet implemented
+ BOOST_TEST(all.is_ready());
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ { // is_ready shared_future copy-constructible
+ boost::shared_future<int> f1 = boost::make_ready_future(123).share();
+ boost::shared_future<int> f2 = boost::make_ready_future(321).share();
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(f1.is_ready());
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(f2.is_ready());
+ boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_all(f1, f2);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(all.valid());
+ if (0) // todo FAILS not yet implemented
+ BOOST_TEST(all.is_ready());
+ boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ { // packaged_task future copy-constructible
+ boost::packaged_task<int()> pt1(&p1);
+ boost::future<int> f1 = pt1.get_future();
+ BOOST_TEST(f1.valid());
+ boost::packaged_task<int()> pt2(&p2);
+ boost::future<int> f2 = pt2.get_future();
+ BOOST_TEST(f2.valid());
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(! f2.valid());
+ BOOST_TEST(all.valid());
+ pt1();
+ pt2();
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ { // packaged_task future copy-constructible
+ boost::packaged_task<int()> pt1(&thr);
+ boost::future<int> f1 = pt1.get_future();
+ BOOST_TEST(f1.valid());
+ boost::packaged_task<int()> pt2(&p2);
+ boost::future<int> f2 = pt2.get_future();
+ BOOST_TEST(f2.valid());
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(! f2.valid());
+ BOOST_TEST(all.valid());
+ pt1();
+ pt2();
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ try {
+ boost::csbl::get<0>(res).get();
+ BOOST_TEST(false);
+ } catch (std::logic_error& ex) {
+ BOOST_TEST(ex.what() == std::string("123"));
+ } catch (...) {
+ BOOST_TEST(false);
+ }
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ { // packaged_task shared_future copy-constructible
+ boost::packaged_task<int()> pt1(&p1);
+ boost::shared_future<int> f1 = pt1.get_future().share();
+ BOOST_TEST(f1.valid());
+ boost::packaged_task<int()> pt2(&p2);
+ boost::shared_future<int> f2 = pt2.get_future().share();
+ BOOST_TEST(f2.valid());
+ boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_all(f1, f2);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(all.valid());
+ BOOST_TEST(! all.is_ready());
+ pt1();
+ BOOST_TEST(! all.is_ready());
+ pt2();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(300));
+ BOOST_TEST(all.is_ready());
+ boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ { // async future copy-constructible
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<int> f2 = boost::async(boost::launch::async, &p2);
+ BOOST_TEST(f2.valid());
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(! f2.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ { // async shared_future copy-constructible
+ boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
+ BOOST_TEST(f1.valid());
+ boost::shared_future<int> f2 = boost::async(boost::launch::async, &p2).share();
+ BOOST_TEST(f2.valid());
+ boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_all(f1, f2);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ { // async future copy-constructible
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<int> f2 = boost::make_ready_future(321);
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(f2.is_ready());
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(! f2.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD
+ // fixme darwin-4.8.0_11 terminate called without an active exception
+ { // deferred future copy-constructible
+ boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);
+ boost::future<int> f2 = boost::async(boost::launch::deferred, &p2);
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(! f2.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ // fixme darwin-4.8.0_11 terminate called without an active exception
+ { // deferred shared_future copy-constructible
+ boost::shared_future<int> f1 = boost::async(boost::launch::deferred, &p1).share();
+ boost::shared_future<int> f2 = boost::async(boost::launch::deferred, &p2).share();
+ boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_all(f1, f2);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+#endif
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+ { // async futures copy-constructible then()
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<int> f2 = boost::async(boost::launch::async, &p2);
+ BOOST_TEST(f2.valid());
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(! f2.valid());
+ BOOST_TEST(all.valid());
+ boost::future<int> sum = all.then([](boost::future<boost::csbl::tuple<boost::future<int>, boost::future<int> > > f)
+ {
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > v = f.get();
+ return boost::csbl::get<0>(v).get()+boost::csbl::get<1>(v).get();
+ });
+ BOOST_TEST(sum.valid());
+ BOOST_TEST(sum.get() == 444);
+ }
+#endif
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/when_any/iterators_pass.cpp b/src/boost/libs/thread/test/sync/futures/when_any/iterators_pass.cpp
new file mode 100644
index 000000000..03336d022
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/when_any/iterators_pass.cpp
@@ -0,0 +1,363 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// template< typename InputIterator>
+// future<vector<typename InputIterator::value_type> >
+// when_any(InputIterator first, InputIterator last)
+
+#include <boost/config.hpp>
+
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <stdexcept>
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+int p1()
+{
+ return 123;
+}
+
+int thr()
+{
+ throw std::logic_error("123");
+}
+int p2()
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
+ return 321;
+}
+
+int main()
+{
+#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
+ if (0) // todo not yet implemented
+ { // invalid future copy-constructible
+ boost::csbl::vector<boost::future<int> > v;
+ boost::future<int> f1;
+ v.push_back(boost::move(f1));
+ v.push_back(boost::make_ready_future(321));
+ BOOST_TEST(! v[0].valid());
+ BOOST_TEST(v[1].valid());
+
+ boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_any(v.begin(), v.end());
+ BOOST_TEST(! v[0].valid());
+ BOOST_TEST(! v[1].valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::vector<boost::future<int> > res = all.get();
+ BOOST_TEST(res.size() == 2);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ // has exception
+ //BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+ { // is_ready future copy-constructible
+ boost::future<int> f1 = boost::make_ready_future(123);
+ boost::future<int> f2 = boost::make_ready_future(321);
+ boost::csbl::vector<boost::future<int> > v;
+ v.push_back(boost::move(f1));
+ v.push_back(boost::move(f2));
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[0].is_ready());
+ BOOST_TEST(v[1].valid());
+ BOOST_TEST(v[1].is_ready());
+ boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_any(v.begin(), v.end());
+ BOOST_TEST(! v[0].valid());
+ BOOST_TEST(! v[1].valid());
+ BOOST_TEST(all.valid());
+ if (0) // todo FAILS not yet implemented
+ BOOST_TEST(all.is_ready());
+ boost::csbl::vector<boost::future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ BOOST_TEST(res[0].is_ready());
+ BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+ { // is_ready shared_future copy-constructible
+ boost::shared_future<int> f1 = boost::make_ready_future(123).share();
+ boost::shared_future<int> f2 = boost::make_ready_future(321).share();
+ boost::csbl::vector<boost::shared_future<int> > v;
+ v.push_back(f1);
+ v.push_back(f2);
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[0].is_ready());
+ BOOST_TEST(v[1].valid());
+ BOOST_TEST(v[1].is_ready());
+ boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_any(v.begin(), v.end());
+ if (0) // fixme
+ BOOST_TEST(v[0].valid());
+ if (0) // fixme
+ BOOST_TEST(v[1].valid());
+ BOOST_TEST(all.valid());
+ if (0) // todo FAILS not yet implemented
+ BOOST_TEST(all.is_ready());
+ boost::csbl::vector<boost::shared_future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ BOOST_TEST(res[0].is_ready());
+ BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+ { // packaged_task future copy-constructible
+ boost::packaged_task<int()> pt1(&p1);
+ boost::future<int> f1 = pt1.get_future();
+ BOOST_TEST(f1.valid());
+ boost::packaged_task<int()> pt2(&p2);
+ boost::future<int> f2 = pt2.get_future();
+ BOOST_TEST(f2.valid());
+ boost::csbl::vector<boost::future<int> > v;
+ v.push_back(boost::move(f1));
+ v.push_back(boost::move(f2));
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[1].valid());
+ boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_any(v.begin(), v.end());
+ BOOST_TEST(! v[0].valid());
+ BOOST_TEST(! v[1].valid());
+ BOOST_TEST(all.valid());
+ pt1();
+ pt2();
+ boost::csbl::vector<boost::future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ BOOST_TEST(res[0].is_ready());
+ BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+ { // packaged_task future copy-constructible
+ boost::packaged_task<int()> pt1(&thr);
+ boost::future<int> f1 = pt1.get_future();
+ BOOST_TEST(f1.valid());
+ boost::packaged_task<int()> pt2(&p2);
+ boost::future<int> f2 = pt2.get_future();
+ BOOST_TEST(f2.valid());
+ boost::csbl::vector<boost::future<int> > v;
+ v.push_back(boost::move(f1));
+ v.push_back(boost::move(f2));
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[1].valid());
+ boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_any(v.begin(), v.end());
+ BOOST_TEST(! v[0].valid());
+ BOOST_TEST(! v[1].valid());
+ BOOST_TEST(all.valid());
+ pt1();
+ pt2();
+ boost::csbl::vector<boost::future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ BOOST_TEST(res[0].is_ready());
+ try {
+ res[0].get();
+ BOOST_TEST(false);
+ } catch (std::logic_error& ex) {
+ BOOST_TEST(ex.what() == std::string("123"));
+ } catch (...) {
+ BOOST_TEST(false);
+ }
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+ { // packaged_task shared_future copy-constructible
+ boost::packaged_task<int()> pt1(&p1);
+ boost::shared_future<int> f1 = pt1.get_future().share();
+ BOOST_TEST(f1.valid());
+ boost::packaged_task<int()> pt2(&p2);
+ boost::shared_future<int> f2 = pt2.get_future().share();
+ BOOST_TEST(f2.valid());
+ boost::csbl::vector<boost::shared_future<int> > v;
+ v.push_back(f1);
+ v.push_back(f2);
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[1].valid());
+ boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_any(v.begin(), v.end());
+ if (0) // fixme
+ BOOST_TEST(v[0].valid());
+ if (0) // fixme
+ BOOST_TEST(v[1].valid());
+ BOOST_TEST(all.valid());
+ BOOST_TEST(! all.is_ready());
+ pt1();
+ pt2();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(300));
+ BOOST_TEST(all.is_ready());
+ boost::csbl::vector<boost::shared_future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ BOOST_TEST(res[0].is_ready());
+ BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+ { // async future copy-constructible
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<int> f2 = boost::async(boost::launch::async, &p2);
+ BOOST_TEST(f2.valid());
+ boost::csbl::vector<boost::future<int> > v;
+ v.push_back(boost::move(f1));
+ v.push_back(boost::move(f2));
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[1].valid());
+ boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_any(v.begin(), v.end());
+ BOOST_TEST(! v[0].valid());
+ BOOST_TEST(! v[1].valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::vector<boost::future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ BOOST_TEST(res[0].is_ready());
+ BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(! res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+ { // async shared_future copy-constructible
+ boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
+ BOOST_TEST(f1.valid());
+ boost::shared_future<int> f2 = boost::async(boost::launch::async, &p2).share();
+ BOOST_TEST(f2.valid());
+ boost::csbl::vector<boost::shared_future<int> > v;
+ v.push_back(f1);
+ v.push_back(f2);
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[1].valid());
+ boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_any(v.begin(), v.end());
+ if (0) // fixme
+ BOOST_TEST(v[0].valid());
+ if (0) // fixme
+ BOOST_TEST(v[1].valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::vector<boost::shared_future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ BOOST_TEST(res[0].is_ready());
+ BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(! res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+ { // async future copy-constructible
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<int> f2 = boost::make_ready_future(321);
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(f2.is_ready());
+ boost::csbl::vector<boost::future<int> > v;
+ v.push_back(boost::move(f1));
+ v.push_back(boost::move(f2));
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[1].valid());
+ boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_any(v.begin(), v.end());
+ BOOST_TEST(! v[0].valid());
+ BOOST_TEST(! v[1].valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::vector<boost::future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ if (0) // fixme
+ BOOST_TEST(! res[0].is_ready());
+ BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD
+ // fixme darwin-4.8.0_11 terminate called without an active exception
+ { // deferred future copy-constructible
+ boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);
+ boost::future<int> f2 = boost::async(boost::launch::deferred, &p2);
+ boost::csbl::vector<boost::future<int> > v;
+ v.push_back(boost::move(f1));
+ v.push_back(boost::move(f2));
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[1].valid());
+ boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_any(v.begin(), v.end());
+ BOOST_TEST(! v[0].valid());
+ BOOST_TEST(! v[1].valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::vector<boost::future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ BOOST_TEST(res[0].is_ready());
+ BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(! res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+ // fixme darwin-4.8.0_11 terminate called without an active exception
+ { // deferred shared_future copy-constructible
+ boost::shared_future<int> f1 = boost::async(boost::launch::deferred, &p1).share();
+ boost::shared_future<int> f2 = boost::async(boost::launch::deferred, &p2).share();
+ boost::csbl::vector<boost::shared_future<int> > v;
+ v.push_back(f1);
+ v.push_back(f2);
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[1].valid());
+ boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_any(v.begin(), v.end());
+ if (0) // fixme
+ BOOST_TEST(v[0].valid());
+ if (0) // fixme
+ BOOST_TEST(v[1].valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::vector<boost::shared_future<int> > res = all.get();
+ BOOST_TEST(res[0].valid());
+ BOOST_TEST(res[0].is_ready());
+ BOOST_TEST(res[0].get() == 123);
+ BOOST_TEST(res[1].valid());
+ BOOST_TEST(! res[1].is_ready());
+ BOOST_TEST(res[1].get() == 321);
+ }
+#endif
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+ { // async futures copy-constructible then()
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<int> f2 = boost::async(boost::launch::async, &p2);
+ BOOST_TEST(f2.valid());
+ boost::csbl::vector<boost::future<int> > v;
+ v.push_back(boost::move(f1));
+ v.push_back(boost::move(f2));
+ BOOST_TEST(v[0].valid());
+ BOOST_TEST(v[1].valid());
+ boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_any(v.begin(), v.end());
+ BOOST_TEST(! v[0].valid());
+ BOOST_TEST(! v[1].valid());
+ BOOST_TEST(all.valid());
+ boost::future<int> sum = all.then([](boost::future<boost::csbl::vector<boost::future<int> > > f)
+ {
+ boost::csbl::vector<boost::future<int> > v = f.get();
+ return v[0].get() + v[1].get();
+ });
+ BOOST_TEST(sum.valid());
+ BOOST_TEST(sum.get() == 444);
+ }
+#endif
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/when_any/none_pass.cpp b/src/boost/libs/thread/test/sync/futures/when_any/none_pass.cpp
new file mode 100644
index 000000000..2edd0bc6d
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/when_any/none_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// future<tuple<>> when_any();
+
+#include <boost/config.hpp>
+
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
+
+ {
+ boost::future<boost::csbl::tuple<> > all = boost::when_any();
+ BOOST_TEST(all.valid());
+ BOOST_TEST(all.is_ready());
+ }
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/when_any/one_pass.cpp b/src/boost/libs/thread/test/sync/futures/when_any/one_pass.cpp
new file mode 100644
index 000000000..61882ef6d
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/when_any/one_pass.cpp
@@ -0,0 +1,159 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// future<tuple<T>> when_any(T&&);
+
+#include <boost/config.hpp>
+
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+int p1()
+{
+ return 123;
+}
+
+int main()
+{
+#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
+ if (0) // todo not yet implemented
+ { // invalid future copy-constructible
+ boost::future<int> f1;
+ BOOST_TEST(! f1.valid());
+ boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_any(boost::move(f1));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ // has exception
+ //BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ }
+ { // is_ready future copy-constructible
+ boost::future<int> f1 = boost::make_ready_future(123);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(f1.is_ready());
+ boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_any(boost::move(f1));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(all.valid());
+ if (0) // todo FAILS not yet implemented
+ BOOST_TEST(all.is_ready());
+ boost::csbl::tuple<boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ }
+ { // is_ready shared_future copy-constructible
+ boost::shared_future<int> f1 = boost::make_ready_future(123).share();
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(f1.is_ready());
+ boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_any(f1);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(all.valid());
+ if (0) // todo FAILS not yet implemented
+ BOOST_TEST(all.is_ready());
+ boost::csbl::tuple<boost::shared_future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ }
+ { // packaged_task future copy-constructible
+ boost::packaged_task<int()> pt1(&p1);
+ boost::future<int> f1 = pt1.get_future();
+ BOOST_TEST(f1.valid());
+ boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_any(boost::move(f1));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(all.valid());
+ pt1();
+ boost::csbl::tuple<boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ }
+ { // packaged_task shared_future copy-constructible
+ boost::packaged_task<int()> pt1(&p1);
+ boost::shared_future<int> f1 = pt1.get_future().share();
+ BOOST_TEST(f1.valid());
+ boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_any(f1);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(all.valid());
+ pt1();
+ boost::csbl::tuple<boost::shared_future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ }
+ { // async future copy-constructible
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_any(boost::move(f1));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ }
+ { // async shared_future copy-constructible
+ boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
+ BOOST_TEST(f1.valid());
+ boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_any(f1);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::shared_future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ }
+#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD
+ // fixme darwin-4.8.0_11 terminate called without an active exception
+ { // deferred future copy-constructible
+ boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);
+ boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_any(boost::move(f1));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ }
+ // fixme darwin-4.8.0_11 terminate called without an active exception
+ { // deferred shared_future copy-constructible
+ boost::shared_future<int> f1 = boost::async(boost::launch::deferred, &p1).share();
+ boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_any(f1);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::shared_future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ }
+#endif
+#endif
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/futures/when_any/variadic_pass.cpp b/src/boost/libs/thread/test/sync/futures/when_any/variadic_pass.cpp
new file mode 100644
index 000000000..09b3951fc
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/futures/when_any/variadic_pass.cpp
@@ -0,0 +1,323 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/future.hpp>
+
+// template <class T, class Ts>
+// future<tuple<T, Ts...>> when_any(T&&, Ts&& ...);
+
+#include <boost/config.hpp>
+
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <stdexcept>
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+int p1()
+{
+ return 123;
+}
+
+int thr()
+{
+ throw std::logic_error("123");
+}
+int p2()
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
+ return 321;
+}
+
+int main()
+{
+#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
+ if (0) // todo not yet implemented
+ { // invalid future copy-constructible
+ boost::future<int> f1;
+ boost::future<int> f2 = boost::make_ready_future(321);
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(f2.valid());
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(! f2.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready());
+ // has exception
+ //BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ { // is_ready future copy-constructible
+ boost::future<int> f1 = boost::make_ready_future(123);
+ boost::future<int> f2 = boost::make_ready_future(321);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(f1.is_ready());
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(f2.is_ready());
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(! f2.valid());
+ BOOST_TEST(all.valid());
+ if (0) // todo FAILS not yet implemented
+ BOOST_TEST(all.is_ready());
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ { // is_ready shared_future copy-constructible
+ boost::shared_future<int> f1 = boost::make_ready_future(123).share();
+ boost::shared_future<int> f2 = boost::make_ready_future(321).share();
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(f1.is_ready());
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(f2.is_ready());
+ boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_any(f1, f2);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(all.valid());
+ if (0) // todo FAILS not yet implemented
+ BOOST_TEST(all.is_ready());
+ boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ { // packaged_task future copy-constructible
+ boost::packaged_task<int()> pt1(&p1);
+ boost::future<int> f1 = pt1.get_future();
+ BOOST_TEST(f1.valid());
+ boost::packaged_task<int()> pt2(&p2);
+ boost::future<int> f2 = pt2.get_future();
+ BOOST_TEST(f2.valid());
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(! f2.valid());
+ BOOST_TEST(all.valid());
+ pt1();
+ pt2();
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ { // packaged_task future copy-constructible
+ boost::packaged_task<int()> pt1(&thr);
+ boost::future<int> f1 = pt1.get_future();
+ BOOST_TEST(f1.valid());
+ boost::packaged_task<int()> pt2(&p2);
+ boost::future<int> f2 = pt2.get_future();
+ BOOST_TEST(f2.valid());
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(! f2.valid());
+ BOOST_TEST(all.valid());
+ pt1();
+ pt2();
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready());
+ try {
+ boost::csbl::get<0>(res).get();
+ BOOST_TEST(false);
+ } catch (std::logic_error& ex) {
+ BOOST_TEST(ex.what() == std::string("123"));
+ } catch (...) {
+ BOOST_TEST(false);
+ }
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ { // packaged_task shared_future copy-constructible
+ boost::packaged_task<int()> pt1(&p1);
+ boost::shared_future<int> f1 = pt1.get_future().share();
+ BOOST_TEST(f1.valid());
+ boost::packaged_task<int()> pt2(&p2);
+ boost::shared_future<int> f2 = pt2.get_future().share();
+ BOOST_TEST(f2.valid());
+ boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_any(f1, f2);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(all.valid());
+ BOOST_TEST(! all.is_ready());
+ pt1();
+ pt2();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(300));
+ BOOST_TEST(all.is_ready());
+ boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ { // async future copy-constructible
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<int> f2 = boost::async(boost::launch::async, &p2);
+ BOOST_TEST(f2.valid());
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(! f2.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ { // async shared_future copy-constructible
+ boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
+ BOOST_TEST(f1.valid());
+ boost::shared_future<int> f2 = boost::async(boost::launch::async, &p2).share();
+ BOOST_TEST(f2.valid());
+ boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_any(f1, f2);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ { // async future copy-constructible
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<int> f2 = boost::make_ready_future(321);
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(f2.is_ready());
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(! f2.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ //BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD
+ // fixme darwin-4.8.0_11 terminate called without an active exception
+ { // deferred future copy-constructible
+ boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);
+ boost::future<int> f2 = boost::async(boost::launch::deferred, &p2);
+ std::cout << __FILE__ << " " << __LINE__ << std::endl;
+
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2));
+ std::cout << __FILE__ << " " << __LINE__ << std::endl;
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(! f2.valid());
+ BOOST_TEST(all.valid());
+ std::cout << __FILE__ << " " << __LINE__ << std::endl;
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ std::cout << __FILE__ << " " << __LINE__ << std::endl;
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ // fixme darwin-4.8.0_11 terminate called without an active exception
+ { // deferred future copy-constructible
+ boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);
+ boost::future<int> f2 = boost::async(boost::launch::async, &p2);
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(! f2.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ //BOOST_TEST(! boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ // fixme darwin-4.8.0_11 terminate called without an active exception
+ { // deferred future copy-constructible
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ boost::future<int> f2 = boost::async(boost::launch::deferred, &p2);
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(! f2.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ //BOOST_TEST(boost::csbl::get<0>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+ // fixme darwin-4.8.0_11 terminate called without an active exception
+ { // deferred shared_future copy-constructible
+ boost::shared_future<int> f1 = boost::async(boost::launch::deferred, &p1).share();
+ boost::shared_future<int> f2 = boost::async(boost::launch::deferred, &p2).share();
+ boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_any(f1, f2);
+ BOOST_TEST(f1.valid());
+ BOOST_TEST(f2.valid());
+ BOOST_TEST(all.valid());
+ boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get();
+ BOOST_TEST(boost::csbl::get<0>(res).valid());
+ BOOST_TEST(boost::csbl::get<1>(res).valid());
+ BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready());
+ BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
+ BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
+ }
+#endif
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+ { // async futures copy-constructible then()
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<int> f2 = boost::async(boost::launch::async, &p2);
+ BOOST_TEST(f2.valid());
+ boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2));
+ BOOST_TEST(! f1.valid());
+ BOOST_TEST(! f2.valid());
+ BOOST_TEST(all.valid());
+ boost::future<int> sum = all.then([](boost::future<boost::csbl::tuple<boost::future<int>, boost::future<int> > > f)
+ {
+ boost::csbl::tuple<boost::future<int>,boost::future<int> > v = f.get();
+ return boost::csbl::get<0>(v).get()+boost::csbl::get<1>(v).get();
+ });
+ BOOST_TEST(sum.valid());
+ BOOST_TEST(sum.get() == 444);
+ }
+#endif
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/deque_views/single_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/deque_views/single_thread_pass.cpp
new file mode 100644
index 000000000..bd9ff152f
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/deque_views/single_thread_pass.cpp
@@ -0,0 +1,468 @@
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/sync_deque.hpp>
+
+// class sync_deque<T>
+
+// sync_deque();
+
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
+
+#include <boost/thread/concurrent_queues/sync_deque.hpp>
+#include <boost/thread/concurrent_queues/deque_adaptor.hpp>
+#include <boost/thread/concurrent_queues/deque_views.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+class non_copyable
+{
+ int val;
+public:
+ BOOST_THREAD_MOVABLE_ONLY(non_copyable)
+ non_copyable(int v) : val(v){}
+ non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {}
+ non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; }
+ bool operator==(non_copyable const& x) const {return val==x.val;}
+ template <typename OSTREAM>
+ friend OSTREAM& operator <<(OSTREAM& os, non_copyable const&x )
+ {
+ os << x.val;
+ return os;
+ }
+
+};
+
+#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
+BOOST_STATIC_ASSERT( ! boost::is_copy_constructible<non_copyable>::value );
+BOOST_STATIC_ASSERT( boost::has_move_emulation_enabled<non_copyable>::value );
+#endif
+
+int main()
+{
+
+ {
+ // default queue invariants
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_back<int> q(sq);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // default queue invariants
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_front<int> q(sq);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+
+
+ {
+ // empty queue try_pull fails
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_front<int> q(sq);
+ int i;
+ BOOST_TEST( boost::queue_op_status::empty == q.try_pull(i));
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push rvalue/copyable succeeds
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_back<int> q(sq);
+ q.push(1);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push lvalue/copyable succeeds
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_back<int> q(sq);
+ int i;
+ q.push(i);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+
+
+#if 0
+ {
+ // empty queue push rvalue/non_copyable succeeds
+ boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
+ boost::deque_back<non_copyable> q(sq);
+ q.push(non_copyable(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
+ {
+ // empty queue push rvalue/non_copyable succeeds
+ boost::deque_adaptor<boost::sync_deque<non_copyable> > q;
+ //boost::sync_deque<non_copyable> q;
+ //boost::deque_back<non_copyable> q(sq);
+ non_copyable nc(1);
+ q.push_back(boost::move(nc));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // empty queue push rvalue succeeds
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_back<int> q(sq);
+ q.push(1);
+ q.push(2);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 2u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push lvalue succeeds
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_back<int> q(sq);
+ int i;
+ q.push(i);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue/copyable succeeds
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_back<int> q(sq);
+ BOOST_TEST(boost::queue_op_status::success == q.try_push(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue/copyable succeeds
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_back<int> q(sq);
+ BOOST_TEST(boost::queue_op_status::success == q.try_push(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+
+#if 0
+ {
+ // empty queue try_push rvalue/non-copyable succeeds
+ boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
+ boost::deque_back<non_copyable> q(sq);
+ non_copyable nc(1);
+ BOOST_TEST(boost::queue_op_status::success == q.try_push(boost::move(nc)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+
+ {
+ // empty queue try_push lvalue succeeds
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_back<int> q(sq);
+ int i=0;
+ BOOST_TEST(boost::queue_op_status::success == q.try_push(i));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue succeeds
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_back<int> q(sq);
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+
+
+#if 0
+ {
+ // empty queue nonblocking_push_back rvalue/non-copyable succeeds
+ boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
+ boost::deque_back<non_copyable> q(sq);
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(non_copyable(1)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
+ {
+ // empty queue nonblocking_push_back rvalue/non-copyable succeeds
+ boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
+ boost::deque_back<non_copyable> q(sq);
+ non_copyable nc(1);
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(boost::move(nc)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // 1-element queue pull_front succeed
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_front<int> q(sq);
+ sq.push_back(1);
+ int i;
+ q.pull(i);
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
+ {
+ // 1-element queue pull_front succeed
+ boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
+ boost::deque_front<non_copyable> q(sq);
+ non_copyable nc1(1);
+ sq.push_back(boost::move(nc1));
+ non_copyable nc2(2);
+ q.pull(nc2);
+ BOOST_TEST_EQ(nc1, nc2);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // 1-element queue pull_front succeed
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_front<int> q(sq);
+ sq.push_back(1);
+ int i = q.pull();
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
+ {
+ // 1-element queue pull_front succeed
+ boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
+ boost::deque_front<non_copyable> q(sq);
+ non_copyable nc1(1);
+ sq.push_back(boost::move(nc1));
+ non_copyable nc = q.pull();
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // 1-element queue try_pull_front succeed
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_front<int> q(sq);
+ sq.push_back(1);
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.try_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
+ {
+ // 1-element queue try_pull_front succeed
+ boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
+ boost::deque_front<non_copyable> q(sq);
+ non_copyable nc1(1);
+ sq.push_back(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.try_pull(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+
+ {
+ // 1-element queue nonblocking_pull_front succeed
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_front<int> q(sq);
+ sq.push_back(1);
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
+ {
+ // 1-element queue nonblocking_pull_front succeed
+ boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
+ boost::deque_front<non_copyable> q(sq);
+ non_copyable nc1(1);
+ sq.push_back(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue wait_pull_front succeed
+ boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
+ boost::deque_front<non_copyable> q(sq);
+ non_copyable nc1(1);
+ sq.push_back(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // 1-element queue wait_pull_front succeed
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_front<int> q(sq);
+ sq.push_back(1);
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
+ {
+ // 1-element queue wait_pull_front succeed
+ boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
+ boost::deque_front<non_copyable> q(sq);
+ non_copyable nc1(1);
+ sq.push_back(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // closed invariants
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_back<int> q(sq);
+ q.close();
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed invariants
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_front<int> q(sq);
+ q.close();
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed queue push fails
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_back<int> q(sq);
+ q.close();
+ try {
+ q.push(1);
+ BOOST_TEST(false);
+ } catch (...) {
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ }
+ {
+ // 1-element closed queue pull succeed
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_front<int> q(sq);
+ sq.push_back(1);
+ q.close();
+ int i;
+ q.pull(i);
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // 1-element closed queue wait_pull_front succeed
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_front<int> q(sq);
+ sq.push_back(1);
+ q.close();
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed empty queue wait_pull_front fails
+ boost::deque_adaptor<boost::sync_deque<int> > sq;
+ boost::deque_front<int> q(sq);
+ q.close();
+ BOOST_TEST(q.empty());
+ BOOST_TEST(q.closed());
+ int i;
+ BOOST_TEST(boost::queue_op_status::closed == q.wait_pull(i));
+ BOOST_TEST(q.empty());
+ BOOST_TEST(q.closed());
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/adopt_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/adopt_lock_pass.cpp
new file mode 100644
index 000000000..b6039c556
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/adopt_lock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class lock_guard;
+
+// lock_guard(mutex_type& m, adopt_lock_t);
+
+#include <boost/thread/lock_guard.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../../timming.hpp"
+
+#ifdef BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#endif
+boost::mutex m;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#ifdef BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ {
+ m.lock();
+ boost::lock_guard<boost::mutex> lg(m, boost::adopt_lock);
+ t1 = Clock::now();
+ }
+#else
+ //time_point t0 = Clock::now();
+ //time_point t1;
+ {
+ m.lock();
+ boost::lock_guard<boost::mutex> lg(m, boost::adopt_lock);
+ //t1 = Clock::now();
+ }
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#ifdef BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_assign_fail.cpp
new file mode 100644
index 000000000..a3957c750
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_assign_fail.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class lock_guard;
+
+// lock_guard& operator=(lock_guard const&) = delete;
+
+#include <boost/thread/lock_guard.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ boost::lock_guard<boost::mutex> lk0(m0);
+ boost::lock_guard<boost::mutex> lk1(m1);
+ lk1 = lk0;
+
+}
+
+#include "../../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_ctor_fail.cpp
new file mode 100644
index 000000000..5c1b3a1c2
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_ctor_fail.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class lock_guard;
+
+// lock_guard(lock_guard const&) = delete;
+
+
+#include <boost/thread/lock_guard.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ boost::lock_guard<boost::mutex> lk0(m0);
+ boost::lock_guard<boost::mutex> lk1 = lk0;
+}
+
+#include "../../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/default_pass.cpp
new file mode 100644
index 000000000..4fcc26a9b
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/default_pass.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class lock_guard;
+
+// lock_guard(Mutex &);
+
+#include <boost/thread/lock_guard.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../../timming.hpp"
+
+#ifdef BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#endif
+
+boost::mutex m;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#ifdef BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ {
+ boost::lock_guard<boost::mutex> lg(m);
+ t1 = Clock::now();
+ }
+#else
+ //time_point t0 = Clock::now();
+ //time_point t1;
+ {
+ boost::lock_guard<boost::mutex> lg(m);
+ //t1 = Clock::now();
+ }
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#ifdef BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_adopt_lock_compile_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_adopt_lock_compile_fail.cpp
new file mode 100644
index 000000000..9aab78ddd
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_adopt_lock_compile_fail.cpp
@@ -0,0 +1,21 @@
+// Copyright (C) 2018 Tom Hughes
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/lock_guard.hpp>
+
+// template <class Mutex> class lock_guard;
+
+// lock_guard(Mutex& m_, adopt_lock_t)
+
+#include <boost/thread/lock_guard.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m;
+
+void fail()
+{
+ boost::lock_guard<boost::mutex> lk(m, boost::adopt_lock);
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_adopt_lock_compile_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_adopt_lock_compile_pass.cpp
new file mode 100644
index 000000000..a158677ad
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_adopt_lock_compile_pass.cpp
@@ -0,0 +1,22 @@
+// Copyright (C) 2018 Tom Hughes
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/lock_guard.hpp>
+
+// template <class Mutex> class lock_guard;
+
+// lock_guard(Mutex& m_, adopt_lock_t)
+
+#include <boost/thread/lock_guard.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m;
+
+void pass()
+{
+ m.lock();
+ boost::lock_guard<boost::mutex> lk(m, boost::adopt_lock);
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_compile_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_compile_fail.cpp
new file mode 100644
index 000000000..eead4501c
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_compile_fail.cpp
@@ -0,0 +1,22 @@
+// Copyright (C) 2018 Tom Hughes
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/lock_guard.hpp>
+
+// template <class Mutex> class lock_guard;
+
+// lock_guard(Mutex& m_)
+
+#include <boost/thread/lock_guard.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m;
+
+void fail()
+{
+ boost::lock_guard<boost::mutex> lk0(m);
+ boost::lock_guard<boost::mutex> lk1(m);
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_compile_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_compile_pass.cpp
new file mode 100644
index 000000000..aee2e40e4
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_compile_pass.cpp
@@ -0,0 +1,24 @@
+// Copyright (C) 2018 Tom Hughes
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/lock_guard.hpp>
+
+// template <class Mutex> class lock_guard;
+
+// lock_guard(Mutex& m_)
+
+#include <boost/thread/lock_guard.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m;
+
+void pass()
+{
+ {
+ boost::lock_guard<boost::mutex> lk0(m);
+ }
+ boost::lock_guard<boost::mutex> lk1(m);
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/make_lock_guard_adopt_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/make_lock_guard_adopt_lock_pass.cpp
new file mode 100644
index 000000000..cecdc84ce
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/make_lock_guard_adopt_lock_pass.cpp
@@ -0,0 +1,93 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/lock_guard.hpp>
+
+// template <class Lockable>
+// lock_guard<Lockable> make_lock_guard(Lockable &, adopt_lock_t);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/lock_guard.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../../timming.hpp"
+
+
+#ifdef BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#endif
+boost::mutex m;
+
+#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_THREAD_NO_MAKE_LOCK_GUARD
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#ifdef BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ {
+ m.lock();
+ auto&& lg = boost::make_lock_guard(m, boost::adopt_lock); (void)lg;
+
+ t1 = Clock::now();
+ }
+#else
+ //time_point t0 = Clock::now();
+ //time_point t1;
+ {
+ m.lock();
+ auto&& lg = boost::make_lock_guard(m, boost::adopt_lock); (void)lg;
+ //t1 = Clock::now();
+ }
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+#endif
+
+int main()
+{
+#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_THREAD_NO_MAKE_LOCK_GUARD
+ m.lock();
+ boost::thread t(f);
+#ifdef BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+#endif
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/make_lock_guard_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/make_lock_guard_pass.cpp
new file mode 100644
index 000000000..853fae743
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/make_lock_guard_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/lock_guard.hpp>
+
+// template <class Lockable>
+// lock_guard<Lockable> make_lock_guard(Lockable &);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/lock_guard.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../../timming.hpp"
+
+#ifdef BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#endif
+
+boost::mutex m;
+
+#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_THREAD_NO_MAKE_LOCK_GUARD && defined BOOST_THREAD_USES_CHRONO
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+ t0 = Clock::now();
+ {
+ const auto&& lg = boost::make_lock_guard(m); (void)lg;
+ t1 = Clock::now();
+ }
+}
+#endif
+
+int main()
+{
+
+#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_THREAD_NO_MAKE_LOCK_GUARD && defined BOOST_THREAD_USES_CHRONO
+ {
+ m.lock();
+ boost::thread t(f);
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+ m.unlock();
+ t.join();
+
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+ }
+#endif
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/types_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/types_pass.cpp
new file mode 100644
index 000000000..7c2d39375
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/types_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// <mutex>
+
+// template <class Mutex>
+// class lock_guard
+// {
+// public:
+// typedef Mutex mutex_type;
+// ...
+// };
+
+
+#include <boost/thread/lock_guard.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::lock_guard<boost::mutex>::mutex_type,
+ boost::mutex>::value), "");
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_assign_fail.cpp
new file mode 100644
index 000000000..c5d9a39b5
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_assign_fail.cpp
@@ -0,0 +1,31 @@
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class nested_strict_lock;
+
+// nested_strict_lock& operator=(nested_strict_lock const&) = delete;
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/strict_lock.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ boost::unique_lock<boost::mutex> lk0(m0);
+ boost::unique_lock<boost::mutex> lk1(m1);
+ boost::nested_strict_lock<boost::unique_lock<boost::mutex> > nlk0(lk0);
+ boost::nested_strict_lock<boost::unique_lock<boost::mutex> > nlk1(lk1);
+ lk1 = lk0;
+
+}
+
+#include "../../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_ctor_fail.cpp
new file mode 100644
index 000000000..1c0abf94a
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_ctor_fail.cpp
@@ -0,0 +1,28 @@
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class nested_strict_lock;
+
+// nested_strict_lock(nested_strict_lock const&) = delete;
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/strict_lock.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ boost::nested_strict_lock<boost::unique_lock<boost::mutex> > lk0(m0);
+ boost::nested_strict_lock<boost::unique_lock<boost::mutex> > lk1 = lk0;
+}
+
+#include "../../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/default_pass.cpp
new file mode 100644
index 000000000..0182bdd95
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/default_pass.cpp
@@ -0,0 +1,79 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class nested_strict_lock;
+
+// nested_strict_lock(Mutex &);
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/strict_lock.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../../timming.hpp"
+
+#ifdef BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#endif
+
+boost::mutex m;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#ifdef BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ boost::unique_lock<boost::mutex> lg(m);
+ {
+ boost::nested_strict_lock<boost::unique_lock<boost::mutex> > nlg(lg);
+ t1 = Clock::now();
+ }
+#else
+ //time_point t0 = Clock::now();
+ //time_point t1;
+ boost::unique_lock<boost::mutex> lg(m);
+ {
+ boost::nested_strict_lock<boost::unique_lock<boost::mutex> > nlg(lg);
+ //t1 = Clock::now();
+ }
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f);
+#ifdef BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp
new file mode 100644
index 000000000..5a10728cb
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp
@@ -0,0 +1,70 @@
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/strict_lock.hpp>
+
+// template <class Lockable>
+// strict_lock<Lockable> make_strict_lock(Lockable &);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/strict_lock.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../../timming.hpp"
+
+#ifdef BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#endif
+
+boost::mutex m;
+
+#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_THREAD_NO_MAKE_NESTED_STRICT_LOCK && defined BOOST_THREAD_USES_CHRONO
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+ t0 = Clock::now();
+ boost::unique_lock<boost::mutex> lg(m);
+ {
+ const auto&& nlg = boost::make_nested_strict_lock(lg); (void)nlg;
+ t1 = Clock::now();
+ }
+}
+#endif
+
+int main()
+{
+
+#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_THREAD_NO_MAKE_NESTED_STRICT_LOCK && defined BOOST_THREAD_USES_CHRONO
+ {
+ m.lock();
+ boost::thread t(f);
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+ m.unlock();
+ t.join();
+
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+ }
+#endif
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/owns_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/owns_lock_pass.cpp
new file mode 100644
index 000000000..be06b6a06
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/owns_lock_pass.cpp
@@ -0,0 +1,60 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class nested_strict_lock;
+
+// bool owns_lock(Mutex *) const;
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/strict_lock.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::mutex m;
+ boost::mutex m2;
+ {
+ boost::unique_lock<boost::mutex> lk(m);
+ {
+ boost::nested_strict_lock<boost::unique_lock<boost::mutex> > nlk(lk);
+ BOOST_TEST(nlk.owns_lock(&m) == true);
+ BOOST_TEST(!nlk.owns_lock(&m2) == true);
+ }
+ BOOST_TEST(lk.owns_lock() == true && lk.mutex()==&m);
+ }
+ {
+ m.lock();
+ boost::unique_lock<boost::mutex> lk(m, boost::adopt_lock);
+ {
+ boost::nested_strict_lock<boost::unique_lock<boost::mutex> > nlk(lk);
+ BOOST_TEST(nlk.owns_lock(&m) == true);
+ BOOST_TEST(!nlk.owns_lock(&m2) == true);
+ }
+ BOOST_TEST(lk.owns_lock() == true && lk.mutex()==&m);
+ }
+ {
+ boost::unique_lock<boost::mutex> lk(m, boost::defer_lock);
+ {
+ boost::nested_strict_lock<boost::unique_lock<boost::mutex> > nlk(lk);
+ BOOST_TEST(nlk.owns_lock(&m) == true);
+ BOOST_TEST(!nlk.owns_lock(&m2) == true);
+ }
+ BOOST_TEST(lk.owns_lock() == true && lk.mutex()==&m);
+ }
+ {
+ boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+ {
+ boost::nested_strict_lock<boost::unique_lock<boost::mutex> > nlk(lk);
+ BOOST_TEST(nlk.owns_lock(&m) == true);
+ BOOST_TEST(!nlk.owns_lock(&m2) == true);
+ }
+ BOOST_TEST(lk.owns_lock() == true && lk.mutex()==&m);
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/types_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/types_pass.cpp
new file mode 100644
index 000000000..5a7c690e4
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/types_pass.cpp
@@ -0,0 +1,35 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// <mutex>
+
+// template <class Lock>
+// class nested_strict_lock
+// {
+// public:
+// typedef typename Lock::mutex_type mutex_type;
+// ...
+// };
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/strict_lock.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::nested_strict_lock<boost::unique_lock<boost::mutex> >::mutex_type,
+ boost::mutex>::value), "");
+
+ BOOST_STATIC_ASSERT_MSG((boost::is_strict_lock<boost::nested_strict_lock<boost::unique_lock<boost::mutex> > >::value), "");
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_assign_fail.cpp
new file mode 100644
index 000000000..408e0f267
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_assign_fail.cpp
@@ -0,0 +1,33 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class reverse_lock;
+
+// reverse_lock& operator=(reverse_lock const&) = delete;
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/reverse_lock.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/lock_types.hpp>
+
+
+int main()
+{
+ boost::mutex m0;
+ boost::mutex m1;
+ boost::unique_lock<boost::mutex> lk0(m0);
+ boost::unique_lock<boost::mutex> lk1(m1);
+ {
+ boost::reverse_lock<boost::unique_lock<boost::mutex> > lg0(lk0);
+ boost::reverse_lock<boost::unique_lock<boost::mutex> > lg1(lk1);
+ lg1 = lg0;
+ }
+
+}
+
+#include "../../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_ctor_fail.cpp
new file mode 100644
index 000000000..c936c11b8
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_ctor_fail.cpp
@@ -0,0 +1,32 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class reverse_lock;
+
+// reverse_lock(reverse_lock const&) = delete;
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/reverse_lock.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/lock_types.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ boost::mutex m0;
+ boost::unique_lock<boost::mutex> lk0(m0);
+ {
+ boost::reverse_lock<boost::unique_lock<boost::mutex> > lg0(lk0);
+ boost::reverse_lock<boost::unique_lock<boost::mutex> > lg1(lg0);
+ }
+}
+
+#include "../../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/types_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/types_pass.cpp
new file mode 100644
index 000000000..13a17fd3a
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/types_pass.cpp
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// <mutex>
+
+// template <class Mutex>
+// class unlock_guard
+// {
+// public:
+// typedef Mutex mutex_type;
+// ...
+// };
+
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/reverse_lock.hpp>
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::reverse_lock<boost::unique_lock<boost::mutex> >::mutex_type,
+ boost::mutex>::value), "");
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/unique_lock_ctor_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/unique_lock_ctor_pass.cpp
new file mode 100644
index 000000000..57a1f1e01
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/unique_lock_ctor_pass.cpp
@@ -0,0 +1,52 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unlock_guard;
+
+// unlock_guard(unlock_guard const&) = delete;
+
+#include <boost/thread/reverse_lock.hpp>
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+int main()
+{
+ {
+ boost::mutex m;
+ boost::unique_lock<boost::mutex> lk(m);
+ BOOST_TEST(lk.owns_lock());
+ BOOST_TEST(lk.mutex()==&m);
+
+ {
+ boost::reverse_lock<boost::unique_lock<boost::mutex> > lg(lk);
+ BOOST_TEST(!lk.owns_lock());
+ BOOST_TEST(lk.mutex()==0);
+ }
+ BOOST_TEST(lk.owns_lock());
+ BOOST_TEST(lk.mutex()==&m);
+ }
+
+ {
+ boost::mutex m;
+ boost::unique_lock<boost::mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(! lk.owns_lock());
+ BOOST_TEST(lk.mutex()==&m);
+ {
+ boost::reverse_lock<boost::unique_lock<boost::mutex> > lg(lk);
+ BOOST_TEST(!lk.owns_lock());
+ BOOST_TEST(lk.mutex()==0);
+ }
+ BOOST_TEST(lk.owns_lock());
+ BOOST_TEST(lk.mutex()==&m);
+ }
+
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/adopt_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/adopt_lock_pass.cpp
new file mode 100644
index 000000000..f9089e7a8
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/adopt_lock_pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock(mutex_type& m, adopt_lock_t);
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+int main()
+{
+ boost::shared_mutex m;
+ m.lock_shared();
+ boost::shared_lock<boost::shared_mutex> lk(m, boost::adopt_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_assign_fail.cpp
new file mode 100644
index 000000000..2bc99f34b
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_assign_fail.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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock& operator=(shared_lock const&) = delete;
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m0;
+boost::shared_mutex m1;
+
+int main()
+{
+ boost::shared_lock<boost::shared_mutex> lk0(m0);
+ boost::shared_lock<boost::shared_mutex> lk1(m1);
+ lk1 = lk0;
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+
+}
+
+#include "../../../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_ctor_fail.cpp
new file mode 100644
index 000000000..43fddebe8
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_ctor_fail.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock(shared_lock const&) = delete;
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m0;
+boost::shared_mutex m1;
+
+int main()
+{
+ boost::shared_lock<boost::shared_mutex> lk0(m0);
+ boost::shared_lock<boost::shared_mutex> lk1 = lk0;
+ BOOST_TEST(lk1.mutex() == &m1);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+}
+
+#include "../../../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/default_pass.cpp
new file mode 100644
index 000000000..9ccae93b7
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/default_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock(shared_lock const&) = delete;
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::shared_lock<boost::shared_mutex> ul;
+ BOOST_TEST(!ul.owns_lock());
+ BOOST_TEST(ul.mutex() == 0);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/defer_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/defer_lock_pass.cpp
new file mode 100644
index 000000000..84388aca4
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/defer_lock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock(mutex_type& m, adopt_lock_t);
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::shared_mutex m;
+ m.lock();
+ boost::shared_lock<boost::shared_mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/duration_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/duration_pass.cpp
new file mode 100644
index 000000000..45037c224
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/duration_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// template <class Rep, class Period>
+// shared_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/chrono/chrono_io.hpp>
+#include "../../../../../timming.hpp"
+
+boost::shared_mutex m;
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f1()
+{
+ t0 = Clock::now();
+ boost::shared_lock<boost::shared_mutex> lk(m, ms(750));
+ BOOST_TEST(lk.owns_lock() == true);
+ t1 = Clock::now();
+}
+
+void f2()
+{
+ t0 = Clock::now();
+ boost::shared_lock<boost::shared_mutex> lk(m, ms(250));
+ BOOST_TEST(lk.owns_lock() == false);
+ t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+ m.unlock();
+ t.join();
+
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(750));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_assign_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_assign_pass.cpp
new file mode 100644
index 000000000..ef54e229f
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_assign_pass.cpp
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_mutex.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock(shared_lock const&) = delete;
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m0;
+boost::shared_mutex m1;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m0);
+ boost::shared_lock<boost::shared_mutex> lk1(m1);
+ lk1 = boost::move(lk0);
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+
+ boost::shared_lock<boost::shared_mutex> lk1;
+ lk1 = BOOST_THREAD_MAKE_RV_REF(boost::shared_lock<boost::shared_mutex>(m0));
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ }
+ {
+ boost::unique_lock<boost::shared_mutex> lk0(m0);
+ boost::shared_lock<boost::shared_mutex> lk1(m1);
+ lk1 = BOOST_THREAD_MAKE_RV_REF(boost::shared_lock<boost::shared_mutex>(boost::move(lk0)));
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+
+ boost::shared_lock<boost::shared_mutex> lk1;
+ lk1 = BOOST_THREAD_MAKE_RV_REF(boost::shared_lock<boost::shared_mutex>(boost::unique_lock<boost::shared_mutex>(m0)));
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk0(m0);
+ boost::shared_lock<boost::shared_mutex> lk1(m1);
+ lk1 = BOOST_THREAD_MAKE_RV_REF(boost::shared_lock<boost::shared_mutex>(boost::move(lk0)));
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+
+ boost::shared_lock<boost::shared_mutex> lk1;
+ lk1 = BOOST_THREAD_MAKE_RV_REF(boost::shared_lock<boost::shared_mutex>(boost::upgrade_lock<boost::shared_mutex>(m0)));
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ }
+ return boost::report_errors();
+
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_pass.cpp
new file mode 100644
index 000000000..307c76142
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock& operator=(shared_lock&& u);
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk( (BOOST_THREAD_MAKE_RV_REF(boost::shared_lock<boost::shared_mutex>(m))));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_unique_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_unique_lock_pass.cpp
new file mode 100644
index 000000000..38f6e7d7d
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_unique_lock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock& operator=(shared_lock&& u);
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+
+ {
+ boost::unique_lock<boost::shared_mutex> lk0(m);
+ boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk( (boost::unique_lock<boost::shared_mutex>(m)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::unique_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_upgrade_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_upgrade_lock_pass.cpp
new file mode 100644
index 000000000..36ecb6a5a
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_upgrade_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock& operator=(shared_lock&& u);
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk0(m);
+ boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk( (boost::upgrade_lock<boost::shared_mutex>(m)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/mutex_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/mutex_pass.cpp
new file mode 100644
index 000000000..f50aa6199
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/mutex_pass.cpp
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// explicit shared_lock(Mutex& m);
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../../../timming.hpp"
+
+boost::shared_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ {
+ boost::shared_lock<boost::shared_mutex> ul(m);
+ t1 = Clock::now();
+ }
+#else
+ //time_point t0 = Clock::now();
+ //time_point t1;
+ {
+ boost::shared_lock<boost::shared_mutex> ul(m);
+ //t1 = Clock::now();
+ }
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/time_point_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/time_point_pass.cpp
new file mode 100644
index 000000000..41d9cd8f9
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/time_point_pass.cpp
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// template <class Clock, class Duration>
+// shared_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../../../timming.hpp"
+
+boost::shared_mutex m;
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f1()
+{
+ t0 = Clock::now();
+ boost::shared_lock<boost::shared_mutex> lk(m, Clock::now() + ms(750));
+ BOOST_TEST(lk.owns_lock() == true);
+ t1 = Clock::now();
+}
+
+void f2()
+{
+ t0 = Clock::now();
+ boost::shared_lock<boost::shared_mutex> lk(m, Clock::now() + ms(250));
+ BOOST_TEST(lk.owns_lock() == false);
+ t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+ m.unlock();
+ t.join();
+
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(750));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/try_to_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/try_to_lock_pass.cpp
new file mode 100644
index 000000000..5f3036c0c
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/try_to_lock_pass.cpp
@@ -0,0 +1,115 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// shared_lock(mutex_type& m, try_to_lock_t);
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../../../timming.hpp"
+
+boost::shared_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ {
+ boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ }
+ for (;;)
+ {
+ boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ if (lk.owns_lock()) {
+ t1 = Clock::now();
+ break;
+ }
+ }
+#else
+// time_point t0 = Clock::now();
+// {
+// boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+// {
+// boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+// {
+// boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+ for (;;)
+ {
+ boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ if (lk.owns_lock()) break;
+ }
+ //time_point t1 = Clock::now();
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/lock_pass.cpp
new file mode 100644
index 000000000..456c26dfd
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/lock_pass.cpp
@@ -0,0 +1,126 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// void lock();
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include "../../../../../timming.hpp"
+
+boost::shared_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::shared_lock < boost::shared_mutex > lk(m, boost::defer_lock);
+ t0 = Clock::now();
+ lk.lock();
+ t1 = Clock::now();
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ lk.release();
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+#else
+ boost::shared_lock < boost::shared_mutex > lk(m, boost::defer_lock);
+ //time_point t0 = Clock::now();
+ lk.lock();
+ //time_point t1 = Clock::now();
+ BOOST_TEST(lk.owns_lock() == true);
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ lk.release();
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_for_pass.cpp
new file mode 100644
index 000000000..07d32df39
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_for_pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/lock_types.hpp>
+//#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+bool try_lock_for_called = false;
+
+typedef boost::chrono::milliseconds ms;
+
+struct shared_mutex
+{
+ template <class Rep, class Period>
+ bool try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
+ {
+ BOOST_TEST(rel_time == ms(5));
+ try_lock_for_called = !try_lock_for_called;
+ return try_lock_for_called;
+ }
+ void unlock_shared()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::shared_lock<shared_mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.try_lock_for(ms(5)) == true);
+ BOOST_TEST(try_lock_for_called == true);
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock_for(ms(5));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ BOOST_TEST(lk.try_lock_for(ms(5)) == false);
+ BOOST_TEST(try_lock_for_called == false);
+ BOOST_TEST(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock_for(ms(5));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_pass.cpp
new file mode 100644
index 000000000..6a1997238
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/lock_types.hpp>
+//#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+bool try_lock_called = false;
+
+struct shared_mutex
+{
+ bool try_lock_shared()
+ {
+ try_lock_called = !try_lock_called;
+ return try_lock_called;
+ }
+ void unlock_shared()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::shared_lock<shared_mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.try_lock() == true);
+ BOOST_TEST(try_lock_called == true);
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ BOOST_TEST(lk.try_lock() == false);
+ BOOST_TEST(try_lock_called == false);
+ BOOST_TEST(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_until_pass.cpp
new file mode 100644
index 000000000..cdfd0e161
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_until_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// template <class Clock, class Duration>
+// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+bool try_lock_until_called = false;
+
+struct shared_mutex
+{
+ template <class Clock, class Duration>
+ bool try_lock_shared_until(const boost::chrono::time_point<Clock, Duration>& abs_time)
+ {
+ typedef boost::chrono::milliseconds ms;
+ BOOST_TEST(Clock::now() - abs_time < ms(5));
+ try_lock_until_called = !try_lock_until_called;
+ return try_lock_until_called;
+ }
+ void unlock_shared()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ typedef boost::chrono::steady_clock Clock;
+ boost::shared_lock<shared_mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.try_lock_until(Clock::now()) == true);
+ BOOST_TEST(try_lock_until_called == true);
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock_until(Clock::now());
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ BOOST_TEST(lk.try_lock_until(Clock::now()) == false);
+ BOOST_TEST(try_lock_until_called == false);
+ BOOST_TEST(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock_until(Clock::now());
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/unlock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/unlock_pass.cpp
new file mode 100644
index 000000000..e8ed7c74c
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/unlock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/lock_types.hpp>
+//#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+bool unlock_called = false;
+
+struct shared_mutex
+{
+ void lock_shared()
+ {
+ }
+ void unlock_shared()
+ {
+ unlock_called = true;
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::shared_lock<shared_mutex> lk(m);
+ lk.unlock();
+ BOOST_TEST(unlock_called == true);
+ BOOST_TEST(lk.owns_lock() == false);
+ try
+ {
+ lk.unlock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+ lk.release();
+ try
+ {
+ lk.unlock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/member_swap_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/member_swap_pass.cpp
new file mode 100644
index 000000000..11f366bd6
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/member_swap_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// void swap(shared_lock& u);
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct shared_mutex
+{
+ void lock_shared()
+ {
+ }
+ void unlock_shared()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::shared_lock<shared_mutex> lk1(m);
+ boost::shared_lock<shared_mutex> lk2;
+ lk1.swap(lk2);
+ BOOST_TEST(lk1.mutex() == 0);
+ BOOST_TEST(lk1.owns_lock() == false);
+ BOOST_TEST(lk2.mutex() == &m);
+ BOOST_TEST(lk2.owns_lock() == true);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/non_member_swap_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/non_member_swap_pass.cpp
new file mode 100644
index 000000000..c0ccb8b9d
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/non_member_swap_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex>
+// void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y);
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct shared_mutex
+{
+ void lock_shared()
+ {
+ }
+ void unlock_shared()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::shared_lock<shared_mutex> lk1(m);
+ boost::shared_lock<shared_mutex> lk2;
+ swap(lk1, lk2);
+ BOOST_TEST(lk1.mutex() == 0);
+ BOOST_TEST(lk1.owns_lock() == false);
+ BOOST_TEST(lk2.mutex() == &m);
+ BOOST_TEST(lk2.owns_lock() == true);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/release_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/release_pass.cpp
new file mode 100644
index 000000000..c39ca50aa
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/release_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// void Mutex* release();
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct shared_mutex
+{
+ static int lock_count;
+ static int unlock_count;
+ void lock_shared()
+ {
+ ++lock_count;
+ }
+ void unlock_shared()
+ {
+ ++unlock_count;
+ }
+};
+
+int shared_mutex::lock_count = 0;
+int shared_mutex::unlock_count = 0;
+
+shared_mutex m;
+
+int main()
+{
+ boost::shared_lock<shared_mutex> lk(m);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(shared_mutex::lock_count == 1);
+ BOOST_TEST(shared_mutex::unlock_count == 0);
+ BOOST_TEST(lk.release() == &m);
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(shared_mutex::lock_count == 1);
+ BOOST_TEST(shared_mutex::unlock_count == 0);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/mutex_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/mutex_pass.cpp
new file mode 100644
index 000000000..2012186ae
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// Mutex *mutex() const;
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ boost::shared_lock<boost::shared_mutex> lk0;
+ BOOST_TEST(lk0.mutex() == 0);
+ boost::shared_lock<boost::shared_mutex> lk1(m);
+ BOOST_TEST(lk1.mutex() == &m);
+ lk1.unlock();
+ BOOST_TEST(lk1.mutex() == &m);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/op_bool_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/op_bool_pass.cpp
new file mode 100644
index 000000000..407bfcc6f
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// explicit operator bool() const;
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ boost::shared_lock < boost::shared_mutex > lk0;
+ BOOST_TEST(bool(lk0) == false);
+ boost::shared_lock < boost::shared_mutex > lk1(m);
+ BOOST_TEST(bool(lk1) == true);
+ lk1.unlock();
+ BOOST_TEST(bool(lk1) == false);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/owns_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/owns_lock_pass.cpp
new file mode 100644
index 000000000..dce14d3e9
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/owns_lock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class shared_lock;
+
+// bool owns_lock() const;
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ boost::shared_lock<boost::shared_mutex> lk0;
+ BOOST_TEST(lk0.owns_lock() == false);
+ boost::shared_lock<boost::shared_mutex> lk1(m);
+ BOOST_TEST(lk1.owns_lock() == true);
+ lk1.unlock();
+ BOOST_TEST(lk1.owns_lock() == false);
+
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/types_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/types_pass.cpp
new file mode 100644
index 000000000..2f83ef98f
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/types_pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// <mutex>
+
+// template <class Mutex>
+// class shared_lock
+// {
+// public:
+// typedef Mutex mutex_type;
+// ...
+// };
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::shared_lock<boost::shared_mutex>::mutex_type,
+ boost::shared_mutex>::value), "");
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/adopt_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/adopt_lock_pass.cpp
new file mode 100644
index 000000000..fe125e8a0
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/adopt_lock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_lock_guard.hpp>
+
+// template <class Mutex> class shared_lock_guard;
+
+// shared_lock_guard(mutex_type& m, adopt_lock_t);
+
+#include <boost/thread/shared_lock_guard.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+boost::shared_mutex m;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ {
+ m.lock_shared();
+ boost::shared_lock_guard<boost::shared_mutex> lg(m, boost::adopt_lock);
+ t1 = Clock::now();
+ }
+#else
+ //time_point t0 = Clock::now();
+ //time_point t1;
+ {
+ m.lock_shared();
+ boost::shared_lock_guard<boost::shared_mutex> lg(m, boost::adopt_lock);
+ //t1 = Clock::now();
+ }
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_assign_fail.cpp
new file mode 100644
index 000000000..43607ac26
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_assign_fail.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_lock_guard.hpp>
+
+// template <class Mutex> class shared_lock_guard;
+
+// shared_lock_guard& operator=(shared_lock_guard const&) = delete;
+
+#include <boost/thread/shared_lock_guard.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m0;
+boost::shared_mutex m1;
+
+int main()
+{
+ boost::shared_lock_guard<boost::shared_mutex> lk0(m0);
+ boost::shared_lock_guard<boost::shared_mutex> lk1(m1);
+ lk1 = lk0;
+
+}
+
+#include "../../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_ctor_fail.cpp
new file mode 100644
index 000000000..a7d4f006d
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_ctor_fail.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_lock_guard.hpp>
+
+// template <class Mutex> class shared_lock_guard;
+
+// shared_lock_guard(shared_lock_guard const&) = delete;
+
+
+#include <boost/thread/shared_lock_guard.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m0;
+boost::shared_mutex m1;
+
+int main()
+{
+ boost::shared_lock_guard<boost::shared_mutex> lk0(m0);
+ boost::shared_lock_guard<boost::shared_mutex> lk1 = lk0;
+}
+
+#include "../../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/default_pass.cpp
new file mode 100644
index 000000000..694ba4a14
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/default_pass.cpp
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_lock_guard.hpp>
+
+// template <class Mutex> class shared_lock_guard;
+
+// shared_lock_guard(shared_lock_guard const&) = delete;
+
+#include <boost/thread/shared_lock_guard.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include "../../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+boost::shared_mutex m;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ {
+ boost::shared_lock_guard<boost::shared_mutex> lg(m);
+ t1 = Clock::now();
+ }
+#else
+ //time_point t0 = Clock::now();
+ //time_point t1;
+ {
+ boost::shared_lock_guard<boost::shared_mutex> lg(m);
+ //t1 = Clock::now();
+ }
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/types_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/types_pass.cpp
new file mode 100644
index 000000000..57a2116d1
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/types_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_lock_guard.hpp>
+
+// <mutex>
+
+// template <class Mutex>
+// class shared_lock_guard
+// {
+// public:
+// typedef Mutex mutex_type;
+// ...
+// };
+
+
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/shared_lock_guard.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::shared_lock_guard<boost::shared_mutex>::mutex_type,
+ boost::shared_mutex>::value), "");
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/copy_assign_fail.cpp
new file mode 100644
index 000000000..1852224bb
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/copy_assign_fail.cpp
@@ -0,0 +1,28 @@
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class strict_lock;
+
+// strict_lock& operator=(strict_lock const&) = delete;
+
+#include <boost/thread/strict_lock.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ boost::strict_lock<boost::mutex> lk0(m0);
+ boost::strict_lock<boost::mutex> lk1(m1);
+ lk1 = lk0;
+
+}
+
+#include "../../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/copy_ctor_fail.cpp
new file mode 100644
index 000000000..331610cb1
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/copy_ctor_fail.cpp
@@ -0,0 +1,27 @@
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class strict_lock;
+
+// strict_lock(strict_lock const&) = delete;
+
+
+#include <boost/thread/strict_lock.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ boost::strict_lock<boost::mutex> lk0(m0);
+ boost::strict_lock<boost::mutex> lk1 = lk0;
+}
+
+#include "../../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/default_pass.cpp
new file mode 100644
index 000000000..aa2fb0071
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/default_pass.cpp
@@ -0,0 +1,74 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class strict_lock;
+
+// strict_lock(Mutex &);
+
+#include <boost/thread/strict_lock.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../../timming.hpp"
+
+#ifdef BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#endif
+
+boost::mutex m;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#ifdef BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ {
+ boost::strict_lock<boost::mutex> lg(m);
+ t1 = Clock::now();
+ }
+#else
+ //time_point t0 = Clock::now();
+ //time_point t1;
+ {
+ boost::strict_lock<boost::mutex> lg(m);
+ //t1 = Clock::now();
+ }
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#ifdef BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp
new file mode 100644
index 000000000..c5a3069f0
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp
@@ -0,0 +1,70 @@
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/strict_lock.hpp>
+
+// template <class Lockable>
+// strict_lock<Lockable> make_strict_lock(Lockable &);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/strict_lock.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../../timming.hpp"
+
+#ifdef BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#endif
+
+boost::mutex m;
+
+#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_THREAD_NO_MAKE_STRICT_LOCK && defined BOOST_THREAD_USES_CHRONO
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+ t0 = Clock::now();
+ {
+ const auto&& lg = boost::make_strict_lock(m); (void)lg;
+ t1 = Clock::now();
+ }
+ ns d = t1 - t0 - ms(250);
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+}
+#endif
+
+int main()
+{
+
+#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_THREAD_NO_MAKE_STRICT_LOCK && defined BOOST_THREAD_USES_CHRONO
+ {
+ m.lock();
+ boost::thread t(f);
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+ m.unlock();
+ t.join();
+
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+ }
+#endif
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/owns_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/owns_lock_pass.cpp
new file mode 100644
index 000000000..c0c2ec861
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/owns_lock_pass.cpp
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class strict_lock;
+
+// bool owns_lock(Mutex *) const;
+
+#include <boost/thread/strict_lock.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#ifdef BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#endif
+
+int main()
+{
+ boost::mutex m;
+ boost::mutex m2;
+
+ boost::strict_lock<boost::mutex> lk(m);
+ BOOST_TEST(lk.owns_lock(&m) == true);
+ BOOST_TEST(!lk.owns_lock(&m2) == true);
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/types_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/types_pass.cpp
new file mode 100644
index 000000000..f813e5ca8
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/types_pass.cpp
@@ -0,0 +1,34 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// <mutex>
+
+// template <class Mutex>
+// class strict_lock
+// {
+// public:
+// typedef Mutex mutex_type;
+// ...
+// };
+
+
+#include <boost/thread/strict_lock.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::strict_lock<boost::mutex>::mutex_type,
+ boost::mutex>::value), "");
+
+ BOOST_STATIC_ASSERT_MSG((boost::is_strict_lock<boost::strict_lock<boost::mutex> >::value), "");
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/adopt_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/adopt_lock_pass.cpp
new file mode 100644
index 000000000..42d33378e
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/adopt_lock_pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(mutex_type& m, adopt_lock_t);
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+int main()
+{
+ boost::mutex m;
+ m.lock();
+ boost::unique_lock<boost::mutex> lk(m, boost::adopt_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_assign_fail.cpp
new file mode 100644
index 000000000..d69a1eec7
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_assign_fail.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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock& operator=(unique_lock const&) = delete;
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ boost::unique_lock<boost::mutex> lk0(m0);
+ boost::unique_lock<boost::mutex> lk1(m1);
+ lk1 = lk0;
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+
+}
+
+#include "../../../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_ctor_fail.cpp
new file mode 100644
index 000000000..08fc3c344
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_ctor_fail.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(unique_lock const&) = delete;
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ boost::unique_lock<boost::mutex> lk0(m0);
+ boost::unique_lock<boost::mutex> lk1 = lk0;
+ BOOST_TEST(lk1.mutex() == &m1);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+}
+
+#include "../../../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/default_pass.cpp
new file mode 100644
index 000000000..7989b8173
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/default_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(unique_lock const&) = delete;
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::unique_lock<boost::mutex> ul;
+ BOOST_TEST(!ul.owns_lock());
+ BOOST_TEST(ul.mutex() == 0);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/defer_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/defer_lock_pass.cpp
new file mode 100644
index 000000000..5045af26e
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/defer_lock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(mutex_type& m, adopt_lock_t);
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::mutex m;
+ boost::unique_lock<boost::mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/duration_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/duration_pass.cpp
new file mode 100644
index 000000000..19aa0575f
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/duration_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Rep, class Period>
+// unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
+
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/chrono/chrono_io.hpp>
+#include "../../../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+boost::timed_mutex m;
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f1()
+{
+ t0 = Clock::now();
+ boost::unique_lock<boost::timed_mutex> lk(m, ms(750));
+ BOOST_TEST(lk.owns_lock() == true);
+ t1 = Clock::now();
+}
+
+void f2()
+{
+ t0 = Clock::now();
+ boost::unique_lock<boost::timed_mutex> lk(m, ms(250));
+ BOOST_TEST(lk.owns_lock() == false);
+ t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+ m.unlock();
+ t.join();
+
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(750));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_adopt_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_adopt_lock_pass.cpp
new file mode 100644
index 000000000..2f385ec87
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_adopt_lock_pass.cpp
@@ -0,0 +1,31 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/lock_factories.hpp>
+
+// template <class Mutex> class unique_lock;
+// unique_lock<Mutex> make_unique_lock(Mutex&, adopt_lock_t);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/lock_factories.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::mutex m;
+ m.lock();
+#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
+ auto
+#else
+ boost::unique_lock<boost::mutex>
+#endif
+ lk = boost::make_unique_lock(m, boost::adopt_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_defer_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_defer_lock_pass.cpp
new file mode 100644
index 000000000..e32fad168
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_defer_lock_pass.cpp
@@ -0,0 +1,32 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/lock_factories.hpp>
+
+// template <class Mutex> class unique_lock;
+// unique_lock<Mutex> make_unique_lock(Mutex&, defer_lock_t);
+
+// unique_lock(mutex_type& m, adopt_lock_t);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/lock_factories.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::mutex m;
+#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
+ auto
+#else
+ boost::unique_lock<boost::mutex>
+#endif
+ lk = boost::make_unique_lock(m, boost::defer_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_mutex_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_mutex_pass.cpp
new file mode 100644
index 000000000..97b625564
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_mutex_pass.cpp
@@ -0,0 +1,100 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/lock_factories.hpp>
+
+// template <class Mutex>
+// unique_lock<Mutex> make_unique_lock(Mutex&);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/thread/lock_factories.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../../../timming.hpp"
+
+//#if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+boost::mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ {
+#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
+ auto
+#else
+ boost::unique_lock<boost::mutex>
+#endif
+ //&&
+ _ = boost::make_unique_lock(m); (void)_;
+ t1 = Clock::now();
+ }
+#else
+ //time_point t0 = Clock::now();
+ //time_point t1;
+ {
+#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
+ auto
+#else
+ boost::unique_lock<boost::mutex>
+#endif
+ //&&
+ _ = boost::make_unique_lock(m); (void)_;
+ //t1 = Clock::now();
+ }
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+//#else
+//int main()
+//{
+// return boost::report_errors();
+//}
+//#endif
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_try_to_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_try_to_lock_pass.cpp
new file mode 100644
index 000000000..d0149d906
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_try_to_lock_pass.cpp
@@ -0,0 +1,146 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+// unique_lock<Mutex> make_unique_lock(Mutex&, try_to_lock_t);
+
+#define BOOST_THREAD_VERSION 4
+
+
+#include <boost/thread/lock_factories.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../../../timming.hpp"
+
+boost::mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ {
+ t0 = Clock::now();
+#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
+ auto
+#else
+ boost::unique_lock<boost::mutex>
+#endif
+ lk = boost::make_unique_lock(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ t1 = Clock::now();
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ }
+ {
+ t0 = Clock::now();
+#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
+ auto
+#else
+ boost::unique_lock<boost::mutex>
+#endif
+ lk = boost::make_unique_lock(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ t1 = Clock::now();
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ }
+ {
+ t0 = Clock::now();
+#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
+ auto
+#else
+ boost::unique_lock<boost::mutex>
+#endif
+ lk = boost::make_unique_lock(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ t1 = Clock::now();
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ }
+ {
+ t0 = Clock::now();
+ for (;;)
+ {
+#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
+ auto
+#else
+ boost::unique_lock<boost::mutex>
+#endif
+ lk = boost::make_unique_lock(m, boost::try_to_lock);
+ if (lk.owns_lock()) {
+ t1 = Clock::now();
+ break;
+ }
+ }
+ }
+#else
+// time_point t0 = Clock::now();
+// {
+// boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+// {
+// boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+// {
+// boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+ for (;;)
+ {
+#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
+ auto
+#else
+ boost::unique_lock<boost::mutex>
+#endif
+ lk = boost::make_unique_lock(m, boost::try_to_lock);
+ if (lk.owns_lock()) break;
+ }
+ //time_point t1 = Clock::now();
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_locks_mutex_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_locks_mutex_pass.cpp
new file mode 100644
index 000000000..72c574b20
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_locks_mutex_pass.cpp
@@ -0,0 +1,94 @@
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/lock_factories.hpp>
+
+// template <class Mutex>
+// unique_lock<Mutex> make_unique_lock(Mutex&);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/lock_factories.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../../../timming.hpp"
+
+#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && ! defined BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS && ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+
+boost::mutex m1;
+boost::mutex m2;
+boost::mutex m3;
+
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ {
+ auto&& _ = boost::make_unique_locks(m1,m2,m3); (void)_;
+ t1 = Clock::now();
+ }
+#else
+ //time_point t0 = Clock::now();
+ //time_point t1;
+ {
+ auto&& _ = boost::make_unique_locks(m1,m2,m3); (void)_;
+ //t1 = Clock::now();
+ }
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m1.lock();
+ m2.lock();
+ m3.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m1.unlock();
+ m2.unlock();
+ m3.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+#else
+int main()
+{
+ return boost::report_errors();
+}
+#endif
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_assign_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_assign_pass.cpp
new file mode 100644
index 000000000..7c84d1520
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_assign_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(unique_lock const&) = delete;
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m0;
+boost::mutex m1;
+
+int main()
+{
+ {
+ boost::unique_lock<boost::mutex> lk0(m0);
+ boost::unique_lock<boost::mutex> lk1(m1);
+ lk1 = boost::move(lk0);
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+
+ {
+
+ boost::unique_lock<boost::mutex> lk1;
+ lk1 = BOOST_THREAD_MAKE_RV_REF(boost::unique_lock<boost::mutex>(m0));
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ }
+ return boost::report_errors();
+
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_pass.cpp
new file mode 100644
index 000000000..cf682fbd4
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(unique_lock&& u);
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m;
+
+int main()
+{
+ {
+ boost::unique_lock<boost::mutex> lk0(m);
+ boost::unique_lock<boost::mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::mutex> lk( (BOOST_THREAD_MAKE_RV_REF(boost::unique_lock<boost::mutex>(m))));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::unique_lock<boost::mutex> lk0(m, boost::defer_lock);
+ boost::unique_lock<boost::mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::unique_lock<boost::mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp
new file mode 100644
index 000000000..0e61cb1a7
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Rep, class Period>
+// unique_lock(shared_lock<mutex_type>&&,
+// const chrono::duration<Rep, Period>&);
+
+#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::shared_mutex>
+ lk(boost::shared_lock<boost::shared_mutex>(m), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp
new file mode 100644
index 000000000..3068866f0
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(shared_lock&& u, try_to_lock);
+
+#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock );
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::shared_mutex> lk(boost::shared_lock<boost::shared_mutex>(m), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp
new file mode 100644
index 000000000..f1e54cf45
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Clock, class Duration>
+// unique_lock(shared_lock<mutex_type>&&,
+// const chrono::time_point<Clock, Duration>&);
+
+#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::unique_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::shared_mutex>
+ lk( boost::shared_lock<boost::shared_mutex>(m), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::unique_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::unique_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_for_pass.cpp
new file mode 100644
index 000000000..7437ee0e7
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Clock, class Duration>
+// unique_lock(shared_lock<mutex_type>&&,
+// const chrono::duration<Rep, Period>&);
+
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::upgrade_mutex m;
+
+int main()
+{
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m);
+ boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::upgrade_mutex>
+ lk(boost::upgrade_lock<boost::upgrade_mutex>(m), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
+ boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_pass.cpp
new file mode 100644
index 000000000..c72067ae9
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(upgrade_lock&& u);
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::upgrade_mutex m;
+
+int main()
+{
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m);
+ boost::unique_lock<boost::upgrade_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::upgrade_mutex> lk( (BOOST_THREAD_MAKE_RV_REF(boost::upgrade_lock<boost::upgrade_mutex>(m))));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
+ boost::unique_lock<boost::upgrade_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::unique_lock<boost::upgrade_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_try_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_try_pass.cpp
new file mode 100644
index 000000000..fdbdf2165
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_try_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(upgrade_lock&& u, try_to_lock);
+
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::upgrade_mutex m;
+
+int main()
+{
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m);
+ boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::try_to_lock );
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::upgrade_mutex> lk(boost::upgrade_lock<boost::upgrade_mutex>(m), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
+ boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_until_pass.cpp
new file mode 100644
index 000000000..cd33f709c
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Clock, class Duration>
+// unique_lock(shared_lock<mutex_type>&&,
+// const chrono::time_point<Clock, Duration>&);
+
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::upgrade_mutex m;
+
+int main()
+{
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m);
+ boost::unique_lock<boost::upgrade_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::upgrade_mutex>
+ lk( boost::upgrade_lock<boost::upgrade_mutex>(m), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
+ boost::unique_lock<boost::upgrade_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::unique_lock<boost::upgrade_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/mutex_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/mutex_pass.cpp
new file mode 100644
index 000000000..d5b7ca295
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/mutex_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// explicit unique_lock(Mutex& m);
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include "../../../../../timming.hpp"
+
+
+boost::mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ {
+ boost::unique_lock<boost::mutex> ul(m);
+ t1 = Clock::now();
+ }
+#else
+ //time_point t0 = Clock::now();
+ //time_point t1;
+ {
+ boost::unique_lock<boost::mutex> ul(m);
+ //t1 = Clock::now();
+ }
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/time_point_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/time_point_pass.cpp
new file mode 100644
index 000000000..53358de6e
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/time_point_pass.cpp
@@ -0,0 +1,93 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Clock, class Duration>
+// unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
+
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+boost::timed_mutex m;
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f1()
+{
+ t0 = Clock::now();
+ boost::unique_lock<boost::timed_mutex> lk(m, Clock::now() + ms(750));
+ BOOST_TEST(lk.owns_lock() == true);
+ t1 = Clock::now();
+}
+
+void f2()
+{
+ t0 = Clock::now();
+ boost::unique_lock<boost::timed_mutex> lk(m, Clock::now() + ms(250));
+ BOOST_TEST(lk.owns_lock() == false);
+ t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ BOOST_TEST(d < max_diff);
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+ m.unlock();
+ t.join();
+
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(750));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/try_to_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/try_to_lock_pass.cpp
new file mode 100644
index 000000000..0f0c8ded4
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/try_to_lock_pass.cpp
@@ -0,0 +1,120 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// unique_lock(mutex_type& m, try_to_lock_t);
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../../../timming.hpp"
+
+
+boost::mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ {
+ boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ }
+ {
+ boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ }
+ for (;;)
+ {
+ boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+ if (lk.owns_lock()) {
+ t1 = Clock::now();
+ break;
+ }
+ }
+ //m.unlock();
+#else
+// time_point t0 = Clock::now();
+// {
+// boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+// {
+// boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+// {
+// boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+ for (;;)
+ {
+ boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock);
+ if (lk.owns_lock()) break;
+ }
+ //time_point t1 = Clock::now();
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ std::cout << "d_ns: " << d_ns.count() << std::endl;
+ std::cout << "d_ms: " << d_ms.count() << std::endl;
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/lock_pass.cpp
new file mode 100644
index 000000000..94edb4342
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/lock_pass.cpp
@@ -0,0 +1,127 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// void lock();
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include "../../../../../timming.hpp"
+
+boost::mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::unique_lock < boost::mutex > lk(m, boost::defer_lock);
+ t0 = Clock::now();
+ lk.lock();
+ t1 = Clock::now();
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ lk.release();
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+#else
+ boost::unique_lock < boost::mutex > lk(m, boost::defer_lock);
+ //time_point t0 = Clock::now();
+ lk.lock();
+ //time_point t1 = Clock::now();
+ BOOST_TEST(lk.owns_lock() == true);
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ lk.release();
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_for_pass.cpp
new file mode 100644
index 000000000..2be8416eb
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_for_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/lock_types.hpp>
+//#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+
+bool try_lock_for_called = false;
+
+typedef boost::chrono::milliseconds ms;
+
+struct mutex
+{
+ template <class Rep, class Period>
+ bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time)
+ {
+ BOOST_TEST(rel_time == ms(5));
+ try_lock_for_called = !try_lock_for_called;
+ return try_lock_for_called;
+ }
+ void unlock()
+ {
+ }
+};
+
+mutex m;
+
+int main()
+{
+ boost::unique_lock<mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.try_lock_for(ms(5)) == true);
+ BOOST_TEST(try_lock_for_called == true);
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock_for(ms(5));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ BOOST_TEST(lk.try_lock_for(ms(5)) == false);
+ BOOST_TEST(try_lock_for_called == false);
+ BOOST_TEST(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock_for(ms(5));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_pass.cpp
new file mode 100644
index 000000000..8553c1c0b
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/lock_types.hpp>
+//#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+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()
+{
+ boost::unique_lock<mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.try_lock() == true);
+ BOOST_TEST(try_lock_called == true);
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ BOOST_TEST(lk.try_lock() == false);
+ BOOST_TEST(try_lock_called == false);
+ BOOST_TEST(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_until_pass.cpp
new file mode 100644
index 000000000..df6e7369e
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_until_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// template <class Clock, class Duration>
+// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+
+bool try_lock_until_called = false;
+
+struct mutex
+{
+ template <class Clock, class Duration>
+ bool try_lock_until(const boost::chrono::time_point<Clock, Duration>& abs_time)
+ {
+ typedef boost::chrono::milliseconds ms;
+ BOOST_TEST(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 boost::chrono::steady_clock Clock;
+ boost::unique_lock<mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.try_lock_until(Clock::now()) == true);
+ BOOST_TEST(try_lock_until_called == true);
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock_until(Clock::now());
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ BOOST_TEST(lk.try_lock_until(Clock::now()) == false);
+ BOOST_TEST(try_lock_until_called == false);
+ BOOST_TEST(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock_until(Clock::now());
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/unlock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/unlock_pass.cpp
new file mode 100644
index 000000000..4ad954f24
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/unlock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// bool unlock();
+
+#include <boost/thread/lock_types.hpp>
+//#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+bool unlock_called = false;
+
+struct mutex
+{
+ void lock()
+ {
+ }
+ void unlock()
+ {
+ unlock_called = true;
+ }
+};
+
+mutex m;
+
+int main()
+{
+ boost::unique_lock<mutex> lk(m);
+ lk.unlock();
+ BOOST_TEST(unlock_called == true);
+ BOOST_TEST(lk.owns_lock() == false);
+ try
+ {
+ lk.unlock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+ lk.release();
+ try
+ {
+ lk.unlock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/member_swap_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/member_swap_pass.cpp
new file mode 100644
index 000000000..617682fe3
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/member_swap_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// void swap(unique_lock& u);
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct mutex
+{
+ void lock()
+ {
+ }
+ void unlock()
+ {
+ }
+};
+
+mutex m;
+
+int main()
+{
+ boost::unique_lock<mutex> lk1(m);
+ boost::unique_lock<mutex> lk2;
+ lk1.swap(lk2);
+ BOOST_TEST(lk1.mutex() == 0);
+ BOOST_TEST(lk1.owns_lock() == false);
+ BOOST_TEST(lk2.mutex() == &m);
+ BOOST_TEST(lk2.owns_lock() == true);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/non_member_swap_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/non_member_swap_pass.cpp
new file mode 100644
index 000000000..74ba5ff3f
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/non_member_swap_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex>
+// void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y);
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct mutex
+{
+ void lock()
+ {
+ }
+ void unlock()
+ {
+ }
+};
+
+mutex m;
+
+int main()
+{
+ boost::unique_lock<mutex> lk1(m);
+ boost::unique_lock<mutex> lk2;
+ swap(lk1, lk2);
+ BOOST_TEST(lk1.mutex() == 0);
+ BOOST_TEST(lk1.owns_lock() == false);
+ BOOST_TEST(lk2.mutex() == &m);
+ BOOST_TEST(lk2.owns_lock() == true);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/release_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/release_pass.cpp
new file mode 100644
index 000000000..63c3831e5
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/release_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// void Mutex* release();
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+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()
+{
+ boost::unique_lock<mutex> lk(m);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(mutex::lock_count == 1);
+ BOOST_TEST(mutex::unlock_count == 0);
+ BOOST_TEST(lk.release() == &m);
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(mutex::lock_count == 1);
+ BOOST_TEST(mutex::unlock_count == 0);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/mutex_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/mutex_pass.cpp
new file mode 100644
index 000000000..68f1bbb6d
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// Mutex *mutex() const;
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m;
+
+int main()
+{
+ boost::unique_lock<boost::mutex> lk0;
+ BOOST_TEST(lk0.mutex() == 0);
+ boost::unique_lock<boost::mutex> lk1(m);
+ BOOST_TEST(lk1.mutex() == &m);
+ lk1.unlock();
+ BOOST_TEST(lk1.mutex() == &m);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_bool_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_bool_pass.cpp
new file mode 100644
index 000000000..3fa18225a
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_bool_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// explicit operator bool() const;
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m;
+
+int main()
+{
+ {
+ boost::unique_lock<boost::mutex> lk0;
+ BOOST_TEST(bool(lk0) == false);
+ boost::unique_lock<boost::mutex> lk1(m);
+ BOOST_TEST(bool(lk1) == true);
+ lk1.unlock();
+ BOOST_TEST(bool(lk1) == false);
+ }
+
+ {
+ boost::unique_lock<boost::mutex> lk0;
+ if (lk0) BOOST_TEST(false);
+ boost::unique_lock<boost::mutex> lk1(m);
+ if (!lk1) BOOST_TEST(false);
+ lk1.unlock();
+ if (lk1) BOOST_TEST(false);
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_int_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_int_fail.cpp
new file mode 100644
index 000000000..92fe0ffcb
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_int_fail.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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// explicit operator bool() const;
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::mutex m;
+
+int main()
+{
+ {
+ boost::unique_lock<boost::mutex> lk0;
+ int i = int(lk0);
+ BOOST_TEST(i == 0);
+ }
+
+ return boost::report_errors();
+}
+
+#include "../../../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/owns_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/owns_lock_pass.cpp
new file mode 100644
index 000000000..6a9f019aa
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/owns_lock_pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class unique_lock;
+
+// bool owns_lock() const;
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+int main()
+{
+ boost::mutex m;
+
+ boost::unique_lock<boost::mutex> lk0;
+ BOOST_TEST(lk0.owns_lock() == false);
+ boost::unique_lock<boost::mutex> lk1(m);
+ BOOST_TEST(lk1.owns_lock() == true);
+ lk1.unlock();
+ BOOST_TEST(lk1.owns_lock() == false);
+
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/types_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/types_pass.cpp
new file mode 100644
index 000000000..69b963a6f
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/types_pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// <mutex>
+
+// template <class Mutex>
+// class unique_lock
+// {
+// public:
+// typedef Mutex mutex_type;
+// ...
+// };
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::unique_lock<boost::mutex>::mutex_type,
+ boost::mutex>::value), "");
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/adopt_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/adopt_lock_pass.cpp
new file mode 100644
index 000000000..1822fe0b6
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/adopt_lock_pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock(mutex_type& m, adopt_lock_t);
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+int main()
+{
+ boost::shared_mutex m;
+ m.lock_upgrade();
+ boost::upgrade_lock<boost::shared_mutex> lk(m, boost::adopt_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_assign_fail.cpp
new file mode 100644
index 000000000..521304d81
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_assign_fail.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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock& operator=(upgrade_lock const&) = delete;
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m0;
+boost::shared_mutex m1;
+
+int main()
+{
+ boost::upgrade_lock<boost::shared_mutex> lk0(m0);
+ boost::upgrade_lock<boost::shared_mutex> lk1(m1);
+ lk1 = lk0;
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+
+}
+
+#include "../../../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_ctor_fail.cpp
new file mode 100644
index 000000000..8e20196b1
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_ctor_fail.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock(upgrade_lock const&) = delete;
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m0;
+boost::shared_mutex m1;
+
+int main()
+{
+ boost::upgrade_lock<boost::shared_mutex> lk0(m0);
+ boost::upgrade_lock<boost::shared_mutex> lk1(lk0);
+ BOOST_TEST(lk1.mutex() == &m1);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+}
+
+#include "../../../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/default_pass.cpp
new file mode 100644
index 000000000..59ea2a9a2
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/default_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock(upgrade_lock const&) = delete;
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::upgrade_lock<boost::shared_mutex> ul;
+ BOOST_TEST(!ul.owns_lock());
+ BOOST_TEST(ul.mutex() == 0);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/defer_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/defer_lock_pass.cpp
new file mode 100644
index 000000000..ececb845c
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/defer_lock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock(mutex_type& m, adopt_lock_t);
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::shared_mutex m;
+ m.lock();
+ boost::upgrade_lock<boost::shared_mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/duration_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/duration_pass.cpp
new file mode 100644
index 000000000..b6506b9b3
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/duration_pass.cpp
@@ -0,0 +1,89 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// template <class Rep, class Period>
+// upgrade_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
+
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/chrono/chrono_io.hpp>
+#include "../../../../../timming.hpp"
+
+boost::shared_mutex m;
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f1()
+{
+ t0 = Clock::now();
+ boost::upgrade_lock<boost::shared_mutex> lk(m, ms(750));
+ BOOST_TEST(lk.owns_lock() == true);
+ t1 = Clock::now();
+}
+
+void f2()
+{
+ t0 = Clock::now();
+ boost::upgrade_lock<boost::shared_mutex> lk(m, ms(250));
+ BOOST_TEST(lk.owns_lock() == false);
+ t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+ m.unlock();
+ t.join();
+
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(750));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_assign_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_assign_pass.cpp
new file mode 100644
index 000000000..42ef355c9
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_assign_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_mutex.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock(upgrade_lock const&) = delete;
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m0;
+boost::shared_mutex m1;
+
+int main()
+{
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk0(m0);
+ boost::upgrade_lock<boost::shared_mutex> lk1(m1);
+ lk1 = boost::move(lk0);
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+
+ boost::upgrade_lock<boost::shared_mutex> lk1;
+ lk1 = BOOST_THREAD_MAKE_RV_REF(boost::upgrade_lock<boost::shared_mutex>(m0));
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ }
+ {
+ boost::unique_lock<boost::shared_mutex> lk0(m0);
+ boost::upgrade_lock<boost::shared_mutex> lk1(m1);
+ lk1 = BOOST_THREAD_MAKE_RV_REF(boost::upgrade_lock<boost::shared_mutex>(boost::move(lk0)));
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+
+ boost::upgrade_lock<boost::shared_mutex> lk1;
+ lk1 = BOOST_THREAD_MAKE_RV_REF(boost::upgrade_lock<boost::shared_mutex>(boost::unique_lock<boost::shared_mutex>(m0)));
+ BOOST_TEST(lk1.mutex() == &m0);
+ BOOST_TEST(lk1.owns_lock() == true);
+ }
+ return boost::report_errors();
+
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_pass.cpp
new file mode 100644
index 000000000..5d5c0a948
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock& operator=(upgrade_lock&& u);
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk0(m);
+ boost::upgrade_lock<boost::shared_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk( (BOOST_THREAD_MAKE_RV_REF(boost::upgrade_lock<boost::shared_mutex>(m))));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp
new file mode 100644
index 000000000..ccad7b1ac
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// template <class Clock, class Duration>
+// upgrade_lock(shared_lock<mutex_type>&&,
+// const chrono::duration<Rep, Period>&);
+
+#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex>
+ lk(boost::shared_lock<boost::shared_mutex>(m), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp
new file mode 100644
index 000000000..93deda8c3
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock(shared_lock&& u, try_to_lock);
+
+#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock );
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::shared_lock<boost::shared_mutex>(m), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock);
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp
new file mode 100644
index 000000000..3d2c2871b
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// template <class Clock, class Duration>
+// upgrade_lock(shared_lock<mutex_type>&&,
+// const chrono::time_point<Clock, Duration>&);
+
+#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m);
+ boost::upgrade_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex>
+ lk( boost::shared_lock<boost::shared_mutex>(m), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ boost::upgrade_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock);
+ lk0.release();
+ boost::upgrade_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1));
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_unique_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_unique_lock_pass.cpp
new file mode 100644
index 000000000..3d591d176
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_unique_lock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock& operator=(unique_lock&& u);
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ {
+ boost::unique_lock<boost::shared_mutex> lk0(m);
+ boost::upgrade_lock<boost::shared_mutex> lk( (boost::move(lk0)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(lk0.mutex() == 0);
+ BOOST_TEST(lk0.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk( (boost::unique_lock<boost::shared_mutex>(m)));
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/mutex_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/mutex_pass.cpp
new file mode 100644
index 000000000..1e634807d
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/mutex_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// explicit upgrade_lock(Mutex& m);
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include "../../../../../timming.hpp"
+
+boost::shared_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ {
+ boost::upgrade_lock<boost::shared_mutex> ul(m);
+ t1 = Clock::now();
+ }
+#else
+ //time_point t0 = Clock::now();
+ //time_point t1;
+ {
+ boost::upgrade_lock<boost::shared_mutex> ul(m);
+ //t1 = Clock::now();
+ }
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/time_point_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/time_point_pass.cpp
new file mode 100644
index 000000000..4cf71476b
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/time_point_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// template <class Clock, class Duration>
+// upgrade_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
+
+#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../../../timming.hpp"
+
+boost::shared_mutex m;
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f1()
+{
+ t0 = Clock::now();
+ boost::upgrade_lock<boost::shared_mutex> lk(m, Clock::now() + ms(750));
+ BOOST_TEST(lk.owns_lock() == true);
+ t1 = Clock::now();
+}
+
+void f2()
+{
+ t0 = Clock::now();
+ boost::upgrade_lock<boost::shared_mutex> lk(m, Clock::now() + ms(250));
+ BOOST_TEST(lk.owns_lock() == false);
+ t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+ m.unlock();
+ t.join();
+
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(750));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/try_to_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/try_to_lock_pass.cpp
new file mode 100644
index 000000000..9a7fe26bf
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/try_to_lock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// upgrade_lock(mutex_type& m, try_to_lock_t);
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../../../timming.hpp"
+
+boost::shared_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ }
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ BOOST_TEST(lk.owns_lock() == false);
+ }
+ for (;;)
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ if (lk.owns_lock()) {
+ t1 = Clock::now();
+ break;
+ }
+ }
+ //m.unlock();
+#else
+// time_point t0 = Clock::now();
+// {
+// boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+// {
+// boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+// {
+// boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+// BOOST_TEST(lk.owns_lock() == false);
+// }
+ for (;;)
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock);
+ if (lk.owns_lock()) break;
+ }
+ //time_point t1 = Clock::now();
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/lock_pass.cpp
new file mode 100644
index 000000000..2ff49ac96
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/lock_pass.cpp
@@ -0,0 +1,126 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// void lock();
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include "../../../../../timming.hpp"
+
+boost::shared_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::upgrade_lock < boost::shared_mutex > lk(m, boost::defer_lock);
+ t0 = Clock::now();
+ lk.lock();
+ t1 = Clock::now();
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ lk.release();
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+#else
+ boost::upgrade_lock < boost::shared_mutex > lk(m, boost::defer_lock);
+ //time_point t0 = Clock::now();
+ lk.lock();
+ //time_point t1 = Clock::now();
+ BOOST_TEST(lk.owns_lock() == true);
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ lk.release();
+ try
+ {
+ lk.lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_for_pass.cpp
new file mode 100644
index 000000000..5f8f4f5fe
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_for_pass.cpp
@@ -0,0 +1,78 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/lock_types.hpp>
+//#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+bool try_lock_for_called = false;
+
+typedef boost::chrono::milliseconds ms;
+
+struct shared_mutex
+{
+ template <class Rep, class Period>
+ bool try_lock_upgrade_for(const boost::chrono::duration<Rep, Period>& rel_time)
+ {
+ BOOST_TEST(rel_time == ms(5));
+ try_lock_for_called = !try_lock_for_called;
+ return try_lock_for_called;
+ }
+ void unlock_upgrade()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::upgrade_lock<shared_mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.try_lock_for(ms(5)) == true);
+ BOOST_TEST(try_lock_for_called == true);
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock_for(ms(5));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ BOOST_TEST(lk.try_lock_for(ms(5)) == false);
+ BOOST_TEST(try_lock_for_called == false);
+ BOOST_TEST(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock_for(ms(5));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_pass.cpp
new file mode 100644
index 000000000..820fd71a3
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/lock_types.hpp>
+//#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+bool try_lock_called = false;
+
+struct shared_mutex
+{
+ bool try_lock_upgrade()
+ {
+ try_lock_called = !try_lock_called;
+ return try_lock_called;
+ }
+ void unlock_upgrade()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::upgrade_lock<shared_mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.try_lock() == true);
+ BOOST_TEST(try_lock_called == true);
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ BOOST_TEST(lk.try_lock() == false);
+ BOOST_TEST(try_lock_called == false);
+ BOOST_TEST(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_until_pass.cpp
new file mode 100644
index 000000000..1c53d6a5b
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_until_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// template <class Clock, class Duration>
+// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+bool try_lock_until_called = false;
+
+struct shared_mutex
+{
+ template <class Clock, class Duration>
+ bool try_lock_upgrade_until(const boost::chrono::time_point<Clock, Duration>& abs_time)
+ {
+ typedef boost::chrono::milliseconds ms;
+ BOOST_TEST(Clock::now() - abs_time < ms(5));
+ try_lock_until_called = !try_lock_until_called;
+ return try_lock_until_called;
+ }
+ void unlock_upgrade()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ typedef boost::chrono::steady_clock Clock;
+ boost::upgrade_lock<shared_mutex> lk(m, boost::defer_lock);
+ BOOST_TEST(lk.try_lock_until(Clock::now()) == true);
+ BOOST_TEST(try_lock_until_called == true);
+ BOOST_TEST(lk.owns_lock() == true);
+ try
+ {
+ lk.try_lock_until(Clock::now());
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ lk.unlock();
+ BOOST_TEST(lk.try_lock_until(Clock::now()) == false);
+ BOOST_TEST(try_lock_until_called == false);
+ BOOST_TEST(lk.owns_lock() == false);
+ lk.release();
+ try
+ {
+ lk.try_lock_until(Clock::now());
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/unlock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/unlock_pass.cpp
new file mode 100644
index 000000000..bc49a0433
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/unlock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/lock_types.hpp>
+//#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+bool unlock_called = false;
+
+struct shared_mutex
+{
+ void lock_upgrade()
+ {
+ }
+ void unlock_upgrade()
+ {
+ unlock_called = true;
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::upgrade_lock<shared_mutex> lk(m);
+ lk.unlock();
+ BOOST_TEST(unlock_called == true);
+ BOOST_TEST(lk.owns_lock() == false);
+ try
+ {
+ lk.unlock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+ lk.release();
+ try
+ {
+ lk.unlock();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/member_swap_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/member_swap_pass.cpp
new file mode 100644
index 000000000..4b0752ef5
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/member_swap_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// void swap(upgrade_lock& u);
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct shared_mutex
+{
+ void lock_upgrade()
+ {
+ }
+ void unlock_upgrade()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::upgrade_lock<shared_mutex> lk1(m);
+ boost::upgrade_lock<shared_mutex> lk2;
+ lk1.swap(lk2);
+ BOOST_TEST(lk1.mutex() == 0);
+ BOOST_TEST(lk1.owns_lock() == false);
+ BOOST_TEST(lk2.mutex() == &m);
+ BOOST_TEST(lk2.owns_lock() == true);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/non_member_swap_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/non_member_swap_pass.cpp
new file mode 100644
index 000000000..c7ebaa271
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/non_member_swap_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex>
+// void swap(upgrade_lock<Mutex>& x, upgrade_lock<Mutex>& y);
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct shared_mutex
+{
+ void lock_upgrade()
+ {
+ }
+ void unlock_upgrade()
+ {
+ }
+};
+
+shared_mutex m;
+
+int main()
+{
+ boost::upgrade_lock<shared_mutex> lk1(m);
+ boost::upgrade_lock<shared_mutex> lk2;
+ swap(lk1, lk2);
+ BOOST_TEST(lk1.mutex() == 0);
+ BOOST_TEST(lk1.owns_lock() == false);
+ BOOST_TEST(lk2.mutex() == &m);
+ BOOST_TEST(lk2.owns_lock() == true);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/release_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/release_pass.cpp
new file mode 100644
index 000000000..226819446
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/release_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// void Mutex* release();
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct shared_mutex
+{
+ static int lock_count;
+ static int unlock_count;
+ void lock_upgrade()
+ {
+ ++lock_count;
+ }
+ void unlock_upgrade()
+ {
+ ++unlock_count;
+ }
+};
+
+int shared_mutex::lock_count = 0;
+int shared_mutex::unlock_count = 0;
+
+shared_mutex m;
+
+int main()
+{
+ boost::upgrade_lock<shared_mutex> lk(m);
+ BOOST_TEST(lk.mutex() == &m);
+ BOOST_TEST(lk.owns_lock() == true);
+ BOOST_TEST(shared_mutex::lock_count == 1);
+ BOOST_TEST(shared_mutex::unlock_count == 0);
+ BOOST_TEST(lk.release() == &m);
+ BOOST_TEST(lk.mutex() == 0);
+ BOOST_TEST(lk.owns_lock() == false);
+ BOOST_TEST(shared_mutex::lock_count == 1);
+ BOOST_TEST(shared_mutex::unlock_count == 0);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/mutex_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/mutex_pass.cpp
new file mode 100644
index 000000000..276cd0a93
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// Mutex *mutex() const;
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ boost::upgrade_lock<boost::shared_mutex> lk0;
+ BOOST_TEST(lk0.mutex() == 0);
+ boost::upgrade_lock<boost::shared_mutex> lk1(m);
+ BOOST_TEST(lk1.mutex() == &m);
+ lk1.unlock();
+ BOOST_TEST(lk1.mutex() == &m);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/op_bool_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/op_bool_pass.cpp
new file mode 100644
index 000000000..4e722d174
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// explicit operator bool() const;
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ boost::upgrade_lock < boost::shared_mutex > lk0;
+ BOOST_TEST(bool(lk0) == false);
+ boost::upgrade_lock < boost::shared_mutex > lk1(m);
+ BOOST_TEST(bool(lk1) == true);
+ lk1.unlock();
+ BOOST_TEST(bool(lk1) == false);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/owns_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/owns_lock_pass.cpp
new file mode 100644
index 000000000..9d8b80d69
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/owns_lock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/locks.hpp>
+
+// template <class Mutex> class upgrade_lock;
+
+// bool owns_lock() const;
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+boost::shared_mutex m;
+
+int main()
+{
+ boost::upgrade_lock<boost::shared_mutex> lk0;
+ BOOST_TEST(lk0.owns_lock() == false);
+ boost::upgrade_lock<boost::shared_mutex> lk1(m);
+ BOOST_TEST(lk1.owns_lock() == true);
+ lk1.unlock();
+ BOOST_TEST(lk1.owns_lock() == false);
+
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/types_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/types_pass.cpp
new file mode 100644
index 000000000..876428e46
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/types_pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// <mutex>
+
+// template <class Mutex>
+// class upgrade_lock
+// {
+// public:
+// typedef Mutex mutex_type;
+// ...
+// };
+
+
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::upgrade_lock<boost::upgrade_mutex>::mutex_type,
+ boost::upgrade_mutex>::value), "");
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/assign_fail.cpp
new file mode 100644
index 000000000..fa1aff9b5
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// class mutex;
+
+// mutex& operator=(const mutex&) = delete;
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::mutex m0;
+ boost::mutex m1(m0);
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/copy_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/copy_fail.cpp
new file mode 100644
index 000000000..e6f6d6b88
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/copy_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// class mutex;
+
+// mutex(const mutex&) = delete;
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::mutex m0;
+ boost::mutex m1(m0);
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/default_pass.cpp
new file mode 100644
index 000000000..a911eefcf
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/default_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// class mutex;
+
+// mutex();
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::mutex m0;
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_compile_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_compile_fail.cpp
new file mode 100644
index 000000000..f6bf74b56
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_compile_fail.cpp
@@ -0,0 +1,19 @@
+// Copyright (C) 2017 Tom Hughes
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// class mutex;
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+void fail()
+{
+ boost::mutex m0;
+ m0.lock();
+ m0.lock();
+ m0.unlock();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_compile_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_compile_pass.cpp
new file mode 100644
index 000000000..9da22a59d
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_compile_pass.cpp
@@ -0,0 +1,18 @@
+// Copyright (C) 2017 Tom Hughes
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// class mutex;
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+void pass()
+{
+ boost::mutex m0;
+ m0.lock();
+ m0.unlock();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_pass.cpp
new file mode 100644
index 000000000..94818fbad
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_pass.cpp
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// class mutex;
+
+// void lock();
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+boost::mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ m.lock();
+ t1 = Clock::now();
+ m.unlock();
+#else
+ //time_point t0 = Clock::now();
+ m.lock();
+ //time_point t1 = Clock::now();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/native_handle_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/native_handle_pass.cpp
new file mode 100644
index 000000000..489ec375d
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/native_handle_pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// class mutex;
+
+// typedef pthread_mutex_t* native_handle_type;
+// native_handle_type native_handle();
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+#if defined BOOST_THREAD_DEFINES_MUTEX_NATIVE_HANDLE
+ boost::mutex m;
+ boost::mutex::native_handle_type h = m.native_handle();
+ BOOST_TEST(h);
+#else
+#error "Test not applicable: BOOST_THREAD_DEFINES_MUTEX_NATIVE_HANDLE not defined for this platform as not supported"
+#endif
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_compile_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_compile_fail.cpp
new file mode 100644
index 000000000..05c2016cb
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_compile_fail.cpp
@@ -0,0 +1,19 @@
+// Copyright (C) 2017 Tom Hughes
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// class mutex;
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+void fail()
+{
+ boost::mutex m0;
+ if (!m0.try_lock()) {
+ m0.unlock();
+ }
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_compile_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_compile_pass.cpp
new file mode 100644
index 000000000..e4cec906a
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_compile_pass.cpp
@@ -0,0 +1,19 @@
+// Copyright (C) 2017 Tom Hughes
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// class mutex;
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+void pass()
+{
+ boost::mutex m0;
+ if (m0.try_lock()) {
+ m0.unlock();
+ }
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_pass.cpp
new file mode 100644
index 000000000..b973c1b23
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/mutex.hpp>
+
+// class mutex;
+
+// bool try_lock();
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+
+boost::mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ BOOST_TEST(!m.try_lock());
+ BOOST_TEST(!m.try_lock());
+ BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ t1 = Clock::now();
+ m.unlock();
+#else
+ //time_point t0 = Clock::now();
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ //time_point t1 = Clock::now();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/assign_fail.cpp
new file mode 100644
index 000000000..e8b440abd
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/assign_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/null_mutex.hpp>
+
+// class null_mutex;
+
+// null_mutex& operator=(const null_mutex&) = delete;
+
+#include <boost/thread/null_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::null_mutex m0;
+ boost::null_mutex m1(m0);
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/copy_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/copy_fail.cpp
new file mode 100644
index 000000000..66668f5e0
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/copy_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/null_mutex.hpp>
+
+// class null_mutex;
+
+// null_mutex(const null_mutex&) = delete;
+
+#include <boost/thread/null_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::null_mutex m0;
+ boost::null_mutex m1(m0);
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/default_pass.cpp
new file mode 100644
index 000000000..343431a9e
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/default_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/null_mutex.hpp>
+
+// class null_mutex;
+
+// null_mutex();
+
+#include <boost/thread/null_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::null_mutex m0;
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/lock_pass.cpp
new file mode 100644
index 000000000..3c91e25f6
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/lock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/null_mutex.hpp>
+
+// class null_mutex;
+
+// void lock();
+
+#include <boost/thread/null_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+boost::null_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ m.lock();
+ time_point t1 = Clock::now();
+ m.lock();
+ m.unlock();
+ m.unlock();
+ ns d = t1 - t0 ;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+#else
+ //time_point t0 = Clock::now();
+ m.lock();
+ //time_point t1 = Clock::now();
+ m.lock();
+ m.unlock();
+ m.unlock();
+ //ns d = t1 - t0 ;
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_for_pass.cpp
new file mode 100644
index 000000000..1f5f5e9fc
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/null_mutex.hpp>
+
+// class null_mutex;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/null_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+
+boost::null_mutex m;
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ BOOST_TEST(m.try_lock_for(ms(250)) == true);
+ time_point t1 = Clock::now();
+ BOOST_TEST(m.try_lock());
+ m.unlock();
+ m.unlock();
+ ns d = t1 - t0 ;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_pass.cpp
new file mode 100644
index 000000000..cc51928bb
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/null_mutex.hpp>
+
+// class null_mutex;
+
+// bool try_lock();
+
+#include <boost/thread/null_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+
+
+boost::null_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t0 = Clock::now();
+ BOOST_TEST(m.try_lock());
+ time_point t1 = Clock::now();
+ BOOST_TEST(m.try_lock());
+ m.unlock();
+ m.unlock();
+ ns d = t1 - t0;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+#else
+ BOOST_TEST(m.try_lock());
+ BOOST_TEST(m.try_lock());
+ m.unlock();
+ m.unlock();
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+ m.unlock();
+ t.join();
+
+ return boost::report_errors();
+}
+
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_until_pass.cpp
new file mode 100644
index 000000000..8a6985165
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_until_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/null_mutex>
+
+// class null_mutex;
+
+// template <class Clock, class Duration>
+// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <boost/thread/null_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+boost::null_mutex m;
+
+typedef boost::chrono::steady_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f1()
+{
+ time_point t0 = Clock::now();
+ BOOST_TEST(m.try_lock_until(Clock::now() + ms(250)) == true);
+ time_point t1 = Clock::now();
+ m.unlock();
+ ns d = t1 - t0 ;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+}
+
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp
new file mode 100644
index 000000000..ac7b80769
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp
@@ -0,0 +1,297 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/once.hpp>
+
+// struct once_flag;
+
+// template<class Callable, class ...Args>
+// void call_once(once_flag& flag, Callable&& func, Args&&... args);
+
+//#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_USES_MOVE
+#define BOOST_THREAD_PROVIDES_ONCE_CXX11
+
+#include <boost/thread/once.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
+#define BOOST_INIT_ONCE_INIT
+#else
+#define BOOST_INIT_ONCE_INIT =BOOST_ONCE_INIT
+#endif
+
+typedef boost::chrono::milliseconds ms;
+
+boost::once_flag flg0 BOOST_INIT_ONCE_INIT;
+
+int init0_called = 0;
+
+void init0()
+{
+ boost::this_thread::sleep_for(ms(250));
+ ++init0_called;
+}
+
+void f0()
+{
+ boost::call_once(flg0, init0);
+}
+
+boost::once_flag flg3 BOOST_INIT_ONCE_INIT;
+
+int init3_called = 0;
+int init3_completed = 0;
+
+void init3()
+{
+ ++init3_called;
+ boost::this_thread::sleep_for(ms(250));
+ if (init3_called == 1)
+ throw 1;
+ ++init3_completed;
+}
+
+void f3()
+{
+ try
+ {
+ boost::call_once(flg3, init3);
+ }
+ catch (...)
+ {
+ }
+}
+
+struct init1
+{
+ static int called;
+ typedef void result_type;
+
+ void operator()(int i) {called += i;}
+ void operator()(int i) const {called += i;}
+};
+
+int init1::called = 0;
+
+boost::once_flag flg1 BOOST_INIT_ONCE_INIT;
+
+void f1()
+{
+ boost::call_once(flg1, init1(), 1);
+}
+
+boost::once_flag flg1_member BOOST_INIT_ONCE_INIT;
+
+struct init1_member
+{
+ static int called;
+ typedef void result_type;
+ void call(int i) {
+ called += i;
+ }
+};
+int init1_member::called = 0;
+
+void f1_member_l()
+{
+ init1_member o;
+ int i=1;
+ boost::call_once(flg1_member, &init1_member::call, o, i);
+}
+void f1_member_r()
+{
+ init1_member o;
+ boost::call_once(flg1_member, &init1_member::call, o, 1);
+}
+struct init2
+{
+ static int called;
+ typedef void result_type;
+
+ void operator()(int i, int j) {called += i + j;}
+ void operator()(int i, int j) const {called += i + j;}
+};
+
+int init2::called = 0;
+
+boost::once_flag flg2 BOOST_INIT_ONCE_INIT;
+
+void f2()
+{
+ boost::call_once(flg2, init2(), 2, 3);
+ boost::call_once(flg2, init2(), 4, 5);
+}
+
+boost::once_flag flg41 BOOST_INIT_ONCE_INIT;
+boost::once_flag flg42 BOOST_INIT_ONCE_INIT;
+
+int init41_called = 0;
+int init42_called = 0;
+
+void init42();
+
+void init41()
+{
+ boost::this_thread::sleep_for(ms(250));
+ ++init41_called;
+}
+
+void init42()
+{
+ boost::this_thread::sleep_for(ms(250));
+ ++init42_called;
+}
+
+void f41()
+{
+ boost::call_once(flg41, init41);
+ boost::call_once(flg42, init42);
+}
+
+void f42()
+{
+ boost::call_once(flg42, init42);
+ boost::call_once(flg41, init41);
+}
+
+class MoveOnly
+{
+public:
+ typedef void result_type;
+
+ BOOST_THREAD_MOVABLE_ONLY(MoveOnly)
+ MoveOnly()
+ {
+ }
+ MoveOnly(BOOST_THREAD_RV_REF(MoveOnly))
+ {}
+
+ void operator()(BOOST_THREAD_RV_REF(MoveOnly))
+ {
+ }
+ void operator()(int)
+ {
+ }
+ void operator()()
+ {
+ }
+};
+
+
+struct id_string
+{
+ static boost::once_flag flag;
+ static void do_init(id_string & )
+ {}
+ void operator()()
+ {
+ boost::call_once(flag, &id_string::do_init, boost::ref(*this));
+ }
+// void operator()(int,int)
+// {
+// // This should fail but works with gcc-4.6.3
+// //std::bind(&id_string::do_init, *this)();
+// std::bind(&id_string::do_init, std::ref(*this))();
+// }
+// void operator()(int) const
+// {
+// //std::bind(&id_string::do_init, *this)();
+// }
+};
+
+
+boost::once_flag id_string::flag BOOST_INIT_ONCE_INIT;
+
+int main()
+{
+
+ //
+ {
+ id_string id;
+ id();
+ //id(1,1);
+ }
+ // check basic functionality
+ {
+ boost::thread t0(f0);
+ boost::thread t1(f0);
+ t0.join();
+ t1.join();
+ BOOST_TEST(init0_called == 1);
+ }
+ // check basic exception safety
+ {
+ boost::thread t0(f3);
+ boost::thread t1(f3);
+ t0.join();
+ t1.join();
+ BOOST_TEST(init3_called == 2);
+ BOOST_TEST(init3_completed == 1);
+ }
+ // check deadlock avoidance
+ {
+ boost::thread t0(f41);
+ boost::thread t1(f42);
+ t0.join();
+ t1.join();
+ BOOST_TEST(init41_called == 1);
+ BOOST_TEST(init42_called == 1);
+ }
+ // check functors with 1 arg
+ {
+ boost::thread t0(f1);
+ boost::thread t1(f1);
+ t0.join();
+ t1.join();
+ BOOST_TEST(init1::called == 1);
+ }
+ // check functors with 2 args
+ {
+ boost::thread t0(f2);
+ boost::thread t1(f2);
+ t0.join();
+ t1.join();
+ BOOST_TEST(init2::called == 5);
+ }
+
+ // check member function with 1 arg
+ {
+ boost::thread t0(f1_member_l);
+ boost::thread t1(f1_member_r);
+ t0.join();
+ t1.join();
+ BOOST_TEST(init1_member::called == 1);
+ }
+#if defined BOOST_THREAD_PLATFORM_PTHREAD || (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ > 40600)
+ {
+ boost::once_flag f BOOST_INIT_ONCE_INIT;
+ boost::call_once(f, MoveOnly());
+ }
+#endif
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+ {
+ boost::once_flag f BOOST_INIT_ONCE_INIT;
+ boost::call_once(f, MoveOnly(), 1);
+ }
+ {
+ boost::once_flag f BOOST_INIT_ONCE_INIT;
+ boost::call_once(f, MoveOnly(), MoveOnly());
+ }
+#endif // BOOST_THREAD_PLATFORM_PTHREAD
+ return boost::report_errors();
+}
+
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/queue_views/single_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/queue_views/single_thread_pass.cpp
new file mode 100644
index 000000000..05a628230
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/queue_views/single_thread_pass.cpp
@@ -0,0 +1,468 @@
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/sync_queue.hpp>
+
+// class sync_queue<T>
+
+// sync_queue();
+
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
+
+#include <boost/thread/concurrent_queues/sync_queue.hpp>
+#include <boost/thread/concurrent_queues/queue_adaptor.hpp>
+#include <boost/thread/concurrent_queues/queue_views.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+class non_copyable
+{
+ int val;
+public:
+ BOOST_THREAD_MOVABLE_ONLY(non_copyable)
+ non_copyable(int v) : val(v){}
+ non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {}
+ non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; }
+ bool operator==(non_copyable const& x) const {return val==x.val;}
+ template <typename OSTREAM>
+ friend OSTREAM& operator <<(OSTREAM& os, non_copyable const&x )
+ {
+ os << x.val;
+ return os;
+ }
+
+};
+
+#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
+BOOST_STATIC_ASSERT( ! boost::is_copy_constructible<non_copyable>::value );
+BOOST_STATIC_ASSERT( boost::has_move_emulation_enabled<non_copyable>::value );
+#endif
+
+int main()
+{
+
+ {
+ // default queue invariants
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_back<int> q(sq);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // default queue invariants
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_front<int> q(sq);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+
+
+ {
+ // empty queue try_pull fails
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_front<int> q(sq);
+ int i;
+ BOOST_TEST( boost::queue_op_status::empty == q.try_pull(i));
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push rvalue/copyable succeeds
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_back<int> q(sq);
+ q.push(1);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push lvalue/copyable succeeds
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_back<int> q(sq);
+ int i;
+ q.push(i);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+
+
+#if 0
+ {
+ // empty queue push rvalue/non_copyable succeeds
+ boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
+ boost::queue_back<non_copyable> q(sq);
+ q.push(non_copyable(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
+ {
+ // empty queue push rvalue/non_copyable succeeds
+ boost::queue_adaptor<boost::sync_queue<non_copyable> > q;
+ //boost::sync_queue<non_copyable> q;
+ //boost::queue_back<non_copyable> q(sq);
+ non_copyable nc(1);
+ q.push(boost::move(nc));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+
+ {
+ // empty queue push rvalue succeeds
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_back<int> q(sq);
+ q.push(1);
+ q.push(2);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 2u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push lvalue succeeds
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_back<int> q(sq);
+ int i;
+ q.push(i);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue/copyable succeeds
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_back<int> q(sq);
+ BOOST_TEST(boost::queue_op_status::success == q.try_push(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue/copyable succeeds
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_back<int> q(sq);
+ BOOST_TEST(boost::queue_op_status::success == q.try_push(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+
+#if 0
+ {
+ // empty queue try_push rvalue/non-copyable succeeds
+ boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
+ boost::queue_back<non_copyable> q(sq);
+ non_copyable nc(1);
+ BOOST_TEST(boost::queue_op_status::success == q.try_push(boost::move(nc)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+
+ {
+ // empty queue try_push lvalue succeeds
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_back<int> q(sq);
+ int i=0;
+ BOOST_TEST(boost::queue_op_status::success == q.try_push(i));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue succeeds
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_back<int> q(sq);
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+
+
+#if 0
+ {
+ // empty queue nonblocking_push rvalue/non-copyable succeeds
+ boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
+ boost::queue_back<non_copyable> q(sq);
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(non_copyable(1)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
+ {
+ // empty queue nonblocking_push rvalue/non-copyable succeeds
+ boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
+ boost::queue_back<non_copyable> q(sq);
+ non_copyable nc(1);
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(boost::move(nc)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // 1-element queue pull succeed
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_front<int> q(sq);
+ sq.push(1);
+ int i;
+ q.pull(i);
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
+ {
+ // 1-element queue pull succeed
+ boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
+ boost::queue_front<non_copyable> q(sq);
+ non_copyable nc1(1);
+ sq.push(boost::move(nc1));
+ non_copyable nc2(2);
+ q.pull(nc2);
+ BOOST_TEST_EQ(nc1, nc2);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // 1-element queue pull succeed
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_front<int> q(sq);
+ sq.push(1);
+ int i = q.pull();
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
+ {
+ // 1-element queue pull succeed
+ boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
+ boost::queue_front<non_copyable> q(sq);
+ non_copyable nc1(1);
+ sq.push(boost::move(nc1));
+ non_copyable nc = q.pull();
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // 1-element queue try_pull succeed
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_front<int> q(sq);
+ sq.push(1);
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.try_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
+ {
+ // 1-element queue try_pull succeed
+ boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
+ boost::queue_front<non_copyable> q(sq);
+ non_copyable nc1(1);
+ sq.push(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.try_pull(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // 1-element queue nonblocking_pull succeed
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_front<int> q(sq);
+ sq.push(1);
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
+ {
+ // 1-element queue nonblocking_pull succeed
+ boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
+ boost::queue_front<non_copyable> q(sq);
+ non_copyable nc1(1);
+ sq.push(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue wait_pull succeed
+ boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
+ boost::queue_front<non_copyable> q(sq);
+ non_copyable nc1(1);
+ sq.push(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // 1-element queue wait_pull succeed
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_front<int> q(sq);
+ sq.push(1);
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
+ {
+ // 1-element queue wait_pull succeed
+ boost::queue_adaptor<boost::sync_queue<non_copyable> > sq;
+ boost::queue_front<non_copyable> q(sq);
+ non_copyable nc1(1);
+ sq.push(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // closed invariants
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_back<int> q(sq);
+ q.close();
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed invariants
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_front<int> q(sq);
+ q.close();
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed queue push fails
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_back<int> q(sq);
+ q.close();
+ try {
+ q.push(1);
+ BOOST_TEST(false);
+ } catch (...) {
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ }
+ {
+ // 1-element closed queue pull succeed
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_front<int> q(sq);
+ sq.push(1);
+ q.close();
+ int i;
+ q.pull(i);
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // 1-element closed queue wait_pull succeed
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_front<int> q(sq);
+ sq.push(1);
+ q.close();
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed empty queue wait_pull fails
+ boost::queue_adaptor<boost::sync_queue<int> > sq;
+ boost::queue_front<int> q(sq);
+ q.close();
+ BOOST_TEST(q.empty());
+ BOOST_TEST(q.closed());
+ int i;
+ BOOST_TEST(boost::queue_op_status::closed == q.wait_pull(i));
+ BOOST_TEST(q.empty());
+ BOOST_TEST(q.closed());
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/assign_fail.cpp
new file mode 100644
index 000000000..041102e91
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_mutex;
+
+// recursive_mutex& operator=(const recursive_mutex&) = delete;
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::recursive_mutex m0;
+ boost::recursive_mutex m1(m0);
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/copy_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/copy_fail.cpp
new file mode 100644
index 000000000..932422d15
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/copy_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_mutex;
+
+// recursive_mutex(const recursive_mutex&) = delete;
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::recursive_mutex m0;
+ boost::recursive_mutex m1(m0);
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/default_pass.cpp
new file mode 100644
index 000000000..6b6199720
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/default_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_mutex;
+
+// recursive_mutex();
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::recursive_mutex m0;
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/lock_pass.cpp
new file mode 100644
index 000000000..a5410d25e
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/lock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_mutex;
+
+// void lock();
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+
+boost::recursive_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ m.lock();
+ t1 = Clock::now();
+ m.lock();
+ m.unlock();
+ m.unlock();
+#else
+ //time_point t0 = Clock::now();
+ m.lock();
+ //time_point t1 = Clock::now();
+ m.lock();
+ m.unlock();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp
new file mode 100644
index 000000000..b784f24e5
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_mutex;
+
+// typedef pthread_recursive_mutex_t* native_handle_type;
+// native_handle_type native_handle();
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+#if defined BOOST_THREAD_DEFINES_RECURSIVE_MUTEX_NATIVE_HANDLE
+ boost::recursive_mutex m;
+ boost::recursive_mutex::native_handle_type h = m.native_handle();
+ BOOST_TEST(h);
+#else
+#error "Test not applicable: BOOST_THREAD_DEFINES_RECURSIVE_MUTEX_NATIVE_HANDLE not defined for this platform as not supported"
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/try_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/try_lock_pass.cpp
new file mode 100644
index 000000000..0f8fe822a
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/try_lock_pass.cpp
@@ -0,0 +1,96 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_mutex;
+
+// bool try_lock();
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include "../../../timming.hpp"
+
+boost::recursive_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+// BOOST_TEST(!m.try_lock());
+// BOOST_TEST(!m.try_lock());
+// BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ t1 = Clock::now();
+ BOOST_TEST(m.try_lock());
+ m.unlock();
+ m.unlock();
+#else
+ //time_point t0 = Clock::now();
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ //time_point t1 = Clock::now();
+ BOOST_TEST(m.try_lock());
+ m.unlock();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/assign_fail.cpp
new file mode 100644
index 000000000..48b9cc47d
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/assign_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_timed_mutex;
+
+// recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::recursive_timed_mutex m0;
+ boost::recursive_timed_mutex m1(m0);
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/copy_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/copy_fail.cpp
new file mode 100644
index 000000000..b4e96c7ac
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/copy_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_timed_mutex;
+
+// recursive_timed_mutex(const recursive_timed_mutex&) = delete;
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::recursive_timed_mutex m0;
+ boost::recursive_timed_mutex m1(m0);
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/default_pass.cpp
new file mode 100644
index 000000000..1e75b7b04
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/default_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_timed_mutex;
+
+// recursive_timed_mutex();
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::recursive_timed_mutex m0;
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/lock_pass.cpp
new file mode 100644
index 000000000..bd0646f64
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/lock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_timed_mutex;
+
+// void lock();
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include "../../../timming.hpp"
+
+boost::recursive_timed_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ m.lock();
+ t1 = Clock::now();
+ m.lock();
+ m.unlock();
+ m.unlock();
+#else
+ //time_point t0 = Clock::now();
+ m.lock();
+ //time_point t1 = Clock::now();
+ m.lock();
+ m.unlock();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/native_handle_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/native_handle_pass.cpp
new file mode 100644
index 000000000..bcd375e53
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/native_handle_pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_timed_mutex;
+
+// typedef pthread_recursive_mutex_t* native_handle_type;
+// native_handle_type native_handle();
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+#if defined BOOST_THREAD_DEFINES_RECURSIVE_TIMED_MUTEX_NATIVE_HANDLE
+ boost::recursive_timed_mutex m;
+ boost::recursive_timed_mutex::native_handle_type h = m.native_handle();
+ BOOST_TEST(h);
+#else
+#error "Test not applicable: BOOST_THREAD_DEFINES_RECURSIVE_TIMED_MUTEX_NATIVE_HANDLE not defined for this platform as not supported"
+#endif
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_for_pass.cpp
new file mode 100644
index 000000000..c7f6d2b0b
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_for_pass.cpp
@@ -0,0 +1,92 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_timed_mutex;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+boost::recursive_timed_mutex m;
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f1()
+{
+ t0 = Clock::now();
+ BOOST_TEST(m.try_lock_for(ms(750)) == true);
+ t1 = Clock::now();
+ BOOST_TEST(m.try_lock());
+ m.unlock();
+ m.unlock();
+}
+
+void f2()
+{
+ time_point t0 = Clock::now();
+ BOOST_TEST(m.try_lock_for(ms(250)) == false);
+ time_point t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+ m.unlock();
+ t.join();
+
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(750));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_pass.cpp
new file mode 100644
index 000000000..3874d6853
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex.hpp>
+
+// class recursive_timed_mutex;
+
+// bool try_lock();
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+boost::recursive_timed_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ BOOST_TEST(!m.try_lock());
+ BOOST_TEST(!m.try_lock());
+ BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ t1 = Clock::now();
+ BOOST_TEST(m.try_lock());
+ m.unlock();
+ m.unlock();
+#else
+ //time_point t0 = Clock::now();
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ //time_point t1 = Clock::now();
+ BOOST_TEST(m.try_lock());
+ m.unlock();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_until_pass.cpp
new file mode 100644
index 000000000..238467204
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_until_pass.cpp
@@ -0,0 +1,92 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/recursive_mutex>
+
+// class recursive_timed_mutex;
+
+// template <class Clock, class Duration>
+// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+boost::recursive_timed_mutex m;
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f1()
+{
+ t0 = Clock::now();
+ BOOST_TEST(m.try_lock_until(Clock::now() + ms(750)) == true);
+ t1 = Clock::now();
+ m.unlock();
+}
+
+void f2()
+{
+ t0 = Clock::now();
+ BOOST_TEST(m.try_lock_until(Clock::now() + ms(250)) == false);
+ t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(750));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/assign_fail.cpp
new file mode 100644
index 000000000..ee6446d7e
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_mutex.hpp>
+
+// class shared_mutex;
+
+// shared_mutex& operator=(const shared_mutex&) = delete;
+
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::shared_mutex m0;
+ boost::shared_mutex m1(m0);
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/copy_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/copy_fail.cpp
new file mode 100644
index 000000000..9627f9f66
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/copy_fail.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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_mutex.hpp>
+
+// class shared_mutex;
+
+// shared_mutex(const shared_mutex&) = delete;
+
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::shared_mutex m0;
+ boost::shared_mutex m1(m0);
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/default_pass.cpp
new file mode 100644
index 000000000..730c9cafc
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/default_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/timed_mutex.hpp>
+
+// class shared_mutex;
+
+// shared_mutex();
+
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::shared_mutex m0;
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/lock_pass.cpp
new file mode 100644
index 000000000..0b53fb275
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/lock_pass.cpp
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_mutex.hpp>
+
+// class shared_mutex;
+
+// void lock();
+
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+boost::shared_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ m.lock();
+ t1 = Clock::now();
+ m.unlock();
+#else
+ //time_point t0 = Clock::now();
+ m.lock();
+ //time_point t1 = Clock::now();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_for_pass.cpp
new file mode 100644
index 000000000..bc06576ec
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_for_pass.cpp
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_mutex.hpp>
+
+// class shared_mutex;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+boost::shared_mutex m;
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f1()
+{
+ t0 = Clock::now();
+ BOOST_TEST(m.try_lock_for(ms(750)) == true);
+ t1 = Clock::now();
+ m.unlock();
+}
+
+void f2()
+{
+ t0 = Clock::now();
+ BOOST_TEST(m.try_lock_for(ms(250)) == false);
+ t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(750));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_pass.cpp
new file mode 100644
index 000000000..515589a6f
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_mutex.hpp>
+
+// class shared_mutex;
+
+// bool try_lock();
+
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+boost::shared_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ BOOST_TEST(!m.try_lock());
+ BOOST_TEST(!m.try_lock());
+ BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ t1 = Clock::now();
+ m.unlock();
+#else
+ //time_point t0 = Clock::now();
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ //time_point t1 = Clock::now();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_until_pass.cpp
new file mode 100644
index 000000000..dd8a1a816
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_until_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2012 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/shared_mutex.hpp>
+
+// class shared_mutex;
+
+// template <class Clock, class Duration>
+// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+boost::shared_mutex m;
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f1()
+{
+ t0 = Clock::now();
+ BOOST_TEST(m.try_lock_until(Clock::now() + ms(750)) == true);
+ t1 = Clock::now();
+ m.unlock();
+}
+
+void f2()
+{
+ t0 = Clock::now();
+ BOOST_TEST(m.try_lock_until(Clock::now() + ms(250)) == false);
+ t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+ m.unlock();
+ t.join();
+
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(750));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/multi_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/multi_thread_pass.cpp
new file mode 100644
index 000000000..9975a995a
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/multi_thread_pass.cpp
@@ -0,0 +1,252 @@
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/sync_bounded_queue.hpp>
+
+// class sync_queue<T>
+
+// push || pull;
+
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/sync_bounded_queue.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/thread/barrier.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+struct call_push
+{
+ boost::sync_bounded_queue<int> &q_;
+ boost::barrier& go_;
+
+ call_push(boost::sync_bounded_queue<int> &q, boost::barrier &go) :
+ q_(q), go_(go)
+ {
+ }
+ typedef void result_type;
+ void operator()()
+ {
+ go_.count_down_and_wait();
+ q_.push(42);
+
+ }
+};
+
+struct call_push_2
+{
+ boost::sync_bounded_queue<int> &q_;
+ boost::barrier& go_;
+ boost::barrier& end_;
+
+ call_push_2(boost::sync_bounded_queue<int> &q, boost::barrier &go, boost::barrier &end) :
+ q_(q), go_(go), end_(end)
+ {
+ }
+ typedef void result_type;
+ void operator()()
+ {
+ go_.count_down_and_wait();
+ q_.push(42);
+ end_.count_down_and_wait();
+
+ }
+};
+
+struct call_pull
+{
+ boost::sync_bounded_queue<int> &q_;
+ boost::barrier& go_;
+
+ call_pull(boost::sync_bounded_queue<int> &q, boost::barrier &go) :
+ q_(q), go_(go)
+ {
+ }
+ typedef int result_type;
+ int operator()()
+ {
+ go_.count_down_and_wait();
+ return q_.pull();
+ }
+};
+
+void test_concurrent_push_and_pull_on_empty_queue()
+{
+ boost::sync_bounded_queue<int> q(4);
+
+ boost::barrier go(2);
+
+ boost::future<void> push_done;
+ boost::future<int> pull_done;
+
+ try
+ {
+ push_done=boost::async(boost::launch::async,
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+ [&q,&go]()
+ {
+ go.wait();
+ q.push(42);
+ }
+#else
+ call_push(q,go)
+#endif
+ );
+ pull_done=boost::async(boost::launch::async,
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+ [&q,&go]() -> int
+ {
+ go.wait();
+ return q.pull();
+ }
+#else
+ call_pull(q,go)
+#endif
+ );
+
+ push_done.get();
+ BOOST_TEST_EQ(pull_done.get(), 42);
+ BOOST_TEST(q.empty());
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+}
+
+void test_concurrent_push_on_empty_queue()
+{
+ boost::sync_bounded_queue<int> q(4);
+ const unsigned int n = 3;
+ boost::barrier go(n);
+ boost::future<void> push_done[n];
+
+ try
+ {
+ for (unsigned int i =0; i< n; ++i)
+ push_done[i]=boost::async(boost::launch::async,
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+ [&q,&go]()
+ {
+ go.wait();
+ q.push(42);
+ }
+#else
+ call_push(q,go)
+#endif
+ );
+
+ for (unsigned int i = 0; i < n; ++i)
+ push_done[i].get();
+
+ BOOST_TEST(!q.empty());
+ for (unsigned int i =0; i< n; ++i)
+ BOOST_TEST_EQ(q.pull(), 42);
+ BOOST_TEST(q.empty());
+
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+}
+
+void test_concurrent_push_on_full_queue()
+{
+ const unsigned int size = 2;
+ boost::sync_bounded_queue<int> q(size);
+ const unsigned int n = 2*size;
+ boost::barrier go(n);
+ boost::barrier end(size+1);
+ boost::future<void> push_done[n];
+
+ try
+ {
+ for (unsigned int i =0; i< n; ++i)
+ push_done[i]=boost::async(boost::launch::async,
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+ [&q,&go,&end]()
+ {
+ go.wait();
+ q.push(42);
+ end.wait();
+ }
+#else
+ call_push_2(q,go,end)
+#endif
+ );
+
+ end.wait();
+ BOOST_TEST(!q.empty());
+ BOOST_TEST(q.full());
+ for (unsigned int i =0; i< size; ++i)
+ BOOST_TEST_EQ(q.pull(), 42);
+ end.wait();
+
+ for (unsigned int i = 0; i < n; ++i)
+ push_done[i].get();
+
+ BOOST_TEST(!q.empty());
+ for (unsigned int i =0; i< size; ++i)
+ BOOST_TEST_EQ(q.pull(), 42);
+ BOOST_TEST(q.empty());
+
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+}
+void test_concurrent_pull_on_queue()
+{
+ boost::sync_bounded_queue<int> q(4);
+ const unsigned int n = 3;
+ boost::barrier go(n);
+
+ boost::future<int> pull_done[n];
+
+ try
+ {
+ for (unsigned int i =0; i< n; ++i)
+ q.push(42);
+
+ for (unsigned int i =0; i< n; ++i)
+ pull_done[i]=boost::async(boost::launch::async,
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+ [&q,&go]() -> int
+ {
+ go.wait();
+ return q.pull();
+ }
+#else
+ call_pull(q,go)
+#endif
+ );
+
+ for (unsigned int i = 0; i < n; ++i)
+ BOOST_TEST_EQ(pull_done[i].get(), 42);
+ BOOST_TEST(q.empty());
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+}
+
+int main()
+{
+ test_concurrent_push_and_pull_on_empty_queue();
+ test_concurrent_push_on_empty_queue();
+ test_concurrent_push_on_full_queue();
+ test_concurrent_pull_on_queue();
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp
new file mode 100644
index 000000000..201e0bc13
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp
@@ -0,0 +1,600 @@
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/sync_bounded_queue.hpp>
+
+// class sync_bounded_queue<T>
+
+// sync_bounded_queue();
+
+#define BOOST_THREAD_VERSION 4
+//#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
+
+#include <boost/thread/sync_bounded_queue.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+class non_copyable
+{
+ BOOST_THREAD_MOVABLE_ONLY(non_copyable)
+ int val;
+public:
+ non_copyable() {}
+ non_copyable(int v) : val(v){}
+ non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {}
+ non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; }
+ bool operator==(non_copyable const& x) const {return val==x.val;}
+ template <typename OSTREAM>
+ friend OSTREAM& operator <<(OSTREAM& os, non_copyable const&x )
+ {
+ os << x.val;
+ return os;
+ }
+
+};
+
+
+int main()
+{
+
+ {
+ // default queue invariants
+ boost::sync_bounded_queue<int> q(2);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST_EQ(q.capacity(), 2u);
+ BOOST_TEST(! q.closed());
+ }
+#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD
+ {
+ // empty queue try_pull fails
+ boost::sync_bounded_queue<int> q(2);
+ int i;
+ BOOST_TEST(! q.try_pull(i));
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_pull fails
+ boost::sync_bounded_queue<int> q(2);
+ BOOST_TEST(! q.try_pull());
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push rvalue succeeds
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push rvalue succeeds
+ boost::sync_bounded_queue<non_copyable> q(2);
+ non_copyable nc(1);
+ q.push(boost::move(nc));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push rvalue succeeds
+ boost::sync_bounded_queue<int> q(3);
+ q.push(1);
+ BOOST_TEST_EQ(q.size(), 1u);
+ q.push(2);
+ BOOST_TEST_EQ(q.size(), 2u);
+ q.push(2);
+ BOOST_TEST_EQ(q.size(), 3u);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST( q.full());
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push value succeeds
+ boost::sync_bounded_queue<int> q(2);
+ int i;
+ q.push(i);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue succeeds
+ boost::sync_bounded_queue<int> q(2);
+ BOOST_TEST(q.try_push(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue succeeds
+ boost::sync_bounded_queue<non_copyable> q(2);
+ non_copyable nc(1);
+ BOOST_TEST(q.try_push(boost::move(nc)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push value succeeds
+ boost::sync_bounded_queue<int> q(2);
+ int i=1;
+ BOOST_TEST(q.try_push(i));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue succeeds
+ boost::sync_bounded_queue<int> q(2);
+ BOOST_TEST(q.try_push(boost::no_block, 1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue succeeds
+ boost::sync_bounded_queue<non_copyable> q(2);
+ non_copyable nc(1);
+ BOOST_TEST(q.try_push(boost::no_block, boost::move(nc)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ int i;
+ q.pull(i);
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull succeed
+ boost::sync_bounded_queue<non_copyable> q(2);
+ non_copyable nc(1);
+ q.push(boost::move(nc));
+ non_copyable nc2(2);
+ q.pull(nc2);
+ BOOST_TEST_EQ(nc, nc2);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ int i = q.pull();
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue try_pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ int i;
+ BOOST_TEST(q.try_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue try_pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ int i;
+ BOOST_TEST(q.try_pull(boost::no_block, i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue try_pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ boost::shared_ptr<int> i = q.try_pull();
+ BOOST_TEST_EQ(*i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // full queue try_push rvalue fails
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ q.push(2);
+ BOOST_TEST(! q.try_push(3));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST( q.full());
+ BOOST_TEST_EQ(q.size(), 2u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // full queue try_push succeeds
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ q.push(2);
+ BOOST_TEST(q.try_pull());
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+
+ {
+ // closed invariants
+ boost::sync_bounded_queue<int> q(2);
+ q.close();
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed queue push fails
+ boost::sync_bounded_queue<int> q(2);
+ q.close();
+ try {
+ q.push(1);
+ BOOST_TEST(false);
+ } catch (...) {
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ }
+ {
+ // 1-element closed queue pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push(1);
+ q.close();
+ int i;
+ q.pull(i);
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+#endif
+ {
+ // empty queue try_pull fails
+ boost::sync_bounded_queue<int> q(2);
+ int i;
+ BOOST_TEST( boost::queue_op_status::empty == q.try_pull_front(i));
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push rvalue succeeds
+ boost::sync_bounded_queue<int> q(2);
+ q.push_back(1);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push rvalue succeeds
+ boost::sync_bounded_queue<non_copyable> q(2);
+ non_copyable nc(1);
+ q.push_back(boost::move(nc));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push rvalue succeeds
+ boost::sync_bounded_queue<int> q(3);
+ q.push_back(1);
+ BOOST_TEST_EQ(q.size(), 1u);
+ q.push_back(2);
+ BOOST_TEST_EQ(q.size(), 2u);
+ q.push_back(3);
+ BOOST_TEST_EQ(q.size(), 3u);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST( q.full());
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push value succeeds
+ boost::sync_bounded_queue<int> q(2);
+ int i;
+ q.push_back(i);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue succeeds
+ boost::sync_bounded_queue<int> q(2);
+ BOOST_TEST(boost::queue_op_status::success == q.try_push_back(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue succeeds
+ boost::sync_bounded_queue<non_copyable> q(2);
+ non_copyable nc(1);
+ BOOST_TEST(boost::queue_op_status::success == q.try_push_back(boost::move(nc)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push value succeeds
+ boost::sync_bounded_queue<int> q(2);
+ int i=1;
+ BOOST_TEST(boost::queue_op_status::success == q.try_push_back(i));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue succeeds
+ boost::sync_bounded_queue<int> q(2);
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back( 1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue succeeds
+ boost::sync_bounded_queue<non_copyable> q(2);
+ non_copyable nc(1);
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(boost::move(nc)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue wait_push rvalue succeeds
+ boost::sync_bounded_queue<int> q(2);
+ BOOST_TEST(boost::queue_op_status::success == q.wait_push_back(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue wait_push rvalue succeeds
+ boost::sync_bounded_queue<non_copyable> q(2);
+ non_copyable nc(1);
+ BOOST_TEST(boost::queue_op_status::success == q.wait_push_back(boost::move(nc)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue wait_push value succeeds
+ boost::sync_bounded_queue<int> q(2);
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.wait_push_back(i));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push_back(1);
+ int i;
+ q.pull_front(i);
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull succeed
+ boost::sync_bounded_queue<non_copyable> q(2);
+ non_copyable nc(1);
+ q.push_back(boost::move(nc));
+ non_copyable nc2(2);
+ q.pull_front(nc2);
+ BOOST_TEST_EQ(nc, nc2);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push_back(1);
+ int i = q.pull_front();
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue try_pull succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push_back(1);
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.try_pull_front(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue nonblocking_pull_front succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push_back(1);
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull_front(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue wait_pull_front succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push_back(1);
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // full queue try_push rvalue fails
+ boost::sync_bounded_queue<int> q(2);
+ q.push_back(1);
+ q.push_back(2);
+ BOOST_TEST(boost::queue_op_status::full == q.try_push_back(3));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST( q.full());
+ BOOST_TEST_EQ(q.size(), 2u);
+ BOOST_TEST(! q.closed());
+ }
+
+ {
+ // closed invariants
+ boost::sync_bounded_queue<int> q(2);
+ q.close();
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed queue push fails
+ boost::sync_bounded_queue<int> q(2);
+ q.close();
+ try {
+ q.push_back(1);
+ BOOST_TEST(false);
+ } catch (...) {
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ }
+ {
+ // closed empty queue try_pull_front closed
+ boost::sync_bounded_queue<int> q(2);
+ q.close();
+ int i;
+ BOOST_TEST(boost::queue_op_status::closed == q.try_pull_front(i));
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed empty queue nonblocking_pull_front closed
+ boost::sync_bounded_queue<int> q(2);
+ q.close();
+ int i;
+ BOOST_TEST(boost::queue_op_status::closed == q.nonblocking_pull_front(i));
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // 1-element closed queue pull_front succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push_back(1);
+ q.close();
+ int i;
+ q.pull_front(i);
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // 1-element closed queue wait_pull_front succeed
+ boost::sync_bounded_queue<int> q(2);
+ q.push_back(1);
+ q.close();
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed empty queue wait_pull_front closed
+ boost::sync_bounded_queue<int> q(2);
+ q.close();
+ BOOST_TEST(q.empty());
+ BOOST_TEST(q.closed());
+ int i;
+ BOOST_TEST(boost::queue_op_status::closed == q.wait_pull_front(i));
+ BOOST_TEST(q.empty());
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed queue wait_push_back fails
+ boost::sync_bounded_queue<int> q(2);
+ q.close();
+ BOOST_TEST(q.empty());
+ BOOST_TEST(q.closed());
+ int i;
+ BOOST_TEST(boost::queue_op_status::closed == q.wait_push_back(i));
+ BOOST_TEST(q.empty());
+ BOOST_TEST(q.closed());
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_deque/multi_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_deque/multi_thread_pass.cpp
new file mode 100644
index 000000000..703c54f40
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_deque/multi_thread_pass.cpp
@@ -0,0 +1,256 @@
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/concurrent_queues/sync_deque.hpp>
+
+// class sync_deque<T>
+
+// push || pull;
+
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/concurrent_queues/sync_deque.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/thread/barrier.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+template <typename ValueType>
+struct call_push_back
+{
+ boost::sync_deque<ValueType> *q_;
+ boost::barrier *go_;
+
+ call_push_back(boost::sync_deque<ValueType> *q, boost::barrier *go) :
+ q_(q), go_(go)
+ {
+ }
+ typedef void result_type;
+ void operator()()
+ {
+ go_->count_down_and_wait();
+ q_->push_back(42);
+ }
+};
+
+template <typename ValueType>
+struct call_pull_front
+{
+ boost::sync_deque<ValueType> *q_;
+ boost::barrier *go_;
+
+ call_pull_front(boost::sync_deque<ValueType> *q, boost::barrier *go) :
+ q_(q), go_(go)
+ {
+ }
+ typedef ValueType result_type;
+ ValueType operator()()
+ {
+ go_->count_down_and_wait();
+ return q_->pull_front();
+ }
+};
+
+template <typename ValueType>
+struct call_wait_pull_front
+{
+ boost::sync_deque<ValueType> *q_;
+ boost::barrier *go_;
+
+ call_wait_pull_front(boost::sync_deque<ValueType> *q, boost::barrier *go) :
+ q_(q), go_(go)
+ {
+ }
+ typedef boost::queue_op_status result_type;
+ boost::queue_op_status operator()(ValueType& v)
+ {
+ go_->wait();
+ return q_->wait_pull_front(v);
+ }
+};
+
+void test_concurrent_push_back_and_pull_front_on_empty_queue()
+{
+ boost::sync_deque<int> q;
+
+ boost::barrier go(2);
+
+ boost::future<void> push_done;
+ boost::future<int> pull_done;
+
+ try
+ {
+ push_done=boost::async(boost::launch::async,
+ call_push_back<int>(&q,&go));
+ pull_done=boost::async(boost::launch::async,
+ call_pull_front<int>(&q,&go));
+
+ push_done.get();
+ BOOST_TEST_EQ(pull_done.get(), 42);
+ BOOST_TEST(q.empty());
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+}
+
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+void test_concurrent_push_back_and_wait_pull_front_on_empty_queue()
+{
+ boost::sync_deque<int> q;
+ const unsigned int n = 3;
+ boost::barrier go(n);
+
+ boost::future<boost::queue_op_status> pull_done[n];
+ int results[n];
+
+ try
+ {
+ for (unsigned int i =0; i< n; ++i)
+ pull_done[i]=boost::async(boost::launch::async,
+ call_wait_pull_front<int>(&q,&go),
+ boost::ref(results[i]));
+
+ for (unsigned int i =0; i< n; ++i)
+ q.push_back(42);
+
+ for (unsigned int i = 0; i < n; ++i) {
+ BOOST_TEST(pull_done[i].get() == boost::queue_op_status::success);
+ BOOST_TEST_EQ(results[i], 42);
+ }
+ BOOST_TEST(q.empty());
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+}
+
+void test_concurrent_wait_pull_front_and_close_on_empty_queue()
+{
+ boost::sync_deque<int> q;
+ const unsigned int n = 3;
+ boost::barrier go(n);
+
+ boost::future<boost::queue_op_status> pull_done[n];
+ int results[n];
+
+ try
+ {
+ for (unsigned int i =0; i< n; ++i)
+ pull_done[i]=boost::async(boost::launch::async,
+ call_wait_pull_front<int>(&q,&go),
+ boost::ref(results[i]));
+
+ q.close();
+
+ for (unsigned int i = 0; i < n; ++i) {
+ BOOST_TEST(pull_done[i].get() == boost::queue_op_status::closed);
+ }
+ BOOST_TEST(q.empty());
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+}
+#endif
+
+void test_concurrent_push_back_on_empty_queue()
+{
+ boost::sync_deque<int> q;
+ const unsigned int n = 3;
+ boost::barrier go(n);
+ boost::future<void> push_done[n];
+
+ try
+ {
+ for (unsigned int i =0; i< n; ++i)
+ push_done[i]=boost::async(boost::launch::async,
+ call_push_back<int>(&q,&go));
+
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ try
+ {
+ for (unsigned int i = 0; i < n; ++i)
+ push_done[i].get();
+
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ try
+ {
+ BOOST_TEST(!q.empty());
+ for (unsigned int i =0; i< n; ++i)
+ BOOST_TEST_EQ(q.pull_front(), 42);
+ BOOST_TEST(q.empty());
+
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+}
+
+void test_concurrent_pull_front_on_queue()
+{
+ boost::sync_deque<int> q;
+ const unsigned int n = 3;
+ boost::barrier go(n);
+
+ boost::future<int> pull_done[n];
+
+ try
+ {
+ for (unsigned int i =0; i< n; ++i)
+ q.push_back(42);
+
+ for (unsigned int i =0; i< n; ++i)
+ pull_done[i]=boost::async(boost::launch::async,
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+ [&q,&go]() -> int
+ {
+ go.wait();
+ return q.pull_front();
+ }
+#else
+ call_pull_front<int>(&q,&go)
+#endif
+ );
+
+ for (unsigned int i = 0; i < n; ++i)
+ BOOST_TEST_EQ(pull_done[i].get(), 42);
+ BOOST_TEST(q.empty());
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+}
+
+int main()
+{
+ test_concurrent_push_back_and_pull_front_on_empty_queue();
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ test_concurrent_push_back_and_wait_pull_front_on_empty_queue();
+ test_concurrent_wait_pull_front_and_close_on_empty_queue();
+#endif
+ test_concurrent_push_back_on_empty_queue();
+ test_concurrent_pull_front_on_queue();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_deque/single_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_deque/single_thread_pass.cpp
new file mode 100644
index 000000000..5170bcf61
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_deque/single_thread_pass.cpp
@@ -0,0 +1,403 @@
+// Copyright (C) 2013,2015 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/concurrent_queues/sync_deque.hpp>
+
+// class sync_deque<T>
+
+// sync_deque();
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/concurrent_queues/sync_deque.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+class non_copyable
+{
+ BOOST_THREAD_MOVABLE_ONLY(non_copyable)
+ int val;
+public:
+ non_copyable(int v) : val(v){}
+ non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {}
+ non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; }
+ bool operator==(non_copyable const& x) const {return val==x.val;}
+ template <typename OSTREAM>
+ friend OSTREAM& operator <<(OSTREAM& os, non_copyable const&x )
+ {
+ os << x.val;
+ return os;
+ }
+
+};
+
+
+
+int main()
+{
+
+ {
+ // default queue invariants
+ boost::sync_deque<int> q;
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_pull fails
+ boost::sync_deque<int> q;
+ int i;
+ BOOST_TEST( boost::queue_op_status::empty == q.try_pull_front(i));
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push rvalue/copyable succeeds
+ boost::sync_deque<int> q;
+ q.push_back(1);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push lvalue/copyable succeeds
+ boost::sync_deque<int> q;
+ int i;
+ q.push_back(i);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ {
+ // empty queue push rvalue/non_copyable succeeds
+ boost::sync_deque<non_copyable> q;
+ q.push_back(non_copyable(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // empty queue push rvalue/non_copyable succeeds
+ boost::sync_deque<non_copyable> q;
+ non_copyable nc(1);
+ q.push_back(boost::move(nc));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+
+ {
+ // empty queue push rvalue succeeds
+ boost::sync_deque<int> q;
+ q.push_back(1);
+ q.push_back(2);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 2u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push lvalue succeeds
+ boost::sync_deque<int> q;
+ int i;
+ q.push_back(i);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue/copyable succeeds
+ boost::sync_deque<int> q;
+ BOOST_TEST(boost::queue_op_status::success == q.try_push_back(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue/copyable succeeds
+ boost::sync_deque<int> q;
+ BOOST_TEST(boost::queue_op_status::success == q.try_push_back(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ {
+ // empty queue try_push rvalue/non-copyable succeeds
+ boost::sync_deque<non_copyable> q;
+ BOOST_TEST(boost::queue_op_status::success ==q.try_push_back(non_copyable(1)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // empty queue try_push rvalue/non-copyable succeeds
+ boost::sync_deque<non_copyable> q;
+ non_copyable nc(1);
+ BOOST_TEST(boost::queue_op_status::success == q.try_push_back(boost::move(nc)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+
+ {
+ // empty queue try_push lvalue succeeds
+ boost::sync_deque<int> q;
+ int i=1;
+ BOOST_TEST(boost::queue_op_status::success == q.try_push_back(i));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue succeeds
+ boost::sync_deque<int> q;
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ {
+ // empty queue nonblocking_push_back rvalue/non-copyable succeeds
+ boost::sync_deque<non_copyable> q;
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(non_copyable(1)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // empty queue nonblocking_push_back rvalue/non-copyable succeeds
+ boost::sync_deque<non_copyable> q;
+ non_copyable nc(1);
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(boost::move(nc)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull_front succeed
+ boost::sync_deque<int> q;
+ q.push_back(1);
+ int i;
+ q.pull_front(i);
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull_front succeed
+ boost::sync_deque<non_copyable> q;
+ non_copyable nc1(1);
+ q.push_back(boost::move(nc1));
+ non_copyable nc2(2);
+ q.pull_front(nc2);
+ BOOST_TEST_EQ(nc1, nc2);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull_front succeed
+ boost::sync_deque<int> q;
+ q.push_back(1);
+ int i = q.pull_front();
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull_front succeed
+ boost::sync_deque<non_copyable> q;
+ non_copyable nc1(1);
+ q.push_back(boost::move(nc1));
+ non_copyable nc = q.pull_front();
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue try_pull_front succeed
+ boost::sync_deque<int> q;
+ q.push_back(1);
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.try_pull_front(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue try_pull_front succeed
+ boost::sync_deque<non_copyable> q;
+ non_copyable nc1(1);
+ q.push_back(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.try_pull_front(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue nonblocking_pull_front succeed
+ boost::sync_deque<int> q;
+ q.push_back(1);
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull_front(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue nonblocking_pull_front succeed
+ boost::sync_deque<non_copyable> q;
+ non_copyable nc1(1);
+ q.push_back(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull_front(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue wait_pull_front succeed
+ boost::sync_deque<non_copyable> q;
+ non_copyable nc1(1);
+ q.push_back(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue wait_pull_front succeed
+ boost::sync_deque<int> q;
+ q.push_back(1);
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue wait_pull_front succeed
+ boost::sync_deque<non_copyable> q;
+ non_copyable nc1(1);
+ q.push_back(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+
+ {
+ // closed invariants
+ boost::sync_deque<int> q;
+ q.close();
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed queue push fails
+ boost::sync_deque<int> q;
+ q.close();
+ try {
+ q.push_back(1);
+ BOOST_TEST(false);
+ } catch (...) {
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ }
+ {
+ // 1-element closed queue pull succeed
+ boost::sync_deque<int> q;
+ q.push_back(1);
+ q.close();
+ int i;
+ q.pull_front(i);
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // 1-element closed queue wait_pull_front succeed
+ boost::sync_deque<int> q;
+ q.push_back(1);
+ q.close();
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed empty queue wait_pull_front fails
+ boost::sync_deque<int> q;
+ q.close();
+ BOOST_TEST(q.empty());
+ BOOST_TEST(q.closed());
+ int i;
+ BOOST_TEST(boost::queue_op_status::closed == q.wait_pull_front(i));
+ BOOST_TEST(q.empty());
+ BOOST_TEST(q.closed());
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_multi_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_multi_thread_pass.cpp
new file mode 100644
index 000000000..92e183079
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_multi_thread_pass.cpp
@@ -0,0 +1,219 @@
+// Copyright (C) 2014 Ian Forbed
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+
+#include <exception>
+
+#include <boost/thread/thread.hpp>
+#include <boost/thread/barrier.hpp>
+#include <boost/thread/concurrent_queues/sync_priority_queue.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+typedef boost::concurrent::sync_priority_queue<int> sync_pq;
+
+int call_pull(sync_pq* q, boost::barrier* go)
+{
+ go->wait();
+ return q->pull();
+
+}
+
+void call_push(sync_pq* q, boost::barrier* go, int val)
+{
+ go->wait();
+ q->push(val);
+}
+
+void test_pull(const int n)
+{
+ sync_pq pq;
+ BOOST_TEST(pq.empty());
+ for(int i = 0; i < n; i++)
+ {
+ pq.push(i);
+ }
+ BOOST_TEST(!pq.empty());
+ BOOST_TEST_EQ(pq.size(), std::size_t(n));
+ pq.close();
+ BOOST_TEST(pq.closed());
+ boost::barrier b(n);
+ boost::thread_group tg;
+ for(int i = 0; i < n; i++)
+ {
+ tg.create_thread(boost::bind(call_pull, &pq, &b));
+ }
+ tg.join_all();
+ BOOST_TEST(pq.empty());
+}
+
+void test_push(const int n)
+{
+ sync_pq pq;
+ BOOST_TEST(pq.empty());
+
+ boost::barrier b(n);
+ boost::thread_group tg;
+ for(int i = 0; i < n; i++)
+ {
+ tg.create_thread(boost::bind(call_push, &pq, &b, i));
+ }
+ tg.join_all();
+ BOOST_TEST(!pq.empty());
+ BOOST_TEST_EQ(pq.size(), std::size_t(n));
+}
+
+void test_both(const int n)
+{
+ sync_pq pq;
+ BOOST_TEST(pq.empty());
+
+ boost::barrier b(2*n);
+ boost::thread_group tg;
+ for(int i = 0; i < n; i++)
+ {
+ tg.create_thread(boost::bind(call_pull, &pq, &b));
+ tg.create_thread(boost::bind(call_push, &pq, &b, i));
+ }
+ tg.join_all();
+ BOOST_TEST(pq.empty());
+ BOOST_TEST_EQ(pq.size(), std::size_t(0));
+}
+
+void push_range(sync_pq* q, const int begin, const int end)
+{
+ for(int i = begin; i < end; i++)
+ q->push(i);
+}
+
+void atomic_pull(sync_pq* q, boost::atomic<int>* sum)
+{
+ while(1)
+ {
+ try{
+ const int val = q->pull();
+ sum->fetch_add(val);
+ }
+ catch(std::exception& ){
+ break;
+ }
+ }
+}
+
+/**
+ * This test computes the sum of the first N integers upto $limit using
+ * $n threads for the push operation and $n threads for the pull and count
+ * operation. The push operation push a range of numbers on the queue while
+ * the pull operation pull from the queue and increments an atomic int.
+ * At the end of execution the value of atomic<int> $sum should be the same
+ * as n*(n+1)/2 as this is the closed form solution to this problem.
+ */
+void compute_sum(const int n)
+{
+ const int limit = 1000;
+ sync_pq pq;
+ BOOST_TEST(pq.empty());
+ boost::atomic<int> sum(0);
+ boost::thread_group tg1;
+ boost::thread_group tg2;
+ for(int i = 0; i < n; i++)
+ {
+ tg1.create_thread(boost::bind(push_range, &pq, i*(limit/n)+1, (i+1)*(limit/n)+1));
+ tg2.create_thread(boost::bind(atomic_pull, &pq, &sum));
+ }
+ tg1.join_all();
+ pq.close(); //Wait until all enqueuing is done before closing.
+ BOOST_TEST(pq.closed());
+ tg2.join_all();
+ BOOST_TEST(pq.empty());
+ BOOST_TEST_EQ(sum.load(), limit*(limit+1)/2);
+}
+
+void move_between_queues(sync_pq* q1, sync_pq* q2)
+{
+ while(1){
+ try{
+ const int val = q1->pull();
+ q2->push(val);
+ }
+ catch(std::exception& ){
+ break;
+ }
+ }
+}
+
+/**
+ * This test computes the sum of the first N integers upto $limit by moving
+ * numbers between 2 sync_priority_queues. A range of numbers are pushed onto
+ * one queue by $n threads while $n threads pull from this queue and push onto
+ * another sync_pq. At the end the main thread ensures the the values in the
+ * second queue are in proper order and then sums all the values from this
+ * queue. The sum should match n*(n+1)/2, the closed form solution to this
+ * problem.
+ */
+void sum_with_moving(const int n)
+{
+ const int limit = 1000;
+ sync_pq pq1;
+ sync_pq pq2;
+ BOOST_TEST(pq1.empty());
+ BOOST_TEST(pq2.empty());
+ boost::thread_group tg1;
+ boost::thread_group tg2;
+ for(int i = 0; i < n; i++)
+ {
+ tg1.create_thread(boost::bind(push_range, &pq1, i*(limit/n)+1, (i+1)*(limit/n)+1));
+ tg2.create_thread(boost::bind(move_between_queues, &pq1, &pq2));
+ }
+ tg1.join_all();
+ pq1.close(); //Wait until all enqueuing is done before closing.
+ BOOST_TEST(pq1.closed());
+ tg2.join_all();
+ BOOST_TEST(pq1.empty());
+ BOOST_TEST(!pq2.empty());
+ int sum = 0;
+ for(int i = 1000; i > 0; i--){
+ const int val = pq2.pull();
+ BOOST_TEST_EQ(i,val);
+ sum += val;
+ }
+ BOOST_TEST(pq2.empty());
+ BOOST_TEST_EQ(sum, limit*(limit+1)/2);
+}
+
+int main()
+{
+ for(int i = 1; i <= 64; i *= 2)
+ {
+ test_pull(i);
+ test_push(i);
+ test_both(i);
+ }
+ //These numbers must divide 1000
+ compute_sum(1);
+ compute_sum(4);
+ compute_sum(10);
+ compute_sum(25);
+ compute_sum(50);
+ sum_with_moving(1);
+ sum_with_moving(4);
+ sum_with_moving(10);
+ sum_with_moving(25);
+ sum_with_moving(50);
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_single_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_single_thread_pass.cpp
new file mode 100644
index 000000000..b51827731
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_single_thread_pass.cpp
@@ -0,0 +1,429 @@
+// Copyright (C) 2014 Ian Forbed
+// Copyright (C) 2014,2015 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+
+#include <iostream>
+
+#include <boost/thread.hpp>
+#include <boost/chrono.hpp>
+#include <boost/thread/concurrent_queues/sync_priority_queue.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+using namespace boost::chrono;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+
+typedef boost::concurrent::sync_priority_queue<int> sync_pq;
+
+class non_copyable
+{
+ BOOST_THREAD_MOVABLE_ONLY(non_copyable)
+ int val;
+public:
+ non_copyable(int v) : val(v){}
+ non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {}
+ non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; }
+ bool operator==(non_copyable const& x) const {return val==x.val;}
+ template <typename OSTREAM>
+ friend OSTREAM& operator <<(OSTREAM& os, non_copyable const&x )
+ {
+ os << x.val;
+ return os;
+ }
+ bool operator <(const non_copyable& other) const
+ {
+ return val < other.val;
+ }
+};
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void test_pull_for()
+{
+ sync_pq pq;
+ steady_clock::time_point start = steady_clock::now();
+ int val;
+ boost::queue_op_status st = pq.pull_for(milliseconds(500), val);
+ ns d = steady_clock::now() - start - milliseconds(500);
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ BOOST_TEST(boost::queue_op_status::timeout == st);
+}
+
+void test_pull_until()
+{
+ sync_pq pq;
+ steady_clock::time_point start = steady_clock::now();
+ int val;
+ boost::queue_op_status st = pq.pull_until(start + milliseconds(500), val);
+ ns d = steady_clock::now() - start - milliseconds(500);
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ BOOST_TEST(boost::queue_op_status::timeout == st);
+}
+
+void test_nonblocking_pull()
+{
+ sync_pq pq;
+ steady_clock::time_point start = steady_clock::now();
+ int val;
+ boost::queue_op_status st = pq.nonblocking_pull(val);
+ ns d = steady_clock::now() - start;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ BOOST_TEST(boost::queue_op_status::empty == st);
+}
+
+void test_pull_for_when_not_empty()
+{
+ sync_pq pq;
+ pq.push(1);
+ steady_clock::time_point start = steady_clock::now();
+ int val;
+ boost::queue_op_status st = pq.pull_for(milliseconds(500), val);
+ ns d = steady_clock::now() - start;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ BOOST_TEST(boost::queue_op_status::success == st);
+ BOOST_TEST(1 == val);
+}
+
+void test_pull_until_when_not_empty()
+{
+ sync_pq pq;
+ pq.push(1);
+ steady_clock::time_point start = steady_clock::now();
+ int val;
+ boost::queue_op_status st = pq.pull_until(start + milliseconds(500), val);
+ ns d = steady_clock::now() - start;
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+ BOOST_TEST(boost::queue_op_status::success == st);
+ BOOST_TEST(1 == val);
+}
+
+int main()
+{
+ sync_pq pq;
+ BOOST_TEST(pq.empty());
+ BOOST_TEST(!pq.closed());
+ BOOST_TEST_EQ(pq.size(), std::size_t(0));
+
+ for(int i = 1; i <= 5; i++){
+ pq.push(i);
+ BOOST_TEST(!pq.empty());
+ BOOST_TEST_EQ(pq.size(), std::size_t(i));
+ }
+
+ for(int i = 6; i <= 10; i++){
+ boost::queue_op_status succ = pq.try_push(i);
+ BOOST_TEST(succ == boost::queue_op_status::success );
+ BOOST_TEST(!pq.empty());
+ BOOST_TEST_EQ(pq.size(), std::size_t(i));
+ }
+
+ for(int i = 10; i > 5; i--){
+ int val = pq.pull();
+ BOOST_TEST_EQ(val, i);
+ }
+
+// for(int i = 5; i > 0; i--){
+// boost::optional<int> val = pq.try_pull();
+// BOOST_TEST(val);
+// BOOST_TEST_EQ(*val, i);
+// }
+
+// BOOST_TEST(pq.empty());
+ pq.close();
+ BOOST_TEST(pq.closed());
+
+ test_pull_for();
+ test_pull_until();
+ test_nonblocking_pull();
+
+ test_pull_for_when_not_empty();
+ //test_pull_until_when_not_empty();
+
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ {
+ // empty queue try_push rvalue/non-copyable succeeds
+ boost::concurrent::sync_priority_queue<non_copyable> q;
+ BOOST_TEST(boost::queue_op_status::success ==q.try_push(non_copyable(1)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ //fixme
+ // empty queue try_push rvalue/non-copyable succeeds
+ boost::concurrent::sync_priority_queue<non_copyable> q;
+ non_copyable nc(1);
+ BOOST_TEST(boost::queue_op_status::success == q.try_push(boost::move(nc)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+
+ {
+ // empty queue try_push lvalue succeeds
+ boost::concurrent::sync_priority_queue<int> q;
+ int i=1;
+ BOOST_TEST(boost::queue_op_status::success == q.try_push(i));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+#if 0
+ {
+ // empty queue try_push rvalue succeeds
+ boost::concurrent::sync_priority_queue<int> q;
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue nonblocking_push rvalue/non-copyable succeeds
+ boost::concurrent::sync_priority_queue<non_copyable> q;
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(non_copyable(1)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue nonblocking_push rvalue/non-copyable succeeds
+ boost::concurrent::sync_priority_queue<non_copyable> q;
+ non_copyable nc(1);
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(boost::move(nc)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+
+ {
+ // 1-element queue pull succeed
+ boost::concurrent::sync_priority_queue<int> q;
+ q.push(1);
+ int i;
+ i=q.pull();
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ {
+ // 1-element queue pull succeed
+ boost::concurrent::sync_priority_queue<non_copyable> q;
+ non_copyable nc1(1);
+ q.push(boost::move(nc1));
+ non_copyable nc2(2);
+ nc2=q.pull();
+ BOOST_TEST_EQ(nc1, nc2);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+
+ {
+ // 1-element queue pull succeed
+ boost::concurrent::sync_priority_queue<int> q;
+ q.push(1);
+ int i = q.pull();
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ {
+ // 1-element queue pull succeed
+ boost::concurrent::sync_priority_queue<non_copyable> q;
+ non_copyable nc1(1);
+ q.push(boost::move(nc1));
+ non_copyable nc = q.pull();
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+
+ {
+ // 1-element queue try_pull succeed
+ boost::concurrent::sync_priority_queue<int> q;
+ q.push(1);
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.try_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ {
+ // 1-element queue try_pull succeed
+ boost::concurrent::sync_priority_queue<non_copyable> q;
+ non_copyable nc1(1);
+ q.push(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.try_pull(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // 1-element queue nonblocking_pull succeed
+ boost::concurrent::sync_priority_queue<int> q;
+ q.push(1);
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ {
+ // 1-element queue nonblocking_pull succeed
+ boost::concurrent::sync_priority_queue<non_copyable> q;
+ non_copyable nc1(1);
+ q.push(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue wait_pull succeed
+ boost::concurrent::sync_priority_queue<non_copyable> q;
+ non_copyable nc1(1);
+ q.push(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // 1-element queue wait_pull succeed
+ boost::concurrent::sync_priority_queue<int> q;
+ q.push(1);
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ {
+ // 1-element queue wait_pull succeed
+ boost::concurrent::sync_priority_queue<non_copyable> q;
+ non_copyable nc1(1);
+ q.push(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+
+ {
+ // closed invariants
+ boost::concurrent::sync_priority_queue<int> q;
+ q.close();
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed queue push fails
+ boost::concurrent::sync_priority_queue<int> q;
+ q.close();
+ try {
+ q.push(1);
+ BOOST_TEST(false); // fixme
+ } catch (...) {
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ }
+ {
+ // 1-element closed queue pull succeed
+ boost::concurrent::sync_priority_queue<int> q;
+ q.push(1);
+ q.close();
+ int i;
+ i=q.pull();
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // 1-element closed queue wait_pull succeed
+ boost::concurrent::sync_priority_queue<int> q;
+ q.push(1);
+ q.close();
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed empty queue wait_pull fails
+ boost::concurrent::sync_priority_queue<int> q;
+ q.close();
+ BOOST_TEST(q.empty());
+ BOOST_TEST(q.closed());
+ int i;
+ BOOST_TEST(boost::queue_op_status::closed == q.wait_pull(i));
+ BOOST_TEST(q.empty());
+ BOOST_TEST(q.closed());
+ }
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/tq_multi_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/tq_multi_thread_pass.cpp
new file mode 100644
index 000000000..77656f8b3
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/tq_multi_thread_pass.cpp
@@ -0,0 +1,124 @@
+// Copyright (C) 2019 Austin Beer
+// Copyright (C) 2019 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+
+#include <boost/thread.hpp>
+#include <boost/chrono.hpp>
+#include <boost/thread/concurrent_queues/sync_timed_queue.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+using namespace boost::chrono;
+
+typedef boost::concurrent::sync_timed_queue<int> sync_tq;
+
+const int cnt = 5;
+
+void call_push(sync_tq* q, const steady_clock::time_point start)
+{
+ // push elements onto the queue every 500 milliseconds but with a decreasing delay each time
+ for (int i = 0; i < cnt; ++i)
+ {
+ boost::this_thread::sleep_until(start + milliseconds(i * 500));
+ const steady_clock::time_point expected = start + milliseconds(i * 500) + seconds(cnt - i);
+ q->push(i, expected);
+ }
+}
+
+void call_pull(sync_tq* q, const steady_clock::time_point start)
+{
+ // pull elements off of the queue (earliest element first)
+ for (int i = cnt - 1; i >= 0; --i)
+ {
+ int j;
+ q->pull(j);
+ BOOST_TEST_EQ(i, j);
+ const steady_clock::time_point expected = start + milliseconds(i * 500) + seconds(cnt - i);
+ BOOST_TEST_GE(steady_clock::now(), expected - milliseconds(BOOST_THREAD_TEST_TIME_MS));
+ BOOST_TEST_LE(steady_clock::now(), expected + milliseconds(BOOST_THREAD_TEST_TIME_MS));
+ }
+}
+
+void call_pull_until(sync_tq* q, const steady_clock::time_point start)
+{
+ // pull elements off of the queue (earliest element first)
+ for (int i = cnt - 1; i >= 0; --i)
+ {
+ int j;
+ q->pull_until(steady_clock::now() + hours(1), j);
+ BOOST_TEST_EQ(i, j);
+ const steady_clock::time_point expected = start + milliseconds(i * 500) + seconds(cnt - i);
+ BOOST_TEST_GE(steady_clock::now(), expected - milliseconds(BOOST_THREAD_TEST_TIME_MS));
+ BOOST_TEST_LE(steady_clock::now(), expected + milliseconds(BOOST_THREAD_TEST_TIME_MS));
+ }
+}
+
+void call_pull_for(sync_tq* q, const steady_clock::time_point start)
+{
+ // pull elements off of the queue (earliest element first)
+ for (int i = cnt - 1; i >= 0; --i)
+ {
+ int j;
+ q->pull_for(hours(1), j);
+ BOOST_TEST_EQ(i, j);
+ const steady_clock::time_point expected = start + milliseconds(i * 500) + seconds(cnt - i);
+ BOOST_TEST_GE(steady_clock::now(), expected - milliseconds(BOOST_THREAD_TEST_TIME_MS));
+ BOOST_TEST_LE(steady_clock::now(), expected + milliseconds(BOOST_THREAD_TEST_TIME_MS));
+ }
+}
+
+void test_push_while_pull()
+{
+ sync_tq tq;
+ BOOST_TEST(tq.empty());
+ boost::thread_group tg;
+ const steady_clock::time_point start = steady_clock::now();
+ tg.create_thread(boost::bind(call_push, &tq, start));
+ tg.create_thread(boost::bind(call_pull, &tq, start));
+ tg.join_all();
+ BOOST_TEST(tq.empty());
+}
+
+void test_push_while_pull_until()
+{
+ sync_tq tq;
+ BOOST_TEST(tq.empty());
+ boost::thread_group tg;
+ const steady_clock::time_point start = steady_clock::now();
+ tg.create_thread(boost::bind(call_push, &tq, start));
+ tg.create_thread(boost::bind(call_pull_until, &tq, start));
+ tg.join_all();
+ BOOST_TEST(tq.empty());
+}
+
+void test_push_while_pull_for()
+{
+ sync_tq tq;
+ BOOST_TEST(tq.empty());
+ boost::thread_group tg;
+ const steady_clock::time_point start = steady_clock::now();
+ tg.create_thread(boost::bind(call_push, &tq, start));
+ tg.create_thread(boost::bind(call_pull_for, &tq, start));
+ tg.join_all();
+ BOOST_TEST(tq.empty());
+}
+
+int main()
+{
+ test_push_while_pull();
+ test_push_while_pull_until();
+ test_push_while_pull_for();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/tq_single_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/tq_single_thread_pass.cpp
new file mode 100644
index 000000000..dd4dfc17f
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/tq_single_thread_pass.cpp
@@ -0,0 +1,155 @@
+// Copyright (C) 2014 Ian Forbed
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+
+#include <boost/thread.hpp>
+#include <boost/chrono.hpp>
+#include <boost/function.hpp>
+#include <boost/thread/concurrent_queues/sync_timed_queue.hpp>
+#include <boost/thread/executors/work.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+
+using namespace boost::chrono;
+
+typedef boost::concurrent::sync_timed_queue<int> sync_tq;
+
+void test_all()
+{
+ sync_tq pq;
+ BOOST_TEST(pq.empty());
+ BOOST_TEST(!pq.closed());
+ BOOST_TEST_EQ(pq.size(), std::size_t(0));
+
+ for(int i = 1; i <= 5; i++){
+ pq.push(i, milliseconds(i*100));
+ BOOST_TEST(!pq.empty());
+ BOOST_TEST_EQ(pq.size(), std::size_t(i));
+ }
+
+ for(int i = 6; i <= 10; i++){
+ pq.push(i,steady_clock::now() + milliseconds(i*100));
+ BOOST_TEST(!pq.empty());
+ BOOST_TEST_EQ(pq.size(), std::size_t(i));
+ }
+
+ for(int i = 1; i <= 10; i++){
+ int val = pq.pull();
+ BOOST_TEST_EQ(val, i);
+ }
+
+ int val;
+ boost::queue_op_status st = pq.nonblocking_pull(val);
+ BOOST_TEST(boost::queue_op_status::empty == st);
+
+ BOOST_TEST(pq.empty());
+ pq.close();
+ BOOST_TEST(pq.closed());
+}
+
+void test_all_with_try()
+{
+ sync_tq pq;
+ BOOST_TEST(pq.empty());
+ BOOST_TEST(!pq.closed());
+ BOOST_TEST_EQ(pq.size(), std::size_t(0));
+
+ for(int i = 1; i <= 5; i++){
+ boost::queue_op_status st = pq.try_push(i, milliseconds(i*100));
+ BOOST_TEST(st == boost::queue_op_status::success );
+ BOOST_TEST(!pq.empty());
+ BOOST_TEST_EQ(pq.size(), std::size_t(i));
+ }
+
+ for(int i = 6; i <= 10; i++){
+ boost::queue_op_status st = pq.try_push(i,steady_clock::now() + milliseconds(i*100));
+ BOOST_TEST(st == boost::queue_op_status::success );
+ BOOST_TEST(!pq.empty());
+ BOOST_TEST_EQ(pq.size(), std::size_t(i));
+ }
+
+ for(int i = 1; i <= 10; i++){
+ int val=0;
+ boost::queue_op_status st = pq.wait_pull(val);
+ BOOST_TEST(st == boost::queue_op_status::success );
+ BOOST_TEST_EQ(val, i);
+ }
+
+ int val;
+ boost::queue_op_status st = pq.nonblocking_pull(val);
+ BOOST_TEST(st == boost::queue_op_status::empty );
+
+ BOOST_TEST(pq.empty());
+ pq.close();
+ BOOST_TEST(pq.closed());
+}
+
+void func(steady_clock::time_point pushed, steady_clock::duration dur)
+{
+ BOOST_TEST(pushed + dur <= steady_clock::now());
+}
+void func2()
+{
+ BOOST_TEST(false);
+}
+
+/**
+ * This test ensures that when items come of the front of the queue
+ * that at least $dur has elapsed.
+ */
+void test_deque_times()
+{
+ boost::concurrent::sync_timed_queue<boost::function<void()> > tq;
+ for(int i = 0; i < 10; i++)
+ {
+ steady_clock::duration d = milliseconds(i*100);
+ boost::function<void()> fn = boost::bind(func, steady_clock::now(), d);
+ tq.push(fn, d);
+ }
+ while(!tq.empty())
+ {
+ boost::function<void()> fn = tq.pull();
+ fn();
+ }
+}
+
+/**
+ * This test ensures that when items come of the front of the queue
+ * that at least $dur has elapsed.
+ */
+#if 0
+void test_deque_times2()
+{
+ boost::concurrent::sync_timed_queue<boost::executors::work> tq;
+ for(int i = 0; i < 10; i++)
+ {
+ steady_clock::duration d = milliseconds(i*100);
+ tq.push(func2, d);
+ }
+ while(!tq.empty())
+ {
+ boost::executors::work fn = tq.pull();
+ fn();
+ }
+}
+#endif
+
+int main()
+{
+ test_all();
+ test_all_with_try();
+ test_deque_times();
+ //test_deque_times2(); // rt fails
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp
new file mode 100644
index 000000000..556ca68e9
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp
@@ -0,0 +1,256 @@
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/sync_queue.hpp>
+
+// class sync_queue<T>
+
+// push || pull;
+
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/sync_queue.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/thread/barrier.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+template <typename ValueType>
+struct call_push
+{
+ boost::sync_queue<ValueType> *q_;
+ boost::barrier *go_;
+
+ call_push(boost::sync_queue<ValueType> *q, boost::barrier *go) :
+ q_(q), go_(go)
+ {
+ }
+ typedef void result_type;
+ void operator()()
+ {
+ go_->count_down_and_wait();
+ q_->push(42);
+ }
+};
+
+template <typename ValueType>
+struct call_pull
+{
+ boost::sync_queue<ValueType> *q_;
+ boost::barrier *go_;
+
+ call_pull(boost::sync_queue<ValueType> *q, boost::barrier *go) :
+ q_(q), go_(go)
+ {
+ }
+ typedef ValueType result_type;
+ ValueType operator()()
+ {
+ go_->count_down_and_wait();
+ return q_->pull();
+ }
+};
+
+template <typename ValueType>
+struct call_wait_pull
+{
+ boost::sync_queue<ValueType> *q_;
+ boost::barrier *go_;
+
+ call_wait_pull(boost::sync_queue<ValueType> *q, boost::barrier *go) :
+ q_(q), go_(go)
+ {
+ }
+ typedef boost::queue_op_status result_type;
+ boost::queue_op_status operator()(ValueType& v)
+ {
+ go_->wait();
+ return q_->wait_pull(v);
+ }
+};
+
+void test_concurrent_push_and_pull_on_empty_queue()
+{
+ boost::sync_queue<int> q;
+
+ boost::barrier go(2);
+
+ boost::future<void> push_done;
+ boost::future<int> pull_done;
+
+ try
+ {
+ push_done=boost::async(boost::launch::async,
+ call_push<int>(&q,&go));
+ pull_done=boost::async(boost::launch::async,
+ call_pull<int>(&q,&go));
+
+ push_done.get();
+ BOOST_TEST_EQ(pull_done.get(), 42);
+ BOOST_TEST(q.empty());
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+}
+
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+void test_concurrent_push_and_wait_pull_on_empty_queue()
+{
+ boost::sync_queue<int> q;
+ const unsigned int n = 3;
+ boost::barrier go(n);
+
+ boost::future<boost::queue_op_status> pull_done[n];
+ int results[n];
+
+ try
+ {
+ for (unsigned int i =0; i< n; ++i)
+ pull_done[i]=boost::async(boost::launch::async,
+ call_wait_pull<int>(&q,&go),
+ boost::ref(results[i]));
+
+ for (unsigned int i =0; i< n; ++i)
+ q.push(42);
+
+ for (unsigned int i = 0; i < n; ++i) {
+ BOOST_TEST(pull_done[i].get() == boost::queue_op_status::success);
+ BOOST_TEST_EQ(results[i], 42);
+ }
+ BOOST_TEST(q.empty());
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+}
+
+void test_concurrent_wait_pull_and_close_on_empty_queue()
+{
+ boost::sync_queue<int> q;
+ const unsigned int n = 3;
+ boost::barrier go(n);
+
+ boost::future<boost::queue_op_status> pull_done[n];
+ int results[n];
+
+ try
+ {
+ for (unsigned int i =0; i< n; ++i)
+ pull_done[i]=boost::async(boost::launch::async,
+ call_wait_pull<int>(&q,&go),
+ boost::ref(results[i]));
+
+ q.close();
+
+ for (unsigned int i = 0; i < n; ++i) {
+ BOOST_TEST(pull_done[i].get() == boost::queue_op_status::closed);
+ }
+ BOOST_TEST(q.empty());
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+}
+#endif
+
+void test_concurrent_push_on_empty_queue()
+{
+ boost::sync_queue<int> q;
+ const unsigned int n = 3;
+ boost::barrier go(n);
+ boost::future<void> push_done[n];
+
+ try
+ {
+ for (unsigned int i =0; i< n; ++i)
+ push_done[i]=boost::async(boost::launch::async,
+ call_push<int>(&q,&go));
+
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ try
+ {
+ for (unsigned int i = 0; i < n; ++i)
+ push_done[i].get();
+
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+ try
+ {
+ BOOST_TEST(!q.empty());
+ for (unsigned int i =0; i< n; ++i)
+ BOOST_TEST_EQ(q.pull(), 42);
+ BOOST_TEST(q.empty());
+
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+}
+
+void test_concurrent_pull_on_queue()
+{
+ boost::sync_queue<int> q;
+ const unsigned int n = 3;
+ boost::barrier go(n);
+
+ boost::future<int> pull_done[n];
+
+ try
+ {
+ for (unsigned int i =0; i< n; ++i)
+ q.push(42);
+
+ for (unsigned int i =0; i< n; ++i)
+ pull_done[i]=boost::async(boost::launch::async,
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+ [&q,&go]() -> int
+ {
+ go.wait();
+ return q.pull();
+ }
+#else
+ call_pull<int>(&q,&go)
+#endif
+ );
+
+ for (unsigned int i = 0; i < n; ++i)
+ BOOST_TEST_EQ(pull_done[i].get(), 42);
+ BOOST_TEST(q.empty());
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ }
+}
+
+int main()
+{
+ test_concurrent_push_and_pull_on_empty_queue();
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ test_concurrent_push_and_wait_pull_on_empty_queue();
+ test_concurrent_wait_pull_and_close_on_empty_queue();
+#endif
+ test_concurrent_push_on_empty_queue();
+ test_concurrent_pull_on_queue();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_queue/single_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_queue/single_thread_pass.cpp
new file mode 100644
index 000000000..8f47ec82a
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_queue/single_thread_pass.cpp
@@ -0,0 +1,374 @@
+// Copyright (C) 2013,2015 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/sync_queue.hpp>
+
+// class sync_queue<T>
+
+// sync_queue();
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/sync_queue.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+class non_copyable
+{
+ BOOST_THREAD_MOVABLE_ONLY(non_copyable)
+ int val;
+public:
+ non_copyable(int v) : val(v){}
+ non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {}
+ non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; }
+ bool operator==(non_copyable const& x) const {return val==x.val;}
+ template <typename OSTREAM>
+ friend OSTREAM& operator <<(OSTREAM& os, non_copyable const&x )
+ {
+ os << x.val;
+ return os;
+ }
+
+};
+
+
+
+int main()
+{
+
+ {
+ // default queue invariants
+ boost::sync_queue<int> q;
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ {
+ // empty queue push rvalue/non_copyable succeeds
+ boost::sync_queue<non_copyable> q;
+ q.push(non_copyable(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // empty queue push rvalue/non_copyable succeeds
+ boost::sync_queue<non_copyable> q;
+ non_copyable nc(1);
+ q.push(boost::move(nc));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+
+ {
+ // empty queue push rvalue succeeds
+ boost::sync_queue<int> q;
+ q.push(1);
+ q.push(2);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 2u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue push lvalue succeeds
+ boost::sync_queue<int> q;
+ int i;
+ q.push(i);
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue/copyable succeeds
+ boost::sync_queue<int> q;
+ BOOST_TEST(boost::queue_op_status::success == q.try_push(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue/copyable succeeds
+ boost::sync_queue<int> q;
+ BOOST_TEST(boost::queue_op_status::success == q.try_push(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ {
+ // empty queue try_push rvalue/non-copyable succeeds
+ boost::sync_queue<non_copyable> q;
+ BOOST_TEST(boost::queue_op_status::success ==q.try_push(non_copyable(1)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // empty queue try_push rvalue/non-copyable succeeds
+ boost::sync_queue<non_copyable> q;
+ non_copyable nc(1);
+ BOOST_TEST(boost::queue_op_status::success == q.try_push(boost::move(nc)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+
+ {
+ // empty queue try_push lvalue succeeds
+ boost::sync_queue<int> q;
+ int i=1;
+ BOOST_TEST(boost::queue_op_status::success == q.try_push(i));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // empty queue try_push rvalue succeeds
+ boost::sync_queue<int> q;
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(1));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ {
+ // empty queue nonblocking_push rvalue/non-copyable succeeds
+ boost::sync_queue<non_copyable> q;
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(non_copyable(1)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+#endif
+ {
+ // empty queue nonblocking_push rvalue/non-copyable succeeds
+ boost::sync_queue<non_copyable> q;
+ non_copyable nc(1);
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(boost::move(nc)));
+ BOOST_TEST(! q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 1u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull succeed
+ boost::sync_queue<int> q;
+ q.push(1);
+ int i;
+ q.pull(i);
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull succeed
+ boost::sync_queue<non_copyable> q;
+ non_copyable nc1(1);
+ q.push(boost::move(nc1));
+ non_copyable nc2(2);
+ q.pull(nc2);
+ BOOST_TEST_EQ(nc1, nc2);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull succeed
+ boost::sync_queue<int> q;
+ q.push(1);
+ int i = q.pull();
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue pull succeed
+ boost::sync_queue<non_copyable> q;
+ non_copyable nc1(1);
+ q.push(boost::move(nc1));
+ non_copyable nc = q.pull();
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue try_pull succeed
+ boost::sync_queue<int> q;
+ q.push(1);
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.try_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue try_pull succeed
+ boost::sync_queue<non_copyable> q;
+ non_copyable nc1(1);
+ q.push(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.try_pull(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue nonblocking_pull succeed
+ boost::sync_queue<int> q;
+ q.push(1);
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue nonblocking_pull succeed
+ boost::sync_queue<non_copyable> q;
+ non_copyable nc1(1);
+ q.push(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue wait_pull succeed
+ boost::sync_queue<non_copyable> q;
+ non_copyable nc1(1);
+ q.push(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue wait_pull succeed
+ boost::sync_queue<int> q;
+ q.push(1);
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+ {
+ // 1-element queue wait_pull succeed
+ boost::sync_queue<non_copyable> q;
+ non_copyable nc1(1);
+ q.push(boost::move(nc1));
+ non_copyable nc(2);
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc));
+ BOOST_TEST_EQ(nc, nc1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(! q.closed());
+ }
+
+ {
+ // closed invariants
+ boost::sync_queue<int> q;
+ q.close();
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed queue push fails
+ boost::sync_queue<int> q;
+ q.close();
+ try {
+ q.push(1);
+ BOOST_TEST(false);
+ } catch (...) {
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ }
+ {
+ // 1-element closed queue pull succeed
+ boost::sync_queue<int> q;
+ q.push(1);
+ q.close();
+ int i;
+ q.pull(i);
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // 1-element closed queue wait_pull succeed
+ boost::sync_queue<int> q;
+ q.push(1);
+ q.close();
+ int i;
+ BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i));
+ BOOST_TEST_EQ(i, 1);
+ BOOST_TEST(q.empty());
+ BOOST_TEST(! q.full());
+ BOOST_TEST_EQ(q.size(), 0u);
+ BOOST_TEST(q.closed());
+ }
+ {
+ // closed empty queue wait_pull fails
+ boost::sync_queue<int> q;
+ q.close();
+ BOOST_TEST(q.empty());
+ BOOST_TEST(q.closed());
+ int i;
+ BOOST_TEST(boost::queue_op_status::closed == q.wait_pull(i));
+ BOOST_TEST(q.empty());
+ BOOST_TEST(q.closed());
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/call_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/call_pass.cpp
new file mode 100644
index 000000000..f1ed8be4a
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/call_pass.cpp
@@ -0,0 +1,144 @@
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/synchronized_value.hpp>
+
+// class synchronized_value<T,M>
+
+// template <typename F>
+// inline typename boost::result_of<F(value_type&)>::type
+// operator()(BOOST_THREAD_RV_REF(F) fct);
+// template <typename F>
+// inline typename boost::result_of<F(value_type const&)>::type
+// operator()(BOOST_THREAD_RV_REF(F) fct) const;
+
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/synchronized_value.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+struct S {
+ int f() const {return 1;}
+ int g() {return 1;}
+};
+
+void c(S const& s)
+{
+ BOOST_TEST(s.f()==1);
+}
+
+void nc(S & s)
+{
+ BOOST_TEST(s.f()==1);
+ BOOST_TEST(s.g()==1);
+}
+
+struct cfctr {
+ typedef void result_type;
+ void operator()(S const& s) const {
+ BOOST_TEST(s.f()==1);
+ }
+};
+struct ncfctr {
+ typedef void result_type;
+ void operator()(S& s) const {
+ BOOST_TEST(s.f()==1);
+ BOOST_TEST(s.g()==1);
+ }
+};
+
+struct cfctr3 {
+ typedef void result_type;
+ BOOST_THREAD_MOVABLE_ONLY(cfctr3)
+ cfctr3()
+ {}
+ cfctr3(BOOST_THREAD_RV_REF(cfctr3))
+ {}
+ void operator()(S const& s) const {
+ BOOST_TEST(s.f()==1);
+ }
+};
+struct ncfctr3 {
+ typedef void result_type;
+ BOOST_THREAD_MOVABLE_ONLY(ncfctr3)
+ ncfctr3()
+ {}
+ ncfctr3(BOOST_THREAD_RV_REF(ncfctr3))
+ {}
+ void operator()(S& s) const {
+ BOOST_TEST(s.f()==1);
+ BOOST_TEST(s.g()==1);
+ }
+};
+
+cfctr3 make_cfctr3() {
+ return BOOST_THREAD_MAKE_RV_REF(cfctr3());
+}
+
+ncfctr3 make_ncfctr3() {
+ return BOOST_THREAD_MAKE_RV_REF(ncfctr3());
+}
+
+int main()
+{
+ {
+ boost::synchronized_value<S> v;
+ v(&nc);
+ v(&c);
+ }
+ {
+ const boost::synchronized_value<S> v;
+ v(&c);
+ }
+ {
+ boost::synchronized_value<S> v;
+ v(ncfctr());
+ }
+ {
+ const boost::synchronized_value<S> v;
+ v(cfctr());
+ }
+ {
+ boost::synchronized_value<S> v;
+ ncfctr fct;
+ v(fct);
+ }
+ {
+ const boost::synchronized_value<S> v;
+ cfctr fct;
+ v(fct);
+ }
+ {
+ boost::synchronized_value<S> v;
+ v(make_ncfctr3());
+ }
+ {
+ const boost::synchronized_value<S> v;
+ v(make_cfctr3());
+ }
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+ {
+ boost::synchronized_value<S> v;
+ v([](S& s) {
+ BOOST_TEST(s.f()==1);
+ BOOST_TEST(s.g()==1);
+ });
+ }
+ {
+ const boost::synchronized_value<S> v;
+ v([](S const& s) {
+ BOOST_TEST(s.f()==1);
+ });
+ }
+#endif
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_T_assign_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_T_assign_pass.cpp
new file mode 100644
index 000000000..3b43f8f90
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_T_assign_pass.cpp
@@ -0,0 +1,30 @@
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/synchronized_value.hpp>
+
+// class synchronized_value<T,M>
+
+// synchronized_value& operator=(T const&);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/synchronized_value.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ int i = 1;
+ boost::synchronized_value<int> v;
+ v = i;
+ BOOST_TEST(v.value() == 1);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_T_ctor_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_T_ctor_pass.cpp
new file mode 100644
index 000000000..e395c57aa
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_T_ctor_pass.cpp
@@ -0,0 +1,29 @@
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/synchronized_value.hpp>
+
+// class synchronized_value<T,M>
+
+// synchronized_value(T const&);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/synchronized_value.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ int i = 1;
+ boost::synchronized_value<int> v(i);
+ BOOST_TEST(v.value() == 1);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_assign_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_assign_pass.cpp
new file mode 100644
index 000000000..d4e80b0ce
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_assign_pass.cpp
@@ -0,0 +1,31 @@
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/synchronized_value.hpp>
+
+// class synchronized_value<T,M>
+
+// synchronized_value& operator=(synchronized_value const&);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/synchronized_value.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ int i = 1;
+ boost::synchronized_value<int> v1(i);
+ boost::synchronized_value<int> v2;
+ v2 = v1;
+ BOOST_TEST(v2.value() == 1);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_ctor_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_ctor_pass.cpp
new file mode 100644
index 000000000..13fcf6d80
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_ctor_pass.cpp
@@ -0,0 +1,30 @@
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/synchronized_value.hpp>
+
+// class synchronized_value<T,M>
+
+// synchronized_value(synchronized_value const&);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/synchronized_value.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ int i = 1;
+ boost::synchronized_value<int> v1(i);
+ boost::synchronized_value<int> v2(v1);
+ BOOST_TEST(v2.value() == 1);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/default_ctor_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/default_ctor_pass.cpp
new file mode 100644
index 000000000..7b4095650
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/default_ctor_pass.cpp
@@ -0,0 +1,30 @@
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/synchronized_value.hpp>
+
+// class synchronized_value<T,M>
+
+// synchronized_value();
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/synchronized_value.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ boost::synchronized_value<int, boost::mutex > f;
+ }
+ {
+ boost::synchronized_value<int, boost::timed_mutex> f;
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/indirect_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/indirect_pass.cpp
new file mode 100644
index 000000000..09b8e89d2
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/indirect_pass.cpp
@@ -0,0 +1,38 @@
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/synchronized_value.hpp>
+
+// class synchronized_value<T,M>
+
+// strict_lock_ptr<T,M> operator->();
+// const_strict_lock_ptr<T,M> operator->() const;
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/synchronized_value.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+struct S {
+ int f() const {return 1;}
+ int g() {return 1;}
+};
+
+int main()
+{
+ {
+ boost::synchronized_value<S> v;
+ BOOST_TEST(v->f()==1);
+ BOOST_TEST(v->g()==1);
+ }
+ {
+ const boost::synchronized_value<S> v;
+ BOOST_TEST(v->f()==1);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_T_assign_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_T_assign_pass.cpp
new file mode 100644
index 000000000..146ed2e51
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_T_assign_pass.cpp
@@ -0,0 +1,29 @@
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/synchronized_value.hpp>
+
+// class synchronized_value<T,M>
+
+// synchronized_value& operator=(T &&);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/synchronized_value.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ boost::synchronized_value<int> v;
+ v = 1;
+ BOOST_TEST(v.value() == 1);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_T_ctor_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_T_ctor_pass.cpp
new file mode 100644
index 000000000..564d57da8
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_T_ctor_pass.cpp
@@ -0,0 +1,28 @@
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/synchronized_value.hpp>
+
+// class synchronized_value<T,M>
+
+// synchronized_value(T &&);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/synchronized_value.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ boost::synchronized_value<int> v(1);
+ BOOST_TEST(v.value() == 1);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_assign_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_assign_pass.cpp
new file mode 100644
index 000000000..818216382
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_assign_pass.cpp
@@ -0,0 +1,30 @@
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/synchronized_value.hpp>
+
+// class synchronized_value<T,M>
+
+// synchronized_value& operator=(synchronized_value &&);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/synchronized_value.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ boost::synchronized_value<int> v1(1);
+ boost::synchronized_value<int> v2;
+ v2 = boost::move(v1);
+ BOOST_TEST(v2.value() == 1);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_ctor_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_ctor_pass.cpp
new file mode 100644
index 000000000..7250e896f
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_ctor_pass.cpp
@@ -0,0 +1,29 @@
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/synchronized_value.hpp>
+
+// class synchronized_value<T,M>
+
+// synchronized_value(synchronized_value &&);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/synchronized_value.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ boost::synchronized_value<int> v1(1);
+ boost::synchronized_value<int> v2(boost::move(v1));
+ BOOST_TEST(v2.value() == 1);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/swap_T_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/swap_T_pass.cpp
new file mode 100644
index 000000000..801b514d6
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/swap_T_pass.cpp
@@ -0,0 +1,38 @@
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/synchronized_value.hpp>
+
+// class synchronized_value<T,M>
+
+// void swap(synchronized_value&,synchronized_value&);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/synchronized_value.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ boost::synchronized_value<int> v1(1);
+ int v2(2);
+ boost::swap(v1,v2);
+ BOOST_TEST(v1.value() == 2);
+ BOOST_TEST(v2 == 1);
+ }
+ {
+ boost::synchronized_value<int> v1(1);
+ int v2(2);
+ boost::swap(v2,v1);
+ BOOST_TEST(v1.value() == 2);
+ BOOST_TEST(v2 == 1);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/swap_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/swap_pass.cpp
new file mode 100644
index 000000000..c52069ff3
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/swap_pass.cpp
@@ -0,0 +1,31 @@
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/synchronized_value.hpp>
+
+// class synchronized_value<T,M>
+
+// void swap(synchronized_value&,synchronized_value&);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/synchronized_value.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+
+ {
+ boost::synchronized_value<int> v1(1);
+ boost::synchronized_value<int> v2(2);
+ swap(v1,v2);
+ BOOST_TEST(v1.value() == 2);
+ BOOST_TEST(v2.value() == 1);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/synchronize_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/synchronize_pass.cpp
new file mode 100644
index 000000000..af24d79b6
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/synchronize_pass.cpp
@@ -0,0 +1,41 @@
+// Copyright (C) 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/synchronized_value.hpp>
+
+// class synchronized_value<T,M>
+
+// strict_lock_ptr<T,M> synchronize();
+// const_strict_lock_ptr<T,M> synchronize() const;
+
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/synchronized_value.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+struct S {
+ int f() const {return 1;}
+ int g() {return 1;}
+};
+
+int main()
+{
+ {
+ boost::synchronized_value<S> v;
+ boost::strict_lock_ptr<S> ptr = v.synchronize();
+ BOOST_TEST(ptr->f()==1);
+ BOOST_TEST(ptr->g()==1);
+ }
+ {
+ const boost::synchronized_value<S> v;
+ boost::const_strict_lock_ptr<S> ptr = v.synchronize();
+ BOOST_TEST(ptr->f()==1);
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/assign_fail.cpp
new file mode 100644
index 000000000..49188e130
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/timed_mutex.hpp>
+
+// class timed_mutex;
+
+// timed_mutex& operator=(const timed_mutex&) = delete;
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::timed_mutex m0;
+ boost::timed_mutex m1(m0);
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/copy_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/copy_fail.cpp
new file mode 100644
index 000000000..ed0a4c955
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/copy_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/timed_mutex.hpp>
+
+// class timed_mutex;
+
+// timed_mutex(const timed_mutex&) = delete;
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::timed_mutex m0;
+ boost::timed_mutex m1(m0);
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/default_pass.cpp
new file mode 100644
index 000000000..6b7c6f2b3
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/default_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/timed_mutex.hpp>
+
+// class timed_mutex;
+
+// timed_mutex();
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::timed_mutex m0;
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/lock_pass.cpp
new file mode 100644
index 000000000..8d2733e1f
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/lock_pass.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/timed_mutex.hpp>
+
+// class timed_mutex;
+
+// void lock();
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+boost::timed_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ m.lock();
+ t1 = Clock::now();
+ m.unlock();
+#else
+ //time_point t0 = Clock::now();
+ m.lock();
+ //time_point t1 = Clock::now();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/native_handle_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/native_handle_pass.cpp
new file mode 100644
index 000000000..b203e5d91
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/native_handle_pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/timed_mutex.hpp>
+
+// class timed_mutex;
+
+// typedef pthread_timed_mutex_t* native_handle_type;
+// native_handle_type native_handle();
+
+#include <boost/thread/mutex.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+int main()
+{
+#if defined BOOST_THREAD_DEFINES_TIMED_MUTEX_NATIVE_HANDLE
+ boost::timed_mutex m;
+ boost::timed_mutex::native_handle_type h = m.native_handle();
+ BOOST_TEST(h);
+#else
+#error "Test not applicable: BOOST_THREAD_DEFINES_TIMED_MUTEX_NATIVE_HANDLE not defined for this platform as not supported"
+#endif
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_for_pass.cpp
new file mode 100644
index 000000000..94d790e0e
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/timed_mutex.hpp>
+
+// class timed_mutex;
+
+// template <class Rep, class Period>
+// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+boost::timed_mutex m;
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f1()
+{
+ t0 = Clock::now();
+ BOOST_TEST(m.try_lock_for(ms(750)) == true);
+ t1 = Clock::now();
+ m.unlock();
+}
+
+void f2()
+{
+ t0 = Clock::now();
+ BOOST_TEST(m.try_lock_for(ms(250)) == false);
+ t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+ m.unlock();
+ t.join();
+
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(750));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_pass.cpp
new file mode 100644
index 000000000..96e99e7f7
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_pass.cpp
@@ -0,0 +1,92 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/timed_mutex.hpp>
+
+// class timed_mutex;
+
+// bool try_lock();
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+
+boost::timed_mutex m;
+
+#if defined BOOST_THREAD_USES_CHRONO
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+#else
+#endif
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f()
+{
+#if defined BOOST_THREAD_USES_CHRONO
+ t0 = Clock::now();
+ BOOST_TEST(!m.try_lock());
+ BOOST_TEST(!m.try_lock());
+ BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ t1 = Clock::now();
+ m.unlock();
+#else
+ //time_point t0 = Clock::now();
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ //BOOST_TEST(!m.try_lock());
+ while (!m.try_lock())
+ ;
+ //time_point t1 = Clock::now();
+ m.unlock();
+ //ns d = t1 - t0 - ms(250);
+ //BOOST_TEST(d < max_diff);
+#endif
+}
+
+int main()
+{
+ m.lock();
+ boost::thread t(f);
+#if defined BOOST_THREAD_USES_CHRONO
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+#else
+#endif
+ m.unlock();
+ t.join();
+
+#if defined BOOST_THREAD_USES_CHRONO
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+#endif
+
+ return boost::report_errors();
+}
+
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_until_pass.cpp
new file mode 100644
index 000000000..958a42d03
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_until_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/timed_mutex.hpp>
+
+// class timed_mutex;
+
+// template <class Clock, class Duration>
+// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "../../../timming.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+boost::timed_mutex m;
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point time_point;
+typedef Clock::duration duration;
+typedef boost::chrono::milliseconds ms;
+typedef boost::chrono::nanoseconds ns;
+time_point t0;
+time_point t1;
+
+const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
+
+void f1()
+{
+ t0 = Clock::now();
+ BOOST_TEST(m.try_lock_until(Clock::now() + ms(750)) == true);
+ t1 = Clock::now();
+ m.unlock();
+}
+
+void f2()
+{
+ t0 = Clock::now();
+ BOOST_TEST(m.try_lock_until(Clock::now() + ms(250)) == false);
+ t1 = Clock::now();
+ ns d = t1 - t0 - ms(250);
+ BOOST_THREAD_TEST_IT(d, ns(max_diff));
+}
+
+int main()
+{
+ {
+ m.lock();
+ boost::thread t(f1);
+ time_point t2 = Clock::now();
+ boost::this_thread::sleep_for(ms(250));
+ time_point t3 = Clock::now();
+ m.unlock();
+ t.join();
+
+ ns sleep_time = t3 - t2;
+ ns d_ns = t1 - t0 - sleep_time;
+ ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns);
+ // BOOST_TEST_GE(d_ms.count(), 0);
+ BOOST_THREAD_TEST_IT(d_ms, max_diff);
+ BOOST_THREAD_TEST_IT(d_ns, ns(max_diff));
+ }
+ {
+ m.lock();
+ boost::thread t(f2);
+ boost::this_thread::sleep_for(ms(750));
+ m.unlock();
+ t.join();
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_bind.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_bind.cpp
new file mode 100644
index 000000000..9ec0dfdfb
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_bind.cpp
@@ -0,0 +1,145 @@
+// (C) Copyright 2013 Ruslan Baratov
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See www.boost.org/libs/thread for documentation.
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/detail/lightweight_test.hpp> // BOOST_TEST
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/with_lock_guard.hpp>
+#include <boost/bind/bind.hpp>
+
+class Foo {
+ public:
+ Foo(int value): value_(value) {
+ }
+
+ int func(int a, int b) const {
+ BOOST_TEST(a == 1);
+ BOOST_TEST(b == 31);
+ return a + b + value_;
+ }
+
+ int func_ref(int& a) const {
+ a = 133;
+ return 36;
+ }
+
+ void func_ref(int& a, int& b, int* c) const {
+ BOOST_TEST(value_ == 3);
+ a = 567;
+ b = 897;
+ *c = 345;
+ }
+
+ private:
+ int value_;
+};
+
+void test_bind() {
+ boost::mutex m;
+
+ Foo foo(2);
+
+ int res_bind = boost::with_lock_guard(
+ m,
+ boost::bind(&Foo::func, foo, 1, 31)
+ );
+ BOOST_TEST(res_bind == 34);
+
+ int a = 0;
+ int res_bind_ref = boost::with_lock_guard(
+ m,
+ boost::bind(&Foo::func_ref, foo, boost::ref(a))
+ );
+ BOOST_TEST(res_bind_ref == 36);
+ BOOST_TEST(a == 133);
+
+ a = 0;
+ int b = 0;
+ int c = 0;
+ Foo boo(3);
+ boost::with_lock_guard(
+ m, boost::bind(&Foo::func_ref, boo, boost::ref(a), boost::ref(b), &c)
+ );
+ BOOST_TEST(a == 567);
+ BOOST_TEST(b == 897);
+ BOOST_TEST(c == 345);
+}
+
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+void test_bind_non_const() {
+ std::cout << "c++11 variadic templates disabled" << std::endl;
+}
+#else
+
+// calling non-const bind methods supported only with c++11 variadic templates
+class Boo {
+ public:
+ Boo(int value): value_(value) {
+ }
+
+ int func(int a, int b) {
+ BOOST_TEST(a == 7);
+ BOOST_TEST(b == 3);
+ return a - b + value_;
+ }
+
+ int func_ref(int& a) {
+ a = 598;
+ return 23;
+ }
+
+ void func_ref(int& a, int& b, int* c) {
+ BOOST_TEST(value_ == 67);
+ a = 111;
+ b = 222;
+ *c = 333;
+ }
+
+ private:
+ int value_;
+};
+
+void test_bind_non_const() {
+ boost::mutex m;
+
+ Boo boo(20);
+
+ int res_bind = boost::with_lock_guard(
+ m,
+ boost::bind(&Boo::func, boo, 7, 3)
+ );
+ BOOST_TEST(res_bind == 24);
+
+ int a = 0;
+ int res_bind_ref = boost::with_lock_guard(
+ m,
+ boost::bind(&Boo::func_ref, boo, boost::ref(a))
+ );
+ BOOST_TEST(res_bind_ref == 23);
+ BOOST_TEST(a == 598);
+
+ a = 0;
+ int b = 0;
+ int c = 0;
+ Boo foo(67);
+ boost::with_lock_guard(
+ m, boost::bind(&Boo::func_ref, foo, boost::ref(a), boost::ref(b), &c)
+ );
+ BOOST_TEST(a == 111);
+ BOOST_TEST(b == 222);
+ BOOST_TEST(c == 333);
+}
+#endif
+
+int main() {
+ test_bind();
+ test_bind_non_const();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_lambda.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_lambda.cpp
new file mode 100644
index 000000000..8eda53dea
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_lambda.cpp
@@ -0,0 +1,59 @@
+// (C) Copyright 2013 Ruslan Baratov
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See www.boost.org/libs/thread for documentation.
+
+#include <boost/config.hpp>
+
+#if !defined(BOOST_NO_CXX11_DECLTYPE)
+# define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/detail/lightweight_test.hpp> // BOOST_TEST
+
+#include <iostream> // std::cout
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/with_lock_guard.hpp>
+
+#if defined(BOOST_NO_CXX11_LAMBDAS) || (defined BOOST_MSVC && _MSC_VER < 1700)
+void test_lambda() {
+ std::cout << "C++11 lambda disabled" << std::endl;
+}
+#else
+void test_lambda() {
+ boost::mutex m;
+ int res_1 = boost::with_lock_guard(
+ m,
+ [](int a) {
+ BOOST_TEST(a == 13);
+ return a + 3;
+ },
+ 13
+ );
+ BOOST_TEST(res_1 == 16);
+
+ int v = 0;
+ int res_2 = boost::with_lock_guard(
+ m,
+ [&v](int a) {
+ BOOST_TEST(a == 55);
+ v = 15;
+ return 45;
+ },
+ 55
+ );
+ BOOST_TEST(res_2 == 45);
+ BOOST_TEST(v == 15);
+}
+#endif
+
+int main() {
+ std::cout << std::boolalpha;
+ test_lambda();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_move.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_move.cpp
new file mode 100644
index 000000000..2c685790d
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_move.cpp
@@ -0,0 +1,110 @@
+// (C) Copyright 2013 Ruslan Baratov
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See www.boost.org/libs/thread for documentation.
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/detail/lightweight_test.hpp> // BOOST_TEST
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/with_lock_guard.hpp>
+
+class Foo {
+ public:
+ explicit Foo(int a) : a_(a) {
+ }
+
+ Foo(BOOST_RV_REF(Foo) foo) : a_(foo.a_) {
+ BOOST_ASSERT(&foo != this);
+ foo.a_ = 0;
+ }
+
+ Foo& operator=(BOOST_RV_REF(Foo) foo) {
+ BOOST_ASSERT(&foo != this);
+ a_ = foo.a_;
+ foo.a_ = 0;
+ return *this;
+ }
+
+ int get() const {
+ return a_;
+ }
+
+ private:
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(Foo)
+
+ int a_;
+};
+
+template <class T1, class T2>
+bool func_with_2_arg(BOOST_FWD_REF(T1) arg_1, BOOST_FWD_REF(T2) arg_2) {
+ BOOST_TEST(arg_1.get() == 3);
+ BOOST_TEST(arg_2.get() == 767);
+ return false;
+}
+
+void test_movable() {
+ boost::mutex m;
+
+ Foo foo_1(3);
+ Foo foo_2(767);
+
+ bool res = boost::with_lock_guard(
+ m, &func_with_2_arg<Foo, Foo>, boost::move(foo_1), boost::move(foo_2)
+ );
+ BOOST_TEST(!res);
+}
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+void test_real_movable() {
+ std::cout << "c++11 move emulated" << std::endl;
+}
+#else
+// test real one
+class Boo {
+ public:
+ Boo(int a) : a_(a) {
+ }
+
+ Boo(Boo&& boo) : a_(boo.a_) {
+ BOOST_ASSERT(&boo != this);
+ boo.a_ = 0;
+ }
+
+ int get() const {
+ return a_;
+ }
+
+ BOOST_DELETED_FUNCTION(Boo(Boo&))
+ BOOST_DELETED_FUNCTION(Boo& operator=(Boo&))
+ BOOST_DELETED_FUNCTION(Boo& operator=(Boo&&))
+ private:
+ int a_;
+};
+
+void func_with_3_arg(Boo&& boo_1, Boo&& boo_2, Boo&& boo_3) {
+ BOOST_TEST(boo_1.get() == 11);
+ BOOST_TEST(boo_2.get() == 12);
+ BOOST_TEST(boo_3.get() == 13);
+}
+
+void test_real_movable() {
+ boost::mutex m;
+
+ Boo boo_3(13);
+
+ boost::with_lock_guard(
+ m, func_with_3_arg, Boo(11), Boo(12), boost::move(boo_3)
+ );
+}
+#endif
+
+int main() {
+ test_movable();
+ test_real_movable();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_simple.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_simple.cpp
new file mode 100644
index 000000000..dc9c44455
--- /dev/null
+++ b/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_simple.cpp
@@ -0,0 +1,139 @@
+// (C) Copyright 2013 Ruslan Baratov
+// (C) Copyright 2013 Ruslan Baratov
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See www.boost.org/libs/thread for documentation.
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/detail/lightweight_test.hpp> // BOOST_TEST
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/with_lock_guard.hpp>
+#include <boost/ref.hpp>
+
+void func_with_0_arg() {
+}
+
+void func_with_1_arg(int arg_1) {
+ BOOST_TEST(arg_1 == 3);
+}
+
+bool func_with_2_arg(int arg_1, bool arg_2) {
+ BOOST_TEST(arg_1 == 3);
+ BOOST_TEST(arg_2 == true);
+ return !arg_2;
+}
+
+int func_with_3_arg(int arg_1, bool arg_2, const char* arg_3) {
+ BOOST_TEST(arg_1 == 13);
+ BOOST_TEST(arg_2 == false);
+ BOOST_TEST(std::string(arg_3) == "message for func with 3 arg");
+ return 12;
+}
+
+const char* func_with_4_arg(int arg_1, bool arg_2, int* arg_3, int& arg_4) {
+ BOOST_TEST(arg_1 == 23);
+ BOOST_TEST(arg_2 == false);
+ *arg_3 = 128;
+ arg_4 = 456;
+ return "hello";
+}
+
+void test_simple() {
+ boost::mutex m;
+
+ // #0
+ boost::with_lock_guard(m, func_with_0_arg);
+
+ // #1
+ boost::with_lock_guard(m, func_with_1_arg, 3);
+
+ // #2
+ bool res2 = boost::with_lock_guard(m, func_with_2_arg, 3, true);
+ BOOST_TEST(res2 == false);
+
+ // #3
+ int arg1 = 13;
+ const char* mes = "message for func with 3 arg";
+ int res3 = boost::with_lock_guard(m, func_with_3_arg, arg1, false, mes);
+ BOOST_TEST(res3 == 12);
+
+ // #4
+ int arg3 = 0;
+ int arg4 = 0;
+ const char* res4 = boost::with_lock_guard(
+ m,
+ func_with_4_arg,
+ 23,
+ false,
+ &arg3,
+ boost::ref(arg4)
+ );
+ BOOST_TEST(arg3 == 128);
+ BOOST_TEST(arg4 == 456);
+ BOOST_TEST(std::string(res4) == "hello");
+}
+
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+void test_variadic_templates() {
+ std::cout << "C++11 variadic templates disabled" << std::endl;
+}
+#else
+int func_with_5_args(int a1, char a2, int& a3, bool* a4, bool a5) {
+ BOOST_TEST(a1 == 12);
+ BOOST_TEST(a2 == 'x');
+ BOOST_TEST(a5 == false);
+ a3 = 135;
+ *a4 = false;
+ return 45;
+}
+
+int func_with_6_args(int a1, char a2, int& a3, bool* a4, int&& a5, bool a6) {
+ BOOST_TEST(a1 == 12);
+ BOOST_TEST(a2 == 'N');
+ BOOST_TEST(a5 == 2 || a5 == 13);
+ BOOST_TEST(a6 == false);
+ a3 = 200;
+ *a4 = true;
+ return 888;
+}
+
+void test_variadic_templates() {
+ boost::mutex m;
+
+ int a3 = 0;
+ bool a4 = true;
+ int res5 = boost::with_lock_guard(
+ m, func_with_5_args, 12, 'x', a3, &a4, false
+ );
+ BOOST_TEST(a3 == 135);
+ BOOST_TEST(a4 == false);
+ BOOST_TEST(res5 == 45);
+
+ int res6 = boost::with_lock_guard(
+ m, func_with_6_args, 12, 'N', a3, &a4, 2, false
+ );
+ BOOST_TEST(a3 == 200);
+ BOOST_TEST(a4 == true);
+ BOOST_TEST(res6 == 888);
+
+ a3 = 0;
+ a4 = false;
+ int a5 = 13;
+ int res6_move = boost::with_lock_guard(
+ m, func_with_6_args, 12, 'N', a3, &a4, boost::move(a5), false
+ );
+ BOOST_TEST(a3 == 200);
+ BOOST_TEST(a4 == true);
+ BOOST_TEST_EQ(res6_move, 888);
+}
+#endif
+
+int main() {
+ test_simple();
+ test_variadic_templates();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/test.mcp b/src/boost/libs/thread/test/test.mcp
new file mode 100644
index 000000000..f27f0b97b
--- /dev/null
+++ b/src/boost/libs/thread/test/test.mcp
Binary files differ
diff --git a/src/boost/libs/thread/test/test_10340.cpp b/src/boost/libs/thread/test/test_10340.cpp
new file mode 100644
index 000000000..5311e8210
--- /dev/null
+++ b/src/boost/libs/thread/test/test_10340.cpp
@@ -0,0 +1,28 @@
+// Copyright (C) 2014 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+
+struct foo
+{
+ foo(int i_): i(i_) {}
+ int i;
+};
+
+int main()
+{
+ boost::promise<foo> p;
+ const foo f(42);
+ p.set_value(f);
+
+ // Clearly a const future ref isn't much use, but I needed to
+ // prove the problem wasn't me trying to copy a unique_future
+
+ const boost::future<foo>& fut = boost::make_ready_future( foo(42) );
+ return 0;
+}
+
diff --git a/src/boost/libs/thread/test/test_10963.cpp b/src/boost/libs/thread/test/test_10963.cpp
new file mode 100644
index 000000000..1ec8d6cfc
--- /dev/null
+++ b/src/boost/libs/thread/test/test_10963.cpp
@@ -0,0 +1,61 @@
+// Copyright (C) 2014 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 4
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+
+#include <boost/thread/future.hpp>
+#include <boost/static_assert.hpp>
+#include <cassert>
+#include <boost/thread/executors/basic_thread_pool.hpp>
+
+
+struct TestCallback
+{
+ typedef boost::future<void> result_type;
+
+ result_type operator()(boost::future<void> future) const
+ {
+ assert(future.is_ready());
+ future.get();
+ return boost::make_ready_future();
+ }
+
+ result_type operator()(boost::future<boost::future<void> > future) const
+ {
+ assert(future.is_ready());
+ future.get();
+ return boost::make_ready_future();
+ }
+};
+
+int main()
+{
+#if ! defined BOOST_NO_CXX11_DECLTYPE && ! defined BOOST_NO_CXX11_AUTO_DECLARATIONS
+ {
+ boost::promise<void> test_promise;
+ boost::future<void> test_future(test_promise.get_future());
+ auto f1 = test_future.then(TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ auto f2 = f1.then(TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f2), boost::future<boost::future<void> > >::value);
+ }
+ {
+ boost::basic_thread_pool executor;
+ boost::promise<void> test_promise;
+ boost::future<void> test_future(test_promise.get_future());
+ auto f1 = test_future.then(executor, TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ auto f2 = f1.then(executor, TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f2), boost::future<boost::future<void> > >::value);
+
+ }
+#endif
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/test_10964.cpp b/src/boost/libs/thread/test/test_10964.cpp
new file mode 100644
index 000000000..48ee5cd95
--- /dev/null
+++ b/src/boost/libs/thread/test/test_10964.cpp
@@ -0,0 +1,191 @@
+// Copyright (C) 2015 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 4
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+
+#include <boost/thread/future.hpp>
+#include <boost/static_assert.hpp>
+#include <cassert>
+#include <iostream>
+#include <boost/thread/executors/basic_thread_pool.hpp>
+
+struct TestCallback
+{
+ typedef boost::future<void> result_type;
+
+ result_type operator()(boost::future<void> future) const
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ assert(future.is_ready());
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ future.wait();
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ return boost::make_ready_future();
+ }
+
+ result_type operator()(boost::future<boost::future<void> > future) const
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ assert(future.is_ready());
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ assert(future.get().is_ready());
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ //boost::future<void> ff = future.get();
+
+ return boost::make_ready_future();
+ }
+ result_type operator()(boost::shared_future<void> future) const
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ assert(future.is_ready());
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ future.wait();
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ return boost::make_ready_future();
+ }
+
+ result_type operator()(boost::shared_future<boost::future<void> > future) const
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ assert(future.is_ready());
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ assert(future.get().is_ready());
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ //boost::future<void> ff = future.get();
+
+ return boost::make_ready_future();
+ }
+};
+
+void p1()
+{
+}
+
+int main()
+{
+ const int number_of_tests = 2;
+ (void)(number_of_tests);
+
+#if ! defined BOOST_NO_CXX11_DECLTYPE && ! defined BOOST_NO_CXX11_AUTO_DECLARATIONS
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ auto f1 = boost::make_ready_future().then(TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ f1.wait();
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ for (int i=0; i< number_of_tests; i++)
+ {
+ auto f1 = boost::make_ready_future().then(TestCallback());
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ auto f2 = f1.unwrap();
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f2), boost::future<void> >::value);
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ f2.wait();
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ for (int i=0; i< number_of_tests; i++)
+ {
+ auto f1 = boost::make_ready_future().then(TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ boost::future<void> f2 = f1.get();
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ auto f1 = boost::make_ready_future().then(TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ auto f3 = f1.then(TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f3), boost::future<boost::future<void> > >::value);
+ f3.wait();
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ for (int i=0; i< number_of_tests; i++)
+ {
+ auto f1 = boost::make_ready_future().then(TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ auto f2 = f1.unwrap();
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f2), boost::future<void> >::value);
+ auto f3 = f2.then(TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f3), boost::future<boost::future<void> > >::value);
+ f3.wait();
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ for (int i=0; i< number_of_tests; i++)
+ {
+ boost::make_ready_future().then(
+ TestCallback()).unwrap().then(TestCallback()).get();
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ for (int i=0; i< number_of_tests; i++)
+ {
+ boost::future<void> f = boost::async(p1);
+ f.then(
+ TestCallback()).unwrap().then(TestCallback()).get();
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ for (int i=0; i< number_of_tests; i++)
+ {
+ auto f1 = boost::make_ready_future().then(TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ auto f3 = f1.then(TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f3), boost::future<boost::future<void> > >::value);
+ f3.wait();
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ for (int i=0; i< number_of_tests; i++)
+ {
+ boost::basic_thread_pool executor;
+ auto f1 = boost::make_ready_future().then(executor, TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ auto f3 = f1.then(executor, TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f3), boost::future<boost::future<void> > >::value);
+ f3.wait();
+ }
+#if 1
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ // fixme
+ for (int i=0; i< number_of_tests; i++)
+ {
+ boost::basic_thread_pool executor(2);
+
+ auto f1 = boost::make_ready_future().then(executor, TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ std::cout << __FILE__ << "[" << __LINE__ << "] " << int(f1.valid()) << std::endl;
+ auto f2 = f1.unwrap();
+ std::cout << __FILE__ << "[" << __LINE__ << "] " << int(f2.valid()) << std::endl;
+
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f2), boost::future<void> >::value);
+ auto f3 = f2.then(executor, TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f3), boost::future<boost::future<void> > >::value);
+ f3.wait();
+ }
+#endif
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ for (int i=0; i< number_of_tests; i++)
+ {
+ boost::basic_thread_pool executor;
+
+ auto f1 = boost::make_ready_future().then(executor, TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ auto f2 = f1.unwrap();
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f2), boost::future<void> >::value);
+ auto f3 = f2.then(executor, TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f3), boost::future<boost::future<void> > >::value);
+ f3.wait();
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+
+#endif
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/test_11053.cpp b/src/boost/libs/thread/test/test_11053.cpp
new file mode 100644
index 000000000..a8b6dfa97
--- /dev/null
+++ b/src/boost/libs/thread/test/test_11053.cpp
@@ -0,0 +1,70 @@
+// Copyright (C) 2015 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 4
+#include <boost/thread.hpp>
+#include <boost/thread/tss.hpp>
+#include <boost/shared_ptr.hpp>
+#include <iostream>
+
+struct A
+{
+ void DoWork()
+ {
+ std::cout << "A: doing work\n";
+ if (!m_ptr.get())
+ m_ptr.reset(new WorkSpace());
+ // do not very much
+ for (size_t i = 0; i < 10; ++i)
+ m_ptr->a += 10;
+ }
+
+private:
+ struct WorkSpace
+ {
+ int a;
+ WorkSpace() : a(0) {}
+ };
+ boost::thread_specific_ptr<WorkSpace> m_ptr;
+};
+
+struct B
+{
+ void DoWork()
+ {
+ std::cout << "B: doing work\n";
+ if (!m_ptr.get())
+ m_ptr.reset(new A());
+ m_ptr->DoWork();
+ }
+private:
+ boost::thread_specific_ptr<A> m_ptr;
+};
+
+struct C
+{
+ void DoWork()
+ {
+ std::cout << "C: doing work\n";
+ if (!m_ptr.get())
+ m_ptr.reset(new B());
+ m_ptr->DoWork();
+ }
+private:
+ boost::thread_specific_ptr<B> m_ptr;
+};
+
+int main(int ac, char** av)
+{
+ std::cout << "test starting\n";
+ boost::shared_ptr<C> p_C(new C);
+ boost::thread cWorker(&C::DoWork, p_C);
+ cWorker.join();
+ std::cout << "test stopping\n";
+ return 0;
+}
+
+
+
diff --git a/src/boost/libs/thread/test/test_11256.cpp b/src/boost/libs/thread/test/test_11256.cpp
new file mode 100644
index 000000000..13002f867
--- /dev/null
+++ b/src/boost/libs/thread/test/test_11256.cpp
@@ -0,0 +1,42 @@
+// Copyright (C) 2015 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+
+#include <boost/thread.hpp>
+#include <boost/thread/thread_pool.hpp>
+#include <cassert>
+
+auto createFuture()
+{
+ boost::promise<void> promise;
+ promise.set_value();
+ return promise.get_future();
+}
+
+auto stepOne(boost::basic_thread_pool &executor)
+{
+ auto sendFuture = createFuture();
+ auto wrappedFuture = sendFuture.then(executor, [](auto f) mutable {
+ return createFuture();
+ });
+
+ return wrappedFuture.unwrap();
+}
+
+auto stepTwo(boost::basic_thread_pool &executor)
+{
+ auto future = stepOne(executor);
+ return future.then(executor, [](auto f) {
+ assert(f.is_ready());
+ });
+}
+
+int main()
+{
+ boost::basic_thread_pool executor{1};
+ stepTwo(executor).get();
+}
diff --git a/src/boost/libs/thread/test/test_11266.cpp b/src/boost/libs/thread/test/test_11266.cpp
new file mode 100644
index 000000000..0f736783a
--- /dev/null
+++ b/src/boost/libs/thread/test/test_11266.cpp
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+
+void func(int) { }
+
+int main()
+{
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ {
+ boost::packaged_task<void(int)> task{func};
+ }
+ {
+ boost::packaged_task<void(int)> task{func};
+
+ task(0);
+ }
+ {
+ boost::packaged_task<void(int)> task{func};
+ int x = 0;
+ task(x);
+ }
+#endif
+}
diff --git a/src/boost/libs/thread/test/test_11499.cpp b/src/boost/libs/thread/test/test_11499.cpp
new file mode 100644
index 000000000..2fe07ae88
--- /dev/null
+++ b/src/boost/libs/thread/test/test_11499.cpp
@@ -0,0 +1,56 @@
+// Copyright (C) 2014 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/shared_mutex.hpp>
+#include <thread>
+#include <mutex>
+#include <shared_mutex>
+#include <atomic>
+#include <vector>
+
+using MutexT = boost::shared_mutex;
+using ReaderLockT = std::lock_guard<MutexT>;
+using WriterLockT = std::shared_lock<MutexT>;
+
+MutexT gMutex;
+std::atomic<bool> running(true);
+
+
+void myread()
+{
+ long reads = 0;
+ while (running && reads < 100000)
+ {
+ ReaderLockT lock(gMutex);
+ std::this_thread::yield();
+ ++reads;
+ }
+}
+
+int main()
+{
+ using namespace std;
+
+ vector<thread> threads;
+ for (int i = 0; i < 256; ++i)
+ {
+ threads.emplace_back(thread(myread));
+ }
+
+// string str;
+//
+// getline(std::cin, str);
+ running = false;
+
+ for (auto& thread : threads)
+ {
+ thread.join();
+ }
+
+ return 0;
+}
+
diff --git a/src/boost/libs/thread/test/test_11611.cpp b/src/boost/libs/thread/test/test_11611.cpp
new file mode 100644
index 000000000..0a38b4b27
--- /dev/null
+++ b/src/boost/libs/thread/test/test_11611.cpp
@@ -0,0 +1,66 @@
+// Copyright (C) 2014 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 4
+
+#include <iostream>
+
+#define BOOST_THREAD_PROVIDES_FUTURE
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+
+#if __cplusplus >= 201103L
+#include <boost/thread/executors/loop_executor.hpp>
+#include <boost/thread/executors/serial_executor.hpp>
+#endif
+#include <boost/thread/thread.hpp>
+#include <boost/atomic.hpp>
+
+using namespace std;
+
+int main()
+{
+#if __cplusplus >= 201103L
+ static std::size_t const nWorks = 100000;
+ boost::atomic<unsigned> execCount(0u);
+ boost::loop_executor ex;
+
+ boost::thread t([&ex]()
+ {
+ ex.loop();
+ });
+
+ {
+ boost::serial_executor serial(ex);
+
+ for (size_t i = 0; i < nWorks; i++)
+ serial.submit([i, &execCount] {
+ //std::cout << i << ".";
+ ++execCount;
+ });
+
+ serial.close();
+ }
+ unsigned const cnt = execCount.load();
+ if (cnt != nWorks) {
+ // Since the serial_executor is closed, all work should have been done,
+ // even though the loop_executor ex is not.
+ std::cerr << "Only " << cnt << " of " << nWorks << " works executed!\n";
+ return 1;
+ }
+
+ if (ex.try_executing_one()) {
+ std::cerr
+ << "loop_executor::try_executing_one suceeded on closed executor!\n";
+ return 1;
+ }
+
+ ex.close();
+
+ t.join();
+ std::cout << "end\n" << std::endl;
+#endif
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/test_11796.cpp b/src/boost/libs/thread/test/test_11796.cpp
new file mode 100644
index 000000000..6aab1af79
--- /dev/null
+++ b/src/boost/libs/thread/test/test_11796.cpp
@@ -0,0 +1,33 @@
+// Copyright (C) 2015 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/thread.hpp>
+#include <boost/chrono.hpp>
+#include <iostream>
+
+boost::thread th;
+int main()
+{
+
+ for (auto ti = 0; ti < 1000; ti++)
+ {
+ th = boost::thread([ti]()
+ {
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
+ std::cout << ti << std::endl;
+ });
+ }
+ std::string st;
+
+ std::cin >> st;
+
+// for (int i = 0; i < 10; ++i) {
+// std::cout << "." << i << std::endl;
+// boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
+// }
+ th.join();
+ return 0;
+}
+
diff --git a/src/boost/libs/thread/test/test_11818.cpp b/src/boost/libs/thread/test/test_11818.cpp
new file mode 100644
index 000000000..0d2b381de
--- /dev/null
+++ b/src/boost/libs/thread/test/test_11818.cpp
@@ -0,0 +1,64 @@
+// Copyright (C) 2014 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 4
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/thread.hpp>
+#include <thread>
+
+int main()
+{
+
+ {
+ boost::promise<int> promise;
+ boost::future<int> future = promise.get_future();
+
+ boost::future<int> result =
+ future.then
+ (
+ boost::launch::deferred,
+ [](boost::future<int> && f)
+ {
+ std::cout << std::this_thread::get_id() << ": callback" << std::endl;
+ std::cout << "The value is: " << f.get() << std::endl;
+ return f.get();
+ }
+ );
+
+ // We could not reach here.
+ std::cout << std::this_thread::get_id() << ": function" << std::endl;
+
+ promise.set_value(0);
+ }
+
+ {
+ boost::promise<int> promise;
+ boost::shared_future<int> future = promise.get_future().share();
+
+ boost::future<int> result =
+ future.then
+ (
+ boost::launch::deferred,
+ [](boost::shared_future<int> && f)
+ {
+ std::cout << std::this_thread::get_id() << ": callback" << std::endl;
+ std::cout << "The value is: " << f.get() << std::endl;
+ return f.get();
+ }
+ );
+
+ // We could not reach here.
+ std::cout << std::this_thread::get_id() << ": function" << std::endl;
+
+ promise.set_value(0);
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/test_12293.cpp b/src/boost/libs/thread/test/test_12293.cpp
new file mode 100644
index 000000000..0b305edc6
--- /dev/null
+++ b/src/boost/libs/thread/test/test_12293.cpp
@@ -0,0 +1,64 @@
+// Copyright (C) 2014 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 4
+
+// BoostFutureTest.cpp : Defines the entry point for the console application.
+//
+
+#include <iostream>
+
+// boost version 1.60.0
+// has the following set.
+#define BOOST_THREAD_VERSION 4
+// #define BOOST_THREAD_PROVIDES_EXECUTORS
+
+#include <boost/thread/future.hpp>
+
+
+int main()
+{
+#if __cplusplus >= 201103L
+
+ int value = 0;
+ int tmpValue = 0;
+ boost::promise<void> promise1;
+ boost::promise<void> promise2;
+
+ auto future1 = promise1.get_future();
+
+ auto waitFuture = future1.then([&tmpValue, &promise2](boost::future<void> future){
+ assert(future.is_ready()); // this works correctly and is ready.
+
+ auto fut = boost::async(boost::launch::async, [&promise2, &tmpValue](){
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ tmpValue = 1;
+ promise2.set_value();
+ std::cout << "Step 2 "<< std::endl; // should print 1 but prints 0
+ });
+ std::cout << "Step 1 "<< std::endl; // should print 1 but prints 0
+
+ return promise2.get_future();
+ //return ;
+ }).then([&value, &tmpValue](boost::future<boost::future<void>> future){
+ //}).then([&value, &tmpValue](boost::future<void> future){
+ // error: no matching function for call to ‘boost::future<boost::future<void> >::then(main()::<lambda(boost::future<void>)>)’
+ // as expected
+
+ assert(future.is_ready()); // this doesn't work correctly and is not ready.
+
+
+ value = tmpValue;
+ });
+
+
+ promise1.set_value();
+ waitFuture.wait();
+
+ std::cout << "value = " << value << std::endl; // should print 1 but prints 0
+#endif
+ return 0;
+}
+
diff --git a/src/boost/libs/thread/test/test_12949.cpp b/src/boost/libs/thread/test/test_12949.cpp
new file mode 100644
index 000000000..2b6235238
--- /dev/null
+++ b/src/boost/libs/thread/test/test_12949.cpp
@@ -0,0 +1,20 @@
+// Copyright (C) 2017 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 4
+
+//#include <boost/thread/thread.hpp>
+#include <boost/thread/condition_variable.hpp>
+
+void f()
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(10)); // **
+}
+int main()
+{
+
+ return 0;
+}
+
diff --git a/src/boost/libs/thread/test/test_13480b.cpp b/src/boost/libs/thread/test/test_13480b.cpp
new file mode 100644
index 000000000..3f89145d8
--- /dev/null
+++ b/src/boost/libs/thread/test/test_13480b.cpp
@@ -0,0 +1,77 @@
+// comment if you want to see the boost::move issue
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/type_traits/is_same.hpp>
+#include <boost/variant/detail/apply_visitor_binary.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/variant.hpp>
+#include <boost/smart_ptr/shared_ptr.hpp>
+
+#define WANT_BUILD_TO_FAIL
+#ifdef WANT_BUILD_TO_FAIL
+#include <boost/thread.hpp>
+#endif
+
+class AType
+{
+
+};
+
+class BType
+{
+};
+
+typedef boost::shared_ptr<AType> IATypePtr;
+typedef boost::shared_ptr<BType> IBTypePtr;
+
+typedef boost::variant<IATypePtr, IBTypePtr> ABVar;
+
+struct ServiceTimeTableEvent
+{
+public:
+
+ ServiceTimeTableEvent(ABVar abType)
+ : m_abType{ abType }
+ {}
+
+ inline ABVar const& GetABType() const { return m_abType; }
+ inline ABVar & GetABType() { return m_abType; }
+
+private:
+ ABVar m_abType;
+};
+
+class ab_are_equals
+ : public boost::static_visitor<bool>
+{
+public:
+ template<typename T, typename U>
+ bool operator()(T, U) const
+ {
+ return false; // cannot compare different types
+ }
+ template<typename T>
+ bool operator()(T lhs, T rhs) const
+ {
+ return lhs == rhs;
+ }
+};
+
+int main(int argc, char* argv[])
+{
+
+ auto aTypePtr = IATypePtr{ new AType };
+ auto bTypePtr = IBTypePtr{ new BType };
+
+ ABVar aType = aTypePtr;
+ ABVar bType = bTypePtr;
+
+ ServiceTimeTableEvent timeTableEvent1{ aType };
+ ServiceTimeTableEvent timeTableEvent2{ bType };
+
+ auto xx = boost::apply_visitor(ab_are_equals(), timeTableEvent1.GetABType(), timeTableEvent2.GetABType());
+ xx = boost::apply_visitor(ab_are_equals(), timeTableEvent1.GetABType(), timeTableEvent1.GetABType());;
+ xx = boost::apply_visitor(ab_are_equals(), timeTableEvent2.GetABType(), timeTableEvent2.GetABType());;
+}
+
+
diff --git a/src/boost/libs/thread/test/test_13561.cpp b/src/boost/libs/thread/test/test_13561.cpp
new file mode 100644
index 000000000..b72f593d6
--- /dev/null
+++ b/src/boost/libs/thread/test/test_13561.cpp
@@ -0,0 +1,17 @@
+// Copyright (C) 2018 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/detail/nullary_function.hpp>
+#include <boost/system/detail/error_code.ipp>
+
+int main(int argc, char* argv[])
+{
+ boost::detail::nullary_function<void ()> f1;
+ auto f2 = f1;
+}
+
+
diff --git a/src/boost/libs/thread/test/test_2309.cpp b/src/boost/libs/thread/test/test_2309.cpp
new file mode 100644
index 000000000..c3208f97f
--- /dev/null
+++ b/src/boost/libs/thread/test/test_2309.cpp
@@ -0,0 +1,70 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
+//#define BOOST_TEST_MODULE Boost.Threads: 2309
+//#include <boost/test/unit_test.hpp>
+
+#include <iostream>
+
+#include <boost/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+ using namespace std;
+
+ boost::mutex mutex_;
+
+ void perform()
+ {
+ try
+ {
+ boost::this_thread::sleep(boost::posix_time::seconds(100));
+ }
+ catch (boost::thread_interrupted& interrupt)
+ {
+ boost::unique_lock<boost::mutex> lock(mutex_);
+ cerr << "Thread " << boost::this_thread::get_id() << " got interrupted" << endl;
+ throw(interrupt);
+ }
+ catch (std::exception& e)
+ {
+ boost::unique_lock<boost::mutex> lock(mutex_);
+ cerr << "Thread " << boost::this_thread::get_id() << " caught std::exception" << e.what() << endl;
+ }
+ catch (...)
+ {
+ boost::unique_lock<boost::mutex> lock(mutex_);
+ cerr << "Thread " << boost::this_thread::get_id() << " caught something else" << endl;
+ }
+ }
+
+ void ticket_2309_test()
+ {
+ try
+ {
+ boost::thread_group threads;
+
+ for (int i = 0; i < 2; ++i)
+ {
+ threads.create_thread(perform);
+ }
+
+ //boost::this_thread::sleep(1);
+ threads.interrupt_all();
+ threads.join_all();
+ }
+ catch (...)
+ {
+ BOOST_TEST(false && "exception raised");
+ }
+ }
+
+ int main()
+ {
+
+ ticket_2309_test();
+ }
+
diff --git a/src/boost/libs/thread/test/test_2501.cpp b/src/boost/libs/thread/test/test_2501.cpp
new file mode 100644
index 000000000..c654e7272
--- /dev/null
+++ b/src/boost/libs/thread/test/test_2501.cpp
@@ -0,0 +1,16 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/locks.hpp>
+
+int main() {
+
+ boost::shared_mutex mtx; boost::upgrade_lock<boost::shared_mutex> lk(mtx);
+
+ boost::upgrade_to_unique_lock<boost::shared_mutex> lk2(lk);
+
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/test_2741.cpp b/src/boost/libs/thread/test/test_2741.cpp
new file mode 100644
index 000000000..349d7d2ae
--- /dev/null
+++ b/src/boost/libs/thread/test/test_2741.cpp
@@ -0,0 +1,79 @@
+// Copyright (C) 2008 Vicente J. Botet Escriba
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+#define BOOST_TEST_MODULE Boost.Threads: thread attributes test suite
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/xtime.hpp>
+#include <boost/bind/bind.hpp>
+#include <boost/ref.hpp>
+#include <boost/utility.hpp>
+
+#include <iostream>
+#include <boost/test/unit_test.hpp>
+
+#define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_sleep_only
+#include "./util.inl"
+
+int test_value;
+#ifdef PTHREAD_STACK_MIN
+#define MY_PTHREAD_STACK PTHREAD_STACK_MIN
+#else
+#define MY_PTHREAD_STACK 4*0x4000
+#endif
+void simple_thread()
+{
+ test_value = 999;
+}
+
+BOOST_AUTO_TEST_CASE(test_native_handle)
+{
+
+ boost::thread_attributes attrs;
+
+ boost::thread_attributes::native_handle_type* h = attrs.native_handle();
+ (void)(h); // unused
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+ // ... window version
+#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+
+ int k = pthread_attr_setstacksize(h, MY_PTHREAD_STACK);
+ std::cout << k << std::endl;
+ BOOST_CHECK(!pthread_attr_setstacksize(h, MY_PTHREAD_STACK));
+ std::size_t res;
+ BOOST_CHECK(!pthread_attr_getstacksize(h, &res));
+ BOOST_CHECK(res >= (MY_PTHREAD_STACK));
+#else
+#error "Boost thread unavailable on this platform"
+#endif
+
+}
+
+BOOST_AUTO_TEST_CASE(test_stack_size)
+{
+ boost::thread_attributes attrs;
+
+ attrs.set_stack_size(0x4000);
+ BOOST_CHECK(attrs.get_stack_size() >= 0x4000);
+
+}
+
+void do_test_creation_with_attrs()
+{
+ test_value = 0;
+ boost::thread_attributes attrs;
+ attrs.set_stack_size(0x4000);
+ boost::thread thrd(attrs, &simple_thread);
+ thrd.join();
+ BOOST_CHECK_EQUAL(test_value, 999);
+}
+
+BOOST_AUTO_TEST_CASE(test_creation_with_attrs)
+{
+ timed_test(&do_test_creation_with_attrs, 1);
+}
+
+
diff --git a/src/boost/libs/thread/test/test_3628.cpp b/src/boost/libs/thread/test/test_3628.cpp
new file mode 100644
index 000000000..02914d810
--- /dev/null
+++ b/src/boost/libs/thread/test/test_3628.cpp
@@ -0,0 +1,97 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+
+#include <boost/thread/thread.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+#include <list>
+#include <iostream>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+using namespace std;
+
+boost::recursive_mutex theMutex;
+
+typedef std::list<boost::condition*> Conditions;
+Conditions theConditions;
+
+void ThreadFuncWaiter()
+{
+ boost::condition con1;
+ //for(; ; )
+ for (int j = 0; j < 10; j++)
+ {
+ {
+ boost::unique_lock<boost::recursive_mutex> lockMtx(theMutex);
+ theConditions.push_back(&con1);
+
+ cout << "Added " << boost::this_thread::get_id() << " " << &con1 << endl;
+ if (con1.timed_wait(lockMtx, boost::posix_time::time_duration(0, 0, 50)))
+ {
+ cout << "Woke Up " << boost::this_thread::get_id() << " " << &con1 << endl;
+ }
+ else
+ {
+ cout << "*****Timed Out " << boost::this_thread::get_id() << " " << &con1 << endl;
+ exit(13);
+ }
+
+ theConditions.remove(&con1);
+ cout << "Removed " << boost::this_thread::get_id() << " " << &con1 << endl;
+ cout << "Waiter " << j << endl;
+
+ }
+ //Sleep(2000);
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
+ }
+}
+
+void ThreadFuncNotifier()
+{
+ for (int j = 0; j < 70; j++)
+ {
+ {
+ boost::unique_lock<boost::recursive_mutex> lockMtx(theMutex);
+ cout << "<Notifier " << j << endl;
+
+ unsigned int i = 0;
+ for (Conditions::iterator it = theConditions.begin(); it != theConditions.end() && i < 2; ++it)
+ {
+ (*it)->notify_one();
+ //WORKAROUND_ lockMtx.unlock();
+ //WORKAROUND_ boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
+ cout << "Notified One " << theConditions.size() << " " << (*it) << endl;
+ ++i;
+ //WORKAROUND_ lockMtx.lock();
+ }
+
+ cout << "Notifier> " << j << endl;
+ }
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
+ }
+}
+
+int main()
+{
+ boost::thread_group tg;
+ for (int i = 0; i < 12; ++i)
+ {
+ tg.create_thread(ThreadFuncWaiter);
+ }
+
+ tg.create_thread(ThreadFuncNotifier);
+
+ tg.join_all();
+
+ return 0;
+}
+
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/test_3837.cpp b/src/boost/libs/thread/test/test_3837.cpp
new file mode 100644
index 000000000..fd0056f33
--- /dev/null
+++ b/src/boost/libs/thread/test/test_3837.cpp
@@ -0,0 +1,73 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <iostream>
+#include <boost/thread.hpp>
+#include <boost/thread/thread_only.hpp>
+#include <boost/optional.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace boost;
+using namespace boost::chrono;
+
+struct dummy_class_tracks_deletions
+{
+ static unsigned deletions;
+
+ dummy_class_tracks_deletions()
+ {
+ std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
+ }
+ ~dummy_class_tracks_deletions()
+ {
+ ++deletions;
+ std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
+ }
+
+};
+unsigned dummy_class_tracks_deletions::deletions=0;
+
+
+optional<thread_specific_ptr<dummy_class_tracks_deletions> > optr;
+//struct X
+//{
+// thread_specific_ptr<int> f;
+//} sptr;
+
+void other_thread()
+{
+
+ std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
+ optr = none;
+ std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
+ optr = in_place();
+ std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
+ BOOST_TEST(optr->get() == 0);
+ this_thread::sleep(posix_time::seconds(5));
+ BOOST_TEST(optr->get() == 0);
+ std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
+
+}
+
+int main()
+{
+
+ std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
+ dummy_class_tracks_deletions * pi = new dummy_class_tracks_deletions;
+ std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
+ optr = in_place();
+ std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
+ optr->reset(pi);
+ std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
+ BOOST_TEST(optr->get() == pi);
+ thread t1(bind(&other_thread));
+ this_thread::sleep(posix_time::seconds(5));
+ std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
+ BOOST_TEST(optr->get() == pi);
+ std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
+ t1.join();
+ return boost::report_errors();
+
+}
diff --git a/src/boost/libs/thread/test/test_4521.cpp b/src/boost/libs/thread/test/test_4521.cpp
new file mode 100644
index 000000000..2b1a21bf2
--- /dev/null
+++ b/src/boost/libs/thread/test/test_4521.cpp
@@ -0,0 +1,31 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/future.hpp>
+
+int calculate_the_answer_to_life_the_universe_and_everything()
+{
+ return 42;
+}
+
+int main() {
+boost::packaged_task<int> pt(calculate_the_answer_to_life_the_universe_and_everything);
+
+//boost::unique_future<int> fi = BOOST_THREAD_MAKE_RV_REF(pt.get_future());
+boost::unique_future<int> fi((BOOST_THREAD_MAKE_RV_REF(pt.get_future())));
+
+boost::thread task(boost::move(pt)); // launch task on a thread
+
+fi.wait(); // wait for it to finish
+
+//assert(fi.is_ready());
+//assert(fi.has_value());
+//assert(!fi.has_exception());
+//assert(fi.get_state()==boost::future_state::ready);
+//assert(fi.get()==42);
+}
diff --git a/src/boost/libs/thread/test/test_4648.cpp b/src/boost/libs/thread/test/test_4648.cpp
new file mode 100644
index 000000000..34fb131af
--- /dev/null
+++ b/src/boost/libs/thread/test/test_4648.cpp
@@ -0,0 +1,47 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <iostream>
+#include <boost/thread.hpp>
+#include <boost/current_function.hpp>
+
+class boostThreadLocksTest
+{
+public:
+ boost::shared_mutex myMutex;
+ //boost::upgrade_lock<boost::shared_mutex> myLock;
+ static int firstFunction(boostThreadLocksTest *pBoostThreadLocksTest);
+ static int secondFunction(boostThreadLocksTest *pBoostThreadLocksTest,
+ boost::upgrade_lock<boost::shared_mutex>& upgr);
+ boostThreadLocksTest()
+ :myMutex()
+ //, myLock(myMutex,boost::defer_lock_t())
+ {}
+};
+
+int boostThreadLocksTest::firstFunction(boostThreadLocksTest *pBoostThreadLocksTest)
+{
+ std::cout<<"Entering "<<boost::this_thread::get_id()<<" "<<"firstFunction"<<std::endl;
+ boost::upgrade_lock<boost::shared_mutex> myLock(pBoostThreadLocksTest->myMutex);
+ pBoostThreadLocksTest->secondFunction(pBoostThreadLocksTest, myLock);
+ std::cout<<"Returned From Call "<<boost::this_thread::get_id()<<" "<<"firstFunction"<<std::endl;
+ std::cout<<"Returning from "<<boost::this_thread::get_id()<<" "<<"firstFunction"<<std::endl;
+ return(0);
+}
+int boostThreadLocksTest::secondFunction(boostThreadLocksTest *, boost::upgrade_lock<boost::shared_mutex>& upgr) {
+ std::cout<<"Before Exclusive Locking "<<boost::this_thread::get_id()<<" "<<"secondFunction"<<std::endl;
+ boost::upgrade_to_unique_lock<boost::shared_mutex> localUniqueLock(upgr);
+ std::cout<<"After Exclusive Locking "<<boost::this_thread::get_id()<<" "<<"secondFunction"<<std::endl;
+ return(0);
+}
+int main() {
+ boostThreadLocksTest myObject;
+ boost::thread_group myThreadGroup;
+ myThreadGroup.create_thread(boost::bind(boostThreadLocksTest::firstFunction,&myObject));
+ myThreadGroup.create_thread(boost::bind(boostThreadLocksTest::firstFunction,&myObject));
+ myThreadGroup.create_thread(boost::bind(boostThreadLocksTest::firstFunction,&myObject));
+ myThreadGroup.join_all();
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/test_4882.cpp b/src/boost/libs/thread/test/test_4882.cpp
new file mode 100644
index 000000000..b1bb72539
--- /dev/null
+++ b/src/boost/libs/thread/test/test_4882.cpp
@@ -0,0 +1,78 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+//#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+//#define BOOST_THREAD_USES_LOG
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
+//#include <boost/thread/detail/log.hpp>
+
+boost::shared_mutex mutex;
+
+void thread()
+{
+ //BOOST_THREAD_LOG << "<thrd" << BOOST_THREAD_END_LOG;
+ BOOST_TRY
+ {
+ for (int i =0; i<10; ++i)
+ {
+#ifndef BOOST_THREAD_USES_CHRONO
+ boost::system_time timeout = boost::get_system_time() + boost::posix_time::milliseconds(50);
+
+ if (mutex.timed_lock(timeout))
+ {
+ //BOOST_THREAD_LOG << "<thrd" << " i="<<i << BOOST_THREAD_END_LOG;
+ boost::this_thread::sleep(boost::posix_time::milliseconds(10));
+ mutex.unlock();
+ //BOOST_THREAD_LOG << "<thrd" << " i="<<i << BOOST_THREAD_END_LOG;
+ }
+#else
+ boost::chrono::system_clock::time_point timeout = boost::chrono::system_clock::now() + boost::chrono::milliseconds(50);
+
+ //BOOST_THREAD_LOG << "<thrd" << " i="<<i << BOOST_THREAD_END_LOG;
+ if (mutex.try_lock_until(timeout))
+ {
+ //BOOST_THREAD_LOG << "<thrd" << " i="<<i << BOOST_THREAD_END_LOG;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(10));
+ mutex.unlock();
+ //BOOST_THREAD_LOG << "<thrd" << " i="<<i << BOOST_THREAD_END_LOG;
+ }
+#endif
+ }
+ }
+ BOOST_CATCH (boost::lock_error& )
+ {
+ //BOOST_THREAD_LOG << "lock_error exception thrd>" << BOOST_THREAD_END_LOG;
+ }
+ BOOST_CATCH (...)
+ {
+ //BOOST_THREAD_LOG << "exception thrd>" << BOOST_THREAD_END_LOG;
+ }
+ BOOST_CATCH_END
+ //BOOST_THREAD_LOG << "thrd>" << BOOST_THREAD_END_LOG;
+}
+
+int main()
+{
+ //BOOST_THREAD_LOG << "<main" << BOOST_THREAD_END_LOG;
+ const int nrThreads = 20;
+ boost::thread* threads[nrThreads];
+
+ for (int i = 0; i < nrThreads; ++i)
+ threads[i] = new boost::thread(&thread);
+
+ for (int i = 0; i < nrThreads; ++i)
+ {
+ threads[i]->join();
+ //BOOST_THREAD_LOG << "main" << BOOST_THREAD_END_LOG;
+ delete threads[i];
+ //BOOST_THREAD_LOG << "main" << BOOST_THREAD_END_LOG;
+ }
+ //BOOST_THREAD_LOG << "main>" << BOOST_THREAD_END_LOG;
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/test_5351.cpp b/src/boost/libs/thread/test/test_5351.cpp
new file mode 100644
index 000000000..958afb31d
--- /dev/null
+++ b/src/boost/libs/thread/test/test_5351.cpp
@@ -0,0 +1,52 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
+
+#include <iostream>
+#include <boost/thread/thread_only.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <boost/thread/future.hpp>
+
+using namespace boost::posix_time;
+using namespace boost;
+
+int foo()
+{
+ this_thread::sleep(seconds(10));
+ return 0;
+}
+
+
+int main()
+{
+ boost::packaged_task<int> pt(&foo);
+ boost::unique_future<int> fi = pt.get_future();
+ boost::thread task(boost::move(pt)); // launch task on a thread
+
+ task.interrupt();
+
+ try
+ {
+ int v = fi.get();
+ }
+ catch (boost::thread_interrupted& exc)
+ {
+ std::cout << "OK: " << std::endl;
+ return 0;
+ }
+ catch (boost::exception& exc)
+ {
+ std::cout << __LINE__ << " ERROR: " << boost::diagnostic_information(exc) << std::endl;
+ return 1;
+ }
+ catch (...)
+ {
+ std::cout << __LINE__ << " ERROR: " << std::endl;
+ return 2;
+ }
+ std::cout << __LINE__ << " ERROR: " << std::endl;
+ return 3;
+}
diff --git a/src/boost/libs/thread/test/test_5502.cpp b/src/boost/libs/thread/test/test_5502.cpp
new file mode 100644
index 000000000..455e79eec
--- /dev/null
+++ b/src/boost/libs/thread/test/test_5502.cpp
@@ -0,0 +1,93 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// bm.cpp
+
+// g++ test.cpp -lboost_thread-mt && ./a.out
+
+// the ration of XXX and YYY determines
+// if this works or deadlocks
+int XXX = 20;
+int YYY = 10;
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/shared_mutex.hpp>
+
+//#include <unistd.h>
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace std;
+
+//void sleepmillis(useconds_t miliis)
+void sleepmillis(int miliis)
+{
+ //usleep(miliis * 1000);
+ boost::this_thread::sleep(boost::posix_time::milliseconds(miliis));
+}
+
+void worker1(boost::shared_mutex * lk, int * x)
+{
+ (*x)++; // 1
+ cout << "lock b try " << *x << endl;
+ while (1)
+ {
+ if (lk->timed_lock(boost::posix_time::milliseconds(XXX))) break;
+ sleepmillis(YYY);
+ }
+ cout << "lock b got " << *x << endl;
+ (*x)++; // 2
+ lk->unlock();
+}
+
+void worker2(boost::shared_mutex * lk, int * x)
+{
+ cout << "lock c try" << endl;
+ lk->lock_shared();
+ (*x)++;
+ cout << "lock c got" << endl;
+ lk->unlock_shared();
+ cout << "lock c unlocked" << endl;
+ (*x)++;
+}
+
+int main()
+{
+
+ // create
+ boost::shared_mutex* lk = new boost::shared_mutex();
+
+ // read lock
+ cout << "lock a" << endl;
+ lk->lock_shared();
+
+ int x1 = 0;
+ boost::thread t1(boost::bind(worker1, lk, &x1));
+ while (!x1)
+ ;
+ BOOST_TEST(x1 == 1);
+ sleepmillis(500);
+ BOOST_TEST(x1 == 1);
+
+ int x2 = 0;
+ boost::thread t2(boost::bind(worker2, lk, &x2));
+ t2.join();
+ BOOST_TEST(x2 == 2);
+
+ lk->unlock_shared();
+ cout << "unlock a" << endl;
+
+ for (int i = 0; i < 2000; i++)
+ {
+ if (x1 == 2) break;
+ sleepmillis(10);
+ }
+
+ BOOST_TEST(x1 == 2);
+ t1.join();
+ delete lk;
+
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/test_5542_1.cpp b/src/boost/libs/thread/test/test_5542_1.cpp
new file mode 100644
index 000000000..4d088dc80
--- /dev/null
+++ b/src/boost/libs/thread/test/test_5542_1.cpp
@@ -0,0 +1,69 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+
+#include <iostream>
+#include <boost/thread/thread_only.hpp>
+
+class Worker
+{
+public:
+
+ Worker()
+ {
+ // the thread is not-a-thread until we call start()
+ }
+
+ void start(int N)
+ {
+// std::cout << "start\n";
+ m_Thread = boost::thread(&Worker::processQueue, this, N);
+// std::cout << "started\n";
+ }
+
+ void join()
+ {
+ m_Thread.join();
+ }
+
+ void processQueue(unsigned N)
+ {
+ unsigned ms = N * 1000;
+ boost::posix_time::milliseconds workTime(ms);
+
+// std::cout << "Worker: started, will work for "
+// << ms << "ms"
+// << std::endl;
+
+ // We're busy, honest!
+ boost::this_thread::sleep(workTime);
+
+// std::cout << "Worker: completed" << std::endl;
+ }
+
+private:
+
+ boost::thread m_Thread;
+};
+
+int main()
+{
+// std::cout << "main: startup" << std::endl;
+
+ Worker worker;
+
+// std::cout << "main: create worker" << std::endl;
+
+ worker.start(3);
+
+// std::cout << "main: waiting for thread" << std::endl;
+
+ worker.join();
+
+// std::cout << "main: done" << std::endl;
+
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/test_5542_2.cpp b/src/boost/libs/thread/test/test_5542_2.cpp
new file mode 100644
index 000000000..b0c48cf9d
--- /dev/null
+++ b/src/boost/libs/thread/test/test_5542_2.cpp
@@ -0,0 +1,18 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+
+#include <boost/thread/thread_only.hpp>
+
+void run_thread() {
+ return;
+}
+
+int main() {
+ boost::thread t(&run_thread);
+ return 0;
+}
+
diff --git a/src/boost/libs/thread/test/test_5542_3.cpp b/src/boost/libs/thread/test/test_5542_3.cpp
new file mode 100644
index 000000000..4541243f3
--- /dev/null
+++ b/src/boost/libs/thread/test/test_5542_3.cpp
@@ -0,0 +1,37 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+
+#include <iostream>
+#include <boost/thread/thread_only.hpp>
+#include <boost/date_time.hpp>
+
+void workerFunc()
+{
+ boost::posix_time::seconds workTime(3);
+
+ std::cout << "Worker: running" << std::endl;
+
+ // Pretend to do something useful...
+ boost::this_thread::sleep(workTime);
+
+ std::cout << "Worker: finished" << std::endl;
+}
+
+int main()
+{
+ std::cout << "main: startup" << std::endl;
+
+ boost::thread workerThread(workerFunc);
+
+ std::cout << "main: waiting for thread" << std::endl;
+
+ workerThread.join();
+
+ std::cout << "main: done" << std::endl;
+
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/test_5891.cpp b/src/boost/libs/thread/test/test_5891.cpp
new file mode 100644
index 000000000..bb1af3d57
--- /dev/null
+++ b/src/boost/libs/thread/test/test_5891.cpp
@@ -0,0 +1,35 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+
+#include <iostream>
+#include <boost/thread/thread_only.hpp>
+
+using namespace std;
+using namespace boost;
+
+ struct X {
+ void operator()()
+ {
+ boost::this_thread::sleep(posix_time::seconds(2));
+ }
+ };
+int main()
+{
+ X run;
+ boost::thread myThread(run);
+ boost::this_thread::yield();
+ if(myThread.timed_join(posix_time::seconds(5)))
+ {
+ cout << "thats ok";
+ return 0;
+ }
+ else
+ {
+ cout << "too late";
+ return 1;
+ }
+}
diff --git a/src/boost/libs/thread/test/test_6130.cpp b/src/boost/libs/thread/test/test_6130.cpp
new file mode 100644
index 000000000..a351039bf
--- /dev/null
+++ b/src/boost/libs/thread/test/test_6130.cpp
@@ -0,0 +1,49 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/date_time/posix_time/posix_time_io.hpp>
+#include <assert.h>
+#include <iostream>
+#include <stdlib.h>
+#if defined(BOOST_THREAD_PLATFORM_PTHREAD)
+#include <unistd.h>
+#endif
+
+boost::mutex mtx;
+boost::condition_variable cv;
+
+using namespace boost::posix_time;
+using namespace boost::gregorian;
+int main()
+{
+#if defined(BOOST_THREAD_PLATFORM_PTHREAD)
+
+ for (int i=0; i<3; ++i)
+ {
+ const time_t now_time = ::time(0);
+ const time_t wait_time = now_time+1;
+ time_t end_time;
+ assert(now_time < wait_time);
+
+ boost::unique_lock<boost::mutex> lk(mtx);
+ //const bool res =
+ (void)cv.timed_wait(lk, from_time_t(wait_time));
+ end_time = ::time(0);
+ std::cerr << "now_time =" << now_time << " \n";
+ std::cerr << "end_time =" << end_time << " \n";
+ std::cerr << "wait_time=" << wait_time << " \n";
+ std::cerr << "now_time =" << from_time_t(now_time) << " \n";
+ std::cerr << "end_time =" << from_time_t(end_time) << " \n";
+ std::cerr << "wait_time=" << from_time_t(wait_time) << " \n";
+ std::cerr << end_time - wait_time << " \n";
+ assert(end_time >= wait_time);
+ std::cerr << " OK\n";
+ }
+#endif
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/test_6170.cpp b/src/boost/libs/thread/test/test_6170.cpp
new file mode 100644
index 000000000..5ddb21e61
--- /dev/null
+++ b/src/boost/libs/thread/test/test_6170.cpp
@@ -0,0 +1,31 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/locks.hpp>
+
+// Including this will cause ambiguous errors in boost::move
+#include <boost/unordered_map.hpp>
+
+using namespace boost;
+
+typedef upgrade_lock<shared_mutex> auto_upgrade_lock;
+typedef upgrade_to_unique_lock<shared_mutex> auto_upgrade_unique_lock;
+
+void testUpgrade(void)
+{
+ shared_mutex mtx;
+ auto_upgrade_lock lock(mtx);
+ // Do some read-only stuff
+
+ auto_upgrade_unique_lock writeLock(lock);
+ // Do some write-only stuff with the upgraded lock
+}
+
+int main()
+{
+ testUpgrade();
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/test_6174.cpp b/src/boost/libs/thread/test/test_6174.cpp
new file mode 100644
index 000000000..bc28dcfad
--- /dev/null
+++ b/src/boost/libs/thread/test/test_6174.cpp
@@ -0,0 +1,48 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/config.hpp>
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+struct MovableButNonCopyable {
+#if ! defined BOOST_NO_CXX11_DELETED_FUNCTIONS
+ MovableButNonCopyable(MovableButNonCopyable const&) = delete;
+ MovableButNonCopyable& operator=(MovableButNonCopyable const&) = delete;
+#else
+private:
+ MovableButNonCopyable(MovableButNonCopyable const&);
+ MovableButNonCopyable& operator=(MovableButNonCopyable const&);
+#endif
+public:
+ MovableButNonCopyable() {};
+ MovableButNonCopyable(MovableButNonCopyable&&) {};
+ MovableButNonCopyable& operator=(MovableButNonCopyable&&)
+ {
+ return *this;
+ };
+};
+
+MovableButNonCopyable construct()
+{
+ return MovableButNonCopyable();
+}
+
+int main()
+{
+ boost::packaged_task<MovableButNonCopyable> pt(construct);
+ pt();
+ return 0;
+}
+#else
+int main()
+{
+ return 0;
+}
+#endif
diff --git a/src/boost/libs/thread/test/test_7160.cpp b/src/boost/libs/thread/test/test_7160.cpp
new file mode 100644
index 000000000..644d87fa8
--- /dev/null
+++ b/src/boost/libs/thread/test/test_7160.cpp
@@ -0,0 +1,36 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
+
+#include <iostream>
+#include <boost/thread/thread_only.hpp>
+
+class ThreadClass
+{
+public:
+ ThreadClass()
+ {
+ }
+
+ void operator()()
+ {
+ return;
+ }
+};
+
+int main()
+{
+ boost::posix_time::ptime currentTimeUTC;
+
+ ThreadClass tc;
+ boost::thread t(tc);
+ t.join(); //causes a runtime access violation here
+
+ std::cout << "done" << std::endl;
+ //system("pause");
+
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/test_7328.cpp b/src/boost/libs/thread/test/test_7328.cpp
new file mode 100644
index 000000000..0c0cca03a
--- /dev/null
+++ b/src/boost/libs/thread/test/test_7328.cpp
@@ -0,0 +1,47 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
+
+#include <iostream>
+#include <boost/thread/thread_only.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+//using namespace boost;
+using namespace boost::chrono;
+
+bool interrupted = false;
+void f()
+{
+ try
+ {
+ std::cout << "Starting sleep in thread" << std::endl;
+ for (;;)
+ {
+ boost::this_thread::sleep_for(seconds(60));
+ }
+ }
+ catch (const boost::thread_interrupted&)
+ {
+ interrupted = true;
+ std::cout << "Thread interrupted." << std::endl;
+ }
+}
+
+int main()
+{
+ boost::thread t(f);
+ t.interrupt();
+ t.join();
+ std::cout << "Joined with thread." << std::endl;
+ BOOST_TEST(interrupted);
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/test_7571.cpp b/src/boost/libs/thread/test/test_7571.cpp
new file mode 100644
index 000000000..a336795f4
--- /dev/null
+++ b/src/boost/libs/thread/test/test_7571.cpp
@@ -0,0 +1,93 @@
+// Copyright (C) 2012 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+
+#include <boost/date_time.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread_only.hpp>
+#include <iostream>
+
+// Number should be big enough to allow context switch between threads, otherwise the bug doesn't show.
+static int MAX_COUNTS;
+
+class ItemKeeper {
+
+public:
+ ItemKeeper() { }
+
+ void doSomething() {
+ boost::unique_lock<boost::mutex> scoped_lock(mutex);
+ int counts = MAX_COUNTS;
+ while (counts--);
+ }
+
+private:
+ boost::mutex mutex;
+};
+
+ItemKeeper itemKeeper;
+
+int MAX_ITERATIONS(5);
+
+void threadFunc(int invokerID, bool& exceptionOccurred) {
+ try {
+ for (int i = 0; i < MAX_ITERATIONS; i++) {
+ std::cout << "Thread " << invokerID << ", iteration " << i << std::endl;
+ itemKeeper.doSomething();
+ }
+ } catch (...) {
+ exceptionOccurred = true;
+ }
+}
+
+
+int main(int argc, char* argv[]) {
+ if (argc < 2) {
+ MAX_COUNTS = 5000000;
+ } else {
+ std::string valueStr(argv[1]);
+ bool has_only_digits = (valueStr.find_first_not_of( "0123456789" ) == std::string::npos);
+ if (has_only_digits) {
+ std::istringstream aStream(valueStr);
+ aStream >> MAX_COUNTS;
+ } else {
+ std::cerr << "Argument should be an integer\n";
+ return 1;
+ }
+ }
+
+ bool exceptionOccurred1(false);
+ bool exceptionOccurred2(false);
+
+ boost::thread thread1(threadFunc, 1, boost::ref(exceptionOccurred1));
+ boost::thread thread2(threadFunc, 2, boost::ref(exceptionOccurred2));
+
+ boost::posix_time::time_duration timeout = boost::posix_time::milliseconds(10000*100);
+
+ bool deadlockOccured(false);
+ //thread1.join();
+ //thread2.join();
+
+ if (!thread1.timed_join(timeout)) {
+ deadlockOccured = true;
+ thread1.interrupt();
+ }
+ if (!thread2.timed_join(timeout)) {
+ deadlockOccured = true;
+ thread2.interrupt();
+ }
+
+ if (deadlockOccured) {
+ std::cout << "Deadlock occurred\n";
+ return 1;
+ }
+ if (exceptionOccurred1 || exceptionOccurred2) {
+ std::cout << "Exception occurred\n";
+ return 1;
+ }
+ return 0;
+}
+
diff --git a/src/boost/libs/thread/test/test_7665.cpp b/src/boost/libs/thread/test/test_7665.cpp
new file mode 100644
index 000000000..7244a7d34
--- /dev/null
+++ b/src/boost/libs/thread/test/test_7665.cpp
@@ -0,0 +1,39 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+#define BOOST_THREAD_USES_LOG
+
+#include <iostream>
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/detail/log.hpp>
+
+void thread()
+{
+ BOOST_THREAD_LOG << "<thrd" << BOOST_THREAD_END_LOG;
+ try {
+ boost::this_thread::sleep_for(boost::chrono::seconds(30));
+ } catch (...)
+ {
+ BOOST_THREAD_LOG << "thrd exception" << BOOST_THREAD_END_LOG;
+ throw;
+ }
+ //while (1) ; // Never quit
+ BOOST_THREAD_LOG << "thrd>" << BOOST_THREAD_END_LOG;
+}
+
+boost::thread example(thread);
+
+int main()
+{
+ BOOST_THREAD_LOG << "<main" << BOOST_THREAD_END_LOG;
+ boost::this_thread::sleep_for(boost::chrono::seconds(30));
+ BOOST_THREAD_LOG << "main" << BOOST_THREAD_END_LOG;
+ //while (1) ; // Never quit
+ example.join();
+ BOOST_THREAD_LOG << "main>" << BOOST_THREAD_END_LOG;
+ return 0;
+}
+
diff --git a/src/boost/libs/thread/test/test_7666.cpp b/src/boost/libs/thread/test/test_7666.cpp
new file mode 100644
index 000000000..1ec71dff8
--- /dev/null
+++ b/src/boost/libs/thread/test/test_7666.cpp
@@ -0,0 +1,23 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_CHRONO_VERSION 2
+#define BOOST_THREAD_VERSION 2
+
+#include <boost/thread/thread_only.hpp>
+
+void myFunc()
+{
+ boost::this_thread::sleep(boost::posix_time::seconds(5));
+}
+
+int main(int, char **)
+{
+ boost::thread p(myFunc);
+
+ p.join();
+
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/test_7720.cpp b/src/boost/libs/thread/test/test_7720.cpp
new file mode 100644
index 000000000..4dfe95a73
--- /dev/null
+++ b/src/boost/libs/thread/test/test_7720.cpp
@@ -0,0 +1,56 @@
+// Copyright (C) 2013 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+////////////////////////////////////////////
+
+//#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/shared_mutex.hpp>
+using namespace boost;
+
+shared_mutex mtx;
+
+const int max_count = 100;
+void f()
+{
+ int count =max_count;
+ while (count--)
+ {
+ upgrade_lock<shared_mutex> lock(mtx);
+ }
+}
+
+void g()
+{
+ int count =max_count;
+ while (count--)
+ {
+ shared_lock<shared_mutex> lock(mtx);
+ }
+}
+
+void h()
+{
+ int count =max_count;
+ while (count--)
+ {
+ unique_lock<shared_mutex> lock(mtx);
+ }
+}
+
+int main()
+{
+ thread t0(f);
+ thread t1(g);
+ thread t2(h);
+
+ t0.join();
+ t1.join();
+ t2.join();
+
+ return 0;
+}
+
+
diff --git a/src/boost/libs/thread/test/test_7755.cpp b/src/boost/libs/thread/test/test_7755.cpp
new file mode 100644
index 000000000..5551a6bb9
--- /dev/null
+++ b/src/boost/libs/thread/test/test_7755.cpp
@@ -0,0 +1,94 @@
+// Copyright (C) 2013 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+////////////////////////////////////////////
+
+//#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+#include <iostream>
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/shared_mutex.hpp>
+// shared_mutex_deadlock.cpp : Defines the entry point for the console application.
+//
+
+
+boost::shared_mutex mutex;
+
+void thread2_func()
+{
+ int i (0);
+ for (;;)
+ {
+ if (mutex.timed_lock(boost::posix_time::milliseconds(500)))
+ {
+ std::cout << "Unique lock acquired" << std::endl
+ << "Test successful" << std::endl;
+ mutex.unlock();
+ break;
+ }
+ ++i;
+ if (i == 100)
+ {
+ std::cout << "Test failed. App is deadlocked" << std::endl;
+ break;
+ }
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ }
+}
+
+void thread3_func()
+{
+ boost::shared_lock<boost::shared_mutex> lock (mutex);
+ std::cout << "Shared lock acquired" << std::endl
+ << "Test successful" << std::endl;
+}
+
+void thread3_func_workaround()
+{
+ for (;;)
+ {
+ if (mutex.timed_lock_shared(boost::posix_time::milliseconds(200)))
+ {
+ std::cout << "Shared lock acquired" << std::endl
+ << "Test successful" << std::endl;
+ mutex.unlock_shared();
+ break;
+ }
+ boost::this_thread::sleep(boost::posix_time::milliseconds(100));
+ }
+}
+
+int main()
+{
+ std::cout << "Starting" << std::endl;
+
+ // 1 - lock the mutex
+ boost::shared_lock<boost::shared_mutex> lock (mutex);
+
+ // 2 - start thread#2
+ boost::thread thread2(&thread2_func);
+
+ // 3 - sleep
+ boost::this_thread::sleep(boost::posix_time::milliseconds(10));
+
+ std::cout << "Thread#2 is waiting" << std::endl;
+
+ // - start thread3
+ boost::thread thread3(&thread3_func);
+ //boost::thread thread3(&thread3_func_workaround);
+
+ std::cout << "Thread#3 is started and blocked. It never will waked" << std::endl;
+
+ thread3.join(); // will never return
+
+ lock.unlock(); // release shared ownership. thread#2 will take unique ownership
+
+ thread2.join();
+
+ std::cout << "Finished" << std::endl;
+ return 0;
+}
+
+
+
diff --git a/src/boost/libs/thread/test/test_8455.cpp b/src/boost/libs/thread/test/test_8455.cpp
new file mode 100644
index 000000000..bbc4e5673
--- /dev/null
+++ b/src/boost/libs/thread/test/test_8455.cpp
@@ -0,0 +1,23 @@
+// Copyright (C) 2013 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/thread/mutex.hpp>
+boost::mutex mut;
+void boostMutexImp1()
+{
+ boost::mutex::scoped_lock lock(mut);
+ mut.unlock(); // A: with this X blocks
+ //lock.unlock(); // No influence if used also if before A
+}
+void boostMutexImp2()
+{
+ boost::mutex::scoped_lock lock(mut); // X: blocks with A
+}
+int main()
+{
+ boostMutexImp1();
+ boostMutexImp2();
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/test_8508.cpp b/src/boost/libs/thread/test/test_8508.cpp
new file mode 100644
index 000000000..f53d1487d
--- /dev/null
+++ b/src/boost/libs/thread/test/test_8508.cpp
@@ -0,0 +1,20 @@
+// Copyright (C) 2013 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//#define BOOST_THREAD_VERSION 2
+
+#include <boost/thread/thread.hpp>
+
+void thread_main()
+{
+}
+
+int main(void)
+{
+ boost::thread t(thread_main);
+ t.join();
+ return 0;
+}
+
diff --git a/src/boost/libs/thread/test/test_8557.cpp b/src/boost/libs/thread/test/test_8557.cpp
new file mode 100644
index 000000000..b8efee5a1
--- /dev/null
+++ b/src/boost/libs/thread/test/test_8557.cpp
@@ -0,0 +1,140 @@
+// Copyright (C) 2013 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// B
+
+#include <malloc.h>
+#include <boost/thread/thread.hpp>
+
+#include <boost/thread/mutex.hpp>
+
+#include <boost/bind/bind.hpp>
+
+#include <iostream>
+
+ static void
+ display_mallinfo()
+ {
+ struct mallinfo mi;
+
+ mi = mallinfo();
+
+ printf("Total non-mmapped bytes (arena): %d\n", mi.arena);
+ printf("# of free chunks (ordblks): %d\n", mi.ordblks);
+ printf("# of free fastbin blocks (smblks): %d\n", mi.smblks);
+ printf("# of mapped regions (hblks): %d\n", mi.hblks);
+ printf("Bytes in mapped regions (hblkhd): %d\n", mi.hblkhd);
+ printf("Max. total allocated space (usmblks): %d\n", mi.usmblks);
+ printf("Free bytes held in fastbins (fsmblks): %d\n", mi.fsmblks);
+ printf("Total allocated space (uordblks): %d\n", mi.uordblks);
+ printf("Total free space (fordblks): %d\n", mi.fordblks);
+ printf("Topmost releasable block (keepcost): %d\n", mi.keepcost);
+ }
+
+boost::mutex io_mutex;
+
+void count() {
+
+ for (int i = 0; i < 10; ++i) {
+
+ boost::mutex::scoped_lock lock(io_mutex);
+
+ //boost::this_thread::sleep( boost::posix_time::milliseconds( 100 ) );
+
+ }
+
+}
+void* count2(void*) {
+
+ for (int i = 0; i < 10; ++i) {
+
+ boost::mutex::scoped_lock lock(io_mutex);
+
+ boost::this_thread::sleep( boost::posix_time::milliseconds( 100 ) );
+
+ }
+ return 0;
+}
+
+int main() {
+ printf("\n============== sizeof(boost::thread) ============== %d\n", sizeof(boost::thread));
+ printf("\n============== sizeof(boost::detail::thread_data_base) ============== %d\n", sizeof(boost::detail::thread_data_base));
+ printf("\n============== sizeof(boost::detail::thread_data<>) ============== %d\n", sizeof(boost::detail::thread_data<void(*)()>));
+ printf("\n============== Before thread creation ==============\n");
+ display_mallinfo();
+ {
+ boost::thread thrd1(&count);
+
+ printf("\n============== After thread creation ==============\n");
+ display_mallinfo();
+
+ boost::thread thrd2(&count);
+ printf("\n============== After thread creation ==============\n");
+ display_mallinfo();
+ boost::thread thrd3(&count);
+ printf("\n============== After thread creation ==============\n");
+ display_mallinfo();
+
+ thrd1.join();
+ printf("\n============== After thread join ==============\n");
+ display_mallinfo();
+
+ thrd2.join();
+ printf("\n============== After thread join ==============\n");
+ display_mallinfo();
+ thrd3.join();
+ printf("\n============== After thread join ==============\n");
+ display_mallinfo();
+ }
+ printf("\n============== After thread destruction ==============\n");
+ display_mallinfo();
+
+ {
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+
+ pthread_t thrd1;
+ pthread_create(&thrd1, &attr, &count2, 0);
+ printf("\n============== After thread creation ==============\n");
+ display_mallinfo();
+
+ pthread_t thrd2;
+ pthread_create(&thrd2, &attr, &count2, 0);
+ printf("\n============== After thread creation ==============\n");
+ display_mallinfo();
+
+ pthread_t thrd3;
+ pthread_create(&thrd3, &attr, &count2, 0);
+ printf("\n============== After thread creation ==============\n");
+ display_mallinfo();
+
+ pthread_attr_destroy(&attr);
+ printf("\n============== After thread attr destroy ==============\n");
+ display_mallinfo();
+
+ void* res;
+ pthread_join(thrd3, &res);
+ printf("\n============== After thread join ==============\n");
+ display_mallinfo();
+
+ pthread_join(thrd2, &res);
+ printf("\n============== After thread join ==============\n");
+ display_mallinfo();
+ pthread_join(thrd1, &res);
+ printf("\n============== After thread join ==============\n");
+ display_mallinfo();
+
+
+
+ //pthread_destroy(&thrd1);
+ //pthread_destroy(&thrd2);
+ //pthread_destroy(&thrd3);
+ }
+ printf("\n============== After thread destruction ==============\n");
+ display_mallinfo();
+
+ return 1;
+
+}
diff --git a/src/boost/libs/thread/test/test_8586.cpp b/src/boost/libs/thread/test/test_8586.cpp
new file mode 100644
index 000000000..926f8b398
--- /dev/null
+++ b/src/boost/libs/thread/test/test_8586.cpp
@@ -0,0 +1,18 @@
+// Copyright (C) 2013 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/thread/thread.hpp>
+#include <iostream>
+
+void hello_world()
+{
+ std::cout << "Hello from thread!" << std::endl;
+}
+
+int main()
+{
+ boost::thread my_thread(&hello_world);
+ my_thread.join();
+}
diff --git a/src/boost/libs/thread/test/test_8596.cpp b/src/boost/libs/thread/test/test_8596.cpp
new file mode 100644
index 000000000..d8af66e87
--- /dev/null
+++ b/src/boost/libs/thread/test/test_8596.cpp
@@ -0,0 +1,61 @@
+// Copyright (C) 2013 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 4
+
+#include <iostream>
+#include <functional>
+//#include <future>
+
+#include <boost/thread.hpp>
+#include <boost/shared_ptr.hpp>
+
+int f()
+{
+ return 42;
+}
+
+boost::packaged_task<int()>* schedule(boost::function<int ()> const& fn)
+{
+ // Normally, the pointer to the packaged task is stored in a queue
+ // for execution on a separate thread, and the schedule function
+ // would return just a future<T>
+
+ boost::function<int ()> copy(fn);
+ boost::packaged_task<int()>* result = new boost::packaged_task<int()>(copy);
+ return result;
+}
+
+struct MyFunc
+{
+ MyFunc(MyFunc const&) = delete;
+ MyFunc& operator=(MyFunc const&) = delete;
+ MyFunc() {};
+ MyFunc(MyFunc &&) {};
+ MyFunc& operator=(MyFunc &&) { return *this;};
+ void operator()()const {}
+};
+
+
+int main()
+{
+ boost::packaged_task<int()>* p(schedule(f));
+ (*p)();
+
+ boost::future<int> fut = p->get_future();
+ std::cout << "The answer to the ultimate question: " << fut.get() << std::endl;
+
+ {
+ boost::function<void()> f;
+ MyFunc mf;
+
+ boost::packaged_task<void()> t1(f);
+ boost::packaged_task<void()> t2(boost::move(mf));
+ }
+
+ return 0;
+}
+
+
diff --git a/src/boost/libs/thread/test/test_8600.cpp b/src/boost/libs/thread/test/test_8600.cpp
new file mode 100644
index 000000000..224e41fa6
--- /dev/null
+++ b/src/boost/libs/thread/test/test_8600.cpp
@@ -0,0 +1,140 @@
+// Copyright (C) 2013 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
+#include <vector>
+#include <utility>
+#include <type_traits>
+#if 1
+
+struct B {
+ int v;
+ B(int i) : v(i) {}
+};
+
+struct D: B {
+ D(int i) : B(i) {}
+};
+
+void fb(B const&) {}
+void fd(D const&) {}
+
+BOOST_STATIC_ASSERT(sizeof(B)==sizeof(D));
+
+template <class T, class Allocator=std::allocator<T> >
+class new_vector;
+template <class T, class Allocator>
+class new_vector : public std::vector<T,Allocator>
+{
+ typedef std::vector<T,Allocator> base_type;
+public:
+ new_vector() : base_type() {}
+ new_vector(unsigned s) : base_type(s) {}
+};
+
+template <class Allocator >
+class new_vector<bool, Allocator>
+{
+ //std::vector<char,typename Allocator::template rebind<char>::other > v;
+ int i;
+public:
+};
+
+template <class T, class A>
+typename std::enable_if<!std::is_same<T, bool>::value,
+ new_vector<T,A>&
+>::type
+new_vector_cast(std::vector<T,A> & v) {
+ return reinterpret_cast<new_vector<T,A>&>(v);
+}
+
+BOOST_STATIC_ASSERT(sizeof(std::vector<int>)==sizeof(new_vector<int>));
+BOOST_STATIC_ASSERT(sizeof(std::vector<bool>)!=sizeof(new_vector<bool>));
+
+void fb(std::vector<int> const&) {}
+void fd(new_vector<int> const&) {}
+
+int main() {
+ {
+ std::vector<int> b(1);
+ b[0] = 1;
+ new_vector<int> d = new_vector_cast(b);
+ BOOST_ASSERT(b[0] == d[0]);
+ }
+ {
+ //std::vector<bool> b;
+ //new_vector<bool> d = new_vector_cast(b); // compile fail
+ }
+ {
+ std::vector<int> b(1);
+ b[0] = 1;
+ fd(new_vector_cast(b));
+ }
+ {
+ new_vector<int> d(1);
+ d[0] = 1;
+ std::vector<int> b = d;
+ BOOST_ASSERT(b[0] == d[0]);
+ }
+ {
+ //new_vector<bool> d;
+ //std::vector<bool> b = d; // compile fail
+ }
+ {
+ new_vector<int> d(1);
+ d[0] = 1;
+ fd(d);
+ }
+ return 0;
+}
+
+
+#else
+int main() {
+ {
+ B b(1);
+ D d = reinterpret_cast<D&>(b);
+ BOOST_ASSERT(b.v == d.v);
+ }
+ {
+ B b(1);
+ fd(reinterpret_cast<D&>(b));
+ }
+ {
+ D d(2);
+ B b = d;
+ BOOST_ASSERT(b.v == d.v);
+ }
+ {
+ D d(2);
+ fd(d);
+ }
+ return 0;
+}
+
+#define BOOST_THREAD_VERSION 4
+
+#include <iostream>
+#include <boost/thread.hpp>
+
+int calculate_the_answer_to_life_the_universe_and_everything()
+{
+return 42;
+}
+
+int main()
+{
+boost::packaged_task<int()> pt(calculate_the_answer_to_life_the_universe_and_everything);
+boost::shared_future<int> fi1 = boost::shared_future<int>(pt.get_future());
+boost::shared_future<int> fi2 = fi1;
+
+boost::thread task(boost::move(pt)); // launch task on a thread
+
+boost::wait_for_any(fi1, fi2);
+std::cout << "Wait for any returned\n";
+return (0);
+}
+#endif
diff --git a/src/boost/libs/thread/test/test_8674.cpp b/src/boost/libs/thread/test/test_8674.cpp
new file mode 100644
index 000000000..87a6524d8
--- /dev/null
+++ b/src/boost/libs/thread/test/test_8674.cpp
@@ -0,0 +1,43 @@
+// Copyright (C) 2013 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <iostream>
+
+#define USE_STD 0
+#define USE_BOOST 1
+
+#define USED_THREAD_API USE_BOOST
+//#define USED_THREAD_API USE_STD
+
+#if USED_THREAD_API == USE_BOOST
+
+# define BOOST_THREAD_VERSION 4
+# include <boost/thread/future.hpp>
+
+ using boost::future;
+ using boost::async;
+
+#endif
+#if USED_THREAD_API == USE_STD
+# include <future>
+ using std::future;
+ using std::async;
+#endif
+
+
+
+future<void> do_something()
+{
+ auto result = async( []{ std::cout<< "A\n"; } );
+ std::cout << "B\n";
+ return result; // error here
+}
+
+int main()
+{
+ do_something().wait();
+ std::cout << "Hello, World!" << std::endl;
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/test_8943.cpp b/src/boost/libs/thread/test/test_8943.cpp
new file mode 100644
index 000000000..99cf70de1
--- /dev/null
+++ b/src/boost/libs/thread/test/test_8943.cpp
@@ -0,0 +1,47 @@
+// Copyright (C) 2013 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined(WIN32)
+#include <tchar.h>
+#endif
+
+#include <cstdlib>
+#include <iostream>
+#include <boost/thread/once.hpp>
+
+namespace {
+
+class foo
+{
+public:
+ void operator()() const
+ {
+ std::cout << "foo" << std::endl;
+ }
+}; // class foo
+
+}
+
+#if defined(WIN32)
+int _tmain(int /*argc*/, _TCHAR* /*argv*/[])
+#else
+int main(int /*argc*/, char* /*argv*/[])
+#endif
+{
+ try
+ {
+ boost::once_flag once_flag = BOOST_ONCE_INIT;
+ boost::call_once(once_flag, foo());
+ return EXIT_SUCCESS;
+ }
+ catch (...)
+ {
+ std::cerr << "Unknown exception" << std::endl;
+ BOOST_TEST(false);
+ }
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/test_8960.cpp b/src/boost/libs/thread/test/test_8960.cpp
new file mode 100644
index 000000000..84cce77e4
--- /dev/null
+++ b/src/boost/libs/thread/test/test_8960.cpp
@@ -0,0 +1,53 @@
+// Copyright (C) 2013 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/thread/thread.hpp>
+#include <iostream>
+
+#include <iostream>
+
+#include <boost/thread.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/chrono.hpp>
+//#include <boost/bind/bind.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+
+void do_thread()
+{
+
+ try
+ {
+ boost::condition_variable c1;
+ boost::mutex m1;
+ boost::unique_lock<boost::mutex> l1(m1);
+
+ c1.wait_for(l1, boost::chrono::seconds(1));
+ }
+ catch (std::runtime_error& ex)
+ {
+ std::cout << "EXCEPTION ! " << ex.what() << std::endl;
+ BOOST_TEST(false);
+
+ }
+ catch (...)
+ {
+ std::cout << "EXCEPTION ! " << std::endl;
+ BOOST_TEST(false);
+ }
+
+}
+
+int main()
+{
+
+ boost::thread th1(&do_thread);
+ th1.join();
+
+ //std::string s1;
+ //std::cin >> s1;
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/test_9079_a.cpp b/src/boost/libs/thread/test/test_9079_a.cpp
new file mode 100644
index 000000000..3e8ca03fd
--- /dev/null
+++ b/src/boost/libs/thread/test/test_9079_a.cpp
@@ -0,0 +1,57 @@
+// Copyright (C) 2013 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// A
+
+//#include <boost/log/trivial.hpp>
+#include <boost/chrono.hpp>
+#include <boost/thread.hpp>
+#include <boost/thread/condition_variable.hpp>
+
+//#if !defined(BOOST_NO_CXX11_ALIGNAS)
+//#error
+//# define BOOST_ALIGNMENT2(x) alignas(x)
+//#elif defined(_MSC_VER)
+//#error
+//# define BOOST_ALIGNMENT2(x) __declspec(align(x))
+//#elif defined(__GNUC__)
+//#error
+//# define BOOST_ALIGNMENT(x) __attribute__ ((__aligned__(x)))
+//#else
+//#error
+//# define BOOST_NO_ALIGNMENT2
+//# define BOOST_ALIGNMENT2(x)
+//#endif
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point TimePoint;
+
+inline TimePoint real_time_now()
+{
+ return Clock::now();
+}
+
+int main()
+{
+ using namespace boost::chrono;
+
+ boost::condition_variable m_task_spawn_condition;
+
+ boost::mutex main_thread_mutex;
+ boost::unique_lock < boost::mutex > main_thread_lock(main_thread_mutex);
+
+ //BOOST_LOG_TRIVIAL(info) << "[TaskScheduler::run_and_wait] Scheduling loop - BEGIN";
+
+ //for (;;)
+ {
+ static const milliseconds TIME_BACK = milliseconds(1);
+ m_task_spawn_condition.wait_until(
+ main_thread_lock,
+ real_time_now() - TIME_BACK); // wait forever
+ m_task_spawn_condition.wait_for( main_thread_lock, - TIME_BACK ); // same problem
+ //BOOST_LOG_TRIVIAL(trace) << "TICK";
+ }
+
+}
diff --git a/src/boost/libs/thread/test/test_9079_b.cpp b/src/boost/libs/thread/test/test_9079_b.cpp
new file mode 100644
index 000000000..90abd206f
--- /dev/null
+++ b/src/boost/libs/thread/test/test_9079_b.cpp
@@ -0,0 +1,86 @@
+// Copyright (C) 2013 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// B
+
+#include <boost/atomic.hpp>
+//#include <boost/log/trivial.hpp>
+#include <boost/chrono.hpp>
+#include <boost/chrono/chrono_io.hpp>
+#include <boost/thread.hpp>
+#include <boost/thread/condition_variable.hpp>
+
+typedef boost::chrono::high_resolution_clock Clock;
+typedef Clock::time_point TimePoint;
+
+inline TimePoint real_time_now()
+{
+ return Clock::now();
+}
+
+class Foo {
+ boost::atomic<bool> m_is_exiting;
+ TimePoint m_next_tick_time;
+
+public:
+
+ bool is_exiting() const
+ {
+ return m_is_exiting;
+ }
+
+ TimePoint spawn_tasks() // note that in my app, this call takes more time than here
+ {
+ using namespace boost::chrono;
+ const TimePoint now = real_time_now();
+
+ if (m_next_tick_time < now) {
+ m_next_tick_time = now + seconds(1);
+ //BOOST_LOG_TRIVIAL(info) << "TICK!";
+ }
+
+ return m_next_tick_time;
+ }
+
+};
+
+int main()
+{
+ using namespace boost::chrono;
+ static const milliseconds MIN_TIME_TASKS_SPAWN_FREQUENCY = milliseconds(1);
+ //microseconds(1); // THE SHORTER THE QUICKER TO REPRODUCE THE BUG
+
+ boost::condition_variable m_task_spawn_condition;
+ Foo foo;
+
+ boost::mutex main_thread_mutex;
+ boost::unique_lock < boost::mutex > main_thread_lock(main_thread_mutex);
+
+ //BOOST_LOG_TRIVIAL(info) << "[TaskScheduler::run_and_wait] Scheduling loop - BEGIN";
+
+ int i =11;
+ while (i--)
+ {
+ const TimePoint next_task_spawn_time = foo.spawn_tasks();
+
+ const TimePoint now = real_time_now();
+ const TimePoint next_minimum_spawn_time = now + MIN_TIME_TASKS_SPAWN_FREQUENCY;
+ const TimePoint next_spawn_time = next_task_spawn_time > TimePoint()
+ && next_task_spawn_time < next_minimum_spawn_time
+ ? next_task_spawn_time : next_minimum_spawn_time;
+
+ const TimePoint::duration wait_time = next_spawn_time - now;
+ if (wait_time > wait_time.zero()) {
+ // BOOST_LOG_TRIVIAL(trace) << "WAIT TIME: " << wait_time; // UNCOMMENT THIS: MAKES IT WORKS. WAT??????
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ std::cout << next_spawn_time << std::endl;
+ m_task_spawn_condition.wait_until(
+ main_thread_lock,
+ next_spawn_time); // DON'T WORK: WILL WAIT IF next_spawn_time is too close!
+ }
+
+ }
+
+}
diff --git a/src/boost/libs/thread/test/test_9192.cpp b/src/boost/libs/thread/test/test_9192.cpp
new file mode 100644
index 000000000..c7aad7dd8
--- /dev/null
+++ b/src/boost/libs/thread/test/test_9192.cpp
@@ -0,0 +1,145 @@
+// Copyright (C) 2014 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/interprocess/shared_memory_object.hpp>
+#include <boost/interprocess/mapped_region.hpp>
+#include <boost/thread.hpp>
+
+using namespace boost::interprocess;
+
+struct item
+{
+ int i;
+};
+
+struct queue
+{
+ void put( const item& item )
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ while ( item_in )
+ cond_full.wait(lock);
+
+ item_ = item;
+ item_in = true;
+ cond_empty.notify_one();
+ }
+
+ void print()
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ while ( !item_in )
+ cond_empty.wait(lock);
+
+ item_in = false;
+ std::cout << item_.i << std::endl;
+ cond_full.notify_one();
+ }
+
+
+private:
+ //Mutex to protect access to the queue
+ boost::mutex mutex;
+
+ //Condition to wait when the queue is empty
+ boost::condition_variable cond_empty;
+
+ //Condition to wait when the queue is full
+ boost::condition_variable cond_full;
+
+ bool item_in;
+
+ //Items to fill
+ item item_;
+};
+
+void *addr;
+
+void printThread()
+{
+ //Erase previous shared memory and schedule erasure on exit
+ struct shm_remove
+ {
+ shm_remove() { shared_memory_object::remove("MySharedMemory"); }
+ ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
+ } remover;
+
+ //Create a shared memory object.
+ shared_memory_object shm(create_only,"MySharedMemory",read_write);
+
+ try
+ {
+// //Set size
+// shm.truncate(sizeof(queue));
+//
+// //Map the whole shared memory in this process
+// mapped_region region(shm,read_write);
+//
+// //Get the address of the mapped region
+// void *addr = region.get_address();
+
+ //Construct the shared structure in memory
+ queue *q = new (addr) queue;
+
+ do
+ {
+ q->print();
+ } while ( true );
+ }
+// catch(interprocess_exception &ex)
+// {
+// std::cout << ex.what() << std::endl;
+// }
+ catch(boost::thread_interrupted&)
+ {
+ std::cout << "interrupted" << std::endl;
+ }
+ catch(...)
+ {
+ std::cout << "exception" << std::endl;
+ }
+}
+
+int main()
+{
+ addr = new queue();
+ boost::thread t(printThread);
+
+ // give the thread time to create the shm
+ boost::this_thread::sleep( boost::posix_time::milliseconds( 1000 ) );
+
+// //Create a shared memory object.
+// shared_memory_object shm(open_only,"MySharedMemory",read_write);
+
+ try
+ {
+// //Map the whole shared memory in this process
+// mapped_region region(shm,read_write);
+//
+// //Get the address of the mapped region
+// void *addr = region.get_address();
+
+ //Obtain a pointer to the shared structure
+ queue *q = static_cast<queue*>(addr);
+
+ item i;
+ i.i = 42;
+ q->put( i );
+
+ ++i.i;
+ q->put( i );
+
+ // give the printThread time to "process" the item
+ boost::this_thread::sleep( boost::posix_time::milliseconds( 1000 ) );
+
+ t.interrupt();
+ t.join();
+ }
+ catch(...)
+ {
+ std::cout << "exception" << std::endl;
+ return -1;
+ }
+}
diff --git a/src/boost/libs/thread/test/test_9303.cpp b/src/boost/libs/thread/test/test_9303.cpp
new file mode 100644
index 000000000..af8be567d
--- /dev/null
+++ b/src/boost/libs/thread/test/test_9303.cpp
@@ -0,0 +1,177 @@
+// Copyright (C) 2014 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 4
+ #include <iostream>
+ #include <fstream>
+ #include <stdio.h>
+ #include <boost/function.hpp>
+ #include <boost/make_shared.hpp>
+ #include <boost/shared_ptr.hpp>
+ #include <boost/bind/bind.hpp>
+ #include <boost/asio.hpp>
+ #include <boost/thread.hpp>
+ #include <boost/thread/future.hpp>
+
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ #define EXAMPLE_1
+ #define EXAMPLE_2
+ #define EXAMPLE_3
+ #define EXAMPLE_4
+ #define EXAMPLE_5
+ #define EXAMPLE_6
+ #define EXAMPLE_7
+#else
+ #define EXAMPLE_1
+ #define EXAMPLE_2
+ //#define EXAMPLE_3
+ //#define EXAMPLE_4
+ //#define EXAMPLE_5
+ //#define EXAMPLE_6
+ //#define EXAMPLE_7
+#endif
+
+ // Test functions
+
+ int int_no_params()
+ {
+ return 42;
+ }
+
+ int int_with_params(int i)
+ {
+ return i;
+ }
+
+ std::string string_no_params()
+ {
+ return std::string("forty two");
+ }
+
+ std::string string_with_params(std::string& ans)
+ {
+ return ans;
+ }
+
+ int main(int /*argc*/, char ** /*argv[]*/)
+ {
+ std::string ans("forty two");
+
+ #if defined EXAMPLE_1
+ //! Compiles and produces correct result.
+ {
+ boost::packaged_task<int()> example(int_no_params);
+ boost::future<int> f = example.get_future();
+ boost::thread task(boost::move(example));
+ int answer = f.get();
+ std::cout << "Answer to life and whatnot, in English: " << answer << std::endl;
+ task.join();
+ }
+ #endif
+
+ #if defined EXAMPLE_2
+ //! Compiles and produces correct result.
+ {
+ boost::packaged_task<std::string()> example(string_no_params);
+ boost::future<std::string> f = example.get_future();
+ boost::thread task(boost::move(example));
+ std::string answer = f.get();
+ std::cout << "string_no_params: " << answer << std::endl;
+ task.join();
+ }
+
+ #endif
+
+ #if defined EXAMPLE_3
+ //! Doesn't compile in C++03.
+ //! error: variable âboost::packaged_task<std::basic_string<char>(std::basic_string<char>&)> exampleâ has initializer but incomplete type
+
+ {
+ boost::packaged_task<std::string(std::string&)> example(string_with_params);
+ boost::future<std::string> f = example.get_future();
+ example(ans);
+ std::string answer = f.get();
+ std::cout << "string_with_params: " << answer << std::endl;
+ }
+
+ #endif
+
+ #if defined EXAMPLE_4
+ //! Doesn't compile in C++11
+// In file included from test_9303.cpp:10:
+// In file included from ../../../boost/thread.hpp:13:
+// In file included from ../../../boost/thread/thread.hpp:12:
+// In file included from ../../../boost/thread/thread_only.hpp:22:
+// ../../../boost/thread/detail/thread.hpp:76:15: error: no matching function for call to 'invoke'
+// invoke(std::move(std::get<0>(fp)), std::move(std::get<Indices>(fp))...);
+// ^~~~~~
+
+ {
+ boost::packaged_task<std::string(std::string&)> example(string_with_params);
+ boost::future<std::string> f = example.get_future();
+ boost::thread task(boost::move(example), boost::ref(ans));
+ std::string answer = f.get();
+ std::cout << "string_with_params: " << answer << std::endl;
+ task.join();
+ }
+ #endif
+
+ #if defined EXAMPLE_5
+ //! Doesn't compile in C++03, C++11 only.
+ //! error: extended initializer lists only available with -std=c++11 or -std=gnu++11 [-Werror]
+ {
+ boost::packaged_task<std::string(std::string&)> example
+ { boost::bind(&string_with_params, ans) };
+ boost::future<std::string> f = example.get_future();
+ boost::thread task(boost::move(example), boost::ref(ans));
+ std::string answer = f.get();
+ std::cout << "string_with_params: " << answer << std::endl;
+ task.join();
+ }
+ #endif
+
+ #if defined EXAMPLE_6
+ //! Doesn't compile in C++03, C++11 only.
+ // packagedTestTest.cpp:94:43: error: invalid use of incomplete type ‘class boost::packaged_task<std::basic_string<char>(std::basic_string<char>&)>’
+ // packagedTestTest.cpp:95:37: error: incomplete type ‘task_t {aka boost::packaged_task<std::basic_string<char>(std::basic_string<char>&)>}’ used in nested name specifier
+ // boost/thread/future.hpp:1320:11: error: declaration of ‘class boost::packaged_task<std::basic_string<char>(std::basic_string<char>&)>’
+ {
+ //typedef boost::packaged_task<std::string(std::string&)> task_t;
+ typedef boost::packaged_task<std::string()> task_t;
+ boost::shared_ptr<task_t> example = boost::make_shared<task_t>(boost::bind(&string_with_params, boost::ref(ans)));
+ boost::future<std::string> f = example->get_future();
+ boost::thread task(boost::bind(&task_t::operator(), example));
+ std::string answer = f.get();
+ std::cout << "string_with_params: " << answer << std::endl;
+ task.join();
+ }
+ #endif
+
+ #if defined EXAMPLE_7
+ //! Doesn't compile in C++03, C++11 only.
+ // packagedTestTest.cpp:94:43: error: invalid use of incomplete type ‘class boost::packaged_task<std::basic_string<char>(std::basic_string<char>&)>’
+ // packagedTestTest.cpp:95:37: error: incomplete type ‘task_t {aka boost::packaged_task<std::basic_string<char>(std::basic_string<char>&)>}’ used in nested name specifier
+ // boost/thread/future.hpp:1320:11: error: declaration of ‘class boost::packaged_task<std::basic_string<char>(std::basic_string<char>&)>’
+ {
+ boost::asio::io_service io_service;
+ boost::thread_group threads;
+ boost::asio::io_service::work work(io_service);
+
+ for (int i = 0; i < 3; ++i)
+ {
+ threads.create_thread(boost::bind(&boost::asio::io_service::run,
+ &io_service));
+ }
+ typedef boost::packaged_task<std::string()> task_t;
+ boost::shared_ptr<task_t> example = boost::make_shared<task_t>(boost::bind(&string_with_params, ans));
+ boost::future<std::string> f = example->get_future();
+ io_service.post(boost::bind(&task_t::operator(), example));
+ std::string answer = f.get();
+ std::cout << "string_with_params: " << answer << std::endl;
+ threads.join_all();
+ }
+ #endif
+ return 0;
+ }
diff --git a/src/boost/libs/thread/test/test_9319.cpp b/src/boost/libs/thread/test/test_9319.cpp
new file mode 100644
index 000000000..5dafe4d49
--- /dev/null
+++ b/src/boost/libs/thread/test/test_9319.cpp
@@ -0,0 +1,60 @@
+// Copyright (C) 2013 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// futtest.cpp
+#include <iostream>
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/bind/bind.hpp>
+#include <boost/chrono.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/scoped_ptr.hpp>
+
+typedef boost::shared_ptr< boost::promise<int> > IntPromise;
+
+void foo(IntPromise p)
+{
+ std::cout << "foo" << std::endl;
+ p->set_value(123); // This line locks the future's mutex, then calls the continuation with the mutex already locked.
+}
+
+void bar(boost::future<int> fooResult)
+{
+ try {
+ std::cout << "bar" << std::endl;
+ int i = fooResult.get(); // Code hangs on this line (Due to future already being locked by the set_value call)
+ std::cout << "i: " << i << std::endl;
+ } catch(...) {
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ }
+}
+
+int main()
+{
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ try {
+ IntPromise p(new boost::promise<int>());
+ boost::thread t(boost::bind(foo, p));
+ boost::future<int> f1 = p->get_future();
+ f1.then(boost::launch::deferred, &bar);
+ t.join();
+ } catch(...) {
+ return 1;
+ }
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ try {
+ IntPromise p(new boost::promise<int>());
+ boost::thread t(boost::bind(foo, p));
+ boost::future<int> f1 = p->get_future();
+ f1.then(boost::launch::async, &bar);
+ t.join();
+ } catch(...) {
+ return 2;
+ }
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+}
+
diff --git a/src/boost/libs/thread/test/test_9711.cpp b/src/boost/libs/thread/test/test_9711.cpp
new file mode 100644
index 000000000..d8fd8e3e8
--- /dev/null
+++ b/src/boost/libs/thread/test/test_9711.cpp
@@ -0,0 +1,44 @@
+// Copyright (C) 2014 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_PROVIDES_FUTURE
+#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#include <boost/thread/future.hpp>
+
+
+int main()
+{
+#if ! defined BOOST_NO_CXX11_LAMBDAS && ! (defined BOOST_MSVC && _MSC_VER < 1700)
+ boost::promise<int> prom;
+ boost::future<int> futr = prom.get_future();
+
+ int callCount = 0;
+
+ boost::future<void> futr2 = futr.then(boost::launch::deferred,
+ [&] (boost::future<int> f) {
+ callCount++;
+ assert(f.valid());
+ assert(f.is_ready());
+ assert(17 == f.get());
+ });
+
+ assert(futr2.valid());
+ assert(!futr2.is_ready());
+ assert(0 == callCount);
+
+ prom.set_value(17);
+ assert(0 == callCount);
+
+ futr2.get();
+ assert(1 == callCount);
+
+#endif
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/test_9856.cpp b/src/boost/libs/thread/test/test_9856.cpp
new file mode 100644
index 000000000..b7dcc6e37
--- /dev/null
+++ b/src/boost/libs/thread/test/test_9856.cpp
@@ -0,0 +1,29 @@
+#include "boost/atomic.hpp"
+#include "boost/thread.hpp"
+#include <iostream>
+
+using namespace boost;
+
+int main() {
+ atomic<size_t> total(0), failures(0);
+
+#pragma omp parallel shared(total, failures) num_threads(1000)
+ {
+ mutex mtx;
+ condition_variable cond;
+ unique_lock<mutex> lk(mtx);
+ for (int i = 0; i < 500; i++) {
+ ++total;
+ if (cv_status::timeout != cond.wait_for(lk, chrono::milliseconds(10)))
+ ++failures;
+ }
+ }
+ if(failures)
+ std::cout << "There were " << failures << " failures out of " << total << " timed waits." << std::endl;
+ if((100*failures)/total>40)
+ {
+ std::cerr << "This exceeds 10%, so failing the test." << std::endl;
+ return 1;
+ }
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/test_barrier.cpp b/src/boost/libs/thread/test/test_barrier.cpp
new file mode 100644
index 000000000..5baf19cd4
--- /dev/null
+++ b/src/boost/libs/thread/test/test_barrier.cpp
@@ -0,0 +1,69 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+// (C) Copyright 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/thread.hpp>
+#include <boost/thread/barrier.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+#include <vector>
+
+namespace {
+
+// Shared variables for generation barrier test
+const int N_THREADS=3;
+boost::barrier gen_barrier(N_THREADS);
+boost::mutex mutex;
+long global_parameter;
+
+void barrier_thread()
+{
+ for (int i = 0; i < 5; ++i)
+ {
+ if (gen_barrier.wait())
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ global_parameter++;
+ }
+ }
+}
+
+} // namespace
+
+void test_barrier()
+{
+ boost::thread_group g;
+ global_parameter = 0;
+
+ try
+ {
+ for (int i = 0; i < N_THREADS; ++i)
+ g.create_thread(&barrier_thread);
+ g.join_all();
+ }
+ catch(...)
+ {
+ BOOST_TEST(false);
+ g.interrupt_all();
+ g.join_all();
+ //throw;
+ }
+
+ BOOST_TEST(global_parameter==5);
+
+}
+
+int main()
+{
+
+ test_barrier();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/test_barrier_size_fct.cpp b/src/boost/libs/thread/test/test_barrier_size_fct.cpp
new file mode 100644
index 000000000..2671af848
--- /dev/null
+++ b/src/boost/libs/thread/test/test_barrier_size_fct.cpp
@@ -0,0 +1,69 @@
+// (C) Copyright 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/thread.hpp>
+#include <boost/thread/barrier.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+#include <vector>
+
+namespace {
+
+
+// Shared variables for generation barrier test
+long global_parameter;
+const int N_THREADS=3;
+
+unsigned int size_fct() {
+ global_parameter++;
+ return N_THREADS;
+}
+
+boost::barrier gen_barrier(N_THREADS, &size_fct);
+
+void barrier_thread()
+{
+ for (int i = 0; i < 5; ++i)
+ {
+ gen_barrier.count_down_and_wait();
+ }
+}
+
+} // namespace
+
+void test_barrier()
+{
+ boost::thread_group g;
+ global_parameter = 0;
+
+ try
+ {
+ for (int i = 0; i < N_THREADS; ++i)
+ g.create_thread(&barrier_thread);
+ g.join_all();
+ }
+ catch(...)
+ {
+ BOOST_TEST(false);
+ g.interrupt_all();
+ g.join_all();
+ //throw;
+ }
+
+ BOOST_TEST(global_parameter==5);
+
+}
+
+int main()
+{
+
+ test_barrier();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/test_barrier_void_fct.cpp b/src/boost/libs/thread/test/test_barrier_void_fct.cpp
new file mode 100644
index 000000000..77a65e581
--- /dev/null
+++ b/src/boost/libs/thread/test/test_barrier_void_fct.cpp
@@ -0,0 +1,68 @@
+// (C) Copyright 2013 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/thread.hpp>
+#include <boost/thread/barrier.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+#include <vector>
+
+namespace {
+
+
+// Shared variables for generation barrier test
+long global_parameter;
+
+void void_fct() {
+ global_parameter++;
+}
+
+const int N_THREADS=3;
+boost::barrier gen_barrier(N_THREADS, &void_fct);
+
+void barrier_thread()
+{
+ for (int i = 0; i < 5; ++i)
+ {
+ gen_barrier.count_down_and_wait();
+ }
+}
+
+} // namespace
+
+void test_barrier()
+{
+ boost::thread_group g;
+ global_parameter = 0;
+
+ try
+ {
+ for (int i = 0; i < N_THREADS; ++i)
+ g.create_thread(&barrier_thread);
+ g.join_all();
+ }
+ catch(...)
+ {
+ BOOST_TEST(false);
+ g.interrupt_all();
+ g.join_all();
+ //throw;
+ }
+
+ BOOST_TEST(global_parameter==5);
+
+}
+
+int main()
+{
+
+ test_barrier();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/test_completion_latch.cpp b/src/boost/libs/thread/test/test_completion_latch.cpp
new file mode 100644
index 000000000..bef883654
--- /dev/null
+++ b/src/boost/libs/thread/test/test_completion_latch.cpp
@@ -0,0 +1,108 @@
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// (C) Copyright 2013 Vicente J. Botet Escriba
+
+#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/thread.hpp>
+#include <boost/thread/completion_latch.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+#include <vector>
+
+namespace
+{
+
+ // Shared variables for generation completion_latch test
+ const int N_THREADS = 10;
+ boost::completion_latch gen_latch(N_THREADS);
+ boost::mutex mutex;
+ long global_parameter;
+
+ void latch_thread()
+ {
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ global_parameter++;
+ }
+ gen_latch.count_down();
+ //do something else
+ }
+
+} // namespace
+
+void test_global_parameter()
+{
+ boost::unique_lock<boost::mutex> lock(mutex);
+ BOOST_TEST_EQ(global_parameter, N_THREADS);
+}
+
+void reset_gen_latch()
+{
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ BOOST_TEST_EQ(global_parameter, N_THREADS);
+ }
+ gen_latch.reset(N_THREADS);
+}
+
+void test_completion_latch_reset()
+{
+ boost::thread_group g;
+ boost::thread_group g2;
+
+ gen_latch.then(&reset_gen_latch);
+
+ {
+ global_parameter = 0;
+ try
+ {
+ for (int i = 0; i < N_THREADS; ++i)
+ g.create_thread(&latch_thread);
+
+ if (!gen_latch.try_wait())
+ if (gen_latch.wait_for(boost::chrono::milliseconds(100)) == boost::cv_status::timeout)
+ if (gen_latch.wait_until(boost::chrono::steady_clock::now()+boost::chrono::milliseconds(100)) == boost::cv_status::timeout)
+ gen_latch.wait(); // All the threads have been updated the global_parameter
+ g.join_all();
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ g.interrupt_all();
+ g.join_all();
+ //throw;
+ }
+ }
+ gen_latch.then(&test_global_parameter);
+ {
+ global_parameter = 0;
+ try
+ {
+ for (int i = 0; i < N_THREADS; ++i)
+ g2.create_thread(&latch_thread);
+
+ if (!gen_latch.try_wait())
+ gen_latch.wait(); // All the threads have been updated the global_parameter
+
+ g2.join_all();
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ g2.interrupt_all();
+ g2.join_all();
+ //throw;
+ }
+ }
+}
+
+int main()
+{
+ test_completion_latch_reset();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/test_condition.cpp b/src/boost/libs/thread/test/test_condition.cpp
new file mode 100644
index 000000000..210860b71
--- /dev/null
+++ b/src/boost/libs/thread/test/test_condition.cpp
@@ -0,0 +1,187 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+// Copyright (C) 2007 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
+#define BOOST_TEST_MODULE Boost.Threads: condition test suite
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/condition.hpp>
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/xtime.hpp>
+
+#include <boost/config.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include "./util.inl"
+
+struct condition_test_data
+{
+ condition_test_data() : notified(0), awoken(0) { }
+
+ boost::mutex mutex;
+ boost::condition_variable condition;
+ int notified;
+ int awoken;
+};
+
+void condition_test_thread(condition_test_data* data)
+{
+ boost::unique_lock<boost::mutex> lock(data->mutex);
+ BOOST_CHECK(lock ? true : false);
+ while (!(data->notified > 0))
+ data->condition.wait(lock);
+ BOOST_CHECK(lock ? true : false);
+ data->awoken++;
+}
+
+struct cond_predicate
+{
+ cond_predicate(int& var, int val) : _var(var), _val(val) { }
+#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
+ cond_predicate(cond_predicate const&) = default;
+#endif
+
+ bool operator()() { return _var == _val; }
+
+ int& _var;
+ int _val;
+
+private:
+ void operator=(cond_predicate&);
+};
+
+void condition_test_waits(condition_test_data* data)
+{
+ boost::unique_lock<boost::mutex> lock(data->mutex);
+ BOOST_CHECK(lock ? true : false);
+
+ // Test wait.
+ while (data->notified != 1)
+ data->condition.wait(lock);
+ BOOST_CHECK(lock ? true : false);
+ BOOST_CHECK_EQUAL(data->notified, 1);
+ data->awoken++;
+ data->condition.notify_one();
+
+ // Test predicate wait.
+ data->condition.wait(lock, cond_predicate(data->notified, 2));
+ BOOST_CHECK(lock ? true : false);
+ BOOST_CHECK_EQUAL(data->notified, 2);
+ data->awoken++;
+ data->condition.notify_one();
+
+ // Test timed_wait.
+ boost::xtime xt = delay(10);
+ while (data->notified != 3)
+ data->condition.timed_wait(lock, xt);
+ BOOST_CHECK(lock ? true : false);
+ BOOST_CHECK_EQUAL(data->notified, 3);
+ data->awoken++;
+ data->condition.notify_one();
+
+ // Test predicate timed_wait.
+ xt = delay(10);
+ cond_predicate pred(data->notified, 4);
+ BOOST_CHECK(data->condition.timed_wait(lock, xt, pred));
+ BOOST_CHECK(lock ? true : false);
+ BOOST_CHECK(pred());
+ BOOST_CHECK_EQUAL(data->notified, 4);
+ data->awoken++;
+ data->condition.notify_one();
+
+ // Test predicate timed_wait with relative timeout
+ cond_predicate pred_rel(data->notified, 5);
+ BOOST_CHECK(data->condition.timed_wait(lock, boost::posix_time::seconds(10), pred_rel));
+ BOOST_CHECK(lock ? true : false);
+ BOOST_CHECK(pred_rel());
+ BOOST_CHECK_EQUAL(data->notified, 5);
+ data->awoken++;
+ data->condition.notify_one();
+}
+
+void do_test_condition_waits()
+{
+ condition_test_data data;
+
+ boost::thread thread(bind(&condition_test_waits, &data));
+
+ {
+ boost::unique_lock<boost::mutex> lock(data.mutex);
+ BOOST_CHECK(lock ? true : false);
+
+ boost::thread::sleep(delay(1));
+ data.notified++;
+ data.condition.notify_one();
+ while (data.awoken != 1)
+ data.condition.wait(lock);
+ BOOST_CHECK(lock ? true : false);
+ BOOST_CHECK_EQUAL(data.awoken, 1);
+
+ boost::thread::sleep(delay(1));
+ data.notified++;
+ data.condition.notify_one();
+ while (data.awoken != 2)
+ data.condition.wait(lock);
+ BOOST_CHECK(lock ? true : false);
+ BOOST_CHECK_EQUAL(data.awoken, 2);
+
+ boost::thread::sleep(delay(1));
+ data.notified++;
+ data.condition.notify_one();
+ while (data.awoken != 3)
+ data.condition.wait(lock);
+ BOOST_CHECK(lock ? true : false);
+ BOOST_CHECK_EQUAL(data.awoken, 3);
+
+ boost::thread::sleep(delay(1));
+ data.notified++;
+ data.condition.notify_one();
+ while (data.awoken != 4)
+ data.condition.wait(lock);
+ BOOST_CHECK(lock ? true : false);
+ BOOST_CHECK_EQUAL(data.awoken, 4);
+
+
+ boost::thread::sleep(delay(1));
+ data.notified++;
+ data.condition.notify_one();
+ while (data.awoken != 5)
+ data.condition.wait(lock);
+ BOOST_CHECK(lock ? true : false);
+ BOOST_CHECK_EQUAL(data.awoken, 5);
+ }
+
+ thread.join();
+ BOOST_CHECK_EQUAL(data.awoken, 5);
+}
+
+BOOST_AUTO_TEST_CASE(test_condition_waits)
+{
+ // We should have already tested notify_one here, so
+ // a timed test with the default execution_monitor::use_condition
+ // should be OK, and gives the fastest performance
+ timed_test(&do_test_condition_waits, 12);
+}
+
+void do_test_condition_wait_is_a_interruption_point()
+{
+ condition_test_data data;
+
+ boost::thread thread(bind(&condition_test_thread, &data));
+
+ thread.interrupt();
+ thread.join();
+ BOOST_CHECK_EQUAL(data.awoken,0);
+}
+
+
+BOOST_AUTO_TEST_CASE(test_condition_wait_is_a_interruption_point)
+{
+ timed_test(&do_test_condition_wait_is_a_interruption_point, 1);
+}
+
diff --git a/src/boost/libs/thread/test/test_condition_notify_all.cpp b/src/boost/libs/thread/test/test_condition_notify_all.cpp
new file mode 100644
index 000000000..17c84d5d5
--- /dev/null
+++ b/src/boost/libs/thread/test/test_condition_notify_all.cpp
@@ -0,0 +1,216 @@
+// Copyright (C) 2007 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+#define BOOST_TEST_MODULE Boost.Threads: condition_variable notify_all test suite
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/thread_only.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+#include "./util.inl"
+#include "./condition_test_common.hpp"
+
+unsigned const number_of_test_threads=5;
+
+void do_test_condition_notify_all_wakes_from_wait()
+{
+ wait_for_flag data;
+
+ boost::thread_group group;
+
+ try
+ {
+ for(unsigned i=0;i<number_of_test_threads;++i)
+ {
+ group.create_thread(bind(&wait_for_flag::wait_without_predicate, data));
+ }
+
+ {
+ boost::unique_lock<boost::mutex> lock(data.mutex);
+ data.flag=true;
+ data.cond_var.notify_all();
+ }
+
+ group.join_all();
+ BOOST_CHECK_EQUAL(data.woken,number_of_test_threads);
+ }
+ catch(...)
+ {
+ group.join_all();
+ throw;
+ }
+}
+
+void do_test_condition_notify_all_wakes_from_wait_with_predicate()
+{
+ wait_for_flag data;
+
+ boost::thread_group group;
+
+ try
+ {
+ for(unsigned i=0;i<number_of_test_threads;++i)
+ {
+ group.create_thread(bind(&wait_for_flag::wait_with_predicate, data));
+ }
+
+ {
+ boost::unique_lock<boost::mutex> lock(data.mutex);
+ data.flag=true;
+ data.cond_var.notify_all();
+ }
+
+ group.join_all();
+ BOOST_CHECK_EQUAL(data.woken,number_of_test_threads);
+ }
+ catch(...)
+ {
+ group.join_all();
+ throw;
+ }
+}
+
+void do_test_condition_notify_all_wakes_from_timed_wait()
+{
+ wait_for_flag data;
+
+ boost::thread_group group;
+
+ try
+ {
+ for(unsigned i=0;i<number_of_test_threads;++i)
+ {
+ group.create_thread(bind(&wait_for_flag::timed_wait_without_predicate, data));
+ }
+
+ {
+ boost::unique_lock<boost::mutex> lock(data.mutex);
+ data.flag=true;
+ data.cond_var.notify_all();
+ }
+
+ group.join_all();
+ BOOST_CHECK_EQUAL(data.woken,number_of_test_threads);
+ }
+ catch(...)
+ {
+ group.join_all();
+ throw;
+ }
+}
+
+void do_test_condition_notify_all_wakes_from_timed_wait_with_predicate()
+{
+ wait_for_flag data;
+
+ boost::thread_group group;
+
+ try
+ {
+ for(unsigned i=0;i<number_of_test_threads;++i)
+ {
+ group.create_thread(bind(&wait_for_flag::timed_wait_with_predicate, data));
+ }
+
+ {
+ boost::unique_lock<boost::mutex> lock(data.mutex);
+ data.flag=true;
+ data.cond_var.notify_all();
+ }
+
+ group.join_all();
+ BOOST_CHECK_EQUAL(data.woken,number_of_test_threads);
+ }
+ catch(...)
+ {
+ group.join_all();
+ throw;
+ }
+}
+
+void do_test_condition_notify_all_wakes_from_relative_timed_wait_with_predicate()
+{
+ wait_for_flag data;
+
+ boost::thread_group group;
+
+ try
+ {
+ for(unsigned i=0;i<number_of_test_threads;++i)
+ {
+ group.create_thread(bind(&wait_for_flag::relative_timed_wait_with_predicate, data));
+ }
+
+ {
+ boost::unique_lock<boost::mutex> lock(data.mutex);
+ data.flag=true;
+ data.cond_var.notify_all();
+ }
+
+ group.join_all();
+ BOOST_CHECK_EQUAL(data.woken,number_of_test_threads);
+ }
+ catch(...)
+ {
+ group.join_all();
+ throw;
+ }
+}
+
+namespace
+{
+ boost::mutex multiple_wake_mutex;
+ boost::condition_variable multiple_wake_cond;
+ unsigned multiple_wake_count=0;
+
+ void wait_for_condvar_and_increase_count()
+ {
+ boost::unique_lock<boost::mutex> lk(multiple_wake_mutex);
+ multiple_wake_cond.wait(lk);
+ ++multiple_wake_count;
+ }
+
+}
+
+
+void do_test_notify_all_following_notify_one_wakes_all_threads()
+{
+ boost::thread thread1(&wait_for_condvar_and_increase_count);
+ boost::thread thread2(&wait_for_condvar_and_increase_count);
+
+ boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+ multiple_wake_cond.notify_one();
+
+ boost::thread thread3(&wait_for_condvar_and_increase_count);
+
+ boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+ multiple_wake_cond.notify_one();
+ multiple_wake_cond.notify_all();
+ boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+
+ {
+ boost::unique_lock<boost::mutex> lk(multiple_wake_mutex);
+ BOOST_CHECK(multiple_wake_count==3);
+ }
+
+ thread1.join();
+ thread2.join();
+ thread3.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_condition_notify_all)
+{
+ timed_test(&do_test_condition_notify_all_wakes_from_wait, timeout_seconds);
+ timed_test(&do_test_condition_notify_all_wakes_from_wait_with_predicate, timeout_seconds);
+ timed_test(&do_test_condition_notify_all_wakes_from_timed_wait, timeout_seconds);
+ timed_test(&do_test_condition_notify_all_wakes_from_timed_wait_with_predicate, timeout_seconds);
+ timed_test(&do_test_condition_notify_all_wakes_from_relative_timed_wait_with_predicate, timeout_seconds);
+ timed_test(&do_test_notify_all_following_notify_one_wakes_all_threads, timeout_seconds);
+}
+
+
+
diff --git a/src/boost/libs/thread/test/test_condition_notify_one.cpp b/src/boost/libs/thread/test/test_condition_notify_one.cpp
new file mode 100644
index 000000000..00aff6268
--- /dev/null
+++ b/src/boost/libs/thread/test/test_condition_notify_one.cpp
@@ -0,0 +1,148 @@
+// Copyright (C) 2007 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+
+#define BOOST_TEST_MODULE Boost.Threads: condition_variable notify_one test suite
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/thread_only.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+#include "./util.inl"
+#include "./condition_test_common.hpp"
+
+void do_test_condition_notify_one_wakes_from_wait()
+{
+ wait_for_flag data;
+
+ boost::thread thread(bind(&wait_for_flag::wait_without_predicate, data));
+
+ {
+ boost::unique_lock<boost::mutex> lock(data.mutex);
+ data.flag=true;
+ data.cond_var.notify_one();
+ }
+
+ thread.join();
+ BOOST_CHECK(data.woken);
+}
+
+void do_test_condition_notify_one_wakes_from_wait_with_predicate()
+{
+ wait_for_flag data;
+
+ boost::thread thread(bind(&wait_for_flag::wait_with_predicate, data));
+
+ {
+ boost::unique_lock<boost::mutex> lock(data.mutex);
+ data.flag=true;
+ data.cond_var.notify_one();
+ }
+
+ thread.join();
+ BOOST_CHECK(data.woken);
+}
+
+void do_test_condition_notify_one_wakes_from_timed_wait()
+{
+ wait_for_flag data;
+
+ boost::thread thread(bind(&wait_for_flag::timed_wait_without_predicate, data));
+
+ {
+ boost::unique_lock<boost::mutex> lock(data.mutex);
+ data.flag=true;
+ data.cond_var.notify_one();
+ }
+
+ thread.join();
+ BOOST_CHECK(data.woken);
+}
+
+void do_test_condition_notify_one_wakes_from_timed_wait_with_predicate()
+{
+ wait_for_flag data;
+
+ boost::thread thread(bind(&wait_for_flag::timed_wait_with_predicate, data));
+
+ {
+ boost::unique_lock<boost::mutex> lock(data.mutex);
+ data.flag=true;
+ data.cond_var.notify_one();
+ }
+
+ thread.join();
+ BOOST_CHECK(data.woken);
+}
+
+void do_test_condition_notify_one_wakes_from_relative_timed_wait_with_predicate()
+{
+ wait_for_flag data;
+
+ boost::thread thread(bind(&wait_for_flag::relative_timed_wait_with_predicate, data));
+
+ {
+ boost::unique_lock<boost::mutex> lock(data.mutex);
+ data.flag=true;
+ data.cond_var.notify_one();
+ }
+
+ thread.join();
+ BOOST_CHECK(data.woken);
+}
+
+namespace
+{
+ boost::mutex multiple_wake_mutex;
+ boost::condition_variable multiple_wake_cond;
+ unsigned multiple_wake_count=0;
+
+ void wait_for_condvar_and_increase_count()
+ {
+ boost::unique_lock<boost::mutex> lk(multiple_wake_mutex);
+ multiple_wake_cond.wait(lk);
+ ++multiple_wake_count;
+ }
+
+}
+
+
+void do_test_multiple_notify_one_calls_wakes_multiple_threads()
+{
+ boost::thread thread1(&wait_for_condvar_and_increase_count);
+ boost::thread thread2(&wait_for_condvar_and_increase_count);
+
+ boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+ multiple_wake_cond.notify_one();
+
+ boost::thread thread3(&wait_for_condvar_and_increase_count);
+
+ boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+ multiple_wake_cond.notify_one();
+ multiple_wake_cond.notify_one();
+ boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+
+ {
+ boost::unique_lock<boost::mutex> lk(multiple_wake_mutex);
+ BOOST_CHECK(multiple_wake_count==3);
+ }
+
+ thread1.join();
+ thread2.join();
+ thread3.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_condition_notify_one)
+{
+ timed_test(&do_test_condition_notify_one_wakes_from_wait, timeout_seconds, execution_monitor::use_mutex);
+ timed_test(&do_test_condition_notify_one_wakes_from_wait_with_predicate, timeout_seconds, execution_monitor::use_mutex);
+ timed_test(&do_test_condition_notify_one_wakes_from_timed_wait, timeout_seconds, execution_monitor::use_mutex);
+ timed_test(&do_test_condition_notify_one_wakes_from_timed_wait_with_predicate, timeout_seconds, execution_monitor::use_mutex);
+ timed_test(&do_test_condition_notify_one_wakes_from_relative_timed_wait_with_predicate, timeout_seconds, execution_monitor::use_mutex);
+ timed_test(&do_test_multiple_notify_one_calls_wakes_multiple_threads, timeout_seconds, execution_monitor::use_mutex);
+}
diff --git a/src/boost/libs/thread/test/test_condition_timed_wait_times_out.cpp b/src/boost/libs/thread/test/test_condition_timed_wait_times_out.cpp
new file mode 100644
index 000000000..8e19cd7bf
--- /dev/null
+++ b/src/boost/libs/thread/test/test_condition_timed_wait_times_out.cpp
@@ -0,0 +1,169 @@
+// Copyright (C) 2007-8 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+
+#define BOOST_TEST_MODULE Boost.Threads: condition_variable test suite
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/condition.hpp>
+#include <boost/thread/thread_only.hpp>
+
+#include <boost/test/unit_test.hpp>
+#include "./util.inl"
+
+bool fake_predicate()
+{
+ return false;
+}
+
+unsigned const timeout_seconds=2;
+unsigned const timeout_grace=1;
+boost::posix_time::milliseconds const timeout_resolution(100);
+
+
+void do_test_timed_wait_times_out()
+{
+ boost::condition_variable cond;
+ boost::mutex m;
+
+ boost::posix_time::seconds const delay(timeout_seconds);
+ boost::unique_lock<boost::mutex> lock(m);
+ boost::system_time const start=boost::get_system_time();
+ boost::system_time const timeout=start+delay;
+
+ while(cond.timed_wait(lock,timeout)) {}
+
+ boost::system_time const end=boost::get_system_time();
+ BOOST_CHECK((delay-timeout_resolution)<=(end-start));
+}
+
+void do_test_timed_wait_with_predicate_times_out()
+{
+ boost::condition_variable cond;
+ boost::mutex m;
+
+ boost::posix_time::seconds const delay(timeout_seconds);
+ boost::unique_lock<boost::mutex> lock(m);
+ boost::system_time const start=boost::get_system_time();
+ boost::system_time const timeout=start+delay;
+
+ bool const res=cond.timed_wait(lock,timeout,fake_predicate);
+
+ boost::system_time const end=boost::get_system_time();
+ BOOST_CHECK(!res);
+ BOOST_CHECK((delay-timeout_resolution)<=(end-start));
+}
+
+void do_test_relative_timed_wait_with_predicate_times_out()
+{
+ boost::condition_variable cond;
+ boost::mutex m;
+
+ boost::posix_time::seconds const delay(timeout_seconds);
+ boost::unique_lock<boost::mutex> lock(m);
+ boost::system_time const start=boost::get_system_time();
+
+ bool const res=cond.timed_wait(lock,delay,fake_predicate);
+
+ boost::system_time const end=boost::get_system_time();
+ BOOST_CHECK(!res);
+ BOOST_CHECK((delay-timeout_resolution)<=(end-start));
+}
+
+void do_test_timed_wait_relative_times_out()
+{
+ boost::condition_variable cond;
+ boost::mutex m;
+
+ boost::posix_time::seconds const delay(timeout_seconds);
+ boost::unique_lock<boost::mutex> lock(m);
+ boost::system_time const start=boost::get_system_time();
+
+ while(cond.timed_wait(lock,delay)) {}
+
+ boost::system_time const end=boost::get_system_time();
+ BOOST_CHECK((delay-timeout_resolution)<=(end-start));
+}
+
+void do_test_cv_any_timed_wait_times_out()
+{
+ boost::condition_variable_any cond;
+ boost::mutex m;
+
+ boost::posix_time::seconds const delay(timeout_seconds);
+ boost::unique_lock<boost::mutex> lock(m);
+ boost::system_time const start=boost::get_system_time();
+ boost::system_time const timeout=start+delay;
+
+ while(cond.timed_wait(lock,timeout)) {}
+
+ boost::system_time const end=boost::get_system_time();
+ BOOST_CHECK((delay-timeout_resolution)<=(end-start));
+}
+
+void do_test_cv_any_timed_wait_with_predicate_times_out()
+{
+ boost::condition_variable_any cond;
+ boost::mutex m;
+
+ boost::posix_time::seconds const delay(timeout_seconds);
+ boost::unique_lock<boost::mutex> lock(m);
+ boost::system_time const start=boost::get_system_time();
+ boost::system_time const timeout=start+delay;
+
+ bool const res=cond.timed_wait(lock,timeout,fake_predicate);
+
+ boost::system_time const end=boost::get_system_time();
+ BOOST_CHECK(!res);
+ BOOST_CHECK((delay-timeout_resolution)<=(end-start));
+}
+
+void do_test_cv_any_relative_timed_wait_with_predicate_times_out()
+{
+ boost::condition_variable_any cond;
+ boost::mutex m;
+
+ boost::posix_time::seconds const delay(timeout_seconds);
+ boost::unique_lock<boost::mutex> lock(m);
+ boost::system_time const start=boost::get_system_time();
+
+ bool const res=cond.timed_wait(lock,delay,fake_predicate);
+
+ boost::system_time const end=boost::get_system_time();
+ BOOST_CHECK(!res);
+ BOOST_CHECK((delay-timeout_resolution)<=(end-start));
+}
+
+void do_test_cv_any_timed_wait_relative_times_out()
+{
+ boost::condition_variable_any cond;
+ boost::mutex m;
+
+ boost::posix_time::seconds const delay(timeout_seconds);
+ boost::unique_lock<boost::mutex> lock(m);
+ boost::system_time const start=boost::get_system_time();
+
+ while(cond.timed_wait(lock,delay)) {}
+
+ boost::system_time const end=boost::get_system_time();
+ BOOST_CHECK((delay-timeout_resolution)<=(end-start));
+}
+
+
+BOOST_AUTO_TEST_CASE(test_timed_wait_times_out)
+{
+ timed_test(&do_test_timed_wait_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex);
+ timed_test(&do_test_timed_wait_with_predicate_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex);
+ timed_test(&do_test_relative_timed_wait_with_predicate_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex);
+ timed_test(&do_test_timed_wait_relative_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex);
+ timed_test(&do_test_cv_any_timed_wait_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex);
+ timed_test(&do_test_cv_any_timed_wait_with_predicate_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex);
+ timed_test(&do_test_cv_any_relative_timed_wait_with_predicate_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex);
+ timed_test(&do_test_cv_any_timed_wait_relative_times_out, timeout_seconds+timeout_grace, execution_monitor::use_mutex);
+}
+
+
diff --git a/src/boost/libs/thread/test/test_futures.cpp b/src/boost/libs/thread/test/test_futures.cpp
new file mode 100644
index 000000000..61515169d
--- /dev/null
+++ b/src/boost/libs/thread/test/test_futures.cpp
@@ -0,0 +1,1236 @@
+// (C) Copyright 2008-10 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+#define BOOST_TEST_MODULE Boost.Threads: futures test suite
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/future.hpp>
+#include <utility>
+#include <memory>
+#include <string>
+#include <iostream>
+#include <boost/thread/detail/log.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+#ifdef BOOST_MSVC
+# pragma warning(disable: 4267) // conversion from ... to ..., possible loss of data
+#endif
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ template<typename T>
+ typename boost::remove_reference<T>::type&& cast_to_rval(T&& t)
+ {
+ return static_cast<typename boost::remove_reference<T>::type&&>(t);
+ }
+#else
+#if defined BOOST_THREAD_USES_MOVE
+ template<typename T>
+ boost::rv<T>& cast_to_rval(T& t)
+ {
+ return boost::move(t);
+ }
+#else
+ template<typename T>
+ boost::detail::thread_move_t<T> cast_to_rval(T& t)
+ {
+ return boost::move(t);
+ }
+#endif
+#endif
+
+struct X
+{
+public:
+ int i;
+
+ BOOST_THREAD_MOVABLE_ONLY(X)
+ X():
+ i(42)
+ {}
+ X(BOOST_THREAD_RV_REF(X) other):
+ i(BOOST_THREAD_RV(other).i)
+ {
+ BOOST_THREAD_RV(other).i=0;
+ }
+ X& operator=(BOOST_THREAD_RV_REF(X) other)
+ {
+ i=BOOST_THREAD_RV(other).i;
+ BOOST_THREAD_RV(other).i=0;
+ return *this;
+ }
+ ~X()
+ {}
+};
+namespace boost {
+ BOOST_THREAD_DCL_MOVABLE(X)
+}
+
+int make_int()
+{
+ return 42;
+}
+
+int throw_runtime_error()
+{
+ throw std::runtime_error("42");
+}
+
+void set_promise_thread(boost::promise<int>* p)
+{
+ p->set_value(42);
+}
+
+struct my_exception
+{};
+
+void set_promise_exception_thread(boost::promise<int>* p)
+{
+ p->set_exception(boost::copy_exception(my_exception()));
+}
+
+
+BOOST_AUTO_TEST_CASE(test_store_value_from_thread)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ try {
+ boost::promise<int> pi2;
+ BOOST_DETAIL_THREAD_LOG;
+ boost::unique_future<int> fi2(BOOST_THREAD_MAKE_RV_REF(pi2.get_future()));
+ BOOST_DETAIL_THREAD_LOG;
+ boost::thread(set_promise_thread,&pi2);
+ BOOST_DETAIL_THREAD_LOG;
+ int j=fi2.get();
+ BOOST_DETAIL_THREAD_LOG;
+ BOOST_CHECK(j==42);
+ BOOST_DETAIL_THREAD_LOG;
+ BOOST_CHECK(fi2.is_ready());
+ BOOST_DETAIL_THREAD_LOG;
+ BOOST_CHECK(fi2.has_value());
+ BOOST_DETAIL_THREAD_LOG;
+ BOOST_CHECK(!fi2.has_exception());
+ BOOST_DETAIL_THREAD_LOG;
+ BOOST_CHECK(fi2.get_state()==boost::future_state::ready);
+ BOOST_DETAIL_THREAD_LOG;
+ }
+ catch (...)
+ {
+ BOOST_CHECK(false&&"Exception thrown");
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_store_exception)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::promise<int> pi3;
+ boost::unique_future<int> fi3(BOOST_THREAD_MAKE_RV_REF(pi3.get_future()));
+ boost::thread(set_promise_exception_thread,&pi3);
+ try
+ {
+ fi3.get();
+ BOOST_CHECK(false);
+ }
+ catch(my_exception)
+ {
+ BOOST_CHECK(true);
+ }
+
+ BOOST_CHECK(fi3.is_ready());
+ BOOST_CHECK(!fi3.has_value());
+ BOOST_CHECK(fi3.has_exception());
+ BOOST_CHECK(fi3.get_state()==boost::future_state::ready);
+}
+
+BOOST_AUTO_TEST_CASE(test_initial_state)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::unique_future<int> fi;
+ BOOST_CHECK(!fi.is_ready());
+ BOOST_CHECK(!fi.has_value());
+ BOOST_CHECK(!fi.has_exception());
+ BOOST_CHECK(fi.get_state()==boost::future_state::uninitialized);
+ int i;
+ try
+ {
+ i=fi.get();
+ (void)i;
+ BOOST_CHECK(false);
+ }
+ catch(boost::future_uninitialized)
+ {
+ BOOST_CHECK(true);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_waiting_future)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::promise<int> pi;
+ boost::unique_future<int> fi;
+ fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
+
+ int i=0;
+ BOOST_CHECK(!fi.is_ready());
+ BOOST_CHECK(!fi.has_value());
+ BOOST_CHECK(!fi.has_exception());
+ BOOST_CHECK(fi.get_state()==boost::future_state::waiting);
+ BOOST_CHECK(i==0);
+}
+
+BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::promise<int> pi;
+ BOOST_THREAD_MAKE_RV_REF(pi.get_future());
+
+ try
+ {
+ pi.get_future();
+ BOOST_CHECK(false);
+ }
+ catch(boost::future_already_retrieved&)
+ {
+ BOOST_CHECK(true);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_set_value_updates_future_state)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::promise<int> pi;
+ boost::unique_future<int> fi;
+ fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
+
+ pi.set_value(42);
+
+ BOOST_CHECK(fi.is_ready());
+ BOOST_CHECK(fi.has_value());
+ BOOST_CHECK(!fi.has_exception());
+ BOOST_CHECK(fi.get_state()==boost::future_state::ready);
+}
+
+BOOST_AUTO_TEST_CASE(test_set_value_can_be_retrieved)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::promise<int> pi;
+ boost::unique_future<int> fi;
+ fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
+
+ pi.set_value(42);
+
+ int i=0;
+ BOOST_CHECK(i=fi.get());
+ BOOST_CHECK(i==42);
+ BOOST_CHECK(fi.is_ready());
+ BOOST_CHECK(fi.has_value());
+ BOOST_CHECK(!fi.has_exception());
+ BOOST_CHECK(fi.get_state()==boost::future_state::ready);
+}
+
+BOOST_AUTO_TEST_CASE(test_set_value_can_be_moved)
+{
+ BOOST_DETAIL_THREAD_LOG;
+// boost::promise<int> pi;
+// boost::unique_future<int> fi;
+// fi=BOOST_THREAD_MAKE_RV_REF(pi.get_future());
+
+// pi.set_value(42);
+
+// int i=0;
+// BOOST_CHECK(i=fi.get());
+// BOOST_CHECK(i==42);
+// BOOST_CHECK(fi.is_ready());
+// BOOST_CHECK(fi.has_value());
+// BOOST_CHECK(!fi.has_exception());
+// BOOST_CHECK(fi.get_state()==boost::future_state::ready);
+}
+
+BOOST_AUTO_TEST_CASE(test_future_from_packaged_task_is_waiting)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int);
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+ int i=0;
+ BOOST_CHECK(!fi.is_ready());
+ BOOST_CHECK(!fi.has_value());
+ BOOST_CHECK(!fi.has_exception());
+ BOOST_CHECK(fi.get_state()==boost::future_state::waiting);
+ BOOST_CHECK(i==0);
+}
+
+BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_populates_future)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int);
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+
+ pt();
+
+ int i=0;
+ BOOST_CHECK(fi.is_ready());
+ BOOST_CHECK(fi.has_value());
+ BOOST_CHECK(!fi.has_exception());
+ BOOST_CHECK(fi.get_state()==boost::future_state::ready);
+ BOOST_CHECK(i=fi.get());
+ BOOST_CHECK(i==42);
+}
+
+BOOST_AUTO_TEST_CASE(test_invoking_a_packaged_task_twice_throws)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int);
+
+ pt();
+ try
+ {
+ pt();
+ BOOST_CHECK(false);
+ }
+ catch(boost::task_already_started)
+ {
+ BOOST_CHECK(true);
+ }
+}
+
+
+BOOST_AUTO_TEST_CASE(test_cannot_get_future_twice_from_task)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int);
+ pt.get_future();
+ try
+ {
+ pt.get_future();
+ BOOST_CHECK(false);
+ }
+ catch(boost::future_already_retrieved)
+ {
+ BOOST_CHECK(true);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_task_stores_exception_if_function_throws)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(throw_runtime_error);
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+
+ pt();
+
+ BOOST_CHECK(fi.is_ready());
+ BOOST_CHECK(!fi.has_value());
+ BOOST_CHECK(fi.has_exception());
+ BOOST_CHECK(fi.get_state()==boost::future_state::ready);
+ try
+ {
+ fi.get();
+ BOOST_CHECK(false);
+ }
+ catch(std::exception&)
+ {
+ BOOST_CHECK(true);
+ }
+ catch(...)
+ {
+ BOOST_CHECK(!"Unknown exception thrown");
+ }
+
+}
+
+BOOST_AUTO_TEST_CASE(test_void_promise)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::promise<void> p;
+ boost::unique_future<void> f(BOOST_THREAD_MAKE_RV_REF(p.get_future()));
+ p.set_value();
+ BOOST_CHECK(f.is_ready());
+ BOOST_CHECK(f.has_value());
+ BOOST_CHECK(!f.has_exception());
+ BOOST_CHECK(f.get_state()==boost::future_state::ready);
+ f.get();
+}
+
+BOOST_AUTO_TEST_CASE(test_reference_promise)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::promise<int&> p;
+ boost::unique_future<int&> f(BOOST_THREAD_MAKE_RV_REF(p.get_future()));
+ int i=42;
+ p.set_value(i);
+ BOOST_CHECK(f.is_ready());
+ BOOST_CHECK(f.has_value());
+ BOOST_CHECK(!f.has_exception());
+ BOOST_CHECK(f.get_state()==boost::future_state::ready);
+ BOOST_CHECK(&f.get()==&i);
+}
+
+void do_nothing()
+{}
+
+BOOST_AUTO_TEST_CASE(test_task_returning_void)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<void> pt(do_nothing);
+ boost::unique_future<void> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+
+ pt();
+
+ BOOST_CHECK(fi.is_ready());
+ BOOST_CHECK(fi.has_value());
+ BOOST_CHECK(!fi.has_exception());
+ BOOST_CHECK(fi.get_state()==boost::future_state::ready);
+}
+
+int global_ref_target=0;
+
+int& return_ref()
+{
+ return global_ref_target;
+}
+
+BOOST_AUTO_TEST_CASE(test_task_returning_reference)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int&> pt(return_ref);
+ boost::unique_future<int&> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+
+ pt();
+
+ BOOST_CHECK(fi.is_ready());
+ BOOST_CHECK(fi.has_value());
+ BOOST_CHECK(!fi.has_exception());
+ BOOST_CHECK(fi.get_state()==boost::future_state::ready);
+ int& i=fi.get();
+ BOOST_CHECK(&i==&global_ref_target);
+}
+
+BOOST_AUTO_TEST_CASE(test_shared_future)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int);
+ boost::unique_future<int> fi=pt.get_future();
+
+ boost::shared_future<int> sf(::cast_to_rval(fi));
+ BOOST_CHECK(fi.get_state()==boost::future_state::uninitialized);
+
+ pt();
+
+ int i=0;
+ BOOST_CHECK(sf.is_ready());
+ BOOST_CHECK(sf.has_value());
+ BOOST_CHECK(!sf.has_exception());
+ BOOST_CHECK(sf.get_state()==boost::future_state::ready);
+ BOOST_CHECK(i=sf.get());
+ BOOST_CHECK(i==42);
+}
+
+BOOST_AUTO_TEST_CASE(test_copies_of_shared_future_become_ready_together)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int);
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+
+ boost::shared_future<int> sf(::cast_to_rval(fi));
+ boost::shared_future<int> sf2(sf);
+ boost::shared_future<int> sf3;
+ sf3=sf;
+ BOOST_CHECK(sf.get_state()==boost::future_state::waiting);
+ BOOST_CHECK(sf2.get_state()==boost::future_state::waiting);
+ BOOST_CHECK(sf3.get_state()==boost::future_state::waiting);
+
+ pt();
+
+ int i=0;
+ BOOST_CHECK(sf.is_ready());
+ BOOST_CHECK(sf.has_value());
+ BOOST_CHECK(!sf.has_exception());
+ BOOST_CHECK(sf.get_state()==boost::future_state::ready);
+ BOOST_CHECK(i=sf.get());
+ BOOST_CHECK(i==42);
+ i=0;
+ BOOST_CHECK(sf2.is_ready());
+ BOOST_CHECK(sf2.has_value());
+ BOOST_CHECK(!sf2.has_exception());
+ BOOST_CHECK(sf2.get_state()==boost::future_state::ready);
+ BOOST_CHECK(i=sf2.get());
+ BOOST_CHECK(i==42);
+ i=0;
+ BOOST_CHECK(sf3.is_ready());
+ BOOST_CHECK(sf3.has_value());
+ BOOST_CHECK(!sf3.has_exception());
+ BOOST_CHECK(sf3.get_state()==boost::future_state::ready);
+ BOOST_CHECK(i=sf3.get());
+ BOOST_CHECK(i==42);
+}
+
+BOOST_AUTO_TEST_CASE(test_shared_future_can_be_move_assigned_from_unique_future)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int);
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+
+ boost::shared_future<int> sf;
+ sf=::cast_to_rval(fi);
+ BOOST_CHECK(fi.get_state()==boost::future_state::uninitialized);
+
+ BOOST_CHECK(!sf.is_ready());
+ BOOST_CHECK(!sf.has_value());
+ BOOST_CHECK(!sf.has_exception());
+ BOOST_CHECK(sf.get_state()==boost::future_state::waiting);
+}
+
+BOOST_AUTO_TEST_CASE(test_shared_future_void)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<void> pt(do_nothing);
+ boost::unique_future<void> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+
+ boost::shared_future<void> sf(::cast_to_rval(fi));
+ BOOST_CHECK(fi.get_state()==boost::future_state::uninitialized);
+
+ pt();
+
+ BOOST_CHECK(sf.is_ready());
+ BOOST_CHECK(sf.has_value());
+ BOOST_CHECK(!sf.has_exception());
+ BOOST_CHECK(sf.get_state()==boost::future_state::ready);
+ sf.get();
+}
+
+BOOST_AUTO_TEST_CASE(test_shared_future_ref)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::promise<int&> p;
+ boost::shared_future<int&> f(BOOST_THREAD_MAKE_RV_REF(p.get_future()));
+ int i=42;
+ p.set_value(i);
+ BOOST_CHECK(f.is_ready());
+ BOOST_CHECK(f.has_value());
+ BOOST_CHECK(!f.has_exception());
+ BOOST_CHECK(f.get_state()==boost::future_state::ready);
+ BOOST_CHECK(&f.get()==&i);
+}
+
+BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_promise)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::promise<int> pi;
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
+
+ boost::promise<int> pi2(::cast_to_rval(pi));
+ boost::unique_future<int> fi2(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
+
+ pi2.set_value(3);
+ BOOST_CHECK(fi.is_ready());
+ BOOST_CHECK(!fi2.is_ready());
+ BOOST_CHECK(fi.get()==3);
+ pi.set_value(42);
+ BOOST_CHECK(fi2.is_ready());
+ BOOST_CHECK(fi2.get()==42);
+}
+
+BOOST_AUTO_TEST_CASE(test_can_get_a_second_future_from_a_moved_void_promise)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::promise<void> pi;
+ boost::unique_future<void> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
+
+ boost::promise<void> pi2(::cast_to_rval(pi));
+ boost::unique_future<void> fi2(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
+
+ pi2.set_value();
+ BOOST_CHECK(fi.is_ready());
+ BOOST_CHECK(!fi2.is_ready());
+ pi.set_value();
+ BOOST_CHECK(fi2.is_ready());
+}
+
+BOOST_AUTO_TEST_CASE(test_unique_future_for_move_only_udt)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::promise<X> pt;
+ boost::unique_future<X> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+
+ pt.set_value(X());
+ X res(fi.get());
+ BOOST_CHECK(res.i==42);
+}
+
+BOOST_AUTO_TEST_CASE(test_unique_future_for_string)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::promise<std::string> pt;
+ boost::unique_future<std::string> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+
+ pt.set_value(std::string("hello"));
+ std::string res(fi.get());
+ BOOST_CHECK(res=="hello");
+
+ boost::promise<std::string> pt2;
+ fi=BOOST_THREAD_MAKE_RV_REF(pt2.get_future());
+
+ std::string const s="goodbye";
+
+ pt2.set_value(s);
+ res=fi.get();
+ BOOST_CHECK(res=="goodbye");
+
+ boost::promise<std::string> pt3;
+ fi=BOOST_THREAD_MAKE_RV_REF(pt3.get_future());
+
+ std::string s2="foo";
+
+ pt3.set_value(s2);
+ res=fi.get();
+ BOOST_CHECK(res=="foo");
+}
+
+boost::mutex callback_mutex;
+unsigned callback_called=0;
+
+void wait_callback(boost::promise<int>& pi)
+{
+ boost::lock_guard<boost::mutex> lk(callback_mutex);
+ ++callback_called;
+ try
+ {
+ pi.set_value(42);
+ }
+ catch(...)
+ {
+ }
+}
+
+void do_nothing_callback(boost::promise<int>& /*pi*/)
+{
+ boost::lock_guard<boost::mutex> lk(callback_mutex);
+ ++callback_called;
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_callback)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ callback_called=0;
+ boost::promise<int> pi;
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
+ pi.set_wait_callback(wait_callback);
+ fi.wait();
+ BOOST_CHECK(callback_called);
+ BOOST_CHECK(fi.get()==42);
+ fi.wait();
+ fi.wait();
+ BOOST_CHECK(callback_called==1);
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_callback_with_timed_wait)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ callback_called=0;
+ boost::promise<int> pi;
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pi.get_future()));
+ pi.set_wait_callback(do_nothing_callback);
+ bool success=fi.timed_wait(boost::posix_time::milliseconds(10));
+ BOOST_CHECK(callback_called);
+ BOOST_CHECK(!success);
+ success=fi.timed_wait(boost::posix_time::milliseconds(10));
+ BOOST_CHECK(!success);
+ success=fi.timed_wait(boost::posix_time::milliseconds(10));
+ BOOST_CHECK(!success);
+ BOOST_CHECK(callback_called==3);
+ pi.set_value(42);
+ success=fi.timed_wait(boost::posix_time::milliseconds(10));
+ BOOST_CHECK(success);
+ BOOST_CHECK(callback_called==3);
+ BOOST_CHECK(fi.get()==42);
+ BOOST_CHECK(callback_called==3);
+}
+
+
+void wait_callback_for_task(boost::packaged_task<int>& pt)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::lock_guard<boost::mutex> lk(callback_mutex);
+ ++callback_called;
+ try
+ {
+ pt();
+ }
+ catch(...)
+ {
+ }
+}
+
+
+BOOST_AUTO_TEST_CASE(test_wait_callback_for_packaged_task)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ callback_called=0;
+ boost::packaged_task<int> pt(make_int);
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+ pt.set_wait_callback(wait_callback_for_task);
+ fi.wait();
+ BOOST_CHECK(callback_called);
+ BOOST_CHECK(fi.get()==42);
+ fi.wait();
+ fi.wait();
+ BOOST_CHECK(callback_called==1);
+}
+
+BOOST_AUTO_TEST_CASE(test_packaged_task_can_be_moved)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int);
+
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+
+ BOOST_CHECK(!fi.is_ready());
+
+ boost::packaged_task<int> pt2(::cast_to_rval(pt));
+
+ BOOST_CHECK(!fi.is_ready());
+ try
+ {
+ pt();
+ BOOST_CHECK(!"Can invoke moved task!");
+ }
+ catch(boost::task_moved&)
+ {
+ }
+
+ BOOST_CHECK(!fi.is_ready());
+
+ pt2();
+
+ BOOST_CHECK(fi.is_ready());
+}
+
+BOOST_AUTO_TEST_CASE(test_destroying_a_promise_stores_broken_promise)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::unique_future<int> f;
+
+ {
+ boost::promise<int> p;
+ f=BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ }
+ BOOST_CHECK(f.is_ready());
+ BOOST_CHECK(f.has_exception());
+ try
+ {
+ f.get();
+ }
+ catch(boost::broken_promise&)
+ {
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_destroying_a_packaged_task_stores_broken_promise)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::unique_future<int> f;
+
+ {
+ boost::packaged_task<int> p(make_int);
+ f=BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ }
+ BOOST_CHECK(f.is_ready());
+ BOOST_CHECK(f.has_exception());
+ try
+ {
+ f.get();
+ }
+ catch(boost::broken_promise&)
+ {
+ }
+}
+
+int make_int_slowly()
+{
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ return 42;
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_1)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int_slowly);
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+ boost::packaged_task<int> pt2(make_int_slowly);
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
+
+ boost::thread(::cast_to_rval(pt));
+
+ unsigned const future=boost::wait_for_any(f1,f2);
+
+ BOOST_CHECK(future==0);
+ BOOST_CHECK(f1.is_ready());
+ BOOST_CHECK(!f2.is_ready());
+ BOOST_CHECK(f1.get()==42);
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_for_either_of_two_futures_2)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int_slowly);
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+ boost::packaged_task<int> pt2(make_int_slowly);
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
+
+ boost::thread(::cast_to_rval(pt2));
+
+ unsigned const future=boost::wait_for_any(f1,f2);
+
+ BOOST_CHECK(future==1);
+ BOOST_CHECK(!f1.is_ready());
+ BOOST_CHECK(f2.is_ready());
+ BOOST_CHECK(f2.get()==42);
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_1)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int_slowly);
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+ boost::packaged_task<int> pt2(make_int_slowly);
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
+ boost::packaged_task<int> pt3(make_int_slowly);
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
+
+ boost::thread(::cast_to_rval(pt));
+
+ unsigned const future=boost::wait_for_any(f1,f2,f3);
+
+ BOOST_CHECK(future==0);
+ BOOST_CHECK(f1.is_ready());
+ BOOST_CHECK(!f2.is_ready());
+ BOOST_CHECK(!f3.is_ready());
+ BOOST_CHECK(f1.get()==42);
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_2)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int_slowly);
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+ boost::packaged_task<int> pt2(make_int_slowly);
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
+ boost::packaged_task<int> pt3(make_int_slowly);
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
+
+ boost::thread(::cast_to_rval(pt2));
+
+ unsigned const future=boost::wait_for_any(f1,f2,f3);
+
+ BOOST_CHECK(future==1);
+ BOOST_CHECK(!f1.is_ready());
+ BOOST_CHECK(f2.is_ready());
+ BOOST_CHECK(!f3.is_ready());
+ BOOST_CHECK(f2.get()==42);
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_for_either_of_three_futures_3)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int_slowly);
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+ boost::packaged_task<int> pt2(make_int_slowly);
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
+ boost::packaged_task<int> pt3(make_int_slowly);
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
+
+ boost::thread(::cast_to_rval(pt3));
+
+ unsigned const future=boost::wait_for_any(f1,f2,f3);
+
+ BOOST_CHECK(future==2);
+ BOOST_CHECK(!f1.is_ready());
+ BOOST_CHECK(!f2.is_ready());
+ BOOST_CHECK(f3.is_ready());
+ BOOST_CHECK(f3.get()==42);
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_1)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int_slowly);
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+ boost::packaged_task<int> pt2(make_int_slowly);
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
+ boost::packaged_task<int> pt3(make_int_slowly);
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
+ boost::packaged_task<int> pt4(make_int_slowly);
+ boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
+
+ boost::thread(::cast_to_rval(pt));
+
+ unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
+
+ BOOST_CHECK(future==0);
+ BOOST_CHECK(f1.is_ready());
+ BOOST_CHECK(!f2.is_ready());
+ BOOST_CHECK(!f3.is_ready());
+ BOOST_CHECK(!f4.is_ready());
+ BOOST_CHECK(f1.get()==42);
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_2)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int_slowly);
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+ boost::packaged_task<int> pt2(make_int_slowly);
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
+ boost::packaged_task<int> pt3(make_int_slowly);
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
+ boost::packaged_task<int> pt4(make_int_slowly);
+ boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
+
+ boost::thread(::cast_to_rval(pt2));
+
+ unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
+
+ BOOST_CHECK(future==1);
+ BOOST_CHECK(!f1.is_ready());
+ BOOST_CHECK(f2.is_ready());
+ BOOST_CHECK(!f3.is_ready());
+ BOOST_CHECK(!f4.is_ready());
+ BOOST_CHECK(f2.get()==42);
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_3)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int_slowly);
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+ boost::packaged_task<int> pt2(make_int_slowly);
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
+ boost::packaged_task<int> pt3(make_int_slowly);
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
+ boost::packaged_task<int> pt4(make_int_slowly);
+ boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
+
+ boost::thread(::cast_to_rval(pt3));
+
+ unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
+
+ BOOST_CHECK(future==2);
+ BOOST_CHECK(!f1.is_ready());
+ BOOST_CHECK(!f2.is_ready());
+ BOOST_CHECK(f3.is_ready());
+ BOOST_CHECK(!f4.is_ready());
+ BOOST_CHECK(f3.get()==42);
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_for_either_of_four_futures_4)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int_slowly);
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+ boost::packaged_task<int> pt2(make_int_slowly);
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
+ boost::packaged_task<int> pt3(make_int_slowly);
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
+ boost::packaged_task<int> pt4(make_int_slowly);
+ boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
+
+ boost::thread(::cast_to_rval(pt4));
+
+ unsigned const future=boost::wait_for_any(f1,f2,f3,f4);
+
+ BOOST_CHECK(future==3);
+ BOOST_CHECK(!f1.is_ready());
+ BOOST_CHECK(!f2.is_ready());
+ BOOST_CHECK(!f3.is_ready());
+ BOOST_CHECK(f4.is_ready());
+ BOOST_CHECK(f4.get()==42);
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_1)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int_slowly);
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+ boost::packaged_task<int> pt2(make_int_slowly);
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
+ boost::packaged_task<int> pt3(make_int_slowly);
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
+ boost::packaged_task<int> pt4(make_int_slowly);
+ boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
+ boost::packaged_task<int> pt5(make_int_slowly);
+ boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
+
+ boost::thread(::cast_to_rval(pt));
+
+ unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
+
+ BOOST_CHECK(future==0);
+ BOOST_CHECK(f1.is_ready());
+ BOOST_CHECK(!f2.is_ready());
+ BOOST_CHECK(!f3.is_ready());
+ BOOST_CHECK(!f4.is_ready());
+ BOOST_CHECK(!f5.is_ready());
+ BOOST_CHECK(f1.get()==42);
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_2)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int_slowly);
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+ boost::packaged_task<int> pt2(make_int_slowly);
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
+ boost::packaged_task<int> pt3(make_int_slowly);
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
+ boost::packaged_task<int> pt4(make_int_slowly);
+ boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
+ boost::packaged_task<int> pt5(make_int_slowly);
+ boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
+
+ boost::thread(::cast_to_rval(pt2));
+
+ unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
+
+ BOOST_CHECK(future==1);
+ BOOST_CHECK(!f1.is_ready());
+ BOOST_CHECK(f2.is_ready());
+ BOOST_CHECK(!f3.is_ready());
+ BOOST_CHECK(!f4.is_ready());
+ BOOST_CHECK(!f5.is_ready());
+ BOOST_CHECK(f2.get()==42);
+}
+BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_3)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int_slowly);
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+ boost::packaged_task<int> pt2(make_int_slowly);
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
+ boost::packaged_task<int> pt3(make_int_slowly);
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
+ boost::packaged_task<int> pt4(make_int_slowly);
+ boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
+ boost::packaged_task<int> pt5(make_int_slowly);
+ boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
+
+ boost::thread(::cast_to_rval(pt3));
+
+ unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
+
+ BOOST_CHECK(future==2);
+ BOOST_CHECK(!f1.is_ready());
+ BOOST_CHECK(!f2.is_ready());
+ BOOST_CHECK(f3.is_ready());
+ BOOST_CHECK(!f4.is_ready());
+ BOOST_CHECK(!f5.is_ready());
+ BOOST_CHECK(f3.get()==42);
+}
+BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_4)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int_slowly);
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+ boost::packaged_task<int> pt2(make_int_slowly);
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
+ boost::packaged_task<int> pt3(make_int_slowly);
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
+ boost::packaged_task<int> pt4(make_int_slowly);
+ boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
+ boost::packaged_task<int> pt5(make_int_slowly);
+ boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
+
+ boost::thread(::cast_to_rval(pt4));
+
+ unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
+
+ BOOST_CHECK(future==3);
+ BOOST_CHECK(!f1.is_ready());
+ BOOST_CHECK(!f2.is_ready());
+ BOOST_CHECK(!f3.is_ready());
+ BOOST_CHECK(f4.is_ready());
+ BOOST_CHECK(!f5.is_ready());
+ BOOST_CHECK(f4.get()==42);
+}
+BOOST_AUTO_TEST_CASE(test_wait_for_either_of_five_futures_5)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ boost::packaged_task<int> pt(make_int_slowly);
+ boost::unique_future<int> f1(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+ boost::packaged_task<int> pt2(make_int_slowly);
+ boost::unique_future<int> f2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
+ boost::packaged_task<int> pt3(make_int_slowly);
+ boost::unique_future<int> f3(BOOST_THREAD_MAKE_RV_REF(pt3.get_future()));
+ boost::packaged_task<int> pt4(make_int_slowly);
+ boost::unique_future<int> f4(BOOST_THREAD_MAKE_RV_REF(pt4.get_future()));
+ boost::packaged_task<int> pt5(make_int_slowly);
+ boost::unique_future<int> f5(BOOST_THREAD_MAKE_RV_REF(pt5.get_future()));
+
+ boost::thread(::cast_to_rval(pt5));
+
+ unsigned const future=boost::wait_for_any(f1,f2,f3,f4,f5);
+
+ BOOST_CHECK(future==4);
+ BOOST_CHECK(!f1.is_ready());
+ BOOST_CHECK(!f2.is_ready());
+ BOOST_CHECK(!f3.is_ready());
+ BOOST_CHECK(!f4.is_ready());
+ BOOST_CHECK(f5.is_ready());
+ BOOST_CHECK(f5.get()==42);
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_for_either_invokes_callbacks)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ callback_called=0;
+ boost::packaged_task<int> pt(make_int_slowly);
+ boost::unique_future<int> fi(BOOST_THREAD_MAKE_RV_REF(pt.get_future()));
+ boost::packaged_task<int> pt2(make_int_slowly);
+ boost::unique_future<int> fi2(BOOST_THREAD_MAKE_RV_REF(pt2.get_future()));
+ pt.set_wait_callback(wait_callback_for_task);
+
+ boost::thread(::cast_to_rval(pt));
+
+ boost::wait_for_any(fi,fi2);
+ BOOST_CHECK(callback_called==1);
+ BOOST_CHECK(fi.get()==42);
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_for_any_from_range)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ unsigned const count=10;
+ for(unsigned i=0;i<count;++i)
+ {
+ boost::packaged_task<int> tasks[count];
+ boost::unique_future<int> futures[count];
+ for(unsigned j=0;j<count;++j)
+ {
+ tasks[j]=boost::packaged_task<int>(make_int_slowly);
+ futures[j]=BOOST_THREAD_MAKE_RV_REF(tasks[j].get_future());
+ }
+ boost::thread(::cast_to_rval(tasks[i]));
+
+ BOOST_CHECK(boost::wait_for_any(futures,futures)==futures);
+
+ boost::unique_future<int>* const future=boost::wait_for_any(futures,futures+count);
+
+ BOOST_CHECK(future==(futures+i));
+ for(unsigned j=0;j<count;++j)
+ {
+ if(j!=i)
+ {
+ BOOST_CHECK(!futures[j].is_ready());
+ }
+ else
+ {
+ BOOST_CHECK(futures[j].is_ready());
+ }
+ }
+ BOOST_CHECK(futures[i].get()==42);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_for_all_from_range)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ unsigned const count=10;
+ boost::unique_future<int> futures[count];
+ for(unsigned j=0;j<count;++j)
+ {
+ boost::packaged_task<int> task(make_int_slowly);
+ futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
+ boost::thread(::cast_to_rval(task));
+ }
+
+ boost::wait_for_all(futures,futures+count);
+
+ for(unsigned j=0;j<count;++j)
+ {
+ BOOST_CHECK(futures[j].is_ready());
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_for_all_two_futures)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ unsigned const count=2;
+ boost::unique_future<int> futures[count];
+ for(unsigned j=0;j<count;++j)
+ {
+ boost::packaged_task<int> task(make_int_slowly);
+ futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
+ boost::thread(::cast_to_rval(task));
+ }
+
+ boost::wait_for_all(futures[0],futures[1]);
+
+ for(unsigned j=0;j<count;++j)
+ {
+ BOOST_CHECK(futures[j].is_ready());
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_for_all_three_futures)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ unsigned const count=3;
+ boost::unique_future<int> futures[count];
+ for(unsigned j=0;j<count;++j)
+ {
+ boost::packaged_task<int> task(make_int_slowly);
+ futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
+ boost::thread(::cast_to_rval(task));
+ }
+
+ boost::wait_for_all(futures[0],futures[1],futures[2]);
+
+ for(unsigned j=0;j<count;++j)
+ {
+ BOOST_CHECK(futures[j].is_ready());
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_for_all_four_futures)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ unsigned const count=4;
+ boost::unique_future<int> futures[count];
+ for(unsigned j=0;j<count;++j)
+ {
+ boost::packaged_task<int> task(make_int_slowly);
+ futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
+ boost::thread(::cast_to_rval(task));
+ }
+
+ boost::wait_for_all(futures[0],futures[1],futures[2],futures[3]);
+
+ for(unsigned j=0;j<count;++j)
+ {
+ BOOST_CHECK(futures[j].is_ready());
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_wait_for_all_five_futures)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ unsigned const count=5;
+ boost::unique_future<int> futures[count];
+ for(unsigned j=0;j<count;++j)
+ {
+ boost::packaged_task<int> task(make_int_slowly);
+ futures[j]=BOOST_THREAD_MAKE_RV_REF(task.get_future());
+ boost::thread(::cast_to_rval(task));
+ }
+
+ boost::wait_for_all(futures[0],futures[1],futures[2],futures[3],futures[4]);
+
+ for(unsigned j=0;j<count;++j)
+ {
+ BOOST_CHECK(futures[j].is_ready());
+ }
+}
diff --git a/src/boost/libs/thread/test/test_generic_locks.cpp b/src/boost/libs/thread/test/test_generic_locks.cpp
new file mode 100644
index 000000000..0a9befcf9
--- /dev/null
+++ b/src/boost/libs/thread/test/test_generic_locks.cpp
@@ -0,0 +1,578 @@
+// (C) Copyright 2008 Anthony Williams
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+
+#define BOOST_TEST_MODULE Boost.Threads: generic locks test suite
+
+#include <boost/test/unit_test.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <iterator>
+#include <cstddef>
+
+BOOST_AUTO_TEST_CASE(test_lock_two_uncontended)
+{
+ boost::mutex m1,m2;
+
+ boost::unique_lock<boost::mutex> l1(m1,boost::defer_lock),
+ l2(m2,boost::defer_lock);
+
+ BOOST_CHECK(!l1.owns_lock());
+ BOOST_CHECK(!l2.owns_lock());
+
+ boost::lock(l1,l2);
+
+ BOOST_CHECK(l1.owns_lock());
+ BOOST_CHECK(l2.owns_lock());
+}
+
+struct wait_data
+{
+ boost::mutex m;
+ bool flag;
+ boost::condition_variable cond;
+
+ wait_data():
+ flag(false)
+ {}
+
+ void wait()
+ {
+ boost::unique_lock<boost::mutex> l(m);
+ while(!flag)
+ {
+ cond.wait(l);
+ }
+ }
+
+ template<typename Duration>
+ bool timed_wait(Duration d)
+ {
+ boost::system_time const target=boost::get_system_time()+d;
+
+ boost::unique_lock<boost::mutex> l(m);
+ while(!flag)
+ {
+ if(!cond.timed_wait(l,target))
+ {
+ return flag;
+ }
+ }
+ return true;
+ }
+
+ void signal()
+ {
+ boost::unique_lock<boost::mutex> l(m);
+ flag=true;
+ cond.notify_all();
+ }
+};
+
+
+void lock_mutexes_slowly(boost::mutex* m1,boost::mutex* m2,wait_data* locked,wait_data* quit)
+{
+ boost::lock_guard<boost::mutex> l1(*m1);
+ boost::this_thread::sleep(boost::posix_time::milliseconds(500));
+ boost::lock_guard<boost::mutex> l2(*m2);
+ locked->signal();
+ quit->wait();
+}
+
+void lock_pair(boost::mutex* m1,boost::mutex* m2)
+{
+ boost::lock(*m1,*m2);
+ boost::unique_lock<boost::mutex> l1(*m1,boost::adopt_lock),
+ l2(*m2,boost::adopt_lock);
+}
+
+BOOST_AUTO_TEST_CASE(test_lock_two_other_thread_locks_in_order)
+{
+ boost::mutex m1,m2;
+ wait_data locked;
+ wait_data release;
+
+ boost::thread t(lock_mutexes_slowly,&m1,&m2,&locked,&release);
+ boost::this_thread::sleep(boost::posix_time::milliseconds(10));
+
+ boost::thread t2(lock_pair,&m1,&m2);
+ BOOST_CHECK(locked.timed_wait(boost::posix_time::seconds(1)));
+
+ release.signal();
+
+ BOOST_CHECK(t2.timed_join(boost::posix_time::seconds(1)));
+
+ t.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_lock_two_other_thread_locks_in_opposite_order)
+{
+ boost::mutex m1,m2;
+ wait_data locked;
+ wait_data release;
+
+ boost::thread t(lock_mutexes_slowly,&m1,&m2,&locked,&release);
+ boost::this_thread::sleep(boost::posix_time::milliseconds(10));
+
+ boost::thread t2(lock_pair,&m2,&m1);
+ BOOST_CHECK(locked.timed_wait(boost::posix_time::seconds(1)));
+
+ release.signal();
+
+ BOOST_CHECK(t2.timed_join(boost::posix_time::seconds(1)));
+
+ t.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_lock_five_uncontended)
+{
+ boost::mutex m1,m2,m3,m4,m5;
+
+ boost::unique_lock<boost::mutex> l1(m1,boost::defer_lock),
+ l2(m2,boost::defer_lock),
+ l3(m3,boost::defer_lock),
+ l4(m4,boost::defer_lock),
+ l5(m5,boost::defer_lock);
+
+ BOOST_CHECK(!l1.owns_lock());
+ BOOST_CHECK(!l2.owns_lock());
+ BOOST_CHECK(!l3.owns_lock());
+ BOOST_CHECK(!l4.owns_lock());
+ BOOST_CHECK(!l5.owns_lock());
+
+ boost::lock(l1,l2,l3,l4,l5);
+
+ BOOST_CHECK(l1.owns_lock());
+ BOOST_CHECK(l2.owns_lock());
+ BOOST_CHECK(l3.owns_lock());
+ BOOST_CHECK(l4.owns_lock());
+ BOOST_CHECK(l5.owns_lock());
+}
+
+void lock_five_mutexes_slowly(boost::mutex* m1,boost::mutex* m2,boost::mutex* m3,boost::mutex* m4,boost::mutex* m5,
+ wait_data* locked,wait_data* quit)
+{
+ boost::lock_guard<boost::mutex> l1(*m1);
+ boost::this_thread::sleep(boost::posix_time::milliseconds(500));
+ boost::lock_guard<boost::mutex> l2(*m2);
+ boost::this_thread::sleep(boost::posix_time::milliseconds(500));
+ boost::lock_guard<boost::mutex> l3(*m3);
+ boost::this_thread::sleep(boost::posix_time::milliseconds(500));
+ boost::lock_guard<boost::mutex> l4(*m4);
+ boost::this_thread::sleep(boost::posix_time::milliseconds(500));
+ boost::lock_guard<boost::mutex> l5(*m5);
+ locked->signal();
+ quit->wait();
+}
+
+void lock_five(boost::mutex* m1,boost::mutex* m2,boost::mutex* m3,boost::mutex* m4,boost::mutex* m5)
+{
+ boost::lock(*m1,*m2,*m3,*m4,*m5);
+ m1->unlock();
+ m2->unlock();
+ m3->unlock();
+ m4->unlock();
+ m5->unlock();
+}
+
+BOOST_AUTO_TEST_CASE(test_lock_five_other_thread_locks_in_order)
+{
+ boost::mutex m1,m2,m3,m4,m5;
+ wait_data locked;
+ wait_data release;
+
+ boost::thread t(lock_five_mutexes_slowly,&m1,&m2,&m3,&m4,&m5,&locked,&release);
+ boost::this_thread::sleep(boost::posix_time::milliseconds(10));
+
+ boost::thread t2(lock_five,&m1,&m2,&m3,&m4,&m5);
+ BOOST_CHECK(locked.timed_wait(boost::posix_time::seconds(3)));
+
+ release.signal();
+
+ BOOST_CHECK(t2.timed_join(boost::posix_time::seconds(3)));
+
+ t.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_lock_five_other_thread_locks_in_different_order)
+{
+ boost::mutex m1,m2,m3,m4,m5;
+ wait_data locked;
+ wait_data release;
+
+ boost::thread t(lock_five_mutexes_slowly,&m1,&m2,&m3,&m4,&m5,&locked,&release);
+ boost::this_thread::sleep(boost::posix_time::milliseconds(10));
+
+ boost::thread t2(lock_five,&m5,&m1,&m4,&m2,&m3);
+ BOOST_CHECK(locked.timed_wait(boost::posix_time::seconds(3)));
+
+ release.signal();
+
+ BOOST_CHECK(t2.timed_join(boost::posix_time::seconds(3)));
+
+ t.join();
+}
+
+void lock_n(boost::mutex* mutexes,unsigned count)
+{
+ boost::lock(mutexes,mutexes+count);
+ for(unsigned i=0;i<count;++i)
+ {
+ mutexes[i].unlock();
+ }
+}
+
+
+BOOST_AUTO_TEST_CASE(test_lock_ten_other_thread_locks_in_different_order)
+{
+ unsigned const num_mutexes=10;
+
+ boost::mutex mutexes[num_mutexes];
+ wait_data locked;
+ wait_data release;
+
+ boost::thread t(lock_five_mutexes_slowly,&mutexes[6],&mutexes[3],&mutexes[8],&mutexes[0],&mutexes[2],&locked,&release);
+ boost::this_thread::sleep(boost::posix_time::milliseconds(10));
+
+ boost::thread t2(lock_n,mutexes,num_mutexes);
+ BOOST_CHECK(locked.timed_wait(boost::posix_time::seconds(3)));
+
+ release.signal();
+
+ BOOST_CHECK(t2.timed_join(boost::posix_time::seconds(3)));
+
+ t.join();
+}
+
+struct dummy_mutex
+{
+ bool is_locked;
+
+ dummy_mutex():
+ is_locked(false)
+ {}
+
+ void lock()
+ {
+ is_locked=true;
+ }
+
+ bool try_lock()
+ {
+ if(is_locked)
+ {
+ return false;
+ }
+ is_locked=true;
+ return true;
+ }
+
+ void unlock()
+ {
+ is_locked=false;
+ }
+};
+
+namespace boost
+{
+ template<>
+ struct is_mutex_type<dummy_mutex>
+ {
+ BOOST_STATIC_CONSTANT(bool, value = true);
+ };
+}
+
+
+
+BOOST_AUTO_TEST_CASE(test_lock_five_in_range)
+{
+ unsigned const num_mutexes=5;
+ dummy_mutex mutexes[num_mutexes];
+
+ boost::lock(mutexes,mutexes+num_mutexes);
+
+ for(unsigned i=0;i<num_mutexes;++i)
+ {
+ BOOST_CHECK(mutexes[i].is_locked);
+ }
+}
+
+class dummy_iterator
+{
+private:
+ dummy_mutex* p;
+public:
+ typedef std::forward_iterator_tag iterator_category;
+ typedef dummy_mutex value_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef dummy_mutex* pointer;
+ typedef dummy_mutex& reference;
+
+ explicit dummy_iterator(dummy_mutex* p_):
+ p(p_)
+ {}
+
+ bool operator==(dummy_iterator const& other) const
+ {
+ return p==other.p;
+ }
+
+ bool operator!=(dummy_iterator const& other) const
+ {
+ return p!=other.p;
+ }
+
+ bool operator<(dummy_iterator const& other) const
+ {
+ return p<other.p;
+ }
+
+ dummy_mutex& operator*() const
+ {
+ return *p;
+ }
+
+ dummy_mutex* operator->() const
+ {
+ return p;
+ }
+
+ dummy_iterator operator++(int)
+ {
+ dummy_iterator temp(*this);
+ ++p;
+ return temp;
+ }
+
+ dummy_iterator& operator++()
+ {
+ ++p;
+ return *this;
+ }
+
+};
+
+
+BOOST_AUTO_TEST_CASE(test_lock_five_in_range_custom_iterator)
+{
+ unsigned const num_mutexes=5;
+ dummy_mutex mutexes[num_mutexes];
+
+ boost::lock(dummy_iterator(mutexes),dummy_iterator(mutexes+num_mutexes));
+
+ for(unsigned i=0;i<num_mutexes;++i)
+ {
+ BOOST_CHECK(mutexes[i].is_locked);
+ }
+}
+
+class dummy_mutex2:
+ public dummy_mutex
+{};
+
+
+BOOST_AUTO_TEST_CASE(test_lock_ten_in_range_inherited_mutex)
+{
+ unsigned const num_mutexes=10;
+ dummy_mutex2 mutexes[num_mutexes];
+
+ boost::lock(mutexes,mutexes+num_mutexes);
+
+ for(unsigned i=0;i<num_mutexes;++i)
+ {
+ BOOST_CHECK(mutexes[i].is_locked);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_try_lock_two_uncontended)
+{
+ dummy_mutex m1,m2;
+
+ int const res=boost::try_lock(m1,m2);
+
+ BOOST_CHECK(res==-1);
+ BOOST_CHECK(m1.is_locked);
+ BOOST_CHECK(m2.is_locked);
+}
+BOOST_AUTO_TEST_CASE(test_try_lock_two_first_locked)
+{
+ dummy_mutex m1,m2;
+ m1.lock();
+
+ boost::unique_lock<dummy_mutex> l1(m1,boost::defer_lock),
+ l2(m2,boost::defer_lock);
+
+ int const res=boost::try_lock(l1,l2);
+
+ BOOST_CHECK(res==0);
+ BOOST_CHECK(m1.is_locked);
+ BOOST_CHECK(!m2.is_locked);
+ BOOST_CHECK(!l1.owns_lock());
+ BOOST_CHECK(!l2.owns_lock());
+}
+BOOST_AUTO_TEST_CASE(test_try_lock_two_second_locked)
+{
+ dummy_mutex m1,m2;
+ m2.lock();
+
+ boost::unique_lock<dummy_mutex> l1(m1,boost::defer_lock),
+ l2(m2,boost::defer_lock);
+
+ int const res=boost::try_lock(l1,l2);
+
+ BOOST_CHECK(res==1);
+ BOOST_CHECK(!m1.is_locked);
+ BOOST_CHECK(m2.is_locked);
+ BOOST_CHECK(!l1.owns_lock());
+ BOOST_CHECK(!l2.owns_lock());
+}
+
+BOOST_AUTO_TEST_CASE(test_try_lock_three)
+{
+ int const num_mutexes=3;
+
+ for(int i=-1;i<num_mutexes;++i)
+ {
+ dummy_mutex mutexes[num_mutexes];
+
+ if(i>=0)
+ {
+ mutexes[i].lock();
+ }
+ boost::unique_lock<dummy_mutex> l1(mutexes[0],boost::defer_lock),
+ l2(mutexes[1],boost::defer_lock),
+ l3(mutexes[2],boost::defer_lock);
+
+ int const res=boost::try_lock(l1,l2,l3);
+
+ BOOST_CHECK(res==i);
+ for(int j=0;j<num_mutexes;++j)
+ {
+ if((i==j) || (i==-1))
+ {
+ BOOST_CHECK(mutexes[j].is_locked);
+ }
+ else
+ {
+ BOOST_CHECK(!mutexes[j].is_locked);
+ }
+ }
+ if(i==-1)
+ {
+ BOOST_CHECK(l1.owns_lock());
+ BOOST_CHECK(l2.owns_lock());
+ BOOST_CHECK(l3.owns_lock());
+ }
+ else
+ {
+ BOOST_CHECK(!l1.owns_lock());
+ BOOST_CHECK(!l2.owns_lock());
+ BOOST_CHECK(!l3.owns_lock());
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_try_lock_four)
+{
+ int const num_mutexes=4;
+
+ for(int i=-1;i<num_mutexes;++i)
+ {
+ dummy_mutex mutexes[num_mutexes];
+
+ if(i>=0)
+ {
+ mutexes[i].lock();
+ }
+ boost::unique_lock<dummy_mutex> l1(mutexes[0],boost::defer_lock),
+ l2(mutexes[1],boost::defer_lock),
+ l3(mutexes[2],boost::defer_lock),
+ l4(mutexes[3],boost::defer_lock);
+
+ int const res=boost::try_lock(l1,l2,l3,l4);
+
+ BOOST_CHECK(res==i);
+ for(int j=0;j<num_mutexes;++j)
+ {
+ if((i==j) || (i==-1))
+ {
+ BOOST_CHECK(mutexes[j].is_locked);
+ }
+ else
+ {
+ BOOST_CHECK(!mutexes[j].is_locked);
+ }
+ }
+ if(i==-1)
+ {
+ BOOST_CHECK(l1.owns_lock());
+ BOOST_CHECK(l2.owns_lock());
+ BOOST_CHECK(l3.owns_lock());
+ BOOST_CHECK(l4.owns_lock());
+ }
+ else
+ {
+ BOOST_CHECK(!l1.owns_lock());
+ BOOST_CHECK(!l2.owns_lock());
+ BOOST_CHECK(!l3.owns_lock());
+ BOOST_CHECK(!l4.owns_lock());
+ }
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_try_lock_five)
+{
+ int const num_mutexes=5;
+
+ for(int i=-1;i<num_mutexes;++i)
+ {
+ dummy_mutex mutexes[num_mutexes];
+
+ if(i>=0)
+ {
+ mutexes[i].lock();
+ }
+ boost::unique_lock<dummy_mutex> l1(mutexes[0],boost::defer_lock),
+ l2(mutexes[1],boost::defer_lock),
+ l3(mutexes[2],boost::defer_lock),
+ l4(mutexes[3],boost::defer_lock),
+ l5(mutexes[4],boost::defer_lock);
+
+ int const res=boost::try_lock(l1,l2,l3,l4,l5);
+
+ BOOST_CHECK(res==i);
+ for(int j=0;j<num_mutexes;++j)
+ {
+ if((i==j) || (i==-1))
+ {
+ BOOST_CHECK(mutexes[j].is_locked);
+ }
+ else
+ {
+ BOOST_CHECK(!mutexes[j].is_locked);
+ }
+ }
+ if(i==-1)
+ {
+ BOOST_CHECK(l1.owns_lock());
+ BOOST_CHECK(l2.owns_lock());
+ BOOST_CHECK(l3.owns_lock());
+ BOOST_CHECK(l4.owns_lock());
+ BOOST_CHECK(l5.owns_lock());
+ }
+ else
+ {
+ BOOST_CHECK(!l1.owns_lock());
+ BOOST_CHECK(!l2.owns_lock());
+ BOOST_CHECK(!l3.owns_lock());
+ BOOST_CHECK(!l4.owns_lock());
+ BOOST_CHECK(!l5.owns_lock());
+ }
+ }
+}
+
diff --git a/src/boost/libs/thread/test/test_hardware_concurrency.cpp b/src/boost/libs/thread/test/test_hardware_concurrency.cpp
new file mode 100644
index 000000000..1d4376c27
--- /dev/null
+++ b/src/boost/libs/thread/test/test_hardware_concurrency.cpp
@@ -0,0 +1,17 @@
+// Copyright (C) 2007 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_TEST_MODULE Boost.Threads: hardware_concurrency test suite
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/thread/mutex.hpp>
+
+BOOST_AUTO_TEST_CASE(test_hardware_concurrency_is_non_zero)
+{
+ BOOST_CHECK(boost::thread::hardware_concurrency()!=0);
+}
+
+
diff --git a/src/boost/libs/thread/test/test_latch.cpp b/src/boost/libs/thread/test/test_latch.cpp
new file mode 100644
index 000000000..e2972c9b1
--- /dev/null
+++ b/src/boost/libs/thread/test/test_latch.cpp
@@ -0,0 +1,70 @@
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// (C) Copyright 2013 Vicente J. Botet Escriba
+
+#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/thread.hpp>
+#include <boost/thread/latch.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+#include <vector>
+
+namespace
+{
+
+ // Shared variables for generation latch test
+ const int N_THREADS = 10;
+ boost::latch gen_latch(N_THREADS);
+ boost::mutex mutex;
+ long global_parameter;
+
+ void latch_thread()
+ {
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ global_parameter++;
+ }
+ gen_latch.count_down();
+ //do something else
+ }
+
+} // namespace
+
+void test_latch()
+{
+ boost::thread_group g;
+ global_parameter = 0;
+
+ try
+ {
+ for (int i = 0; i < N_THREADS; ++i)
+ g.create_thread(&latch_thread);
+
+ if (! gen_latch.try_wait())
+ if (gen_latch.wait_for(boost::chrono::milliseconds(100)) == boost::cv_status::timeout)
+ if (gen_latch.wait_until(boost::chrono::steady_clock::now()+boost::chrono::milliseconds(100)) == boost::cv_status::timeout)
+ gen_latch.wait(); // All the threads have been updated the global_parameter
+ BOOST_TEST_EQ(global_parameter, N_THREADS);
+
+ g.join_all();
+ }
+ catch (...)
+ {
+ BOOST_TEST(false);
+ g.interrupt_all();
+ g.join_all();
+ //throw;
+ }
+
+}
+
+int main()
+{
+ test_latch();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/test_lock_concept.cpp b/src/boost/libs/thread/test/test_lock_concept.cpp
new file mode 100644
index 000000000..ba7de5cd6
--- /dev/null
+++ b/src/boost/libs/thread/test/test_lock_concept.cpp
@@ -0,0 +1,600 @@
+// (C) Copyright 2006-8 Anthony Williams
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+#define BOOST_TEST_MODULE Boost.Threads: lock_concept test suite
+
+#include <boost/test/unit_test.hpp>
+#include <boost/test/test_case_template.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
+
+template<typename Mutex,typename Lock>
+struct test_initially_locked
+{
+ void operator()() const
+ {
+ Mutex m;
+ Lock lock(m);
+
+ BOOST_CHECK(lock);
+ BOOST_CHECK(lock.owns_lock());
+ }
+};
+
+template<typename Mutex,typename Lock>
+struct test_initially_unlocked_if_other_thread_has_lock
+{
+ Mutex m;
+ boost::mutex done_mutex;
+ bool done;
+ bool locked;
+ boost::condition_variable done_cond;
+
+ test_initially_unlocked_if_other_thread_has_lock():
+ done(false),locked(false)
+ {}
+
+ void locking_thread()
+ {
+ Lock lock(m);
+
+ boost::lock_guard<boost::mutex> lk(done_mutex);
+ locked=lock.owns_lock();
+ done=true;
+ done_cond.notify_one();
+ }
+
+ bool is_done() const
+ {
+ return done;
+ }
+
+
+ void operator()()
+ {
+ Lock lock(m);
+
+ typedef test_initially_unlocked_if_other_thread_has_lock<Mutex,Lock> this_type;
+
+ boost::thread t(&this_type::locking_thread,this);
+
+ try
+ {
+ {
+ boost::unique_lock<boost::mutex> lk(done_mutex);
+ BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2),
+ boost::bind(&this_type::is_done,this)));
+ BOOST_CHECK(!locked);
+ }
+
+ lock.unlock();
+ t.join();
+ }
+ catch(...)
+ {
+ lock.unlock();
+ t.join();
+ throw;
+ }
+ }
+};
+
+template<typename Mutex,typename Lock>
+struct test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock
+{
+ Mutex m;
+ boost::mutex done_mutex;
+ bool done;
+ bool locked;
+ boost::condition_variable done_cond;
+
+ test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock():
+ done(false),locked(false)
+ {}
+
+ void locking_thread()
+ {
+ Lock lock(m,boost::try_to_lock);
+
+ boost::lock_guard<boost::mutex> lk(done_mutex);
+ locked=lock.owns_lock();
+ done=true;
+ done_cond.notify_one();
+ }
+
+ bool is_done() const
+ {
+ return done;
+ }
+
+
+ void operator()()
+ {
+ boost::unique_lock<Mutex> lock(m);
+
+ typedef test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock<Mutex,Lock> this_type;
+
+ boost::thread t(&this_type::locking_thread,this);
+
+ try
+ {
+ {
+ boost::unique_lock<boost::mutex> lk(done_mutex);
+ BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2),
+ boost::bind(&this_type::is_done,this)));
+ BOOST_CHECK(!locked);
+ }
+
+ lock.unlock();
+ t.join();
+ }
+ catch(...)
+ {
+ lock.unlock();
+ t.join();
+ throw;
+ }
+ }
+};
+
+template<typename Mutex,typename Lock>
+struct test_initially_locked_if_other_thread_has_shared_lock
+{
+ Mutex m;
+ boost::mutex done_mutex;
+ bool done;
+ bool locked;
+ boost::condition_variable done_cond;
+
+ test_initially_locked_if_other_thread_has_shared_lock():
+ done(false),locked(false)
+ {}
+
+ void locking_thread()
+ {
+ Lock lock(m);
+
+ boost::lock_guard<boost::mutex> lk(done_mutex);
+ locked=lock.owns_lock();
+ done=true;
+ done_cond.notify_one();
+ }
+
+ bool is_done() const
+ {
+ return done;
+ }
+
+
+ void operator()()
+ {
+ boost::shared_lock<Mutex> lock(m);
+
+ typedef test_initially_locked_if_other_thread_has_shared_lock<Mutex,Lock> this_type;
+
+ boost::thread t(&this_type::locking_thread,this);
+
+ try
+ {
+ {
+ boost::unique_lock<boost::mutex> lk(done_mutex);
+ BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2),
+ boost::bind(&this_type::is_done,this)));
+ BOOST_CHECK(locked);
+ }
+
+ lock.unlock();
+ t.join();
+ }
+ catch(...)
+ {
+ lock.unlock();
+ t.join();
+ throw;
+ }
+ }
+};
+
+template<typename Mutex,typename Lock>
+struct test_initially_unlocked_with_defer_lock_parameter
+{
+ void operator()() const
+ {
+ Mutex m;
+ Lock lock(m,boost::defer_lock);
+
+ BOOST_CHECK(!lock);
+ BOOST_CHECK(!lock.owns_lock());
+ }
+};
+
+template<typename Mutex,typename Lock>
+struct test_initially_locked_with_adopt_lock_parameter
+{
+ void operator()() const
+ {
+ Mutex m;
+ m.lock();
+ Lock lock(m,boost::adopt_lock);
+
+ BOOST_CHECK(lock);
+ BOOST_CHECK(lock.owns_lock());
+ }
+};
+template<typename Mutex,typename Lock>
+struct test_initially_lock_shared_with_adopt_lock_parameter
+{
+ void operator()() const
+ {
+ Mutex m;
+ m.lock_shared();
+ Lock lock(m,boost::adopt_lock);
+
+ BOOST_CHECK(lock);
+ BOOST_CHECK(lock.owns_lock());
+ }
+};
+
+
+template<typename Mutex,typename Lock>
+struct test_unlocked_after_unlock_called
+{
+ void operator()() const
+ {
+ Mutex m;
+ Lock lock(m);
+ lock.unlock();
+ BOOST_CHECK(!lock);
+ BOOST_CHECK(!lock.owns_lock());
+ }
+};
+
+template<typename Mutex,typename Lock>
+struct test_locked_after_lock_called
+{
+ void operator()() const
+ {
+ Mutex m;
+ Lock lock(m,boost::defer_lock);
+ lock.lock();
+ BOOST_CHECK(lock);
+ BOOST_CHECK(lock.owns_lock());
+ }
+};
+
+template<typename Mutex,typename Lock>
+struct test_locked_after_try_lock_called
+{
+ void operator()() const
+ {
+ Mutex m;
+ Lock lock(m,boost::defer_lock);
+ lock.try_lock();
+ BOOST_CHECK(lock);
+ BOOST_CHECK(lock.owns_lock());
+ }
+};
+
+template<typename Mutex,typename Lock>
+struct test_unlocked_after_try_lock_if_other_thread_has_lock
+{
+ Mutex m;
+ boost::mutex done_mutex;
+ bool done;
+ bool locked;
+ boost::condition_variable done_cond;
+
+ test_unlocked_after_try_lock_if_other_thread_has_lock():
+ done(false),locked(false)
+ {}
+
+ void locking_thread()
+ {
+ Lock lock(m,boost::defer_lock);
+
+ boost::lock_guard<boost::mutex> lk(done_mutex);
+ locked=lock.owns_lock();
+ done=true;
+ done_cond.notify_one();
+ }
+
+ bool is_done() const
+ {
+ return done;
+ }
+
+
+ void operator()()
+ {
+ Lock lock(m);
+
+ typedef test_unlocked_after_try_lock_if_other_thread_has_lock<Mutex,Lock> this_type;
+
+ boost::thread t(&this_type::locking_thread,this);
+
+ try
+ {
+ {
+ boost::unique_lock<boost::mutex> lk(done_mutex);
+ BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2),
+ boost::bind(&this_type::is_done,this)));
+ BOOST_CHECK(!locked);
+ }
+
+ lock.unlock();
+ t.join();
+ }
+ catch(...)
+ {
+ lock.unlock();
+ t.join();
+ throw;
+ }
+ }
+};
+
+template<typename Mutex,typename Lock>
+struct test_throws_if_lock_called_when_already_locked
+{
+ void operator()() const
+ {
+ Mutex m;
+ Lock lock(m);
+
+ BOOST_CHECK_THROW( lock.lock(), boost::lock_error );
+ }
+};
+
+template<typename Mutex,typename Lock>
+struct test_throws_if_try_lock_called_when_already_locked
+{
+ void operator()() const
+ {
+ Mutex m;
+ Lock lock(m);
+
+ BOOST_CHECK_THROW( lock.try_lock(), boost::lock_error );
+ }
+};
+
+template<typename Mutex,typename Lock>
+struct test_throws_if_unlock_called_when_already_unlocked
+{
+ void operator()() const
+ {
+ Mutex m;
+ Lock lock(m);
+ lock.unlock();
+
+ BOOST_CHECK_THROW( lock.unlock(), boost::lock_error );
+ }
+};
+template<typename Lock>
+struct test_default_constructed_has_no_mutex_and_unlocked
+{
+ void operator()() const
+ {
+ Lock l;
+ BOOST_CHECK(!l.mutex());
+ BOOST_CHECK(!l.owns_lock());
+ }
+};
+
+
+template<typename Mutex,typename Lock>
+struct test_locks_can_be_swapped
+{
+ void operator()() const
+ {
+ Mutex m1;
+ Mutex m2;
+ Mutex m3;
+
+ Lock l1(m1);
+ Lock l2(m2);
+
+ BOOST_CHECK_EQUAL(l1.mutex(),&m1);
+ BOOST_CHECK_EQUAL(l2.mutex(),&m2);
+
+ l1.swap(l2);
+
+ BOOST_CHECK_EQUAL(l1.mutex(),&m2);
+ BOOST_CHECK_EQUAL(l2.mutex(),&m1);
+
+ swap(l1,l2);
+
+ BOOST_CHECK_EQUAL(l1.mutex(),&m1);
+ BOOST_CHECK_EQUAL(l2.mutex(),&m2);
+
+#if 0
+ l1.swap(Lock(m3));
+
+ BOOST_CHECK_EQUAL(l1.mutex(),&m3);
+#endif
+
+ }
+};
+
+template<typename Mutex,typename Lock>
+void test_lock_is_scoped_lock_concept_for_mutex()
+{
+ test_default_constructed_has_no_mutex_and_unlocked<Lock>()();
+ test_initially_locked<Mutex,Lock>()();
+ test_initially_unlocked_with_defer_lock_parameter<Mutex,Lock>()();
+ test_initially_locked_with_adopt_lock_parameter<Mutex,Lock>()();
+ test_unlocked_after_unlock_called<Mutex,Lock>()();
+ test_locked_after_lock_called<Mutex,Lock>()();
+ test_throws_if_lock_called_when_already_locked<Mutex,Lock>()();
+ test_throws_if_unlock_called_when_already_unlocked<Mutex,Lock>()();
+ test_locks_can_be_swapped<Mutex,Lock>()();
+ test_locked_after_try_lock_called<Mutex,Lock>()();
+ test_throws_if_try_lock_called_when_already_locked<Mutex,Lock>()();
+ test_unlocked_after_try_lock_if_other_thread_has_lock<Mutex,Lock>()();
+}
+
+typedef boost::mpl::vector<boost::mutex,boost::timed_mutex,
+ boost::recursive_mutex,boost::recursive_timed_mutex> mutex_types_with_scoped_lock;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_scoped_lock_concept,Mutex,mutex_types_with_scoped_lock)
+{
+ typedef typename Mutex::scoped_lock Lock;
+
+ test_lock_is_scoped_lock_concept_for_mutex<Mutex,Lock>();
+}
+
+typedef boost::mpl::vector<boost::mutex,boost::timed_mutex,
+ boost::recursive_mutex,boost::recursive_timed_mutex,boost::shared_mutex> all_mutex_types;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_unique_lock_is_scoped_lock,Mutex,all_mutex_types)
+{
+ typedef boost::unique_lock<Mutex> Lock;
+
+ test_lock_is_scoped_lock_concept_for_mutex<Mutex,Lock>();
+}
+
+typedef boost::mpl::vector<boost::try_mutex,boost::timed_mutex,
+ boost::recursive_try_mutex,boost::recursive_timed_mutex> mutex_types_with_scoped_try_lock;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_scoped_try_lock_concept,Mutex,mutex_types_with_scoped_try_lock)
+{
+ typedef typename Mutex::scoped_try_lock Lock;
+
+ test_default_constructed_has_no_mutex_and_unlocked<Lock>()();
+ test_initially_locked<Mutex,Lock>()();
+ test_initially_unlocked_if_other_thread_has_lock<Mutex,Lock>()();
+ test_initially_unlocked_with_defer_lock_parameter<Mutex,Lock>()();
+ test_initially_locked_with_adopt_lock_parameter<Mutex,Lock>()();
+ test_unlocked_after_unlock_called<Mutex,Lock>()();
+ test_locked_after_lock_called<Mutex,Lock>()();
+ test_locked_after_try_lock_called<Mutex,Lock>()();
+ test_unlocked_after_try_lock_if_other_thread_has_lock<Mutex,Lock>()();
+ test_throws_if_lock_called_when_already_locked<Mutex,Lock>()();
+ test_throws_if_try_lock_called_when_already_locked<Mutex,Lock>()();
+ test_throws_if_unlock_called_when_already_unlocked<Mutex,Lock>()();
+ test_locks_can_be_swapped<Mutex,Lock>()();
+}
+
+struct dummy_shared_mutex
+{
+ bool locked;
+ bool shared_locked;
+ bool shared_unlocked;
+ bool shared_timed_locked_relative;
+ bool shared_timed_locked_absolute;
+ bool timed_locked_relative;
+ bool timed_locked_absolute;
+
+ dummy_shared_mutex():
+ locked(false),shared_locked(false),shared_unlocked(false),
+ shared_timed_locked_relative(false),
+ shared_timed_locked_absolute(false),
+ timed_locked_relative(false),
+ timed_locked_absolute(false)
+ {}
+
+ void lock()
+ {
+ locked=true;
+ }
+
+ void lock_shared()
+ {
+ shared_locked=true;
+ }
+
+ void unlock()
+ {}
+
+ void unlock_shared()
+ {
+ shared_unlocked=true;
+ }
+
+ bool timed_lock_shared(boost::system_time)
+ {
+ shared_timed_locked_absolute=true;
+ return false;
+ }
+ template<typename Duration>
+ bool timed_lock_shared(Duration)
+ {
+ shared_timed_locked_relative=true;
+ return false;
+ }
+ bool timed_lock(boost::system_time)
+ {
+ timed_locked_absolute=true;
+ return false;
+ }
+ template<typename Duration>
+ bool timed_lock(Duration)
+ {
+ timed_locked_relative=true;
+ return false;
+ }
+
+};
+
+
+BOOST_AUTO_TEST_CASE(test_shared_lock)
+{
+ typedef boost::shared_mutex Mutex;
+ typedef boost::shared_lock<Mutex> Lock;
+
+ test_default_constructed_has_no_mutex_and_unlocked<Lock>()();
+ test_initially_locked<Mutex,Lock>()();
+ test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock<Mutex,Lock>()();
+ test_initially_locked_if_other_thread_has_shared_lock<Mutex,Lock>()();
+ test_initially_unlocked_with_defer_lock_parameter<Mutex,Lock>()();
+ test_initially_lock_shared_with_adopt_lock_parameter<Mutex,Lock>()();
+ test_unlocked_after_unlock_called<Mutex,Lock>()();
+ test_locked_after_lock_called<Mutex,Lock>()();
+ test_locked_after_try_lock_called<Mutex,Lock>()();
+ test_throws_if_lock_called_when_already_locked<Mutex,Lock>()();
+ test_throws_if_try_lock_called_when_already_locked<Mutex,Lock>()();
+ test_throws_if_unlock_called_when_already_unlocked<Mutex,Lock>()();
+ test_locks_can_be_swapped<Mutex,Lock>()();
+
+ dummy_shared_mutex dummy;
+ boost::shared_lock<dummy_shared_mutex> lk(dummy);
+ BOOST_CHECK(dummy.shared_locked);
+ lk.unlock();
+ BOOST_CHECK(dummy.shared_unlocked);
+ lk.timed_lock(boost::posix_time::milliseconds(5));
+ BOOST_CHECK(dummy.shared_timed_locked_relative);
+ lk.timed_lock(boost::get_system_time());
+ BOOST_CHECK(dummy.shared_timed_locked_absolute);
+}
+
+//boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
+//{
+// boost::unit_test::test_suite* test =
+// BOOST_TEST_SUITE("Boost.Threads: lock concept test suite");
+//
+// typedef boost::mpl::vector<boost::mutex,boost::try_mutex,boost::timed_mutex,
+// boost::recursive_mutex,boost::recursive_try_mutex,boost::recursive_timed_mutex> mutex_types_with_scoped_lock;
+//
+// test->add(BOOST_TEST_CASE_TEMPLATE(test_scoped_lock_concept,mutex_types_with_scoped_lock));
+//
+// typedef boost::mpl::vector<boost::try_mutex,boost::timed_mutex,
+// boost::recursive_try_mutex,boost::recursive_timed_mutex> mutex_types_with_scoped_try_lock;
+//
+// test->add(BOOST_TEST_CASE_TEMPLATE(test_scoped_try_lock_concept,mutex_types_with_scoped_try_lock));
+//
+// typedef boost::mpl::vector<boost::mutex,boost::try_mutex,boost::timed_mutex,
+// boost::recursive_mutex,boost::recursive_try_mutex,boost::recursive_timed_mutex,boost::shared_mutex> all_mutex_types;
+//
+// test->add(BOOST_TEST_CASE_TEMPLATE(test_unique_lock_is_scoped_lock,all_mutex_types));
+// test->add(BOOST_TEST_CASE(&test_shared_lock));
+//
+// return test;
+//}
+
diff --git a/src/boost/libs/thread/test/test_ml.cpp b/src/boost/libs/thread/test/test_ml.cpp
new file mode 100644
index 000000000..61b7eff56
--- /dev/null
+++ b/src/boost/libs/thread/test/test_ml.cpp
@@ -0,0 +1,201 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/config.hpp>
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/utility/result_of.hpp>
+#include <functional>
+
+struct async_func {
+ virtual ~async_func() { }
+ virtual void run() =0;
+ };
+
+template <typename Ret>
+class async_func_pt : public async_func {
+ boost::packaged_task<Ret> f;
+public:
+ void run() {
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+f(); }
+ async_func_pt (boost::packaged_task<Ret>&& f) : f(boost::move(f)) {}
+ ~async_func_pt() { }
+ boost::unique_future<Ret> get_future() { return f.get_future(); }
+ };
+
+void async_core (async_func* p) {
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ p->run();
+}
+
+
+
+
+template <typename F>
+boost::unique_future<typename boost::result_of< F() >::type>
+async (F&& f)
+ {
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ typedef typename boost::result_of< F() >::type RetType;
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ async_func_pt<RetType>* p= new async_func_pt<RetType> (boost::packaged_task<RetType>(boost::forward<F>(f)));
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ boost::unique_future<RetType> future_result= p->get_future();
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ async_core (p);
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ return boost::move(future_result);
+ }
+
+template <typename F, typename A1>
+boost::unique_future<typename boost::result_of< F(A1) >::type>
+async (F&& f, A1&& a1)
+ {
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+// This should be all it needs. But get a funny error deep inside Boost.
+// problem overloading with && ?
+ return async (boost::bind(f,a1));
+ }
+
+
+int calculate_the_answer_to_life_the_universe_and_everything()
+{
+ return 42;
+}
+
+
+size_t foo (const std::string& s)
+ {
+ return s.size();
+ }
+
+
+
+void test1()
+{
+// this one works
+ // most fundimental form:
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ boost::unique_future<int> fi= async (&calculate_the_answer_to_life_the_universe_and_everything);
+ int i= fi.get();
+ BOOST_TEST (i== 42);
+
+
+// This one chokes at compile time
+ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ boost::unique_future<size_t> fut_1= async (&foo, "Life");
+
+ BOOST_TEST (fut_1.get()== 4);
+}
+
+int main()
+{
+ test1();
+ return boost::report_errors();
+
+}
+
+#else
+int main()
+{
+ return 0;
+}
+
+#endif
+/*
+ *
+ "/Users/viboes/clang/llvmCore-3.0-rc1.install/bin/clang++"
+ -o "../../../bin.v2/libs/thread/test/test_ml.test/clang-darwin-3.0x/debug/threading-multi/test_ml"
+ "../../../bin.v2/libs/thread/test/test_ml.test/clang-darwin-3.0x/debug/threading-multi/test_ml.o"
+ "../../../bin.v2/libs/test/build/clang-darwin-3.0x/debug/link-static/threading-multi/libboost_unit_test_framework.a"
+ "../../../bin.v2/libs/thread/build/clang-darwin-3.0x/debug/threading-multi/libboost_thread.dylib"
+ "../../../bin.v2/libs/chrono/build/clang-darwin-3.0x/debug/threading-multi/libboost_chrono.dylib"
+ "../../../bin.v2/libs/system/build/clang-darwin-3.0x/debug/threading-multi/libboost_system.dylib" -g
+*/
+
+
+/*
+ *
+ * #include <boost/test/unit_test.hpp>
+#include <boost/thread/future.hpp>
+#include <boost/utility/result_of.hpp>
+#include <functional>
+
+struct async_func {
+ virtual ~async_func() { }
+ virtual void run() =0;
+ };
+
+template <typename Ret>
+class async_func_pt : public async_func {
+ boost::packaged_task<Ret> f;
+public:
+ void run() override { f(); }
+ async_func_pt (boost::packaged_task<Ret>&& f) : f(std::move(f)) {}
+ ~async_func_pt() { }
+ boost::unique_future<Ret> get_future() { return f.get_future(); }
+ };
+
+void async_core (async_func* p);
+
+
+
+
+template <typename F>
+boost::unique_future<typename boost::result_of< F() >::type>
+async (F&& f)
+ {
+ typedef typename boost::result_of< F() >::type RetType;
+ async_func_pt<RetType>* p= new async_func_pt<RetType> (boost::packaged_task<RetType>(f));
+ boost::unique_future<RetType> future_result= p->get_future();
+ async_core (p);
+ return std::move(future_result);
+ }
+
+template <typename F, typename A1>
+boost::unique_future<typename boost::result_of< F(A1) >::type>
+async (F&& f, A1&& a1)
+ {
+// This should be all it needs. But get a funny error deep inside Boost.
+// problem overloading with && ?
+ return async (std::tr1::bind(f,a1));
+ }
+
+BOOST_AUTO_TEST_SUITE(thread_pool_tests)
+
+int calculate_the_answer_to_life_the_universe_and_everything()
+{
+ return 42;
+}
+
+
+size_t foo (const std::string& s)
+ {
+ return s.size();
+ }
+
+
+
+BOOST_AUTO_TEST_CASE( async_test )
+{
+// this one works
+ // most fundimental form:
+ boost::unique_future<int> fi= async (&calculate_the_answer_to_life_the_universe_and_everything);
+ int i= fi.get();
+ BOOST_CHECK_EQUAL (i, 42);
+
+
+// This one chokes at compile time
+ boost::unique_future<size_t> fut_1= async (&foo, "Life");
+
+ BOOST_CHECK_EQUAL (fut_1.get(), 4);
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+ */
diff --git a/src/boost/libs/thread/test/test_ml2.cpp b/src/boost/libs/thread/test/test_ml2.cpp
new file mode 100644
index 000000000..86ff65738
--- /dev/null
+++ b/src/boost/libs/thread/test/test_ml2.cpp
@@ -0,0 +1,60 @@
+// Copyright (C) 2010 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 4
+
+#include <cassert>
+#include <vector>
+#include <future>
+#include <functional>
+#include <boost/thread/future.hpp>
+
+
+int TRUC = 42;
+int main()
+{
+ std::vector< std::function<void()> > work_queue;
+
+ auto do_some_work = [&]()-> boost::future<int*>
+ {
+ auto promise = std::make_shared<boost::promise<int*>>();
+#if 0
+ work_queue.push_back( [=]
+ {
+ promise->set_value( &TRUC );
+ });
+#else
+ auto inner = [=]()
+ {
+ promise->set_value( &TRUC );
+ };
+ work_queue.push_back(inner);
+
+#endif
+
+ return promise->get_future();
+
+ };
+
+ auto ft_value = do_some_work();
+
+ while( !work_queue.empty() )
+ {
+#if 0
+ auto work = work_queue.back();
+#else
+ std::function<void()> work;
+ work = work_queue.back();
+#endif
+ work_queue.pop_back();
+ work();
+ }
+
+ auto value = ft_value.get();
+ assert( value == &TRUC );
+ return 0;
+}
+
+
diff --git a/src/boost/libs/thread/test/test_move_function.cpp b/src/boost/libs/thread/test/test_move_function.cpp
new file mode 100644
index 000000000..6922fbe64
--- /dev/null
+++ b/src/boost/libs/thread/test/test_move_function.cpp
@@ -0,0 +1,134 @@
+// Copyright (C) 2007-8 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+#define BOOST_TEST_MODULE Boost.Threads: move function test suite
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/shared_ptr.hpp>
+
+void do_nothing()
+{}
+
+BOOST_AUTO_TEST_CASE(test_thread_move_from_lvalue_on_construction)
+{
+ boost::thread src(&do_nothing);
+ boost::thread::id src_id=src.get_id();
+ boost::thread dest(boost::move(src));
+ boost::thread::id dest_id=dest.get_id();
+ BOOST_CHECK(src_id==dest_id);
+ BOOST_CHECK(src.get_id()==boost::thread::id());
+ dest.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_thread_move_from_lvalue_on_assignment)
+{
+ boost::thread src(&do_nothing);
+ boost::thread::id src_id=src.get_id();
+ boost::thread dest;
+ dest=boost::move(src);
+ boost::thread::id dest_id=dest.get_id();
+ BOOST_CHECK(src_id==dest_id);
+ BOOST_CHECK(src.get_id()==boost::thread::id());
+ dest.join();
+}
+
+boost::thread start_thread()
+{
+ return boost::thread(&do_nothing);
+}
+
+BOOST_AUTO_TEST_CASE(test_thread_move_from_rvalue_on_construction)
+{
+ boost::thread x(start_thread());
+ BOOST_CHECK(x.get_id()!=boost::thread::id());
+ x.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_thread_move_from_rvalue_using_explicit_move)
+{
+ //boost::thread x(boost::move(start_thread()));
+ boost::thread x=start_thread();
+ BOOST_CHECK(x.get_id()!=boost::thread::id());
+ x.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_unique_lock_move_from_lvalue_on_construction)
+{
+ boost::mutex m;
+ boost::unique_lock<boost::mutex> l(m);
+ BOOST_CHECK(l.owns_lock());
+ BOOST_CHECK(l.mutex()==&m);
+
+ boost::unique_lock<boost::mutex> l2(boost::move(l));
+ BOOST_CHECK(!l.owns_lock());
+ BOOST_CHECK(!l.mutex());
+ BOOST_CHECK(l2.owns_lock());
+ BOOST_CHECK(l2.mutex()==&m);
+}
+
+boost::unique_lock<boost::mutex> get_lock(boost::mutex& m)
+{
+ return boost::unique_lock<boost::mutex>(m);
+}
+
+
+BOOST_AUTO_TEST_CASE(test_unique_lock_move_from_rvalue_on_construction)
+{
+ boost::mutex m;
+ boost::unique_lock<boost::mutex> l(get_lock(m));
+ BOOST_CHECK(l.owns_lock());
+ BOOST_CHECK(l.mutex()==&m);
+}
+
+namespace user_test_ns
+{
+ template<typename T>
+ T move(T& t)
+ {
+ return t.move();
+ }
+
+ bool move_called=false;
+
+ struct nc:
+ public boost::shared_ptr<int>
+ {
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ nc() {}
+ nc(nc&&)
+ {
+ move_called=true;
+ }
+#endif
+ nc move()
+ {
+ move_called=true;
+ return nc();
+ }
+ };
+}
+
+namespace boost
+{
+ BOOST_THREAD_DCL_MOVABLE(user_test_ns::nc)
+}
+
+BOOST_AUTO_TEST_CASE(test_move_for_user_defined_type_unaffected)
+{
+ user_test_ns::nc src;
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ user_test_ns::nc dest=boost::move(src);
+#else
+ user_test_ns::nc dest=move(src);
+#endif
+ BOOST_CHECK(user_test_ns::move_called);
+}
+
+
+
+
diff --git a/src/boost/libs/thread/test/test_mutex.cpp b/src/boost/libs/thread/test/test_mutex.cpp
new file mode 100644
index 000000000..e6ac24e27
--- /dev/null
+++ b/src/boost/libs/thread/test/test_mutex.cpp
@@ -0,0 +1,341 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+#define BOOST_TEST_MODULE Boost.Threads: mutex test suite
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/lock_types.hpp>
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/condition.hpp>
+
+#define BOOST_TEST_MODULE Boost.Threads: mutex test suite
+
+#include <boost/test/unit_test.hpp>
+
+#define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_sleep_only
+#include "./util.inl"
+
+template <typename M>
+struct test_lock
+{
+ typedef M mutex_type;
+ typedef typename M::scoped_lock lock_type;
+
+ void operator()()
+ {
+ mutex_type mutex;
+ boost::condition condition;
+
+ // Test the lock's constructors.
+ {
+ lock_type lock(mutex, boost::defer_lock);
+ BOOST_CHECK(!lock);
+ }
+ lock_type lock(mutex);
+ BOOST_CHECK(lock ? true : false);
+
+ // Construct and initialize an xtime for a fast time out.
+ boost::xtime xt = delay(0, 100);
+
+ // Test the lock and the mutex with condition variables.
+ // No one is going to notify this condition variable. We expect to
+ // time out.
+ BOOST_CHECK(!condition.timed_wait(lock, xt));
+ BOOST_CHECK(lock ? true : false);
+
+ // Test the lock and unlock methods.
+ lock.unlock();
+ BOOST_CHECK(!lock);
+ lock.lock();
+ BOOST_CHECK(lock ? true : false);
+ }
+};
+
+template <typename M>
+struct test_trylock
+{
+ typedef M mutex_type;
+ typedef typename M::scoped_try_lock try_lock_type;
+
+ void operator()()
+ {
+ mutex_type mutex;
+ boost::condition condition;
+
+ // Test the lock's constructors.
+ {
+ try_lock_type lock(mutex);
+ BOOST_CHECK(lock ? true : false);
+ }
+ {
+ try_lock_type lock(mutex, boost::defer_lock);
+ BOOST_CHECK(!lock);
+ }
+ try_lock_type lock(mutex);
+ BOOST_CHECK(lock ? true : false);
+
+ // Construct and initialize an xtime for a fast time out.
+ boost::xtime xt = delay(0, 100);
+
+ // Test the lock and the mutex with condition variables.
+ // No one is going to notify this condition variable. We expect to
+ // time out.
+ BOOST_CHECK(!condition.timed_wait(lock, xt));
+ BOOST_CHECK(lock ? true : false);
+
+ // Test the lock, unlock and trylock methods.
+ lock.unlock();
+ BOOST_CHECK(!lock);
+ lock.lock();
+ BOOST_CHECK(lock ? true : false);
+ lock.unlock();
+ BOOST_CHECK(!lock);
+ BOOST_CHECK(lock.try_lock());
+ BOOST_CHECK(lock ? true : false);
+ }
+};
+
+template<typename Mutex>
+struct test_lock_times_out_if_other_thread_has_lock
+{
+ typedef boost::unique_lock<Mutex> Lock;
+
+ Mutex m;
+ boost::mutex done_mutex;
+ bool done;
+ bool locked;
+ boost::condition_variable done_cond;
+
+ test_lock_times_out_if_other_thread_has_lock():
+ done(false),locked(false)
+ {}
+
+ void locking_thread()
+ {
+ Lock lock(m,boost::defer_lock);
+ lock.timed_lock(boost::posix_time::milliseconds(50));
+
+ boost::lock_guard<boost::mutex> lk(done_mutex);
+ locked=lock.owns_lock();
+ done=true;
+ done_cond.notify_one();
+ }
+
+ void locking_thread_through_constructor()
+ {
+ Lock lock(m,boost::posix_time::milliseconds(50));
+
+ boost::lock_guard<boost::mutex> lk(done_mutex);
+ locked=lock.owns_lock();
+ done=true;
+ done_cond.notify_one();
+ }
+
+ bool is_done() const
+ {
+ return done;
+ }
+
+ typedef test_lock_times_out_if_other_thread_has_lock<Mutex> this_type;
+
+ void do_test(void (this_type::*test_func)())
+ {
+ Lock lock(m);
+
+ locked=false;
+ done=false;
+
+ boost::thread t(test_func,this);
+
+ try
+ {
+ {
+ boost::unique_lock<boost::mutex> lk(done_mutex);
+ BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2),
+ boost::bind(&this_type::is_done,this)));
+ BOOST_CHECK(!locked);
+ }
+
+ lock.unlock();
+ t.join();
+ }
+ catch(...)
+ {
+ lock.unlock();
+ t.join();
+ throw;
+ }
+ }
+
+
+ void operator()()
+ {
+ do_test(&this_type::locking_thread);
+ do_test(&this_type::locking_thread_through_constructor);
+ }
+};
+
+template <typename M>
+struct test_timedlock
+{
+ typedef M mutex_type;
+ typedef typename M::scoped_timed_lock timed_lock_type;
+
+ static bool fake_predicate()
+ {
+ return false;
+ }
+
+ void operator()()
+ {
+ test_lock_times_out_if_other_thread_has_lock<mutex_type>()();
+
+ mutex_type mutex;
+ boost::condition condition;
+
+ // Test the lock's constructors.
+ {
+ // Construct and initialize an xtime for a fast time out.
+ boost::system_time xt = boost::get_system_time()+boost::posix_time::milliseconds(100);
+
+ timed_lock_type lock(mutex, xt);
+ BOOST_CHECK(lock ? true : false);
+ }
+ {
+ timed_lock_type lock(mutex, boost::defer_lock);
+ BOOST_CHECK(!lock);
+ }
+ timed_lock_type lock(mutex);
+ BOOST_CHECK(lock ? true : false);
+
+ // Construct and initialize an xtime for a fast time out.
+ boost::system_time timeout = boost::get_system_time()+boost::posix_time::milliseconds(100);
+
+ // Test the lock and the mutex with condition variables.
+ // No one is going to notify this condition variable. We expect to
+ // time out.
+ BOOST_CHECK(!condition.timed_wait(lock, timeout, fake_predicate));
+ BOOST_CHECK(lock ? true : false);
+
+ boost::system_time now=boost::get_system_time();
+ boost::posix_time::milliseconds const timeout_resolution(20);
+ BOOST_CHECK((timeout-timeout_resolution)<now);
+
+ // Test the lock, unlock and timedlock methods.
+ lock.unlock();
+ BOOST_CHECK(!lock);
+ lock.lock();
+ BOOST_CHECK(lock ? true : false);
+ lock.unlock();
+ BOOST_CHECK(!lock);
+ boost::system_time target = boost::get_system_time()+boost::posix_time::milliseconds(100);
+ BOOST_CHECK(lock.timed_lock(target));
+ BOOST_CHECK(lock ? true : false);
+ lock.unlock();
+ BOOST_CHECK(!lock);
+
+ BOOST_CHECK(mutex.timed_lock(boost::posix_time::milliseconds(100)));
+ mutex.unlock();
+
+ BOOST_CHECK(lock.timed_lock(boost::posix_time::milliseconds(100)));
+ BOOST_CHECK(lock ? true : false);
+ lock.unlock();
+ BOOST_CHECK(!lock);
+
+ }
+};
+
+template <typename M>
+struct test_recursive_lock
+{
+ typedef M mutex_type;
+ typedef typename M::scoped_lock lock_type;
+
+ void operator()()
+ {
+ mutex_type mx;
+ lock_type lock1(mx);
+ lock_type lock2(mx);
+ }
+};
+
+
+void do_test_mutex()
+{
+ test_lock<boost::mutex>()();
+}
+
+BOOST_AUTO_TEST_CASE(test_mutex)
+{
+ timed_test(&do_test_mutex, 3);
+}
+
+void do_test_try_mutex()
+{
+ test_lock<boost::try_mutex>()();
+ test_trylock<boost::try_mutex>()();
+}
+
+BOOST_AUTO_TEST_CASE(test_try_mutex)
+{
+ timed_test(&do_test_try_mutex, 3);
+}
+
+void do_test_timed_mutex()
+{
+ test_lock<boost::timed_mutex>()();
+ test_trylock<boost::timed_mutex>()();
+ test_timedlock<boost::timed_mutex>()();
+}
+
+BOOST_AUTO_TEST_CASE(test_timed_mutex)
+{
+ timed_test(&do_test_timed_mutex, 3);
+}
+
+void do_test_recursive_mutex()
+{
+ test_lock<boost::recursive_mutex>()();
+ test_recursive_lock<boost::recursive_mutex>()();
+}
+
+BOOST_AUTO_TEST_CASE(test_recursive_mutex)
+{
+ timed_test(&do_test_recursive_mutex, 3);
+}
+
+void do_test_recursive_try_mutex()
+{
+ test_lock<boost::recursive_try_mutex>()();
+ test_trylock<boost::recursive_try_mutex>()();
+ test_recursive_lock<boost::recursive_try_mutex>()();
+}
+
+BOOST_AUTO_TEST_CASE(test_recursive_try_mutex)
+{
+ timed_test(&do_test_recursive_try_mutex, 3);
+}
+
+void do_test_recursive_timed_mutex()
+{
+ test_lock<boost::recursive_timed_mutex>()();
+ test_trylock<boost::recursive_timed_mutex>()();
+ test_timedlock<boost::recursive_timed_mutex>()();
+ test_recursive_lock<boost::recursive_timed_mutex>()();
+}
+
+BOOST_AUTO_TEST_CASE(test_recursive_timed_mutex)
+{
+ timed_test(&do_test_recursive_timed_mutex, 3);
+}
+
+
+
diff --git a/src/boost/libs/thread/test/test_once.cpp b/src/boost/libs/thread/test/test_once.cpp
new file mode 100644
index 000000000..3103f1c23
--- /dev/null
+++ b/src/boost/libs/thread/test/test_once.cpp
@@ -0,0 +1,192 @@
+// (C) Copyright 2006-7 Anthony Williams
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
+#define BOOST_TEST_MODULE Boost.Threads: once test suite
+
+#include <boost/test/unit_test.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/once.hpp>
+#include <iostream>
+
+#include <boost/thread/detail/log.hpp>
+
+boost::once_flag flag=BOOST_ONCE_INIT;
+int var_to_init=0;
+boost::mutex m;
+
+void initialize_variable()
+{
+ // ensure that if multiple threads get in here, they are serialized, so we can see the effect
+ boost::unique_lock<boost::mutex> lock(m);
+ ++var_to_init;
+}
+
+
+void call_once_thread()
+{
+ unsigned const loop_count=100;
+ int my_once_value=0;
+ for(unsigned i=0;i<loop_count;++i)
+ {
+ boost::call_once(flag, &initialize_variable);
+ my_once_value=var_to_init;
+ if(my_once_value!=1)
+ {
+ break;
+ }
+ }
+ boost::unique_lock<boost::mutex> lock(m);
+ BOOST_CHECK_EQUAL(my_once_value, 1);
+}
+
+BOOST_AUTO_TEST_CASE(test_call_once)
+{
+ BOOST_DETAIL_THREAD_LOG;
+
+ unsigned const num_threads=20;
+ boost::thread_group group;
+
+ try
+ {
+ for(unsigned i=0;i<num_threads;++i)
+ {
+ group.create_thread(&call_once_thread);
+ }
+ group.join_all();
+ }
+ catch(...)
+ {
+ group.interrupt_all();
+ group.join_all();
+ throw;
+ }
+
+ BOOST_CHECK_EQUAL(var_to_init,1);
+}
+
+int var_to_init_with_functor=0;
+
+struct increment_value
+{
+ int* value;
+ explicit increment_value(int* value_):
+ value(value_)
+ {}
+
+ void operator()() const
+ {
+ boost::unique_lock<boost::mutex> lock(m);
+ ++(*value);
+ }
+};
+
+void call_once_with_functor()
+{
+ unsigned const loop_count=100;
+ int my_once_value=0;
+ static boost::once_flag functor_flag=BOOST_ONCE_INIT;
+ for(unsigned i=0;i<loop_count;++i)
+ {
+ boost::call_once(functor_flag, increment_value(&var_to_init_with_functor));
+ my_once_value=var_to_init_with_functor;
+ if(my_once_value!=1)
+ {
+ break;
+ }
+ }
+ boost::unique_lock<boost::mutex> lock(m);
+ BOOST_CHECK_EQUAL(my_once_value, 1);
+}
+
+BOOST_AUTO_TEST_CASE(test_call_once_arbitrary_functor)
+{
+ BOOST_DETAIL_THREAD_LOG;
+
+ unsigned const num_threads=20;
+ boost::thread_group group;
+
+ try
+ {
+ for(unsigned i=0;i<num_threads;++i)
+ {
+ group.create_thread(&call_once_with_functor);
+ }
+ group.join_all();
+ }
+ catch(...)
+ {
+ group.interrupt_all();
+ group.join_all();
+ throw;
+ }
+
+ BOOST_CHECK_EQUAL(var_to_init_with_functor,1);
+}
+
+
+struct throw_before_third_pass
+{
+ struct my_exception
+ {};
+
+ static unsigned pass_counter;
+
+ void operator()() const
+ {
+ boost::unique_lock<boost::mutex> lock(m);
+ ++pass_counter;
+ if(pass_counter<3)
+ {
+ throw my_exception();
+ }
+ }
+};
+
+unsigned throw_before_third_pass::pass_counter=0;
+unsigned exception_counter=0;
+
+void call_once_with_exception()
+{
+ static boost::once_flag functor_flag=BOOST_ONCE_INIT;
+ try
+ {
+ boost::call_once(functor_flag, throw_before_third_pass());
+ }
+ catch(throw_before_third_pass::my_exception)
+ {
+ boost::unique_lock<boost::mutex> lock(m);
+ ++exception_counter;
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_call_once_retried_on_exception)
+{
+ BOOST_DETAIL_THREAD_LOG;
+ unsigned const num_threads=20;
+ boost::thread_group group;
+
+ try
+ {
+ for(unsigned i=0;i<num_threads;++i)
+ {
+ group.create_thread(&call_once_with_exception);
+ }
+ group.join_all();
+ }
+ catch(...)
+ {
+ group.interrupt_all();
+ group.join_all();
+ throw;
+ }
+
+ BOOST_CHECK_EQUAL(throw_before_third_pass::pass_counter,3u);
+ BOOST_CHECK_EQUAL(exception_counter,2u);
+}
+
+
diff --git a/src/boost/libs/thread/test/test_physical_concurrency.cpp b/src/boost/libs/thread/test/test_physical_concurrency.cpp
new file mode 100644
index 000000000..5c635751f
--- /dev/null
+++ b/src/boost/libs/thread/test/test_physical_concurrency.cpp
@@ -0,0 +1,25 @@
+// Copyright (C) 2007 Anthony Williams
+// Copyright (C) 2013 Tim Blechmann
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_TEST_MODULE Boost.Threads: physical_concurrency test suite
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/thread/mutex.hpp>
+
+BOOST_AUTO_TEST_CASE(test_physical_concurrency_is_non_zero)
+{
+#if defined(__MINGW32__) && !defined(__MINGW64__)
+// This matches the condition in win32/thread.cpp, even though
+// that's probably wrong on MinGW-w64 in 32 bit mode
+#else
+ BOOST_CHECK(boost::thread::physical_concurrency()!=0);
+#endif
+}
+
+
+
+
diff --git a/src/boost/libs/thread/test/test_scheduled_tp.cpp b/src/boost/libs/thread/test/test_scheduled_tp.cpp
new file mode 100644
index 000000000..8684ffd4f
--- /dev/null
+++ b/src/boost/libs/thread/test/test_scheduled_tp.cpp
@@ -0,0 +1,97 @@
+// Copyright (C) 2014 Ian Forbed
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+
+#include <boost/bind/bind.hpp>
+#include <boost/chrono.hpp>
+#include <boost/chrono/chrono_io.hpp>
+#include <boost/function.hpp>
+#include <boost/thread/executors/scheduled_thread_pool.hpp>
+#include <iostream>
+
+#include <boost/core/lightweight_test.hpp>
+
+using namespace boost::chrono;
+
+typedef boost::scheduled_thread_pool scheduled_tp;
+
+void fn(int x)
+{
+ std::cout << x << std::endl;
+}
+
+void func(steady_clock::time_point pushed, steady_clock::duration dur)
+{
+ BOOST_TEST(pushed + dur < steady_clock::now());
+}
+void func2(scheduled_tp* tp, steady_clock::duration d)
+{
+ boost::function<void()> fn = boost::bind(func,steady_clock::now(),d);
+ tp->submit_after(fn, d);
+}
+
+
+
+void test_timing(const int n)
+{
+ //This function should take n seconds to execute.
+ boost::scheduled_thread_pool se(4);
+
+ for(int i = 1; i <= n; i++)
+ {
+ se.submit_after(boost::bind(fn,i), milliseconds(i*100));
+ }
+ boost::this_thread::sleep_for(boost::chrono::seconds(10));
+ //dtor is called here so all task will have to be executed before we return
+}
+
+void test_deque_timing()
+{
+ boost::scheduled_thread_pool se(4);
+ for(int i = 0; i < 10; i++)
+ {
+ steady_clock::duration d = milliseconds(i*100);
+ boost::function<void()> fn = boost::bind(func,steady_clock::now(),d);
+ se.submit_after(fn,d);
+ }
+}
+
+void test_deque_multi(const int n)
+{
+ scheduled_tp se(4);
+ boost::thread_group tg;
+ for(int i = 0; i < n; i++)
+ {
+ steady_clock::duration d = milliseconds(i*100);
+ //boost::function<void()> fn = boost::bind(func,steady_clock::now(),d);
+ //tg.create_thread(boost::bind(boost::mem_fn(&scheduled_tp::submit_after), &se, fn, d));
+ tg.create_thread(boost::bind(func2, &se, d));
+ }
+ tg.join_all();
+ //dtor is called here so execution will block until all the closures
+ //have been completed.
+}
+
+int main()
+{
+ steady_clock::time_point start = steady_clock::now();
+ test_timing(5);
+ steady_clock::duration diff = steady_clock::now() - start;
+ BOOST_TEST(diff > milliseconds(500));
+ test_deque_timing();
+ test_deque_multi(4);
+ test_deque_multi(8);
+ test_deque_multi(16);
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/test_scheduler.cpp b/src/boost/libs/thread/test/test_scheduler.cpp
new file mode 100644
index 000000000..5847ff010
--- /dev/null
+++ b/src/boost/libs/thread/test/test_scheduler.cpp
@@ -0,0 +1,81 @@
+// Copyright (C) 2014 Ian Forbed
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+
+#include <boost/thread/executors/scheduler.hpp>
+#include <boost/thread/executors/basic_thread_pool.hpp>
+#include <boost/chrono/chrono_io.hpp>
+#include <iostream>
+
+#include <boost/core/lightweight_test.hpp>
+
+using namespace boost::chrono;
+
+
+typedef boost::executors::basic_thread_pool thread_pool;
+
+void fn(int x)
+{
+ //std::cout << "[" << __LINE__ << "] " << steady_clock::now() << std::endl;
+ std::cout << x << std::endl;
+}
+
+void test_scheduler(const int n, boost::scheduler<>& sch)
+{
+ for(int i = 1; i <= n; i++)
+ {
+ sch.submit_after(boost::bind(fn,i), seconds(i));
+ sch.submit_after(boost::bind(fn,i), milliseconds(i*100));
+ }
+}
+
+void test_after(const int n, boost::scheduler<>& sch)
+{
+ for(int i = 1; i <= n; i++)
+ {
+ sch.after(seconds(i)).submit(boost::bind(fn,i));
+ sch.after(milliseconds(i*100)).submit(boost::bind(fn,i));
+ }
+}
+
+void test_at(const int n, boost::scheduler<>& sch)
+{
+ for(int i = 1; i <= n; i++)
+ {
+ sch.at(steady_clock::now()+seconds(i)).submit(boost::bind(fn,i));
+ sch.at(steady_clock::now()+milliseconds(i*100)).submit(boost::bind(fn,i));
+ }
+}
+
+void test_on(const int n, boost::scheduler<>& sch, thread_pool& tp)
+{
+ for(int i = 1; i <= n; i++)
+ {
+ sch.on(tp).after(seconds(i)).submit(boost::bind(fn,i));
+ sch.on(tp).after(milliseconds(i*100)).submit(boost::bind(fn,i));
+ }
+}
+
+int main()
+{
+ thread_pool tp(4);
+ boost::scheduler<> sch;
+ test_scheduler(5, sch);
+ test_after(5, sch);
+ test_at(5, sch);
+ test_on(5, sch, tp);
+ boost::this_thread::sleep_for(boost::chrono::seconds(10));
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/test_scheduling_adaptor.cpp b/src/boost/libs/thread/test/test_scheduling_adaptor.cpp
new file mode 100644
index 000000000..38c073bda
--- /dev/null
+++ b/src/boost/libs/thread/test/test_scheduling_adaptor.cpp
@@ -0,0 +1,54 @@
+// Copyright (C) 2014 Ian Forbed
+// Copyright (C) 2014 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+
+#include <boost/function.hpp>
+#include <boost/thread/executors/executor.hpp>
+#include <boost/thread/executors/basic_thread_pool.hpp>
+#include <boost/thread/executors/scheduling_adaptor.hpp>
+#include <boost/chrono/chrono_io.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+
+using namespace boost::chrono;
+
+
+typedef boost::executors::basic_thread_pool thread_pool;
+
+void fn(int x)
+{
+ //std::cout << "[" << __LINE__ << "] " << steady_clock::now() << std::endl;
+ std::cout << x << std::endl;
+}
+
+void test_timing(const int n)
+{
+ thread_pool tp(4);
+ boost::scheduling_adaptor<thread_pool> sa(tp);
+ for(int i = 1; i <= n; i++)
+ {
+ sa.submit_after(boost::bind(fn,i),seconds(i));
+ sa.submit_after(boost::bind(fn,i), milliseconds(i*100));
+ }
+ boost::this_thread::sleep_for(boost::chrono::seconds(10));
+}
+
+int main()
+{
+ steady_clock::time_point start = steady_clock::now();
+ test_timing(5);
+ steady_clock::duration diff = steady_clock::now() - start;
+ BOOST_TEST(diff > seconds(5));
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/test_shared_mutex.cpp b/src/boost/libs/thread/test/test_shared_mutex.cpp
new file mode 100644
index 000000000..17bd9a6a1
--- /dev/null
+++ b/src/boost/libs/thread/test/test_shared_mutex.cpp
@@ -0,0 +1,281 @@
+// (C) Copyright 2006-7 Anthony Williams
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
+#define BOOST_TEST_MODULE Boost.Threads: shared_mutex test suite
+
+#include <boost/test/unit_test.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/xtime.hpp>
+#include "./util.inl"
+#include "./shared_mutex_locking_thread.hpp"
+#include <iostream>
+
+#define CHECK_LOCKED_VALUE_EQUAL(mutex_name,value,expected_value) \
+ { \
+ boost::unique_lock<boost::mutex> lock(mutex_name); \
+ BOOST_CHECK_EQUAL(value,expected_value); \
+ }
+
+BOOST_AUTO_TEST_CASE(test_multiple_readers)
+{
+ std::cout << __LINE__ << std::endl;
+ unsigned const number_of_threads=10;
+
+ boost::thread_group pool;
+
+ boost::shared_mutex rw_mutex;
+ unsigned unblocked_count=0;
+ unsigned simultaneous_running_count=0;
+ unsigned max_simultaneous_running=0;
+ boost::mutex unblocked_count_mutex;
+ boost::condition_variable unblocked_condition;
+ boost::mutex finish_mutex;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+
+ try
+ {
+ for(unsigned i=0;i<number_of_threads;++i)
+ {
+ pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_mutex,simultaneous_running_count,max_simultaneous_running));
+ }
+
+ {
+ boost::unique_lock<boost::mutex> lk(unblocked_count_mutex);
+ while(unblocked_count<number_of_threads)
+ {
+ unblocked_condition.wait(lk);
+ }
+ }
+
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,number_of_threads);
+
+ finish_lock.unlock();
+
+ pool.join_all();
+ }
+ catch(...)
+ {
+ pool.interrupt_all();
+ pool.join_all();
+ throw;
+ }
+
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,number_of_threads);
+}
+
+BOOST_AUTO_TEST_CASE(test_only_one_writer_permitted)
+{
+ std::cout << __LINE__ << std::endl;
+ unsigned const number_of_threads=10;
+
+ boost::thread_group pool;
+
+ boost::shared_mutex rw_mutex;
+ unsigned unblocked_count=0;
+ unsigned simultaneous_running_count=0;
+ unsigned max_simultaneous_running=0;
+ boost::mutex unblocked_count_mutex;
+ boost::condition_variable unblocked_condition;
+ boost::mutex finish_mutex;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+
+ try
+ {
+ for(unsigned i=0;i<number_of_threads;++i)
+ {
+ pool.create_thread(locking_thread<boost::unique_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_mutex,simultaneous_running_count,max_simultaneous_running));
+ }
+
+ boost::thread::sleep(delay(2));
+
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
+
+ finish_lock.unlock();
+
+ pool.join_all();
+ }
+ catch(...)
+ {
+ pool.interrupt_all();
+ pool.join_all();
+ throw;
+ }
+
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,number_of_threads);
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,1u);
+}
+
+BOOST_AUTO_TEST_CASE(test_reader_blocks_writer)
+{
+ std::cout << __LINE__ << std::endl;
+ boost::thread_group pool;
+
+ boost::shared_mutex rw_mutex;
+ unsigned unblocked_count=0;
+ unsigned simultaneous_running_count=0;
+ unsigned max_simultaneous_running=0;
+ boost::mutex unblocked_count_mutex;
+ boost::condition_variable unblocked_condition;
+ boost::mutex finish_mutex;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+
+ try
+ {
+
+ pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_mutex,simultaneous_running_count,max_simultaneous_running));
+ {
+ boost::unique_lock<boost::mutex> lk(unblocked_count_mutex);
+ while(unblocked_count<1)
+ {
+ unblocked_condition.wait(lk);
+ }
+ }
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
+ pool.create_thread(locking_thread<boost::unique_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_mutex,simultaneous_running_count,max_simultaneous_running));
+ boost::thread::sleep(delay(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
+
+ finish_lock.unlock();
+
+ pool.join_all();
+ }
+ catch(...)
+ {
+ pool.interrupt_all();
+ pool.join_all();
+ throw;
+ }
+
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,2U);
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,1u);
+}
+
+BOOST_AUTO_TEST_CASE(test_unlocking_writer_unblocks_all_readers)
+{
+ std::cout << __LINE__ << std::endl;
+ boost::thread_group pool;
+
+ boost::shared_mutex rw_mutex;
+ boost::unique_lock<boost::shared_mutex> write_lock(rw_mutex);
+ unsigned unblocked_count=0;
+ unsigned simultaneous_running_count=0;
+ unsigned max_simultaneous_running=0;
+ boost::mutex unblocked_count_mutex;
+ boost::condition_variable unblocked_condition;
+ boost::mutex finish_mutex;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+
+ unsigned const reader_count=10;
+
+ try
+ {
+ for(unsigned i=0;i<reader_count;++i)
+ {
+ pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_mutex,simultaneous_running_count,max_simultaneous_running));
+ }
+ boost::thread::sleep(delay(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,0U);
+
+ write_lock.unlock();
+
+ {
+ boost::unique_lock<boost::mutex> lk(unblocked_count_mutex);
+ while(unblocked_count<reader_count)
+ {
+ unblocked_condition.wait(lk);
+ }
+ }
+
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count);
+
+ finish_lock.unlock();
+ pool.join_all();
+ }
+ catch(...)
+ {
+ pool.interrupt_all();
+ pool.join_all();
+ throw;
+ }
+
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,reader_count);
+}
+
+BOOST_AUTO_TEST_CASE(test_unlocking_last_reader_only_unblocks_one_writer)
+{
+ std::cout << __LINE__ << std::endl;
+ boost::thread_group pool;
+
+ boost::shared_mutex rw_mutex;
+ unsigned unblocked_count=0;
+ unsigned simultaneous_running_readers=0;
+ unsigned max_simultaneous_readers=0;
+ unsigned simultaneous_running_writers=0;
+ unsigned max_simultaneous_writers=0;
+ boost::mutex unblocked_count_mutex;
+ boost::condition_variable unblocked_condition;
+ boost::mutex finish_reading_mutex;
+ boost::unique_lock<boost::mutex> finish_reading_lock(finish_reading_mutex);
+ boost::mutex finish_writing_mutex;
+ boost::unique_lock<boost::mutex> finish_writing_lock(finish_writing_mutex);
+
+ unsigned const reader_count=10;
+ unsigned const writer_count=10;
+
+ try
+ {
+ for(unsigned i=0;i<reader_count;++i)
+ {
+ pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_reading_mutex,simultaneous_running_readers,max_simultaneous_readers));
+ }
+ boost::thread::sleep(delay(1));
+ for(unsigned i=0;i<writer_count;++i)
+ {
+ pool.create_thread(locking_thread<boost::unique_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_writing_mutex,simultaneous_running_writers,max_simultaneous_writers));
+ }
+ {
+ boost::unique_lock<boost::mutex> lk(unblocked_count_mutex);
+ while(unblocked_count<reader_count)
+ {
+ unblocked_condition.wait(lk);
+ }
+ }
+ boost::thread::sleep(delay(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count);
+
+ finish_reading_lock.unlock();
+
+ {
+ boost::unique_lock<boost::mutex> lk(unblocked_count_mutex);
+ while(unblocked_count<(reader_count+1))
+ {
+ unblocked_condition.wait(lk);
+ }
+ }
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+1);
+
+ finish_writing_lock.unlock();
+ pool.join_all();
+ }
+ catch(...)
+ {
+ pool.interrupt_all();
+ pool.join_all();
+ throw;
+ }
+
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+writer_count);
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_readers,reader_count);
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_writers,1u);
+}
diff --git a/src/boost/libs/thread/test/test_shared_mutex_part_2.cpp b/src/boost/libs/thread/test/test_shared_mutex_part_2.cpp
new file mode 100644
index 000000000..d395b2e78
--- /dev/null
+++ b/src/boost/libs/thread/test/test_shared_mutex_part_2.cpp
@@ -0,0 +1,294 @@
+// (C) Copyright 2006-7 Anthony Williams
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+#define BOOST_TEST_MODULE Boost.Threads: shared_mutex_part2 test suite
+
+#include <boost/config.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/xtime.hpp>
+#include "./util.inl"
+#include "./shared_mutex_locking_thread.hpp"
+
+#define CHECK_LOCKED_VALUE_EQUAL(mutex_name,value,expected_value) \
+ { \
+ boost::unique_lock<boost::mutex> lock(mutex_name); \
+ BOOST_CHECK_EQUAL(value,expected_value); \
+ }
+
+class simple_upgrade_thread
+{
+ boost::shared_mutex& rwm;
+ boost::mutex& finish_mutex;
+ boost::mutex& unblocked_mutex;
+ unsigned& unblocked_count;
+
+ void operator=(simple_upgrade_thread&);
+
+public:
+ simple_upgrade_thread(boost::shared_mutex& rwm_,
+ boost::mutex& finish_mutex_,
+ boost::mutex& unblocked_mutex_,
+ unsigned& unblocked_count_):
+ rwm(rwm_),finish_mutex(finish_mutex_),
+ unblocked_mutex(unblocked_mutex_),unblocked_count(unblocked_count_)
+ {}
+
+#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
+ simple_upgrade_thread(simple_upgrade_thread const&) = default;
+#endif
+
+ void operator()()
+ {
+ boost::upgrade_lock<boost::shared_mutex> lk(rwm);
+
+ {
+ boost::unique_lock<boost::mutex> ulk(unblocked_mutex);
+ ++unblocked_count;
+ }
+
+ boost::unique_lock<boost::mutex> flk(finish_mutex);
+ }
+};
+
+
+BOOST_AUTO_TEST_CASE(test_only_one_upgrade_lock_permitted)
+{
+ unsigned const number_of_threads=2;
+
+ boost::thread_group pool;
+
+ boost::shared_mutex rw_mutex;
+ unsigned unblocked_count=0;
+ unsigned simultaneous_running_count=0;
+ unsigned max_simultaneous_running=0;
+ boost::mutex unblocked_count_mutex;
+ boost::condition_variable unblocked_condition;
+ boost::mutex finish_mutex;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+
+ try
+ {
+ for(unsigned i=0;i<number_of_threads;++i)
+ {
+ pool.create_thread(locking_thread<boost::upgrade_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_mutex,simultaneous_running_count,max_simultaneous_running));
+ }
+
+ boost::thread::sleep(delay(1));
+
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,1U);
+
+ finish_lock.unlock();
+
+ pool.join_all();
+ }
+ catch(...)
+ {
+ pool.interrupt_all();
+ pool.join_all();
+ throw;
+ }
+
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,number_of_threads);
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,1u);
+}
+
+BOOST_AUTO_TEST_CASE(test_can_lock_upgrade_if_currently_locked_shared)
+{
+ boost::thread_group pool;
+
+ boost::shared_mutex rw_mutex;
+ unsigned unblocked_count=0;
+ unsigned simultaneous_running_count=0;
+ unsigned max_simultaneous_running=0;
+ boost::mutex unblocked_count_mutex;
+ boost::condition_variable unblocked_condition;
+ boost::mutex finish_mutex;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+
+ unsigned const reader_count=10;
+
+ try
+ {
+ for(unsigned i=0;i<reader_count;++i)
+ {
+ pool.create_thread(locking_thread<boost::shared_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_mutex,simultaneous_running_count,max_simultaneous_running));
+ }
+ boost::thread::sleep(delay(1));
+ pool.create_thread(locking_thread<boost::upgrade_lock<boost::shared_mutex> >(rw_mutex,unblocked_count,unblocked_count_mutex,unblocked_condition,
+ finish_mutex,simultaneous_running_count,max_simultaneous_running));
+ {
+ boost::unique_lock<boost::mutex> lk(unblocked_count_mutex);
+ while(unblocked_count<(reader_count+1))
+ {
+ unblocked_condition.wait(lk);
+ }
+ }
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+1);
+
+ finish_lock.unlock();
+ pool.join_all();
+ }
+ catch(...)
+ {
+ pool.interrupt_all();
+ pool.join_all();
+ throw;
+ }
+
+
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,unblocked_count,reader_count+1);
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex,max_simultaneous_running,reader_count+1);
+}
+
+BOOST_AUTO_TEST_CASE(test_can_lock_upgrade_to_unique_if_currently_locked_upgrade)
+{
+ boost::shared_mutex mtx;
+ boost::upgrade_lock<boost::shared_mutex> l(mtx);
+ boost::upgrade_to_unique_lock<boost::shared_mutex> ul(l);
+ BOOST_CHECK(ul.owns_lock());
+}
+
+BOOST_AUTO_TEST_CASE(test_if_other_thread_has_write_lock_try_lock_shared_returns_false)
+{
+
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+ boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ bool const try_succeeded=rw_mutex.try_lock_shared();
+ BOOST_CHECK(!try_succeeded);
+ if(try_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ finish_lock.unlock();
+ writer.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_if_other_thread_has_write_lock_try_lock_upgrade_returns_false)
+{
+
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+ boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ bool const try_succeeded=rw_mutex.try_lock_upgrade();
+ BOOST_CHECK(!try_succeeded);
+ if(try_succeeded)
+ {
+ rw_mutex.unlock_upgrade();
+ }
+
+ finish_lock.unlock();
+ writer.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_if_no_thread_has_lock_try_lock_shared_returns_true)
+{
+ boost::shared_mutex rw_mutex;
+ bool const try_succeeded=rw_mutex.try_lock_shared();
+ BOOST_CHECK(try_succeeded);
+ if(try_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_if_no_thread_has_lock_try_lock_upgrade_returns_true)
+{
+ boost::shared_mutex rw_mutex;
+ bool const try_succeeded=rw_mutex.try_lock_upgrade();
+ BOOST_CHECK(try_succeeded);
+ if(try_succeeded)
+ {
+ rw_mutex.unlock_upgrade();
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_if_other_thread_has_shared_lock_try_lock_shared_returns_true)
+{
+
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+ boost::thread writer(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::thread::sleep(delay(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ bool const try_succeeded=rw_mutex.try_lock_shared();
+ BOOST_CHECK(try_succeeded);
+ if(try_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ finish_lock.unlock();
+ writer.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_if_other_thread_has_shared_lock_try_lock_upgrade_returns_true)
+{
+
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+ boost::thread writer(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::thread::sleep(delay(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ bool const try_succeeded=rw_mutex.try_lock_upgrade();
+ BOOST_CHECK(try_succeeded);
+ if(try_succeeded)
+ {
+ rw_mutex.unlock_upgrade();
+ }
+
+ finish_lock.unlock();
+ writer.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_if_other_thread_has_upgrade_lock_try_lock_upgrade_returns_false)
+{
+
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+ boost::thread writer(simple_upgrade_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ bool const try_succeeded=rw_mutex.try_lock_upgrade();
+ BOOST_CHECK(!try_succeeded);
+ if(try_succeeded)
+ {
+ rw_mutex.unlock_upgrade();
+ }
+
+ finish_lock.unlock();
+ writer.join();
+}
+
+
diff --git a/src/boost/libs/thread/test/test_shared_mutex_timed_locks.cpp b/src/boost/libs/thread/test/test_shared_mutex_timed_locks.cpp
new file mode 100644
index 000000000..c29c4260c
--- /dev/null
+++ b/src/boost/libs/thread/test/test_shared_mutex_timed_locks.cpp
@@ -0,0 +1,255 @@
+// (C) Copyright 2006-7 Anthony Williams
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+#define BOOST_TEST_MODULE Boost.Threads: shared_mutex_timed_locks test suite
+
+#include <boost/test/unit_test.hpp>
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/xtime.hpp>
+#include "./util.inl"
+#include "./shared_mutex_locking_thread.hpp"
+
+#define CHECK_LOCKED_VALUE_EQUAL(mutex_name,value,expected_value) \
+ { \
+ boost::unique_lock<boost::mutex> lock(mutex_name); \
+ BOOST_CHECK_EQUAL(value,expected_value); \
+ }
+
+
+BOOST_AUTO_TEST_CASE(test_timed_lock_shared_times_out_if_write_lock_held)
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+ boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::thread::sleep(delay(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ boost::system_time const start=boost::get_system_time();
+ boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
+ boost::posix_time::milliseconds const timeout_resolution(50);
+ bool timed_lock_succeeded=rw_mutex.timed_lock_shared(timeout);
+ BOOST_CHECK((timeout-timeout_resolution)<boost::get_system_time());
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ boost::posix_time::milliseconds const wait_duration(500);
+ boost::system_time const timeout2=boost::get_system_time()+wait_duration;
+ timed_lock_succeeded=rw_mutex.timed_lock_shared(wait_duration);
+ BOOST_CHECK((timeout2-timeout_resolution)<boost::get_system_time());
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ finish_lock.unlock();
+ writer.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_timed_lock_shared_succeeds_if_no_lock_held)
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+
+ boost::system_time const start=boost::get_system_time();
+ boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
+ boost::posix_time::milliseconds const timeout_resolution(50);
+ bool timed_lock_succeeded=rw_mutex.timed_lock_shared(timeout);
+ BOOST_CHECK(boost::get_system_time()<timeout);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ boost::posix_time::milliseconds const wait_duration(500);
+ boost::system_time const timeout2=boost::get_system_time()+wait_duration;
+ timed_lock_succeeded=rw_mutex.timed_lock_shared(wait_duration);
+ BOOST_CHECK(boost::get_system_time()<timeout2);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+}
+
+BOOST_AUTO_TEST_CASE(test_timed_lock_shared_succeeds_if_read_lock_held)
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+ boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::thread::sleep(delay(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ boost::system_time const start=boost::get_system_time();
+ boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
+ boost::posix_time::milliseconds const timeout_resolution(50);
+ bool timed_lock_succeeded=rw_mutex.timed_lock_shared(timeout);
+ BOOST_CHECK(boost::get_system_time()<timeout);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ boost::posix_time::milliseconds const wait_duration(500);
+ boost::system_time const timeout2=boost::get_system_time()+wait_duration;
+ timed_lock_succeeded=rw_mutex.timed_lock_shared(wait_duration);
+ BOOST_CHECK(boost::get_system_time()<timeout2);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ finish_lock.unlock();
+ reader.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_if_write_lock_held)
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+ boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::thread::sleep(delay(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ boost::system_time const start=boost::get_system_time();
+ boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
+ boost::posix_time::milliseconds const timeout_resolution(50);
+ bool timed_lock_succeeded=rw_mutex.timed_lock(timeout);
+ BOOST_CHECK((timeout-timeout_resolution)<boost::get_system_time());
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+ boost::posix_time::milliseconds const wait_duration(500);
+ boost::system_time const timeout2=boost::get_system_time()+wait_duration;
+ timed_lock_succeeded=rw_mutex.timed_lock(wait_duration);
+ BOOST_CHECK((timeout2-timeout_resolution)<boost::get_system_time());
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+ finish_lock.unlock();
+ writer.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_timed_lock_succeeds_if_no_lock_held)
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+
+ boost::system_time const start=boost::get_system_time();
+ boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
+ boost::posix_time::milliseconds const timeout_resolution(50);
+ bool timed_lock_succeeded=rw_mutex.timed_lock(timeout);
+ BOOST_CHECK(boost::get_system_time()<timeout);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+ boost::posix_time::milliseconds const wait_duration(500);
+ boost::system_time const timeout2=boost::get_system_time()+wait_duration;
+ timed_lock_succeeded=rw_mutex.timed_lock(wait_duration);
+ BOOST_CHECK(boost::get_system_time()<timeout2);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+}
+
+BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_if_read_lock_held)
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+ boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::thread::sleep(delay(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ boost::system_time const start=boost::get_system_time();
+ boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
+ boost::posix_time::milliseconds const timeout_resolution(50);
+ bool timed_lock_succeeded=rw_mutex.timed_lock(timeout);
+ BOOST_CHECK((timeout-timeout_resolution)<boost::get_system_time());
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+ boost::posix_time::milliseconds const wait_duration(500);
+ boost::system_time const timeout2=boost::get_system_time()+wait_duration;
+ timed_lock_succeeded=rw_mutex.timed_lock(wait_duration);
+ BOOST_CHECK((timeout2-timeout_resolution)<boost::get_system_time());
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+ finish_lock.unlock();
+ reader.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held)
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+ boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ boost::system_time const start=boost::get_system_time();
+ boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
+ bool timed_lock_succeeded=rw_mutex.timed_lock(timeout);
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+ boost::posix_time::milliseconds const wait_duration(500);
+ timed_lock_succeeded=rw_mutex.timed_lock_shared(wait_duration);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ finish_lock.unlock();
+ reader.join();
+}
+
diff --git a/src/boost/libs/thread/test/test_shared_mutex_timed_locks_chrono.cpp b/src/boost/libs/thread/test/test_shared_mutex_timed_locks_chrono.cpp
new file mode 100644
index 000000000..f746f50a9
--- /dev/null
+++ b/src/boost/libs/thread/test/test_shared_mutex_timed_locks_chrono.cpp
@@ -0,0 +1,259 @@
+// (C) Copyright 2006-7 Anthony Williams
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+#define BOOST_TEST_MODULE Boost.Threads: shared_mutex_locks_chrono test suite
+
+#include <boost/test/unit_test.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include "./util.inl"
+#include "./shared_mutex_locking_thread.hpp"
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+#define CHECK_LOCKED_VALUE_EQUAL(mutex_name,value,expected_value) \
+ { \
+ boost::unique_lock<boost::mutex> lock(mutex_name); \
+ BOOST_CHECK_EQUAL(value,expected_value); \
+ }
+
+
+BOOST_AUTO_TEST_CASE(test_timed_lock_shared_times_out_if_write_lock_held)
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+ boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
+ boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
+ boost::chrono::milliseconds const timeout_resolution(50);
+ bool timed_lock_succeeded=rw_mutex.try_lock_shared_until(timeout);
+ BOOST_CHECK((timeout-timeout_resolution)<boost::chrono::steady_clock::now());
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ boost::chrono::milliseconds const wait_duration(500);
+ boost::chrono::steady_clock::time_point const timeout2=boost::chrono::steady_clock::now()+wait_duration;
+ timed_lock_succeeded=rw_mutex.try_lock_shared_for(wait_duration);
+ BOOST_CHECK((timeout2-timeout_resolution)<boost::chrono::steady_clock::now());
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ finish_lock.unlock();
+ writer.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_timed_lock_shared_succeeds_if_no_lock_held)
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+
+ boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
+ boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
+ bool timed_lock_succeeded=rw_mutex.try_lock_shared_until(timeout);
+ BOOST_CHECK(boost::chrono::steady_clock::now()<timeout);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ boost::chrono::milliseconds const wait_duration(500);
+ boost::chrono::steady_clock::time_point const timeout2=boost::chrono::steady_clock::now()+wait_duration;
+ timed_lock_succeeded=rw_mutex.try_lock_shared_for(wait_duration);
+ BOOST_CHECK(boost::chrono::steady_clock::now()<timeout2);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+}
+
+BOOST_AUTO_TEST_CASE(test_timed_lock_shared_succeeds_if_read_lock_held)
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+ boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
+ boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
+ bool timed_lock_succeeded=rw_mutex.try_lock_shared_until(timeout);
+ BOOST_CHECK(boost::chrono::steady_clock::now()<timeout);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ boost::chrono::milliseconds const wait_duration(500);
+ boost::chrono::steady_clock::time_point const timeout2=boost::chrono::steady_clock::now()+wait_duration;
+ timed_lock_succeeded=rw_mutex.try_lock_shared_for(wait_duration);
+ BOOST_CHECK(boost::chrono::steady_clock::now()<timeout2);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ finish_lock.unlock();
+ reader.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_if_write_lock_held)
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+ boost::thread writer(simple_writing_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
+ boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
+ boost::chrono::milliseconds const timeout_resolution(50);
+ bool timed_lock_succeeded=rw_mutex.try_lock_until(timeout);
+ BOOST_CHECK((timeout-timeout_resolution)<boost::chrono::steady_clock::now());
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+ boost::chrono::milliseconds const wait_duration(500);
+ boost::chrono::steady_clock::time_point const timeout2=boost::chrono::steady_clock::now()+wait_duration;
+ timed_lock_succeeded=rw_mutex.try_lock_for(wait_duration);
+ BOOST_CHECK((timeout2-timeout_resolution)<boost::chrono::steady_clock::now());
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+ finish_lock.unlock();
+ writer.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_timed_lock_succeeds_if_no_lock_held)
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+
+ boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
+ boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
+ bool timed_lock_succeeded=rw_mutex.try_lock_until(timeout);
+ BOOST_CHECK(boost::chrono::steady_clock::now()<timeout);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+ boost::chrono::milliseconds const wait_duration(500);
+ boost::chrono::steady_clock::time_point const timeout2=boost::chrono::steady_clock::now()+wait_duration;
+ timed_lock_succeeded=rw_mutex.try_lock_for(wait_duration);
+ BOOST_CHECK(boost::chrono::steady_clock::now()<timeout2);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+}
+
+BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_if_read_lock_held)
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+ boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
+ boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
+ boost::chrono::milliseconds const timeout_resolution(50);
+ bool timed_lock_succeeded=rw_mutex.try_lock_until(timeout);
+ BOOST_CHECK((timeout-timeout_resolution)<boost::chrono::steady_clock::now());
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+ boost::chrono::milliseconds const wait_duration(500);
+ boost::chrono::steady_clock::time_point const timeout2=boost::chrono::steady_clock::now()+wait_duration;
+ timed_lock_succeeded=rw_mutex.try_lock_for(wait_duration);
+ BOOST_CHECK((timeout2-timeout_resolution)<boost::chrono::steady_clock::now());
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+ finish_lock.unlock();
+ reader.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held)
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::unique_lock<boost::mutex> finish_lock(finish_mutex);
+ boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ boost::chrono::steady_clock::time_point const start=boost::chrono::steady_clock::now();
+ boost::chrono::steady_clock::time_point const timeout=start+boost::chrono::milliseconds(500);
+ bool timed_lock_succeeded=rw_mutex.try_lock_until(timeout);
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+ boost::chrono::milliseconds const wait_duration(500);
+ timed_lock_succeeded=rw_mutex.try_lock_shared_for(wait_duration);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ finish_lock.unlock();
+ reader.join();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
+
diff --git a/src/boost/libs/thread/test/test_thread.cpp b/src/boost/libs/thread/test/test_thread.cpp
new file mode 100644
index 000000000..ab9ddba0d
--- /dev/null
+++ b/src/boost/libs/thread/test/test_thread.cpp
@@ -0,0 +1,222 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+// Copyright (C) 2008 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/xtime.hpp>
+#include <boost/bind/bind.hpp>
+#include <boost/ref.hpp>
+#include <boost/utility.hpp>
+
+#define BOOST_TEST_MODULE Boost.Threads: thread test suite
+
+#include <boost/test/unit_test.hpp>
+
+#define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_sleep_only
+#include "./util.inl"
+
+int test_value;
+
+void simple_thread()
+{
+ test_value = 999;
+}
+
+void comparison_thread(boost::thread::id parent)
+{
+ boost::thread::id const my_id=boost::this_thread::get_id();
+
+ BOOST_CHECK(my_id != parent);
+ boost::thread::id const my_id2=boost::this_thread::get_id();
+ BOOST_CHECK(my_id == my_id2);
+
+ boost::thread::id const no_thread_id=boost::thread::id();
+ BOOST_CHECK(my_id != no_thread_id);
+}
+
+BOOST_AUTO_TEST_CASE(test_sleep)
+{
+ boost::xtime xt = delay(3);
+ boost::thread::sleep(xt);
+
+ // Ensure it's in a range instead of checking actual equality due to time
+ // lapse
+ BOOST_CHECK(boost::threads::test::in_range(xt, 2));
+}
+
+void do_test_creation()
+{
+ test_value = 0;
+ boost::thread thrd(&simple_thread);
+ thrd.join();
+ BOOST_CHECK_EQUAL(test_value, 999);
+}
+
+BOOST_AUTO_TEST_CASE(test_creation)
+{
+ timed_test(&do_test_creation, 1);
+}
+
+void do_test_id_comparison()
+{
+ boost::thread::id const self=boost::this_thread::get_id();
+ boost::thread thrd(boost::bind(&comparison_thread, self));
+ thrd.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_id_comparison)
+{
+ timed_test(&do_test_id_comparison, 1);
+}
+
+void interruption_point_thread(boost::mutex* m,bool* failed)
+{
+ boost::unique_lock<boost::mutex> lk(*m);
+ boost::this_thread::interruption_point();
+ *failed=true;
+}
+
+void do_test_thread_interrupts_at_interruption_point()
+{
+ boost::mutex m;
+ bool failed=false;
+ boost::unique_lock<boost::mutex> lk(m);
+ boost::thread thrd(boost::bind(&interruption_point_thread,&m,&failed));
+ thrd.interrupt();
+ lk.unlock();
+ thrd.join();
+ BOOST_CHECK(!failed);
+}
+
+BOOST_AUTO_TEST_CASE(test_thread_interrupts_at_interruption_point)
+{
+ timed_test(&do_test_thread_interrupts_at_interruption_point, 1);
+}
+
+void disabled_interruption_point_thread(boost::mutex* m,bool* failed)
+{
+ boost::unique_lock<boost::mutex> lk(*m);
+ boost::this_thread::disable_interruption dc;
+ boost::this_thread::interruption_point();
+ *failed=false;
+}
+
+void do_test_thread_no_interrupt_if_interrupts_disabled_at_interruption_point()
+{
+ boost::mutex m;
+ bool failed=true;
+ boost::unique_lock<boost::mutex> lk(m);
+ boost::thread thrd(boost::bind(&disabled_interruption_point_thread,&m,&failed));
+ thrd.interrupt();
+ lk.unlock();
+ thrd.join();
+ BOOST_CHECK(!failed);
+}
+
+BOOST_AUTO_TEST_CASE(test_thread_no_interrupt_if_interrupts_disabled_at_interruption_point)
+{
+ timed_test(&do_test_thread_no_interrupt_if_interrupts_disabled_at_interruption_point, 1);
+}
+
+struct non_copyable_functor:
+ boost::noncopyable
+{
+ unsigned value;
+
+ non_copyable_functor(): boost::noncopyable(),
+ value(0)
+ {}
+
+ void operator()()
+ {
+ value=999;
+ }
+};
+
+void do_test_creation_through_reference_wrapper()
+{
+ non_copyable_functor f;
+
+ boost::thread thrd(boost::ref(f));
+ thrd.join();
+ BOOST_CHECK_EQUAL(f.value, 999u);
+}
+
+BOOST_AUTO_TEST_CASE(test_creation_through_reference_wrapper)
+{
+ timed_test(&do_test_creation_through_reference_wrapper, 1);
+}
+
+struct long_running_thread
+{
+ boost::condition_variable cond;
+ boost::mutex mut;
+ bool done;
+
+ long_running_thread():
+ done(false)
+ {}
+
+ void operator()()
+ {
+ boost::unique_lock<boost::mutex> lk(mut);
+ while(!done)
+ {
+ cond.wait(lk);
+ }
+ }
+};
+
+void do_test_timed_join()
+{
+ long_running_thread f;
+ boost::thread thrd(boost::ref(f));
+ BOOST_CHECK(thrd.joinable());
+ boost::system_time xt=delay(3);
+ bool const joined=thrd.timed_join(xt);
+ BOOST_CHECK(boost::threads::test::in_range(boost::get_xtime(xt), 2));
+ BOOST_CHECK(!joined);
+ BOOST_CHECK(thrd.joinable());
+ {
+ boost::unique_lock<boost::mutex> lk(f.mut);
+ f.done=true;
+ f.cond.notify_one();
+ }
+
+ xt=delay(3);
+ bool const joined2=thrd.timed_join(xt);
+ boost::system_time const now=boost::get_system_time();
+ BOOST_CHECK(xt>now);
+ BOOST_CHECK(joined2);
+ BOOST_CHECK(!thrd.joinable());
+}
+
+BOOST_AUTO_TEST_CASE(test_timed_join)
+{
+ timed_test(&do_test_timed_join, 10);
+}
+
+BOOST_AUTO_TEST_CASE(test_swap)
+{
+ boost::thread t(&simple_thread);
+ boost::thread t2(&simple_thread);
+ boost::thread::id id1=t.get_id();
+ boost::thread::id id2=t2.get_id();
+
+ t.swap(t2);
+ BOOST_CHECK(t.get_id()==id2);
+ BOOST_CHECK(t2.get_id()==id1);
+
+ swap(t,t2);
+ BOOST_CHECK(t.get_id()==id1);
+ BOOST_CHECK(t2.get_id()==id2);
+}
+
diff --git a/src/boost/libs/thread/test/test_thread_exit.cpp b/src/boost/libs/thread/test/test_thread_exit.cpp
new file mode 100644
index 000000000..577bcd05d
--- /dev/null
+++ b/src/boost/libs/thread/test/test_thread_exit.cpp
@@ -0,0 +1,63 @@
+// (C) Copyright 2009 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/future.hpp>
+#include <utility>
+#include <memory>
+#include <string>
+
+#define BOOST_TEST_MODULE Boost.Threads: thread exit test suite
+
+#include <boost/test/unit_test.hpp>
+
+boost::thread::id exit_func_thread_id;
+
+void exit_func()
+{
+ exit_func_thread_id=boost::this_thread::get_id();
+}
+
+void tf1()
+{
+ boost::this_thread::at_thread_exit(exit_func);
+ BOOST_CHECK(exit_func_thread_id!=boost::this_thread::get_id());
+}
+
+BOOST_AUTO_TEST_CASE(test_thread_exit_func_runs_when_thread_exits)
+{
+ exit_func_thread_id=boost::thread::id();
+ boost::thread t(&tf1);
+ boost::thread::id const t_id=t.get_id();
+ t.join();
+ BOOST_CHECK(exit_func_thread_id==t_id);
+}
+
+struct fo
+{
+ void operator()()
+ {
+ exit_func_thread_id=boost::this_thread::get_id();
+ }
+};
+
+void tf2()
+{
+ boost::this_thread::at_thread_exit(fo());
+ BOOST_CHECK(exit_func_thread_id!=boost::this_thread::get_id());
+}
+
+
+BOOST_AUTO_TEST_CASE(test_can_use_function_object_for_exit_func)
+{
+ exit_func_thread_id=boost::thread::id();
+ boost::thread t(tf2);
+ boost::thread::id const t_id=t.get_id();
+ t.join();
+ BOOST_CHECK(exit_func_thread_id==t_id);
+}
diff --git a/src/boost/libs/thread/test/test_thread_id.cpp b/src/boost/libs/thread/test/test_thread_id.cpp
new file mode 100644
index 000000000..477909d1a
--- /dev/null
+++ b/src/boost/libs/thread/test/test_thread_id.cpp
@@ -0,0 +1,139 @@
+// Copyright (C) 2007 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_TEST_MODULE Boost.Threads: thread::get_id test suite
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/bind/bind.hpp>
+
+void do_nothing()
+{}
+
+BOOST_AUTO_TEST_CASE(test_thread_id_for_default_constructed_thread_is_default_constructed_id)
+{
+ boost::thread t;
+ BOOST_CHECK(t.get_id()==boost::thread::id());
+}
+
+BOOST_AUTO_TEST_CASE(test_thread_id_for_running_thread_is_not_default_constructed_id)
+{
+ boost::thread t(&do_nothing);
+ BOOST_CHECK(t.get_id()!=boost::thread::id());
+ t.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_different_threads_have_different_ids)
+{
+ boost::thread t(do_nothing);
+ boost::thread t2(do_nothing);
+ BOOST_CHECK(t.get_id()!=t2.get_id());
+ t.join();
+ t2.join();
+}
+
+BOOST_AUTO_TEST_CASE(test_thread_ids_have_a_total_order)
+{
+ boost::thread t(do_nothing);
+ boost::thread t2(do_nothing);
+ boost::thread t3(do_nothing);
+ BOOST_CHECK(t.get_id()!=t2.get_id());
+ BOOST_CHECK(t.get_id()!=t3.get_id());
+ BOOST_CHECK(t2.get_id()!=t3.get_id());
+
+ BOOST_CHECK((t.get_id()<t2.get_id()) != (t2.get_id()<t.get_id()));
+ BOOST_CHECK((t.get_id()<t3.get_id()) != (t3.get_id()<t.get_id()));
+ BOOST_CHECK((t2.get_id()<t3.get_id()) != (t3.get_id()<t2.get_id()));
+
+ BOOST_CHECK((t.get_id()>t2.get_id()) != (t2.get_id()>t.get_id()));
+ BOOST_CHECK((t.get_id()>t3.get_id()) != (t3.get_id()>t.get_id()));
+ BOOST_CHECK((t2.get_id()>t3.get_id()) != (t3.get_id()>t2.get_id()));
+
+ BOOST_CHECK((t.get_id()<t2.get_id()) == (t2.get_id()>t.get_id()));
+ BOOST_CHECK((t2.get_id()<t.get_id()) == (t.get_id()>t2.get_id()));
+ BOOST_CHECK((t.get_id()<t3.get_id()) == (t3.get_id()>t.get_id()));
+ BOOST_CHECK((t3.get_id()<t.get_id()) == (t.get_id()>t3.get_id()));
+ BOOST_CHECK((t2.get_id()<t3.get_id()) == (t3.get_id()>t2.get_id()));
+ BOOST_CHECK((t3.get_id()<t2.get_id()) == (t2.get_id()>t3.get_id()));
+
+ BOOST_CHECK((t.get_id()<t2.get_id()) == (t2.get_id()>=t.get_id()));
+ BOOST_CHECK((t2.get_id()<t.get_id()) == (t.get_id()>=t2.get_id()));
+ BOOST_CHECK((t.get_id()<t3.get_id()) == (t3.get_id()>=t.get_id()));
+ BOOST_CHECK((t3.get_id()<t.get_id()) == (t.get_id()>=t3.get_id()));
+ BOOST_CHECK((t2.get_id()<t3.get_id()) == (t3.get_id()>=t2.get_id()));
+ BOOST_CHECK((t3.get_id()<t2.get_id()) == (t2.get_id()>=t3.get_id()));
+
+ BOOST_CHECK((t.get_id()<=t2.get_id()) == (t2.get_id()>t.get_id()));
+ BOOST_CHECK((t2.get_id()<=t.get_id()) == (t.get_id()>t2.get_id()));
+ BOOST_CHECK((t.get_id()<=t3.get_id()) == (t3.get_id()>t.get_id()));
+ BOOST_CHECK((t3.get_id()<=t.get_id()) == (t.get_id()>t3.get_id()));
+ BOOST_CHECK((t2.get_id()<=t3.get_id()) == (t3.get_id()>t2.get_id()));
+ BOOST_CHECK((t3.get_id()<=t2.get_id()) == (t2.get_id()>t3.get_id()));
+
+ if((t.get_id()<t2.get_id()) && (t2.get_id()<t3.get_id()))
+ {
+ BOOST_CHECK(t.get_id()<t3.get_id());
+ }
+ else if((t.get_id()<t3.get_id()) && (t3.get_id()<t2.get_id()))
+ {
+ BOOST_CHECK(t.get_id()<t2.get_id());
+ }
+ else if((t2.get_id()<t3.get_id()) && (t3.get_id()<t.get_id()))
+ {
+ BOOST_CHECK(t2.get_id()<t.get_id());
+ }
+ else if((t2.get_id()<t.get_id()) && (t.get_id()<t3.get_id()))
+ {
+ BOOST_CHECK(t2.get_id()<t3.get_id());
+ }
+ else if((t3.get_id()<t.get_id()) && (t.get_id()<t2.get_id()))
+ {
+ BOOST_CHECK(t3.get_id()<t2.get_id());
+ }
+ else if((t3.get_id()<t2.get_id()) && (t2.get_id()<t.get_id()))
+ {
+ BOOST_CHECK(t3.get_id()<t.get_id());
+ }
+ else
+ {
+ BOOST_CHECK(false);
+ }
+
+ boost::thread::id default_id;
+
+ BOOST_CHECK(default_id < t.get_id());
+ BOOST_CHECK(default_id < t2.get_id());
+ BOOST_CHECK(default_id < t3.get_id());
+
+ BOOST_CHECK(default_id <= t.get_id());
+ BOOST_CHECK(default_id <= t2.get_id());
+ BOOST_CHECK(default_id <= t3.get_id());
+
+ BOOST_CHECK(!(default_id > t.get_id()));
+ BOOST_CHECK(!(default_id > t2.get_id()));
+ BOOST_CHECK(!(default_id > t3.get_id()));
+
+ BOOST_CHECK(!(default_id >= t.get_id()));
+ BOOST_CHECK(!(default_id >= t2.get_id()));
+ BOOST_CHECK(!(default_id >= t3.get_id()));
+
+ t.join();
+ t2.join();
+ t3.join();
+}
+
+void get_thread_id(boost::thread::id* id)
+{
+ *id=boost::this_thread::get_id();
+}
+
+BOOST_AUTO_TEST_CASE(test_thread_id_of_running_thread_returned_by_this_thread_get_id)
+{
+ boost::thread::id id;
+ boost::thread t(boost::bind(get_thread_id,&id));
+ boost::thread::id t_id=t.get_id();
+ t.join();
+ BOOST_CHECK(id==t_id);
+}
diff --git a/src/boost/libs/thread/test/test_thread_launching.cpp b/src/boost/libs/thread/test/test_thread_launching.cpp
new file mode 100644
index 000000000..0c74871d3
--- /dev/null
+++ b/src/boost/libs/thread/test/test_thread_launching.cpp
@@ -0,0 +1,216 @@
+// Copyright (C) 2007-8 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 3
+#define BOOST_TEST_MODULE Boost.Threads: thread launching test suite
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/test/unit_test.hpp>
+#include <boost/ref.hpp>
+#include <boost/utility.hpp>
+#include <string>
+#include <vector>
+
+bool normal_function_called=false;
+
+void normal_function()
+{
+ normal_function_called=true;
+}
+
+BOOST_AUTO_TEST_CASE(test_thread_function_no_arguments)
+{
+ boost::thread function(&normal_function);
+ function.join();
+ BOOST_CHECK(normal_function_called);
+}
+
+int nfoa_res=0;
+
+void normal_function_one_arg(int i)
+{
+ nfoa_res=i;
+}
+
+BOOST_AUTO_TEST_CASE(test_thread_function_one_argument)
+{
+ boost::thread function(&normal_function_one_arg,42);
+ function.join();
+ BOOST_CHECK_EQUAL(42,nfoa_res);
+}
+
+struct callable_no_args
+{
+ static bool called;
+
+ void operator()() const
+ {
+ called=true;
+ }
+};
+
+bool callable_no_args::called=false;
+
+BOOST_AUTO_TEST_CASE(test_thread_callable_object_no_arguments)
+{
+ callable_no_args func;
+ boost::thread callable(func);
+ callable.join();
+ BOOST_CHECK(callable_no_args::called);
+}
+
+struct callable_noncopyable_no_args:
+ boost::noncopyable
+{
+ callable_noncopyable_no_args() : boost::noncopyable() {}
+ static bool called;
+
+ void operator()() const
+ {
+ called=true;
+ }
+};
+
+bool callable_noncopyable_no_args::called=false;
+
+BOOST_AUTO_TEST_CASE(test_thread_callable_object_ref_no_arguments)
+{
+ callable_noncopyable_no_args func;
+
+ boost::thread callable(boost::ref(func));
+ callable.join();
+ BOOST_CHECK(callable_noncopyable_no_args::called);
+}
+
+struct callable_one_arg
+{
+ static bool called;
+ static int called_arg;
+
+ void operator()(int arg) const
+ {
+ called=true;
+ called_arg=arg;
+ }
+};
+
+bool callable_one_arg::called=false;
+int callable_one_arg::called_arg=0;
+
+BOOST_AUTO_TEST_CASE(test_thread_callable_object_one_argument)
+{
+ callable_one_arg func;
+ boost::thread callable(func,42);
+ callable.join();
+ BOOST_CHECK(callable_one_arg::called);
+ BOOST_CHECK_EQUAL(callable_one_arg::called_arg,42);
+}
+
+struct callable_multiple_arg
+{
+ static bool called_two;
+ static int called_two_arg1;
+ static double called_two_arg2;
+ static bool called_three;
+ static std::string called_three_arg1;
+ static std::vector<int> called_three_arg2;
+ static int called_three_arg3;
+
+ void operator()(int arg1,double arg2) const
+ {
+ called_two=true;
+ called_two_arg1=arg1;
+ called_two_arg2=arg2;
+ }
+ void operator()(std::string const& arg1,std::vector<int> const& arg2,int arg3) const
+ {
+ called_three=true;
+ called_three_arg1=arg1;
+ called_three_arg2=arg2;
+ called_three_arg3=arg3;
+ }
+};
+
+bool callable_multiple_arg::called_two=false;
+bool callable_multiple_arg::called_three=false;
+int callable_multiple_arg::called_two_arg1;
+double callable_multiple_arg::called_two_arg2;
+std::string callable_multiple_arg::called_three_arg1;
+std::vector<int> callable_multiple_arg::called_three_arg2;
+int callable_multiple_arg::called_three_arg3;
+
+BOOST_AUTO_TEST_CASE(test_thread_callable_object_multiple_arguments)
+{
+ std::vector<int> x;
+ for(unsigned i=0;i<7;++i)
+ {
+ x.push_back(i*i);
+ }
+
+ callable_multiple_arg func;
+ // Avoid
+ // boost/bind/bind.hpp(392) : warning C4244: 'argument' : conversion from 'double' to 'int', possible loss of data
+
+ boost::thread callable3(func,"hello",x,1);
+ callable3.join();
+ BOOST_CHECK(callable_multiple_arg::called_three);
+ BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg1,"hello");
+ BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg2.size(),x.size());
+ for(unsigned j=0;j<x.size();++j)
+ {
+ BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg2.at(j),x[j]);
+ }
+
+ BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg3,1);
+
+ double const dbl=1.234;
+
+ boost::thread callable2(func,19,dbl);
+ callable2.join();
+ BOOST_CHECK(callable_multiple_arg::called_two);
+ BOOST_CHECK_EQUAL(callable_multiple_arg::called_two_arg1,19);
+ BOOST_CHECK_EQUAL(callable_multiple_arg::called_two_arg2,dbl);
+}
+
+struct X
+{
+ bool function_called;
+ int arg_value;
+
+ X():
+ function_called(false),
+ arg_value(0)
+ {}
+
+
+ void f0()
+ {
+ function_called=true;
+ }
+
+ void f1(int i)
+ {
+ arg_value=i;
+ }
+
+};
+
+BOOST_AUTO_TEST_CASE(test_thread_member_function_no_arguments)
+{
+ X x;
+
+ boost::thread function(&X::f0,&x);
+ function.join();
+ BOOST_CHECK(x.function_called);
+}
+
+
+BOOST_AUTO_TEST_CASE(test_thread_member_function_one_argument)
+{
+ X x;
+ boost::thread function(&X::f1,&x,42);
+ function.join();
+ BOOST_CHECK_EQUAL(42,x.arg_value);
+}
diff --git a/src/boost/libs/thread/test/test_thread_mf.cpp b/src/boost/libs/thread/test/test_thread_mf.cpp
new file mode 100644
index 000000000..843008fa7
--- /dev/null
+++ b/src/boost/libs/thread/test/test_thread_mf.cpp
@@ -0,0 +1,135 @@
+//
+// Copyright (C) 2008 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+//
+#define BOOST_THREAD_VERSION 3
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct X
+{
+ mutable unsigned int hash;
+
+ X(): hash(0) {}
+
+ int f0() { f1(17); return 0; }
+ int g0() const { g1(17); return 0; }
+
+ int f1(int a1) { hash = (hash * 17041 + a1) % 32768; return 0; }
+ int g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; return 0; }
+
+ int f2(int a1, int a2) { f1(a1); f1(a2); return 0; }
+ int g2(int a1, int a2) const { g1(a1); g1(a2); return 0; }
+
+ int f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); return 0; }
+ int g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); return 0; }
+
+ int f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); return 0; }
+ int g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); return 0; }
+
+ int f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); return 0; }
+ int g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); return 0; }
+
+ int f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); return 0; }
+ int g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); return 0; }
+
+ int f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); return 0; }
+ int g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); return 0; }
+
+ int f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); return 0; }
+ int g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); return 0; }
+};
+
+int main()
+{
+ X x;
+
+ // 0
+
+ boost::thread( &X::f0, &x ).join();
+ boost::thread( &X::f0, boost::ref(x) ).join();
+
+ boost::thread( &X::g0, &x ).join();
+ boost::thread( &X::g0, x ).join();
+ boost::thread( &X::g0, boost::ref(x) ).join();
+
+ // 1
+
+ boost::thread( &X::f1, &x, 1 ).join();
+ boost::thread( &X::f1, boost::ref(x), 1 ).join();
+
+ boost::thread( &X::g1, &x, 1 ).join();
+ boost::thread( &X::g1, x, 1 ).join();
+ boost::thread( &X::g1, boost::ref(x), 1 ).join();
+
+ // 2
+
+ boost::thread( &X::f2, &x, 1, 2 ).join();
+ boost::thread( &X::f2, boost::ref(x), 1, 2 ).join();
+
+ boost::thread( &X::g2, &x, 1, 2 ).join();
+ boost::thread( &X::g2, x, 1, 2 ).join();
+ boost::thread( &X::g2, boost::ref(x), 1, 2 ).join();
+
+ // 3
+
+ boost::thread( &X::f3, &x, 1, 2, 3 ).join();
+ boost::thread( &X::f3, boost::ref(x), 1, 2, 3 ).join();
+
+ boost::thread( &X::g3, &x, 1, 2, 3 ).join();
+ boost::thread( &X::g3, x, 1, 2, 3 ).join();
+ boost::thread( &X::g3, boost::ref(x), 1, 2, 3 ).join();
+
+ // 4
+
+ boost::thread( &X::f4, &x, 1, 2, 3, 4 ).join();
+ boost::thread( &X::f4, boost::ref(x), 1, 2, 3, 4 ).join();
+
+ boost::thread( &X::g4, &x, 1, 2, 3, 4 ).join();
+ boost::thread( &X::g4, x, 1, 2, 3, 4 ).join();
+ boost::thread( &X::g4, boost::ref(x), 1, 2, 3, 4 ).join();
+
+ // 5
+
+ boost::thread( &X::f5, &x, 1, 2, 3, 4, 5 ).join();
+ boost::thread( &X::f5, boost::ref(x), 1, 2, 3, 4, 5 ).join();
+
+ boost::thread( &X::g5, &x, 1, 2, 3, 4, 5 ).join();
+ boost::thread( &X::g5, x, 1, 2, 3, 4, 5 ).join();
+ boost::thread( &X::g5, boost::ref(x), 1, 2, 3, 4, 5 ).join();
+
+ // 6
+
+ boost::thread( &X::f6, &x, 1, 2, 3, 4, 5, 6 ).join();
+ boost::thread( &X::f6, boost::ref(x), 1, 2, 3, 4, 5, 6 ).join();
+
+ boost::thread( &X::g6, &x, 1, 2, 3, 4, 5, 6 ).join();
+ boost::thread( &X::g6, x, 1, 2, 3, 4, 5, 6 ).join();
+ boost::thread( &X::g6, boost::ref(x), 1, 2, 3, 4, 5, 6 ).join();
+
+ // 7
+
+ boost::thread( &X::f7, &x, 1, 2, 3, 4, 5, 6, 7).join();
+ boost::thread( &X::f7, boost::ref(x), 1, 2, 3, 4, 5, 6, 7).join();
+
+ boost::thread( &X::g7, &x, 1, 2, 3, 4, 5, 6, 7).join();
+ boost::thread( &X::g7, x, 1, 2, 3, 4, 5, 6, 7).join();
+ boost::thread( &X::g7, boost::ref(x), 1, 2, 3, 4, 5, 6, 7).join();
+
+ // 8
+
+ boost::thread( &X::f8, &x, 1, 2, 3, 4, 5, 6, 7, 8 ).join();
+ boost::thread( &X::f8, boost::ref(x), 1, 2, 3, 4, 5, 6, 7, 8 ).join();
+
+ boost::thread( &X::g8, &x, 1, 2, 3, 4, 5, 6, 7, 8 ).join();
+ boost::thread( &X::g8, x, 1, 2, 3, 4, 5, 6, 7, 8 ).join();
+ boost::thread( &X::g8, boost::ref(x), 1, 2, 3, 4, 5, 6, 7, 8 ).join();
+
+ BOOST_TEST( x.hash == 23558 );
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/test_thread_move.cpp b/src/boost/libs/thread/test/test_thread_move.cpp
new file mode 100644
index 000000000..e86db8cad
--- /dev/null
+++ b/src/boost/libs/thread/test/test_thread_move.cpp
@@ -0,0 +1,50 @@
+// Copyright (C) 2007-9 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_TEST_MODULE Boost.Threads: thread move test suite
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/test/unit_test.hpp>
+
+void do_nothing(boost::thread::id* my_id)
+{
+ *my_id=boost::this_thread::get_id();
+}
+
+BOOST_AUTO_TEST_CASE(test_move_on_construction)
+{
+ boost::thread::id the_id;
+ boost::thread x=boost::thread(do_nothing,&the_id);
+ boost::thread::id x_id=x.get_id();
+ x.join();
+ BOOST_CHECK_EQUAL(the_id,x_id);
+}
+
+boost::thread make_thread(boost::thread::id* the_id)
+{
+ return boost::thread(do_nothing,the_id);
+}
+
+BOOST_AUTO_TEST_CASE(test_move_from_function_return)
+{
+ boost::thread::id the_id;
+ boost::thread x=make_thread(&the_id);
+ boost::thread::id x_id=x.get_id();
+ x.join();
+ BOOST_CHECK_EQUAL(the_id,x_id);
+}
+
+BOOST_AUTO_TEST_CASE(test_move_assign)
+{
+ boost::thread::id the_id;
+ boost::thread x(do_nothing,&the_id);
+ boost::thread y;
+ y=boost::move(x);
+ boost::thread::id y_id=y.get_id();
+ y.join();
+ BOOST_CHECK_EQUAL(the_id,y_id);
+}
+
+
diff --git a/src/boost/libs/thread/test/test_thread_move_return.cpp b/src/boost/libs/thread/test/test_thread_move_return.cpp
new file mode 100644
index 000000000..f714fb0a5
--- /dev/null
+++ b/src/boost/libs/thread/test/test_thread_move_return.cpp
@@ -0,0 +1,31 @@
+// Copyright (C) 2009 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_USES_MOVE
+#define BOOST_TEST_MODULE Boost.Threads: thread move return test suite
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/test/unit_test.hpp>
+
+void do_nothing(boost::thread::id* my_id)
+{
+ *my_id=boost::this_thread::get_id();
+}
+
+boost::thread make_thread_move_return(boost::thread::id* the_id)
+{
+ boost::thread t(do_nothing,the_id);
+ return boost::move(t);
+}
+
+BOOST_AUTO_TEST_CASE(test_move_from_function_move_return)
+{
+ boost::thread::id the_id;
+ boost::thread x=make_thread_move_return(&the_id);
+ boost::thread::id x_id=x.get_id();
+ x.join();
+ BOOST_CHECK_EQUAL(the_id,x_id);
+}
+
diff --git a/src/boost/libs/thread/test/test_thread_return_local.cpp b/src/boost/libs/thread/test/test_thread_return_local.cpp
new file mode 100644
index 000000000..6ffd1083a
--- /dev/null
+++ b/src/boost/libs/thread/test/test_thread_return_local.cpp
@@ -0,0 +1,31 @@
+// Copyright (C) 2009 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_USES_MOVE
+
+#define BOOST_TEST_MODULE Boost.Threads: thread return local test suite
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/test/unit_test.hpp>
+
+void do_nothing(boost::thread::id* my_id)
+{
+ *my_id=boost::this_thread::get_id();
+}
+
+boost::thread make_thread_return_local(boost::thread::id* the_id)
+{
+ boost::thread t(do_nothing,the_id);
+ return boost::move(t);
+}
+
+BOOST_AUTO_TEST_CASE(test_move_from_function_return_local)
+{
+ boost::thread::id the_id;
+ boost::thread x=make_thread_return_local(&the_id);
+ boost::thread::id x_id=x.get_id();
+ x.join();
+ BOOST_CHECK_EQUAL(the_id,x_id);
+}
diff --git a/src/boost/libs/thread/test/test_time_jumps.cpp b/src/boost/libs/thread/test/test_time_jumps.cpp
new file mode 100644
index 000000000..706bafa47
--- /dev/null
+++ b/src/boost/libs/thread/test/test_time_jumps.cpp
@@ -0,0 +1,2398 @@
+#ifdef _WIN32
+ #include <windows.h>
+#else
+ #include <sys/time.h>
+#endif
+
+#include "boost/bind/bind.hpp"
+#include "boost/chrono.hpp"
+#include "boost/chrono/ceil.hpp"
+#include "boost/date_time.hpp"
+#include "boost/thread/concurrent_queues/sync_priority_queue.hpp"
+#include "boost/thread/concurrent_queues/sync_timed_queue.hpp"
+#include "boost/thread/future.hpp"
+#include "boost/thread/mutex.hpp"
+#include "boost/thread/recursive_mutex.hpp"
+#include "boost/thread/shared_lock_guard.hpp"
+#include "boost/thread/shared_mutex.hpp"
+#include "boost/thread/thread.hpp"
+
+#include <iomanip>
+#ifdef TEST_CPP14_FEATURES
+#include <future>
+#include <mutex>
+#include <shared_mutex>
+#include <thread>
+#endif
+
+/******************************************************************************/
+
+/*
+ * Summary:
+ *
+ * This code tests the behavior of time-related functions in the presence of
+ * system clock changes (jumps). It requires root/Administrator privileges in
+ * order to run because it changes the system clock. NTP should also be disabled
+ * while running this code so that NTP can't change the system clock.
+ *
+ * Each function to be tested is executed five times. The amount of time the
+ * function waits before returning is measured against the amount of time the
+ * function was expected to wait. If the difference exceeds a threshold value
+ * (defined below) then the test fails.
+ *
+ * The following values are intentially:
+ * - more than 200 milliseconds
+ * - more than 200 milliseconds apart
+ * - not a multiple of 100 milliseconds
+ * - not a multiple of each other
+ * - don't sum or diff to a multiple of 100 milliseconds
+ */
+const long long s_waitMs = 580;
+const long long s_shortJumpMs = 230;
+const long long s_longJumpMs = 870; // Causes additional, unavoidable failures when BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC is disabled
+const long long s_sleepBeforeJumpMs = 110;
+
+#ifdef _WIN32
+const long long s_maxEarlyErrorMs = 10
+ + 100; // Windows is unpredictable, especially in a VM, so allow extra time if the function returns early
+const long long s_maxLateErrorMs = 110 // due to polling, functions may not return for up to 100 milliseconds after they are supposed to
+ + 100; // Windows is slow, especially in a VM, so allow extra time for the functions to return
+#else
+const long long s_maxEarlyErrorMs = 10;
+const long long s_maxLateErrorMs = 110; // Due to polling, functions may not return for up to 100 milliseconds after they are supposed to
+#endif
+
+int g_numTestsRun = 0;
+int g_numTestsPassed = 0;
+int g_numTestsFailed = 0;
+
+/******************************************************************************/
+
+// A custom clock based off the system clock but with a different epoch.
+
+namespace custom
+{
+ class custom_boost_clock
+ {
+ public:
+ typedef boost::chrono::microseconds duration; // intentionally not nanoseconds
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef boost::chrono::time_point<custom_boost_clock> time_point;
+ static bool is_steady;
+
+ static time_point now();
+ };
+
+ bool custom_boost_clock::is_steady = false;
+
+ custom_boost_clock::time_point custom_boost_clock::now()
+ {
+ return time_point(boost::chrono::ceil<duration>(boost::chrono::system_clock::now().time_since_epoch()) - boost::chrono::hours(10 * 365 * 24));
+ }
+
+#ifdef TEST_CPP14_FEATURES
+ class custom_std_clock
+ {
+ public:
+ typedef std::chrono::microseconds duration; // intentionally not nanoseconds
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef std::chrono::time_point<custom_std_clock> time_point;
+ static bool is_steady;
+
+ static time_point now();
+ };
+
+ bool custom_std_clock::is_steady = false;
+
+ custom_std_clock::time_point custom_std_clock::now()
+ {
+ return time_point(std::chrono::duration_cast<duration>(std::chrono::system_clock::now().time_since_epoch()) - std::chrono::hours(10 * 365 * 24));
+ }
+#endif
+}
+
+/******************************************************************************/
+
+template <typename MutexType = boost::mutex, typename CondType = boost::condition_variable>
+struct BoostHelper
+{
+ typedef MutexType mutex;
+ typedef CondType cond;
+
+ typedef boost::lock_guard<MutexType> lock_guard;
+ typedef boost::unique_lock<MutexType> unique_lock;
+
+ typedef boost::chrono::milliseconds milliseconds;
+ typedef boost::chrono::nanoseconds nanoseconds;
+
+ typedef boost::chrono::system_clock system_clock;
+ typedef boost::chrono::steady_clock steady_clock;
+ typedef custom::custom_boost_clock custom_clock;
+
+ typedef system_clock::time_point system_time_point;
+ typedef steady_clock::time_point steady_time_point;
+ typedef custom_clock::time_point custom_time_point;
+
+ typedef boost::cv_status cv_status;
+ typedef boost::future_status future_status;
+
+ typedef boost::packaged_task<bool> packaged_task;
+ typedef boost::future<bool> future;
+ typedef boost::shared_future<bool> shared_future;
+
+ typedef boost::thread thread;
+
+ static const milliseconds waitDur;
+
+ template <typename T>
+ static void sleep_for(T d)
+ {
+ boost::this_thread::sleep_for(d);
+ }
+
+ template <typename T>
+ static void sleep_for_no_int(T d)
+ {
+ boost::this_thread::no_interruption_point::sleep_for(d);
+ }
+
+ template <typename T>
+ static void sleep_until(T t)
+ {
+ boost::this_thread::sleep_until(t);
+ }
+
+ template <typename T>
+ static void sleep_until_no_int(T t)
+ {
+ boost::this_thread::no_interruption_point::sleep_until(t);
+ }
+
+ static system_time_point systemNow()
+ {
+ return system_clock::now();
+ }
+
+ static steady_time_point steadyNow()
+ {
+ return steady_clock::now();
+ }
+
+ static custom_time_point customNow()
+ {
+ return custom_clock::now();
+ }
+
+ template <class ToDuration, class Rep, class Period>
+ static ToDuration duration_cast(const boost::chrono::duration<Rep, Period>& d)
+ {
+ return boost::chrono::duration_cast<ToDuration>(d);
+ }
+
+ static milliseconds zero()
+ {
+ return milliseconds(0);
+ }
+};
+
+template <typename MutexType, typename CondType>
+const typename BoostHelper<MutexType, CondType>::milliseconds
+BoostHelper<MutexType, CondType>::waitDur = typename BoostHelper<MutexType, CondType>::milliseconds(s_waitMs);
+
+#ifdef TEST_CPP14_FEATURES
+template <typename MutexType = std::mutex, typename CondType = std::condition_variable>
+struct StdHelper
+{
+ typedef MutexType mutex;
+ typedef CondType cond;
+
+ typedef std::lock_guard<MutexType> lock_guard;
+ typedef std::unique_lock<MutexType> unique_lock;
+
+ typedef std::chrono::milliseconds milliseconds;
+ typedef std::chrono::nanoseconds nanoseconds;
+
+ typedef std::chrono::system_clock system_clock;
+ typedef std::chrono::steady_clock steady_clock;
+ typedef custom::custom_std_clock custom_clock;
+
+ typedef system_clock::time_point system_time_point;
+ typedef steady_clock::time_point steady_time_point;
+ typedef custom_clock::time_point custom_time_point;
+
+ typedef std::cv_status cv_status;
+ typedef std::future_status future_status;
+
+ typedef std::packaged_task<bool()> packaged_task;
+ typedef std::future<bool> future;
+ typedef std::shared_future<bool> shared_future;
+
+ typedef std::thread thread;
+
+ static const milliseconds waitDur;
+
+ template <typename T>
+ static void sleep_for(T d)
+ {
+ std::this_thread::sleep_for(d);
+ }
+
+ template <typename T>
+ static void sleep_until(T t)
+ {
+ std::this_thread::sleep_until(t);
+ }
+
+ static system_time_point systemNow()
+ {
+ return system_clock::now();
+ }
+
+ static steady_time_point steadyNow()
+ {
+ return steady_clock::now();
+ }
+
+ static custom_time_point customNow()
+ {
+ return custom_clock::now();
+ }
+
+ template <class ToDuration, class Rep, class Period>
+ static ToDuration duration_cast(const std::chrono::duration<Rep, Period>& d)
+ {
+ return std::chrono::duration_cast<ToDuration>(d);
+ }
+
+ static milliseconds zero()
+ {
+ return milliseconds(0);
+ }
+};
+
+template <typename MutexType, typename CondType>
+const typename StdHelper<MutexType, CondType>::milliseconds
+StdHelper<MutexType, CondType>::waitDur = typename StdHelper<MutexType, CondType>::milliseconds(s_waitMs);
+#endif
+
+/******************************************************************************/
+
+#ifdef _WIN32
+
+void changeSystemTime(long long changeMs)
+{
+ Sleep(s_sleepBeforeJumpMs);
+
+ SYSTEMTIME systemTime;
+ GetSystemTime(&systemTime);
+
+ FILETIME fileTime;
+ if (!SystemTimeToFileTime(&systemTime, &fileTime))
+ {
+ std::cout << "ERROR: Couldn't convert system time to file time" << std::endl;
+ }
+
+ ULARGE_INTEGER largeInt;
+ largeInt.LowPart = fileTime.dwLowDateTime;
+ largeInt.HighPart = fileTime.dwHighDateTime;
+ largeInt.QuadPart += changeMs * 10000;
+ fileTime.dwLowDateTime = largeInt.LowPart;
+ fileTime.dwHighDateTime = largeInt.HighPart;
+
+ if (!FileTimeToSystemTime(&fileTime, &systemTime))
+ {
+ std::cout << "ERROR: Couldn't convert file time to system time" << std::endl;
+ }
+
+ if (!SetSystemTime(&systemTime))
+ {
+ std::cout << "ERROR: Couldn't set system time" << std::endl;
+ }
+}
+
+#else
+
+void changeSystemTime(long long changeMs)
+{
+ struct timespec sleepTs;
+ sleepTs.tv_sec = (s_sleepBeforeJumpMs / 1000);
+ sleepTs.tv_nsec = (s_sleepBeforeJumpMs % 1000) * 1000000;
+ nanosleep(&sleepTs, NULL);
+
+ struct timeval tv;
+ if (gettimeofday(&tv, NULL) != 0)
+ {
+ std::cout << "ERROR: Couldn't get system time" << std::endl;
+ }
+
+ changeMs += tv.tv_sec * 1000;
+ changeMs += tv.tv_usec / 1000;
+ tv.tv_sec = (changeMs / 1000);
+ tv.tv_usec = (changeMs % 1000) * 1000;
+
+ if (settimeofday(&tv, NULL) != 0)
+ {
+ std::cout << "ERROR: Couldn't set system time" << std::endl;
+ }
+}
+
+#endif
+
+enum RcEnum
+{
+ e_no_timeout,
+ e_timeout,
+ e_failed_bad,
+ e_failed_good,
+ e_succeeded_bad,
+ e_succeeded_good,
+ e_ready_bad,
+ e_not_ready_good,
+ e_na
+};
+
+template <typename Helper>
+void checkWaitTime(typename Helper::nanoseconds expected, typename Helper::nanoseconds actual, RcEnum rc)
+{
+ if (expected != Helper::zero() && expected < typename Helper::milliseconds(s_sleepBeforeJumpMs))
+ {
+ expected = typename Helper::milliseconds(s_sleepBeforeJumpMs);
+ }
+
+ typename Helper::milliseconds expectedMs = Helper::template duration_cast<typename Helper::milliseconds>(expected);
+ typename Helper::milliseconds actualMs = Helper::template duration_cast<typename Helper::milliseconds>(actual);
+
+ std::cout << "Expected: " << std::setw(4) << expectedMs.count() << " ms"
+ << ", Actual: " << std::setw(4) << actualMs.count() << " ms"
+ << ", Returned: ";
+ switch (rc)
+ {
+ case e_no_timeout : std::cout << "no_timeout, "; break;
+ case e_timeout : std::cout << "timeout, "; break;
+ case e_failed_bad : std::cout << "failed, "; break;
+ case e_failed_good : std::cout << "failed, "; break;
+ case e_succeeded_bad : std::cout << "succeeded, "; break;
+ case e_succeeded_good : std::cout << "succeeded, "; break;
+ case e_ready_bad : std::cout << "ready, "; break;
+ case e_not_ready_good : std::cout << "not_ready, "; break;
+ default : std::cout << "N/A, "; break;
+ }
+
+ if (expectedMs == Helper::zero())
+ {
+ std::cout << "FAILED: SKIPPED (test would lock up if run)";
+ g_numTestsFailed++;
+ }
+ else if (actual < expected - typename Helper::milliseconds(s_maxEarlyErrorMs))
+ {
+ std::cout << "FAILED: TOO SHORT";
+ if (rc == e_timeout) // bad
+ {
+ std::cout << ", RETURNED TIMEOUT";
+ }
+ else if (rc == e_failed_bad)
+ {
+ std::cout << ", RETURNED FAILED";
+ }
+ else if (rc == e_succeeded_bad)
+ {
+ std::cout << ", RETURNED SUCCEEDED";
+ }
+ else if (rc == e_ready_bad)
+ {
+ std::cout << ", RETURNED READY";
+ }
+ g_numTestsFailed++;
+ }
+ else if (actual > expected + typename Helper::milliseconds(s_maxLateErrorMs))
+ {
+ std::cout << "FAILED: TOO LONG";
+ if (rc == e_no_timeout) // bad
+ {
+ std::cout << ", RETURNED NO_TIMEOUT";
+ }
+ else if (rc == e_failed_bad)
+ {
+ std::cout << ", RETURNED FAILED";
+ }
+ else if (rc == e_succeeded_bad)
+ {
+ std::cout << ", RETURNED SUCCEEDED";
+ }
+ else if (rc == e_ready_bad)
+ {
+ std::cout << ", RETURNED READY";
+ }
+ g_numTestsFailed++;
+ }
+ else if (rc == e_no_timeout) // bad
+ {
+ std::cout << "FAILED: RETURNED NO_TIMEOUT";
+ g_numTestsFailed++;
+ }
+ else if (rc == e_failed_bad)
+ {
+ std::cout << "FAILED: RETURNED FAILED";
+ g_numTestsFailed++;
+ }
+ else if (rc == e_succeeded_bad)
+ {
+ std::cout << "FAILED: RETURNED SUCCEEDED";
+ g_numTestsFailed++;
+ }
+ else if (rc == e_ready_bad)
+ {
+ std::cout << "FAILED: RETURNED READY";
+ g_numTestsFailed++;
+ }
+ else
+ {
+ std::cout << "Passed";
+ g_numTestsPassed++;
+ }
+ std::cout << std::endl;
+
+ g_numTestsRun++;
+}
+
+void sleepForLongTime()
+{
+#ifdef _WIN32
+ Sleep(10000);
+#else
+ struct timespec ts = {5, 0};
+ nanosleep(&ts, NULL);
+#endif
+}
+
+bool returnFalse()
+{
+ return false;
+}
+
+/******************************************************************************/
+
+// Run the test in the context provided, which may be the current thread or a separate thread.
+template <typename Helper, typename Context, typename Function>
+void runTestInContext(Context context, Function func, const std::string name)
+{
+ std::cout << name << ":" << std::endl;
+
+ {
+ std::cout << " While system clock remains stable: ";
+ context(func, 0);
+ }
+
+ {
+ std::cout << " While system clock jumps back (short): ";
+ typename Helper::thread t(boost::bind(changeSystemTime, -s_shortJumpMs));
+ context(func, -s_shortJumpMs);
+ t.join();
+ }
+
+ {
+ std::cout << " While system clock jumps back (long): ";
+ typename Helper::thread t(boost::bind(changeSystemTime, -s_longJumpMs));
+ context(func, -s_longJumpMs);
+ t.join();
+ }
+
+ {
+ std::cout << " While system clock jumps forward (short): ";
+ typename Helper::thread t(boost::bind(changeSystemTime, s_shortJumpMs));
+ context(func, s_shortJumpMs);
+ t.join();
+ }
+
+ {
+ std::cout << " While system clock jumps forward (long): ";
+ typename Helper::thread t(boost::bind(changeSystemTime, s_longJumpMs));
+ context(func, s_longJumpMs);
+ t.join();
+ }
+}
+
+//--------------------------------------
+
+template <typename Helper, typename Function>
+void noThreadContext(Function func, const long long jumpMs)
+{
+ func(jumpMs);
+}
+
+template <typename Helper, typename Function>
+void threadContextWithNone(Function func, const long long jumpMs)
+{
+ typename Helper::thread t(boost::bind(func, jumpMs));
+ t.join();
+}
+
+template <typename Helper, typename Function>
+void threadContextWithUnique(Function func, const long long jumpMs)
+{
+ typename Helper::mutex m;
+ typename Helper::lock_guard g(m);
+ typename Helper::thread t(boost::bind(func, boost::ref(m), jumpMs));
+ t.join();
+}
+
+template <typename Helper, typename Function>
+void threadContextWithShared(Function func, const long long jumpMs)
+{
+ typename Helper::mutex m;
+ boost::shared_lock_guard<typename Helper::mutex> g(m);
+ typename Helper::thread t(boost::bind(func, boost::ref(m), jumpMs));
+ t.join();
+}
+
+template <typename Helper, typename Function>
+void threadContextWithUpgrade(Function func, const long long jumpMs)
+{
+ typename Helper::mutex m;
+ boost::upgrade_lock<typename Helper::mutex> g(m);
+ typename Helper::thread t(boost::bind(func, boost::ref(m), jumpMs));
+ t.join();
+}
+
+//--------------------------------------
+
+// Run the test in the current thread.
+template <typename Helper, typename Function>
+void runTest(Function func, const std::string name)
+{
+ runTestInContext<Helper>(noThreadContext<Helper, Function>, func, name);
+}
+
+// Run the test in a separate thread.
+template <typename Helper, typename Function>
+void runTestWithNone(Function func, const std::string name)
+{
+ runTestInContext<Helper>(threadContextWithNone<Helper, Function>, func, name);
+}
+
+// Run the test in a separate thread. Pass a locked mutex to the function under test.
+template <typename Helper, typename Function>
+void runTestWithUnique(Function func, const std::string name)
+{
+ runTestInContext<Helper>(threadContextWithUnique<Helper, Function>, func, name);
+}
+
+// Run the test in a separate thread. Pass a shared-locked mutex to the function under test.
+template <typename Helper, typename Function>
+void runTestWithShared(Function func, const std::string name)
+{
+ runTestInContext<Helper>(threadContextWithShared<Helper, Function>, func, name);
+}
+
+// Run the test in a separate thread. Pass an upgrade-locked mutex to the function under test.
+template <typename Helper, typename Function>
+void runTestWithUpgrade(Function func, const std::string name)
+{
+ runTestInContext<Helper>(threadContextWithUpgrade<Helper, Function>, func, name);
+}
+
+/******************************************************************************/
+
+// Test Sleep
+
+template <typename Helper>
+void testSleepFor(const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ Helper::sleep_for(Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, e_na);
+}
+
+template <typename Helper>
+void testSleepUntilSteady(const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ Helper::sleep_until(Helper::steadyNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, e_na);
+}
+
+template <typename Helper>
+void testSleepUntilSystem(const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ Helper::sleep_until(Helper::systemNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na);
+}
+
+template <typename Helper>
+void testSleepUntilCustom(const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ Helper::sleep_until(Helper::customNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na);
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testSleepRelative(const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ boost::this_thread::sleep(ptDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, e_na);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+template <typename Helper>
+void testSleepAbsolute(const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ boost::this_thread::sleep(ptNow + ptDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testSleepStd(const std::string& name)
+{
+ std::cout << std::endl;
+ runTestWithNone<Helper>(testSleepFor <Helper>, name + "::this_thread::sleep_for()");
+ runTestWithNone<Helper>(testSleepUntilSteady<Helper>, name + "::this_thread::sleep_until(), steady time");
+ runTestWithNone<Helper>(testSleepUntilSystem<Helper>, name + "::this_thread::sleep_until(), system time");
+ runTestWithNone<Helper>(testSleepUntilCustom<Helper>, name + "::this_thread::sleep_until(), custom time");
+}
+
+template <typename Helper>
+void testSleepBoost(const std::string& name)
+{
+ testSleepStd<Helper>(name);
+
+ // Boost-only functions
+ runTestWithNone<Helper>(testSleepRelative<Helper>, name + "::this_thread::sleep(), relative time");
+ runTestWithNone<Helper>(testSleepAbsolute<Helper>, name + "::this_thread::sleep(), absolute time");
+}
+
+template <typename Helper>
+void testSleepNoThreadStd(const std::string& name)
+{
+ std::cout << std::endl;
+ runTest<Helper>(testSleepFor <Helper>, name + "::this_thread::sleep_for(), no thread");
+ runTest<Helper>(testSleepUntilSteady<Helper>, name + "::this_thread::sleep_until(), no thread, steady time");
+ runTest<Helper>(testSleepUntilSystem<Helper>, name + "::this_thread::sleep_until(), no thread, system time");
+ runTest<Helper>(testSleepUntilCustom<Helper>, name + "::this_thread::sleep_until(), no thread, custom time");
+}
+
+template <typename Helper>
+void testSleepNoThreadBoost(const std::string& name)
+{
+ testSleepNoThreadStd<Helper>(name);
+
+ // Boost-only functions
+ runTest<Helper>(testSleepRelative<Helper>, name + "::this_thread::sleep(), no thread, relative time");
+ runTest<Helper>(testSleepAbsolute<Helper>, name + "::this_thread::sleep(), no thread, absolute time");
+}
+
+/******************************************************************************/
+
+// Test Sleep, No Interruption Point
+
+template <typename Helper>
+void testSleepForNoInt(const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ Helper::sleep_for_no_int(Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, e_na);
+}
+
+template <typename Helper>
+void testSleepUntilNoIntSteady(const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ Helper::sleep_until_no_int(Helper::steadyNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, e_na);
+}
+
+template <typename Helper>
+void testSleepUntilNoIntSystem(const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ Helper::sleep_until_no_int(Helper::systemNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na);
+}
+
+template <typename Helper>
+void testSleepUntilNoIntCustom(const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ Helper::sleep_until_no_int(Helper::customNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na);
+}
+
+//--------------------------------------
+
+#ifndef SKIP_NO_INT_SLEEP
+
+template <typename Helper>
+void testSleepNoIntRelative(const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ boost::this_thread::no_interruption_point::sleep(ptDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, e_na);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+template <typename Helper>
+void testSleepNoIntAbsolute(const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ boost::this_thread::no_interruption_point::sleep(ptNow + ptDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+#endif
+
+//--------------------------------------
+
+// Only Boost supports no_interruption_point
+
+template <typename Helper>
+void testSleepNoIntBoost(const std::string& name)
+{
+ std::cout << std::endl;
+ runTestWithNone<Helper>(testSleepForNoInt <Helper>, name + "::this_thread::no_interruption_point::sleep_for()");
+ runTestWithNone<Helper>(testSleepUntilNoIntSteady<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), steady time");
+ runTestWithNone<Helper>(testSleepUntilNoIntSystem<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), system time");
+ runTestWithNone<Helper>(testSleepUntilNoIntCustom<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), custom time");
+
+#ifndef SKIP_NO_INT_SLEEP
+ runTestWithNone<Helper>(testSleepNoIntRelative<Helper>, name + "::this_thread::no_interruption_point::sleep(), relative time");
+ runTestWithNone<Helper>(testSleepNoIntAbsolute<Helper>, name + "::this_thread::no_interruption_point::sleep(), absolute time");
+#endif
+}
+
+template <typename Helper>
+void testSleepNoThreadNoIntBoost(const std::string& name)
+{
+ std::cout << std::endl;
+ runTest<Helper>(testSleepForNoInt <Helper>, name + "::this_thread::no_interruption_point::sleep_for(), no thread");
+ runTest<Helper>(testSleepUntilNoIntSteady<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), no thread, steady time");
+ runTest<Helper>(testSleepUntilNoIntSystem<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), no thread, system time");
+ runTest<Helper>(testSleepUntilNoIntCustom<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), no thread, custom time");
+
+#ifndef SKIP_NO_INT_SLEEP
+ runTest<Helper>(testSleepNoIntRelative<Helper>, name + "::this_thread::no_interruption_point::sleep(), no thread, relative time");
+ runTest<Helper>(testSleepNoIntAbsolute<Helper>, name + "::this_thread::no_interruption_point::sleep(), no thread, absolute time");
+#endif
+}
+
+/******************************************************************************/
+
+// Test Try Join
+
+template <typename Helper>
+void testTryJoinFor(const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ typename Helper::thread t3(sleepForLongTime);
+ bool succeeded = t3.try_join_for(Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryJoinUntilSteady(const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ typename Helper::thread t3(sleepForLongTime);
+ bool succeeded = t3.try_join_until(Helper::steadyNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryJoinUntilSystem(const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ typename Helper::thread t3(sleepForLongTime);
+ bool succeeded = t3.try_join_until(Helper::systemNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryJoinUntilCustom(const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ typename Helper::thread t3(sleepForLongTime);
+ bool succeeded = t3.try_join_until(Helper::customNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testTimedJoinRelative(const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ typename Helper::thread t3(sleepForLongTime);
+ bool succeeded = t3.timed_join(ptDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+template <typename Helper>
+void testTimedJoinAbsolute(const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ typename Helper::thread t3(sleepForLongTime);
+ bool succeeded = t3.timed_join(ptNow + ptDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+//--------------------------------------
+
+// Only Boost supports timed try_join functions
+
+template <typename Helper>
+void testJoinBoost(const std::string& name)
+{
+ std::cout << std::endl;
+ runTestWithNone<Helper>(testTryJoinFor <Helper>, name + "::thread::try_join_for()");
+ runTestWithNone<Helper>(testTryJoinUntilSteady<Helper>, name + "::thread::try_join_until(), steady time");
+ runTestWithNone<Helper>(testTryJoinUntilSystem<Helper>, name + "::thread::try_join_until(), system time");
+ runTestWithNone<Helper>(testTryJoinUntilCustom<Helper>, name + "::thread::try_join_until(), custom time");
+ runTestWithNone<Helper>(testTimedJoinRelative <Helper>, name + "::thread::timed_join(), relative time");
+ runTestWithNone<Helper>(testTimedJoinAbsolute <Helper>, name + "::thread::timed_join(), absolute time");
+}
+
+/******************************************************************************/
+
+// Test Condition Variable Wait
+
+template <typename Helper>
+void testCondVarWaitFor(const long long jumpMs)
+{
+ typename Helper::cond cv;
+ typename Helper::mutex m;
+ typename Helper::unique_lock g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool noTimeout = (cv.wait_for(g, Helper::waitDur) == Helper::cv_status::no_timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout);
+}
+
+template <typename Helper>
+void testCondVarWaitUntilSteady(const long long jumpMs)
+{
+ typename Helper::cond cv;
+ typename Helper::mutex m;
+ typename Helper::unique_lock g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool noTimeout = (cv.wait_until(g, Helper::steadyNow() + Helper::waitDur) == Helper::cv_status::no_timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout);
+}
+
+template <typename Helper>
+void testCondVarWaitUntilSystem(const long long jumpMs)
+{
+ typename Helper::cond cv;
+ typename Helper::mutex m;
+ typename Helper::unique_lock g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool noTimeout = (cv.wait_until(g, Helper::systemNow() + Helper::waitDur) == Helper::cv_status::no_timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout);
+}
+
+template <typename Helper>
+void testCondVarWaitUntilCustom(const long long jumpMs)
+{
+ typename Helper::cond cv;
+ typename Helper::mutex m;
+ typename Helper::unique_lock g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool noTimeout = (cv.wait_until(g, Helper::customNow() + Helper::waitDur) == Helper::cv_status::no_timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout);
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testCondVarTimedWaitRelative(const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::cond cv;
+ typename Helper::mutex m;
+ typename Helper::unique_lock g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ bool noTimeout = cv.timed_wait(g, ptDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+template <typename Helper>
+void testCondVarTimedWaitAbsolute(const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::cond cv;
+ typename Helper::mutex m;
+ typename Helper::unique_lock g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ bool noTimeout = cv.timed_wait(g, ptNow + ptDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testCondVarStd(const std::string& name)
+{
+ std::cout << std::endl;
+ runTestWithNone<Helper>(testCondVarWaitFor <Helper>, name + "::wait_for()");
+ runTestWithNone<Helper>(testCondVarWaitUntilSteady<Helper>, name + "::wait_until(), steady time");
+ runTestWithNone<Helper>(testCondVarWaitUntilSystem<Helper>, name + "::wait_until(), system time");
+ runTestWithNone<Helper>(testCondVarWaitUntilCustom<Helper>, name + "::wait_until(), custom time");
+}
+
+template <typename Helper>
+void testCondVarBoost(const std::string& name)
+{
+ testCondVarStd<Helper>(name);
+
+ // Boost-only functions
+ runTestWithNone<Helper>(testCondVarTimedWaitRelative<Helper>, name + "::timed_wait(), relative time");
+ runTestWithNone<Helper>(testCondVarTimedWaitAbsolute<Helper>, name + "::timed_wait(), absolute time");
+}
+
+/******************************************************************************/
+
+// Test Condition Variable Wait with Predicate
+
+template <typename Helper>
+void testCondVarWaitForPred(const long long jumpMs)
+{
+ typename Helper::cond cv;
+ typename Helper::mutex m;
+ typename Helper::unique_lock g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool noTimeout = cv.wait_for(g, Helper::waitDur, returnFalse);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout);
+}
+
+template <typename Helper>
+void testCondVarWaitUntilPredSteady(const long long jumpMs)
+{
+ typename Helper::cond cv;
+ typename Helper::mutex m;
+ typename Helper::unique_lock g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool noTimeout = cv.wait_until(g, Helper::steadyNow() + Helper::waitDur, returnFalse);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout);
+}
+
+template <typename Helper>
+void testCondVarWaitUntilPredSystem(const long long jumpMs)
+{
+ typename Helper::cond cv;
+ typename Helper::mutex m;
+ typename Helper::unique_lock g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool noTimeout = cv.wait_until(g, Helper::systemNow() + Helper::waitDur, returnFalse);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout);
+}
+
+template <typename Helper>
+void testCondVarWaitUntilPredCustom(const long long jumpMs)
+{
+ typename Helper::cond cv;
+ typename Helper::mutex m;
+ typename Helper::unique_lock g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool noTimeout = cv.wait_until(g, Helper::customNow() + Helper::waitDur, returnFalse);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout);
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testCondVarTimedWaitPredRelative(const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::cond cv;
+ typename Helper::mutex m;
+ typename Helper::unique_lock g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ bool noTimeout = cv.timed_wait(g, ptDur, returnFalse);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+template <typename Helper>
+void testCondVarTimedWaitPredAbsolute(const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::cond cv;
+ typename Helper::mutex m;
+ typename Helper::unique_lock g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ bool noTimeout = cv.timed_wait(g, ptNow + ptDur, returnFalse);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testCondVarPredStd(const std::string& name)
+{
+ std::cout << std::endl;
+ runTestWithNone<Helper>(testCondVarWaitForPred <Helper>, name + "::wait_for(), with predicate");
+ runTestWithNone<Helper>(testCondVarWaitUntilPredSteady<Helper>, name + "::wait_until(), with predicate, steady time");
+ runTestWithNone<Helper>(testCondVarWaitUntilPredSystem<Helper>, name + "::wait_until(), with predicate, system time");
+ runTestWithNone<Helper>(testCondVarWaitUntilPredCustom<Helper>, name + "::wait_until(), with predicate, custom time");
+}
+
+template <typename Helper>
+void testCondVarPredBoost(const std::string& name)
+{
+ testCondVarPredStd<Helper>(name);
+
+ // Boost-only functions
+ runTestWithNone<Helper>(testCondVarTimedWaitPredRelative<Helper>, name + "::timed_wait(), with predicate, relative time");
+ runTestWithNone<Helper>(testCondVarTimedWaitPredAbsolute<Helper>, name + "::timed_wait(), with predicate, absolute time");
+}
+
+/******************************************************************************/
+
+// Test Try Lock
+
+template <typename Helper>
+void testTryLockFor(typename Helper::mutex& m, const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_lock_for(Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryLockUntilSteady(typename Helper::mutex& m, const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_lock_until(Helper::steadyNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryLockUntilSystem(typename Helper::mutex& m, const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_lock_until(Helper::systemNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryLockUntilCustom(typename Helper::mutex& m, const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_lock_until(Helper::customNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testTimedLockRelative(typename Helper::mutex& m, const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ bool succeeded = m.timed_lock(ptDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+template <typename Helper>
+void testTimedLockAbsolute(typename Helper::mutex& m, const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ bool succeeded = m.timed_lock(ptNow + ptDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testMutexStd(const std::string& name)
+{
+ std::cout << std::endl;
+ runTestWithUnique<Helper>(testTryLockFor <Helper>, name + "::try_lock_for()");
+ runTestWithUnique<Helper>(testTryLockUntilSteady<Helper>, name + "::try_lock_until(), steady time");
+ runTestWithUnique<Helper>(testTryLockUntilSystem<Helper>, name + "::try_lock_until(), system time");
+ runTestWithUnique<Helper>(testTryLockUntilCustom<Helper>, name + "::try_lock_until(), custom time");
+}
+
+template <typename Helper>
+void testMutexBoost(const std::string& name)
+{
+ testMutexStd<Helper>(name);
+
+ // Boost-only functions
+ runTestWithUnique<Helper>(testTimedLockRelative<Helper>, name + "::timed_lock(), relative time");
+ runTestWithUnique<Helper>(testTimedLockAbsolute<Helper>, name + "::timed_lock(), absolute time");
+}
+
+/******************************************************************************/
+
+// Test Try Lock Shared
+
+template <typename Helper>
+void testTryLockSharedFor(typename Helper::mutex& m, const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_lock_shared_for(Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryLockSharedUntilSteady(typename Helper::mutex& m, const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_lock_shared_until(Helper::steadyNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryLockSharedUntilSystem(typename Helper::mutex& m, const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_lock_shared_until(Helper::systemNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryLockSharedUntilCustom(typename Helper::mutex& m, const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_lock_shared_until(Helper::customNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testTimedLockSharedRelative(typename Helper::mutex& m, const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ bool succeeded = m.timed_lock_shared(ptDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+template <typename Helper>
+void testTimedLockSharedAbsolute(typename Helper::mutex& m, const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ bool succeeded = m.timed_lock_shared(ptNow + ptDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testMutexSharedStd(const std::string& name)
+{
+ std::cout << std::endl;
+ runTestWithUnique<Helper>(testTryLockSharedFor <Helper>, name + "::try_lock_shared_for()");
+ runTestWithUnique<Helper>(testTryLockSharedUntilSteady<Helper>, name + "::try_lock_shared_until(), steady time");
+ runTestWithUnique<Helper>(testTryLockSharedUntilSystem<Helper>, name + "::try_lock_shared_until(), system time");
+ runTestWithUnique<Helper>(testTryLockSharedUntilCustom<Helper>, name + "::try_lock_shared_until(), custom time");
+}
+
+template <typename Helper>
+void testMutexSharedBoost(const std::string& name)
+{
+ testMutexSharedStd<Helper>(name);
+
+ // Boost-only functions
+ runTestWithUnique<Helper>(testTimedLockSharedRelative<Helper>, name + "::timed_lock_shared(), relative time");
+ runTestWithUnique<Helper>(testTimedLockSharedAbsolute<Helper>, name + "::timed_lock_shared(), absolute time");
+}
+
+/******************************************************************************/
+
+// Test Try Lock Upgrade
+
+#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+
+template <typename Helper>
+void testTryLockUpgradeFor(typename Helper::mutex& m, const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_lock_upgrade_for(Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryLockUpgradeUntilSteady(typename Helper::mutex& m, const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_lock_upgrade_until(Helper::steadyNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryLockUpgradeUntilSystem(typename Helper::mutex& m, const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_lock_upgrade_until(Helper::systemNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryLockUpgradeUntilCustom(typename Helper::mutex& m, const long long jumpMs)
+{
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_lock_upgrade_until(Helper::customNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testTimedLockUpgradeRelative(typename Helper::mutex& m, const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ bool succeeded = m.timed_lock_upgrade(ptDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+template <typename Helper>
+void testTimedLockUpgradeAbsolute(typename Helper::mutex& m, const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ bool succeeded = m.timed_lock_upgrade(ptNow + ptDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testTryUnlockSharedAndLockFor(typename Helper::mutex& m, const long long jumpMs)
+{
+ boost::shared_lock_guard<typename Helper::mutex> g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_unlock_shared_and_lock_for(Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryUnlockSharedAndLockUntilSteady(typename Helper::mutex& m, const long long jumpMs)
+{
+ boost::shared_lock_guard<typename Helper::mutex> g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_unlock_shared_and_lock_until(Helper::steadyNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryUnlockSharedAndLockUntilSystem(typename Helper::mutex& m, const long long jumpMs)
+{
+ boost::shared_lock_guard<typename Helper::mutex> g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_unlock_shared_and_lock_until(Helper::systemNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryUnlockSharedAndLockUntilCustom(typename Helper::mutex& m, const long long jumpMs)
+{
+ boost::shared_lock_guard<typename Helper::mutex> g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_unlock_shared_and_lock_until(Helper::customNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testTryUnlockUpgradeAndLockFor(typename Helper::mutex& m, const long long jumpMs)
+{
+ boost::upgrade_lock<typename Helper::mutex> g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_unlock_upgrade_and_lock_for(Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryUnlockUpgradeAndLockUntilSteady(typename Helper::mutex& m, const long long jumpMs)
+{
+ boost::upgrade_lock<typename Helper::mutex> g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_unlock_upgrade_and_lock_until(Helper::steadyNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryUnlockUpgradeAndLockUntilSystem(typename Helper::mutex& m, const long long jumpMs)
+{
+ boost::upgrade_lock<typename Helper::mutex> g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_unlock_upgrade_and_lock_until(Helper::systemNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryUnlockUpgradeAndLockUntilCustom(typename Helper::mutex& m, const long long jumpMs)
+{
+ boost::upgrade_lock<typename Helper::mutex> g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_unlock_upgrade_and_lock_until(Helper::customNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testTryUnlockSharedAndLockUpgradeFor(typename Helper::mutex& m, const long long jumpMs)
+{
+ boost::shared_lock_guard<typename Helper::mutex> g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_unlock_shared_and_lock_upgrade_for(Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryUnlockSharedAndLockUpgradeUntilSteady(typename Helper::mutex& m, const long long jumpMs)
+{
+ boost::shared_lock_guard<typename Helper::mutex> g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_unlock_shared_and_lock_upgrade_until(Helper::steadyNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryUnlockSharedAndLockUpgradeUntilSystem(typename Helper::mutex& m, const long long jumpMs)
+{
+ boost::shared_lock_guard<typename Helper::mutex> g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_unlock_shared_and_lock_upgrade_until(Helper::systemNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+template <typename Helper>
+void testTryUnlockSharedAndLockUpgradeUntilCustom(typename Helper::mutex& m, const long long jumpMs)
+{
+ boost::shared_lock_guard<typename Helper::mutex> g(m);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = m.try_unlock_shared_and_lock_upgrade_until(Helper::customNow() + Helper::waitDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
+}
+
+#endif
+
+//--------------------------------------
+
+// Only Boost supports upgrade mutexes
+
+template <typename Helper>
+void testMutexUpgradeBoost(const std::string& name)
+{
+#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+ std::cout << std::endl;
+ runTestWithUnique<Helper>(testTryLockUpgradeFor <Helper>, name + "::try_lock_upgrade_for()");
+ runTestWithUnique<Helper>(testTryLockUpgradeUntilSteady<Helper>, name + "::try_lock_upgrade_until(), steady time");
+ runTestWithUnique<Helper>(testTryLockUpgradeUntilSystem<Helper>, name + "::try_lock_upgrade_until(), system time");
+ runTestWithUnique<Helper>(testTryLockUpgradeUntilCustom<Helper>, name + "::try_lock_upgrade_until(), custom time");
+ runTestWithUnique<Helper>(testTimedLockUpgradeRelative <Helper>, name + "::timed_lock_upgrade(), relative time");
+ runTestWithUnique<Helper>(testTimedLockUpgradeAbsolute <Helper>, name + "::timed_lock_upgrade(), absolute time");
+
+ std::cout << std::endl;
+ runTestWithShared<Helper>(testTryUnlockSharedAndLockFor <Helper>, name + "::try_unlock_shared_and_lock_for()");
+ runTestWithShared<Helper>(testTryUnlockSharedAndLockUntilSteady<Helper>, name + "::try_unlock_shared_and_lock_until(), steady time");
+ runTestWithShared<Helper>(testTryUnlockSharedAndLockUntilSystem<Helper>, name + "::try_unlock_shared_and_lock_until(), system time");
+ runTestWithShared<Helper>(testTryUnlockSharedAndLockUntilCustom<Helper>, name + "::try_unlock_shared_and_lock_until(), custom time");
+
+ std::cout << std::endl;
+ runTestWithShared<Helper>(testTryUnlockUpgradeAndLockFor <Helper>, name + "::try_unlock_upgrade_and_lock_for()");
+ runTestWithShared<Helper>(testTryUnlockUpgradeAndLockUntilSteady<Helper>, name + "::try_unlock_upgrade_and_lock_until(), steady time");
+ runTestWithShared<Helper>(testTryUnlockUpgradeAndLockUntilSystem<Helper>, name + "::try_unlock_upgrade_and_lock_until(), system time");
+ runTestWithShared<Helper>(testTryUnlockUpgradeAndLockUntilCustom<Helper>, name + "::try_unlock_upgrade_and_lock_until(), custom time");
+
+ std::cout << std::endl;
+ runTestWithUpgrade<Helper>(testTryUnlockSharedAndLockFor <Helper>, name + "::try_unlock_shared_and_lock_upgrade_for()");
+ runTestWithUpgrade<Helper>(testTryUnlockSharedAndLockUntilSteady<Helper>, name + "::try_unlock_shared_and_lock_upgrade_until(), steady time");
+ runTestWithUpgrade<Helper>(testTryUnlockSharedAndLockUntilSystem<Helper>, name + "::try_unlock_shared_and_lock_upgrade_until(), system time");
+ runTestWithUpgrade<Helper>(testTryUnlockSharedAndLockUntilCustom<Helper>, name + "::try_unlock_shared_and_lock_upgrade_until(), custom time");
+#endif
+}
+
+/******************************************************************************/
+
+// Test Future Wait
+
+template <typename Helper>
+void testFutureWaitFor(const long long jumpMs)
+{
+ typename Helper::packaged_task pt(returnFalse);
+ typename Helper::future f = pt.get_future();
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool timeout = (f.wait_for(Helper::waitDur) == Helper::future_status::timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
+}
+
+template <typename Helper>
+void testFutureWaitUntilSteady(const long long jumpMs)
+{
+ typename Helper::packaged_task pt(returnFalse);
+ typename Helper::future f = pt.get_future();
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool timeout = (f.wait_until(Helper::steadyNow() + Helper::waitDur) == Helper::future_status::timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
+}
+
+template <typename Helper>
+void testFutureWaitUntilSystem(const long long jumpMs)
+{
+ typename Helper::packaged_task pt(returnFalse);
+ typename Helper::future f = pt.get_future();
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool timeout = (f.wait_until(Helper::systemNow() + Helper::waitDur) == Helper::future_status::timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout);
+}
+
+template <typename Helper>
+void testFutureWaitUntilCustom(const long long jumpMs)
+{
+ typename Helper::packaged_task pt(returnFalse);
+ typename Helper::future f = pt.get_future();
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool timeout = (f.wait_until(Helper::customNow() + Helper::waitDur) == Helper::future_status::timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout);
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testFutureTimedWaitRelative(const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::packaged_task pt(returnFalse);
+ typename Helper::future f = pt.get_future();
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ bool noTimeout = f.timed_wait(ptDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+template <typename Helper>
+void testFutureTimedWaitAbsolute(const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::packaged_task pt(returnFalse);
+ typename Helper::future f = pt.get_future();
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ bool noTimeout = f.timed_wait_until(ptNow + ptDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testFutureStd(const std::string& name)
+{
+ std::cout << std::endl;
+ runTestWithNone<Helper>(testFutureWaitFor <Helper>, name + "::wait_for()");
+ runTestWithNone<Helper>(testFutureWaitUntilSteady<Helper>, name + "::wait_until(), steady time");
+ runTestWithNone<Helper>(testFutureWaitUntilSystem<Helper>, name + "::wait_until(), system time");
+ runTestWithNone<Helper>(testFutureWaitUntilCustom<Helper>, name + "::wait_until(), custom time");
+}
+
+template <typename Helper>
+void testFutureBoost(const std::string& name)
+{
+ testFutureStd<Helper>(name);
+
+ // Boost-only functions
+ runTestWithNone<Helper>(testFutureTimedWaitRelative<Helper>, name + "::timed_wait(), relative time");
+ runTestWithNone<Helper>(testFutureTimedWaitAbsolute<Helper>, name + "::timed_wait_until(), absolute time");
+}
+
+/******************************************************************************/
+
+// Test Shared Future Wait
+
+template <typename Helper>
+void testSharedFutureWaitFor(const long long jumpMs)
+{
+ typename Helper::packaged_task pt(returnFalse);
+ typename Helper::future f = pt.get_future();
+ typename Helper::shared_future sf = boost::move(f);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool timeout = (sf.wait_for(Helper::waitDur) == Helper::future_status::timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
+}
+
+template <typename Helper>
+void testSharedFutureWaitUntilSteady(const long long jumpMs)
+{
+ typename Helper::packaged_task pt(returnFalse);
+ typename Helper::future f = pt.get_future();
+ typename Helper::shared_future sf = boost::move(f);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool timeout = (sf.wait_until(Helper::steadyNow() + Helper::waitDur) == Helper::future_status::timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
+}
+
+template <typename Helper>
+void testSharedFutureWaitUntilSystem(const long long jumpMs)
+{
+ typename Helper::packaged_task pt(returnFalse);
+ typename Helper::future f = pt.get_future();
+ typename Helper::shared_future sf = boost::move(f);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool timeout = (sf.wait_until(Helper::systemNow() + Helper::waitDur) == Helper::future_status::timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout);
+}
+
+template <typename Helper>
+void testSharedFutureWaitUntilCustom(const long long jumpMs)
+{
+ typename Helper::packaged_task pt(returnFalse);
+ typename Helper::future f = pt.get_future();
+ typename Helper::shared_future sf = boost::move(f);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool timeout = (sf.wait_until(Helper::customNow() + Helper::waitDur) == Helper::future_status::timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout);
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testSharedFutureTimedWaitRelative(const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::packaged_task pt(returnFalse);
+ typename Helper::future f = pt.get_future();
+ typename Helper::shared_future sf = boost::move(f);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ bool noTimeout = sf.timed_wait(ptDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+template <typename Helper>
+void testSharedFutureTimedWaitAbsolute(const long long jumpMs)
+{
+#ifndef SKIP_DATETIME_FUNCTIONS
+ typename Helper::packaged_task pt(returnFalse);
+ typename Helper::future f = pt.get_future();
+ typename Helper::shared_future sf = boost::move(f);
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
+ boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
+ bool noTimeout = sf.timed_wait_until(ptNow + ptDur);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout);
+#else
+ checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
+#endif
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testSharedFutureStd(const std::string& name)
+{
+ std::cout << std::endl;
+ runTestWithNone<Helper>(testSharedFutureWaitFor <Helper>, name + "::wait_for()");
+ runTestWithNone<Helper>(testSharedFutureWaitUntilSteady<Helper>, name + "::wait_until(), steady time");
+ runTestWithNone<Helper>(testSharedFutureWaitUntilSystem<Helper>, name + "::wait_until(), system time");
+ runTestWithNone<Helper>(testSharedFutureWaitUntilCustom<Helper>, name + "::wait_until(), custom time");
+}
+
+template <typename Helper>
+void testSharedFutureBoost(const std::string& name)
+{
+ testSharedFutureStd<Helper>(name);
+
+ // Boost-only functions
+ runTestWithNone<Helper>(testSharedFutureTimedWaitRelative<Helper>, name + "::timed_wait(), relative time");
+ runTestWithNone<Helper>(testSharedFutureTimedWaitAbsolute<Helper>, name + "::timed_wait_until(), absolute time");
+}
+
+/******************************************************************************/
+
+// Test Sync Priority Queue
+
+template <typename Helper>
+void testSyncPriorityQueuePullFor(const long long jumpMs)
+{
+ boost::sync_priority_queue<int> q;
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool timeout = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
+}
+
+template <typename Helper>
+void testSyncPriorityQueuePullUntilSteady(const long long jumpMs)
+{
+ boost::sync_priority_queue<int> q;
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool timeout = (q.pull_until(Helper::steadyNow() + Helper::waitDur, i) == boost::queue_op_status::timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
+}
+
+template <typename Helper>
+void testSyncPriorityQueuePullUntilSystem(const long long jumpMs)
+{
+ boost::sync_priority_queue<int> q;
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool timeout = (q.pull_until(Helper::systemNow() + Helper::waitDur, i) == boost::queue_op_status::timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout);
+}
+
+template <typename Helper>
+void testSyncPriorityQueuePullUntilCustom(const long long jumpMs)
+{
+ boost::sync_priority_queue<int> q;
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool timeout = (q.pull_until(Helper::customNow() + Helper::waitDur, i) == boost::queue_op_status::timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout);
+}
+
+//--------------------------------------
+
+// Only Boost supports sync_priority_queue
+
+template <typename Helper>
+void testSyncPriorityQueueBoost(const std::string& name)
+{
+ std::cout << std::endl;
+ runTestWithNone<Helper>(testSyncPriorityQueuePullFor <Helper>, name + "::pull_for()");
+ runTestWithNone<Helper>(testSyncPriorityQueuePullUntilSteady<Helper>, name + "::pull_until(), steady time");
+ runTestWithNone<Helper>(testSyncPriorityQueuePullUntilSystem<Helper>, name + "::pull_until(), system time");
+ runTestWithNone<Helper>(testSyncPriorityQueuePullUntilCustom<Helper>, name + "::pull_until(), custom time");
+}
+
+/******************************************************************************/
+
+// Test Sync Timed Queue
+
+template <typename Helper>
+void testSyncTimedQueuePullForEmptySteady(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::steady_clock> q;
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool timeout = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
+}
+
+template <typename Helper>
+void testSyncTimedQueuePullForEmptySystem(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::system_clock> q;
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool timeout = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
+}
+
+template <typename Helper>
+void testSyncTimedQueuePullForEmptyCustom(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::custom_clock> q;
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool timeout = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
+}
+
+template <typename Helper>
+void testSyncTimedQueuePullUntilEmptySteady(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::steady_clock> q;
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool timeout = (q.pull_until(Helper::steadyNow() + Helper::waitDur, i) == boost::queue_op_status::timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
+}
+
+template <typename Helper>
+void testSyncTimedQueuePullUntilEmptySystem(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::system_clock> q;
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool timeout = (q.pull_until(Helper::systemNow() + Helper::waitDur, i) == boost::queue_op_status::timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout);
+}
+
+template <typename Helper>
+void testSyncTimedQueuePullUntilEmptyCustom(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::custom_clock> q;
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool timeout = (q.pull_until(Helper::customNow() + Helper::waitDur, i) == boost::queue_op_status::timeout);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout);
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testSyncTimedQueuePullForNotReadySteady(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::steady_clock> q;
+ q.push(0, typename Helper::milliseconds(10000)); // a long time
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool notReady = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::not_ready);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, notReady ? e_not_ready_good : e_ready_bad);
+}
+
+template <typename Helper>
+void testSyncTimedQueuePullForNotReadySystem(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::system_clock> q;
+ q.push(0, typename Helper::milliseconds(10000)); // a long time
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool notReady = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::not_ready);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, notReady ? e_not_ready_good : e_ready_bad);
+}
+
+template <typename Helper>
+void testSyncTimedQueuePullForNotReadyCustom(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::custom_clock> q;
+ q.push(0, typename Helper::milliseconds(10000)); // a long time
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool notReady = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::not_ready);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, notReady ? e_not_ready_good : e_ready_bad);
+}
+
+template <typename Helper>
+void testSyncTimedQueuePullUntilNotReadySteady(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::steady_clock> q;
+ q.push(0, typename Helper::milliseconds(10000)); // a long time
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool notReady = (q.pull_until(Helper::steadyNow() + Helper::waitDur, i) == boost::queue_op_status::not_ready);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, notReady ? e_not_ready_good : e_ready_bad);
+}
+
+template <typename Helper>
+void testSyncTimedQueuePullUntilNotReadySystem(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::system_clock> q;
+ q.push(0, typename Helper::milliseconds(10000)); // a long time
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool notReady = (q.pull_until(Helper::systemNow() + Helper::waitDur, i) == boost::queue_op_status::not_ready);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, notReady ? e_not_ready_good : e_ready_bad);
+}
+
+template <typename Helper>
+void testSyncTimedQueuePullUntilNotReadyCustom(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::custom_clock> q;
+ q.push(0, typename Helper::milliseconds(10000)); // a long time
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool notReady = (q.pull_until(Helper::customNow() + Helper::waitDur, i) == boost::queue_op_status::not_ready);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, notReady ? e_not_ready_good : e_ready_bad);
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testSyncTimedQueuePullForSucceedsSteady(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::steady_clock> q;
+ q.push(0, Helper::waitDur);
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = (q.pull_for(typename Helper::milliseconds(10000), i) == boost::queue_op_status::success);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_good : e_failed_bad);
+}
+
+template <typename Helper>
+void testSyncTimedQueuePullForSucceedsSystem(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::system_clock> q;
+ q.push(0, Helper::waitDur);
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = (q.pull_for(typename Helper::milliseconds(10000), i) == boost::queue_op_status::success);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad);
+}
+
+template <typename Helper>
+void testSyncTimedQueuePullForSucceedsCustom(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::custom_clock> q;
+ q.push(0, Helper::waitDur);
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = (q.pull_for(typename Helper::milliseconds(10000), i) == boost::queue_op_status::success);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad);
+}
+
+template <typename Helper>
+void testSyncTimedQueuePullUntilSucceedsSteady(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::steady_clock> q;
+ q.push(0, Helper::steadyNow() + Helper::waitDur);
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = (q.pull_until(Helper::steadyNow() + typename Helper::milliseconds(10000), i) == boost::queue_op_status::success);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_good : e_failed_bad);
+}
+
+template <typename Helper>
+void testSyncTimedQueuePullUntilSucceedsSystem(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::system_clock> q;
+ q.push(0, Helper::systemNow() + Helper::waitDur);
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = (q.pull_until(Helper::systemNow() + typename Helper::milliseconds(10000), i) == boost::queue_op_status::success);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad);
+}
+
+template <typename Helper>
+void testSyncTimedQueuePullUntilSucceedsCustom(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::custom_clock> q;
+ q.push(0, Helper::customNow() + Helper::waitDur);
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = (q.pull_until(Helper::customNow() + typename Helper::milliseconds(10000), i) == boost::queue_op_status::success);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad);
+}
+
+//--------------------------------------
+
+template <typename Helper>
+void testSyncTimedQueueWaitPullSucceedsSteady(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::steady_clock> q;
+ q.push(0, Helper::steadyNow() + Helper::waitDur);
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = (q.wait_pull(i) == boost::queue_op_status::success);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_good : e_failed_bad);
+}
+
+template <typename Helper>
+void testSyncTimedQueueWaitPullSucceedsSystem(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::system_clock> q;
+ q.push(0, Helper::systemNow() + Helper::waitDur);
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = (q.wait_pull(i) == boost::queue_op_status::success);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad);
+}
+
+template <typename Helper>
+void testSyncTimedQueueWaitPullSucceedsCustom(const long long jumpMs)
+{
+ boost::sync_timed_queue<int, typename Helper::custom_clock> q;
+ q.push(0, Helper::customNow() + Helper::waitDur);
+ int i;
+
+ typename Helper::steady_time_point before(Helper::steadyNow());
+ bool succeeded = (q.wait_pull(i) == boost::queue_op_status::success);
+ typename Helper::steady_time_point after(Helper::steadyNow());
+
+ checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad);
+}
+
+//--------------------------------------
+
+// Only Boost supports sync_timed_queue
+
+template <typename Helper>
+void testSyncTimedQueueBoost(const std::string& name)
+{
+ std::cout << std::endl;
+ runTestWithNone<Helper>(testSyncTimedQueuePullForEmptySteady <Helper>, name + "::pull_for(), empty, steady time");
+ runTestWithNone<Helper>(testSyncTimedQueuePullForEmptySystem <Helper>, name + "::pull_for(), empty, system time");
+ runTestWithNone<Helper>(testSyncTimedQueuePullForEmptyCustom <Helper>, name + "::pull_for(), empty, custom time");
+ runTestWithNone<Helper>(testSyncTimedQueuePullUntilEmptySteady<Helper>, name + "::pull_until(), empty, steady time");
+ runTestWithNone<Helper>(testSyncTimedQueuePullUntilEmptySystem<Helper>, name + "::pull_until(), empty, system time");
+ runTestWithNone<Helper>(testSyncTimedQueuePullUntilEmptyCustom<Helper>, name + "::pull_until(), empty, custom time");
+
+ std::cout << std::endl;
+ runTestWithNone<Helper>(testSyncTimedQueuePullForNotReadySteady <Helper>, name + "::pull_for(), not ready, steady time");
+ runTestWithNone<Helper>(testSyncTimedQueuePullForNotReadySystem <Helper>, name + "::pull_for(), not ready, system time");
+ runTestWithNone<Helper>(testSyncTimedQueuePullForNotReadyCustom <Helper>, name + "::pull_for(), not ready, custom time");
+ runTestWithNone<Helper>(testSyncTimedQueuePullUntilNotReadySteady<Helper>, name + "::pull_until(), not ready, steady time");
+ runTestWithNone<Helper>(testSyncTimedQueuePullUntilNotReadySystem<Helper>, name + "::pull_until(), not ready, system time");
+ runTestWithNone<Helper>(testSyncTimedQueuePullUntilNotReadyCustom<Helper>, name + "::pull_until(), not ready, custom time");
+
+ std::cout << std::endl;
+ runTestWithNone<Helper>(testSyncTimedQueuePullForSucceedsSteady <Helper>, name + "::pull_for(), succeeds, steady time");
+ runTestWithNone<Helper>(testSyncTimedQueuePullForSucceedsSystem <Helper>, name + "::pull_for(), succeeds, system time");
+ runTestWithNone<Helper>(testSyncTimedQueuePullForSucceedsCustom <Helper>, name + "::pull_for(), succeeds, custom time");
+ runTestWithNone<Helper>(testSyncTimedQueuePullUntilSucceedsSteady<Helper>, name + "::pull_until(), succeeds, steady time");
+ runTestWithNone<Helper>(testSyncTimedQueuePullUntilSucceedsSystem<Helper>, name + "::pull_until(), succeeds, system time");
+ runTestWithNone<Helper>(testSyncTimedQueuePullUntilSucceedsCustom<Helper>, name + "::pull_until(), succeeds, custom time");
+
+ std::cout << std::endl;
+ runTestWithNone<Helper>(testSyncTimedQueueWaitPullSucceedsSteady<Helper>, name + "::wait_pull(), succeeds, steady time");
+ runTestWithNone<Helper>(testSyncTimedQueueWaitPullSucceedsSystem<Helper>, name + "::wait_pull(), succeeds, system time");
+ runTestWithNone<Helper>(testSyncTimedQueueWaitPullSucceedsCustom<Helper>, name + "::wait_pull(), succeeds, custom time");
+}
+
+/******************************************************************************/
+
+int main()
+{
+ std::cout << std::endl;
+ std::cout << "INFO: This test requires root/Administrator privileges in order to change the system clock." << std::endl;
+ std::cout << "INFO: Disable NTP while running this test to prevent NTP from changing the system clock." << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "BOOST_HAS_PTHREAD_DELAY_NP: ";
+#ifdef BOOST_HAS_PTHREAD_DELAY_NP
+ std::cout << "YES" << std::endl;
+#else
+ std::cout << "NO" << std::endl;
+#endif
+
+ std::cout << "BOOST_HAS_NANOSLEEP: ";
+#ifdef BOOST_HAS_NANOSLEEP
+ std::cout << "YES" << std::endl;
+#else
+ std::cout << "NO" << std::endl;
+#endif
+
+ std::cout << "BOOST_THREAD_SLEEP_FOR_IS_STEADY: ";
+#ifdef BOOST_THREAD_SLEEP_FOR_IS_STEADY
+ std::cout << "YES" << std::endl;
+#else
+ std::cout << "NO" << std::endl;
+#endif
+
+ std::cout << "CLOCK_MONOTONIC: ";
+#ifdef CLOCK_MONOTONIC
+ std::cout << "YES" << std::endl;
+#else
+ std::cout << "NO" << std::endl;
+#endif
+
+ std::cout << "BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN: ";
+#ifdef BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
+ std::cout << "YES" << std::endl;
+#else
+ std::cout << "NO" << std::endl;
+#endif
+
+ std::cout << "BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS: ";
+#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
+ std::cout << "YES" << std::endl;
+#else
+ std::cout << "NO" << std::endl;
+#endif
+
+ std::cout << "BOOST_THREAD_V2_SHARED_MUTEX: ";
+#ifdef BOOST_THREAD_V2_SHARED_MUTEX
+ std::cout << "YES" << std::endl;
+#else
+ std::cout << "NO" << std::endl;
+#endif
+
+ std::cout << "BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC: ";
+#ifdef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
+ std::cout << "YES" << std::endl;
+#else
+ std::cout << "NO" << std::endl;
+#endif
+
+ std::cout << std::endl;
+ std::cout << "Wait Time: " << s_waitMs << " ms" << std::endl;
+ std::cout << "Short Jump Time: " << s_shortJumpMs << " ms" << std::endl;
+ std::cout << "Long Jump Time: " << s_longJumpMs << " ms" << std::endl;
+ std::cout << "Sleep Before Jump Time: " << s_sleepBeforeJumpMs << " ms" << std::endl;
+ std::cout << "Max Early Error: " << s_maxEarlyErrorMs << " ms" << std::endl;
+ std::cout << "Max Late Error: " << s_maxLateErrorMs << " ms" << std::endl;
+
+ testSleepBoost <BoostHelper< > >("boost");
+ testSleepNoIntBoost <BoostHelper< > >("boost");
+ testSleepNoThreadBoost <BoostHelper< > >("boost");
+ testSleepNoThreadNoIntBoost<BoostHelper< > >("boost");
+ testJoinBoost <BoostHelper< > >("boost");
+ testCondVarBoost <BoostHelper<boost::mutex, boost::condition_variable > >("boost::condition_variable");
+ testCondVarPredBoost <BoostHelper<boost::mutex, boost::condition_variable > >("boost::condition_variable");
+ testCondVarBoost <BoostHelper<boost::mutex, boost::condition_variable_any> >("boost::condition_variable_any");
+ testCondVarPredBoost <BoostHelper<boost::mutex, boost::condition_variable_any> >("boost::condition_variable_any");
+ testMutexBoost <BoostHelper<boost::timed_mutex > >("boost::timed_mutex");
+ testMutexBoost <BoostHelper<boost::recursive_timed_mutex > >("boost::recursive_timed_mutex");
+ testMutexBoost <BoostHelper<boost::shared_mutex > >("boost::shared_mutex"); // upgrade_mutex is a typedef of shared_mutex, so no need to test upgrade_mutex
+ testMutexSharedBoost <BoostHelper<boost::shared_mutex > >("boost::shared_mutex"); // upgrade_mutex is a typedef of shared_mutex, so no need to test upgrade_mutex
+ testMutexUpgradeBoost <BoostHelper<boost::shared_mutex > >("boost::shared_mutex"); // upgrade_mutex is a typedef of shared_mutex, so no need to test upgrade_mutex
+ testFutureBoost <BoostHelper< > >("boost::future");
+ testSharedFutureBoost <BoostHelper< > >("boost::shared_future");
+ testSyncPriorityQueueBoost <BoostHelper< > >("boost::sync_priority_queue");
+ testSyncTimedQueueBoost <BoostHelper< > >("boost::sync_timed_queue");
+
+#ifdef TEST_CPP14_FEATURES
+ testSleepStd <StdHelper< > >("std");
+ testSleepNoThreadStd<StdHelper< > >("std");
+ testCondVarStd <StdHelper<std::mutex, std::condition_variable > >("std::condition_variable");
+ testCondVarPredStd <StdHelper<std::mutex, std::condition_variable > >("std::condition_variable");
+ testCondVarStd <StdHelper<std::mutex, std::condition_variable_any> >("std::condition_variable_any");
+ testCondVarPredStd <StdHelper<std::mutex, std::condition_variable_any> >("std::condition_variable_any");
+ testMutexStd <StdHelper<std::timed_mutex > >("std::timed_mutex");
+ testMutexStd <StdHelper<std::recursive_timed_mutex > >("std::recursive_timed_mutex");
+ testMutexStd <StdHelper<std::shared_timed_mutex > >("std::shared_timed_mutex");
+ testMutexSharedStd <StdHelper<std::shared_timed_mutex > >("std::shared_timed_mutex");
+ testFutureStd <StdHelper< > >("std::future");
+ testSharedFutureStd <StdHelper< > >("std::shared_future");
+#endif
+
+ std::cout << std::endl;
+ std::cout << "Number of Tests Run: " << g_numTestsRun << std::endl;
+ std::cout << "Number of Tests Passed: " << g_numTestsPassed << std::endl;
+ std::cout << "Number of Tests Failed: " << g_numTestsFailed << std::endl;
+
+ return 0;
+}
diff --git a/src/boost/libs/thread/test/test_tss.cpp b/src/boost/libs/thread/test/test_tss.cpp
new file mode 100644
index 000000000..08bbddc0c
--- /dev/null
+++ b/src/boost/libs/thread/test/test_tss.cpp
@@ -0,0 +1,511 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+// Copyright (C) 2007 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
+#define BOOST_TEST_MODULE Boost.Threads: tss test suite
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/predef/platform.h>
+
+#include <boost/thread/tss.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+#include "./util.inl"
+
+#include <iostream>
+
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+#endif
+
+boost::mutex check_mutex;
+boost::mutex tss_mutex;
+int tss_instances = 0;
+int tss_total = 0;
+
+struct tss_value_t
+{
+ tss_value_t()
+ {
+ boost::unique_lock<boost::mutex> lock(tss_mutex);
+ ++tss_instances;
+ ++tss_total;
+ value = 0;
+ }
+ ~tss_value_t()
+ {
+ boost::unique_lock<boost::mutex> lock(tss_mutex);
+ --tss_instances;
+ }
+ int value;
+};
+
+boost::thread_specific_ptr<tss_value_t> tss_value;
+
+void test_tss_thread()
+{
+ tss_value.reset(new tss_value_t());
+ for (int i=0; i<1000; ++i)
+ {
+ int& n = tss_value->value;
+ // Don't call BOOST_CHECK_EQUAL directly, as it doesn't appear to
+ // be thread safe. Must evaluate further.
+ if (n != i)
+ {
+ boost::unique_lock<boost::mutex> lock(check_mutex);
+ BOOST_CHECK_EQUAL(n, i);
+ }
+ ++n;
+ }
+}
+
+
+
+#if defined(BOOST_THREAD_PLATFORM_WIN32)
+#if BOOST_PLAT_WINDOWS_RUNTIME
+ typedef std::shared_ptr<std::thread> native_thread_t;
+
+ BOOST_AUTO_TEST_CASE(test_tss_thread_native)
+ {
+ test_tss_thread();
+ }
+
+ native_thread_t create_native_thread()
+ {
+ return std::make_shared<std::thread>(test_tss_thread_native);
+ }
+
+ void join_native_thread(native_thread_t thread)
+ {
+ thread->join();
+ }
+
+#else
+ typedef HANDLE native_thread_t;
+
+ DWORD WINAPI test_tss_thread_native(LPVOID /*lpParameter*/)
+ {
+ test_tss_thread();
+ return 0;
+ }
+
+ native_thread_t create_native_thread(void)
+ {
+ native_thread_t const res=CreateThread(
+ 0, //security attributes (0 = not inheritable)
+ 0, //stack size (0 = default)
+ &test_tss_thread_native, //function to execute
+ 0, //parameter to pass to function
+ 0, //creation flags (0 = run immediately)
+ 0 //thread id (0 = thread id not returned)
+ );
+ BOOST_CHECK(res!=0);
+ return res;
+ }
+
+ void join_native_thread(native_thread_t thread)
+ {
+ DWORD res = WaitForSingleObject(thread, INFINITE);
+ BOOST_CHECK(res == WAIT_OBJECT_0);
+
+ res = CloseHandle(thread);
+ BOOST_CHECK(SUCCEEDED(res));
+ }
+#endif
+#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+ typedef pthread_t native_thread_t;
+
+extern "C"
+{
+ void* test_tss_thread_native(void* )
+ {
+ test_tss_thread();
+ return 0;
+ }
+}
+
+ native_thread_t create_native_thread()
+ {
+ native_thread_t thread_handle;
+
+ int const res = pthread_create(&thread_handle, 0, &test_tss_thread_native, 0);
+ BOOST_CHECK(!res);
+ return thread_handle;
+ }
+
+ void join_native_thread(native_thread_t thread)
+ {
+ void* result=0;
+ int const res=pthread_join(thread,&result);
+ BOOST_CHECK(!res);
+ }
+#endif
+
+void do_test_tss()
+{
+ tss_instances = 0;
+ tss_total = 0;
+
+ const int NUMTHREADS=5;
+ boost::thread_group threads;
+ try
+ {
+ for (int i=0; i<NUMTHREADS; ++i)
+ threads.create_thread(&test_tss_thread);
+ threads.join_all();
+ }
+ catch(...)
+ {
+ threads.interrupt_all();
+ threads.join_all();
+ throw;
+ }
+
+
+ std::cout
+ << "tss_instances = " << tss_instances
+ << "; tss_total = " << tss_total
+ << "\n";
+ std::cout.flush();
+
+ BOOST_CHECK_EQUAL(tss_instances, 0);
+ BOOST_CHECK_EQUAL(tss_total, 5);
+
+ tss_instances = 0;
+ tss_total = 0;
+
+ native_thread_t thread1 = create_native_thread();
+ native_thread_t thread2 = create_native_thread();
+ native_thread_t thread3 = create_native_thread();
+ native_thread_t thread4 = create_native_thread();
+ native_thread_t thread5 = create_native_thread();
+
+ join_native_thread(thread5);
+ join_native_thread(thread4);
+ join_native_thread(thread3);
+ join_native_thread(thread2);
+ join_native_thread(thread1);
+
+ std::cout
+ << "tss_instances = " << tss_instances
+ << "; tss_total = " << tss_total
+ << "\n";
+ std::cout.flush();
+
+ // The following is not really an error. TSS cleanup support still is available for boost threads.
+ // Also this usually will be triggered only when bound to the static version of thread lib.
+ // 2006-10-02 Roland Schwarz
+ //BOOST_CHECK_EQUAL(tss_instances, 0);
+#if !defined(__MINGW32__)
+ // This fails on MinGW, when using the static lib
+ BOOST_CHECK_MESSAGE(tss_instances == 0, "Support of automatic tss cleanup for native threading API not available");
+#endif
+ BOOST_CHECK_EQUAL(tss_total, 5);
+}
+
+BOOST_AUTO_TEST_CASE(test_tss)
+{
+ timed_test(&do_test_tss, 2);
+}
+
+
+bool tss_void_cleanup_called=false;
+
+void tss_void_custom_cleanup(void* d)
+{
+ std::cout << d << std::endl;
+ delete reinterpret_cast<tss_value_t*>(d);
+ tss_void_cleanup_called=true;
+}
+
+boost::thread_specific_ptr<void> tss_void(tss_void_custom_cleanup);
+
+void test_tss_void_thread()
+{
+ tss_void.reset(new tss_value_t());
+ for (int i=0; i<10; ++i)
+ {
+ int& n = static_cast<tss_value_t*>(tss_value.get())->value;
+ *tss_value;
+ // Don't call BOOST_CHECK_EQUAL directly, as it doesn't appear to
+ // be thread safe. Must evaluate further.
+ if (n != i)
+ {
+ boost::unique_lock<boost::mutex> lock(check_mutex);
+ BOOST_CHECK_EQUAL(n, i);
+ }
+ ++n;
+ }
+}
+void do_test_tss_void()
+{
+ tss_instances = 0;
+ tss_total = 0;
+
+ const int NUMTHREADS=5;
+ boost::thread_group threads;
+ try
+ {
+ for (int i=0; i<NUMTHREADS; ++i)
+ threads.create_thread(&test_tss_void_thread);
+ threads.join_all();
+ }
+ catch(...)
+ {
+ threads.interrupt_all();
+ threads.join_all();
+ throw;
+ }
+
+
+ std::cout
+ << "tss_instances = " << tss_instances
+ << "; tss_total = " << tss_total
+ << "\n";
+ std::cout.flush();
+
+ BOOST_CHECK_EQUAL(tss_instances, 0);
+ BOOST_CHECK_EQUAL(tss_total, 5);
+
+// tss_instances = 0;
+// tss_total = 0;
+//
+// native_thread_t thread1 = create_native_thread();
+// native_thread_t thread2 = create_native_thread();
+// native_thread_t thread3 = create_native_thread();
+// native_thread_t thread4 = create_native_thread();
+// native_thread_t thread5 = create_native_thread();
+//
+// join_native_thread(thread5);
+// join_native_thread(thread4);
+// join_native_thread(thread3);
+// join_native_thread(thread2);
+// join_native_thread(thread1);
+//
+// std::cout
+// << "tss_instances = " << tss_instances
+// << "; tss_total = " << tss_total
+// << "\n";
+// std::cout.flush();
+//
+// // The following is not really an error. TSS cleanup support still is available for boost threads.
+// // Also this usually will be triggered only when bound to the static version of thread lib.
+// // 2006-10-02 Roland Schwarz
+// //BOOST_CHECK_EQUAL(tss_instances, 0);
+// BOOST_CHECK_MESSAGE(tss_instances == 0, "Support of automatic tss cleanup for native threading API not available");
+// BOOST_CHECK_EQUAL(tss_total, 5);
+}
+
+//BOOST_AUTO_TEST_CASE(test_tss_void)
+//{
+// timed_test(&do_test_tss_void, 2);
+//}
+
+
+boost::thread_specific_ptr<void> tss_void_with_cleanup(tss_void_custom_cleanup);
+
+void tss_void_thread_with_custom_cleanup()
+{
+ tss_void_with_cleanup.reset(new tss_value_t);
+}
+
+void do_test_tss_void_with_custom_cleanup()
+{
+ boost::thread t(tss_void_thread_with_custom_cleanup);
+ try
+ {
+ t.join();
+ }
+ catch(...)
+ {
+ t.interrupt();
+ t.join();
+ throw;
+ }
+
+ BOOST_CHECK(tss_void_cleanup_called);
+}
+
+
+BOOST_AUTO_TEST_CASE(test_tss_void_with_custom_cleanup)
+{
+ timed_test(&do_test_tss_void_with_custom_cleanup, 2);
+}
+
+
+bool tss_cleanup_called=false;
+
+struct Dummy
+{};
+
+void tss_custom_cleanup(Dummy* d)
+{
+ delete d;
+ tss_cleanup_called=true;
+}
+
+boost::thread_specific_ptr<Dummy> tss_with_cleanup(tss_custom_cleanup);
+
+void tss_thread_with_custom_cleanup()
+{
+ tss_with_cleanup.reset(new Dummy);
+}
+
+void do_test_tss_with_custom_cleanup()
+{
+ boost::thread t(tss_thread_with_custom_cleanup);
+ try
+ {
+ t.join();
+ }
+ catch(...)
+ {
+ t.interrupt();
+ t.join();
+ throw;
+ }
+
+ BOOST_CHECK(tss_cleanup_called);
+}
+
+
+BOOST_AUTO_TEST_CASE(test_tss_with_custom_cleanup)
+{
+ timed_test(&do_test_tss_with_custom_cleanup, 2);
+}
+
+Dummy* tss_object=new Dummy;
+
+void tss_thread_with_custom_cleanup_and_release()
+{
+ tss_with_cleanup.reset(tss_object);
+ tss_with_cleanup.release();
+}
+
+void do_test_tss_does_no_cleanup_after_release()
+{
+ tss_cleanup_called=false;
+ boost::thread t(tss_thread_with_custom_cleanup_and_release);
+ try
+ {
+ t.join();
+ }
+ catch(...)
+ {
+ t.interrupt();
+ t.join();
+ throw;
+ }
+
+ BOOST_CHECK(!tss_cleanup_called);
+ if(!tss_cleanup_called)
+ {
+ delete tss_object;
+ }
+}
+
+struct dummy_class_tracks_deletions
+{
+ static unsigned deletions;
+
+ ~dummy_class_tracks_deletions()
+ {
+ ++deletions;
+ }
+
+};
+
+unsigned dummy_class_tracks_deletions::deletions=0;
+
+boost::thread_specific_ptr<dummy_class_tracks_deletions> tss_with_null_cleanup(NULL);
+
+void tss_thread_with_null_cleanup(dummy_class_tracks_deletions* delete_tracker)
+{
+ tss_with_null_cleanup.reset(delete_tracker);
+}
+
+void do_test_tss_does_no_cleanup_with_null_cleanup_function()
+{
+ dummy_class_tracks_deletions* delete_tracker=new dummy_class_tracks_deletions;
+ boost::thread t(tss_thread_with_null_cleanup,delete_tracker);
+ try
+ {
+ t.join();
+ }
+ catch(...)
+ {
+ t.interrupt();
+ t.join();
+ throw;
+ }
+
+ BOOST_CHECK(!dummy_class_tracks_deletions::deletions);
+ if(!dummy_class_tracks_deletions::deletions)
+ {
+ delete delete_tracker;
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_tss_does_no_cleanup_after_release)
+{
+ timed_test(&do_test_tss_does_no_cleanup_after_release, 2);
+}
+
+BOOST_AUTO_TEST_CASE(test_tss_does_no_cleanup_with_null_cleanup_function)
+{
+ timed_test(&do_test_tss_does_no_cleanup_with_null_cleanup_function, 2);
+}
+
+void thread_with_local_tss_ptr()
+{
+ {
+ boost::thread_specific_ptr<Dummy> local_tss(tss_custom_cleanup);
+
+ local_tss.reset(new Dummy);
+ }
+ BOOST_CHECK(tss_cleanup_called);
+ tss_cleanup_called=false;
+}
+
+
+BOOST_AUTO_TEST_CASE(test_tss_does_not_call_cleanup_after_ptr_destroyed)
+{
+ boost::thread t(thread_with_local_tss_ptr);
+ t.join();
+ BOOST_CHECK(!tss_cleanup_called);
+}
+
+BOOST_AUTO_TEST_CASE(test_tss_cleanup_not_called_for_null_pointer)
+{
+ boost::thread_specific_ptr<Dummy> local_tss(tss_custom_cleanup);
+ local_tss.reset(new Dummy);
+ tss_cleanup_called=false;
+ local_tss.reset(0);
+ BOOST_CHECK(tss_cleanup_called);
+ tss_cleanup_called=false;
+ local_tss.reset(new Dummy);
+ BOOST_CHECK(!tss_cleanup_called);
+}
+
+//BOOST_AUTO_TEST_CASE(test_tss_at_the_same_adress)
+//{
+// for(int i=0; i<2; i++)
+// {
+// boost::thread_specific_ptr<Dummy> local_tss(tss_custom_cleanup);
+// local_tss.reset(new Dummy);
+// tss_cleanup_called=false;
+// BOOST_CHECK(tss_cleanup_called);
+// tss_cleanup_called=false;
+// BOOST_CHECK(!tss_cleanup_called);
+// }
+//}
+
diff --git a/src/boost/libs/thread/test/test_xtime.cpp b/src/boost/libs/thread/test/test_xtime.cpp
new file mode 100644
index 000000000..4988d1f86
--- /dev/null
+++ b/src/boost/libs/thread/test/test_xtime.cpp
@@ -0,0 +1,97 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+// Copyright (C) 2008 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 2
+#define BOOST_TEST_MODULE Boost.Threads: xtime test suite
+
+#include <boost/thread/detail/config.hpp>
+
+#include <boost/thread/xtime.hpp>
+
+#include <boost/test/unit_test.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+
+BOOST_AUTO_TEST_CASE(test_xtime_cmp)
+{
+ boost::xtime xt1, xt2, cur;
+ BOOST_CHECK_EQUAL(
+ boost::xtime_get(&cur, boost::TIME_UTC_),
+ static_cast<int>(boost::TIME_UTC_));
+
+ xt1 = xt2 = cur;
+ xt1.nsec -= 1;
+ xt2.nsec += 1;
+
+ BOOST_CHECK(boost::xtime_cmp(xt1, cur) < 0);
+ BOOST_CHECK(boost::xtime_cmp(xt2, cur) > 0);
+ BOOST_CHECK(boost::xtime_cmp(cur, cur) == 0);
+
+ xt1 = xt2 = cur;
+ xt1.sec -= 1;
+ xt2.sec += 1;
+
+ BOOST_CHECK(boost::xtime_cmp(xt1, cur) < 0);
+ BOOST_CHECK(boost::xtime_cmp(xt2, cur) > 0);
+ BOOST_CHECK(boost::xtime_cmp(cur, cur) == 0);
+}
+
+BOOST_AUTO_TEST_CASE(test_xtime_get)
+{
+ boost::xtime orig, cur, old;
+ BOOST_CHECK_EQUAL(
+ boost::xtime_get(&orig,
+ boost::TIME_UTC_), static_cast<int>(boost::TIME_UTC_));
+ old = orig;
+
+ for (int x=0; x < 100; ++x)
+ {
+ BOOST_CHECK_EQUAL(
+ boost::xtime_get(&cur, boost::TIME_UTC_),
+ static_cast<int>(boost::TIME_UTC_));
+ BOOST_CHECK(boost::xtime_cmp(cur, orig) >= 0);
+ BOOST_CHECK(boost::xtime_cmp(cur, old) >= 0);
+ old = cur;
+ }
+}
+
+BOOST_AUTO_TEST_CASE(test_xtime_mutex_backwards_compatibility)
+{
+ boost::timed_mutex m;
+ BOOST_CHECK(m.timed_lock(boost::get_xtime(boost::get_system_time()+boost::posix_time::milliseconds(10))));
+ m.unlock();
+ boost::timed_mutex::scoped_timed_lock lk(m,boost::get_xtime(boost::get_system_time()+boost::posix_time::milliseconds(10)));
+ BOOST_CHECK(lk.owns_lock());
+ if(lk.owns_lock())
+ {
+ lk.unlock();
+ }
+ BOOST_CHECK(lk.timed_lock(boost::get_xtime(boost::get_system_time()+boost::posix_time::milliseconds(10))));
+ if(lk.owns_lock())
+ {
+ lk.unlock();
+ }
+}
+
+bool predicate()
+{
+ return false;
+}
+
+
+BOOST_AUTO_TEST_CASE(test_xtime_condvar_backwards_compatibility)
+{
+ boost::condition_variable cond;
+ boost::condition_variable_any cond_any;
+ boost::mutex m;
+
+ boost::unique_lock<boost::mutex> lk(m);
+ cond.timed_wait(lk,boost::get_xtime(boost::get_system_time()+boost::posix_time::milliseconds(10)));
+ cond.timed_wait(lk,boost::get_xtime(boost::get_system_time()+boost::posix_time::milliseconds(10)),predicate);
+ cond_any.timed_wait(lk,boost::get_xtime(boost::get_system_time()+boost::posix_time::milliseconds(10)));
+ cond_any.timed_wait(lk,boost::get_xtime(boost::get_system_time()+boost::posix_time::milliseconds(10)),predicate);
+}
diff --git a/src/boost/libs/thread/test/threads/container/thread_ptr_list_pass.cpp b/src/boost/libs/thread/test/threads/container/thread_ptr_list_pass.cpp
new file mode 100644
index 000000000..76047051f
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/container/thread_ptr_list_pass.cpp
@@ -0,0 +1,101 @@
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_USES_MOVE
+
+#include <boost/config.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/csbl/list.hpp>
+//#include <boost/interprocess/smart_ptr/shared_ptr.hpp>
+#include <boost/smart_ptr.hpp>
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+
+int count = 0;
+boost::mutex mutex;
+
+namespace {
+
+
+template <typename TC>
+void join_all(TC & tc)
+{
+ for (typename TC::iterator it = tc.begin(); it != tc.end(); ++it)
+ {
+ (*it)->join();
+ }
+}
+
+
+void increment_count()
+{
+ boost::unique_lock<boost::mutex> lock(mutex);
+ std::cout << "count = " << ++count << std::endl;
+}
+
+template <class T>
+struct default_delete
+{
+ typedef T* pointer;
+
+ BOOST_CONSTEXPR default_delete() BOOST_NOEXCEPT {} //= default;
+ template <class U>
+ default_delete(const default_delete<U>&) BOOST_NOEXCEPT
+ {}
+ void operator()(T* ptr) const
+ {
+ delete ptr;
+ }
+};
+
+}
+int main()
+{
+ {
+ typedef boost::shared_ptr<boost::thread > thread_ptr;
+ //typedef boost::interprocess::shared_ptr<boost::thread, std::allocator<boost::thread>, default_delete<boost::thread> > thread_ptr;
+ typedef boost::csbl::list<thread_ptr > thread_ptr_list;
+ thread_ptr_list threads;
+ for (int i = 0; i < 10; ++i)
+ {
+ //threads.push_back(BOOST_THREAD_MAKE_RV_REF(thread_ptr(new boost::thread(&increment_count))));
+ threads.push_back(thread_ptr(new boost::thread(&increment_count)));
+ }
+ BOOST_TEST(threads.size()==10);
+ //join_all(threads);
+ for (thread_ptr_list::iterator it = threads.begin(); it != threads.end(); ++it)
+ {
+ (*it)->join();
+ }
+ }
+ count = 0;
+ {
+ typedef boost::shared_ptr<boost::thread > thread_ptr;
+ //typedef boost::interprocess::shared_ptr<boost::thread, std::allocator<boost::thread>, default_delete<boost::thread> > thread_ptr;
+ typedef boost::csbl::list<thread_ptr > thread_ptr_list;
+ thread_ptr_list threads;
+ for (int i = 0; i < 10; ++i)
+ {
+ //threads.push_back(BOOST_THREAD_MAKE_RV_REF(thread_ptr(new boost::thread(&increment_count))));
+ threads.push_back(thread_ptr(new boost::thread(&increment_count)));
+ }
+ BOOST_TEST(threads.size()==10);
+ thread_ptr sth(new boost::thread(&increment_count));
+ threads.push_back(sth);
+ BOOST_TEST(threads.size()==11);
+ threads.remove(sth);
+ BOOST_TEST(threads.size()==10);
+ sth->join();
+ //join_all(threads);
+ for (thread_ptr_list::iterator it = threads.begin(); it != threads.end(); ++it)
+ {
+ (*it)->join();
+ }
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/threads/container/thread_vector_pass.cpp b/src/boost/libs/thread/test/threads/container/thread_vector_pass.cpp
new file mode 100644
index 000000000..059a77e36
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/container/thread_vector_pass.cpp
@@ -0,0 +1,97 @@
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_USES_MOVE
+
+#include <boost/thread/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/csbl/vector.hpp>
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+int count = 0;
+boost::mutex mutex;
+
+namespace
+{
+template <typename TC>
+void join_all(TC & tc)
+{
+ for (typename TC::iterator it = tc.begin(); it != tc.end(); ++it)
+ {
+ it->join();
+ }
+}
+
+template <typename TC>
+void interrupt_all(TC & tc)
+{
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ for (typename TC::iterator it = tc.begin(); it != tc.end(); ++it)
+ {
+ it->interrupt();
+ }
+#endif
+}
+}
+
+void increment_count()
+{
+ boost::unique_lock<boost::mutex> lock(mutex);
+ std::cout << "count = " << ++count << std::endl;
+}
+
+#if defined BOOST_NO_CXX11_RVALUE_REFERENCES && defined BOOST_THREAD_USES_MOVE
+BOOST_STATIC_ASSERT(::boost::is_function<boost::rv<boost::rv<boost::thread> >&>::value==false);
+#endif
+
+int main()
+{
+ typedef boost::csbl::vector<boost::thread> thread_vector;
+ {
+ thread_vector threads;
+ threads.reserve(10);
+ for (int i = 0; i < 10; ++i)
+ {
+ boost::thread th(&increment_count);
+ threads.push_back(boost::move(th));
+ }
+ join_all(threads);
+ }
+ count = 0;
+ {
+ thread_vector threads;
+ threads.reserve(10);
+ for (int i = 0; i < 10; ++i)
+ {
+ threads.push_back(BOOST_THREAD_MAKE_RV_REF(boost::thread(&increment_count)));
+ }
+ join_all(threads);
+ }
+ count = 0;
+ {
+ thread_vector threads;
+ threads.reserve(10);
+ for (int i = 0; i < 10; ++i)
+ {
+ threads.emplace_back(&increment_count);
+ }
+ join_all(threads);
+ }
+ count = 0;
+ {
+ thread_vector threads;
+ threads.reserve(10);
+ for (int i = 0; i < 10; ++i)
+ {
+ threads.emplace_back(&increment_count);
+ }
+ interrupt_all(threads);
+ join_all(threads);
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/threads/this_thread/get_id/get_id_pass.cpp b/src/boost/libs/thread/test/threads/this_thread/get_id/get_id_pass.cpp
new file mode 100644
index 000000000..f0287cb6a
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/this_thread/get_id/get_id_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// thread::id this_thread::get_id();
+
+#include <boost/thread/thread_only.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::thread::id id = boost::this_thread::get_id();
+ BOOST_TEST(id != boost::thread::id());
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/threads/this_thread/sleep_for/sleep_for_pass.cpp b/src/boost/libs/thread/test/threads/this_thread/sleep_for/sleep_for_pass.cpp
new file mode 100644
index 000000000..05c5a790d
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/this_thread/sleep_for/sleep_for_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// thread::id this_thread::get_id();
+
+#include <boost/thread/thread_only.hpp>
+#include <cstdlib>
+#include <algorithm>
+
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+int main()
+{
+ {
+ typedef boost::chrono::system_clock Clock;
+ typedef Clock::time_point time_point;
+ boost::chrono::milliseconds ms(500);
+ time_point t0 = Clock::now();
+ boost::this_thread::sleep_for(ms);
+ time_point t1 = Clock::now();
+ boost::chrono::nanoseconds ns = (t1 - t0) - ms;
+ boost::chrono::nanoseconds err = ms / 100;
+ // The time slept is within 1% of 500ms
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST((std::max)(ns.count(), -ns.count()) < (err+boost::chrono::milliseconds(1000)).count());
+ //BOOST_TEST(std::abs(static_cast<long>(ns.count())) < (err+boost::chrono::milliseconds(1000)).count());
+ }
+ {
+ typedef boost::chrono::system_clock Clock;
+ typedef Clock::time_point time_point;
+ boost::chrono::milliseconds ms(500);
+ time_point t0 = Clock::now();
+ boost::this_thread::no_interruption_point::sleep_for(ms);
+ time_point t1 = Clock::now();
+ boost::chrono::nanoseconds ns = (t1 - t0) - ms;
+ boost::chrono::nanoseconds err = ms / 100;
+ // The time slept is within 1% of 500ms
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST((std::max)(ns.count(), -ns.count()) < (err+boost::chrono::milliseconds(1000)).count());
+ //BOOST_TEST(std::abs(static_cast<long>(ns.count())) < (err+boost::chrono::milliseconds(1000)).count());
+ }
+ return boost::report_errors();
+
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/src/boost/libs/thread/test/threads/this_thread/sleep_until/sleep_until_pass.cpp b/src/boost/libs/thread/test/threads/this_thread/sleep_until/sleep_until_pass.cpp
new file mode 100644
index 000000000..232712eed
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/this_thread/sleep_until/sleep_until_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// thread::id this_thread::get_id();
+
+#include <boost/thread/thread_only.hpp>
+#include <cstdlib>
+#include <algorithm>
+
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+int main()
+{
+ {
+ typedef boost::chrono::steady_clock Clock;
+ typedef Clock::time_point time_point;
+ //typedef Clock::duration duration;
+ boost::chrono::milliseconds ms(500);
+ time_point t0 = Clock::now();
+ boost::this_thread::sleep_until(t0 + ms);
+ time_point t1 = Clock::now();
+ boost::chrono::nanoseconds ns = (t1 - t0) - ms;
+ boost::chrono::nanoseconds err = ms / 100;
+ // The time slept is within 1% of 500ms
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST((std::max)(ns.count(), -ns.count()) < (err+boost::chrono::milliseconds(1000)).count());
+ //BOOST_TEST(std::abs(static_cast<long>(ns.count())) < (err+boost::chrono::milliseconds(1000)).count());
+ }
+ {
+ typedef boost::chrono::system_clock Clock;
+ typedef Clock::time_point time_point;
+ //typedef Clock::duration duration;
+ boost::chrono::milliseconds ms(500);
+ time_point t0 = Clock::now();
+ boost::this_thread::sleep_until(t0 + ms);
+ time_point t1 = Clock::now();
+ boost::chrono::nanoseconds ns = (t1 - t0) - ms;
+ boost::chrono::nanoseconds err = ms / 100;
+ // The time slept is within 1% of 500ms
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST((std::max)(ns.count(), -ns.count()) < (err+boost::chrono::milliseconds(1000)).count());
+ //BOOST_TEST(std::abs(static_cast<long>(ns.count())) < (err+boost::chrono::milliseconds(1000)).count());
+ }
+ {
+ typedef boost::chrono::steady_clock Clock;
+ typedef Clock::time_point time_point;
+ //typedef Clock::duration duration;
+ boost::chrono::milliseconds ms(500);
+ time_point t0 = Clock::now();
+ boost::this_thread::no_interruption_point::sleep_until(t0 + ms);
+ time_point t1 = Clock::now();
+ boost::chrono::nanoseconds ns = (t1 - t0) - ms;
+ boost::chrono::nanoseconds err = ms / 100;
+ // The time slept is within 1% of 500ms
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST((std::max)(ns.count(), -ns.count()) < (err+boost::chrono::milliseconds(1000)).count());
+ //BOOST_TEST(std::abs(static_cast<long>(ns.count())) < (err+boost::chrono::milliseconds(1000)).count());
+ }
+ {
+ typedef boost::chrono::system_clock Clock;
+ typedef Clock::time_point time_point;
+ //typedef Clock::duration duration;
+ boost::chrono::milliseconds ms(500);
+ time_point t0 = Clock::now();
+ boost::this_thread::no_interruption_point::sleep_until(t0 + ms);
+ time_point t1 = Clock::now();
+ boost::chrono::nanoseconds ns = (t1 - t0) - ms;
+ boost::chrono::nanoseconds err = ms / 100;
+ // The time slept is within 1% of 500ms
+ // This test is spurious as it depends on the time the thread system switches the threads
+ BOOST_TEST((std::max)(ns.count(), -ns.count()) < (err+boost::chrono::milliseconds(1000)).count());
+ //BOOST_TEST(std::abs(static_cast<long>(ns.count())) < (err+boost::chrono::milliseconds(1000)).count());
+ }
+ return boost::report_errors();
+
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
+
diff --git a/src/boost/libs/thread/test/threads/thread/assign/copy_fail.cpp b/src/boost/libs/thread/test/threads/thread/assign/copy_fail.cpp
new file mode 100644
index 000000000..5ccac5b31
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/assign/copy_fail.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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// thread& operator=(thread&& t);
+
+#include <boost/thread/thread_only.hpp>
+#include <new>
+#include <cstdlib>
+#include <boost/detail/lightweight_test.hpp>
+
+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()()
+ {
+ BOOST_TEST(alive_ == 1);
+ //BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ boost::thread t0( (G()));
+ boost::thread t1;
+ t1 = t0;
+ }
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
diff --git a/src/boost/libs/thread/test/threads/thread/assign/move_pass.cpp b/src/boost/libs/thread/test/threads/thread/assign/move_pass.cpp
new file mode 100644
index 000000000..293c5d838
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/assign/move_pass.cpp
@@ -0,0 +1,101 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// thread& operator=(thread&& t);
+
+#define BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
+
+#include <boost/thread/thread_only.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/detail/lightweight_test.hpp>
+
+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()()
+ {
+ BOOST_TEST(alive_ == 1);
+ //BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+
+ void operator()(int i, double j)
+ {
+ BOOST_TEST(alive_ == 1);
+ //BOOST_TEST(n_alive == 1);
+ BOOST_TEST(i == 5);
+ BOOST_TEST(j == 5.5);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+void f1()
+{
+ std::exit(boost::report_errors());
+}
+
+int main()
+{
+ std::set_terminate(f1);
+ {
+ BOOST_TEST(G::n_alive == 0);
+ BOOST_TEST(!G::op_run);
+ boost::thread t0(G(), 5, 5.5);
+ boost::thread::id id = t0.get_id();
+ boost::thread t1;
+ t1 = boost::move(t0);
+ BOOST_TEST(t1.get_id() == id);
+ BOOST_TEST(t0.get_id() == boost::thread::id());
+ t1.join();
+ BOOST_TEST(G::op_run);
+ }
+ BOOST_TEST(G::n_alive == 0);
+ {
+ boost::thread t0(G(), 5, 5.5);
+ boost::thread t1;
+ t0 = boost::move(t1);
+ BOOST_TEST(false);
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/threads/thread/constr/FArgs_pass.cpp b/src/boost/libs/thread/test/threads/thread/constr/FArgs_pass.cpp
new file mode 100644
index 000000000..afdc7018f
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/constr/FArgs_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// template <class F, class ...Args> thread(F f, Args... args);
+
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/thread/thread_only.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+unsigned throw_one = 0xFFFF;
+
+#if defined _GLIBCXX_THROW
+void* operator new(std::size_t s) _GLIBCXX_THROW (std::bad_alloc)
+#elif defined BOOST_MSVC
+void* operator new(std::size_t s)
+#elif __cplusplus > 201402L
+void* operator new(std::size_t s)
+#else
+void* operator new(std::size_t s) throw (std::bad_alloc)
+#endif
+{
+ //std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ if (throw_one == 0) throw std::bad_alloc();
+ --throw_one;
+ return std::malloc(s);
+}
+
+#if defined BOOST_MSVC
+void operator delete(void* p)
+#else
+void operator delete(void* p) BOOST_NOEXCEPT_OR_NOTHROW
+#endif
+{
+ //std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ std::free(p);
+}
+
+bool f_run = false;
+
+void f(int i, double j)
+{
+ BOOST_TEST(i == 5);
+ BOOST_TEST(j == 5.5);
+ 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()(int i, double j)
+ {
+ BOOST_TEST(alive_ == 1);
+ //BOOST_TEST(n_alive >= 1);
+ BOOST_TEST(i == 5);
+ BOOST_TEST(j == 5.5);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+
+int main()
+{
+ {
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ boost::thread t(f, 5, 5.5);
+ t.join();
+ BOOST_TEST(f_run == true);
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ }
+#if !defined(BOOST_MSVC) && !defined(__MINGW32__)
+ f_run = false;
+ {
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ try
+ {
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ throw_one = 0;
+ boost::thread t(f, 5, 5.5);
+ BOOST_TEST(false);
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ }
+ catch (...)
+ {
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ throw_one = 0xFFFF;
+ BOOST_TEST(!f_run);
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ }
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ }
+#endif
+ {
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ BOOST_TEST(G::n_alive == 0);
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ BOOST_TEST(!G::op_run);
+ boost::thread t(G(), 5, 5.5);
+ t.join();
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ BOOST_TEST(G::n_alive == 0);
+ BOOST_TEST(G::op_run);
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/threads/thread/constr/F_pass.cpp b/src/boost/libs/thread/test/threads/thread/constr/F_pass.cpp
new file mode 100644
index 000000000..7fd2bbc24
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/constr/F_pass.cpp
@@ -0,0 +1,150 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// template <class F, class ...Args> thread(F f, Args... args);
+
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/thread/thread_only.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+unsigned throw_one = 0xFFFF;
+
+#if defined _GLIBCXX_THROW
+void* operator new(std::size_t s) _GLIBCXX_THROW (std::bad_alloc)
+#elif defined BOOST_MSVC
+void* operator new(std::size_t s)
+#elif __cplusplus > 201402L
+void* operator new(std::size_t s)
+#else
+void* operator new(std::size_t s) throw (std::bad_alloc)
+#endif
+{
+ //std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ if (throw_one == 0) throw std::bad_alloc();
+ --throw_one;
+ return std::malloc(s);
+}
+
+#if defined BOOST_MSVC
+void operator delete(void* p)
+#else
+void operator delete(void* p) BOOST_NOEXCEPT_OR_NOTHROW
+#endif
+{
+ //std::cout << __FILE__ << ":" << __LINE__ << std::endl;
+ 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()()
+ {
+ BOOST_TEST(alive_ == 1);
+ //BOOST_TEST(n_alive >= 1);
+ op_run = true;
+ }
+
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+
+int main()
+{
+ {
+ boost::thread t(f);
+ t.join();
+ BOOST_TEST(f_run == true);
+ }
+ f_run = false;
+#if !defined(BOOST_MSVC) && !defined(__MINGW32__)
+ {
+ try
+ {
+ throw_one = 0;
+ boost::thread t(f);
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ throw_one = 0xFFFF;
+ BOOST_TEST(!f_run);
+ }
+ }
+#endif
+ {
+ BOOST_TEST(G::n_alive == 0);
+ BOOST_TEST(!G::op_run);
+ boost::thread t( (G()));
+ t.join();
+ BOOST_TEST(G::n_alive == 0);
+ BOOST_TEST(G::op_run);
+ }
+#if !defined(BOOST_MSVC) && !defined(__MINGW32__)
+ G::op_run = false;
+ {
+ try
+ {
+ throw_one = 0;
+ BOOST_TEST(G::n_alive == 0);
+ BOOST_TEST(!G::op_run);
+ boost::thread t( (G()));
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ throw_one = 0xFFFF;
+ BOOST_TEST(G::n_alive == 0);
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << G::n_alive << std::endl;
+ BOOST_TEST(!G::op_run);
+ }
+ }
+#endif
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/threads/thread/constr/FrvalueArgs_pass.cpp b/src/boost/libs/thread/test/threads/thread/constr/FrvalueArgs_pass.cpp
new file mode 100644
index 000000000..e76db7022
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/constr/FrvalueArgs_pass.cpp
@@ -0,0 +1,103 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// template <class F, class ...Args> thread(F&& f, Args&&... args);
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/thread_only.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/detail/lightweight_test.hpp>
+
+class MoveOnly
+{
+public:
+ BOOST_THREAD_MOVABLE_ONLY(MoveOnly)
+ MoveOnly()
+ {
+ }
+ MoveOnly(BOOST_THREAD_RV_REF(MoveOnly))
+ {}
+
+ void operator()(BOOST_THREAD_RV_REF(MoveOnly))
+ {
+ }
+};
+
+class M
+{
+
+public:
+ long data_;
+ static int n_moves;
+
+ BOOST_THREAD_MOVABLE_ONLY(M)
+ static void reset() {
+ n_moves=0;
+ }
+ explicit M(long i) : data_(i)
+ {
+ }
+ M(BOOST_THREAD_RV_REF(M) a) : data_(BOOST_THREAD_RV(a).data_)
+ {
+ BOOST_THREAD_RV(a).data_ = -1;
+ ++n_moves;
+ }
+ M& operator=(BOOST_THREAD_RV_REF(M) a)
+ {
+ data_ = BOOST_THREAD_RV(a).data_;
+ BOOST_THREAD_RV(a).data_ = -1;
+ ++n_moves;
+ return *this;
+ }
+ ~M()
+ {
+ }
+
+ void operator()(int) const
+ { }
+ long operator()() const
+ { return data_;}
+ long operator()(long i, long j) const
+ { return data_ + i + j;}
+};
+
+int M::n_moves = 0;
+
+void fct(BOOST_THREAD_RV_REF(M) v)
+{
+ BOOST_TEST_EQ(v.data_, 1);
+}
+
+int main()
+{
+#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ {
+ boost::thread t = boost::thread( MoveOnly(), MoveOnly() );
+ t.join();
+ }
+ {
+ M::reset();
+ boost::thread t = boost::thread( fct, M(1) );
+ t.join();
+ BOOST_TEST_EQ(M::n_moves, 2);
+ }
+#endif
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/threads/thread/constr/Frvalue_pass.cpp b/src/boost/libs/thread/test/threads/thread/constr/Frvalue_pass.cpp
new file mode 100644
index 000000000..38061e0a7
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/constr/Frvalue_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// template <class F, class ...Args> thread(F&& f, Args&&... args);
+
+#define BOOST_THREAD_USES_MOVE
+
+#include <boost/thread/thread_only.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/static_assert.hpp>
+
+class MoveOnly
+{
+public:
+ BOOST_THREAD_MOVABLE_ONLY(MoveOnly)
+ MoveOnly()
+ {
+ }
+ MoveOnly(BOOST_THREAD_RV_REF(MoveOnly))
+ {}
+
+ void operator()()
+ {
+ }
+};
+
+MoveOnly MakeMoveOnly() {
+ return BOOST_THREAD_MAKE_RV_REF(MoveOnly());
+}
+
+#if defined BOOST_NO_CXX11_RVALUE_REFERENCES && defined BOOST_THREAD_USES_MOVE
+BOOST_STATIC_ASSERT(::boost::is_function<boost::rv<boost::rv<MoveOnly> >&>::value==false);
+#endif
+
+int main()
+{
+ {
+ boost::thread t(( BOOST_THREAD_MAKE_RV_REF(MakeMoveOnly()) ));
+ t.join();
+ }
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/threads/thread/constr/copy_fail.cpp b/src/boost/libs/thread/test/threads/thread/constr/copy_fail.cpp
new file mode 100644
index 000000000..caa72c2d8
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/constr/copy_fail.cpp
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// thread(const thread&) = delete;
+
+#include <boost/thread/thread_only.hpp>
+#include <new>
+#include <cstdlib>
+#include <boost/detail/lightweight_test.hpp>
+
+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()()
+ {
+ BOOST_TEST(alive_ == 1);
+ //BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+
+ void operator()(int i, double j)
+ {
+ BOOST_TEST(alive_ == 1);
+ //BOOST_TEST(n_alive == 1);
+ BOOST_TEST(i == 5);
+ BOOST_TEST(j == 5.5);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ BOOST_TEST(G::n_alive == 0);
+ BOOST_TEST(!G::op_run);
+ boost::thread t0(G(), 5, 5.5);
+ boost::thread::id id = t0.get_id();
+ boost::thread t1( (t0));
+ BOOST_TEST(t1.get_id() == id);
+ BOOST_TEST(t0.get_id() == boost::thread::id());
+ t1.join();
+ BOOST_TEST(G::n_alive == 0);
+ BOOST_TEST(G::op_run);
+ }
+}
+
+#include "../../../remove_error_code_unused_warning.hpp"
+
diff --git a/src/boost/libs/thread/test/threads/thread/constr/default_pass.cpp b/src/boost/libs/thread/test/threads/thread/constr/default_pass.cpp
new file mode 100644
index 000000000..cea602d15
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/constr/default_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.
+//
+//===----------------------------------------------------------------------===//
+
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// thread();
+
+#include <boost/thread/thread_only.hpp>
+#include <cassert>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ boost::thread t;
+ BOOST_TEST(t.get_id() == boost::thread::id());
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/threads/thread/constr/lambda_pass.cpp b/src/boost/libs/thread/test/threads/thread/constr/lambda_pass.cpp
new file mode 100644
index 000000000..84615bf88
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/constr/lambda_pass.cpp
@@ -0,0 +1,89 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// template <class Clousure> thread(Clousure f);
+
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/thread/thread_only.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if ! defined BOOST_NO_CXX11_LAMBDAS
+
+unsigned throw_one = 0xFFFF;
+
+#if defined _GLIBCXX_THROW
+void* operator new(std::size_t s) _GLIBCXX_THROW (std::bad_alloc)
+#elif defined BOOST_MSVC
+void* operator new(std::size_t s)
+#elif __cplusplus > 201402L
+void* operator new(std::size_t s)
+#else
+void* operator new(std::size_t s) throw (std::bad_alloc)
+#endif
+{
+ if (throw_one == 0) throw std::bad_alloc();
+ --throw_one;
+ return std::malloc(s);
+}
+
+#if defined BOOST_MSVC
+void operator delete(void* p)
+#else
+void operator delete(void* p) BOOST_NOEXCEPT_OR_NOTHROW
+#endif
+{
+ std::free(p);
+}
+
+bool f_run = false;
+
+int main()
+{
+ {
+ f_run = false;
+ boost::thread t( []() { f_run = true; } );
+ t.join();
+ BOOST_TEST(f_run == true);
+ }
+#if !defined(BOOST_MSVC) && !defined(__MINGW32__)
+ {
+ f_run = false;
+ try
+ {
+ throw_one = 0;
+ boost::thread t( []() { f_run = true; } );
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ throw_one = 0xFFFF;
+ BOOST_TEST(!f_run);
+ }
+ }
+#endif
+
+ return boost::report_errors();
+}
+
+#else
+int main()
+{
+ return 0;
+}
+#endif
diff --git a/src/boost/libs/thread/test/threads/thread/constr/move_pass.cpp b/src/boost/libs/thread/test/threads/thread/constr/move_pass.cpp
new file mode 100644
index 000000000..66f9d7546
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/constr/move_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// thread(thread&& t);
+
+#include <boost/thread/thread_only.hpp>
+#include <new>
+#include <cstdlib>
+#include <boost/detail/lightweight_test.hpp>
+
+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()()
+ {
+ BOOST_TEST(alive_ == 1);
+ //BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+
+ void operator()(int i, double j)
+ {
+ BOOST_TEST(alive_ == 1);
+ std::cout << __FILE__ << ":" << __LINE__ <<" " << n_alive << std::endl;
+ //BOOST_TEST(n_alive == 1);
+ BOOST_TEST(i == 5);
+ BOOST_TEST(j == 5.5);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+boost::thread make_thread() {
+ return boost::thread(G(), 5, 5.5);
+}
+
+int main()
+{
+ {
+ //BOOST_TEST(G::n_alive == 0);
+ BOOST_TEST(!G::op_run);
+ boost::thread t0((G()));
+ boost::thread::id id = t0.get_id();
+ boost::thread t1((boost::move(t0)));
+ BOOST_TEST(t1.get_id() == id);
+ BOOST_TEST(t0.get_id() == boost::thread::id());
+ t1.join();
+ BOOST_TEST(G::op_run);
+ }
+ //BOOST_TEST(G::n_alive == 0);
+ {
+ boost::thread t1((BOOST_THREAD_MAKE_RV_REF(make_thread())));
+ t1.join();
+ BOOST_TEST(G::op_run);
+ }
+ //BOOST_TEST(G::n_alive == 0);
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/thread/test/threads/thread/destr/dtor_pass.cpp b/src/boost/libs/thread/test/threads/thread/destr/dtor_pass.cpp
new file mode 100644
index 000000000..ea0e6bac4
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/destr/dtor_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// ~thread();
+
+#define BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
+
+#include <boost/thread/thread_only.hpp>
+#include <new>
+#include <cstdlib>
+#include <boost/detail/lightweight_test.hpp>
+
+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()()
+ {
+ BOOST_TEST(alive_ == 1);
+ //BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+void f1()
+{
+ std::exit(boost::report_errors());
+}
+
+int main()
+{
+ std::set_terminate(f1);
+ {
+ BOOST_TEST(G::n_alive == 0);
+ BOOST_TEST(!G::op_run);
+ boost::thread t( (G()));
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(250));
+#endif
+ BOOST_TEST(t.joinable());
+ }
+ BOOST_TEST(false);
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/threads/thread/id/hash_pass.cpp b/src/boost/libs/thread/test/threads/thread/id/hash_pass.cpp
new file mode 100644
index 000000000..6ce52c97a
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/id/hash_pass.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// <functional>
+
+// template <class T>
+// struct hash
+// : public unary_function<T, size_t>
+// {
+// size_t operator()(T val) const;
+// };
+
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ {
+ boost::thread::id id1;
+ boost::thread::id id2 = boost::this_thread::get_id();
+ typedef boost::hash<boost::thread::id> H;
+ H h;
+ BOOST_TEST(h(id1) != h(id2));
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/threads/thread/members/detach_pass.cpp b/src/boost/libs/thread/test/threads/thread/members/detach_pass.cpp
new file mode 100644
index 000000000..927175338
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/members/detach_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// void detach();
+
+#include <boost/thread/thread_only.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/detail/lightweight_test.hpp>
+
+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()()
+ {
+ BOOST_TEST(alive_ == 1);
+ //BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ t0.detach();
+ BOOST_TEST(!t0.joinable());
+#if defined BOOST_THREAD_USES_CHRONO
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(250));
+ BOOST_TEST(G::op_run);
+ BOOST_TEST(G::n_alive == 0);
+#endif
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/threads/thread/members/get_id_pass.cpp b/src/boost/libs/thread/test/threads/thread/members/get_id_pass.cpp
new file mode 100644
index 000000000..dcaa7090b
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/members/get_id_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// id get_id() const;
+
+#include <boost/thread/thread_only.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/detail/lightweight_test.hpp>
+
+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()()
+ {
+ BOOST_TEST(alive_ == 1);
+ //BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ boost::thread t0( (G()));
+ //boost::thread::id id0 = t0.get_id();
+ boost::thread t1;
+ boost::thread::id id1 = t1.get_id();
+ BOOST_TEST(t0.get_id() != id1);
+ BOOST_TEST(t1.get_id() == boost::thread::id());
+ t0.join();
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/threads/thread/members/join_pass.cpp b/src/boost/libs/thread/test/threads/thread/members/join_pass.cpp
new file mode 100644
index 000000000..f2d42b72b
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/members/join_pass.cpp
@@ -0,0 +1,135 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// void join();
+#define BOOST_THREAD_VESRION 3
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+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()()
+ {
+ BOOST_TEST(alive_ == 1);
+ //BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+boost::thread* resource_deadlock_would_occur_th=0;
+boost::mutex resource_deadlock_would_occur_mtx;
+void resource_deadlock_would_occur_tester()
+{
+ try
+ {
+ boost::unique_lock<boost::mutex> lk(resource_deadlock_would_occur_mtx);
+ resource_deadlock_would_occur_th->join();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false&&"exception thrown");
+ }
+}
+
+int main()
+{
+ {
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ t0.join();
+ BOOST_TEST(!t0.joinable());
+ }
+
+ {
+ boost::unique_lock<boost::mutex> lk(resource_deadlock_would_occur_mtx);
+ boost::thread t0( resource_deadlock_would_occur_tester );
+ resource_deadlock_would_occur_th = &t0;
+ BOOST_TEST(t0.joinable());
+ lk.unlock();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
+ boost::unique_lock<boost::mutex> lk2(resource_deadlock_would_occur_mtx);
+ t0.join();
+ BOOST_TEST(!t0.joinable());
+ }
+
+ {
+ boost::thread t0( (G()));
+ t0.detach();
+ try
+ {
+ t0.join();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
+ }
+ }
+ {
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ t0.join();
+ try
+ {
+ t0.join();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
+ }
+
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/threads/thread/members/joinable_pass.cpp b/src/boost/libs/thread/test/threads/thread/members/joinable_pass.cpp
new file mode 100644
index 000000000..dcf09d1f8
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/members/joinable_pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// bool joinable() const;
+
+#include <boost/thread/thread_only.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/detail/lightweight_test.hpp>
+
+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()()
+ {
+ BOOST_TEST(alive_ == 1);
+ //BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ t0.join();
+ BOOST_TEST(!t0.joinable());
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/threads/thread/members/native_handle_pass.cpp b/src/boost/libs/thread/test/threads/thread/members/native_handle_pass.cpp
new file mode 100644
index 000000000..01115da05
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/members/native_handle_pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// native_handle_type native_handle();
+
+#include <boost/thread/thread_only.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/detail/lightweight_test.hpp>
+
+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()()
+ {
+ BOOST_TEST(alive_ == 1);
+ //BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ boost::thread t0( (G()));
+ // boost::thread::native_handle_type hdl =
+ (void)t0.native_handle();
+ t0.join();
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/threads/thread/members/swap_pass.cpp b/src/boost/libs/thread/test/threads/thread/members/swap_pass.cpp
new file mode 100644
index 000000000..16af2d1b8
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/members/swap_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// native_handle_type native_handle();
+
+#include <boost/thread/thread_only.hpp>
+#include <cstdlib>
+#include <boost/detail/lightweight_test.hpp>
+
+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()()
+ {
+ BOOST_TEST(alive_ == 1);
+ std::cout << n_alive << std::endl;
+ //BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ boost::thread t0( (G()));
+ boost::thread::id id0 = t0.get_id();
+ boost::thread t1;
+ boost::thread::id id1 = t1.get_id();
+ t0.swap(t1);
+ BOOST_TEST(t0.get_id() == id1);
+ BOOST_TEST(t1.get_id() == id0);
+ t1.join();
+ return boost::report_errors();
+ }
+}
+
diff --git a/src/boost/libs/thread/test/threads/thread/members/try_join_for_pass.cpp b/src/boost/libs/thread/test/threads/thread/members/try_join_for_pass.cpp
new file mode 100644
index 000000000..5215d18d6
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/members/try_join_for_pass.cpp
@@ -0,0 +1,161 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// template <class Rep, class Period>
+// bool try_join_for(const chrono::duration<Rep, Period>& rel_time);
+
+#define BOOST_THREAD_VESRION 3
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+class G
+{
+ int alive_;
+public:
+ static bool op_run;
+
+ G() :
+ alive_(1)
+ {
+ }
+ G(const G& g) :
+ alive_(g.alive_)
+ {
+ }
+ ~G()
+ {
+ alive_ = 0;
+ }
+
+ void operator()()
+ {
+ BOOST_TEST(alive_ == 1);
+ op_run = true;
+ }
+};
+
+bool G::op_run = false;
+
+boost::thread* resource_deadlock_would_occur_th=0;
+boost::mutex resource_deadlock_would_occur_mtx;
+void resource_deadlock_would_occur_tester()
+{
+ try
+ {
+ boost::unique_lock<boost::mutex> lk(resource_deadlock_would_occur_mtx);
+ resource_deadlock_would_occur_th->try_join_for(boost::chrono::milliseconds(50));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false&&"exception thrown");
+ }
+}
+
+void th_250_ms()
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(250));
+}
+
+int main()
+{
+ {
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ BOOST_TEST(t0.try_join_for(boost::chrono::milliseconds(250)));
+ BOOST_TEST(!t0.joinable());
+ }
+ {
+ boost::thread t0( (th_250_ms));
+ BOOST_TEST(!t0.try_join_for(boost::chrono::milliseconds(50)));
+ t0.join();
+ }
+
+ {
+ boost::unique_lock<boost::mutex> lk(resource_deadlock_would_occur_mtx);
+ boost::thread t0( resource_deadlock_would_occur_tester );
+ resource_deadlock_would_occur_th = &t0;
+ BOOST_TEST(t0.joinable());
+ lk.unlock();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(250));
+ boost::unique_lock<boost::mutex> lk2(resource_deadlock_would_occur_mtx);
+ t0.join();
+ BOOST_TEST(!t0.joinable());
+ }
+
+ {
+ boost::thread t0( (G()));
+ t0.detach();
+ try
+ {
+ t0.try_join_for(boost::chrono::milliseconds(50));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
+ }
+ }
+ {
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ t0.join();
+ try
+ {
+ t0.try_join_for(boost::chrono::milliseconds(50));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
+ }
+
+ }
+ {
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ t0.try_join_for(boost::chrono::milliseconds(250));
+ try
+ {
+ t0.join();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
+ }
+
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/threads/thread/members/try_join_until_pass.cpp b/src/boost/libs/thread/test/threads/thread/members/try_join_until_pass.cpp
new file mode 100644
index 000000000..749ff5b06
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/members/try_join_until_pass.cpp
@@ -0,0 +1,162 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// template <class Clock, class Duration>
+// bool try_join_until(const chrono::time_point<Clock, Duration>& t);
+
+#define BOOST_THREAD_VESRION 3
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined BOOST_THREAD_USES_CHRONO
+
+class G
+{
+ int alive_;
+public:
+ static bool op_run;
+
+ G() :
+ alive_(1)
+ {
+ }
+ G(const G& g) :
+ alive_(g.alive_)
+ {
+ }
+ ~G()
+ {
+ alive_ = 0;
+ }
+
+ void operator()()
+ {
+ BOOST_TEST(alive_ == 1);
+ op_run = true;
+ }
+};
+
+bool G::op_run = false;
+
+boost::thread* resource_deadlock_would_occur_th=0;
+boost::mutex resource_deadlock_would_occur_mtx;
+void resource_deadlock_would_occur_tester()
+{
+ try
+ {
+ boost::unique_lock<boost::mutex> lk(resource_deadlock_would_occur_mtx);
+ resource_deadlock_would_occur_th->try_join_until(boost::chrono::steady_clock::now()+boost::chrono::milliseconds(50));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur);
+ }
+ catch (...)
+ {
+ BOOST_TEST(false&&"exception thrown");
+ }
+}
+
+void th_250_ms()
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(250));
+}
+
+
+int main()
+{
+ {
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ t0.try_join_until(boost::chrono::steady_clock::now()+boost::chrono::milliseconds(250));
+ BOOST_TEST(!t0.joinable());
+ }
+ {
+ boost::thread t0( (th_250_ms));
+ BOOST_TEST(!t0.try_join_until(boost::chrono::steady_clock::now()+boost::chrono::milliseconds(50)));
+ t0.join();
+ }
+
+ {
+ boost::unique_lock<boost::mutex> lk(resource_deadlock_would_occur_mtx);
+ boost::thread t0( resource_deadlock_would_occur_tester );
+ resource_deadlock_would_occur_th = &t0;
+ BOOST_TEST(t0.joinable());
+ lk.unlock();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(250));
+ boost::unique_lock<boost::mutex> lk2(resource_deadlock_would_occur_mtx);
+ t0.join();
+ BOOST_TEST(!t0.joinable());
+ }
+
+ {
+ boost::thread t0( (G()));
+ t0.detach();
+ try
+ {
+ t0.try_join_until(boost::chrono::steady_clock::now()+boost::chrono::milliseconds(50));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
+ }
+ }
+ {
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ t0.join();
+ try
+ {
+ t0.try_join_until(boost::chrono::steady_clock::now()+boost::chrono::milliseconds(50));
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
+ }
+
+ }
+ {
+ boost::thread t0( (G()));
+ BOOST_TEST(t0.joinable());
+ t0.try_join_until(boost::chrono::steady_clock::now()+boost::chrono::milliseconds(250));
+ try
+ {
+ t0.join();
+ BOOST_TEST(false);
+ }
+ catch (boost::system::system_error& e)
+ {
+ BOOST_TEST(e.code().value() == boost::system::errc::invalid_argument);
+ }
+
+ }
+
+ return boost::report_errors();
+}
+
+#else
+#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
+#endif
diff --git a/src/boost/libs/thread/test/threads/thread/non_members/swap_pass.cpp b/src/boost/libs/thread/test/threads/thread/non_members/swap_pass.cpp
new file mode 100644
index 000000000..eb6faf157
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/non_members/swap_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// void swap(thread& x, thread& y);
+
+#include <boost/thread/thread_only.hpp>
+#include <new>
+#include <cstdlib>
+#include <cassert>
+#include <boost/detail/lightweight_test.hpp>
+
+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()()
+ {
+ BOOST_TEST(alive_ == 1);
+ //BOOST_TEST(n_alive == 1);
+ op_run = true;
+ }
+};
+
+int G::n_alive = 0;
+bool G::op_run = false;
+
+int main()
+{
+ {
+ boost::thread t0( (G()));
+ boost::thread::id id0 = t0.get_id();
+ boost::thread t1;
+ boost::thread::id id1 = t1.get_id();
+ swap(t0, t1);
+ BOOST_TEST(t0.get_id() == id1);
+ BOOST_TEST(t1.get_id() == id0);
+ t1.join();
+ }
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/threads/thread/static/hardware_concurrency_pass.cpp b/src/boost/libs/thread/test/threads/thread/static/hardware_concurrency_pass.cpp
new file mode 100644
index 000000000..2a2a227ed
--- /dev/null
+++ b/src/boost/libs/thread/test/threads/thread/static/hardware_concurrency_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.
+//
+//===----------------------------------------------------------------------===//
+// Copyright (C) 2011 Vicente J. Botet Escriba
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// <boost/thread/thread.hpp>
+
+// class thread
+
+// static unsigned hardware_concurrency();
+
+#include <boost/thread/thread_only.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+ BOOST_TEST(boost::thread::hardware_concurrency() > 0);
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/thread/test/timming.hpp b/src/boost/libs/thread/test/timming.hpp
new file mode 100644
index 000000000..6ae320e8d
--- /dev/null
+++ b/src/boost/libs/thread/test/timming.hpp
@@ -0,0 +1,27 @@
+// Copyright (C) 2018 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_THREAD_TEST_TIMMING_HPP
+#define BOOST_THREAD_TEST_TIMMING_HPP
+
+#include <boost/thread/detail/config.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if ! defined BOOST_THREAD_TEST_TIME_MS
+#ifdef __linux__
+#define BOOST_THREAD_TEST_TIME_MS 75
+#else
+// Windows, Cygwin, macOS all need this
+#define BOOST_THREAD_TEST_TIME_MS 250
+#endif
+#endif
+
+#if ! defined BOOST_THREAD_TEST_TIME_WARNING
+#define BOOST_THREAD_TEST_IT(A, B) BOOST_TEST_LT((A).count(), (B).count())
+#else
+#define BOOST_THREAD_TEST_IT(A, B) BOOST_TEST_LT((A).count(), (B).count())
+#endif
+
+#endif
diff --git a/src/boost/libs/thread/test/util.inl b/src/boost/libs/thread/test/util.inl
new file mode 100644
index 000000000..e4709bc3e
--- /dev/null
+++ b/src/boost/libs/thread/test/util.inl
@@ -0,0 +1,243 @@
+// Copyright (C) 2001-2003
+// William E. Kempf
+// Copyright (C) 2007-8 Anthony Williams
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(UTIL_INL_WEK01242003)
+#define UTIL_INL_WEK01242003
+
+#include <boost/thread/xtime.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/config.hpp>
+
+#ifndef DEFAULT_EXECUTION_MONITOR_TYPE
+# define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_condition
+#endif
+
+// boostinspect:nounnamed
+
+
+
+namespace
+{
+inline boost::xtime delay(int secs, int msecs=0, int nsecs=0)
+{
+ const int MILLISECONDS_PER_SECOND = 1000;
+ const int NANOSECONDS_PER_SECOND = 1000000000;
+ const int NANOSECONDS_PER_MILLISECOND = 1000000;
+
+ boost::xtime xt;
+ if (boost::TIME_UTC_ != boost::xtime_get (&xt, boost::TIME_UTC_))
+ BOOST_ERROR ("boost::xtime_get != boost::TIME_UTC_");
+
+ nsecs += xt.nsec;
+ msecs += nsecs / NANOSECONDS_PER_MILLISECOND;
+ secs += msecs / MILLISECONDS_PER_SECOND;
+ nsecs += (msecs % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
+ xt.nsec = nsecs % NANOSECONDS_PER_SECOND;
+ xt.sec += secs + (nsecs / NANOSECONDS_PER_SECOND);
+
+ return xt;
+}
+
+}
+namespace boost
+{
+namespace threads
+{
+namespace test
+{
+inline bool in_range(const boost::xtime& xt, int secs=1)
+{
+ boost::xtime min = delay(-secs);
+ boost::xtime max = delay(0);
+ return (boost::xtime_cmp(xt, min) >= 0) &&
+ (boost::xtime_cmp(xt, max) <= 0);
+}
+}
+}
+}
+
+
+namespace
+{
+class execution_monitor
+{
+public:
+ enum wait_type { use_sleep_only, use_mutex, use_condition };
+
+ execution_monitor(wait_type type, int secs)
+ : done(false), type(type), secs(secs) { }
+ void start()
+ {
+ if (type != use_sleep_only) {
+ boost::unique_lock<boost::mutex> lock(mutex); done = false;
+ } else {
+ done = false;
+ }
+ }
+ void finish()
+ {
+ if (type != use_sleep_only) {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ done = true;
+ if (type == use_condition)
+ cond.notify_one();
+ } else {
+ done = true;
+ }
+ }
+ bool wait()
+ {
+ boost::xtime xt = delay(secs);
+ if (type == use_sleep_only) {
+ boost::thread::sleep(xt);
+ return done;
+ }
+ if (type == use_condition) {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ while (!done) {
+ if (!cond.timed_wait(lock, xt))
+ break;
+ }
+ return done;
+ }
+ for (int i = 0; ; ++i) {
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ if (done)
+ return true;
+ else if (i > secs * 2)
+ return done;
+ }
+ boost::thread::sleep(delay(0, 500));
+ }
+ }
+
+private:
+ boost::mutex mutex;
+ boost::condition cond;
+ bool done;
+ wait_type type;
+ int secs;
+};
+}
+namespace thread_detail_anon
+{
+template <typename F>
+class indirect_adapter
+{
+public:
+ indirect_adapter(F func, execution_monitor& monitor)
+ : func(func), monitor(monitor) { }
+#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
+ indirect_adapter(indirect_adapter const&) = default;
+#endif
+
+ void operator()() const
+ {
+ try
+ {
+ boost::thread thrd(func);
+ thrd.join();
+ }
+ catch (...)
+ {
+ monitor.finish();
+ throw;
+ }
+ monitor.finish();
+ }
+
+private:
+ F func;
+ execution_monitor& monitor;
+ void operator=(indirect_adapter&);
+};
+
+}
+// boostinspect:nounnamed
+namespace
+{
+
+template <typename F>
+void timed_test(F func, int secs,
+ execution_monitor::wait_type type=DEFAULT_EXECUTION_MONITOR_TYPE)
+{
+ execution_monitor monitor(type, secs);
+ thread_detail_anon::indirect_adapter<F> ifunc(func, monitor);
+ monitor.start();
+ boost::thread thrd(ifunc);
+ BOOST_REQUIRE_MESSAGE(monitor.wait(),
+ "Timed test didn't complete in time, possible deadlock.");
+}
+
+}
+
+namespace thread_detail_anon
+{
+
+template <typename F, typename T>
+class thread_binder
+{
+public:
+ thread_binder(const F& func, const T& param)
+ : func(func), param(param) { }
+ void operator()() const { func(param); }
+
+private:
+ F func;
+ T param;
+};
+
+}
+
+// boostinspect:nounnamed
+namespace
+{
+template <typename F, typename T>
+thread_detail_anon::thread_binder<F, T> bind(const F& func, const T& param)
+{
+ return thread_detail_anon::thread_binder<F, T>(func, param);
+}
+}
+
+namespace thread_detail_anon
+{
+
+template <typename R, typename T>
+class thread_member_binder
+{
+public:
+ thread_member_binder(R (T::*func)(), T& param)
+ : func(func), param(param) { }
+#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
+ thread_member_binder(thread_member_binder const&) = default;
+#endif
+
+ void operator()() const { (param.*func)(); }
+
+private:
+ void operator=(thread_member_binder&);
+
+ R (T::*func)();
+ T& param;
+};
+
+}
+
+// boostinspect:nounnamed
+namespace
+{
+template <typename R, typename T>
+thread_detail_anon::thread_member_binder<R, T> bind(R (T::*func)(), T& param)
+{
+ return thread_detail_anon::thread_member_binder<R, T>(func, param);
+}
+} // namespace
+
+#endif
diff --git a/src/boost/libs/thread/test/winrt_init.cpp b/src/boost/libs/thread/test/winrt_init.cpp
new file mode 100644
index 000000000..b6d0864ba
--- /dev/null
+++ b/src/boost/libs/thread/test/winrt_init.cpp
@@ -0,0 +1,19 @@
+// Copyright (C) 2014 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/predef/platform.h>
+
+#if BOOST_PLAT_WINDOWS_RUNTIME
+
+#include <wrl\wrappers\corewrappers.h>
+#pragma comment(lib, "runtimeobject.lib")
+
+// Necessary for the tests which to keep the Windows Runtime active,
+// when running in an actual Windows store/phone application initialization
+// is handled automatically by the CRT.
+// This is easier than calling in the main function for each test case.
+Microsoft::WRL::Wrappers::RoInitializeWrapper runtime(RO_INIT_MULTITHREADED);
+
+#endif